From a1d2c4b24f2f687d8b8bd664a24e82f8f5d44473 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E9=92=8A?= Date: Wed, 10 Sep 2025 22:41:11 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B7=A1=E4=B9=90=E4=BC=9A=E6=8A=BD=E5=A5=96?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E6=8F=90=E4=BA=A4.-=E7=9B=B2=E7=9B=92?= =?UTF-8?q?=E8=BD=AC=E7=9B=98=E6=8A=BD=E5=A5=96=E6=96=B9=E6=B3=95=E9=87=8D?= =?UTF-8?q?=E6=9E=84=E3=80=82=E4=BC=98=E5=8C=96=E6=9F=A5=E8=AF=A2=E9=80=9F?= =?UTF-8?q?=E5=BA=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/model/BlindBoxTurntableGift.php | 539 +++++++++++------- 1 file changed, 347 insertions(+), 192 deletions(-) diff --git a/application/api/model/BlindBoxTurntableGift.php b/application/api/model/BlindBoxTurntableGift.php index 89da72d..3b875ee 100644 --- a/application/api/model/BlindBoxTurntableGift.php +++ b/application/api/model/BlindBoxTurntableGift.php @@ -63,7 +63,6 @@ class BlindBoxTurntableGift extends Model $result_data = [ 'title' => $box['name'], 'rule_url' => get_system_config_value('web_site')."/api/Page/get_gift_box_rule?box_id=".$box["id"], -// 'rule' => $ext['introd'], 'box_price' => $box_gift['gift_price'], 'is_xlh' => $is_xlh, 'xlh_data' => $xlh, @@ -71,19 +70,67 @@ class BlindBoxTurntableGift extends Model ]; return ['code' => 1, 'msg' => '获取成功', 'data' => $result_data]; } + /* * 抽奖 */ - public function draw_gift($gift_bag_id, $user_id, $gift_user_ids,$num=1,$room_id=0,$heart_id=0){ - //获取盲盒配置 - $bag_data = db::name("vs_gift_bag")->field('id,name,ext,periods')->where('id',$gift_bag_id)->find(); + public function draw_gift($gift_bag_id, $user_id, $gift_user_ids,$num=1,$room_id=0,$heart_id=0) + { + // 合并配置查询 + $bag_data = db::name("vs_gift_bag") + ->field('id,name,ext') + ->where('id',$gift_bag_id) + ->find(); + + if (!$bag_data) { + return ['code' => 0, 'msg' => '盲盒配置不存在', 'data' => null]; + } + $ext = json_decode($bag_data['ext'],true); - $bag_gift = db::name("vs_gift")->where(['gid'=>$ext['gift_id']])->find();// 获取盲盒信息 + + // 合并盲盒和礼物信息查询 + $bag_gift = db::name("vs_gift") + ->where(['gid'=>$ext['gift_id']]) + ->find(); + + if (!$bag_gift) { + return ['code' => 0, 'msg' => '盲盒礼物不存在', 'data' => null]; + } + + // 合并巡乐会配置查询 + $xlh_box = db::name('vs_gift_bag') + ->where('id',13) + ->find(); + + $xlh_ext = $xlh_box ? json_decode($xlh_box['ext'],true) : []; + + $xlh_is_piao_ping = 0; + + // 处理收礼用户数组(多个) $toarray = explode(',',$gift_user_ids); - $room = db::name('vs_room')->field('id,xlh_periods,xlh_periods_num,is_open_blind_box_turntable')->where(['id'=>$room_id])->find(); - //判断是否有足够的金币 - $user_waller = db::name('user_wallet')->where(['user_id'=>$user_id])->find(); - //抽奖总消耗金币 + + // 合并房间信息查询 + $room = db::name('vs_room') + ->field('id,room_name,xlh_periods,xlh_periods_num,is_open_blind_box_turntable') + ->where(['id'=>$room_id]) + ->find(); + + if (!$room) { + return ['code' => 0, 'msg' => '房间不存在', 'data' => null]; + } + + $this_xlh_periods_num = $room['xlh_periods_num'];//本期当前抽奖次数(巡乐会出发条件) + + // 判断是否有足够的金币 + $user_waller = db::name('user_wallet') + ->where(['user_id'=>$user_id]) + ->find(); + + if (!$user_waller) { + return ['code' => 0, 'msg' => '用户钱包不存在', 'data' => null]; + } + + // 抽奖总消耗金币 $bag_gift_price = $bag_gift['gift_price'] * $num; if ($user_waller['coin'] < $bag_gift_price) { return ['code' => 0, 'msg' => '用户金币不足', 'data' => null]; @@ -91,9 +138,94 @@ class BlindBoxTurntableGift extends Model if ($room['is_open_blind_box_turntable'] != 1) { return ['code' => 0, 'msg' => '该房间未开启盲盒转盘', 'data' => null]; } + + // 预计算抽奖结果,减少数据库事务中的查询 + // 计算期数和抽奖次数 + // 合并奖池总抽奖次数和房间奖池信息查询 + $room_pan_info = db::name("vs_gift_bag_detail") + ->alias('a') + ->join('vs_room_pan b', 'b.gift_bag_id = a.gift_bag_id AND b.room_id = ' . $room_id) + ->where(['a.gift_bag_id' => $gift_bag_id]) + ->field('SUM(a.quantity) as total_quantity, SUM(b.remaining_number) as total_remaining, b.periods') + ->find(); + + $total_quantity = $room_pan_info['total_quantity'] ?: 0; + $total_remaining = $room_pan_info['total_remaining'] ?: 0; + $periods = $room_pan_info['periods'] ?: 0; + + // 本期当前第多少次后抽奖 总的抽奖次数- 剩余数量 + $total_draw_times = $total_quantity - $total_remaining; + + // 预计算所有抽奖结果 + $precomputed_results = []; + $current_draw_times = $total_draw_times; + $current_periods = $periods; + $current_xlh_periods_num = $this_xlh_periods_num; + + // 获取所有可用礼物用于预计算 + $available_gifts = $this->get_available_gifts_for_precompute($gift_bag_id, $room_id, $current_draw_times); + + if (empty($available_gifts)) { + return ['code' => 0, 'msg' => '当前盲盒无可用礼物', 'data' => null]; + } + + // 预计算所有抽奖结果 + $should_reset_all_gifts = false; // 标记是否需要重置所有礼物 + foreach ($toarray as $gift_user_id) { + if($user_id == $gift_user_id){ + return ['code' => 0, 'msg' => "收礼人不能包含自己", 'data' => null]; + } + + for($i = 0; $i < $num; $i++){ + // 使用加权随机算法预计算单次抽奖结果 + $draw_result = $this->precompute_single_draw($available_gifts); + + if (!$draw_result) { + return ['code' => 0, 'msg' => '预计算抽奖失败', 'data' => null]; + } + + $precomputed_results[] = [ + 'gift_user_id' => $gift_user_id, + 'gift_bag_detail' => $draw_result['gift_bag_detail'], + 'gift' => $draw_result['gift'], + 'draw_times' => $current_draw_times, + 'periods' => $current_periods + ]; + + $current_draw_times++; + + // 判断巡乐会飘屏判断 + $current_xlh_periods_num++; + if(!empty($xlh_ext) && $xlh_ext['inlet_bag_id'] == $gift_bag_id && $current_xlh_periods_num == $xlh_ext['open_condition']['waiting_start_num']){ + $xlh_is_piao_ping = 1; + } + if(!empty($xlh_ext) && $xlh_ext['inlet_bag_id'] == $gift_bag_id && $current_xlh_periods_num == $xlh_ext['open_condition']['start_num']){ + $xlh_is_piao_ping = 2; + } + + // 更新可用礼物数量(模拟数据库更新) + $total_remaining_after_update = 0; + foreach ($available_gifts as &$gift) { + if ($gift['id'] == $draw_result['gift_bag_detail']['id']) { + $gift['remaining_number']--; + } + + // 计算更新后的总剩余数量 + $total_remaining_after_update += $gift['remaining_number']; + } + + // 检查是否需要重置所有礼物 + if ($total_remaining_after_update <= 0) { + $should_reset_all_gifts = true; + $current_periods++; // 增加期数 + } + } + } + + // 开始数据库事务处理 db::startTrans(); try{ - //盲盒转盘抽奖记录 + // 盲盒转盘抽奖记录 $box_turntable_log = db::name('vs_blind_box_turntable_log')->insertGetId([ 'user_id' => $user_id, 'gift_bag_id' => $gift_bag_id, @@ -106,57 +238,105 @@ class BlindBoxTurntableGift extends Model db::rollback(); return ['code' => 0, 'msg' => '添加盲盒转盘记录失败', 'data' => null]; } - foreach ($toarray as $gift_user_id){ - if($user_id == $gift_user_id){ - db::rollback(); - return ['code' => 0, 'msg' => "收礼人不能包含自己", 'data' => null]; - } - for($i = 0; $i < $num; $i++){ - $reslut_draw_gift_data = $this->draw_gift_one($gift_bag_id, $user_id, $gift_user_id,$bag_gift['gift_price'],$room_id,$box_turntable_log); - if($reslut_draw_gift_data['code'] != 1){ - db::rollback(); - return ['code' => 0, 'msg' => $reslut_draw_gift_data['msg'], 'data' => null]; - } - $reslut_draw_gift[] = $reslut_draw_gift_data['data']; - } - } - $reslut_gift = []; - $reslut_data = []; - foreach ($reslut_draw_gift as $key => $value) { - $gift_user_id = $value['gift_user_id']; - $gift_id = $value['gift_id']; - // 以 gift_user_id 和 gift_id 作为键进行分组 - $group_key = $gift_user_id . '_' . $gift_id; + // 处理预计算的抽奖结果 + $result_draw_gift = []; + $gift_counts = []; // 统计每个礼物的数量 + $gift_user_counts = []; // 统计每个用户每个礼物的数量 - if (!isset($reslut_gift[$group_key])) { - $reslut_gift[$group_key] = [ + foreach ($precomputed_results as $result) { + $gift_user_id = $result['gift_user_id']; + $gift_bag_detail = $result['gift_bag_detail']; + $gift = $result['gift']; + + // 构造返回数据 + $result_data = [ + 'user_id' => $user_id, + 'gift_user_id' => $gift_user_id, + 'gift_id' => $gift_bag_detail['foreign_id'], + 'gift_price' => $gift['gift_price'], + 'is_public_screen' => $gift['is_public_screen'], + 'periods' => $result['periods'], + ]; + $result_draw_gift[] = $result_data; + + // 统计礼物数量 + $gift_id = $gift_bag_detail['foreign_id']; + if (!isset($gift_counts[$gift_id])) { + $gift_counts[$gift_id] = [ + 'gift_id' => $gift_id, + 'count' => 0, + 'gift_price' => $gift['gift_price'] + ]; + } + $gift_counts[$gift_id]['count']++; + + // 统计用户礼物数量 + $user_gift_key = $gift_user_id . '_' . $gift_id; + if (!isset($gift_user_counts[$user_gift_key])) { + $gift_user_counts[$user_gift_key] = [ 'gift_user_id' => $gift_user_id, 'gift_id' => $gift_id, - 'count' => 1, - 'gift_price' => $value['gift_price'] + 'count' => 0, + 'gift_price' => $gift['gift_price'] ]; - } else { - $reslut_gift[$group_key]['count']++; } - if (!isset($reslut_data[$gift_id])) { - $reslut_data[$gift_id] = [ - 'gift_id' => $gift_id, - 'count' => 1 - ]; - }else { - $reslut_data[$gift_id]['count']++; + $gift_user_counts[$user_gift_key]['count']++; + + // 处理礼包发放记录表 + $data = []; + $data['user_id'] = $user_id; + $data['gift_user_id'] = $gift_user_id; + $data['parent_id'] = $box_turntable_log; + $data['gift_bag_id'] = $gift_bag_id; + $data['gift_id'] = $gift_bag_detail['foreign_id']; + $data['periods'] = $result['periods']; + $data['room_id'] = $room_id; + $data['gift_price'] = $gift['gift_price']; + $data['bag_price'] = $bag_gift['gift_price']; + $data['createtime'] = time(); + $insert_result = db::name("vs_gift_bag_receive_log")->insert($data); + if(!$insert_result){ + db::rollback(); + return ['code' => 0, 'msg' => '插入礼包发放记录失败', 'data' => []]; + } + + // 减去盲盒包礼物数量 + $ret = db::name("vs_room_pan") + ->where(['room_id'=>$room_id,'gift_bag_detail_id'=>$gift_bag_detail['id']]) + ->setDec('remaining_number',1); + + if(!$ret){ + db::rollback(); + return ['code' => 0, 'msg' => '更新礼物剩余数量失败', 'data' => []]; } } - $reslut_gift = array_values($reslut_gift); - foreach ($reslut_gift as $key => $value) { + + // 处理奖池重置操作 + if ($should_reset_all_gifts) { + // 重置奖池中所有礼物数量 + db::name("vs_room_pan") + ->where(['room_id'=>$room_id,'gift_bag_id'=>$gift_bag_id]) + ->update([ + 'remaining_number' => db::raw('(SELECT quantity FROM fa_vs_gift_bag_detail WHERE id = fa_vs_room_pan.gift_bag_detail_id)'), + 'periods' => $current_periods + ]); + + // 更新总期数 + db::name("vs_gift_bag") + ->where('id', $gift_bag_id) + ->setInc('periods'); + } + + // 批量插入盲盒转盘结果记录 + foreach ($gift_user_counts as $user_gift) { $ret = db::name('vs_blind_box_turntable_results_log')->insert([ 'tid' => $box_turntable_log, - 'gift_user_id' => $value['gift_user_id'], - 'gift_id' => $value['gift_id'], - 'count' => $value['count'], - 'gift_price' => $value['gift_price'], - 'all_gift_price' => $value['gift_price'] * $value['count'], + 'gift_user_id' => $user_gift['gift_user_id'], + 'gift_id' => $user_gift['gift_id'], + 'count' => $user_gift['count'], + 'gift_price' => $user_gift['gift_price'], + 'all_gift_price' => $user_gift['gift_price'] * $user_gift['count'], 'createtime' => time(), 'heart_id' => $heart_id ]); @@ -165,14 +345,15 @@ class BlindBoxTurntableGift extends Model 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,'盲盒转盘抽奖消耗'); if(!$wallet_update){ Db::rollback(); return ['code' => 0, 'msg' => '扣除用户金币失败', 'data' => null]; } - //用户财富等级更新 + // 用户财富等级更新 $user_level = model('Level')->user_level_data_update($user_id,$bag_gift_price,1,$room_id); if(!$user_level){ Db::rollback(); @@ -184,132 +365,16 @@ class BlindBoxTurntableGift extends Model db::rollback(); return V(0,$e->getMessage()); } - //巡乐会 - $xlh_box = db::name('vs_gift_bag')->where('id',13)->find(); - $xlh_ext = json_decode($xlh_box['ext'],true); + + // 巡乐会 $xlh = []; - if($xlh_ext['inlet_bag_id'] == $bag_data['id']){ - $xlh['waiting_start_num'] = $xlh_ext['open_condition']['waiting_start_num'];//等待开奖次数 - $xlh['start_num'] = $xlh_ext['open_condition']['start_num'];//开始开奖次数 - //当前抽奖次数 - $xlh['current_num'] = db::name('vs_room')->where(['id'=>$room_id])->value('xlh_periods_num'); - //状态 - if($xlh['current_num'] >= $xlh_ext['open_condition']['start_num']){ - $xlh['status'] = 1;//状态 1:巡乐会开始 2:即将开始开始 0:等待开始 - } elseif($xlh['current_num'] >= $xlh_ext['open_condition']['waiting_start_num'] && $xlh['current_num'] < $xlh_ext['open_condition']['start_num']){ - $xlh['status'] = 2;//状态 1:巡乐会开始 2:即将开始开始 0:等待开始 - }else{ - $xlh['status'] = 0; - } - //推送 - $text = [ - 'xlh_data' => $xlh, - 'text' => "" - ]; - //聊天室推送系统消息 - model('Chat')->sendMsg(1056,$room_id,$text); - } - $reslut = []; - $reslut['blind_box_turntable_id'] = $box_turntable_log; - $reslut['reslut_list'] = array_values($reslut_data); - return V(1,"成功", $reslut); - } - /* - * 单人单次抽奖 - */ - public function draw_gift_one($gift_bag_id, $user_id, $gift_user_id,$gift_price,$room_id=0,$box_turntable_log=0){ - //奖池总的抽奖次数 - $total_quantity = db::name("vs_gift_bag_detail")->where(['gift_bag_id' => $gift_bag_id])->sum('quantity'); - $room_pan = db::name("vs_room_pan")->where(['room_id'=>$room_id,'gift_bag_id'=>$gift_bag_id])->field('remaining_number,periods')->find(); - $total_remaining = $room_pan['remaining_number']; - $periods = $room_pan['periods']; - //本期当前第多少次后抽奖 总的抽奖次数- 剩余数量 - $total_draw_times = $total_quantity - $total_remaining; - //随机获取一个礼物 - $where = [ - 'a.gift_bag_id' => $gift_bag_id, - 'a.quantity' => ['>',0], - 'b.remaining_number' => ['>',0], - 'b.room_id' => $room_id, - 'a.weight' => ['<=', $total_draw_times], - ]; - // 使用闭包条件来处理复杂的 weight 逻辑 -// $where['a.weight'] = ['exp', Db::raw('= 0 OR a.weight < '.$total_draw_times)]; - // 优化:基于剩余数量的加权随机选择 - $gift_bag_details = db::name("vs_gift_bag_detail") - ->field('a.id,a.quantity,b.remaining_number,a.weight,a.foreign_id') - ->alias('a') - ->join('vs_room_pan b','b.gift_bag_detail_id = a.id','left') - ->where($where) - ->select(); - if (empty($gift_bag_details)) { - return ['code' => 0, 'msg' => '当前盲盒无可用礼物', 'data' => []]; - } - // 实现加权随机算法:剩余数量越多,被抽中的概率越大 - $remaining = 0; - foreach ($gift_bag_details as $gift) { - $remaining += $gift['remaining_number']; - } - $rand_value = mt_rand(1, $remaining); - $current_sum = 0; - $gift_bag_detail = null; - foreach ($gift_bag_details as $gift) { - if($gift['remaining_number'] <= 0){ - continue; - } - $current_sum += $gift['remaining_number']; - if ($rand_value <= $current_sum) { - $gift_bag_detail = $gift; - break; - } - } - if($gift_bag_detail){ - //获取开出礼物的信息 - $gift = db::name("vs_gift")->where(['gid'=>$gift_bag_detail['foreign_id']])->find(); - //处理礼包发放记录表 - $data = []; - $data['user_id'] = $user_id; - $data['gift_user_id'] = $gift_user_id; - $data['parent_id'] = $box_turntable_log; - $data['gift_bag_id'] = $gift_bag_id; - $data['gift_id'] = $gift_bag_detail['foreign_id']; - $data['periods'] = $periods; - $data['room_id'] = $room_id; - $data['gift_price'] = $gift['gift_price']; - $data['bag_price'] = $gift_price; - $data['createtime'] = time(); - $result = db::name("vs_gift_bag_receive_log")->insert($data); - if(!$result){ - return ['code' => 0, 'msg' => '失败,', 'data' => []]; - } - //减去盲盒包礼物数量 -// $ret = db::name("vs_gift_bag_detail")->where('id',$gift_bag_detail['id'])->setDec('remaining_number'); - $ret = db::name("vs_room_pan")->where(['room_id'=>$room_id,'gift_bag_detail_id'=>$gift_bag_detail['id']])->setDec('remaining_number',1); - if(!$ret){ - return ['code' => 0, 'msg' => '失败.', 'data' => []]; - } - //判断剩余数量是否为0 为0重置,进入下一期 - $gift_bag_num = db::name("vs_room_pan")->where(['room_id'=>$room_id,'gift_bag_id'=>$gift_bag_id])->sum('remaining_number'); - if($gift_bag_num <= 0){ - db::name("vs_gift_bag")->where('id',$gift_bag_id)->setInc('periods'); - db::name("vs_room_pan")->where(['room_id'=>$room_id,'gift_bag_id'=>$gift_bag_id])->setInc('periods'); - db::name("vs_room_pan")->where(['room_id'=>$room_id,'gift_bag_id'=>$gift_bag_id])->update( - ['remaining_number' => db::raw('(SELECT quantity FROM fa_vs_gift_bag_detail WHERE id = fa_vs_room_pan.gift_bag_detail_id)')]); - } - }else{ - return ['code' => 0, 'msg' => '失败!', 'data' => []]; - } - //巡乐会飘屏 - $xlh_box = db::name('vs_gift_bag')->where('id',13)->find(); - $xlh_ext = json_decode($xlh_box['ext'],true); - if($xlh_ext['inlet_bag_id'] == $gift_bag_id){ - db::name("vs_room")->where('id',$room_id)->setInc('xlh_periods_num');//加巡乐会条件次数 - $room = Db::name('vs_room')->field('room_name,xlh_periods,xlh_periods_num')->where(['id' => $room_id, 'apply_status' => 2])->find(); - if($room['xlh_periods_num'] == $xlh_ext['open_condition']['waiting_start_num']){ - $room_name = Db::name('vs_room')->where(['id' => $room_id, 'apply_status' => 2])->value('room_name'); - //即将开始推送飘屏 - $text = $room_name."的巡乐会即将开始,请大家尽快参与哦!"; - //推送礼物横幅 + if(!empty($xlh_ext) && $xlh_ext['inlet_bag_id'] == $gift_bag_id){ + // 巡乐会飘屏 + db::name("vs_room")->where('id',$room_id)->setInc('xlh_periods_num',$num);//加巡乐会条件次数 + if($xlh_is_piao_ping == 1){ + // 即将开始推送飘屏 + $text = $room['room_name']."的巡乐会即将开始,请大家尽快参与哦!"; + // 推送礼物横幅 $push = new Push(UID, $room_id); $text_list_new = [ 'text' => $text, @@ -318,10 +383,10 @@ class BlindBoxTurntableGift extends Model ]; $push->xunlehui($text_list_new); } - if($room['xlh_periods_num'] == $xlh_ext['open_condition']['start_num']){ - //正式开始推送飘屏 + if($xlh_is_piao_ping == 2){ + // 正式开始推送飘屏 $text = $room['room_name']."的巡乐会正式开始,请大家尽快参与哦!"; - //推送礼物横幅 + // 推送礼物横幅 $push = new Push(UID, $room_id); $text_list_new = [ 'text' => $text, @@ -329,7 +394,7 @@ class BlindBoxTurntableGift extends Model 'from_type' => 2 ]; $push->xunlehui($text_list_new); - //巡乐会正式开始 + // 巡乐会正式开始 $pan_xlh_id = db::name('vs_room_pan_xlh')->insertGetId([ 'room_id' => $room_id, 'gift_id' => $xlh_ext['locking_condition']['locking_gift_id'], @@ -340,19 +405,109 @@ class BlindBoxTurntableGift extends Model 'createtime' => time() ]); if(!$pan_xlh_id){ - return ['code' => 0, 'msg' => '失败!', 'data' => []]; + return ['code' => 0, 'msg' => '创建巡乐会失败!', 'data' => []]; } - db::name("vs_room")->where('id',$room_id)->setInc('xlh_periods');//修给巡乐会期数 + db::name("vs_room")->where('id',$room_id)->setInc('xlh_periods');//修改巡乐会期数 + } + + $xlh['waiting_start_num'] = $xlh_ext['open_condition']['waiting_start_num'];//等待开奖次数 + $xlh['start_num'] = $xlh_ext['open_condition']['start_num'];//开始开奖次数 + // 当前抽奖次数 + $xlh['current_num'] = $current_xlh_periods_num; + // 状态 + if($xlh['current_num'] >= $xlh_ext['open_condition']['start_num']){ + $xlh['status'] = 1;//状态 1:巡乐会开始 2:即将开始开始 0:等待开始 + } elseif($xlh['current_num'] >= $xlh_ext['open_condition']['waiting_start_num'] && $xlh['current_num'] < $xlh_ext['open_condition']['start_num']){ + $xlh['status'] = 2;//状态 1:巡乐会开始 2:即将开始开始 0:等待开始 + }else{ + $xlh['status'] = 0; + } + // 推送 + $text = [ + 'xlh_data' => $xlh, + 'text' => "" + ]; + // 聊天室推送系统消息 + model('Chat')->sendMsg(1056,$room_id,$text); + } + + // 整理返回结果 + $result_list = []; + foreach ($gift_counts as $gift) { + $result_list[] = [ + 'gift_id' => $gift['gift_id'], + 'count' => $gift['count'] + ]; + } + $reslut = []; + $reslut['blind_box_turntable_id'] = $box_turntable_log; + $reslut['reslut_list'] = $result_list; + return V(1,"成功", $reslut); + } + + /* + * 获取可用礼物用于预计算 + */ + private function get_available_gifts_for_precompute($gift_bag_id, $room_id, $total_draw_times) { + $where = [ + 'a.gift_bag_id' => $gift_bag_id, + 'a.quantity' => ['>',0], + 'b.remaining_number' => ['>',0], + 'b.room_id' => $room_id, + 'a.weight' => ['<=', $total_draw_times], + ]; + + return db::name("vs_gift_bag_detail") + ->field('a.id,a.quantity,b.remaining_number,a.weight,a.foreign_id') + ->alias('a') + ->join('vs_room_pan b','b.gift_bag_detail_id = a.id','left') + ->where($where) + ->select(); + } + + /* + * 预计算单次抽奖结果 + */ + private function precompute_single_draw($available_gifts) { + if (empty($available_gifts)) { + return false; + } + + // 实现加权随机算法:剩余数量越多,被抽中的概率越大 + $remaining = 0; + foreach ($available_gifts as $gift) { + $remaining += $gift['remaining_number']; + } + + $rand_value = mt_rand(1, $remaining); + $current_sum = 0; + $selected_gift = null; + + foreach ($available_gifts as $gift) { + if($gift['remaining_number'] <= 0){ + continue; + } + $current_sum += $gift['remaining_number']; + if ($rand_value <= $current_sum) { + $selected_gift = $gift; + break; } } - $result_data = [ - 'user_id' => $user_id, - 'gift_user_id'=>$gift_user_id, - 'gift_id'=>$gift_bag_detail['foreign_id'], - 'gift_price'=>$gift['gift_price'], - 'is_public_screen'=>$gift['is_public_screen'], + if (!$selected_gift) { + return false; + } + // 获取开出礼物的信息 + $gift = db::name("vs_gift") + ->where(['gid'=>$selected_gift['foreign_id']]) + ->find(); + + if (!$gift) { + return false; + } + return [ + 'gift_bag_detail' => $selected_gift, + 'gift' => $gift ]; - return ['code' => 1, 'msg' => '成功', 'data' => $result_data]; } /*