|
|
|
|
@ -796,11 +796,20 @@ 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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$availablePlans = $this->getAvailablePlansForDate($regnum, [$entrustId], $episodeid, $appointment_type, $nowdate, $scope, $userDeptId);
|
|
|
|
|
|
|
|
|
|
// 过滤已占用的号源
|
|
|
|
|
if (!empty($occupied_plan_ids)) {
|
|
|
|
|
@ -812,15 +821,77 @@ private function doFullDayAssign($startDate, $endDate, $regnum, $entrustids, $ep
|
|
|
|
|
|
|
|
|
|
if (empty($availablePlans)) {
|
|
|
|
|
$allAssigned = false;
|
|
|
|
|
break;
|
|
|
|
|
break 2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$allItemPlans[$item['id']] = $availablePlans;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!$allAssigned) {
|
|
|
|
|
$currentDate->modify('+1 day');
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 尝试分配所有项目到同一天
|
|
|
|
|
$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
|
|
|
|
|
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) {
|
|
|
|
|
foreach ($itemPlans as $plan) {
|
|
|
|
|
$planId = $plan->id;
|
|
|
|
|
$useSeats = $item['use_seats'] ?? 1;
|
|
|
|
|
// 共享项目号源持有者:减去已有共享项目的 max
|
|
|
|
|
@ -853,6 +924,8 @@ private function doFullDayAssign($startDate, $endDate, $regnum, $entrustids, $ep
|
|
|
|
|
$assigned = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!$assigned) {
|
|
|
|
|
$allAssigned = false;
|
|
|
|
|
break 2;
|
|
|
|
|
|