diff --git a/application/api/controller/Room.php b/application/api/controller/Room.php index d1e15539..162f5d37 100644 --- a/application/api/controller/Room.php +++ b/application/api/controller/Room.php @@ -189,7 +189,8 @@ class Room extends BaseCom $pit_number = input('pit_number', 0); $heart_id = input('heart_id', 0); - if($gift_id == 88){ + $pool_gift_id = db::name('bb_lottery_config')->where(['key' => 'pool_gift_id'])->value('value'); + if($gift_id == $pool_gift_id){ $reslut = model('Lottery')->gift($this->uid, $to_uid, $gift_id, $room_id,$gift_num); }else{ $reslut = model('Room')->room_gift($this->uid, $to_uid, $gift_id, $gift_num, $type, $room_id, $pit_number,$heart_id); diff --git a/application/api/model/Lottery.php b/application/api/model/Lottery.php index 30993a23..ca0cad94 100644 --- a/application/api/model/Lottery.php +++ b/application/api/model/Lottery.php @@ -23,8 +23,11 @@ class Lottery extends Model if(in_array($send_uid,$toarray)){ return ['code' => 0, 'msg' => '收礼人不能包含自己', 'data' => null]; } + + //获取礼物信息 $gift_info = Db::name('vs_gift')->where(['gid'=>$gift_id]) ->field('gid as gift_id,gift_name,gift_price,file_type,base_image,play_image,gift_type,label,is_public_server')->find(); + //送给所有人的总价格 $all_gift_price = $gift_info['gift_price'] * $num * count($toarray); //判断是否有足够的金币 diff --git a/application/common/library/LotteryGiftLua.php b/application/common/library/LotteryGiftLua.php index fa30035b..6ad47631 100644 --- a/application/common/library/LotteryGiftLua.php +++ b/application/common/library/LotteryGiftLua.php @@ -126,6 +126,148 @@ if small_total_times >= small_trigger_times then end end +-- 返回结果 +return cjson.encode(result) +LUA; + + } + + // 获取Lua脚本 + public static function getLotteryLuaScripts() + { + return <<= small_trigger_times then + result.is_small_prize = 1 + -- 小奖随机比例 + local small_ratio = math.random(1, 99) + result.small_prize_amount = math.floor(small_total_gold * small_ratio / 100 * 100) / 100 + result.small_remain_amount = math.floor((small_total_gold - result.small_prize_amount) * 100) / 100 + + -- 重置小奖池,小轮次+1 + redis.call('set', small_total_times_key, 0) + redis.call('set', small_total_gold_key, 0) + small_round = small_round + 1 + redis.call('set', small_round_key, small_round) + result.small_round = small_round + + -- 6. 小奖剩余划入大奖池当前轮次 + big_total_gold = math.floor((big_total_gold + result.small_remain_amount) * 100) / 100 + redis.call('set', big_total_gold_key, big_total_gold) + result.big_total_gold = big_total_gold + + -- 7. 大奖池开奖判断 + if big_total_gold >= big_threshold then + -- ===================== 关键修改:记录开奖前总金额 ===================== + result.big_pool_total_before_open = big_total_gold -- 保存开奖前的总金额 + -- ====================================================== + + result.is_big_prize = 1 + -- 从配置读取权重计算出奖比例 + local random_weight = math.random(1, big_weight_total) + local big_ratio = 60 + if random_weight > big_weight_60 and random_weight <= (big_weight_60 + big_weight_70) then + big_ratio = 70 + elseif random_weight > (big_weight_60 + big_weight_70) then + big_ratio = 80 + end + result.big_ratio = big_ratio + + -- 大奖金额计算(基于开奖前的总金额) + result.big_prize_amount = math.floor(result.big_pool_total_before_open * big_ratio / 100 * 100) / 100 + result.big_release_amount = math.floor((result.big_pool_total_before_open - result.big_prize_amount) * 100) / 100 + + -- 重置大奖池,大轮次+1 + redis.call('set', big_total_gold_key, 0) + big_round = big_round + 1 + redis.call('set', big_round_key, big_round) + if small_round < big_round then + small_round = big_round + redis.call('set', small_round_key, small_round) + result.small_round = small_round + end + result.big_round = big_round + result.big_total_gold = 0 + + -- 小奖开奖金额划入大奖池下一轮 + result.small_prize_to_big_next_round = result.small_prize_amount + local new_big_total_gold = math.floor(result.small_prize_amount * 100) / 100 + redis.call('set', big_total_gold_key, new_big_total_gold) + result.big_total_gold = new_big_total_gold + end +end + -- 返回结果 return cjson.encode(result) LUA; diff --git a/application/common/service/LotteryService.php b/application/common/service/LotteryService.php index 3e4d235f..e66c32f0 100644 --- a/application/common/service/LotteryService.php +++ b/application/common/service/LotteryService.php @@ -12,6 +12,7 @@ class LotteryService private $redis; // 配置参数 private $config; + private $bigPrizeWeights; public function __construct() { @@ -19,10 +20,31 @@ class LotteryService // 加载配置 $this->config = Db::name('bb_lottery_config')->column('value', 'key'); // 初始化Redis缓存(若Redis数据丢失,从数据库恢复) + $this->initBigPrizeWeights(); $this->initRedisFromDb(); + $this->checkRoundConstraint(); } + private function initBigPrizeWeights() + { + $this->bigPrizeWeights = [ + '60' => intval($this->config['big_prize_ratio_60_weight'] ?? 20), + '70' => intval($this->config['big_prize_ratio_70_weight'] ?? 50), + '80' => intval($this->config['big_prize_ratio_80_weight'] ?? 30) + ]; + $this->bigPrizeWeights['total'] = array_sum($this->bigPrizeWeights); + } + + private function checkRoundConstraint() + { + $small_round = intval($this->redis->get('lottery:small_pool:round') ?: 1); + $big_round = intval($this->redis->get('lottery:big_pool:round') ?: 1); + if ($small_round < $big_round) { + $this->redis->set('lottery:small_pool:round', $big_round); + } + } + /** * 缓存恢复:独立恢复大小轮次+对应金额 */ @@ -92,13 +114,17 @@ class LotteryService $big_total_gold = floatval($this->redis->get('lottery:big_pool:total_gold') ?: 0); // 加载Lua脚本 - $luaSha = LotteryGiftLua::getLotteryLuaScript(); + $luaSha = LotteryGiftLua::getLotteryLuaScripts(); // 执行Lua脚本(入参:small_round + big_round) $result = $this->redis->eval($luaSha, [ $send_uid, 0, $gift_gold, $small_trigger_times, $big_threshold, - $small_round, $big_round, $big_total_gold + $small_round, $big_round, $big_total_gold, + $this->bigPrizeWeights['60'], + $this->bigPrizeWeights['70'], + $this->bigPrizeWeights['80'], + $this->bigPrizeWeights['total'] ], 0); // var_dump($result);die; $result = json_decode($result, true); @@ -143,8 +169,8 @@ class LotteryService $winnerUid, 2, // 大奖 $result['big_prize_amount'],//中奖金额 - $result['big_total_gold'], // 开奖时大奖池金额 - $this->getBigRatio($result['big_prize_amount'], $result['big_total_gold']), + $result['big_pool_total_before_open'], // 开奖时大奖池金额 + $result['big_ratio'], $result['big_release_amount']//释放金额 ); @@ -153,7 +179,7 @@ class LotteryService 2, // 大奖池 4, // 释放 -$result['big_release_amount'],//释放金额 - $result['big_total_gold'],// 开奖时大奖池金额 + $result['big_pool_total_before_open'],// 开奖时大奖池金额 0, $giftId, $result['big_round'] - 1, // 关联已结束的小奖池轮次