| | |
| | | </div> |
| | | </div> |
| | | <div class="search_thing"> |
| | | <el-button size="mini" type="primary" @click="refreshTable()" |
| | | >查 询</el-button |
| | | <el-button icon="el-icon-search" size="mini" type="primary" @click="refreshTable()">查 询</el-button |
| | | > |
| | | <el-button size="mini" @click="resetQuery">重置</el-button> |
| | | <el-button size="mini" type="primary" @click="openAddAttendanceDialog()">手动新增</el-button> |
| | | <el-button size="mini" type="success" @click="openSyncAttendanceDialog()">同步考勤记录</el-button> |
| | | <el-button icon="el-icon-refresh-left" size="mini" @click="resetQuery">重置</el-button> |
| | | <el-button icon="el-icon-plus" size="mini" type="primary" @click="openAddAttendanceDialog()">手动新增</el-button> |
| | | <el-button icon="el-icon-refresh" size="mini" type="success" @click="openSyncAttendanceDialog()">同步考勤记录</el-button> |
| | | <el-button plain icon="el-icon-download" size="mini" type="primary" @click="openAttendanceRecordDialog()">导出</el-button> |
| | | </div> |
| | | </div> |
| | | <div class="container"> |
| | |
| | | <el-button type="primary" @click="confirmSyncAttendance">确 定</el-button> |
| | | </span> |
| | | </el-dialog> |
| | | <el-dialog |
| | | title="导出考勤记录" |
| | | :visible.sync="attendanceRecordVisible" |
| | | width="40%"> |
| | | <el-row> |
| | | <el-col :span="4"> |
| | | <label>统计维度:</label> |
| | | </el-col> |
| | | <el-col :span="20"> |
| | | <el-radio-group v-model="reportType" size="mini" disabled> |
| | | <el-radio label="YEAR">年度</el-radio> |
| | | <el-radio label="MONTH">月度</el-radio> |
| | | </el-radio-group> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row style="margin-top:20px"> |
| | | <el-col :span="4"> |
| | | <label>统计日期:</label> |
| | | </el-col> |
| | | <el-col :span="20"> |
| | | <el-date-picker |
| | | size="small" |
| | | v-model="reportDateRange" |
| | | style="width:100%" |
| | | @change="changeReportDateRange" |
| | | type="datetimerange" |
| | | value-format="yyyy-MM-dd HH:mm:ss" |
| | | :default-time="['00:00:00','23:59:59']" |
| | | range-separator="至" |
| | | start-placeholder="开始日期" |
| | | end-placeholder="结束日期"> |
| | | </el-date-picker> |
| | | </el-col> |
| | | </el-row> |
| | | <span slot="footer" class="dialog-footer"> |
| | | <el-button @click="attendanceRecordVisible = false">取 消</el-button> |
| | | <el-button :loading="exportLoading" type="primary" @click="exportStaffAttendanceRecords()">确 定</el-button> |
| | | </span> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import StaffClockInRecord from "./components/staffClockInRecord.vue"; |
| | | import {selectAllUser} from '@/api/system/user' |
| | | import {selectUserListByPerformance} from '@/api/system/user' |
| | | import { |
| | | pageAttendanceRecord, |
| | | checkDutyDate, |
| | | saveOrUpdateStaffAttendanceTrackingRecord, |
| | | removeStaffAttendanceTrackingRecord, |
| | | syncAttendanceRecord |
| | | syncAttendanceRecord, |
| | | exportStaffAttendanceRecords |
| | | } from '@/api/performance/attendance' |
| | | import {getDicts} from "@/api/system/dict/data"; |
| | | import dayjs from 'dayjs'; |
| | | import {getTimeRange,isOverOneMonth} from "@/utils/date"; |
| | | import {transformExcel} from '@/utils/file' |
| | | export default { |
| | | name: "Attendance", |
| | | components: { |
| | |
| | | }, |
| | | data() { |
| | | return { |
| | | reportDateRange:[], |
| | | reportType:"MONTH", |
| | | attendanceRecordVisible:false, |
| | | syncDateRange:[], |
| | | syncAttendanceVisible: false, |
| | | exportLoading: false, |
| | | attendanceForm:{ |
| | | workDataId: null, |
| | | offWorkDataId: null, |
| | |
| | | this.selectEnumByCategory() |
| | | this.getUserList() |
| | | this.getTableHeight(); |
| | | this.dateRange = this.getTimeRange() |
| | | this.dateRange = getTimeRange() |
| | | this.resizeHandler = this.debounce(() => { |
| | | this.getTableHeight(); |
| | | }, 200); |
| | |
| | | window.removeEventListener("resize",this.resizeHandler) |
| | | }, |
| | | methods: { |
| | | changeReportDateRange(val){ |
| | | //判断时间区间是否超过一个月 |
| | | if(val && val.length===2){ |
| | | const flag = isOverOneMonth(val[0],val[1]); |
| | | this.reportType = flag?'YEAR':'MONTH' |
| | | } |
| | | }, |
| | | openAttendanceRecordDialog (){ |
| | | this.reportDateRange = getTimeRange() |
| | | this.$nextTick(()=>{ |
| | | this.attendanceRecordVisible = true |
| | | }) |
| | | }, |
| | | //导出考勤记录 |
| | | exportStaffAttendanceRecords(){ |
| | | this.exportLoading = true |
| | | let params = { |
| | | attendanceReportType:this.reportType, |
| | | } |
| | | if (this.reportDateRange && this.reportDateRange.length === 2) { |
| | | params.startDate = this.reportDateRange[0]; |
| | | params.endDate = this.reportDateRange[1]; |
| | | } else { |
| | | params.startDate = ""; |
| | | params.endDate = ""; |
| | | } |
| | | exportStaffAttendanceRecords({...params}).then(res=>{ |
| | | transformExcel(res, "中天耐丝质量考勤汇总.xlsx") |
| | | this.$message.success("导出成功") |
| | | }).catch(error=>{ |
| | | console.error(error) |
| | | }).finally(()=>{ |
| | | this.exportLoading = false |
| | | }) |
| | | }, |
| | | getShiftByDic(e) { |
| | | let obj = this.dailyTypeList.find((m) => m.dictValue == e); |
| | | if (obj) { |
| | |
| | | this.dailyTypeList = response.data; |
| | | }); |
| | | }, |
| | | /** |
| | | * 初始化默认日期范围:近一个月(当前日期 - 30天 至 当前日期) |
| | | */ |
| | | getTimeRange(format = 'YYYY-MM-DD HH:mm:ss') { |
| | | // 获取当前时间 |
| | | const now = dayjs(); |
| | | // 获取当前日期的「日」(1-31) |
| | | const currentDate = now.date(); |
| | | |
| | | let startTime, endTime; |
| | | |
| | | // 核心逻辑:判断当前日期是否大于25号 |
| | | if (currentDate > 25) { |
| | | // ✅ 情况1:当前日>25 → 当月26号 ~ 次月25号 |
| | | startTime = now.startOf('month').add(25, 'day'); // 当月1号 +25天 = 26号 |
| | | endTime = startTime.add(1, 'month').date(25).hour(23) |
| | | .minute(59) |
| | | .second(59); // 次月25号(dayjs自动处理跨年) |
| | | } else { |
| | | // ✅ 情况2:当前日≤25 → 上月26号 ~ 当月25号 |
| | | startTime = now.subtract(1, 'month').startOf('month').add(25, 'day'); // 上月26号 |
| | | endTime = now.date(25).hour(23) |
| | | .minute(59) |
| | | .second(59); // 当月25号 |
| | | } |
| | | |
| | | // 返回格式化后的时间数组 |
| | | return [startTime.format(format), endTime.format(format)]; |
| | | }, |
| | | //同步考勤记录 |
| | | confirmSyncAttendance(){ |
| | | if(!this.syncDateRange || this.syncDateRange.length<2){ |
| | |
| | | }, |
| | | //打开同步考勤记录弹框 |
| | | openSyncAttendanceDialog(){ |
| | | this.syncAttendanceVisible = true |
| | | this.syncDateRange = getTimeRange() |
| | | this.$nextTick(()=>{ |
| | | this.syncAttendanceVisible = true |
| | | }) |
| | | }, |
| | | //删除考勤记录 |
| | | confirmRemoveRecord(row){ |
| | |
| | | }, |
| | | //查询用户列表 |
| | | getUserList(){ |
| | | selectAllUser().then(res=>{ |
| | | selectUserListByPerformance().then(res=>{ |
| | | this.userList = res.data |
| | | }).catch(error=>{ |
| | | console.error(error) |
| | |
| | | }, |
| | | //重置按钮 |
| | | resetQuery() { |
| | | this.dateRange = this.getTimeRange(); |
| | | this.dateRange = getTimeRange(); |
| | | this.queryParams = { |
| | | startDate: "", |
| | | endDate: "", |