|
|
|
|
@ -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) {
|
|
|
|
|
// 校验①:合并渠道总额校验(计数器维度)
|
|
|
|
|
@ -1583,6 +1529,49 @@ public function YuYue($planid, $appointment_type, $mainlistids, $do_type,$is_eme
|
|
|
|
|
} // 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;
|
|
|
|
|
$savedDataMap = []; // 记录每条项目的实际写入数据
|
|
|
|
|
foreach ($mainlistids as $id) {
|
|
|
|
|
|