巡乐会抽奖接口提交.-盲盒转盘抽奖方法重构。优化查询速度
This commit is contained in:
@@ -63,7 +63,6 @@ class BlindBoxTurntableGift extends Model
|
|||||||
$result_data = [
|
$result_data = [
|
||||||
'title' => $box['name'],
|
'title' => $box['name'],
|
||||||
'rule_url' => get_system_config_value('web_site')."/api/Page/get_gift_box_rule?box_id=".$box["id"],
|
'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'],
|
'box_price' => $box_gift['gift_price'],
|
||||||
'is_xlh' => $is_xlh,
|
'is_xlh' => $is_xlh,
|
||||||
'xlh_data' => $xlh,
|
'xlh_data' => $xlh,
|
||||||
@@ -71,19 +70,67 @@ class BlindBoxTurntableGift extends Model
|
|||||||
];
|
];
|
||||||
return ['code' => 1, 'msg' => '获取成功', 'data' => $result_data];
|
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){
|
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();
|
// 合并配置查询
|
||||||
|
$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);
|
$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);
|
$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;
|
$bag_gift_price = $bag_gift['gift_price'] * $num;
|
||||||
if ($user_waller['coin'] < $bag_gift_price) {
|
if ($user_waller['coin'] < $bag_gift_price) {
|
||||||
return ['code' => 0, 'msg' => '用户金币不足', 'data' => null];
|
return ['code' => 0, 'msg' => '用户金币不足', 'data' => null];
|
||||||
@@ -91,9 +138,94 @@ class BlindBoxTurntableGift extends Model
|
|||||||
if ($room['is_open_blind_box_turntable'] != 1) {
|
if ($room['is_open_blind_box_turntable'] != 1) {
|
||||||
return ['code' => 0, 'msg' => '该房间未开启盲盒转盘', 'data' => null];
|
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();
|
db::startTrans();
|
||||||
try{
|
try{
|
||||||
//盲盒转盘抽奖记录
|
// 盲盒转盘抽奖记录
|
||||||
$box_turntable_log = db::name('vs_blind_box_turntable_log')->insertGetId([
|
$box_turntable_log = db::name('vs_blind_box_turntable_log')->insertGetId([
|
||||||
'user_id' => $user_id,
|
'user_id' => $user_id,
|
||||||
'gift_bag_id' => $gift_bag_id,
|
'gift_bag_id' => $gift_bag_id,
|
||||||
@@ -106,57 +238,105 @@ class BlindBoxTurntableGift extends Model
|
|||||||
db::rollback();
|
db::rollback();
|
||||||
return ['code' => 0, 'msg' => '添加盲盒转盘记录失败', 'data' => null];
|
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])) {
|
foreach ($precomputed_results as $result) {
|
||||||
$reslut_gift[$group_key] = [
|
$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_user_id' => $gift_user_id,
|
||||||
'gift_id' => $gift_id,
|
'gift_id' => $gift_id,
|
||||||
'count' => 1,
|
'count' => 0,
|
||||||
'gift_price' => $value['gift_price']
|
'gift_price' => $gift['gift_price']
|
||||||
];
|
];
|
||||||
} else {
|
|
||||||
$reslut_gift[$group_key]['count']++;
|
|
||||||
}
|
}
|
||||||
if (!isset($reslut_data[$gift_id])) {
|
$gift_user_counts[$user_gift_key]['count']++;
|
||||||
$reslut_data[$gift_id] = [
|
|
||||||
'gift_id' => $gift_id,
|
// 处理礼包发放记录表
|
||||||
'count' => 1
|
$data = [];
|
||||||
];
|
$data['user_id'] = $user_id;
|
||||||
}else {
|
$data['gift_user_id'] = $gift_user_id;
|
||||||
$reslut_data[$gift_id]['count']++;
|
$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([
|
$ret = db::name('vs_blind_box_turntable_results_log')->insert([
|
||||||
'tid' => $box_turntable_log,
|
'tid' => $box_turntable_log,
|
||||||
'gift_user_id' => $value['gift_user_id'],
|
'gift_user_id' => $user_gift['gift_user_id'],
|
||||||
'gift_id' => $value['gift_id'],
|
'gift_id' => $user_gift['gift_id'],
|
||||||
'count' => $value['count'],
|
'count' => $user_gift['count'],
|
||||||
'gift_price' => $value['gift_price'],
|
'gift_price' => $user_gift['gift_price'],
|
||||||
'all_gift_price' => $value['gift_price'] * $value['count'],
|
'all_gift_price' => $user_gift['gift_price'] * $user_gift['count'],
|
||||||
'createtime' => time(),
|
'createtime' => time(),
|
||||||
'heart_id' => $heart_id
|
'heart_id' => $heart_id
|
||||||
]);
|
]);
|
||||||
@@ -165,14 +345,15 @@ class BlindBoxTurntableGift extends Model
|
|||||||
return ['code' => 0, 'msg' => '添加盲盒转盘结果记录失败', 'data' => null];
|
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,'盲盒转盘抽奖消耗');
|
$wallet_update = model('GiveGift')->change_user_cion_or_earnings_log($user_id,$bag_gift_price,$room_id,1,10,'盲盒转盘抽奖消耗');
|
||||||
if(!$wallet_update){
|
if(!$wallet_update){
|
||||||
Db::rollback();
|
Db::rollback();
|
||||||
return ['code' => 0, 'msg' => '扣除用户金币失败', 'data' => null];
|
return ['code' => 0, 'msg' => '扣除用户金币失败', 'data' => null];
|
||||||
}
|
}
|
||||||
//用户财富等级更新
|
// 用户财富等级更新
|
||||||
$user_level = model('Level')->user_level_data_update($user_id,$bag_gift_price,1,$room_id);
|
$user_level = model('Level')->user_level_data_update($user_id,$bag_gift_price,1,$room_id);
|
||||||
if(!$user_level){
|
if(!$user_level){
|
||||||
Db::rollback();
|
Db::rollback();
|
||||||
@@ -184,132 +365,16 @@ class BlindBoxTurntableGift extends Model
|
|||||||
db::rollback();
|
db::rollback();
|
||||||
return V(0,$e->getMessage());
|
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 = [];
|
$xlh = [];
|
||||||
if($xlh_ext['inlet_bag_id'] == $bag_data['id']){
|
if(!empty($xlh_ext) && $xlh_ext['inlet_bag_id'] == $gift_bag_id){
|
||||||
$xlh['waiting_start_num'] = $xlh_ext['open_condition']['waiting_start_num'];//等待开奖次数
|
// 巡乐会飘屏
|
||||||
$xlh['start_num'] = $xlh_ext['open_condition']['start_num'];//开始开奖次数
|
db::name("vs_room")->where('id',$room_id)->setInc('xlh_periods_num',$num);//加巡乐会条件次数
|
||||||
//当前抽奖次数
|
if($xlh_is_piao_ping == 1){
|
||||||
$xlh['current_num'] = db::name('vs_room')->where(['id'=>$room_id])->value('xlh_periods_num');
|
// 即将开始推送飘屏
|
||||||
//状态
|
$text = $room['room_name']."的巡乐会即将开始,请大家尽快参与哦!";
|
||||||
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."的巡乐会即将开始,请大家尽快参与哦!";
|
|
||||||
//推送礼物横幅
|
|
||||||
$push = new Push(UID, $room_id);
|
$push = new Push(UID, $room_id);
|
||||||
$text_list_new = [
|
$text_list_new = [
|
||||||
'text' => $text,
|
'text' => $text,
|
||||||
@@ -318,10 +383,10 @@ class BlindBoxTurntableGift extends Model
|
|||||||
];
|
];
|
||||||
$push->xunlehui($text_list_new);
|
$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']."的巡乐会正式开始,请大家尽快参与哦!";
|
$text = $room['room_name']."的巡乐会正式开始,请大家尽快参与哦!";
|
||||||
//推送礼物横幅
|
// 推送礼物横幅
|
||||||
$push = new Push(UID, $room_id);
|
$push = new Push(UID, $room_id);
|
||||||
$text_list_new = [
|
$text_list_new = [
|
||||||
'text' => $text,
|
'text' => $text,
|
||||||
@@ -329,7 +394,7 @@ class BlindBoxTurntableGift extends Model
|
|||||||
'from_type' => 2
|
'from_type' => 2
|
||||||
];
|
];
|
||||||
$push->xunlehui($text_list_new);
|
$push->xunlehui($text_list_new);
|
||||||
//巡乐会正式开始
|
// 巡乐会正式开始
|
||||||
$pan_xlh_id = db::name('vs_room_pan_xlh')->insertGetId([
|
$pan_xlh_id = db::name('vs_room_pan_xlh')->insertGetId([
|
||||||
'room_id' => $room_id,
|
'room_id' => $room_id,
|
||||||
'gift_id' => $xlh_ext['locking_condition']['locking_gift_id'],
|
'gift_id' => $xlh_ext['locking_condition']['locking_gift_id'],
|
||||||
@@ -340,19 +405,109 @@ class BlindBoxTurntableGift extends Model
|
|||||||
'createtime' => time()
|
'createtime' => time()
|
||||||
]);
|
]);
|
||||||
if(!$pan_xlh_id){
|
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 = [
|
if (!$selected_gift) {
|
||||||
'user_id' => $user_id,
|
return false;
|
||||||
'gift_user_id'=>$gift_user_id,
|
}
|
||||||
'gift_id'=>$gift_bag_detail['foreign_id'],
|
// 获取开出礼物的信息
|
||||||
'gift_price'=>$gift['gift_price'],
|
$gift = db::name("vs_gift")
|
||||||
'is_public_screen'=>$gift['is_public_screen'],
|
->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];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
Reference in New Issue
Block a user