ebc

index.vue 13KB

    <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>