解决超出发放礼物问题-盲盒转盘
This commit is contained in:
@@ -47,8 +47,9 @@ class BlindBoxTurntableGiftDraw extends Model
|
|||||||
$availableGiftss = $precomputeResult['data']['availableGifts'];
|
$availableGiftss = $precomputeResult['data']['availableGifts'];
|
||||||
$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'];
|
||||||
if(count($precomputedResults) != count(explode(',', $gift_user_ids)) * $num){
|
$expectedCount = count(explode(',', $gift_user_ids)) * $num;
|
||||||
Log::record('抽奖结果数量与预期数量不一致,请重试! ('.count($precomputedResults).'): ' . $room_id."【数据】".var_export($precomputedResults, true),"infos-mhzp");
|
if(count($precomputedResults) != $expectedCount){
|
||||||
|
Log::record('抽奖结果数量与预期数量不一致,请重试!预期: '.$expectedCount.', 实际: '.count($precomputedResults).': ' . $room_id."【数据】".var_export($precomputedResults, true),"infos-mhzp");
|
||||||
return ['code' => 0, 'msg' => '抽奖结果数量与预期数量不一致,请重试! ', 'data' => null];
|
return ['code' => 0, 'msg' => '抽奖结果数量与预期数量不一致,请重试! ', 'data' => null];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -210,7 +211,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);
|
||||||
@@ -218,7 +219,7 @@ class BlindBoxTurntableGiftDraw extends Model
|
|||||||
return ['code' => 0, 'msg' => '重置奖池后仍无可用礼物', 'data' => null];
|
return ['code' => 0, 'msg' => '重置奖池后仍无可用礼物', 'data' => null];
|
||||||
}
|
}
|
||||||
$totalDrawTimes = 0;
|
$totalDrawTimes = 0;
|
||||||
$num = abs($totalRemaining - $num);
|
// 不要修改$num的值,保持原始请求数量
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5. 使用Alias Method预计算抽奖结果(O(1)复杂度)
|
// 5. 使用Alias Method预计算抽奖结果(O(1)复杂度)
|
||||||
@@ -267,26 +268,47 @@ 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 $key=>$value) {
|
foreach ($remaining_available_gifts as $value) {
|
||||||
$remaining_num += $value['remaining_number'];
|
$remaining_num += $value['remaining_number'];
|
||||||
}
|
}
|
||||||
if($remaining_num > $num){
|
|
||||||
$availableGifts = $remaining_available_gifts;
|
// 如果剩余礼物数量大于请求数量,只使用部分剩余礼物
|
||||||
$remaining_available_gifts = [];
|
if($remaining_num > count($toarray) * $num){
|
||||||
|
// 重新构建剩余礼物数组,只取需要的数量
|
||||||
|
$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[] = [
|
||||||
@@ -299,27 +321,24 @@ class BlindBoxTurntableGiftDraw extends Model
|
|||||||
];
|
];
|
||||||
$totalDrawTimes++;
|
$totalDrawTimes++;
|
||||||
$currentXlhPeriodsNum++;
|
$currentXlhPeriodsNum++;
|
||||||
|
|
||||||
}
|
}
|
||||||
unset($remaining_available_gifts[$key]);
|
|
||||||
}
|
}
|
||||||
$numm = $num;
|
$remaining_available_gifts = []; // 清空剩余礼物
|
||||||
}else{
|
$numm = $num; // 使用原始请求数量
|
||||||
$numm = $num+$remaining_num;
|
} else {
|
||||||
|
$numm = $num; // 使用原始请求数量
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 正常抽奖逻辑
|
||||||
for ($i = 0; $i < $numm; $i++) {
|
for ($i = 0; $i < $numm; $i++) {
|
||||||
// 使用Alias Method选择礼物(O(1)复杂度)
|
// 使用Alias Method选择礼物
|
||||||
$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,
|
||||||
@@ -341,22 +360,12 @@ 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ['precomputedResults' => $precomputedResults,'precomputedResultss' => $precomputedResultss];
|
return ['precomputedResults' => $precomputedResults, 'precomputedResultss' => $precomputedResultss];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user