From 0a286023c77afa016ce91afb4c7e853148099c22 Mon Sep 17 00:00:00 2001 From: jhd <1684074631@qq.com> Date: Fri, 22 May 2026 15:28:48 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8E=92=E7=8F=AD=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- klp-ui/src/views/wms/hrm/attendance/drag.vue | 499 +++++++++++++++---- 1 file changed, 392 insertions(+), 107 deletions(-) diff --git a/klp-ui/src/views/wms/hrm/attendance/drag.vue b/klp-ui/src/views/wms/hrm/attendance/drag.vue index 01d5ceaf..40b1981f 100644 --- a/klp-ui/src/views/wms/hrm/attendance/drag.vue +++ b/klp-ui/src/views/wms/hrm/attendance/drag.vue @@ -53,45 +53,112 @@ - - - - - - - - - -
-
-
- - {{ item.employeeName || '员工' + (index + 1) }} -
- + +
+ + + + + +
+
+
+ 班次 {{ index + 1 }} + 添加班次 + 删除 +
+
+ + + + + {{ getShiftTime(item.shiftId) }} + + + + +
+
+
+
+
+ + +
+
+
+ {{ getShiftName(item.shiftId) || '未选择班次' }} + + 已分配 {{ item.employeeIds ? item.employeeIds.split(',').filter(id => id.trim()).length : 0 }} 人 + + 复制
- - + +
+
+ + 按部门自动分配 + +
+
+ + +
+ + + + + +
+ 共 {{ totalEmployeeCount }} 名员工,{{ totalScheduleCount }} 条排班记录 +
+
+ + @@ -152,11 +219,12 @@ export default { shiftRuleList: [], dialogVisible: false, editDialogVisible: false, - scheduleMode: 'single', // single: 普通排班, rotate: 倒班排班 + currentStep: 1, // 步骤:1-选择班次,2-分配人员,3-确认 form: { dateRange: [], - selectedEmployees: '', - shiftConfig: [] + shiftList: [ + { shiftId: '', ruleId: '', employeeIds: '' } + ] }, editForm: { shiftId: '' @@ -174,21 +242,52 @@ export default { } }, computed: { - canSubmit() { - if (!this.form.dateRange || this.form.dateRange.length === 0) { - return false - } - if (!this.form.selectedEmployees) { - return false - } - if (this.form.shiftConfig.length === 0) { - return false - } - if (this.scheduleMode === 'single') { - return this.form.shiftConfig.every(item => item.shiftId) - } else { - return this.form.shiftConfig.every(item => item.shiftRuleId) + // 检查是否可以进入下一步 + canProceed() { + if (this.currentStep === 1) { + // 步骤1:必须选择时间段和至少一个有效班次 + if (!this.form.dateRange || this.form.dateRange.length === 0) return false + return this.form.shiftList.some(item => item.shiftId) + } else if (this.currentStep === 2) { + // 步骤2:至少有一个班次分配了人员 + return this.form.shiftList.some(item => item.employeeIds && item.employeeIds.trim()) } + return true + }, + + // 预览数据 + previewData() { + return this.form.shiftList + .filter(item => item.shiftId && item.employeeIds) + .map(item => ({ + shiftName: this.getShiftName(item.shiftId), + employeeNames: this.getEmployeeNames(item.employeeIds), + count: item.employeeIds.split(',').filter(id => id.trim()).length + })) + }, + + // 总员工数 + totalEmployeeCount() { + const allIds = new Set() + this.form.shiftList.forEach(item => { + if (item.employeeIds) { + item.employeeIds.split(',').forEach(id => { + if (id.trim()) allIds.add(id.trim()) + }) + } + }) + return allIds.size + }, + + // 总排班记录数 + totalScheduleCount() { + let count = 0 + this.form.shiftList.forEach(item => { + if (item.employeeIds) { + count += item.employeeIds.split(',').filter(id => id.trim()).length + } + }) + return count }, currentShift() { if (!this.editForm.shiftId) { @@ -529,74 +628,113 @@ export default { // 重置表单 reset() { - this.scheduleMode = 'single' + this.currentStep = 1 this.form = { dateRange: [], - selectedEmployees: '', - shiftConfig: [] + shiftList: [ + { shiftId: '', ruleId: '', employeeIds: '' } + ] } - this.resetForm('form') - }, - - // 员工选择变化时自动生成配置项 - handleEmployeeSelect(employees) { - if (!employees || employees.length === 0) { - this.form.shiftConfig = [] - return - } - - // 为每个选中的员工生成配置项 - if (this.scheduleMode === 'single') { - this.form.shiftConfig = employees.map(employee => ({ - employeeId: employee.infoId, - employeeName: employee.name, - shiftId: null - })) - } else { - this.form.shiftConfig = employees.map(employee => ({ - employeeId: employee.infoId, - employeeName: employee.name, - shiftRuleId: null - })) + if (this.$refs['form']) { + this.$refs['form'].resetFields() } }, - // 排班模式切换 - handleScheduleModeChange() { - // 模式切换时重新生成配置项 - if (this.form.selectedEmployees && this.form.selectedEmployees.length > 0) { - this.handleEmployeeSelect(this.form.selectedEmployees) + // 添加班次配置项 + addShiftItem() { + this.form.shiftList.push({ shiftId: '', ruleId: '', employeeIds: '' }) + }, + + // 移除班次配置项 + removeShiftItem(index) { + this.form.shiftList.splice(index, 1) + }, + + // 复制班次配置(不复制人员) + copyShiftItem(index) { + const source = this.form.shiftList[index] + this.form.shiftList.push({ + shiftId: source.shiftId, + ruleId: source.ruleId, + employeeIds: '' + }) + }, + + // 获取排除的员工ID(避免重复分配) + getExcludedIds(currentIndex) { + const excluded = [] + this.form.shiftList.forEach((item, index) => { + if (index !== currentIndex && item.employeeIds) { + excluded.push(...item.employeeIds.split(',')) + } + }) + return excluded.join(',').trim() + }, + + // 获取班次名称 + getShiftName(shiftId) { + const shift = this.shiftList.find(s => s.shiftId === shiftId) + return shift ? shift.shiftName : '未知班次' + }, + + // 获取员工姓名(临时实现,实际应从API获取) + getEmployeeNames(employeeIds) { + if (!employeeIds) return '未分配' + return employeeIds.split(',').filter(id => id.trim()).length + ' 名员工' + }, + + // 下一步 + nextStep() { + if (this.currentStep < 3) { + this.currentStep++ } }, + // 上一步 + prevStep() { + if (this.currentStep > 1) { + this.currentStep-- + } + }, + + // 按部门自动分配 + quickAssignByDepartment() { + this.$message.info('按部门自动分配功能开发中...') + // 实际实现时可以调用API获取部门员工列表并分配 + }, + // 提交表单 submitForm() { - this.$refs['form'].validate(valid => { - if (valid) { - this.loading = true; - this.buttonLoading = true; - // 构建提交数据 - const list = [] - for (const item of this.form.shiftConfig) { - const payload = { - userId: item.employeeId, - shiftId: item.shiftId, - ruleId: item.shiftRuleId, - startDate: this.dateRangeParams.scheduleDateStart.split(' ')[0], - endDate: this.dateRangeParams.scheduleDateEnd.split(' ')[0] - } - list.push(payload) - } + this.buttonLoading = true - // 调用API - generateenerateSchedule(list).then(response => { - this.$modal.msgSuccess('生成成功') - this.dialogVisible = false - this.loading = false; - this.buttonLoading = false; - this.getScheduleList() + // 构建提交数据 + const list = [] + const startDate = this.form.dateRange[0] + const endDate = this.form.dateRange[1] + + this.form.shiftList.forEach(shiftItem => { + if (!shiftItem.shiftId || !shiftItem.employeeIds) return + + const employeeIds = shiftItem.employeeIds.split(',').filter(id => id.trim()) + employeeIds.forEach(employeeId => { + list.push({ + userId: employeeId, + shiftId: shiftItem.shiftId, + ruleId: shiftItem.ruleId, + startDate: startDate, + endDate: endDate }) - } + }) + }) + + // 调用API + generateenerateSchedule(list).then(response => { + this.$modal.msgSuccess('生成成功') + this.dialogVisible = false + this.buttonLoading = false + this.getScheduleList() + }).catch(() => { + this.buttonLoading = false }) }, @@ -716,4 +854,151 @@ export default { font-size: 12px; color: #606266; } + +/* ===== 优化后的排班弹窗样式 ===== */ + +/* 步骤指示器 */ +.steps { + display: flex; + align-items: center; + justify-content: center; + margin-bottom: 24px; + padding-bottom: 20px; + border-bottom: 1px solid #e4e7ed; +} + +.step { + display: flex; + flex-direction: column; + align-items: center; + min-width: 80px; +} + +.step-number { + width: 32px; + height: 32px; + line-height: 32px; + border-radius: 50%; + background-color: #e4e7ed; + color: #909399; + font-size: 14px; + font-weight: bold; + text-align: center; + transition: all 0.3s; +} + +.step.active .step-number { + background-color: #409eff; + color: #fff; +} + +.step.done .step-number { + background-color: #67c23a; + color: #fff; +} + +.step-text { + margin-top: 8px; + font-size: 13px; + color: #909399; +} + +.step.active .step-text, +.step.done .step-text { + color: #606266; +} + +.step-arrow { + margin: 0 12px; + color: #c0c4cc; + font-size: 16px; +} + +/* 步骤内容 */ +.step-content { + min-height: 200px; +} + +/* 班次配置面板 */ +.shift-config-panel { + margin-top: 12px; +} + +.shift-config-row { + margin-bottom: 16px; + padding: 16px; + background-color: #fafafa; + border-radius: 4px; +} + +.shift-config-header { + display: flex; + align-items: center; + gap: 12px; + margin-bottom: 12px; +} + +.config-label { + font-weight: 600; + color: #606266; +} + +.shift-config-fields { + display: flex; + align-items: center; + gap: 16px; +} + +.shift-time-display { + font-size: 13px; + color: #67c23a; + padding: 4px 8px; + background-color: #f0f9eb; + border-radius: 4px; +} + +/* 班次分配区域 */ +.shift-assignment { + margin-bottom: 20px; + padding: 16px; + background-color: #fafafa; + border-radius: 4px; +} + +.assignment-header { + display: flex; + align-items: center; + gap: 12px; + margin-bottom: 12px; +} + +.assignment-count { + font-size: 13px; + color: #909399; +} + +/* 快速操作按钮 */ +.quick-actions { + margin-top: 16px; + padding-top: 16px; + border-top: 1px dashed #e4e7ed; +} + +/* 预览摘要 */ +.preview-summary { + margin-top: 16px; + padding: 12px; + background-color: #f0f9eb; + border-radius: 4px; + text-align: center; + color: #67c23a; + font-size: 14px; +} + +/* 对话框按钮 */ +.dialog-footer { + display: flex; + justify-content: flex-end; + gap: 12px; +}