diff --git a/Laravel/app/Http/Controllers/API/PdfController.php b/Laravel/app/Http/Controllers/API/PdfController.php index 1c58cb5..9f7f582 100644 --- a/Laravel/app/Http/Controllers/API/PdfController.php +++ b/Laravel/app/Http/Controllers/API/PdfController.php @@ -236,8 +236,12 @@ public function GetCheckPdf() // Dev模式:直接输出PDF,不生成文件 if ($dev == '1') { $pdf = SnappyPdf::loadView('pdf.GroupedCheckPdf', ['groups' => $groups]) - ->setOption('page-size', 'a5') - ->setOption('orientation', 'landscape'); + ->setOption('page-width', '210mm') + ->setOption('page-height', '297mm') + ->setOption('margin-top', '5mm') + ->setOption('margin-bottom', '5mm') + ->setOption('margin-left', '5mm') + ->setOption('margin-right', '5mm'); return $pdf->inline('CheckPdf.pdf'); } @@ -288,10 +292,15 @@ public function GetCheckPdf() $filePath = $fullDir . '/' . $filename; //检查文件是否存在,不存在则生成 + //检查文件是否存在,不存在则生成(打印路径变更时需手动清理旧文件) if (!File::exists($filePath)) { $pdf = SnappyPdf::loadView('pdf.GroupedCheckPdf', ['groups' => $tempGroups]) - ->setOption('page-size', 'a5') - ->setOption('orientation', 'landscape'); + ->setOption('page-width', '210mm') + ->setOption('page-height', '297mm') + ->setOption('margin-top', '5mm') + ->setOption('margin-bottom', '5mm') + ->setOption('margin-left', '5mm') + ->setOption('margin-right', '5mm'); $pdf->save($filePath); } @@ -543,8 +552,12 @@ public function GenerateGroupedCheckPdf() unset($typeGroup, $patient, $room); $pdf = SnappyPdf::loadView('pdf.GroupedCheckPdf', ['groups' => $groups]) - ->setOption('page-size', 'a4') - ->setOption('orientation', 'portrait'); + ->setOption('page-width', '210mm') + ->setOption('page-height', '297mm') + ->setOption('margin-top', '5mm') + ->setOption('margin-bottom', '5mm') + ->setOption('margin-left', '5mm') + ->setOption('margin-right', '5mm'); return $pdf->inline('GenerateGroupedCheckPdf.pdf'); } diff --git a/Laravel/app/Http/Controllers/API/Third/PacsController.php b/Laravel/app/Http/Controllers/API/Third/PacsController.php index e9658cf..c5667fa 100644 --- a/Laravel/app/Http/Controllers/API/Third/PacsController.php +++ b/Laravel/app/Http/Controllers/API/Third/PacsController.php @@ -213,7 +213,26 @@ public function SignIn(){ 'note' => '通知PacS', 'data' => json_encode($pacs_res,JSON_UNESCAPED_UNICODE) ]); - return \Yz::JsonReturn(true,'报道成功',['orderNo'=>$orderNo,'pacs_info'=>$pacs_res]); + + if (!!$pacs_res['status']) { + return \Yz::JsonReturn(true, '报道成功', ['orderNo' => $orderNo, 'pacs_info' => $pacs_res]); + } else { + $data = [ + 'list_status' => 1, + 'check_num' => '', + ]; + $u = DB::table('s_list')->where(['entrust_id' => $orderNo])->update($data); + $i_log = DB::table('s_list_log')->insert([ + 'list_id' => $entrust->id, + 'reg_num' => $entrust->reg_num, + 'old_status' => 2, + 'new_status' => 1, + 'create_user' => 'Pacs接口', + 'note' => '通知Pacs失败', + 'data' => json_encode(['checkNo' => $checkNo], JSON_UNESCAPED_UNICODE) + ]); + return \Yz::JsonReturn(false, '报道失败', ['orderNo' => $orderNo, 'pacs_info' => $pacs_res]); + } }else{ return \Yz::JsonError('报道失败'); } diff --git a/Laravel/app/Services/Admin/YeWu/PlanListService.php b/Laravel/app/Services/Admin/YeWu/PlanListService.php index 749b4a6..1be69a4 100644 --- a/Laravel/app/Services/Admin/YeWu/PlanListService.php +++ b/Laravel/app/Services/Admin/YeWu/PlanListService.php @@ -22,6 +22,7 @@ public function GetEnablePlan($regnum, $entrustids, $episodeid, $appointment_typ $allDevice = [];//所有医嘱检查项目绑定的设备id $commPatientType = [];//所有医嘱共同的病人类型 $zhanweiCount=0;//勾选的检查项目共计占多少名额 + $shareSlotMaxSeats = 0;//共享号源项目的use_seats最大值 $allItemRules = [];//所有检查项目的TIME_RESTRICTION规则 foreach ($entrustids as $key => $entrustid) { // $info = DB::table('s_list')->where(['reg_num' => $regnum, 'entrust_id' => $entrustid, 'episodeid' => $episodeid, 'is_nullify' => 0])->first(); @@ -35,7 +36,11 @@ public function GetEnablePlan($regnum, $entrustids, $episodeid, $appointment_typ $itemInfo = DB::table('s_check_item')->where(['item_name' => $info->entrust, 'status' => 1, "is_del" => 0])->get(); if (count($itemInfo) == 0) return \Yz::echoError1('没有找到可用的检查项目信息'); $itemInfo = $itemInfo[0]; - $zhanweiCount+=isset($itemInfo->use_seats)?$itemInfo->use_seats:0; + if (!empty($itemInfo->is_share_slot)) { + $shareSlotMaxSeats = max($shareSlotMaxSeats, isset($itemInfo->use_seats) ? $itemInfo->use_seats : 0); + } else { + $zhanweiCount += isset($itemInfo->use_seats) ? $itemInfo->use_seats : 0; + } $qudaos = explode(',', $itemInfo->reservation_method); //只判断主渠道,如果主渠道支持,则子渠道默认也支持,即使项目没绑定子渠道 if (!in_array($appointment_type, $qudaos)) return \Yz::echoError1('此检查项目不支持在当前渠道预约'); @@ -64,6 +69,12 @@ public function GetEnablePlan($regnum, $entrustids, $episodeid, $appointment_typ } } + // 共享号源项目合并计算:只取最大值 + if ($shareSlotMaxSeats > 0) { + $zhanweiCount += $shareSlotMaxSeats; + } + $newSharedMax = $shareSlotMaxSeats; + $commonDevice = []; //多个检查项目共同的设备id $first = true; foreach ($allDevice as $set) { @@ -262,6 +273,30 @@ public function GetEnablePlan($regnum, $entrustids, $episodeid, $appointment_typ $pl2 = []; $pp = []; $nowtime = date('Y-m-d H:i:s'); + + // 查询该患者已有共享项目在各排班下的 max + $existingSharedAtPlan = []; + if (!empty($regnum)) { + $existingSharedItems = DB::table('s_list') + ->join('s_check_item', 's_list.entrust', '=', 's_check_item.item_name') + ->where('s_list.reg_num', $regnum) + ->where('s_list.list_status', 1) + ->where('s_list.roster_id', '>', 0) + ->where('s_check_item.is_share_slot', 1) + ->select('s_list.roster_id', 's_check_item.use_seats') + ->get(); + foreach ($existingSharedItems as $esi) { + $pid = $esi->roster_id; + $existingSharedAtPlan[$pid] = max($existingSharedAtPlan[$pid] ?? 0, $esi->use_seats); + } + } + Log::info('[YuYueDebug] GetEnablePlan', [ + 'regnum' => $regnum, + 'zhanweiCount' => $zhanweiCount, + 'newSharedMax' => $newSharedMax, + 'existingSharedAtPlan' => $existingSharedAtPlan, + ]); + foreach ($plan as $key => $p) { // //病人类型不符合的过滤掉 $planPatientType = explode(",", $p->patient_type); @@ -284,7 +319,10 @@ public function GetEnablePlan($regnum, $entrustids, $episodeid, $appointment_typ //过期的排在后面 $time = $p->date . ' ' . $p->end_time; - if ($time > $nowtime) { + $remaining = ($p->count ?? 0) - ($p->used_count ?? 0); + $existingMax = $existingSharedAtPlan[$p->id] ?? 0; + $needed = $zhanweiCount - min($newSharedMax, $existingMax); + if ($time > $nowtime && $remaining >= $needed) { $p->plan_enable=true; $pl1[] = $p; } else { @@ -434,32 +472,84 @@ public function GetOptimalPlan($type, $regnum, $entrustids, $episodeid, $appoint $endDate = new DateTime(); $endDate->modify('+' . $dateRange . ' day'); - // 批量查询每个检查项目的 use_seats + // 批量查询每个检查项目的 use_seats 和 is_share_slot $entrustIds = array_column($items, 'entrust_id'); $useSeatsMap = []; + $shareSlotMap = []; if (!empty($entrustIds)) { - $useSeatsMap = DB::table('s_list') + $itemData = DB::table('s_list') ->join('s_check_item', 's_list.entrust', '=', 's_check_item.item_name') ->whereIn('s_list.entrust_id', $entrustIds) - ->pluck('s_check_item.use_seats', 's_list.entrust_id') - ->toArray(); + ->select('s_list.entrust_id', 's_check_item.use_seats', 's_check_item.is_share_slot') + ->get(); + foreach ($itemData as $row) { + $useSeatsMap[$row->entrust_id] = $row->use_seats; + $shareSlotMap[$row->entrust_id] = $row->is_share_slot ?? 0; + } } foreach ($items as &$item) { $item['use_seats'] = $useSeatsMap[$item['entrust_id']] ?? 1; + $item['is_share_slot'] = $shareSlotMap[$item['entrust_id']] ?? 0; } unset($item); + // 共享号源项目合并计算:只保留最大值,其余设为0 + $shareSlotItems = array_filter($items, function($it) { return !empty($it['is_share_slot']); }); + if (count($shareSlotItems) > 1) { + $maxSeats = 0; + foreach ($shareSlotItems as $it) { + $maxSeats = max($maxSeats, $it['use_seats']); + } + // 找到 use_seats 最高的共享项目,将 max 分配给它 + $maxShareItemIdx = null; + $maxShareSeats = 0; + foreach ($items as $idx => $it) { + if (!empty($it['is_share_slot']) && $it['use_seats'] > $maxShareSeats) { + $maxShareSeats = $it['use_seats']; + $maxShareItemIdx = $idx; + } + } + foreach ($items as &$it) { + if (!empty($it['is_share_slot'])) { + $it['use_seats'] = 0; + } + } + unset($it); + if ($maxShareItemIdx !== null) { + $items[$maxShareItemIdx]['use_seats'] = $maxSeats; + } + } + + // 查询该患者已有共享项目在各排班下的 max + $existingSharedAtPlan = []; + $existingSharedItems = DB::table('s_list') + ->join('s_check_item', 's_list.entrust', '=', 's_check_item.item_name') + ->where('s_list.reg_num', $regnum) + ->where('s_list.list_status', 1) + ->where('s_list.is_nullify', 0) + ->where('s_list.roster_id', '>', 0) + ->where('s_check_item.is_share_slot', 1) + ->select('s_list.roster_id', 's_check_item.use_seats') + ->get(); + foreach ($existingSharedItems as $esi) { + $pid = $esi->roster_id; + if (!isset($existingSharedAtPlan[$pid])) { + $existingSharedAtPlan[$pid] = 0; + } + $existingSharedAtPlan[$pid] = max($existingSharedAtPlan[$pid], $esi->use_seats); + } + 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, $existingSharedAtPlan); } elseif ($type === 'same_day_slot') { - return $this->doSameDaySlotAssign($startDate, $endDate, $regnum, $entrustids, $episodeid, $appointment_type, $items, $scope, $userDeptId, $occupied_plan_ids); + return $this->doSameDaySlotAssign($startDate, $endDate, $regnum, $entrustids, $episodeid, $appointment_type, $items, $scope, $userDeptId, $occupied_plan_ids, $existingSharedAtPlan); } 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, $existingSharedAtPlan); } } // 最优时间分配:按科室分组,逐个 item 找最早可用号源,可跨天 - private function doOptimalTimeAssign($startDate, $endDate, $regnum, $entrustids, $episodeid, $appointment_type, $items, $scope, $userDeptId, $occupied_plan_ids = []) + private function doOptimalTimeAssign($startDate, $endDate, $regnum, $entrustids, $episodeid, $appointment_type, $items, $scope, $userDeptId, $occupied_plan_ids = [], $existingSharedAtPlan = []) { // 按科室分组 $deptGroups = $this->groupItemsByDept($items); @@ -512,6 +602,11 @@ private function doOptimalTimeAssign($startDate, $endDate, $regnum, $entrustids, foreach ($availablePlans 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; @@ -565,7 +660,7 @@ private function doOptimalTimeAssign($startDate, $endDate, $regnum, $entrustids, } // 单天全检分配:所有 item 必须在同一天完成 - private function doFullDayAssign($startDate, $endDate, $regnum, $entrustids, $episodeid, $appointment_type, $items, $scope, $userDeptId, $occupied_plan_ids = []) + private function doFullDayAssign($startDate, $endDate, $regnum, $entrustids, $episodeid, $appointment_type, $items, $scope, $userDeptId, $occupied_plan_ids = [], $existingSharedAtPlan = []) { // 按科室分组 $deptGroups = $this->groupItemsByDept($items); @@ -604,6 +699,11 @@ private function doFullDayAssign($startDate, $endDate, $regnum, $entrustids, $ep foreach ($availablePlans 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; @@ -647,7 +747,7 @@ private function doFullDayAssign($startDate, $endDate, $regnum, $entrustids, $ep } // 同一天同一时间段分配:所有 item 必须在同一天且同一时间段完成 - private function doSameDaySlotAssign($startDate, $endDate, $regnum, $entrustids, $episodeid, $appointment_type, $items, $scope, $userDeptId, $occupied_plan_ids = []) + private function doSameDaySlotAssign($startDate, $endDate, $regnum, $entrustids, $episodeid, $appointment_type, $items, $scope, $userDeptId, $occupied_plan_ids = [], $existingSharedAtPlan = []) { // 按科室分组 $deptGroups = $this->groupItemsByDept($items); @@ -723,6 +823,11 @@ private function doSameDaySlotAssign($startDate, $endDate, $regnum, $entrustids, foreach ($availablePlans 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; @@ -872,6 +977,7 @@ public function YuYue($planid, $appointment_type, $mainlistids, $do_type,$is_eme $zhanweiCount=0;//各个检查项目需要占用检查名额的总和 $itemSeatsQueue = []; // 队列:按顺序存储每个项目需要的座位数 [项目ID => 座位数] + $itemSeatsData = []; // 原始数据:临时收集每个项目的use_seats和is_share_slot $huchiList=[];//互斥item_id对应关系 $oldMainInfos = [];//临时存储原来的主表信息,用于改约 //遍历多个s_list表id,前端多选,一次预约多个检查项目 @@ -908,9 +1014,11 @@ public function YuYue($planid, $appointment_type, $mainlistids, $do_type,$is_eme //判断互斥(暂时根据reg_num判断身份) //查询想要预约的项目 其自身code $item = DB::table('s_check_item')->where(['item_code' => $mainInfo->entrust_code, 'status' => 1, 'is_del' => 0])->first(); - $itemSeatsQueue[$mainlistid]=$item->use_seats; if (!$item) return \Yz::echoError1('此检查项目不可用'); - $zhanweiCount+=$item->use_seats; + $itemSeatsData[$mainlistid] = [ + 'use_seats' => $item->use_seats, + 'is_share_slot' => $item->is_share_slot ?? 0, + ]; //医嘱开具后,预约时间需在设定的等待期之后,单位分钟 $entrust_time = $mainInfo->entrust_date . ' ' . $mainInfo->entrust_time; //医嘱时间 $date = new DateTime($entrust_time); @@ -1024,6 +1132,73 @@ public function YuYue($planid, $appointment_type, $mainlistids, $do_type,$is_eme } + // 共享号源项目合并计算:只保留最大值,其余设为0 + $shareSlotIds = []; + $shareSlotMax = 0; + foreach ($itemSeatsData as $id => $data) { + if (!empty($data['is_share_slot'])) { + $shareSlotIds[] = $id; + $shareSlotMax = max($shareSlotMax, $data['use_seats']); + } + } + + // 查询该排班下已有共享项目的 max + $existingSharedMax = 0; + $additionalNeeded = 0; + $regNum = $oldMainInfos[0]->reg_num ?? null; + if (!empty($shareSlotIds) && $regNum) { + $existingSharedItems = DB::table('s_list') + ->join('s_check_item', 's_list.entrust', '=', 's_check_item.item_name') + ->where('s_list.reg_num', $regNum) + ->where('s_list.roster_id', $planid) + ->where('s_list.list_status', 1) + ->where('s_check_item.is_share_slot', 1) + ->select('s_check_item.use_seats') + ->get(); + if ($existingSharedItems->isNotEmpty()) { + $existingSharedMax = $existingSharedItems->max('use_seats'); + } + $overallMax = max($existingSharedMax, $shareSlotMax); + $additionalNeeded = max(0, $overallMax - $existingSharedMax); + } + + // 找到 use_seats 最高的共享项目,将 max 分配给它 + $maxShareSlotId = null; + $maxShareSeats = 0; + foreach ($itemSeatsData as $id => $data) { + if (!empty($data['is_share_slot']) && $data['use_seats'] > $maxShareSeats) { + $maxShareSeats = $data['use_seats']; + $maxShareSlotId = $id; + } + } + + $zhanweiCount = 0; + foreach ($itemSeatsData as $id => $data) { + if (!empty($data['is_share_slot'])) { + if ($id === $maxShareSlotId) { + $itemSeatsQueue[$id] = $additionalNeeded; + $zhanweiCount += $additionalNeeded; + } else { + $itemSeatsQueue[$id] = 0; + } + } else { + $itemSeatsQueue[$id] = $data['use_seats']; + $zhanweiCount += $data['use_seats']; + } + } + + Log::info('[YuYueDebug] YuYue 预约参数', [ + 'planid' => $planid, + 'mainlistids' => $mainlistids, + 'itemSeatsData' => $itemSeatsData, + 'shareSlotMax' => $shareSlotMax, + 'existingSharedMax' => $existingSharedMax, + 'additionalNeeded' => $additionalNeeded, + 'maxShareSlotId' => $maxShareSlotId, + 'itemSeatsQueue' => $itemSeatsQueue, + 'zhanweiCount' => $zhanweiCount, + ]); + DB::beginTransaction(); try { if ($do_type == 2) { @@ -1167,6 +1342,14 @@ public function YuYue($planid, $appointment_type, $mainlistids, $do_type,$is_eme return \Yz::echoError1('紧急预约失败:未找到匹配的预约渠道配置'); } } + + Log::info('[YuYueDebug] 流分配结果', [ + 'plan_qudao_tempCount' => $plan_qudao_tempCount, + 'weifenpeiCount' => $weifenpeiCount, + 'itemChannelMap' => $itemChannelMap, + 'roster_detail_counts' => array_map(function($c) { return ['id' => $c->id, 'type' => $c->appointment_type_id, 'count' => $c->count, 'used' => $c->used_count, 'locked' => $c->locked_count ?? 0]; }, $roster_detail_counts->toArray()), + ]); + // --- 3. 最终校验 --- if ($weifenpeiCount > 0) { // 如果不是紧急模式,或者紧急模式但没找到渠道导致还有剩余 @@ -1286,11 +1469,27 @@ public function YuYue($planid, $appointment_type, $mainlistids, $do_type,$is_eme 'is_emergency' => $is_emergency ]; + Log::info('[YuYueDebug] 保存预约 detail', [ + 'id' => $id, + 'entrust' => $mainInfo->entrust ?? 'unknown', + 'details' => $details, + 'roster_id' => $planInfo->id, + ]); + $u_mainList = DB::table('s_list')->where('id', $id)->update($u_data); if (!$u_mainList) { $list_all_success = false; break; } + + // 更新后读回确认 + $afterUpdate = DB::table('s_list')->where('id', $id)->value('appointment_use_plan_detail'); + Log::info('[YuYueDebug] 更新后读回', [ + 'id' => $id, + '写入值' => json_encode($details), + '读回值' => $afterUpdate, + 'affected' => $u_mainList, + ]); } if (!$list_all_success) { @@ -1405,6 +1604,14 @@ public function CancelYuYue($MainListId, $reg_num,$do_user=null) ->lockForUpdate() ->first(); + Log::info('[YuYueDebug] CancelYuYue 读取主表', [ + 'MainListId' => $MainListId, + 'entrust' => $mainInfo->entrust ?? 'null', + 'list_status' => $mainInfo->list_status ?? 'null', + 'appointment_use_plan_detail' => $mainInfo->appointment_use_plan_detail ?? 'null', + 'roster_id' => $mainInfo->roster_id ?? 'null', + ]); + if (!$mainInfo) { return \Yz::echoError1('医嘱不存在'); } @@ -1415,6 +1622,12 @@ public function CancelYuYue($MainListId, $reg_num,$do_user=null) $this->releaseSourceFromDetail($MainListId, $mainInfo); + Log::info('[YuYueDebug] CancelYuYue 释放后', [ + 'MainListId' => $MainListId, + 'entrust' => $mainInfo->entrust, + '释放结果' => 'releaseSourceFromDetail 已执行', + ]); + $u_data = [ 'list_status' => 0, 'reservation_date' => null, @@ -1465,6 +1678,135 @@ public function releaseSourceFromDetail($mainListId, $mainInfo = null) } $useDetailJson = $mainInfo->appointment_use_plan_detail; + + Log::info('[YuYueDebug] releaseSourceFromDetail 入口', [ + 'mainListId' => $mainListId, + 'entrust' => $mainInfo->entrust, + 'useDetailJson' => $useDetailJson, + 'reg_num' => $mainInfo->reg_num, + 'roster_id' => $mainInfo->roster_id, + ]); + + // 共享号源逻辑:取消号源持有者时差值释放 + $shareItem = DB::table('s_check_item') + ->where(['item_code' => $mainInfo->entrust_code, 'status' => 1, 'is_del' => 0]) + ->select('is_share_slot', 'use_seats') + ->first(); + $isShareSlot = $shareItem && !empty($shareItem->is_share_slot); + + if ($isShareSlot && !empty($useDetailJson) && $useDetailJson !== '[]') { + // 该共享项目是号源持有者:查询其他同排班同资源的共享项目 + $otherSharedItems = DB::table('s_list') + ->join('s_check_item', 's_list.entrust', '=', 's_check_item.item_name') + ->where('s_list.reg_num', $mainInfo->reg_num) + ->where('s_list.roster_id', $mainInfo->roster_id) + ->where('s_list.id', '!=', $mainListId) + ->where('s_list.list_status', 1) + ->where('s_check_item.is_share_slot', 1) + ->select('s_check_item.use_seats') + ->get(); + + if ($otherSharedItems->isNotEmpty()) { + $remainingMax = $otherSharedItems->max('use_seats'); + if ($remainingMax > 0) { + // 解析当前持有量 + $useDetails = json_decode($useDetailJson, true); + if (!is_array($useDetails)) { + return $this->releaseSourceFallback($mainInfo); + } + $currentCount = 0; + foreach ($useDetails as $d) { + $currentCount += (int)($d['count'] ?? 0); + } + + Log::info('[YuYueDebug] 共享持有者取消', [ + 'mainListId' => $mainListId, + 'entrust' => $mainInfo->entrust, + 'useDetails' => $useDetails, + 'currentCount' => $currentCount, + 'remainingMax' => $remainingMax, + 'otherSharedCount' => $otherSharedItems->count(), + ]); + + // 只释放差值 + $releaseCount = $currentCount - $remainingMax; + if ($releaseCount > 0) { + // 调整 detail 为只释放差值:从原始条目中按顺序扣除 + $adjustedDetail = []; + $remainingToRelease = $releaseCount; + foreach ($useDetails as $d) { + $entryCount = (int)($d['count'] ?? 0); + $take = min($entryCount, $remainingToRelease); + if ($take > 0) { + $adjustedDetail[] = [ + 'roster_detail_count_id' => $d['roster_detail_count_id'], + 'count' => $take + ]; + $remainingToRelease -= $take; + } + } + + // 更新剩余某个共享项目为新持有者 + // 新持有者的 detail = 原始条目中未被释放的剩余部分 + $newHolder = DB::table('s_list') + ->join('s_check_item', 's_list.entrust', '=', 's_check_item.item_name') + ->where('s_list.reg_num', $mainInfo->reg_num) + ->where('s_list.roster_id', $mainInfo->roster_id) + ->where('s_list.id', '!=', $mainListId) + ->where('s_list.list_status', 1) + ->where('s_check_item.is_share_slot', 1) + ->select('s_list.id') + ->first(); + + if ($newHolder) { + // 有可转移的共享项目:只释放差值 + $useDetailJson = json_encode($adjustedDetail); + + $newHolderDetail = []; + $adjustmentIdx = 0; + foreach ($useDetails as $d) { + $entryCount = (int)($d['count'] ?? 0); + // 该条目被释放了多少 + $releasedFromEntry = 0; + if ($adjustmentIdx < count($adjustedDetail) && $adjustedDetail[$adjustmentIdx]['roster_detail_count_id'] == $d['roster_detail_count_id']) { + $releasedFromEntry = $adjustedDetail[$adjustmentIdx]['count']; + $adjustmentIdx++; + } + $remainingInEntry = $entryCount - $releasedFromEntry; + if ($remainingInEntry > 0) { + $newHolderDetail[] = [ + 'roster_detail_count_id' => $d['roster_detail_count_id'], + 'count' => $remainingInEntry + ]; + } + } + DB::table('s_list') + ->where('id', $newHolder->id) + ->update(['appointment_use_plan_detail' => json_encode($newHolderDetail)]); + } + // 没有可转移的共享项目:不修改 useDetailJson,正常释放逻辑释放全部 + } else { + // currentCount <= remainingMax,按实际占用量正常释放全部 + // 不修改 useDetailJson,让正常释放逻辑处理 + } + } + // remainingMax == 0:正常释放全部 + } + // 没有其他共享项目:正常释放全部 + } + + Log::info('[YuYueDebug] 进入正常释放逻辑', [ + 'mainListId' => $mainListId, + 'entrust' => $mainInfo->entrust, + 'useDetailJson' => $useDetailJson, + 'isShareSlot' => $isShareSlot ? 'true' : 'false', + ]); + + if ($isShareSlot && empty($useDetailJson)) { + // 共享项目但不是号源持有者,不释放号源 + return true; + } + if (empty($useDetailJson)) { $fallbackResult = $this->releaseSourceFallback($mainInfo); return $fallbackResult; @@ -1505,6 +1847,15 @@ public function releaseSourceFromDetail($mainListId, $mainInfo = null) 'updated_at' => date('Y-m-d H:i:s') ]); + Log::info('[YuYueDebug] 释放号源', [ + 'mainListId' => $mainListId, + 'entrust' => $mainInfo->entrust, + 'rosterDetailCountId' => $rosterDetailCountId, + 'countToRelease' => $countToRelease, + 'currentVersion' => $currentVersion, + 'affected' => $affected, + ]); + if ($affected == 0) { $retryRecord = DB::table('s_source_roster_detail_count')->where(['id' => $rosterDetailCountId])->first(); if (!$retryRecord) { @@ -1543,6 +1894,12 @@ public function releaseSourceFromDetail($mainListId, $mainInfo = null) } } + Log::info('[YuYueDebug] releaseSourceFromDetail 返回', [ + 'mainListId' => $mainListId, + 'entrust' => $mainInfo->entrust, + 'allSuccess' => $allSuccess ? 'true' : 'false', + ]); + return $allSuccess; } diff --git a/Laravel/resources/views/pdf/GroupedCheckPdf.blade.php b/Laravel/resources/views/pdf/GroupedCheckPdf.blade.php index 1388b3b..fc971f9 100644 --- a/Laravel/resources/views/pdf/GroupedCheckPdf.blade.php +++ b/Laravel/resources/views/pdf/GroupedCheckPdf.blade.php @@ -4,24 +4,32 @@
| 姓名:{{ $patient['patient_name'] }} | -性别:{{ $patient['user_sex_label'] }} | -年龄:{{ $patient['age'] }} | -病人类型:{{ $patient['patient_type_label'] }} | +姓 名:{{ $patient['patient_name'] }} | +性 别:{{ $patient['user_sex_label'] }} | +年 龄:{{ $patient['age'] }} | +病人类型:{{ $patient['patient_type_label'] }} | ||||
| {{ $patient['patient_type_label'] }}号:{{ $patient['patient_id'] }} | +{{ $patient['patient_type_label'] }}号:{{ $patient['patient_id'] }} | @if ($patient['patient_type'] == 0) -病区:{{ $patient['warddesc'] }} | -床号:{{ $patient['bedno'] }} | -联系电话:{{ $patient['user_phone'] }} | +病 区:{{ $patient['warddesc'] }} | +床 号:{{ $patient['bedno'] }} | +联系电话:{{ $patient['user_phone'] }} | @else -联系电话:{{ $patient['user_phone'] }} | +联系电话:{{ $patient['user_phone'] }} | @endif @@ -63,32 +71,32 @@ |
| 检查项目: | -{{ $room['items_str'] }} | +检查项目: | +{{ $room['items_str'] }} |
| 预约时间: | -{{ str_replace('-', '/', $room['reservation_date']) }} + | 预约时间: | +{{ str_replace('-', '/', $room['reservation_date']) }} @if ($room['period_begin'] && $room['period_end']) {{ $room['period_begin'] }}-{{ $room['period_end'] }} @endif {{ $room['weekday_label'] }} |
| 检查地点: | -{{ $room['room_addr'] }} | +检查地点: | +{{ $room['room_addr'] }} |
| 温馨提示: | -+ | 温馨提示: | +
1、预约后请您及时缴费,门诊患者预约成功后60分钟内不缴费,系统会自动取消您的预约申请。自动取消后,如需继续预约,请到相关检查科室重新预约。
2、预约时间为8点~10点的,请8点到登记处签到,预约时间为10点~12点的,请10点前到登记处签到,便于工作人员进行检查评估和准备。
3、预约时间不是实际检查时间,以现场登记后排队号为准。
@@ -97,10 +105,10 @@
|
| 姓名:{{printInfo.user_name}} | 性别:{{printInfo.user_sex_label}} | @@ -28,7 +28,7 @@
| 温馨提示: | -+ | 温馨提示: | +
1、预约后请您及时缴费,门诊患者预约成功后60分钟内不缴费,系统会自动取消您的预约申请。自动取消后,如需继续预约,请到相关检查科室重新预约。
2、预约时间为8点~10点的,请8点到登记处签到,预约时间为10点~12点的,请10点前到登记处签到,便于工作人员进行检查评估和准备。
3、预约时间不是实际检查时间,以现场登记后排队号为准。
@@ -49,12 +49,12 @@
|
| @@ -128,11 +129,12 @@ |
| @@ -128,11 +129,12 @@ |