|
|
|
|
@ -1201,10 +1201,16 @@ public function YuYue($planid, $appointment_type, $mainlistids, $do_type,$is_eme
|
|
|
|
|
|
|
|
|
|
DB::beginTransaction();
|
|
|
|
|
try {
|
|
|
|
|
// 改约时提前记录旧排班 ID,在 s_list 更新后校正
|
|
|
|
|
$oldRosterIds = [];
|
|
|
|
|
if ($do_type == 2) {
|
|
|
|
|
foreach ($oldMainInfos as $oldMainInfo) {
|
|
|
|
|
$this->releaseSourceFromDetail($oldMainInfo->id, $oldMainInfo);
|
|
|
|
|
if ($oldMainInfo->roster_id) {
|
|
|
|
|
$oldRosterIds[] = $oldMainInfo->roster_id;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
$oldRosterIds = array_unique($oldRosterIds);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//查询号源渠道是否有合并
|
|
|
|
|
@ -1272,10 +1278,12 @@ public function YuYue($planid, $appointment_type, $mainlistids, $do_type,$is_eme
|
|
|
|
|
while ($remainingInChannel > 0 && $currentItemId !== null) {
|
|
|
|
|
$take = min($currentItemRemaining, $remainingInChannel);
|
|
|
|
|
|
|
|
|
|
if (!isset($itemChannelMap[$currentItemId][$channelId])) {
|
|
|
|
|
$itemChannelMap[$currentItemId][$channelId] = 0;
|
|
|
|
|
if ($take > 0) {
|
|
|
|
|
if (!isset($itemChannelMap[$currentItemId][$channelId])) {
|
|
|
|
|
$itemChannelMap[$currentItemId][$channelId] = 0;
|
|
|
|
|
}
|
|
|
|
|
$itemChannelMap[$currentItemId][$channelId] += $take;
|
|
|
|
|
}
|
|
|
|
|
$itemChannelMap[$currentItemId][$channelId] += $take;
|
|
|
|
|
|
|
|
|
|
$currentItemRemaining -= $take;
|
|
|
|
|
$remainingInChannel -= $take;
|
|
|
|
|
@ -1313,10 +1321,12 @@ public function YuYue($planid, $appointment_type, $mainlistids, $do_type,$is_eme
|
|
|
|
|
while ($remainingEmergency > 0 && $currentItemId !== null) {
|
|
|
|
|
$take = min($currentItemRemaining, $remainingEmergency);
|
|
|
|
|
|
|
|
|
|
if (!isset($itemChannelMap[$currentItemId][$targetChannelId])) {
|
|
|
|
|
$itemChannelMap[$currentItemId][$targetChannelId] = 0;
|
|
|
|
|
if ($take > 0) {
|
|
|
|
|
if (!isset($itemChannelMap[$currentItemId][$targetChannelId])) {
|
|
|
|
|
$itemChannelMap[$currentItemId][$targetChannelId] = 0;
|
|
|
|
|
}
|
|
|
|
|
$itemChannelMap[$currentItemId][$targetChannelId] += $take;
|
|
|
|
|
}
|
|
|
|
|
$itemChannelMap[$currentItemId][$targetChannelId] += $take;
|
|
|
|
|
|
|
|
|
|
$currentItemRemaining -= $take;
|
|
|
|
|
$remainingEmergency -= $take;
|
|
|
|
|
@ -1452,6 +1462,23 @@ public function YuYue($planid, $appointment_type, $mainlistids, $do_type,$is_eme
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 共享非持有者:使用项目的 use_seats 写入 detail,校正时自动计算总占位
|
|
|
|
|
$allZero = true;
|
|
|
|
|
foreach ($details as $d) {
|
|
|
|
|
if (($d['count'] ?? 0) > 0) { $allZero = false; break; }
|
|
|
|
|
}
|
|
|
|
|
if ($allZero && isset($itemSeatsData[$id]) && !empty($itemSeatsData[$id]['is_share_slot'])) {
|
|
|
|
|
if ($maxShareSlotId !== null && isset($itemChannelMap[$maxShareSlotId])) {
|
|
|
|
|
foreach ($itemChannelMap[$maxShareSlotId] as $cId => $count) {
|
|
|
|
|
$details[] = [
|
|
|
|
|
'roster_detail_count_id' => $cId,
|
|
|
|
|
'count' => $itemSeatsData[$id]['use_seats']
|
|
|
|
|
];
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$xuhao = $this->generateQueueNumber($planInfo->id);
|
|
|
|
|
|
|
|
|
|
$u_data = [
|
|
|
|
|
@ -1509,6 +1536,13 @@ public function YuYue($planid, $appointment_type, $mainlistids, $do_type,$is_eme
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 校正旧排班号源(s_list 已更新,旧项目已移走)
|
|
|
|
|
foreach ($oldRosterIds as $rid) {
|
|
|
|
|
$this->correctUsedCount($rid);
|
|
|
|
|
}
|
|
|
|
|
// 校正新排班号源
|
|
|
|
|
$this->correctUsedCount($planInfo->id);
|
|
|
|
|
|
|
|
|
|
DB::commit();
|
|
|
|
|
|
|
|
|
|
// HIS 回写通知
|
|
|
|
|
@ -1645,6 +1679,11 @@ public function CancelYuYue($MainListId, $reg_num,$do_user=null)
|
|
|
|
|
|
|
|
|
|
$u_mainList = DB::table('s_list')->where(['id' => $MainListId])->update($u_data);
|
|
|
|
|
|
|
|
|
|
// 校正号源
|
|
|
|
|
if ($mainInfo->roster_id) {
|
|
|
|
|
$this->correctUsedCount($mainInfo->roster_id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$i_log = DB::table('s_list_log')->insert([
|
|
|
|
|
'list_id' => $mainInfo->id,
|
|
|
|
|
'reg_num' => $mainInfo->reg_num,
|
|
|
|
|
@ -1667,302 +1706,10 @@ public function CancelYuYue($MainListId, $reg_num,$do_user=null)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function releaseSourceFromDetail($mainListId, $mainInfo = null)
|
|
|
|
|
public function releaseSourceFromDetail($mainListId, $mainInfo = null)
|
|
|
|
|
{
|
|
|
|
|
if (!$mainInfo) {
|
|
|
|
|
$mainInfo = DB::table('s_list')->where(['id' => $mainListId])->first();
|
|
|
|
|
}
|
|
|
|
|
if (!$mainInfo) {
|
|
|
|
|
Log::error("释放号源失败-记录不存在", ['MainListId' => $mainListId]);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$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,不释放,将占位合并到新持有者
|
|
|
|
|
$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();
|
|
|
|
|
|
|
|
|
|
Log::info('[YuYueDebug] else 转移-新持有者查询', [
|
|
|
|
|
'mainListId' => $mainListId,
|
|
|
|
|
'entrust' => $mainInfo->entrust,
|
|
|
|
|
'newHolderId' => $newHolder ? $newHolder->id : 'null',
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
if ($newHolder) {
|
|
|
|
|
// 读取新持有者当前 detail,合并当前项目的占位
|
|
|
|
|
$newHolderJson = DB::table('s_list')->where('id', $newHolder->id)->value('appointment_use_plan_detail');
|
|
|
|
|
$newHolderDetail = json_decode($newHolderJson, true) ?: [];
|
|
|
|
|
|
|
|
|
|
Log::info('[YuYueDebug] else 转移-合并前', [
|
|
|
|
|
'newHolderId' => $newHolder->id,
|
|
|
|
|
'newHolderDetail' => $newHolderDetail,
|
|
|
|
|
'cancelDetail' => $useDetails,
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
foreach ($useDetails as $d) {
|
|
|
|
|
$found = false;
|
|
|
|
|
foreach ($newHolderDetail as &$nd) {
|
|
|
|
|
if ($nd['roster_detail_count_id'] == $d['roster_detail_count_id']) {
|
|
|
|
|
$nd['count'] += (int)($d['count'] ?? 0);
|
|
|
|
|
$found = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!$found) {
|
|
|
|
|
$newHolderDetail[] = [
|
|
|
|
|
'roster_detail_count_id' => $d['roster_detail_count_id'],
|
|
|
|
|
'count' => (int)($d['count'] ?? 0)
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Log::info('[YuYueDebug] else 转移-合并后', [
|
|
|
|
|
'newHolderId' => $newHolder->id,
|
|
|
|
|
'newHolderDetail' => $newHolderDetail,
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
DB::table('s_list')
|
|
|
|
|
->where('id', $newHolder->id)
|
|
|
|
|
->update(['appointment_use_plan_detail' => json_encode($newHolderDetail)]);
|
|
|
|
|
|
|
|
|
|
// 更新后读回确认
|
|
|
|
|
$afterUpdate = DB::table('s_list')->where('id', $newHolder->id)->value('appointment_use_plan_detail');
|
|
|
|
|
Log::info('[YuYueDebug] else 转移-更新后读回', [
|
|
|
|
|
'newHolderId' => $newHolder->id,
|
|
|
|
|
'写入值' => json_encode($newHolderDetail),
|
|
|
|
|
'读回值' => $afterUpdate,
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
// 不修改 useDetailJson,但返回 true 阻止正常释放逻辑
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// 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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$useDetails = json_decode($useDetailJson, true);
|
|
|
|
|
if (!is_array($useDetails)) {
|
|
|
|
|
Log::error("释放号源失败-明细格式错误", ['MainListId' => $mainListId, 'detail' => $useDetailJson]);
|
|
|
|
|
return $this->releaseSourceFallback($mainInfo);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$allSuccess = true;
|
|
|
|
|
foreach ($useDetails as $detail) {
|
|
|
|
|
$rosterDetailCountId = $detail['roster_detail_count_id'] ?? null;
|
|
|
|
|
$countToRelease = (int)($detail['count'] ?? 0);
|
|
|
|
|
|
|
|
|
|
if (!$rosterDetailCountId || $countToRelease <= 0) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$countRecord = DB::table('s_source_roster_detail_count')
|
|
|
|
|
->where(['id' => $rosterDetailCountId])
|
|
|
|
|
->first();
|
|
|
|
|
|
|
|
|
|
if (!$countRecord) {
|
|
|
|
|
Log::error("释放号源-记录缺失", ['MainListId' => $mainListId, 'count_id' => $rosterDetailCountId]);
|
|
|
|
|
$allSuccess = false;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$currentVersion = $countRecord->version;
|
|
|
|
|
$affected = DB::table('s_source_roster_detail_count')
|
|
|
|
|
->where(['id' => $rosterDetailCountId, 'version' => $currentVersion])
|
|
|
|
|
->where('used_count', '>=', $countToRelease)
|
|
|
|
|
->update([
|
|
|
|
|
'used_count' => DB::raw('used_count - ' . $countToRelease),
|
|
|
|
|
'version' => DB::raw('version + 1'),
|
|
|
|
|
'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) {
|
|
|
|
|
Log::error("释放号源重试-记录缺失", ['MainListId' => $mainListId, 'count_id' => $rosterDetailCountId]);
|
|
|
|
|
$allSuccess = false;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ($retryRecord->used_count < $countToRelease) {
|
|
|
|
|
$actualRelease = $retryRecord->used_count;
|
|
|
|
|
if ($actualRelease > 0) {
|
|
|
|
|
DB::table('s_source_roster_detail_count')
|
|
|
|
|
->where(['id' => $rosterDetailCountId])
|
|
|
|
|
->update([
|
|
|
|
|
'used_count' => 0,
|
|
|
|
|
'version' => DB::raw('version + 1'),
|
|
|
|
|
'updated_at' => date('Y-m-d H:i:s')
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
Log::warning("释放号源-数量不足", [
|
|
|
|
|
'MainListId' => $mainListId,
|
|
|
|
|
'count_id' => $rosterDetailCountId,
|
|
|
|
|
'expected' => $countToRelease,
|
|
|
|
|
'actual' => $actualRelease
|
|
|
|
|
]);
|
|
|
|
|
} else {
|
|
|
|
|
DB::table('s_source_roster_detail_count')
|
|
|
|
|
->where(['id' => $rosterDetailCountId])
|
|
|
|
|
->update([
|
|
|
|
|
'used_count' => DB::raw('used_count - ' . $countToRelease),
|
|
|
|
|
'version' => DB::raw('version + 1'),
|
|
|
|
|
'updated_at' => date('Y-m-d H:i:s')
|
|
|
|
|
]);
|
|
|
|
|
Log::warning("释放号源-乐观锁冲突已重试", ['MainListId' => $mainListId, 'count_id' => $rosterDetailCountId]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Log::info('[YuYueDebug] releaseSourceFromDetail 返回', [
|
|
|
|
|
'mainListId' => $mainListId,
|
|
|
|
|
'entrust' => $mainInfo->entrust,
|
|
|
|
|
'allSuccess' => $allSuccess ? 'true' : 'false',
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
return $allSuccess;
|
|
|
|
|
// 由 correctUsedCount 校正替代,不再在此处释放号源
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private function releaseSourceFallback($mainInfo)
|
|
|
|
|
@ -1987,6 +1734,78 @@ private function releaseSourceFallback($mainInfo)
|
|
|
|
|
return $affected > 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 校正排班号源:根据项目配置(is_share_slot / use_seats)重新计算 used_count
|
|
|
|
|
*/
|
|
|
|
|
private function correctUsedCount($rosterId)
|
|
|
|
|
{
|
|
|
|
|
if (!$rosterId) return;
|
|
|
|
|
|
|
|
|
|
// 先重置该排班所有渠道的 used_count 为 0
|
|
|
|
|
DB::table('s_source_roster_detail_count')
|
|
|
|
|
->where('roster_detail_id', $rosterId)
|
|
|
|
|
->update(['used_count' => 0, 'version' => DB::raw('version + 1')]);
|
|
|
|
|
|
|
|
|
|
// 获取该排班上所有活跃项目及其配置
|
|
|
|
|
$activeItems = DB::table('s_list')
|
|
|
|
|
->join('s_check_item', 's_list.entrust', '=', 's_check_item.item_name')
|
|
|
|
|
->where('s_list.roster_id', $rosterId)
|
|
|
|
|
->where('s_list.list_status', 1)
|
|
|
|
|
->where('s_check_item.status', 1)
|
|
|
|
|
->where('s_check_item.is_del', 0)
|
|
|
|
|
->select('s_list.*', 's_check_item.use_seats', 's_check_item.is_share_slot')
|
|
|
|
|
->get();
|
|
|
|
|
|
|
|
|
|
// 计算总占位:按人隔离,共享取 max,非共享累加
|
|
|
|
|
$grouped = [];
|
|
|
|
|
$firstDetail = null;
|
|
|
|
|
|
|
|
|
|
foreach ($activeItems as $item) {
|
|
|
|
|
$reg = $item->reg_num;
|
|
|
|
|
if (!isset($grouped[$reg])) {
|
|
|
|
|
$grouped[$reg] = ['sharedMax' => 0, 'nonSharedSum' => 0];
|
|
|
|
|
}
|
|
|
|
|
if (!empty($item->is_share_slot)) {
|
|
|
|
|
$grouped[$reg]['sharedMax'] = max($grouped[$reg]['sharedMax'], (int)($item->use_seats ?? 1));
|
|
|
|
|
} else {
|
|
|
|
|
$grouped[$reg]['nonSharedSum'] += (int)($item->use_seats ?? 1);
|
|
|
|
|
}
|
|
|
|
|
// 记录第一个有 detail 的渠道
|
|
|
|
|
if ($firstDetail === null) {
|
|
|
|
|
$details = json_decode($item->appointment_use_plan_detail, true) ?: [];
|
|
|
|
|
if (!empty($details)) {
|
|
|
|
|
$firstDetail = $details;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$totalUsed = 0;
|
|
|
|
|
foreach ($grouped as $reg => $g) {
|
|
|
|
|
$totalUsed += $g['sharedMax'] + $g['nonSharedSum'];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 按渠道分配占位
|
|
|
|
|
if ($firstDetail && $totalUsed > 0) {
|
|
|
|
|
$totalDetailCount = array_sum(array_column($firstDetail, 'count'));
|
|
|
|
|
foreach ($firstDetail as $d) {
|
|
|
|
|
$cid = $d['roster_detail_count_id'] ?? null;
|
|
|
|
|
if (!$cid) continue;
|
|
|
|
|
$ratio = $totalDetailCount > 0 ? ($d['count'] / $totalDetailCount) : 0;
|
|
|
|
|
$channelUsed = (int)round($totalUsed * $ratio);
|
|
|
|
|
DB::table('s_source_roster_detail_count')
|
|
|
|
|
->where('id', $cid)
|
|
|
|
|
->update(['used_count' => $channelUsed, 'version' => DB::raw('version + 1')]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Log::info('[YuYueDebug] 校正号源', [
|
|
|
|
|
'rosterId' => $rosterId,
|
|
|
|
|
'grouped' => $grouped,
|
|
|
|
|
'totalUsed' => $totalUsed,
|
|
|
|
|
'activeItemCount' => $activeItems->count(),
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 预约完成后通知 HIS 回写执行科室
|
|
|
|
|
* 在事务提交后调用,异常不影响主流程
|
|
|
|
|
|