|
<template>
<div class="page-main">
<div class="page-content">
<t-tabs :animated="false" @change="changeTabs">
<!-- 日报 -->
<t-tab-panel label="日报" panel-id="tab-1">
<div class="row mt-32">
<div class="keep-row">
<span>日期:</span>
<t-date-picker v-model="dailyForm.workDay" style="width:200px" placeholder="请选择日期"></t-date-picker>
</div>
<div class="keep-row">
<span>部门/员工:</span>
<dept-staff-cascader v-model="dailyForm" @inited="handleDailyInited" @getOrgId="getDailyOrgId" @getDepId="getDailyDepId" @getStaffId="getDailyStaffId" />
</div>
<div class="search-btn">
<t-button color="primary" @click="handSearchDay">查询</t-button>
<t-button @click="resetDailyData">重置</t-button>
</div>
</div>
<t-table :data="dailyTableData" :loading="loadDailyTable" size="sm" line class="table-detail">
<t-table-column size="sm" type="selection"></t-table-column>
<t-table-column size="sm" prop="name" label="姓名"></t-table-column>
<t-table-column size="sm" prop="userid" label="员工编号"></t-table-column>
<t-table-column size="sm" prop="duty" label="职务"></t-table-column>
<t-table-column size="sm" prop="status" label="考勤状态">
<template slot-scope="scope">
<span :class="getStatusClass(scope.row.goToWorkStatus)">{{ scope.row.goToWorkStatus }}</span>
<span :class="getStatusClass(scope.row.goOffWorkStatus)">{{ scope.row.goOffWorkStatus }}</span>
</template>
</t-table-column>
</t-table>
<t-pager :page-size="dailyForm.pageSize" :current="dailyForm.current" :total="dailyTotal" :sizer-range="[ 5, 10, 20, 30 ]" class="pager" show-elevator @on-change="onChangeDay"></t-pager>
</t-tab-panel>
<!-- 月报 -->
<t-tab-panel label="月报" panel-id="tab-2">
<div class="row mt-32">
<div class="keep-row">
<span>月份:</span>
<t-date-picker v-model="monthlyForm.month" style="width:200px" type="month" placeholder="请选择月份"></t-date-picker>
</div>
<div class="keep-row">
<span>部门/员工:</span>
<dept-staff-cascader v-model="monthlyForm" @getOrgId="getMonthOrgId" @getDepId="getMonthDepId" @getStaffId="getMonthStaffId" />
</div>
<div class="search-btn">
<t-button color="primary" @click="handSearchMonth">查询</t-button>
<t-button @click="resetMonthData">重置</t-button>
</div>
</div>
<t-button class="export-excel" color="primary">
<t-icon size="14" class="icon-txt" icon="upload-outline"></t-icon>导出至Excel
</t-button>
<t-table :data="monthTableData" :loading="loadMonthTable" size="sm" line class="table-detail">
<t-table-column type="selection"></t-table-column>
<t-table-column width="75" prop="name" label="姓名"></t-table-column>
<t-table-column width="90" prop="userid" label="员工编号"></t-table-column>
<t-table-column width="90" prop="duty" label="职务"></t-table-column>
<t-table-column width="120" prop="daysAttendance" label="出勤天数(天)"></t-table-column>
<t-table-column width="120" prop="timesLate" label="迟到次数(次)">
<template slot-scope="scope">
<span v-if="scope.row.timesLate===0" size="sm">{{ scope.row.timesLate }}</span>
<span v-else class="abnormalState">{{ scope.row.timesLate }}</span>
</template>
</t-table-column>
<t-table-column width="110" prop="hoursLate" label="迟到时长(h)">
<template slot-scope="scope">
<span v-if="scope.row.hoursLate===0" size="sm">{{ scope.row.hoursLate }}</span>
<span v-else class="abnormalState">{{ scope.row.hoursLate }}</span>
</template>
</t-table-column>
<t-table-column width="120" prop="timesLeftearly" label="早退次数(次)">
<template slot-scope="scope">
<span v-if="scope.row.timesLeftearly===0" size="sm">{{ scope.row.timesLeftearly }}</span>
<span v-else class="abnormalState">{{ scope.row.timesLeftearly }}</span>
</template>
</t-table-column>
<t-table-column width="120" prop="hoursLeftearly" label="早退时长(h)">
<template slot-scope="scope">
<span v-if="scope.row.hoursLeftearly===0" size="sm">{{ scope.row.hoursLeftearly }}</span>
<span v-else class="abnormalState">{{ scope.row.hoursLeftearly }}</span>
</template>
</t-table-column>
<t-table-column width="120" prop="timesAbsence" label="旷工次数(次)">
<template slot-scope="scope">
<span v-if="scope.row.timesAbsence===0" size="sm">{{ scope.row.timesAbsence }}</span>
<span v-else class="abnormalState">{{ scope.row.timesAbsence }}</span>
</template>
</t-table-column>
<t-table-column width="120" prop="daysAbsence" label="旷工时长(天)">
<template slot-scope="scope">
<span v-if="scope.row.daysAbsence===0" size="sm">{{ scope.row.daysAbsence }}</span>
<span v-else class="abnormalState">{{ scope.row.daysAbsence }}</span>
</template>
</t-table-column>
<t-table-column prop="operation" label="操作" fixed="right">
<template slot-scope="scope">
<a class="link" size="sm" @click="handleClick(scope.row)">详情</a>
</template>
</t-table-column>
</t-table>
<t-pager :page-size="monthlyForm.pageSize" :current="monthlyForm.current" :total="monthlyTotal" :sizer-range="[ 5, 10, 20, 30 ]" class="pager" show-elevator @on-change="onChangeMonth"></t-pager>
</t-tab-panel>
</t-tabs>
</div>
<attendance-dialog :visibled.sync="attendanceModal" :data="modalData" :loading="loadDetail" />
</div>
</template>
<script>
import atdapi from '@/api/attendance'
import formatDateTime from '@/utils/formatDateTime.js'
import AttendanceDialog from '../components/AttendanceDialog'
import DeptStaffCascader from '../components/DeptStaffCascader'
export default {
components: { AttendanceDialog, DeptStaffCascader },
data () {
const now = new Date()
return {
attendanceModal: false,
modalData: {},
tabName: 'tab-1',
dailyTableData: [],
monthTableData: [],
data: '',
loadDetail: false,
loadDailyTable: false,
loadMonthTable: false,
// 公司、部门、员工、列表
companyTypesList: [],
departmentTypesList: [],
getStaffTypesList: [],
monthlyTotal: 0,
dailyTotal: 0,
monthlyForm: {
month: formatDateTime(new Date().setMonth(now.getMonth() - 1), 'yyyy-MM'),
userid: null,
depId: '',
orgId: '',
current: 1,
pageSize: 10
},
dailyForm: {
workDay: formatDateTime(now, 'yyyy-MM-dd'),
userid: null,
depId: '',
orgId: '',
current: 1,
pageSize: 10
}
}
},
methods: {
getDailyOrgId(id) {
this.dailyForm.orgId = id
},
getDailyDepId(id) {
this.dailyForm.depId = id
},
getDailyStaffId(id) {
this.dailyForm.userid = id
},
getMonthOrgId(id) {
this.monthlyForm.orgId = id
},
getMonthDepId(id) {
this.monthlyForm.depId = id
},
getMonthStaffId(id) {
this.monthlyForm.userid = id
},
handleDailyInited () {
// this.getDailyTable()
},
changeTabs (tabName) {
this.tabName = tabName
},
// 搜索
handSearchDay () {
if (this.dailyForm.workDay && this.dailyForm.orgId) {
this.dailyForm.current = 1
this.getDailyTable()
} else { return this.$Message.warning('请选择时间和部门') }
},
handSearchMonth () {
if (this.monthlyForm.month && this.monthlyForm.orgId) {
this.monthlyForm.current = 1
this.getMonthTable()
} else { return this.$Message.warning('请选择时间和部门') }
},
// 分页
onChangeDay (val) {
this.dailyForm.current = val
this.getDailyTable()
},
onChangeMonth (val) {
this.monthlyForm.current = val
this.getMonthTable()
},
// // 向服务器发送请求获取公司类型列表数据
// async getCompanyTypesList () {
// const res = await commonApi.getCompanyTypesList()
// if (res.status === 200) {
// this.companyTypesList = res.data.data
// } else {
// this.$Message.danger('公司类型列表数据获取失败!')
// }
// },
// // 获取部门列表
// async queryCycleChildOrg (id) {
// const res = await commonApi.queryCycleChildOrg(id)
// if (res.status === 200) {
// const data = []
// // 递归 实现tree组件所需部门数据结构
// this.nextDepartment(res.data, data)
// // 深拷贝data
// const data1 = JSON.parse(JSON.stringify(data))
// // 用部门id映射关系代替code与parentCode父子映射关系
// data.forEach(item => {
// // 删除pid为"-1"的的pid属性,否则tree渲染的时候没有根节点渲染不出来
// if (item.pid === '-1') {
// delete item.pid
// }
// item.id = item.orgId
// data1.some((item1) => {
// if (item.pid === item1.id) {
// item.pid = item1.orgId
// } else {
// return false
// }
// })
// })
// // eslint-disable-next-line no-return-assign
// this.departmentTypesList = data.filter(item => item.data = item.id)
// } else {
// this.$Message.danger('部门类型列表数据获取失败!')
// }
// },
// // 向服务器发送请求获取用户类型列表数据
// async getStaffTypesList (id) {
// const res = await commonApi.getStaffTypesList(id)
// if (res.status === 200) {
// this.staffTypesList = res.data.data
// } else {
// this.$Message.danger('用户类型列表数据获取失败!')
// }
// },
// // 如果部门还有下级 递归
// nextDepartment (data, arr) {
// if (data.length > 0) {
// data.forEach(item => {
// arr.push({
// orgId: item.id + '',
// id: item.code,
// label: item.name,
// pid: item.parentCode
// })
// this.nextDepartment(item.departments, arr)
// })
// }
// },
// 重置日报数据
resetDailyData() {
this.$nextTick(() => {
this.dailyForm = {
workDay: '',
userid: null,
depId: '',
orgId: '',
current: 1,
pageSize: 10
}
})
},
// 重置月报数据
resetMonthData() {
this.monthlyForm = {
month: '',
userid: null,
depId: '',
orgId: '',
current: 1,
pageSize: 10
}
},
// 获得月报表格数据
getMonthTable () {
this.loadMonthTable = true
atdapi.getMonthAttendance({ params: this.monthlyForm }).then(res => {
let tableData = res.data.data
this.monthTableData = []
tableData.forEach(element => {
this.monthTableData.push(element)
})
this.monthlyTotal = res.data.total
}).finally(() => {
this.loadMonthTable = false
})
},
// 获得日报表格数据
getDailyTable () {
this.loadDailyTable = true
atdapi.getDayAttendance({ params: this.dailyForm }).then(res => {
let tableData = res.data.data
this.dailyTableData = []
tableData.forEach(element => {
this.dailyTableData.push(element)
})
this.dailyTotal = res.data.total
}).finally(() => {
this.loadDailyTable = false
})
},
// 弹窗打开
handleClick (data) {
const { userid, beginDay, endDay } = data
if (beginDay == null) {
this.$Message.danger('未识别到有效的起止日期')
return
}
this.loadDetail = true
this.modalData = Object.assign({}, data)
this.attendanceModal = true
this.modalData.range = [beginDay, endDay]
atdapi.getAttendanceDetail({
params: { userid, beginDay, endDay }
}).then(res => {
const { detail } = res.data
this.modalData.detail = detail
}).finally(() => {
this.loadDetail = false
})
},
getStatusClass (status) {
if (status === '未打卡') {
return 'abnormalState'
}
return ''
}
}
}
</script>
<style lang="scss" scoped>
.page-main {
margin: 20px 20px 16px 20px;
.abnormalState {
color: #eda30f;
font-size: 14px;
}
.keep-row {
display: flex;
align-items: center;
margin-left: 24px;
}
.search-btn {
margin-left: auto;
margin-right: 15px;
}
.icon-txt {
margin-right: 8px;
}
.export-excel {
margin-top: 24px;
display: flex;
align-items: center;
}
.table-detail {
margin-top: 20px;
}
.pager {
margin-right: auto;
margin: 21px 21px 0 0;
float: right;
}
}
</style>
|