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.
227 lines
8.3 KiB
227 lines
8.3 KiB
<template>
|
|
<div>
|
|
<card-container>
|
|
<vxe-toolbar export print custom ref="toolbar">
|
|
<template #buttons>
|
|
<el-date-picker v-model="select.month" type="month" size="small" value-format="yyyy-MM"></el-date-picker>
|
|
|
|
<el-select v-if="is_bgs" style="width:250px;margin-left:6px" size="small"
|
|
v-model="select.department_id" placeholder="请选择">
|
|
<el-option v-for="item in departments" :key="item.id" :label="item.name" :value="item.id">
|
|
</el-option>
|
|
</el-select>
|
|
<el-input size="small" style="width:250px;margin-left:6px" v-model="select.keyword" placeholder="请输入关键词"></el-input>
|
|
<el-button icon="el-icon-search" type="primary" plain size="small" style="margin-left: 6px;" @click="getStatistics">搜索</el-button>
|
|
</template>
|
|
</vxe-toolbar>
|
|
<vxe-table
|
|
ref="table"
|
|
stripe
|
|
style="margin-top: 10px;"
|
|
round
|
|
:max-height="600"
|
|
keep-source
|
|
show-header-overflow
|
|
show-footer-overflow
|
|
show-overflow
|
|
:row-config="{ isHover: true }"
|
|
:header-cell-style="{ 'white-space': 'wrap' }"
|
|
:print-config="{}"
|
|
:export-config="{type:'xlsx',isColgroup:true}"
|
|
:column-config="{ resizable: true }"
|
|
:data="tableData.admins">
|
|
<vxe-column type="seq" width="50" align="center" fixed="left"></vxe-column>
|
|
<vxe-column field="name" title="姓名"
|
|
fixed="left"
|
|
align="center"
|
|
width="120">
|
|
</vxe-column>
|
|
<vxe-column field="department.name" title="所在部门" align="center" width="150"></vxe-column>
|
|
<vxe-colgroup v-for="item in dateTableColumns" align="center" :title="item.title">
|
|
<vxe-column title="上午" width="160" align="center">
|
|
<template #default="{ row }">
|
|
<div>
|
|
<div v-if="row.attendance[item.date]['qingxiujia'] && row.attendance[item.date]['qingxiujia'][0]">
|
|
{{ row.attendance[item.date]['qingxiujia'][0].qingjialeibie }}
|
|
</div>
|
|
<div v-else-if="row.attendance[item.date]['chuchai'] && row.attendance[item.date]['chuchai'][0]">
|
|
<!-- 出差 -->
|
|
✔️
|
|
</div>
|
|
|
|
<div v-else-if="(row.attendance[item.date].hasOwnProperty('0')) && row.attendance[item.date]['0'].sign_in_at">
|
|
✔️
|
|
</div>
|
|
<div v-else>
|
|
✘
|
|
</div>
|
|
|
|
<div v-if="row.attendance[item.date]['jiaban'] instanceof Array && row.attendance[item.date]['jiaban'].filter(i => i) && row.attendance[item.date]['jiaban'].filter(i => i).find(i => i.kaishiriqi && $moment(i.kaishiriqi).isBefore($moment().hours(11).minutes(30)))">
|
|
加班
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</vxe-column>
|
|
<vxe-column title="下午" width="160" align="center">
|
|
<template #default="{ row }">
|
|
<div>
|
|
<div v-if="row.attendance[item.date]['qingxiujia'] && row.attendance[item.date]['qingxiujia'][1]">
|
|
{{ row.attendance[item.date]['qingxiujia'][1].qingjialeibie }}
|
|
</div>
|
|
<div v-else-if="row.attendance[item.date]['chuchai'] && row.attendance[item.date]['chuchai'][1]">
|
|
<!-- 出差 -->
|
|
✔️
|
|
</div>
|
|
|
|
<div v-else-if="(row.attendance[item.date].hasOwnProperty('0')) && row.attendance[item.date]['0'].sign_out_at">
|
|
✔️
|
|
</div>
|
|
<div v-else>
|
|
✘
|
|
</div>
|
|
|
|
<div v-if="row.attendance[item.date]['jiaban'] instanceof Array && row.attendance[item.date]['jiaban'].filter(i => i) && row.attendance[item.date]['jiaban'].filter(i => i).find(i => i.kaishiriqi && $moment(i.kaishiriqi).isBefore($moment().hours(14)))">
|
|
加班
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</vxe-column>
|
|
</vxe-colgroup>
|
|
<vxe-column title="备注" min-width="200" header-align="center" align="left">
|
|
<template #default="{ row }">
|
|
<span>{{ getRemark(row) }}</span>
|
|
</template>
|
|
</vxe-column>
|
|
</vxe-table>
|
|
</card-container>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import { throttle } from '@/utils'
|
|
import { statistics } from '@/api/attendance'
|
|
import {
|
|
departmentListNoAuth
|
|
} from "@/api/common.js"
|
|
import store from "@/store/modules/user.js"
|
|
export default {
|
|
data() {
|
|
return {
|
|
select: {
|
|
month: this.$moment().format('YYYY-MM'),
|
|
department_id:'',
|
|
keyword:""
|
|
},
|
|
is_bgs:false,
|
|
departments: [],
|
|
tableData: {
|
|
admins: [],
|
|
dates: [],
|
|
leave_types: []
|
|
},
|
|
my_department_id:''
|
|
}
|
|
},
|
|
methods: {
|
|
bindToolbar: throttle(function () {
|
|
this.$nextTick(() => {
|
|
if (this.$refs["table"] && this.$refs["toolbar"]) {
|
|
this.$refs["table"].connect(this.$refs["toolbar"]);
|
|
}
|
|
});
|
|
}, 1000, true),
|
|
async getStatistics() {
|
|
try {
|
|
const res = await statistics(this.select)
|
|
this.tableData = res
|
|
} catch (err) {
|
|
console.error(err)
|
|
}
|
|
},
|
|
async getDepartmentList() {
|
|
try {
|
|
const res = await departmentListNoAuth();
|
|
console.log(res);
|
|
let arr = res
|
|
this.departments = arr
|
|
this.departments.unshift({
|
|
id: '',
|
|
name: '全部'
|
|
})
|
|
} catch (err) {
|
|
console.error(err);
|
|
}
|
|
},
|
|
getRemark(row) {
|
|
let result = ''
|
|
let overtimeDay = 0
|
|
let leave = new Map(this.tableData.leave_types.map(i => [i, 0]))
|
|
let signDay = Object.entries(row.attendance).reduce((pre, [key, value]) => {
|
|
if (value['qingxiujia'][0]) {
|
|
leave.set(value['qingxiujia'][0]['qingjialeibie'], Number(leave.get(value['qingxiujia'][0]['qingjialeibie']) ?? 0) + (value['qingxiujia'][0]['qingjialeibie'] === '调休' ? Number(value['qingxiujia'][0]['qingjiashijian'] ?? 0) : Number(value['qingxiujia'][0]['day'] ?? 0)))
|
|
}
|
|
if (value['qingxiujia'][1]) {
|
|
leave.set(value['qingxiujia'][1]['qingjialeibie'], Number(leave.get(value['qingxiujia'][1]['qingjialeibie']) ?? 0) + (value['qingxiujia'][1]['qingjialeibie'] === '调休' ? Number(value['qingxiujia'][1]['qingjiashijian'] ?? 0) : Number(value['qingxiujia'][1]['day'] ?? 0)))
|
|
}
|
|
if (value['jiaban'] instanceof Array && value['jiaban'].filter(i => i).length > 0) {
|
|
overtimeDay += value['jiaban'].filter(i => i).reduce((pre1, cur1) => pre1 + (isNaN(Number(cur1.jiabanshichang)) ? 0 : Number(cur1.jiabanshichang)), 0) ?? 0
|
|
}
|
|
return pre + (!value.hasOwnProperty('0') ? 0 : (
|
|
this.workDates.indexOf(key) !== -1 ? (
|
|
(() => {
|
|
let temp = 0
|
|
temp += value['0'].sign_in_at ? 0.5 : 0
|
|
temp += value['0'].sign_out_at ? 0.5 : 0
|
|
return temp
|
|
})()
|
|
) : 0
|
|
))
|
|
}, 0)
|
|
result += signDay === this.workDates.length ? '全勤' : `缺勤${this.workDates.length-signDay}天`
|
|
result += overtimeDay ? `,加班${overtimeDay}时` : ''
|
|
Array.from(leave).forEach(([name, day]) => {
|
|
if (day) {
|
|
if (name === '调休') {
|
|
result += `,${name}${day}小时`
|
|
} else {
|
|
result += `,${name}${day}天`
|
|
}
|
|
}
|
|
})
|
|
return result
|
|
}
|
|
},
|
|
computed: {
|
|
dateTableColumns() {
|
|
let columns = this.tableData.dates.map(i => ({
|
|
title: `${this.$moment(i.day).format('YYYY年MM月DD日')} ${i.is_workday ? '工作日' : '公休'}`,
|
|
field: i.day,
|
|
date: i.date
|
|
}))
|
|
return columns
|
|
},
|
|
workDates() {
|
|
return this.tableData.dates.filter(i => i.is_workday).map(i => i.date)
|
|
}
|
|
},
|
|
created() {
|
|
this.my_department_id = store.state.department?store.state.department.id:''
|
|
if(this.my_department_id){
|
|
this.is_bgs = this.my_department_id==2?true:false
|
|
this.select.department_id = this.my_department_id
|
|
}
|
|
|
|
|
|
|
|
this.getStatistics()
|
|
this.getDepartmentList()
|
|
},
|
|
mounted() {
|
|
this.bindToolbar()
|
|
},
|
|
}
|
|
</script>
|
|
|
|
<style scoped lang="scss">
|
|
</style>
|