预约号源BUG

main
鹿和sa0ChunLuyu 2 days ago
parent 260b608e83
commit 820866b30e

@ -1465,61 +1465,7 @@ public function YuYue($planid, $appointment_type, $mainlistids, $do_type,$is_eme
} }
//更新计划明细表使用数量(使用乐观锁) // === 号源总量校验 + 精确扣减(替换原乐观锁扣减)===
$up_plan_count_all_success = true;
$versionMismatchIds = [];
foreach ($roster_detail_counts as $key => $planCount) {
$countToDeduct = $plan_qudao_tempCount[$key];
if ($countToDeduct == 0) continue;
if ($is_emergency !== 1) {
$affected = DB::table('s_source_roster_detail_count')
->where(['id' => $planCount->id, 'version' => $planCount->version])
->whereRaw('count >= (used_count + IFNULL(locked_count, 0) + ?)', [$countToDeduct])
->update([
'used_count' => DB::raw('used_count + ' . $countToDeduct),
'version' => DB::raw('version + 1'),
'updated_at' => date('Y-m-d H:i:s')
]);
} else {
$affected = DB::table('s_source_roster_detail_count')
->where(['id' => $planCount->id, 'version' => $planCount->version])
->update([
'used_count' => DB::raw('used_count + ' . $countToDeduct),
'version' => DB::raw('version + 1'),
'updated_at' => date('Y-m-d H:i:s')
]);
if ($affected == 0) {
$check = DB::table('s_source_roster_detail_count')->find($planCount->id);
if (!$check) {
$up_plan_count_all_success = false;
break;
}
$affected = DB::table('s_source_roster_detail_count')
->where(['id' => $planCount->id])
->update([
'used_count' => DB::raw('used_count + ' . $countToDeduct),
'version' => DB::raw('version + 1'),
'updated_at' => date('Y-m-d H:i:s')
]);
}
}
if ($affected == 0 && $is_emergency !== 1) {
$versionMismatchIds[] = $planCount->id;
$up_plan_count_all_success = false;
}
}
if (!$up_plan_count_all_success && $is_emergency !== 1) {
if (count($versionMismatchIds) > 0) {
Log::warning("预约乐观锁冲突", ['planid' => $planid, 'conflict_ids' => $versionMismatchIds]);
throw new \Exception('号源数据已被其他用户修改,请刷新后重试');
}
throw new \Exception('名额不足,扣减失败');
}
// === 号源总量校验扣减后、更新s_list前===
// 加急预约允许超量,跳过总量校验 // 加急预约允许超量,跳过总量校验
if ($is_emergency !== 1) { if ($is_emergency !== 1) {
// 校验①:合并渠道总额校验(计数器维度) // 校验①:合并渠道总额校验(计数器维度)
@ -1583,6 +1529,49 @@ public function YuYue($planid, $appointment_type, $mainlistids, $do_type,$is_eme
} // end if ($is_emergency !== 1) } // end if ($is_emergency !== 1)
// === 号源总量校验结束 === // === 号源总量校验结束 ===
// === 精确扣减号源占位(在 lockForUpdate 和总量校验之后)===
// 按实际占位逻辑共享取max、非共享累加分配到各渠道逐渠道扣减 used_count
$channelDeduct = [];
foreach ($itemChannelMap as $mid => $channels) {
$useSeats = $itemSeatsQueue[$mid] ?? 0;
if ($useSeats <= 0) continue;
foreach ($channels as $cId => $cnt) {
$channelDeduct[$cId] = ($channelDeduct[$cId] ?? 0) + $cnt;
}
}
foreach ($channelDeduct as $cId => $deductCount) {
if ($deductCount <= 0) continue;
$channelInfo = null;
foreach ($roster_detail_counts as $rc) {
if ($rc->id == $cId) { $channelInfo = $rc; break; }
}
if (!$channelInfo) {
throw new \Exception('号源扣减失败:渠道不存在(id=' . $cId . ')');
}
// 加急预约允许超量,不校验单渠道上限
if ($is_emergency !== 1) {
$afterDeduct = $channelInfo->used_count + $deductCount;
if ($afterDeduct > $channelInfo->count) {
Log::warning('号源单渠道超限', [
'planid' => $planid,
'channelId' => $cId,
'used_count' => $channelInfo->used_count,
'deductCount' => $deductCount,
'count' => $channelInfo->count,
]);
throw new \Exception('号源不足,渠道容量' . $channelInfo->count . ',已用' . $channelInfo->used_count . ',本次需' . $deductCount);
}
}
DB::table('s_source_roster_detail_count')
->where('id', $cId)
->update([
'used_count' => DB::raw('used_count + ' . $deductCount),
'version' => DB::raw('version + 1'),
'updated_at' => date('Y-m-d H:i:s')
]);
}
// === 精确扣减结束 ===
$list_all_success = true; $list_all_success = true;
$savedDataMap = []; // 记录每条项目的实际写入数据 $savedDataMap = []; // 记录每条项目的实际写入数据
foreach ($mainlistids as $id) { foreach ($mainlistids as $id) {

Loading…
Cancel
Save