feat(wms/attendance): 新增考勤检查部门筛选功能,优化跨天排班逻辑与打卡记录批量查询
1. 前端新增部门筛选下拉框,支持按部门筛选员工并自动勾选,优化穿梭框数据映射逻辑 2. 后端实现跨天排班重叠检测机制,正向跨天夜班被反向跨天班覆盖时跳过下班打卡校验 3. 重构打卡记录查询为批量预取模式,通过单次SQL查询提升性能,支持按员工姓名集合和时间范围精确检索 4. 优化考勤检查记录构建逻辑,调整时段时间计算方式,完善全天缺勤状态判断规则
This commit is contained in:
@@ -403,10 +403,20 @@
|
||||
placeholder="请选择结束日期">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="选择部门" prop="dept">
|
||||
<el-select v-model="checkDept" placeholder="请选择部门" @change="handleCheckDeptChange">
|
||||
<el-option
|
||||
v-for="item in departmentList"
|
||||
:key="item.deptName"
|
||||
:label="item.deptName + '(' + item.count + '人)'"
|
||||
:value="item.deptName"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="选择员工" prop="userIds">
|
||||
<el-transfer
|
||||
v-model="selectedUserIds"
|
||||
:data="transferData"
|
||||
:data="checkTransferData"
|
||||
:titles="['待选员工', '已选员工']"
|
||||
filterable
|
||||
filter-placeholder="请输入员工姓名">
|
||||
@@ -499,6 +509,7 @@ export default {
|
||||
departmentList: [],
|
||||
selectedDept: '',
|
||||
currentDeptEmployeeIds: '',
|
||||
checkDept: '',
|
||||
selectedUserIds: [],
|
||||
|
||||
detailRecordsLoading: false,
|
||||
@@ -508,9 +519,18 @@ export default {
|
||||
computed: {
|
||||
transferData() {
|
||||
return this.allEmployees.map(emp => ({
|
||||
key: emp.infoId,
|
||||
key: String(emp.infoId),
|
||||
label: emp.name + '(' + emp.dept + ')'
|
||||
}))
|
||||
},
|
||||
checkTransferData() {
|
||||
if (!this.checkDept) return this.transferData
|
||||
return this.allEmployees
|
||||
.filter(emp => (emp.dept || '未分配部门') === this.checkDept)
|
||||
.map(emp => ({
|
||||
key: String(emp.infoId),
|
||||
label: emp.name + '(' + emp.dept + ')'
|
||||
}))
|
||||
}
|
||||
},
|
||||
created() {
|
||||
@@ -548,15 +568,18 @@ export default {
|
||||
this.allEmployees.forEach(emp => {
|
||||
const deptName = emp.dept || '未分配部门'
|
||||
if (!deptMap[deptName]) {
|
||||
deptMap[deptName] = []
|
||||
deptMap[deptName] = new Set()
|
||||
}
|
||||
deptMap[deptName].add(String(emp.infoId))
|
||||
})
|
||||
this.departmentList = Object.keys(deptMap).map(deptName => {
|
||||
const ids = [...deptMap[deptName]]
|
||||
return {
|
||||
deptName,
|
||||
count: ids.length,
|
||||
empIds: ids.join(',')
|
||||
}
|
||||
deptMap[deptName].push(emp.infoId)
|
||||
})
|
||||
this.departmentList = Object.keys(deptMap).map(deptName => ({
|
||||
deptName,
|
||||
count: deptMap[deptName].length,
|
||||
empIds: deptMap[deptName].join(',')
|
||||
}))
|
||||
if (this.departmentList.length > 0) {
|
||||
this.selectedDept = this.departmentList[0].deptName
|
||||
this.currentDeptEmployeeIds = this.departmentList[0].empIds
|
||||
@@ -841,23 +864,35 @@ export default {
|
||||
startDate: this.dateRangeParams.startDate,
|
||||
endDate: this.dateRangeParams.endDate
|
||||
}
|
||||
this.selectedUserIds = []
|
||||
this.checkDept = this.selectedDept || ''
|
||||
if (this.checkDept) {
|
||||
const dept = this.departmentList.find(d => d.deptName === this.checkDept)
|
||||
this.selectedUserIds = dept ? dept.empIds.split(',') : []
|
||||
} else {
|
||||
this.selectedUserIds = []
|
||||
}
|
||||
},
|
||||
|
||||
cancelCheck() {
|
||||
this.checkOpen = false
|
||||
this.checkForm = { startDate: undefined, endDate: undefined }
|
||||
this.selectedUserIds = []
|
||||
this.checkDept = ''
|
||||
this.$refs['checkForm'] && this.$refs['checkForm'].resetFields()
|
||||
},
|
||||
|
||||
handleCheckDeptChange(deptName) {
|
||||
const dept = this.departmentList.find(d => d.deptName === deptName)
|
||||
this.selectedUserIds = dept ? dept.empIds.split(',') : []
|
||||
},
|
||||
|
||||
submitCheck() {
|
||||
this.$refs["checkForm"].validate(valid => {
|
||||
if (valid) {
|
||||
this.checkLoading = true
|
||||
const params = {
|
||||
...this.checkForm,
|
||||
userIds: this.selectedUserIds.join(',')
|
||||
userIds: this.selectedUserIds
|
||||
}
|
||||
generateAttendanceCheck(params).then(response => {
|
||||
this.$modal.msgSuccess("比对成功")
|
||||
|
||||
Reference in New Issue
Block a user