You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

212 lines
10 KiB

<template>
<div>
<el-calendar v-model="day">
<template #dateCell="{ date, data }">
<div @click="selectDay = data.day,isShow = true">
<div>{{ data.day.split('-')[2] }}</div>
<div v-if="dayAttendances(data.day) && dayAttendances(data.day).attendance" class="clock-in">
<el-tag v-if="dayAttendances(data.day).attendance.jiaban && dayAttendances(data.day).attendance.jiaban instanceof Array && dayAttendances(data.day).attendance.jiaban.filter(i => i).length > 0" effect="dark" size="mini" type="danger" color="#9f2222">
加班
</el-tag>
<el-tag v-if="dayAttendances(data.day).on_duty_schedules" effect="dark" size="mini" type="danger">
{{ dayAttendances(data.day).on_duty_schedules.status ? '已值班' : '待值班' }}
</el-tag>
<el-tag v-if="dayAttendances(data.day).attendance.sign_in_at" effect="dark" size="mini">{{ $moment(dayAttendances(data.day).attendance.sign_in_at).format('HH:mm:ss') }}签到</el-tag>
<el-tag v-if="dayAttendances(data.day).attendance.sign_out_at" effect="dark" type="success" size="mini">{{ $moment(dayAttendances(data.day).attendance.sign_out_at).format('HH:mm:ss') }}签退</el-tag>
<el-tag v-if="dayAttendances(data.day).attendance.chuchai && dayAttendances(data.day).attendance.chuchai instanceof Array && (dayAttendances(data.day).attendance.chuchai[0] || dayAttendances(data.day).attendance.chuchai[1])" effect="dark" type="warning" size="mini">出差</el-tag>
<el-tag v-if="dayAttendances(data.day).attendance.qingxiujia && dayAttendances(data.day).attendance.qingxiujia instanceof Array && dayAttendances(data.day).attendance.qingxiujia[0]" effect="dark" type="info" size="mini">上午请假</el-tag>
<el-tag v-if="dayAttendances(data.day).attendance.qingxiujia && dayAttendances(data.day).attendance.qingxiujia instanceof Array && dayAttendances(data.day).attendance.qingxiujia[1]" effect="dark" type="info" size="mini">下午请假</el-tag>
</div>
</div>
</template>
</el-calendar>
<vxe-modal
v-model="isShow"
show-footer
:z-index="zIndex"
title="打卡详情"
show-confirm-button
transfer
show-zoom
resize
:width="defaultModalSize.sWidth"
:height="defaultModalSize.sHeight"
esc-closable
:fullscreen="$store.getters.device === 'mobile'"
>
<div>
<el-tag v-if="selectDay && dayAttendances(selectDay).on_duty_schedules" style="margin-bottom: 10px;" effect="dark" size="mini" type="danger">
{{ dayAttendances(selectDay).on_duty_schedules.status ? '已值班' : '待值班' }}
</el-tag>
<template v-if="selectDay && dayAttendances(selectDay).attendance.chuchai && dayAttendances(selectDay).attendance.chuchai instanceof Array && (dayAttendances(selectDay).attendance.chuchai[0] ||dayAttendances(selectDay).attendance.chuchai[1])">
<el-descriptions :column="2" size="mini" border>
<template #title>
<el-tag effect="dark" type="warning" size="mini">出差</el-tag>
</template>
<el-descriptions-item label="目的地">{{ dayAttendances(selectDay).attendance.chuchai[0].mudidi }}</el-descriptions-item>
<el-descriptions-item label="交通方式">{{ dayAttendances(selectDay).attendance.chuchai[0].jiaotongfangshi }}</el-descriptions-item>
<el-descriptions-item label="开始时间">{{ dayAttendances(selectDay).attendance.chuchai[0].kaishi }}</el-descriptions-item>
<el-descriptions-item label="结束时间">{{ dayAttendances(selectDay).attendance.chuchai[0].jieshu }}</el-descriptions-item>
</el-descriptions>
</template>
<template v-if="selectDay && dayAttendances(selectDay).attendance.jiaban && dayAttendances(selectDay).attendance.jiaban instanceof Array && dayAttendances(selectDay).attendance.jiaban.filter(i => i).length > 0">
<el-descriptions :column="2" size="mini" border v-for="item in dayAttendances(selectDay).attendance.jiaban.filter(i => i)" :key="item.id">
<template #title>
<el-tag effect="dark" type="danger" color="#9f2222" size="mini">加班</el-tag>
</template>
<el-descriptions-item label="标题">{{ item.title }}</el-descriptions-item>
<el-descriptions-item label="加班时长">{{ item.jiabanshichang }}小时</el-descriptions-item>
<el-descriptions-item label="开始时间">{{ item.kaishiriqi ? $moment(item.kaishiriqi).format('YYYY年MM月DD日 HH时mm分') : '' }}</el-descriptions-item>
<el-descriptions-item label="结束时间">{{ item.jieshushijian ? $moment(item.jieshushijian).format('YYYY年MM月DD日 HH时mm分') : '' }}</el-descriptions-item>
<el-descriptions-item span="2" label="原因说明">{{ item.yuanyinshuoming }}</el-descriptions-item>
</el-descriptions>
</template>
<template v-if="selectDay && dayAttendances(selectDay).attendance.qingxiujia && dayAttendances(selectDay).attendance.qingxiujia instanceof Array && dayAttendances(selectDay).attendance.qingxiujia[0]">
<el-descriptions :column="2" size="mini" border>
<template #title>
<el-tag effect="dark" type="info" size="mini">上午请假</el-tag>
</template>
<el-descriptions-item label="请假类别">{{ dayAttendances(selectDay).attendance.qingxiujia[0].qingjialeibie }}</el-descriptions-item>
<el-descriptions-item label="请假时长">{{ dayAttendances(selectDay).attendance.qingxiujia[0].shijiqingjiashichang }}</el-descriptions-item>
<el-descriptions-item label="开始时间">{{ dayAttendances(selectDay).attendance.qingxiujia[0].kaishishijian }}</el-descriptions-item>
<el-descriptions-item label="结束时间">{{ dayAttendances(selectDay).attendance.qingxiujia[0].jieshushijian }}</el-descriptions-item>
<el-descriptions-item label="实际开始时间">{{ dayAttendances(selectDay).attendance.qingxiujia[0].shijikaishishijian }}</el-descriptions-item>
<el-descriptions-item label="实际结束时间">{{ dayAttendances(selectDay).attendance.qingxiujia[0].shijijieshushijian }}</el-descriptions-item>
</el-descriptions>
</template>
<template v-if="selectDay && dayAttendances(selectDay).attendance.qingxiujia && dayAttendances(selectDay).attendance.qingxiujia instanceof Array && dayAttendances(selectDay).attendance.qingxiujia[1]">
<el-descriptions :column="2" size="mini" border>
<template #title>
<el-tag effect="dark" type="info" size="mini">下午请假</el-tag>
</template>
<el-descriptions-item label="请假类别">{{ dayAttendances(selectDay).attendance.qingxiujia[1].qingjialeibie }}</el-descriptions-item>
<el-descriptions-item label="请假时长">{{ dayAttendances(selectDay).attendance.qingxiujia[1].shijiqingjiashichang }}</el-descriptions-item>
<el-descriptions-item label="开始时间">{{ dayAttendances(selectDay).attendance.qingxiujia[1].kaishishijian }}</el-descriptions-item>
<el-descriptions-item label="结束时间">{{ dayAttendances(selectDay).attendance.qingxiujia[1].jieshushijian }}</el-descriptions-item>
<el-descriptions-item label="实际开始时间">{{ dayAttendances(selectDay).attendance.qingxiujia[1].shijikaishishijian }}</el-descriptions-item>
<el-descriptions-item label="实际结束时间">{{ dayAttendances(selectDay).attendance.qingxiujia[1].shijijieshushijian }}</el-descriptions-item>
</el-descriptions>
</template>
<template v-if="selectDay && dayAttendances(selectDay).attendance">
<el-timeline>
<el-timeline-item
v-for="(item) in dayAttendances(selectDay).attendance.details"
:key="item.id"
:type="item.sign_at_image ? 'warning' : 'primary'"
:timestamp="item.sign_at">
<p>{{ item.sign_at_address }}{{ item.sign_at_image ? '(外勤)' : '' }}</p>
<p style="color: #909399;">{{ item.remark }}</p>
<el-image v-if="item.sign_at_image" style="max-width: 120px" fit="contain" :src="item.sign_at_image.url"></el-image>
</el-timeline-item>
</el-timeline>
</template>
<template v-else>
<el-empty description="暂无打卡记录"></el-empty>
</template>
</div>
</vxe-modal>
</div>
</template>
<script>
import { index } from '@/api/attendance'
import { PopupManager } from "element-ui/lib/utils/popup";
import {defaultModalSize} from "@/settings";
export default {
data() {
return {
isShow: false,
defaultModalSize,
zIndex: PopupManager.nextZIndex(),
day: new Date(),
selectDay: '',
clockLogs: {
attendances: [],
is_workday: true,
on_dutys: [],
today_attendance: {
details: []
}
}
}
},
computed: {
dayAttendances() {
return function(day) {
return this.clockLogs.attendances.find(i => i.date === day)
}
},
device() {
return this.$store.getters.device
}
},
watch: {
'day': {
handler: function(newVal, oldVal) {
if (new Date(newVal).getFullYear() !== new Date(oldVal).getFullYear() || new Date(newVal).getMonth() !== new Date(oldVal).getMonth()) {
this.getData()
}
},
immediate: true
},
isShow(newVal) {
if(newVal) {
this.zIndex = PopupManager.nextZIndex()
}
}
},
created() {
},
methods: {
async getData() {
try {
this.clockLogs = await index({
month: this.$moment(this.day).format('YYYY-MM')
})
this.$emit('today-attendance', this.clockLogs.today_attendance)
} catch (err) {
console.error(err)
}
}
}
}
</script>
<style scoped lang="scss">
::v-deep .el-calendar-day {
height: auto!important;
min-height: 60px;
}
::v-deep .el-tag--mini + .el-tag--mini {
margin-top: 4px;
}
.clock-in {
display: flex;
flex-direction: column;
justify-content: flex-end;
align-items: flex-end;
}
@media (max-width: 768px) {
.clock-in > .el-tag {
font-size: 0;
padding: 0;
width: 10px;
height: 10px;
border-radius: 100%;
}
}
</style>