| | |
| | | :key="'d' + i"> |
| | | <el-dropdown trigger="click" |
| | | placement="bottom" |
| | | @command="(e) => handleCommand(e, m)" |
| | | :disabled="isCellBlockedByLeaveDate(item, m)" |
| | | @command="(e) => handleCommand(e, item, m)" |
| | | class="shift-dropdown"> |
| | | <div class="shift-box" |
| | | :class="{ |
| | |
| | | update, |
| | | staffOnJobListPage, |
| | | } from "@/api/personnelManagement/class"; |
| | | import { findStaffLeaveListPage } from "@/api/personnelManagement/staffLeave.js"; |
| | | import { deptTreeSelect } from "@/api/system/user.js"; |
| | | import { getAttendanceRules } from "@/api/personnelManagement/attendanceRules.js"; |
| | | import { useDict } from "@/utils/dict"; |
| | |
| | | // 人员列表 |
| | | const personList = ref([]); |
| | | const personListAll = ref([]); |
| | | const leaveDateMap = ref({}); |
| | | |
| | | // 加载状态 |
| | | const loading = ref(false); |
| | |
| | | proxy.$modal.msgError("请选择班次"); |
| | | return; |
| | | } |
| | | const blockedEmployees = (personList.value || []).filter(item => { |
| | | const leaveDate = getEmployeeLeaveDate(item?.id); |
| | | const weekEndDate = getSchedulingWeekEndDate(); |
| | | return leaveDate && weekEndDate && weekEndDate.getTime() > leaveDate.getTime(); |
| | | }); |
| | | if (blockedEmployees.length) { |
| | | proxy.$modal.msgError("存在已超过离职日期的人员,不能继续排班"); |
| | | return; |
| | | } |
| | | loading.value = true; |
| | | add({ |
| | | startWeek, |
| | |
| | | }); |
| | | }; |
| | | // 处理命令 |
| | | const handleCommand = (e, m) => { |
| | | const handleCommand = (e, row, cell) => { |
| | | if (isCellBlockedByLeaveDate(row, cell)) { |
| | | proxy.$modal.msgError("该员工已超出离职日期,不能继续排班"); |
| | | return; |
| | | } |
| | | // if (e != m.shift) { |
| | | update({ |
| | | id: m.id, |
| | | id: cell.id, |
| | | personalAttendanceLocationConfigId: e, |
| | | }).then(res => { |
| | | proxy.$modal.msgSuccess("操作成功"); |
| | |
| | | }); |
| | | }; |
| | | |
| | | const getLeaveDates = () => { |
| | | findStaffLeaveListPage({ |
| | | current: -1, |
| | | size: -1, |
| | | }).then(res => { |
| | | const records = Array.isArray(res?.data?.records) ? res.data.records : []; |
| | | const map = {}; |
| | | records.forEach(item => { |
| | | const staffId = item?.staffOnJobId ?? item?.staff_on_job_id; |
| | | const leaveDate = item?.leaveDate ?? item?.leave_date; |
| | | if (!staffId || !leaveDate) return; |
| | | const key = String(staffId); |
| | | const prev = map[key]; |
| | | if (!prev || String(leaveDate) > String(prev)) { |
| | | map[key] = leaveDate; |
| | | } |
| | | }); |
| | | leaveDateMap.value = map; |
| | | updatePersonListByDept(); |
| | | syncPersonListSelection(); |
| | | }); |
| | | }; |
| | | |
| | | const findDeptNodeById = (deptId, deptList = deptOptions.value) => { |
| | | const list = Array.isArray(deptList) ? deptList : []; |
| | | for (const node of list) { |
| | |
| | | const deptIds = new Set(collectDeptIds(node)); |
| | | personList.value = (personListAll.value || []).filter(item => { |
| | | const itemDeptId = item.deptId ?? item.sysDeptId ?? item.dept_id; |
| | | return deptIds.has(String(itemDeptId)); |
| | | return deptIds.has(String(itemDeptId)) && !isEmployeeBlockedByLeaveDate(item); |
| | | }); |
| | | }; |
| | | |
| | | const parseDateOnly = value => { |
| | | if (!value) return null; |
| | | if (value instanceof Date) { |
| | | const d = new Date(value); |
| | | d.setHours(0, 0, 0, 0); |
| | | return d; |
| | | } |
| | | const normalized = String(value).trim().slice(0, 10); |
| | | if (!normalized) return null; |
| | | const d = new Date(normalized.replace(/-/g, "/")); |
| | | if (Number.isNaN(d.getTime())) return null; |
| | | d.setHours(0, 0, 0, 0); |
| | | return d; |
| | | }; |
| | | |
| | | const getSchedulingWeekEndDate = () => { |
| | | if (!schedulingQuery.week) return null; |
| | | const start = new Date(schedulingQuery.week); |
| | | start.setHours(0, 0, 0, 0); |
| | | return new Date(start.getTime() + 24 * 60 * 60 * 1000 * 5); |
| | | }; |
| | | |
| | | const getCellDate = cell => parseDateOnly(cell?.time); |
| | | |
| | | const getEmployeeLeaveDate = staffId => { |
| | | const leaveDate = leaveDateMap.value[String(staffId)]; |
| | | return parseDateOnly(leaveDate); |
| | | }; |
| | | |
| | | const isEmployeeBlockedByLeaveDate = item => { |
| | | const leaveDate = getEmployeeLeaveDate(item?.id); |
| | | if (!leaveDate) return false; |
| | | const weekEndDate = getSchedulingWeekEndDate(); |
| | | if (!weekEndDate) return false; |
| | | return weekEndDate.getTime() > leaveDate.getTime(); |
| | | }; |
| | | |
| | | const isCellBlockedByLeaveDate = (row, cell) => { |
| | | const staffId = row?.userId ?? row?.user_id ?? row?.id; |
| | | const leaveDate = getEmployeeLeaveDate(staffId); |
| | | const cellDate = getCellDate(cell); |
| | | if (!leaveDate || !cellDate) return false; |
| | | return cellDate.getTime() > leaveDate.getTime(); |
| | | }; |
| | | |
| | | const syncPersonListSelection = () => { |
| | | if (!Array.isArray(schedulingQuery.userId) || !schedulingQuery.userId.length) return; |
| | | const validIds = new Set((personList.value || []).map(item => String(item.id))); |
| | | const nextIds = schedulingQuery.userId.filter(id => validIds.has(String(id))); |
| | | if (nextIds.length !== schedulingQuery.userId.length) { |
| | | schedulingQuery.userId = nextIds; |
| | | proxy.$modal.msgWarning("已自动剔除超出离职日期的人员"); |
| | | } |
| | | }; |
| | | |
| | | const setDefaultShiftByDept = () => { |
| | |
| | | onMounted(() => { |
| | | fetchData(); |
| | | getUsers(); |
| | | getLeaveDates(); |
| | | fetchDeptOptions(); |
| | | if (query.month) { |
| | | init(); |
| | |
| | | ); |
| | | |
| | | watch( |
| | | () => schedulingQuery.week, |
| | | () => { |
| | | if (!schedulingVisible.value) return; |
| | | updatePersonListByDept(); |
| | | syncPersonListSelection(); |
| | | } |
| | | ); |
| | | |
| | | watch( |
| | | () => schedulingQuery.deptId, |
| | | () => { |
| | | if (!schedulingVisible.value) return; |
| | | updatePersonListByDept(); |
| | | syncPersonListSelection(); |
| | | } |
| | | ); |
| | | |
| | | watch( |
| | | () => schedulingVisible.value, |
| | | val => { |
| | | if (!val) return; |