|
|
|
@ -436,6 +436,8 @@ public function GetOptimalPlan($type, $regnum, $entrustids, $episodeid, $appoint
|
|
|
|
|
|
|
|
|
|
|
|
if ($type === 'full_day') {
|
|
|
|
if ($type === 'full_day') {
|
|
|
|
return $this->doFullDayAssign($startDate, $endDate, $regnum, $entrustids, $episodeid, $appointment_type, $items, $scope, $userDeptId, $occupied_plan_ids);
|
|
|
|
return $this->doFullDayAssign($startDate, $endDate, $regnum, $entrustids, $episodeid, $appointment_type, $items, $scope, $userDeptId, $occupied_plan_ids);
|
|
|
|
|
|
|
|
} elseif ($type === 'same_day_slot') {
|
|
|
|
|
|
|
|
return $this->doSameDaySlotAssign($startDate, $endDate, $regnum, $entrustids, $episodeid, $appointment_type, $items, $scope, $userDeptId, $occupied_plan_ids);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
return $this->doOptimalTimeAssign($startDate, $endDate, $regnum, $entrustids, $episodeid, $appointment_type, $items, $scope, $userDeptId, $occupied_plan_ids);
|
|
|
|
return $this->doOptimalTimeAssign($startDate, $endDate, $regnum, $entrustids, $episodeid, $appointment_type, $items, $scope, $userDeptId, $occupied_plan_ids);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -619,6 +621,125 @@ private function doFullDayAssign($startDate, $endDate, $regnum, $entrustids, $ep
|
|
|
|
return \Yz::Return(true, '获取成功', []);
|
|
|
|
return \Yz::Return(true, '获取成功', []);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 同一天同一时间段分配:所有 item 必须在同一天且同一时间段完成
|
|
|
|
|
|
|
|
private function doSameDaySlotAssign($startDate, $endDate, $regnum, $entrustids, $episodeid, $appointment_type, $items, $scope, $userDeptId, $occupied_plan_ids = [])
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
// 按科室分组
|
|
|
|
|
|
|
|
$deptGroups = $this->groupItemsByDept($items);
|
|
|
|
|
|
|
|
if (empty($deptGroups)) {
|
|
|
|
|
|
|
|
return \Yz::Return(true, '获取成功', []);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$currentDate = clone $startDate;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while ($currentDate <= $endDate) {
|
|
|
|
|
|
|
|
$nowdate = $currentDate->format('Y-m-d');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 收集所有科室在该日期的可用号源
|
|
|
|
|
|
|
|
$allDeptPlans = [];
|
|
|
|
|
|
|
|
$allAssigned = true;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
foreach ($deptGroups as $deptCode => $group) {
|
|
|
|
|
|
|
|
$availablePlans = $this->getAvailablePlansForDate($regnum, $group['entrustids'], $episodeid, $appointment_type, $nowdate, $scope, $userDeptId);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 过滤已占用的号源
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$allDeptPlans[$deptCode] = $availablePlans;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!$allAssigned) {
|
|
|
|
|
|
|
|
$currentDate->modify('+1 day');
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 按时间段分组:提取所有科室共有的时间段
|
|
|
|
|
|
|
|
$slotGroups = [];
|
|
|
|
|
|
|
|
foreach ($allDeptPlans as $deptCode => $plans) {
|
|
|
|
|
|
|
|
foreach ($plans as $plan) {
|
|
|
|
|
|
|
|
$slotKey = $plan->begin_time . '-' . $plan->end_time;
|
|
|
|
|
|
|
|
if (!isset($slotGroups[$slotKey])) {
|
|
|
|
|
|
|
|
$slotGroups[$slotKey] = [];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!isset($slotGroups[$slotKey][$deptCode])) {
|
|
|
|
|
|
|
|
$slotGroups[$slotKey][$deptCode] = [];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
$slotGroups[$slotKey][$deptCode][] = $plan;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 对每个时间段,尝试分配所有项目
|
|
|
|
|
|
|
|
foreach ($slotGroups as $slotKey => $deptPlans) {
|
|
|
|
|
|
|
|
$result = [];
|
|
|
|
|
|
|
|
$allInSlot = true;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
foreach ($deptGroups as $deptCode => $group) {
|
|
|
|
|
|
|
|
if (!isset($deptPlans[$deptCode])) {
|
|
|
|
|
|
|
|
$allInSlot = false;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$availablePlans = $deptPlans[$deptCode];
|
|
|
|
|
|
|
|
$usedCapacity = [];
|
|
|
|
|
|
|
|
$assignedPlans = [];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
foreach ($group['items'] as $item) {
|
|
|
|
|
|
|
|
$assigned = false;
|
|
|
|
|
|
|
|
foreach ($availablePlans as $plan) {
|
|
|
|
|
|
|
|
$planId = $plan->id;
|
|
|
|
|
|
|
|
$remaining = ($plan->count ?? 0) - ($plan->used_count ?? 0);
|
|
|
|
|
|
|
|
$used = $usedCapacity[$planId] ?? 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (($remaining - $used) <= 0) 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) + 1;
|
|
|
|
|
|
|
|
$assignedPlans[] = [
|
|
|
|
|
|
|
|
'resource_name' => $plan->department_resources_name,
|
|
|
|
|
|
|
|
'begin_time' => $plan->begin_time,
|
|
|
|
|
|
|
|
'end_time' => $plan->end_time
|
|
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
$assigned = true;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!$assigned) {
|
|
|
|
|
|
|
|
$allInSlot = false;
|
|
|
|
|
|
|
|
break 2;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ($allInSlot) {
|
|
|
|
|
|
|
|
return \Yz::Return(true, '获取成功', $result);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$currentDate->modify('+1 day');
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return \Yz::Return(true, '获取成功', []);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取指定日期的可用号源(已排序)
|
|
|
|
// 获取指定日期的可用号源(已排序)
|
|
|
|
private function getAvailablePlansForDate($regnum, $entrustids, $episodeid, $appointment_type, $date, $scope, $userDeptId)
|
|
|
|
private function getAvailablePlansForDate($regnum, $entrustids, $episodeid, $appointment_type, $date, $scope, $userDeptId)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|