<template>
<div>
<appHeader :pageName="$e('history')" :pageType="2" v-if="routeQuery === 'h'"/>
<div :class="[routeQuery === 'h'?'container container-padding':'container']">
<img src="../../assets/img/bg.png" alt="" class="bg-img">
<div class="wrap" v-if="demoEvents">
<vue-event-calendar
:clickDate="clickDate"
:events="demoEvents"
@month-changed="handleMonthChange"
@day-changed="handleDayChanged"
:todayMonth="getTodayMonth()" >
</vue-event-calendar>
<div class="current-desc">
<div class="current-desc-title">
<div class="title-date">{{ descArrDate }}</div>
<div class="title-btn" @click="clickTo" v-if="showBtn">
<span>{{ $e('card_replacement_application') }}</span>
<img src="../../assets/img/right.png" alt="">
</div>
</div>
<div class="current-desc-wrap" v-if="descArr.length">
<div class="current-desc-item" v-for="(item, index) in descArr" :key="index">
<div class="item-content">
<div class="item-title" @click="cliclShow(item.id)">
<img src="../../assets/img/didian.png" alt="" class="location-logo">
<div class="item-left">
<div class="item-address">{{ item.city }}</div>
<div class="item-state safe" v-if="item.safetyStatus === 1">{{ $e('security') }}</div>
<div class="item-state abnormal" v-else>{{ $e('abnormal') }}</div>
</div>
<template v-if="item.safetyStatus === 2">
<img src="../../assets/img/down.png" alt="" class="down" v-if="item.hide">
<img src="../../assets/img/down.png" alt="" class="up" v-else>
</template>
</div>
<div class="desc" v-if="item.safetyStatus === 2 && !item.hide">
{{ $e('description_of_abnormal_conditions') }}: {{ item.remark }}
</div>
</div>
</div>
</div>
<div class="no-locking" v-else>
{{ $e('no_record') }}
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import moment from 'moment-timezone'
import { selectList } from '../../service/api'
import Vue from 'vue'
import appHeader from '../components/header.vue'
export default {
components: {
appHeader
},
data () {
return {
show: true,
value: '',
minDate: '',
listData: [],
demoEvents: '',
userInfo: '', // 用户信息
dayList: [], // 一个月信息
fromDate: '', // 月初
toDate: '', // 月末
today: '', // 今天
frontDay: '', // 前一天
totalNormal: '', // 正常总数
totalAbnormal: '', // 异常
assignmentStartDate: 0, // 外派开始日期
descArr: [], // 下面详情数据
descArrDate: '',
clickDate: '', // 点击日期
catchupSaveData: {}, // 点击对象
routeQuery: '',
dateSection: [],
defaultStartDate: '' // 默认开始日期 从该日期后展示打卡情况
}
},
computed: {
// 展示去打卡按钮
showBtn () {
if (this.catchupSaveData && this.catchupSaveData.customClass) {
return this.catchupSaveData.customClass.findIndex(x => x === 'level2') > -1
} else {
return false
}
}
},
created () {
this.defaultStartDate = Number(moment('2022/10/26').format('x'))
this.routeQuery = this.$route.query.f
// 初始化组件数据
this.initEventCalendar()
moa.setCustomNavigation({
type: 'empty',
menuList: [],
success: function (id) {
console.log(id)
},
fail: function (error) {
console.log(error)
}
})
let clockInitData = JSON.parse(localStorage.getItem('clockInitData'))
if (clockInitData && clockInitData.person && clockInitData.person.timeZone) {
moment.tz.setDefault(clockInitData.person.timeZone)
}
if (clockInitData) {
this.getSection(clockInitData)
}
this.getUserInfo()
this.getList(this.fromDate, this.toDate, 'first')
},
methods: {
// 获取用户当前打卡的时间段
getSection (clockInitData) {
this.dateSection = []
if (clockInitData.dateList && clockInitData.dateList.length) {
clockInitData.dateList.forEach(x => {
let obj = {
fromDate: x.fromDate,
toDate: x.toDate || null
}
this.dateSection.push(obj)
})
}
},
initEventCalendar () {
let vm = Vue.prototype.$EventCalendar.$vm.CALENDAR_EVENTS_DATA
let dateObj = new Date()
vm.params.curYear = moment(dateObj).get('year')
vm.params.curMonth = moment(dateObj).get('month')
vm.params.curDate = moment(dateObj).get('date')
},
// 获取用户信息
getUserInfo () {
this.userInfo = moa.getUserInfo()
let time = new Date().getTime()
this.frontDay = moment(time).subtract(1, 'days').format('x')
this.today = time
this.fromDate = moment(time).startOf('month').format('x')
this.toDate = moment(time).endOf('month').format('x')
this.getMonthData(this.fromDate)
},
// 拼一个月信息
getMonthData (fromDate) {
this.dayList = []
let dayStart = moment(Number(fromDate)).format('YYYY/MM/DD HH/mm/ss')
let total = moment(dayStart, 'YYYY/MM/DD').daysInMonth()
for (let i = 0; i < total; i++) {
let timeStamp = Number(moment(Number(fromDate)).add(i, 'days').format('x'))
let obj = {
str: moment(timeStamp).format('YYYY/MM/DD'),
timeStamp: timeStamp,
endStamp: Number(moment(timeStamp).endOf('day').format('x'))
}
this.dayList.push(obj)
}
console.log('llllist', this.dayList)
},
// 拼打卡数据
getList (fromDate, toDate, status) {
let obj = {
userEmpid: this.userInfo.empId,
fromDate: fromDate,
toDate: toDate
}
this.$Indicator.open(this.$e('loading'))
selectList(obj).then(res => {
this.$Indicator.close()
if (res.data.code === 200) {
let tempDate = res.data.data
let resultDate = []
tempDate.forEach((x, index) => {
let obj = {
clockTime: x.clockTime,
date: (moment(x.clockTime).format('YYYY/MM/DD')),
customClass: x.safetyStatus === 1 ? ['level', 'level0'] : (x.safetyStatus === 2 ? ['level', 'level1'] : ['level', 'level2']),
desc: 1,
safetyStatus: x.safetyStatus,
objAll: []
}
let findIndex = resultDate.findIndex(x => x.date === obj.date)
if (findIndex > -1) {
resultDate[findIndex].desc += 1
if (x.safetyStatus === 2) {
resultDate[findIndex].customClass = ['level', 'level1']
resultDate[findIndex].safetyStatus = x.safetyStatus
}
resultDate[findIndex].objAll.push(x)
} else {
obj.objAll.push(x)
resultDate.push(obj)
}
})
// 把缺卡日期填入
this.dayList.forEach((y, index) => {
let findIndex = resultDate.findIndex(x => x.date === y.str)
// 周六日判断暂时去掉
// && moment(y.timeStamp).format('E') < 6
if (findIndex === -1 && (y.timeStamp < this.frontDay)) {
resultDate.push({
clockTime: Number(moment(y.str).format('x')),
date: y.str,
customClass: ['level', 'level2'],
desc: '',
safetyStatus: 0
})
}
})
// 判断当天情况
let todayIndex = resultDate.findIndex(x => x.date === moment(this.today).format('YYYY/MM/DD'))
if (todayIndex > -1) {
resultDate[todayIndex].customClass.unshift('level3')
if (status === 'first') {
this.getTodayDesc(resultDate[todayIndex], resultDate[todayIndex].date)
}
} else {
let todayObj = {
clockTime: Number(moment(this.today).format('x')),
date: moment(this.today).format('YYYY/MM/DD'),
customClass: ['level', 'level3'],
desc: ''
}
resultDate.push(todayObj)
if (status === 'first') {
this.getTodayDesc(todayObj, moment(this.today).format('YYYY/MM/DD'))
}
}
console.log('打卡数据', resultDate)
// this.demoEvents = this.filterList(resultDate)
// 根据区间格式化数据
this.demoEvents = this.filterListBySection(resultDate)
console.log(this.demoEvents)
this.getTotalCount()
this.getTodayMonth()
}
})
.catch(err => {
this.$Indicator.close()
console.log(err)
this.$Toast('服务错误')
})
},
// 获取大于外派信息的数据
filterList (arr) {
return arr.filter(x => x.clockTime >= this.defaultStartDate)
},
filterListBySection (arr) {
let tempArr = []
for (let i = 0; i < this.dateSection.length; i++) {
let fArr = []
if (this.dateSection[i].toDate) {
fArr = arr.filter(x => x.clockTime >= this.dateSection[i].fromDate && x.clockTime <= this.dateSection[i].toDate)
} else {
fArr = arr.filter(x => x.clockTime >= this.dateSection[i].fromDate)
}
tempArr = tempArr.concat(fArr)
}
let resultArr = []
tempArr.forEach(x => {
if (resultArr.findIndex(y => y.date === x.date) < 0) {
resultArr.push(x)
}
})
resultArr = this.filterList(resultArr)
return resultArr
},
// 获取异常 正常数量
getTotalCount () {
let normalArr = this.demoEvents.filter(x => x.safetyStatus === 1)
let abnormalArr = this.demoEvents.filter(x => x.safetyStatus === 2)
this.totalNormal = normalArr.length
this.totalAbnormal = abnormalArr.length
},
// 获取刚进来今天的数据
getTodayDesc (data, date) {
this.catchupSaveData = data
this.clickDate = date
console.log('好好说', data)
let temp = JSON.parse(JSON.stringify(data.objAll || []))
this.descArr = temp.map(item => {
item.hide = true
return item
})
// this.descArr = this.descArr.reverse()
this.descArr.sort(function (a, b) {
return b.clockTime - a.clockTime
})
this.descArrDate = date.split('/').join('.')
},
getTodayMonth () {
let month = moment(this.today).month()
return month + 1
},
// 月份切换
handleMonthChange ({year, month}) {
let changeDate = Number(moment(year + '/' + month + '/20').format('x'))
let fromDate = moment(changeDate).startOf('month').format('x')
let toDate = moment(changeDate).endOf('month').format('x')
this.getMonthData(fromDate)
this.getList(fromDate, toDate)
},
// 天点击
handleDayChanged ({date}) {
this.getTodayDesc(date, date.date)
},
// 显示隐藏
cliclShow (id) {
let index = this.descArr.findIndex(x => x.id === id)
if (index > -1) {
this.descArr[index].hide = !this.descArr[index].hide
}
},
// 跳转去打卡
clickTo () {
this.$router.push({'name': 'cardReplacement', query: {f: this.routeQuery, timeStamp: this.catchupSaveData.timeStamp}})
}
}
}
</script>
<style lang="less" scoped>
.container{
background: #f6f6f6;
width: 100vw;
height: 100vh;
position: relative;
.wrap{
padding: 0.3733333rem 0.266667rem 0.32rem;
background: #f6f6f6;
border-radius: 0.32rem;
z-index: 9;
}
}
.container-padding{
padding-top: 1.173333rem;
}
/deep/.h-popup-mask{
display: none;
}
.bg-img{
width: 100vw;
position: absolute;
top: 0;
}
.__vev_calendar-wrapper{
background: #fff;
border-radius: 0.32rem;
}
.current-desc{
width: 100%;
background: #fff;
border-radius: 0.32rem;
margin-top: 0.26667rem;
padding-left: 0.4rem;
// padding: 0 0.4rem 0;
// margin-bottom: 0.32rem;
.current-desc-title{
font-size: 0.48rem;
display: flex;
align-items: center;
justify-content: space-between !important;
border-bottom: 0.5px solid rgba(241,241,241,1);
}
.current-desc-item{
display: flex;
justify-content: space-between;
align-items: flex-start;
border-bottom: 0.5px solid rgba(241,241,241,1);
padding: 0.48rem 0;
padding-right: 0.32rem;
}
.current-desc-item:last-child{
border: none;
}
}
.item-content{
flex: 1;
padding-left: 20px;
}
.item-title{
display: flex;
justify-content: space-between;
align-items: center;
position: relative;
.location-logo{
width: 0.32rem;
position: absolute;
top: 0;
bottom: 0;
margin: auto;
left: -18px;
}
.item-left{
display: flex;
justify-content: flex-start;
align-items: center;
}
.item-address{
margin-right: 0.2667rem;
max-width: 45vw;
overflow: hidden;
text-overflow:ellipsis;
font-size: 0.426667rem;
font-weight: 400;
}
.item-state{
font-size: 0.32rem;
padding: 0 0.21333rem;
border-radius: 0.1066667rem;
}
.abnormal{
color: #E59200;
background: #FFEFD5;
}
.safe{
color: #33A326;
background: #D9F5D6;
}
}
.desc{
color: #666666;
font-size: 0.3733rem;
margin-top: 0.22rem;
}
.down{
width: 0.5333rem;
}
.up{
width: 0.5333rem;
transform: rotate(180deg);
}
.no-locking{
text-align: center;
padding: 0.48rem 0;
color: #666;
}
.title-btn{
display: flex;
font-size: 0.37333333rem;
color: #007AFF;
justify-content: flex-end;
align-items: center;
margin-right: 0.4rem;
img{
width: 0.37333333rem;
}
}
.arrow-right.icon {
color: #000;
position: absolute;
right: 6%;
margin-top: 10px;
}
.arrow-right.icon:before {
content: '';
position: absolute;
right: 1px;
top: -5px;
width: 10px;
height: 10px;
border-top: solid 1px #007AFF;
border-right: solid 1px #007AFF;
-webkit-transform: rotate(45deg);
transform: rotate(45deg);
}
</style>
<template>
<div class="cal-wrapper">
<div class="cal-header">
<div class="l" @click="preMonth"><div class="arrow-left icon"> </div></div>
<!-- <div class="title">{{curYearMonth}}</div> -->
<div class="title cal-title">
{{ changeYM }}
</div>
<div class="r" @click="nextMonth"><div class="arrow-right icon"> </div></div>
<!-- <div class="today-icon" v-if="todayMonth == calendar.params.curMonth + 1">
<span v-if="currentLanguage === 'CHN'">今</span>
<span v-else>Today</span>
</div> -->
</div>
<div class="cal-body">
<div class="weeks">
<span
v-for="(dayName, dayIndex) in i18n[calendar.options.locale].dayNames"
class="item"
:key="dayIndex"
>
{{i18n[calendar.options.locale].dayNames[(dayIndex + calendar.options.weekStartOn) % 7]}}
</span>
</div>
<div class="dates" >
<div v-for="date in dayList" class="item"
:class="[{
today: date.status ? (today == date.date) : false,
event: date.status ? (date.title != undefined) : false,
[calendar.options.className] : (date.date == selectedDay)
}, ...date.customClass]"
:key="date.date"
>
<!-- :style="{color: date.title != undefined ? ((date.date == selectedDay) ? '#fff' : customColor) : 'inherit'}" -->
<p class="date-num"
@click="handleChangeCurday(date)"
:class="[date.status?'on-month':'other-month']"
>
<span v-if="date.customClass.indexOf('level3') >= 0">
<span v-if="currentLanguage === 'CHN'">今</span>
<span v-else>T</span>
</span>
<span v-else> {{date.dateNum}}</span>
</p>
<div class="bg-level" :class="{'click-shadow': clickDate === date.date}" v-if="date.customClass.length"></div>
<!-- 正常 -->
<div class="bg-desc" v-if="date.safetyStatus == 1">{{ date.desc }}</div>
<!-- 异常 -->
<div class="bg-desc" v-if="date.safetyStatus == 2">{{ currentLanguage === 'CHN'?'异常':'Abnormal' }}</div>
<!-- 缺卡 -->
<div class="bg-desc absence" v-if="date.safetyStatus == 0 && date.customClass.indexOf('level3') < 0">
<span v-if="currentLanguage === 'CHN'">缺卡</span>
<span v-else>Absence <br> from duty</span>
<!-- {{ currentLanguage === 'CHN'?'缺卡':'Absence from duty' }} -->
</div>
<!-- <span v-if="date.status ? (today == date.date) : false" class="is-today" :style="{backgroundColor: customColor }" ></span> -->
<!-- <span v-if="date.status ? (date.title != undefined) : false" class="is-event"
:style="{borderColor: customColor, backgroundColor: (date.date == selectedDay) ? customColor : 'inherit'}"></span> -->
</div>
</div>
</div>
</div>
</template>
<script>
import moment from 'moment-timezone'
import i18n from '../i18n.js'
import { dateTimeFormatter, isEqualDateStr} from '../tools.js'
const inBrowser = typeof window !== 'undefined'
export default {
name: 'cal-panel',
data () {
return {
i18n,
currentLanguage: this.$store.state.currentLanguage,
}
},
props: {
events: {
type: Array,
required: true
},
calendar: {
type: Object,
required: true
},
selectedDay: {
type: String,
required: false
},
todayMonth: {
type: [String,Number]
},
// 获取当前一个月数组
tempDate: {
type: Array
},
clickDate: {
type: String,
required: false
}
},
computed: {
dayList () {
let changeDate = Number(moment(this.calendar.params.curYear + '/' + (Number(this.calendar.params.curMonth)+1)+ '/20').format('x'))
let firstDay = moment(changeDate).startOf('month').format('x')
let dayOfWeek2 = Number(moment(Number(firstDay)).format('E'))
let total = Number(moment(Number(firstDay)).daysInMonth())
let tempArr = []
let nextTotal = 42 - total - dayOfWeek2
let prevArr = this.pushData(1, dayOfWeek2 + 1, firstDay, 'subtract').reverse()
tempArr = tempArr.concat(prevArr)
let currentArr = this.pushData(0, total, firstDay, 'add')
tempArr = tempArr.concat(currentArr)
let nextMonth = tempArr[tempArr.length-1].timeStamp
let nextArr = this.pushData(1, nextTotal + 1, nextMonth, 'add')
tempArr = tempArr.concat(nextArr)
return tempArr
},
today () {
let dateObj = new Date()
return `${dateObj.getFullYear()}/${dateObj.getMonth()+1}/${dateObj.getDate()}`
},
curYearMonth () {
let tempDate = Date.parse(new Date(`${this.calendar.params.curYear}/${this.calendar.params.curMonth+1}/01`))
return dateTimeFormatter(tempDate, this.i18n[this.calendar.options.locale].format)
},
changeYM () {
let str = this.calendar.params.curYear + '.'
let currentM = this.calendar.params.curMonth + 1
return currentM <= 9 ? str + '0' +currentM : str + currentM
},
customColor () {
return this.calendar.options.color
}
},
mounted () {
let clockInitData = JSON.parse(localStorage.getItem('clockInitData'))
if (clockInitData && clockInitData.person && clockInitData.person.timeZone) {
moment.tz.setDefault(clockInitData.person.timeZone)
}
},
methods: {
pushData (startI, total, startDay, type) {
let status = ''
let tempItem = {}
let tempArr = []
for (let i = startI ; i < total ; i++) {
let curTimeStamp = ''
if (type === 'subtract') {
curTimeStamp = Number(moment(Number(startDay)).subtract(i, 'days').format('x'))
} else {
curTimeStamp = Number(moment(Number(startDay)).add(i, 'days').format('x'))
}
if (this.calendar.params.curMonth === moment(curTimeStamp).month()) {
status = 1
} else {
status = 0
}
tempItem = {
timeStamp: curTimeStamp,
date: moment(curTimeStamp).format("YYYY/MM/DD"),
dateNum: moment(curTimeStamp).get('date'),
status: status,
customClass: [],
}
this.events.forEach((event) => {
if (isEqualDateStr(event.date, tempItem.date)) {
tempItem.title = event.title
tempItem.desc = event.desc || ''
tempItem.safetyStatus = event.safetyStatus
tempItem.objAll = event.objAll
if (event.customClass && event.customClass.length) tempItem.customClass = event.customClass
}
})
tempArr.push(tempItem)
}
return tempArr
},
nextMonth () {
this.$EventCalendar.nextMonth()
this.$emit('month-changed', {year:this.calendar.params.curYear,month: this.calendar.params.curMonth +1})
},
preMonth () {
// console.log(this.calendar.params.curYear)
// console.log(this.calendar.params.curMonth)
this.$EventCalendar.preMonth()
this.$emit('month-changed', {year:this.calendar.params.curYear,month: this.calendar.params.curMonth +1})
},
handleChangeCurday (date) {
if (date.status) {
this.setClick(date)
this.$emit('cur-day-changed', date)
}
},
setClick (date) {
this.dayList.forEach(x => {
if (x.date === date.date) {
x.clickDate = true
} else {
x.clickDate = false
}
})
}
}
}
</script>
<style scoped>
.absence{
/* color: #007AFF; */
}
.title{
font-size: 0.66667rem;
font-weight: 700;
}
.date-num{
font-size: 0.4266667rem;
font-weight: 400;
}
.click-shadow{
border: 1px solid rgba(255,255,255,1);
box-shadow: 0px 2px 6px 0px rgba(182,182,182,0.76);
}
</style>