From faba9d6d2b6c90cf6e32dfbad516eefc61bd4be9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E9=92=8A?= Date: Wed, 15 Oct 2025 14:58:37 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E9=9C=80=E6=B1=82-=E6=B4=BB=E5=8A=A8?= =?UTF-8?q?=E9=9C=80=E6=B1=82-=E7=9B=B2=E7=9B=92=E8=BD=AC=E7=9B=98?= =?UTF-8?q?=E8=B0=83=E9=80=9A=E7=9B=98-=E5=B7=A1=E4=B9=90=E4=BC=9A-?= =?UTF-8?q?=E8=B0=83=E8=AF=95-=E4=BC=98=E5=8C=96=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../model/BlindBoxTurntableGiftDrawWorld.php | 287 ++++++++---------- 1 file changed, 134 insertions(+), 153 deletions(-) diff --git a/application/api/model/BlindBoxTurntableGiftDrawWorld.php b/application/api/model/BlindBoxTurntableGiftDrawWorld.php index 4ba99f3..e0e7c36 100644 --- a/application/api/model/BlindBoxTurntableGiftDrawWorld.php +++ b/application/api/model/BlindBoxTurntableGiftDrawWorld.php @@ -1103,157 +1103,140 @@ class BlindBoxTurntableGiftDrawWorld extends Model $batch_size = min(10, $num); // 每批次处理10次 $total_processed = 0; $all_results = []; // 存储所有抽奖结果 - - while ($total_processed < $num) { - $current_batch = min($batch_size, $num - $total_processed); // 当前批次处理数量 - try { - db::startTrans(); - // 批量扣除金币(只在第一次事务中处理) - if ($total_processed == 0) { - $user_waller = db::name('user_wallet')->where(['user_id' => $user_id])->find(); - if (!$user_waller || $user_waller['coin'] < $bag_gift_price) { - return ['code' => 0, 'msg' => '用户金币不足', 'data' => null]; - } - $wallet_update = model('GiveGift')->change_user_cion_or_earnings_log( - $user_id, - $bag_gift_price, - $room_id, - 1, - 10, - $ext['gift_bag_name'].'抽奖消耗' - ); - 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('用户等级更新失败'); - } - } - - // 处理当前批次的抽奖 - $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; - - // 记录抽中结果 - $gift_id = $selected_gift['foreign_id']; - $drawn_gifts[$gift_id] = ($drawn_gifts[$gift_id] ?? 0) + 1; - - // 处理主奖品 - if ($gift_id == $ext['locking_condition']['selected_gift_id']) { - $pan_xlh_num++; - $main_prize_updates[] = [ - 'num' => $pan_xlh_num, - 'user_id' => $user_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) { - 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. 批量处理结果记录 try { db::startTrans(); + while ($total_processed < $num) { + $current_batch = min($batch_size, $num - $total_processed); // 当前批次处理数量 + // 批量扣除金币(只在第一次事务中处理) + if ($total_processed == 0) { + $user_waller = db::name('user_wallet')->where(['user_id' => $user_id])->find(); + if (!$user_waller || $user_waller['coin'] < $bag_gift_price) { + return ['code' => 0, 'msg' => '用户金币不足', 'data' => null]; + } + $wallet_update = model('GiveGift')->change_user_cion_or_earnings_log( + $user_id, + $bag_gift_price, + $room_id, + 1, + 10, + $ext['gift_bag_name'].'抽奖消耗' + ); + 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('用户等级更新失败'); + } + } + + // 处理当前批次的抽奖 + $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; + + // 记录抽中结果 + $gift_id = $selected_gift['foreign_id']; + $drawn_gifts[$gift_id] = ($drawn_gifts[$gift_id] ?? 0) + 1; + + // 处理主奖品 + if ($gift_id == $ext['locking_condition']['selected_gift_id']) { + $pan_xlh_num++; + $main_prize_updates[] = [ + 'num' => $pan_xlh_num, + 'user_id' => $user_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) { + 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; + } + $total_processed += $current_batch; + } + // 7. 批量处理结果记录 if(count($drawn_gifts) > $num){ $key = 'xlh_draw_gift_errors_' . date('Y-m-d-H-i-s'); $errorData = [ @@ -1310,7 +1293,6 @@ class BlindBoxTurntableGiftDrawWorld extends Model 'createtime' => time(), 'updatetime' => time() ]); - db::commit(); } catch (\Exception $e) { db::rollback(); @@ -1320,10 +1302,9 @@ class BlindBoxTurntableGiftDrawWorld extends Model '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]; + $this->redis->setex($key, 86400 * 7, $e->getMessage(). ' ' .json_encode($errorData)); + return ['code' => 0, 'msg' => "抽奖中,请稍等...", 'data' => null]; } - // 8. 处理推送消息 if ($is_zhong_jiang == 1) { $this->handlePrizeNotification($user_id,$gift_id, $room_id, $pan_xlh_num, $end_time,$ext['locking_condition']['locking_gift_id']);