diff --git a/Laravel/app/Http/Controllers/API/Admin/YeWu/WorkMainController.php b/Laravel/app/Http/Controllers/API/Admin/YeWu/WorkMainController.php index a6d467e..5797c76 100644 --- a/Laravel/app/Http/Controllers/API/Admin/YeWu/WorkMainController.php +++ b/Laravel/app/Http/Controllers/API/Admin/YeWu/WorkMainController.php @@ -399,21 +399,36 @@ public function CheckIsDaiJian() { $reg_num= request('reg_num'); $planid=request('planid'); + + $plan=DB::table('s_source_roster_detail')->where(['id'=>$planid])->first(); + if(!$plan) return \Yz::JsonReturn(true,'可以预约',[]); + + $planTime=[$plan->date.' '.$plan->begin_time,$plan->date.' '.$plan->end_time]; + $query=DB::table('s_list')->where(['reg_num'=>$reg_num,'list_status'=>1,'is_nullify'=>0]) - ->select('s_list.*','s_period.period_begin_time','s_period.period_end_time') + ->select('s_list.*','s_period.period_begin_time','s_period.period_end_time','s_department_resources.department_resources_name') ->leftJoin('s_period','s_list.reservation_time','=','s_period.id') + ->leftJoin('s_department_resources','s_list.reservation_sources','=','s_department_resources.id') ->get(); - if(count($query)>0){ - $plan=DB::table('s_source_roster_detail')->where(['id'=>$planid])->first(); - foreach ($query as $key=>$value){ - $entrustTime=[$value->reservation_date.' '.$value->period_begin_time,$value->reservation_date.' '.$value->period_end_time]; - $planTime=[$plan->date.' '.$plan->begin_time,$plan->date.' '.$plan->end_time]; - if ($entrustTime[0] <= $planTime[1] && $planTime[0] <= $entrustTime[1]) { - return \Yz::echoError1('当前时段存在待检项目:'.$value->entrust.',时间:'.$value->reservation_date.' '.substr($value->period_begin_time, 0, 5).'-'.substr($value->period_end_time, 0, 5).' 请确认是否继续预约'); - } + + $conflicts = []; + foreach ($query as $value){ + $entrustTime=[$value->reservation_date.' '.$value->period_begin_time,$value->reservation_date.' '.$value->period_end_time]; + if ($entrustTime[0] <= $planTime[1] && $planTime[0] <= $entrustTime[1]) { + $conflicts[] = [ + 'entrust' => $value->entrust, + 'date' => $value->reservation_date, + 'begin_time' => substr($value->period_begin_time, 0, 5), + 'end_time' => substr($value->period_end_time, 0, 5), + 'room_name' => $value->department_resources_name ?? '', + ]; } } - return \Yz::Return(true,'可以预约',[]); + + if (!empty($conflicts)) { + return \Yz::JsonReturn(false, '存在时段冲突', ['conflicts' => $conflicts]); + } + return \Yz::JsonReturn(true,'可以预约',[]); } public function NoPayCancel() { diff --git a/Laravel/app/Services/Admin/YeWu/PlanListService.php b/Laravel/app/Services/Admin/YeWu/PlanListService.php index 6441d34..a0bb3d3 100644 --- a/Laravel/app/Services/Admin/YeWu/PlanListService.php +++ b/Laravel/app/Services/Admin/YeWu/PlanListService.php @@ -466,6 +466,7 @@ private function doOptimalTimeAssign($startDate, $endDate, $regnum, $entrustids, while ($currentDate <= $endDate && !empty($remainingGroups)) { $nowdate = $currentDate->format('Y-m-d'); $newRemainingGroups = []; + $globalAssignedPlans = []; // 跨科室组的全局已分配时间段 foreach ($remainingGroups as $deptCode => $group) { $groupEntrustids = $group['entrustids']; @@ -502,6 +503,8 @@ private function doOptimalTimeAssign($startDate, $endDate, $regnum, $entrustids, // 冲突检查:同一科室组内,不同排班时间不能重叠 if ($this->isTimeConflict($assignedPlans, $plan)) continue; + // 冲突检查:跨科室组,时间段不能重叠 + if ($this->isTimeConflict($globalAssignedPlans, $plan)) continue; $result[] = [ 'id' => $item['id'], @@ -517,6 +520,11 @@ private function doOptimalTimeAssign($startDate, $endDate, $regnum, $entrustids, 'begin_time' => $plan->begin_time, 'end_time' => $plan->end_time ]; + $globalAssignedPlans[] = [ + 'resource_name' => $plan->department_resources_name, + 'begin_time' => $plan->begin_time, + 'end_time' => $plan->end_time + ]; $assigned = true; break; } diff --git a/YiJi-admin/src/components/Yewu/YuYue202506.vue b/YiJi-admin/src/components/Yewu/YuYue202506.vue index c6fd871..72e04e2 100644 --- a/YiJi-admin/src/components/Yewu/YuYue202506.vue +++ b/YiJi-admin/src/components/Yewu/YuYue202506.vue @@ -179,6 +179,22 @@ 确定 + + + + + + + + 以下项目与当前选择的时间段存在冲突,请确认是否继续预约: + + + + + + 确定 + + @@ -276,6 +292,8 @@ let crossTimeDialogVisible = ref(false) let crossTimeDialogHtml = ref('') let cachedCrossDialogData = ref(null) // 缓存跨时段 dialog 数据:{ html, idx } + let conflictDialogVisible = ref(false) + let conflictDialogHtml = ref('') let resultDialogVisible = ref(false) let resultDialogHtml = ref('') const getWeekday = (date1) => { @@ -1231,28 +1249,67 @@ } const checkDaijianFuc = () => { planLoading.value = true + + // 获取当前选中排班的时间信息 + const selectedPlan = cachedPlans.value.find(p => p.id === selectedPlanId.value) + if (!selectedPlan) { + planLoading.value = false + return + } + const planStart = selectedPlan.date + ' ' + selectedPlan.begin_time + const planEnd = selectedPlan.date + ' ' + selectedPlan.end_time + const currentRoom = selectedPlan.department_resources_name + CheckIsDaiJian({ reg_num: props.reg_num, planid: selectedPlanId.value }).then(res => { planLoading.value = false - if (res.status) { + let allConflicts = [] - } else { - ElMessageBox.confirm( - res.msg, - '提示', { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning', - } - ) - .then(() => { + // ① 后端返回的已预约冲突(过滤同检查室) + if (!res.status && res.data?.conflicts) { + allConflicts = allConflicts.concat( + res.data.conflicts.filter(c => c.room_name !== currentRoom) + ) + } - }) - .catch(() => { + // ② 前端临时匹配的冲突(过滤同检查室) + entrustTableDate.value.forEach(item => { + if (item.list_status !== 0 || !item.temp_plan_id || !item.reservation_date) return + const itemRoom = item.department_resources?.department_resources_name + if (itemRoom === currentRoom) return // 同检查室允许重叠 + const itemStart = item.reservation_date + ' ' + item.period_begin_time + const itemEnd = item.reservation_date + ' ' + item.period_end_time + if (itemStart <= planEnd && planStart <= itemEnd) { + const exists = allConflicts.some(c => + c.entrust === item.entrust && c.date === item.reservation_date + ) + if (!exists) { + allConflicts.push({ + entrust: item.entrust, + date: item.reservation_date, + begin_time: item.period_begin_time?.substring(0, 5), + end_time: item.period_end_time?.substring(0, 5), + room_name: item.department_resources?.department_resources_name || '', + }) + } + } + }) - }) + // ③ 展示冲突(使用独立 dialog) + if (allConflicts.length > 0) { + let msg = '' + msg += '序号项目名称检查室日期时间段' + allConflicts.forEach((c, i) => { + msg += '' + (i + 1) + '' + c.entrust + '' + (c.room_name || '') + '' + c.date + '' + c.begin_time + '-' + c.end_time + '' + }) + msg += '' + conflictDialogHtml.value = msg + conflictDialogVisible.value = true + } else { + // 无冲突,继续预约流程 + // 由调用方处理 } }) }
+ 以下项目与当前选择的时间段存在冲突,请确认是否继续预约: +