From 387dfb80c2666a2eddfdfc128211ed5adf441560 Mon Sep 17 00:00:00 2001 From: sa0ChunLuyu Date: Fri, 7 Aug 2026 12:25:18 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8E=A8=E8=8D=90=E5=8F=B7=E6=BA=90=E9=80=BB?= =?UTF-8?q?=E8=BE=91=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Services/Admin/YeWu/PlanListService.php | 103 +++++++++++++++--- 1 file changed, 88 insertions(+), 15 deletions(-) diff --git a/Laravel/app/Services/Admin/YeWu/PlanListService.php b/Laravel/app/Services/Admin/YeWu/PlanListService.php index 6aab764..cdf499e 100644 --- a/Laravel/app/Services/Admin/YeWu/PlanListService.php +++ b/Laravel/app/Services/Admin/YeWu/PlanListService.php @@ -796,31 +796,66 @@ private function doFullDayAssign($startDate, $endDate, $regnum, $entrustids, $ep while ($currentDate <= $endDate) { $nowdate = $currentDate->format('Y-m-d'); + + // 收集所有项目在该日期的可用排班(各自独立查询,避免设备交集过滤) + $allItemPlans = []; // item_id => [available plans] $allAssigned = true; - $result = []; foreach ($deptGroups as $deptCode => $group) { - $availablePlans = $this->getAvailablePlansForDate($regnum, $group['entrustids'], $episodeid, $appointment_type, $nowdate, $scope, $userDeptId); + foreach ($group['items'] as $item) { + $entrustId = $item['entrust_id'] ?? null; + if (!$entrustId) { + $allAssigned = false; + break 2; + } - // 过滤已占用的号源 - if (!empty($occupied_plan_ids)) { - $availablePlans = array_filter($availablePlans, function($plan) use ($occupied_plan_ids) { - return !in_array($plan->id, $occupied_plan_ids); - }); - $availablePlans = array_values($availablePlans); - } + $availablePlans = $this->getAvailablePlansForDate($regnum, [$entrustId], $episodeid, $appointment_type, $nowdate, $scope, $userDeptId); - if (empty($availablePlans)) { - $allAssigned = false; - break; + // 过滤已占用的号源 + if (!empty($occupied_plan_ids)) { + $availablePlans = array_filter($availablePlans, function($plan) use ($occupied_plan_ids) { + return !in_array($plan->id, $occupied_plan_ids); + }); + $availablePlans = array_values($availablePlans); + } + + if (empty($availablePlans)) { + $allAssigned = false; + break 2; + } + + $allItemPlans[$item['id']] = $availablePlans; } + } + + if (!$allAssigned) { + $currentDate->modify('+1 day'); + continue; + } - $usedCapacity = []; - $assignedPlans = []; + // 尝试分配所有项目到同一天 + $result = []; + $usedCapacity = []; + $assignedPlans = []; + $allAssigned = true; + foreach ($deptGroups as $deptCode => $group) { foreach ($group['items'] as $item) { + $itemPlans = $allItemPlans[$item['id']] ?? []; $assigned = false; - foreach ($availablePlans as $plan) { + + // 第一轮:优先分配不同时间段 + foreach ($itemPlans as $plan) { + // 跳过已分配的时间段 + $slotTaken = false; + foreach ($assignedPlans as $ap) { + if ($ap['begin_time'] === $plan->begin_time && $ap['end_time'] === $plan->end_time) { + $slotTaken = true; + break; + } + } + if ($slotTaken) continue; + $planId = $plan->id; $useSeats = $item['use_seats'] ?? 1; // 共享项目号源持有者:减去已有共享项目的 max @@ -853,6 +888,44 @@ private function doFullDayAssign($startDate, $endDate, $regnum, $entrustids, $ep $assigned = true; break; } + + // 第二轮:回退到同时间段 + if (!$assigned) { + foreach ($itemPlans as $plan) { + $planId = $plan->id; + $useSeats = $item['use_seats'] ?? 1; + // 共享项目号源持有者:减去已有共享项目的 max + if (!empty($item['is_share_slot']) && $useSeats > 0) { + $existingMax = $existingSharedAtPlan[$planId] ?? 0; + $useSeats = max(0, $useSeats - $existingMax); + } + $remaining = ($plan->count ?? 0) - ($plan->used_count ?? 0); + $used = $usedCapacity[$planId] ?? 0; + + if (($remaining - $used) < $useSeats) continue; + + // 冲突检查:同一科室组内,不同排班时间不能重叠 + if ($this->isTimeConflict($assignedPlans, $plan)) continue; + + $result[] = [ + 'id' => $item['id'], + 'plan_id' => $planId, + 'department_resources_name' => $plan->department_resources_name, + 'date' => $plan->date, + 'begin_time' => $plan->begin_time, + 'end_time' => $plan->end_time + ]; + $usedCapacity[$planId] = ($usedCapacity[$planId] ?? 0) + $useSeats; + $assignedPlans[] = [ + 'resource_name' => $plan->department_resources_name, + 'begin_time' => $plan->begin_time, + 'end_time' => $plan->end_time + ]; + $assigned = true; + break; + } + } + if (!$assigned) { $allAssigned = false; break 2;