新需求-活动需求-盲盒转盘调通盘-巡乐会-调试-优化错误
This commit is contained in:
@@ -840,6 +840,7 @@ class BlindBoxTurntableGiftDrawWorld extends Model
|
|||||||
$text_list_new = [
|
$text_list_new = [
|
||||||
'xlh_data' => $xlh,
|
'xlh_data' => $xlh,
|
||||||
'text' => "",
|
'text' => "",
|
||||||
|
'room_id' => $room_id,
|
||||||
'from_type' => 100
|
'from_type' => 100
|
||||||
];
|
];
|
||||||
$push->xunlehui($text_list_new);
|
$push->xunlehui($text_list_new);
|
||||||
@@ -1101,159 +1102,149 @@ class BlindBoxTurntableGiftDrawWorld extends Model
|
|||||||
|
|
||||||
while ($total_processed < $num) {
|
while ($total_processed < $num) {
|
||||||
$current_batch = min($batch_size, $num - $total_processed); // 当前批次处理数量
|
$current_batch = min($batch_size, $num - $total_processed); // 当前批次处理数量
|
||||||
|
try {
|
||||||
$maxRetries = 3;
|
db::startTrans();
|
||||||
for ($retry = 0; $retry < $maxRetries; $retry++) {
|
// 批量扣除金币(只在第一次事务中处理)
|
||||||
try {
|
if ($total_processed == 0) {
|
||||||
db::startTrans();
|
$user_waller = db::name('user_wallet')->where(['user_id' => $user_id])->find();
|
||||||
// 批量扣除金币(只在第一次事务中处理)
|
if (!$user_waller || $user_waller['coin'] < $bag_gift_price) {
|
||||||
if ($total_processed == 0) {
|
return ['code' => 0, 'msg' => '用户金币不足', 'data' => null];
|
||||||
$user_waller = db::name('user_wallet')->where(['user_id' => $user_id])->find();
|
}
|
||||||
if (!$user_waller || $user_waller['coin'] < $bag_gift_price) {
|
$wallet_update = model('GiveGift')->change_user_cion_or_earnings_log(
|
||||||
return ['code' => 0, 'msg' => '用户金币不足', 'data' => null];
|
$user_id,
|
||||||
}
|
$bag_gift_price,
|
||||||
$wallet_update = model('GiveGift')->change_user_cion_or_earnings_log(
|
$room_id,
|
||||||
$user_id,
|
1,
|
||||||
$bag_gift_price,
|
10,
|
||||||
$room_id,
|
$ext['gift_bag_name'].'抽奖消耗'
|
||||||
1,
|
);
|
||||||
10,
|
if (!$wallet_update) {
|
||||||
$ext['gift_bag_name'].'抽奖消耗'
|
throw new \Exception('扣除用户金币失败');
|
||||||
);
|
|
||||||
if (!$wallet_update) {
|
|
||||||
throw new \Exception('扣除用户金币失败');
|
|
||||||
}
|
|
||||||
|
|
||||||
$user_level = model('Level')->user_level_data_update(
|
|
||||||
$user_id,
|
|
||||||
$bag_gift_price,
|
|
||||||
1,
|
|
||||||
$room_id
|
|
||||||
);
|
|
||||||
if (!$user_level) {
|
|
||||||
throw new \Exception('用户等级更新失败');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理当前批次的抽奖
|
$user_level = model('Level')->user_level_data_update(
|
||||||
$inventory_updates = []; // 用于记录库存变化
|
$user_id,
|
||||||
$remaining_available_gifts = $available_gifts;
|
$bag_gift_price,
|
||||||
for ($i = 0; $i < $current_batch; $i++) {
|
1,
|
||||||
// 从可用礼物中选择
|
$room_id
|
||||||
$selected_gift = $this->selectGiftFromAvailable($available_gifts);
|
);
|
||||||
if (!$selected_gift) {
|
if (!$user_level) {
|
||||||
$gift_bag_detail = $this->resetPoolAndReload($gift_bag_id);
|
throw new \Exception('用户等级更新失败');
|
||||||
$selected_gift = $this->selectGiftFromAvailable($gift_bag_detail);
|
}
|
||||||
if(!$selected_gift){
|
}
|
||||||
throw new \Exception('预计算抽奖失败,重置后无可用礼物');
|
|
||||||
}
|
// 处理当前批次的抽奖
|
||||||
|
$inventory_updates = []; // 用于记录库存变化
|
||||||
|
$remaining_available_gifts = $available_gifts;
|
||||||
|
for ($i = 0; $i < $current_batch; $i++) {
|
||||||
|
// 从可用礼物中选择
|
||||||
|
$selected_gift = $this->selectGiftFromAvailable($available_gifts);
|
||||||
|
if (!$selected_gift) {
|
||||||
|
$gift_bag_detail = $this->resetPoolAndReload($gift_bag_id);
|
||||||
|
$selected_gift = $this->selectGiftFromAvailable($gift_bag_detail);
|
||||||
|
if(!$selected_gift){
|
||||||
|
throw new \Exception('预计算抽奖失败,重置后无可用礼物');
|
||||||
}
|
}
|
||||||
// 记录库存变化
|
}
|
||||||
$inventory_updates[$selected_gift['id']] =
|
// 记录库存变化
|
||||||
($inventory_updates[$selected_gift['id']] ?? 0) + 1;
|
$inventory_updates[$selected_gift['id']] =
|
||||||
|
($inventory_updates[$selected_gift['id']] ?? 0) + 1;
|
||||||
|
|
||||||
// 记录抽中结果
|
// 记录抽中结果
|
||||||
$gift_id = $selected_gift['foreign_id'];
|
$gift_id = $selected_gift['foreign_id'];
|
||||||
$drawn_gifts[$gift_id] = ($drawn_gifts[$gift_id] ?? 0) + 1;
|
$drawn_gifts[$gift_id] = ($drawn_gifts[$gift_id] ?? 0) + 1;
|
||||||
|
|
||||||
// 处理主奖品
|
// 处理主奖品
|
||||||
if ($gift_id == $ext['locking_condition']['selected_gift_id']) {
|
if ($gift_id == $ext['locking_condition']['selected_gift_id']) {
|
||||||
$pan_xlh_num++;
|
$pan_xlh_num++;
|
||||||
$main_prize_updates[] = [
|
$main_prize_updates[] = [
|
||||||
'num' => $pan_xlh_num,
|
'num' => $pan_xlh_num,
|
||||||
'user_id' => $user_id,
|
'user_id' => $user_id,
|
||||||
'gift_id' => $gift_id
|
'gift_id' => $gift_id
|
||||||
];
|
|
||||||
|
|
||||||
// 计算延长时间
|
|
||||||
$add_end_time = $this->calculateEndTime($pan_xlh_num, $ext, $room_id);
|
|
||||||
$end_time = time() + $add_end_time;
|
|
||||||
|
|
||||||
// 记录主奖品更新
|
|
||||||
$main_prize_updates[count($main_prize_updates) - 1]['end_time'] = $end_time;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 记录完整结果
|
|
||||||
$all_results[] = [
|
|
||||||
'gift_id' => $gift_id,
|
|
||||||
'gift_detail_id' => $selected_gift['id'],
|
|
||||||
'gift_bag_detail' => $selected_gift
|
|
||||||
];
|
];
|
||||||
|
|
||||||
// 更新可用礼物缓存
|
// 计算延长时间
|
||||||
foreach ($available_gifts as &$gift) {
|
$add_end_time = $this->calculateEndTime($pan_xlh_num, $ext, $room_id);
|
||||||
if ($gift['id'] == $selected_gift['id']) {
|
$end_time = time() + $add_end_time;
|
||||||
$gift['remaining_number']--;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unset($gift);
|
|
||||||
|
|
||||||
// 移除已无剩余数量的礼物
|
// 记录主奖品更新
|
||||||
$available_gifts = array_filter($available_gifts, function($gift) {
|
$main_prize_updates[count($main_prize_updates) - 1]['end_time'] = $end_time;
|
||||||
return $gift['remaining_number'] > 0;
|
|
||||||
});
|
|
||||||
|
|
||||||
// 检查是否需要重置奖池
|
|
||||||
$total_remaining = array_sum(array_column($available_gifts, 'remaining_number'));
|
|
||||||
if ($total_remaining <= 0 && $total_processed + $i + 1 < $num) {// 剩余数量小于等于0且当前处理数量小于总数量
|
|
||||||
$available_gifts = $this->resetPoolAndReload($gift_bag_id);
|
|
||||||
if (empty($available_gifts)) {
|
|
||||||
throw new \Exception('重置奖池后仍无可用礼物');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 批量更新库存
|
// 记录完整结果
|
||||||
ksort($inventory_updates); // 按ID排序
|
$all_results[] = [
|
||||||
foreach ($inventory_updates as $detail_id => $count) {
|
'gift_id' => $gift_id,
|
||||||
db::name("vs_gift_bag_detail")->where('id',$detail_id)->setDec('remaining_number', $count);
|
'gift_detail_id' => $selected_gift['id'],
|
||||||
}
|
'gift_bag_detail' => $selected_gift
|
||||||
|
|
||||||
// 处理主奖品更新
|
|
||||||
if (!empty($main_prize_updates)) {
|
|
||||||
$last_update = end($main_prize_updates);
|
|
||||||
db::name('vs_room_pan_xlh')->where('id', $pan_xlh['id'])->update([
|
|
||||||
'user_id' => $last_update['user_id'],
|
|
||||||
'room_id' => $room_id,
|
|
||||||
'pay_price' => $ext['xlh_box_price'],
|
|
||||||
'locking_gift_id' => $last_update['gift_id'],
|
|
||||||
'num' => $last_update['num'],
|
|
||||||
'end_time' => $last_update['end_time'],
|
|
||||||
'updatetime' => time()
|
|
||||||
]);
|
|
||||||
|
|
||||||
db::name('vs_room_pan_xlh_log')->insert([
|
|
||||||
'xlh_id' => $pan_xlh['id'],
|
|
||||||
'user_id' => $last_update['user_id'],
|
|
||||||
'room_id' => $room_id,
|
|
||||||
'num' => $last_update['num'],
|
|
||||||
'locking_end_time' => $last_update['end_time'],
|
|
||||||
'createtime' => time()
|
|
||||||
]);
|
|
||||||
$is_zhong_jiang = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
db::commit();
|
|
||||||
$total_processed += $current_batch;
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
db::rollback();
|
|
||||||
// 检查是否是死锁错误
|
|
||||||
if (strpos($e->getMessage(), 'Deadlock') !== false && $retry < $maxRetries - 1) {
|
|
||||||
// 等待随机时间后重试
|
|
||||||
usleep(rand(10000, 100000)); // 10-100ms
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$key = 'xlh_draw_gift_errors_' . date('Y-m-d-H-i-s');
|
|
||||||
$errorData = [
|
|
||||||
'user_id' => $user_id,
|
|
||||||
'gift_bag_id' => $gift_bag_id,
|
|
||||||
'room_id' => $room_id,
|
|
||||||
];
|
];
|
||||||
$this->redis->setex($key, 86400 * 7, $e->getMessage(). ' ' .json_encode($errorData));
|
|
||||||
return ['code' => 0, 'msg' => "抽奖中,请稍等...", 'data' => null];
|
// 更新可用礼物缓存
|
||||||
|
foreach ($available_gifts as &$gift) {
|
||||||
|
if ($gift['id'] == $selected_gift['id']) {
|
||||||
|
$gift['remaining_number']--;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unset($gift);
|
||||||
|
|
||||||
|
// 移除已无剩余数量的礼物
|
||||||
|
$available_gifts = array_filter($available_gifts, function($gift) {
|
||||||
|
return $gift['remaining_number'] > 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 检查是否需要重置奖池
|
||||||
|
$total_remaining = array_sum(array_column($available_gifts, 'remaining_number'));
|
||||||
|
if ($total_remaining <= 0 && $total_processed + $i + 1 < $num) {// 剩余数量小于等于0且当前处理数量小于总数量
|
||||||
|
$available_gifts = $this->resetPoolAndReload($gift_bag_id);
|
||||||
|
if (empty($available_gifts)) {
|
||||||
|
throw new \Exception('重置奖池后仍无可用礼物');
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 批量更新库存
|
||||||
|
ksort($inventory_updates); // 按ID排序
|
||||||
|
foreach ($inventory_updates as $detail_id => $count) {
|
||||||
|
db::name("vs_gift_bag_detail")->where('id',$detail_id)->setDec('remaining_number', $count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 处理主奖品更新
|
||||||
|
if (!empty($main_prize_updates)) {
|
||||||
|
$last_update = end($main_prize_updates);
|
||||||
|
db::name('vs_room_pan_xlh')->where('id', $pan_xlh['id'])->update([
|
||||||
|
'user_id' => $last_update['user_id'],
|
||||||
|
'room_id' => $room_id,
|
||||||
|
'pay_price' => $ext['xlh_box_price'],
|
||||||
|
'locking_gift_id' => $last_update['gift_id'],
|
||||||
|
'num' => $last_update['num'],
|
||||||
|
'end_time' => $last_update['end_time'],
|
||||||
|
'updatetime' => time()
|
||||||
|
]);
|
||||||
|
|
||||||
|
db::name('vs_room_pan_xlh_log')->insert([
|
||||||
|
'xlh_id' => $pan_xlh['id'],
|
||||||
|
'user_id' => $last_update['user_id'],
|
||||||
|
'room_id' => $room_id,
|
||||||
|
'num' => $last_update['num'],
|
||||||
|
'locking_end_time' => $last_update['end_time'],
|
||||||
|
'createtime' => time()
|
||||||
|
]);
|
||||||
|
$is_zhong_jiang = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
db::commit();
|
||||||
|
$total_processed += $current_batch;
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
db::rollback();
|
||||||
|
$key = 'xlh_draw_gift_errors_' . date('Y-m-d-H-i-s');
|
||||||
|
$errorData = [
|
||||||
|
'user_id' => $user_id,
|
||||||
|
'gift_bag_id' => $gift_bag_id,
|
||||||
|
'room_id' => $room_id,
|
||||||
|
];
|
||||||
|
$this->redis->setex($key, 86400 * 7, $e->getMessage(). ' ' .json_encode($errorData));
|
||||||
|
return ['code' => 0, 'msg' => "抽奖中,请稍等...", 'data' => null];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 7. 批量处理结果记录
|
// 7. 批量处理结果记录
|
||||||
@@ -1319,6 +1310,13 @@ class BlindBoxTurntableGiftDrawWorld extends Model
|
|||||||
db::commit();
|
db::commit();
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
db::rollback();
|
db::rollback();
|
||||||
|
$key = 'xlh_draw_gift_errors_' . date('Y-m-d-H-i-s');
|
||||||
|
$errorData = [
|
||||||
|
'user_id' => $user_id,
|
||||||
|
'gift_bag_id' => $gift_bag_id,
|
||||||
|
'room_id' => $room_id,
|
||||||
|
];
|
||||||
|
$this->redis->setex($key, 86400 * 7, "巡乐会抽奖记录失败-异常:".$e->getMessage(). ' ' .json_encode($errorData));
|
||||||
return ['code' => 0, 'msg' => $e->getMessage(), 'data' => null];
|
return ['code' => 0, 'msg' => $e->getMessage(), 'data' => null];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user