盲盒转盘修改

This commit is contained in:
2025-09-28 16:21:24 +08:00
parent 4dac5497f8
commit 5972dc04cc

View File

@@ -7,9 +7,7 @@ use think\Log;
use think\Model; use think\Model;
use think\Db; use think\Db;
use think\Session; use think\Session;
//use think\cache\driver\Redis;
use Redis; use Redis;
/* /*
* 盲盒转盘优化后方法 * 盲盒转盘优化后方法
* *
@@ -68,7 +66,6 @@ class BlindBoxTurntableGiftDraw extends Model
$currentXlhPeriodsNum = $precomputeResult['data']['current_xlh_periods_num']; $currentXlhPeriodsNum = $precomputeResult['data']['current_xlh_periods_num'];
$xlhIsPiaoPing = $precomputeResult['data']['xlh_is_piao_ping']; $xlhIsPiaoPing = $precomputeResult['data']['xlh_is_piao_ping'];
$expectedCount = count(explode(',', $gift_user_ids)) * $num; $expectedCount = count(explode(',', $gift_user_ids)) * $num;
if(count($precomputedResults) != $expectedCount){ if(count($precomputedResults) != $expectedCount){
// 记录错误到Redis // 记录错误到Redis
$this->recordDrawErrorToRedis($expectedCount, count($precomputedResults), $room_id, $user_id, $gift_bag_id, $num, $gift_user_ids, $precomputedResults); $this->recordDrawErrorToRedis($expectedCount, count($precomputedResults), $room_id, $user_id, $gift_bag_id, $num, $gift_user_ids, $precomputedResults);
@@ -186,7 +183,6 @@ class BlindBoxTurntableGiftDraw extends Model
if ($user_waller['coin'] < $bag_data['gift_price'] * $num * count(explode(',', $gift_user_ids))) { if ($user_waller['coin'] < $bag_data['gift_price'] * $num * count(explode(',', $gift_user_ids))) {
return ['code' => 0, 'msg' => '用户金币不足', 'data' => null]; return ['code' => 0, 'msg' => '用户金币不足', 'data' => null];
} }
// 4. 获取巡乐会配置(使用缓存) // 4. 获取巡乐会配置(使用缓存)
$xlh_ext = $this->getCachedXlhConfig(); $xlh_ext = $this->getCachedXlhConfig();
@@ -236,7 +232,7 @@ class BlindBoxTurntableGiftDraw extends Model
// 4. 处理奖池重置逻辑 // 4. 处理奖池重置逻辑
$needGiftNum = count($toarray) * $num; $needGiftNum = count($toarray) * $num;
$remaining_available_gifts = []; $remaining_available_gifts=[];
if ($totalRemaining - $needGiftNum <= 0) { if ($totalRemaining - $needGiftNum <= 0) {
$remaining_available_gifts = $availableGifts; $remaining_available_gifts = $availableGifts;
$availableGifts = $this->resetPoolAndReload($bag_data['id'], $room_id, $periods + 1, 0); $availableGifts = $this->resetPoolAndReload($bag_data['id'], $room_id, $periods + 1, 0);
@@ -244,7 +240,7 @@ class BlindBoxTurntableGiftDraw extends Model
throw new \Exception('重置奖池后仍无可用礼物'); throw new \Exception('重置奖池后仍无可用礼物');
} }
$totalDrawTimes = 0; $totalDrawTimes = 0;
// 不要修改$num的值保持原始请求数量 $num = abs($totalRemaining - $num);
} }
// 5. 使用Alias Method预计算抽奖结果O(1)复杂度) // 5. 使用Alias Method预计算抽奖结果O(1)复杂度)
@@ -293,47 +289,26 @@ class BlindBoxTurntableGiftDraw extends Model
$roomId, $roomId,
$remaining_available_gifts $remaining_available_gifts
) { ) {
// 计算剩余礼物总数量 //计算$remaining_available_gifts 里面 remaining_number 的累加
$remaining_num = 0; $remaining_num = 0;
foreach ($remaining_available_gifts as $value) { foreach ($remaining_available_gifts as $key=>$value) {
$remaining_num += $value['remaining_number']; $remaining_num += $value['remaining_number'];
} }
if($remaining_num > $num){
// 如果剩余礼物数量大于请求数量,只使用部分剩余礼物 $availableGifts = $remaining_available_gifts;
if($remaining_num > count($toarray) * $num){ $remaining_available_gifts = [];
// 重新构建剩余礼物数组,只取需要的数量
$temp_remaining = [];
$need_total = count($toarray) * $num;
$current_total = 0;
foreach ($remaining_available_gifts as $key => $value) {
if ($current_total >= $need_total) break;
$can_take = min($value['remaining_number'], $need_total - $current_total);
$temp_remaining[] = [
'id' => $value['id'],
'quantity' => $value['quantity'],
'remaining_number' => $can_take,
'weight' => $value['weight'],
'foreign_id' => $value['foreign_id'],
'gift_bag_id' => $value['gift_bag_id'],
'gift_bag_detail_id' => $value['gift_bag_detail_id']
];
$current_total += $can_take;
}
$remaining_available_gifts = $temp_remaining;
} }
$precomputedResults = []; $precomputedResults = [];
$precomputedResultss = []; $precomputedResultss = [];
$giftBagIdToGift = [];
// 构建Alias表 // 构建Alias表
$aliasTable = $this->buildAliasTable($availableGifts); $aliasTable = $this->buildAliasTable($availableGifts);
$remaining_num = 0;
foreach ($toarray as $giftUserId) { foreach ($toarray as $giftUserId) {
// 处理剩余礼物
if (!empty($remaining_available_gifts)) { if (!empty($remaining_available_gifts)) {
foreach ($remaining_available_gifts as $key => $value) { foreach ($remaining_available_gifts as $key=>$value) {
$remaining_num += $value['remaining_number'];
$gift = $giftInfoMap[$value['foreign_id']] ?? null; $gift = $giftInfoMap[$value['foreign_id']] ?? null;
for ($j = 0; $j < $value['remaining_number']; $j++) { for ($j = 0; $j < $value['remaining_number']; $j++) {
$precomputedResults[] = [ $precomputedResults[] = [
@@ -346,24 +321,27 @@ class BlindBoxTurntableGiftDraw extends Model
]; ];
$totalDrawTimes++; $totalDrawTimes++;
$currentXlhPeriodsNum++; $currentXlhPeriodsNum++;
}
}
$remaining_available_gifts = []; // 清空剩余礼物
$numm = $num; // 使用原始请求数量
} else {
$numm = $num; // 使用原始请求数量
}
// 正常抽奖逻辑 }
unset($remaining_available_gifts[$key]);
}
$numm = $num;
}else{
$numm = $num+$remaining_num;
}
for ($i = 0; $i < $numm; $i++) { for ($i = 0; $i < $numm; $i++) {
// 使用Alias Method选择礼物 // 使用Alias Method选择礼物O(1)复杂度)
$selectedGift = $this->selectGiftWithAliasMethod($aliasTable); $selectedGift = $this->selectGiftWithAliasMethod($aliasTable);
if (!$selectedGift) { if (!$selectedGift) {
return []; return [];
} }
// 获取礼物信息从预加载的map中获取避免查询
$giftId = $selectedGift['foreign_id']; $giftId = $selectedGift['foreign_id'];
$gift = $giftInfoMap[$giftId] ?? null; $gift = $giftInfoMap[$giftId] ?? null;
// if (!$gift) {
// continue;
// }
$precomputedResults[] = [ $precomputedResults[] = [
'gift_user_id' => $giftUserId, 'gift_user_id' => $giftUserId,
@@ -385,8 +363,18 @@ class BlindBoxTurntableGiftDraw extends Model
$totalDrawTimes++; $totalDrawTimes++;
$currentXlhPeriodsNum++; $currentXlhPeriodsNum++;
// 更新Alias表 // 更新Alias表(模拟库存减少)
$this->updateAliasTable($aliasTable, $selectedGift['id']); $this->updateAliasTable($aliasTable, $selectedGift['id']);
// 检查巡乐会状态
if (!empty($xlhExt) && $xlhExt['inlet_bag_id'] == $giftBagId) {
if ($currentXlhPeriodsNum == $xlhExt['open_condition']['waiting_start_num']) {
$xlh_is_piao_ping = 1;
}
if ($currentXlhPeriodsNum == $xlhExt['open_condition']['start_num']) {
$xlh_is_piao_ping = 2;
}
}
} }
} }
@@ -714,7 +702,7 @@ class BlindBoxTurntableGiftDraw extends Model
// 批量发送礼物 // 批量发送礼物
foreach ($giftUserCounts as $userGift) { foreach ($giftUserCounts as $userGift) {
if($userGift['count'] > 9){ //防止礼物超发礼物超10个则不发送 if($userGift['count'] > 9){ //防止礼物超发礼物超10个则不发送
continue; continue;
} }
$giveGiftExt = [ $giveGiftExt = [
'gift_id' => $userGift['gift_id'], 'gift_id' => $userGift['gift_id'],
@@ -1571,7 +1559,6 @@ class BlindBoxTurntableGiftDraw extends Model
return ['code' => 1, 'msg' => '成功', 'data' => $result_list]; return ['code' => 1, 'msg' => '成功', 'data' => $result_list];
} }
//错误日志记录------------------------------------------------------- //错误日志记录-------------------------------------------------------
/** /**
* 记录抽奖错误日志到Redis * 记录抽奖错误日志到Redis