793 lines
38 KiB
PHP
793 lines
38 KiB
PHP
<?php
|
||
|
||
namespace app\api\model;
|
||
use app\common\controller\Push;
|
||
use think\Cache;
|
||
use think\Model;
|
||
use think\Db;
|
||
use think\Session;
|
||
/*
|
||
* 盲盒转盘
|
||
* 2025-08-16
|
||
*/
|
||
class BlindBoxTurntableGift extends Model
|
||
{
|
||
// 开启自动写入时间戳字段
|
||
protected $autoWriteTimestamp = true;
|
||
// 定义时间戳字段名
|
||
protected $createTime = 'createtime';
|
||
protected $updateTime = 'updatetime';
|
||
protected $table = 'fa_vs_gift';
|
||
|
||
//获取奖池礼物列表
|
||
public function get_gift_list($gift_bag_id,$room_id)
|
||
{
|
||
$box = db::name('vs_gift_bag')->where('id',$gift_bag_id)->find();
|
||
$gifts = db::name('vs_gift_bag_detail')->where('gift_bag_id',$gift_bag_id)->order("id desc")->select();
|
||
$gift_list = [];
|
||
foreach ($gifts as $key => $value) {
|
||
$gift_data = db::name('vs_gift')->where('gid',$value['foreign_id'])->where('delete_time',0)->find();
|
||
if($gift_data){
|
||
$gift_list[$key]['number'] = $key;
|
||
$gift_list[$key]['gift_id'] = $gift_data['gid'];
|
||
$gift_list[$key]['gift_name'] = $gift_data['gift_name'];
|
||
$gift_list[$key]['base_image'] = $gift_data['base_image'];
|
||
$gift_list[$key]['play_image'] = $gift_data['play_image'];
|
||
$gift_list[$key]['gift_price'] = $gift_data['gift_price'];
|
||
}
|
||
}
|
||
$ext = json_decode($box['ext'],true);
|
||
$box_gift = Db::name('vs_gift')->where('gid',$ext['gift_id'])->find();
|
||
|
||
//巡乐会
|
||
$is_xlh = 0;
|
||
$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'] == $box['id']){
|
||
$room = db::name('vs_room')->field('id,xlh_periods,xlh_periods_num')->where(['id'=>$room_id])->find();
|
||
$is_xlh = 1;
|
||
$xlh['waiting_start_num'] = $xlh_ext['open_condition']['waiting_start_num'];//等待开奖次数
|
||
$xlh['start_num'] = $xlh_ext['open_condition']['start_num'];//开始开奖次数
|
||
//当前抽奖次数
|
||
$xlh['current_num'] = $room['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;
|
||
}
|
||
}
|
||
$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,
|
||
'gift_list' => $gift_list,
|
||
];
|
||
return ['code' => 1, 'msg' => '获取成功', 'data' => $result_data];
|
||
}
|
||
/*
|
||
* 抽奖
|
||
*/
|
||
public function draw_gift($gift_bag_id, $user_id, $gift_user_ids,$num=1,$room_id=0){
|
||
//获取盲盒配置
|
||
$bag_data = db::name("vs_gift_bag")->field('id,name,ext,periods')->where('id',$gift_bag_id)->find();
|
||
$ext = json_decode($bag_data['ext'],true);
|
||
$bag_gift = db::name("vs_gift")->where(['gid'=>$ext['gift_id']])->find();// 获取盲盒信息
|
||
$toarray = explode(',',$gift_user_ids);
|
||
$room = db::name('vs_room')->field('id,xlh_periods,xlh_periods_num,is_open_blind_box_turntable,blind_box_turntable_periods')->where(['id'=>$room_id])->find();
|
||
//判断是否有足够的金币
|
||
$user_waller = db::name('user_wallet')->where(['user_id'=>$user_id])->find();
|
||
//抽奖总消耗金币
|
||
$bag_gift_price = $bag_gift['gift_price'] * $num;
|
||
if ($user_waller['coin'] < $bag_gift_price) {
|
||
return ['code' => 0, 'msg' => '用户金币不足', 'data' => null];
|
||
}
|
||
if ($room['is_open_blind_box_turntable'] != 1) {
|
||
return ['code' => 0, 'msg' => '该房间未开启盲盒转盘', 'data' => null];
|
||
}
|
||
db::startTrans();
|
||
try{
|
||
//盲盒转盘抽奖记录
|
||
$box_turntable_log = db::name('vs_blind_box_turntable_log')->insertGetId([
|
||
'user_id' => $user_id,
|
||
'gift_bag_id' => $gift_bag_id,
|
||
'num' => $num,
|
||
'room_id' => $room_id,
|
||
'bag_price' => $bag_gift['gift_price'],
|
||
'createtime' => time()
|
||
]);
|
||
if (!$box_turntable_log) {
|
||
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;
|
||
|
||
if (!isset($reslut_gift[$group_key])) {
|
||
$reslut_gift[$group_key] = [
|
||
'gift_user_id' => $gift_user_id,
|
||
'gift_id' => $gift_id,
|
||
'count' => 1,
|
||
'gift_price' => $value['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']++;
|
||
}
|
||
}
|
||
$reslut_gift = array_values($reslut_gift);
|
||
foreach ($reslut_gift as $key => $value) {
|
||
$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'],
|
||
'createtime' => time()
|
||
]);
|
||
if (!$ret) {
|
||
db::rollback();
|
||
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();
|
||
return ['code' => 0, 'msg' => '用户等级更新失败', 'data' => null];
|
||
}
|
||
|
||
db::commit();
|
||
} catch(\Exception $e) {
|
||
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")->where('id',$room_id)->setInc('blind_box_turntable_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,blind_box_turntable_periods,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);
|
||
$text_list_new = [
|
||
'text' => $text,
|
||
'room_id' => $room_id,
|
||
'from_type' => 1
|
||
];
|
||
$push->xunlehui($text_list_new);
|
||
}
|
||
if($room['xlh_periods_num'] == $xlh_ext['open_condition']['start_num']){
|
||
//正式开始推送飘屏
|
||
$text = $room['room_name']."的巡乐会正式开始,请大家尽快参与哦!";
|
||
//推送礼物横幅
|
||
$push = new Push(UID, $room_id);
|
||
$text_list_new = [
|
||
'text' => $text,
|
||
'room_id' => $room_id,
|
||
'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'],
|
||
'homeowner_gift_id' => $xlh_ext['locking_condition']['give_homeowner_gift_id'],
|
||
'periods' => $room['xlh_periods']+1,
|
||
'num' => 0,
|
||
'end_time' => time() + $xlh_ext['locking_time']['end_time'] * 60,
|
||
'createtime' => time()
|
||
]);
|
||
if(!$pan_xlh_id){
|
||
return ['code' => 0, 'msg' => '失败!', 'data' => []];
|
||
}
|
||
db::name("vs_room")->where('id',$room_id)->setInc('xlh_periods');//修给巡乐会期数
|
||
}
|
||
}
|
||
$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'],
|
||
];
|
||
return ['code' => 1, 'msg' => '成功', 'data' => $result_data];
|
||
}
|
||
|
||
/*
|
||
* 礼物发放
|
||
*/
|
||
public function gift_send($send_id){
|
||
$blind_box_turntable = db('vs_blind_box_turntable_log')->where('id',$send_id)->find();
|
||
if(!$blind_box_turntable){
|
||
return ['code' => 0, 'msg' => '数据不存在','data' => null];
|
||
}
|
||
$blind_box_turntable_log = db('vs_blind_box_turntable_results_log')->where(['tid'=>$send_id])->select();
|
||
if(!$blind_box_turntable_log){
|
||
return ['code' => 0, 'msg' => '开奖数据不存在','data' => null];
|
||
}
|
||
//获取盲盒配置
|
||
foreach ($blind_box_turntable_log as $key => $value) {
|
||
if($value['is_sued'] == 1){ //礼物已发放就不再重复发放
|
||
continue;
|
||
}
|
||
$give_gift_ext['gift_id'] = $value['gift_id'];
|
||
$give_gift_ext['count'] = $value['count'];
|
||
$give_gift_ext['gift_price'] = $value['gift_price'];
|
||
$give_gift_ext['all_gift_price'] = $value['all_gift_price'];
|
||
$give_gift_ext['is_draw_gift'] = 1;
|
||
$res = model('GiveGift')->give_gift($blind_box_turntable['user_id'], $value['gift_user_id'], $value['gift_id'], $value['count'],2,1, $blind_box_turntable['room_id'],0,0,$give_gift_ext);
|
||
if (isset($res) && $res['code'] != 1) {
|
||
// return V(0, $res['msg']);
|
||
continue;
|
||
}
|
||
db('vs_blind_box_turntable_results_log')->where('id', $value['id'])->update(['is_sued' => 1, 'updatetime' => time()]);
|
||
}
|
||
return ['code' => 1, 'msg' => '成功', 'data' => null];
|
||
}
|
||
|
||
/*
|
||
* 获取用户抽奖记录
|
||
*/
|
||
public function get_user_record($gift_bag_id,$user_id=0,$page=1,$page_size=12){
|
||
$where = [];
|
||
$where['b.gift_bag_id'] = $gift_bag_id;
|
||
if($user_id > 0){
|
||
$where['b.user_id'] = $user_id;
|
||
}
|
||
$list = db('vs_blind_box_turntable_results_log')
|
||
->alias('a')
|
||
->join('vs_blind_box_turntable_log b','b.id = a.tid','left')
|
||
->join('user c','a.gift_user_id = c.id','left')
|
||
->join('vs_gift d','d.gid = a.gift_id','left')
|
||
->field('a.gift_id,a.count,a.gift_user_id,b.createtime,c.nickname,d.gift_name as gift_name,d.base_image')
|
||
->where($where)
|
||
->page($page,$page_size)
|
||
->select();
|
||
foreach ($list as &$v){
|
||
$v['createtime'] = date('Y-m-d H:i:s',$v['createtime']);
|
||
}
|
||
return ['code' => 1, 'msg' => '成功', 'data' => $list];
|
||
}
|
||
/*
|
||
* 获取全服抽奖记录
|
||
*/
|
||
public function get_all_record($gift_bag_id,$page=1,$page_size=12){
|
||
$where = [];
|
||
$where['b.gift_bag_id'] = $gift_bag_id;
|
||
$where['d.gift_bag_id'] = $gift_bag_id;
|
||
$where['d.is_world_show'] = 1;
|
||
$list = db('vs_blind_box_turntable_results_log')
|
||
->alias('a')
|
||
->join('vs_blind_box_turntable_log b','b.id = a.tid','left')
|
||
->join('user c','b.user_id = c.id','left')
|
||
->join('vs_gift_bag_detail d','d.foreign_id = a.gift_id','left')
|
||
->join('vs_gift e','e.gid = a.gift_id','left')
|
||
->field('a.gift_id,a.count,b.user_id,b.createtime,c.nickname,d.name as gift_name,e.base_image')
|
||
->where($where)
|
||
->page($page,$page_size)
|
||
->select();
|
||
foreach ($list as &$v){
|
||
$v['createtime'] = date('Y-m-d H:i:s',$v['createtime']);
|
||
}
|
||
return ['code' => 1, 'msg' => '成功', 'data' => $list];
|
||
}
|
||
/*
|
||
* 巡乐会
|
||
*/
|
||
public function xlh_gift_list($room_id){
|
||
$gift_bag_id = 13;
|
||
$xlh_box = db::name('vs_gift_bag')->where('id',$gift_bag_id)->find();
|
||
$xlh_ext = json_decode($xlh_box['ext'],true);
|
||
$gifts = db::name('vs_gift_bag_detail')->where('gift_bag_id',$gift_bag_id)->order("id desc")->select();
|
||
$gift_list = [];
|
||
foreach ($gifts as $key => $value) {
|
||
$gift_data = db::name('vs_gift')->where('gid',$value['foreign_id'])->where('delete_time',0)->find();
|
||
if($gift_data){
|
||
$gift_list[$key]['number'] = $key;
|
||
$gift_list[$key]['gift_id'] = $gift_data['gid'];
|
||
$gift_list[$key]['gift_name'] = $gift_data['gift_name'];
|
||
$gift_list[$key]['base_image'] = $gift_data['base_image'];
|
||
$gift_list[$key]['play_image'] = $gift_data['play_image'];
|
||
$gift_list[$key]['gift_price'] = $gift_data['gift_price'];
|
||
}
|
||
}
|
||
//房主礼物
|
||
$room_user_gift = db::name('vs_gift')->where('gid',$xlh_ext['locking_condition']['give_homeowner_gift_id'])->find();
|
||
//巡乐会主礼物
|
||
$xlh_main_gift = db::name('vs_gift')->where('gid',$xlh_ext['locking_condition']['locking_gift_id'])->find();
|
||
//中奖用户
|
||
$xlh_periods = db::name('vs_room')->where('id',$room_id)->value('xlh_periods');
|
||
$pan_xlh = db::name('vs_room_pan_xlh')->where(['room_id'=>$room_id,'periods'=>$xlh_periods])->find();
|
||
if(empty($pan_xlh)){
|
||
return ['code' => 0, 'msg' => '未开始', 'data' => null];
|
||
}
|
||
$xlh_user_data= null;
|
||
if($pan_xlh['user_id']){
|
||
$xlh_user = db::name('user')->where('id',$pan_xlh['user_id'])->find();
|
||
$xlh_user_data = [
|
||
'user_id' => $xlh_user['id'],
|
||
'nickname' => $xlh_user['nickname'],
|
||
'avatar' => $xlh_user['avatar'],
|
||
];
|
||
}
|
||
$result_data = [
|
||
'title' => $xlh_box['name'],
|
||
'rule_url' => get_system_config_value('web_site')."/api/Page/get_gift_box_rule?box_id=".$xlh_box["id"],
|
||
'box_price' => $xlh_ext['xlh_box_price'],
|
||
'xlh_end_time' =>$pan_xlh['end_time'],
|
||
'give_homeowner_gift' => [
|
||
'gift_id' => $room_user_gift['gid'],
|
||
'gift_name' => $room_user_gift['gift_name'],
|
||
'base_image' => $room_user_gift['base_image'],
|
||
],
|
||
'locking_gift' => [
|
||
'gift_id' => $xlh_main_gift['gid'],
|
||
'gift_name' => $xlh_main_gift['gift_name'],
|
||
'gift_price' => $xlh_main_gift['gift_price'],
|
||
'base_image' => $xlh_main_gift['base_image'],
|
||
'gift_num' => $pan_xlh['num']
|
||
],
|
||
'xlh_user' => $xlh_user_data,
|
||
'gift_list' => $gift_list,
|
||
];
|
||
return ['code' => 1, 'msg' => '获取成功', 'data' => $result_data];
|
||
}
|
||
|
||
/*
|
||
* 巡乐会抽奖
|
||
*/
|
||
public function xlh_draw_gift($user_id,$num,$room_id){
|
||
$gift_bag_id = 13;
|
||
//获取盲盒配置
|
||
$bag_data = db::name("vs_gift_bag")->field('id,name,ext,periods')->where('id',$gift_bag_id)->find();
|
||
$ext = json_decode($bag_data['ext'],true);
|
||
//判断是否有足够的金币
|
||
$bag_gift_price = $ext['xlh_box_price'] * $num;
|
||
$user_waller = db::name('user_wallet')->where(['user_id'=>$user_id])->find();
|
||
if ($user_waller['coin'] < $bag_gift_price) {
|
||
return ['code' => 0, 'msg' => '用户金币不足', 'data' => null];
|
||
}
|
||
$room = db::name('vs_room')->where(['id'=>$room_id])->find();
|
||
if ($room['is_open_blind_box_turntable'] != 1) {
|
||
return ['code' => 0, 'msg' => '该房间未开启盲盒转盘', 'data' => null];
|
||
}
|
||
//开始抽奖
|
||
$pan_xlh = db::name('vs_room_pan_xlh')->where(['room_id'=>$room_id,'periods'=>$room['xlh_periods']])->find();
|
||
if(empty($pan_xlh)){
|
||
return ['code' => 0, 'msg' => '未开始', 'data' => null];
|
||
}
|
||
if($pan_xlh['end_time']<=time()){
|
||
return ['code' => 0, 'msg' => '本轮已结束', 'data' => null];
|
||
}
|
||
if($pan_xlh['send_time']!=0){
|
||
return ['code' => 0, 'msg' => '本轮已结束,礼物已发放', 'data' => null];
|
||
}
|
||
$is_zhong_jiang = 0;
|
||
$pan_xlh_num = $pan_xlh['num'];
|
||
//奖池总的抽奖次数
|
||
$total_quantity = db::name("vs_gift_bag_detail")->where(['gift_bag_id' => $gift_bag_id])->sum('quantity');
|
||
|
||
db::startTrans();
|
||
try{
|
||
//扣除抽奖消耗的金币
|
||
//扣除用户金币并记录日志
|
||
$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();
|
||
return ['code' => 0, 'msg' => '用户等级更新失败', 'data' => null];
|
||
}
|
||
|
||
//开始抽奖
|
||
for($i = 0; $i < $num; $i++){
|
||
//本期当前第多少次后抽奖 总的抽奖次数- 剩余数量
|
||
$room_pan = db::name("vs_room_pan")->where(['room_id'=>$room_id,'gift_bag_id'=>$gift_bag_id])->field('remaining_number,periods')->find();
|
||
if(empty($room_pan)){
|
||
return ['code' => 0, 'msg' => '当前房间未配置抽奖礼物,请联系管理员', 'data' => []];
|
||
}
|
||
$total_remaining = $room_pan['remaining_number'];
|
||
$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();
|
||
//抽中礼物落包
|
||
$res = model('UserGiftPack')->change_user_gift_pack($user_id,$gift_bag_detail['foreign_id'],1,model('UserGiftPack')::XLH_DRAW_GIFT_GET,$bag_data['name']."抽奖所得");
|
||
if ($res['code'] != 1) {
|
||
db::rollback();
|
||
return ['code' => 0, 'msg' => $res['msg'], 'data' => null];
|
||
}
|
||
//处理抽中礼物命中主奖品逻辑
|
||
if($gift_bag_detail['foreign_id'] == $ext['locking_condition']['selected_gift_id']){
|
||
//中奖
|
||
$pan_xlh_num = $pan_xlh_num+1;
|
||
$cache_key = 'selected_gift_id_'.$room_id.$gift_bag_detail['foreign_id'];
|
||
if($pan_xlh_num <= 1){
|
||
$add_end_time = $ext['locking_time']['tow_no_locking_time'] * 60;
|
||
Cache::set($cache_key,$add_end_time,$add_end_time);
|
||
}else{
|
||
// $add_end_time = ($ext['locking_time']['tow_no_locking_time']-$ext['locking_time']['next_time']) * 60;
|
||
if(Cache::get($cache_key)){
|
||
$erci_xlh_num = Cache::get($cache_key);
|
||
$add_end_time = ($erci_xlh_num-$ext['locking_time']['next_time'] *60);
|
||
Cache::set($cache_key,$add_end_time,$add_end_time);
|
||
}else{
|
||
$add_end_time = ($ext['locking_time']['tow_no_locking_time']-$ext['locking_time']['next_time']) * 60;
|
||
}
|
||
}
|
||
if($add_end_time <= 30){
|
||
Cache::set($cache_key,30,30);
|
||
$add_end_time = 30;
|
||
}
|
||
$end_time = time() + $add_end_time;
|
||
db::name('vs_room_pan_xlh')->where('id',$pan_xlh['id'])->update([
|
||
'user_id' => $user_id,
|
||
'pay_price' =>$ext['xlh_box_price'],
|
||
'locking_gift_id' =>$gift_bag_detail['foreign_id'],
|
||
'num' => $pan_xlh_num,
|
||
'end_time' => $end_time,
|
||
'updatetime' => time()
|
||
]);
|
||
db::name('vs_room_pan_xlh_log')->insertGetId([
|
||
'xlh_id' => $pan_xlh['id'],
|
||
'user_id' => $user_id,
|
||
'num' => $pan_xlh_num,
|
||
'locking_end_time' => $end_time,
|
||
'createtime' => time()
|
||
]);
|
||
$is_zhong_jiang = 1;
|
||
}
|
||
//减去盲盒包礼物数量
|
||
$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' => []];
|
||
}
|
||
//判断剩余数量是否为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_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{
|
||
db::rollback();
|
||
return ['code' => 0, 'msg' => '失败!', 'data' => []];
|
||
}
|
||
$result_data[] = [
|
||
'user_id' => $user_id,
|
||
'gift_id'=>$gift_bag_detail['foreign_id'],
|
||
'gift_price'=>$gift['gift_price'],
|
||
'gift_name'=>$gift['gift_name'],
|
||
'base_image'=>$gift['base_image'],
|
||
|
||
];
|
||
}
|
||
$reslut_data = [];
|
||
foreach ($result_data as $key => $value) {
|
||
$gift_id = $value['gift_id'];
|
||
if (!isset($reslut_data[$gift_id])) {
|
||
$reslut_data[$gift_id] = [
|
||
'gift_id' => $gift_id,
|
||
'gift_price'=>$value['gift_price'],
|
||
'gift_name'=>$value['gift_name'],
|
||
'base_image'=>$value['base_image'],
|
||
'count' => 1
|
||
];
|
||
}else {
|
||
$reslut_data[$gift_id]['count']++;
|
||
}
|
||
}
|
||
$result_list = [];
|
||
foreach ($reslut_data as $key => $value) {
|
||
//处理礼包发放记录表
|
||
$data = [];
|
||
$data['user_id'] = $user_id;
|
||
$data['parent_id'] = $pan_xlh['id'];
|
||
$data['gift_bag_id'] = $gift_bag_id;
|
||
$data['gift_id'] = $value['gift_id'];
|
||
$data['periods'] = $room_pan['periods'];
|
||
$data['room_id'] = $room_id;
|
||
$data['num'] = $value['count'];
|
||
$data['gift_price'] = $value['gift_price'];
|
||
$data['bag_price'] = $ext['xlh_box_price'];
|
||
$data['createtime'] = time();
|
||
$result = db::name("vs_gift_bag_receive_log")->insert($data);
|
||
if(!$result){
|
||
db::rollback();
|
||
return ['code' => 0, 'msg' => '失败,', 'data' => []];
|
||
}
|
||
$result_list[]=[
|
||
'gift_id'=>$value['gift_id'],
|
||
'gift_name'=>$value['gift_name'],
|
||
'base_image' =>$value['base_image'],
|
||
'gift_price'=>$value['gift_price'],
|
||
'count'=>$value['count'],
|
||
];
|
||
}
|
||
// 添加活动记录
|
||
$reslut = Db::name('vs_activities_receive')->insert([
|
||
'user_id' => $user_id,
|
||
'activities_id' => 6,
|
||
'room_id' => $room_id,
|
||
'createtime' => time(),
|
||
'updatetime' => time()
|
||
]);
|
||
db::commit();
|
||
} catch(\Exception $e) {
|
||
db::rollback();
|
||
return V(0,$e->getMessage());
|
||
}
|
||
if($is_zhong_jiang == 1){
|
||
//推送
|
||
$FromUserInfo = db::name('user')->field('nickname,avatar')->where(['id'=>$user_id])->find();
|
||
$room_name = db::name('vs_room')->where(['id'=>$room_id])->value('room_name');
|
||
$gift_name = db::name('vs_gift')->where(['gid'=>$value['gift_id']])->value('gift_name');
|
||
$text = $FromUserInfo['nickname'] . ' 用户在 ' . $room_name.' 房间巡乐会中 ' .$gift_name.'礼物 x ' .$value['count']." 已收入背包";
|
||
$text = [
|
||
'gift_num' => $pan_xlh_num,
|
||
'FromUserInfo' => $FromUserInfo,
|
||
'end_time' => $end_time,
|
||
'text' => $text
|
||
];
|
||
//聊天室推送系统消息
|
||
model('Chat')->sendMsg(1057,$room_id,$text);
|
||
}
|
||
//返回结果排序
|
||
usort($result_list, function($a, $b) {
|
||
return $b['gift_price'] <=> $a['gift_price'];
|
||
});
|
||
return ['code' => 1, 'msg' => '成功', 'data' => $result_list];
|
||
}
|
||
|
||
/*
|
||
* 巡乐会抽奖记录
|
||
*/
|
||
public function xlh_get_user_record($user_id,$room_id,$page=1,$page_size=12){
|
||
$where = [];
|
||
$where['a.gift_bag_id'] = 13;
|
||
$where['a.user_id'] = $user_id;
|
||
$where['a.room_id'] = $room_id;
|
||
$list = db('vs_gift_bag_receive_log')
|
||
->alias('a')
|
||
->join('vs_room_pan_xlh b','b.id = a.parent_id','left')
|
||
->join('vs_gift c','c.gid = a.gift_id','left')
|
||
->field('a.gift_id,a.num as count,b.createtime,c.gift_name as gift_name,c.base_image')
|
||
->where($where)
|
||
->page($page,$page_size)
|
||
->select();
|
||
foreach ($list as &$v){
|
||
$v['createtime'] = date('Y-m-d H:i:s',$v['createtime']);
|
||
}
|
||
return ['code' => 1, 'msg' => '成功', 'data' => $list];
|
||
}
|
||
|
||
/*
|
||
* 巡乐会榜单
|
||
*/
|
||
public function xlh_ranking($room_id,$page=1,$page_size=12){
|
||
$where = [];
|
||
$where['a.gift_bag_id'] = 13;
|
||
$where['a.room_id'] = $room_id;
|
||
$where['e.is_world_show'] = 1;
|
||
$list = db('vs_gift_bag_receive_log')
|
||
->alias('a')
|
||
->join('vs_room_pan_xlh b','b.id = a.parent_id','left')
|
||
->join('vs_gift c','c.gid = a.gift_id','left')
|
||
->join('fa_user d','d.id = a.user_id','left')
|
||
->join('vs_gift_bag_detail e','e.foreign_id = a.gift_id','left')
|
||
->field('a.gift_id,a.num as count,b.createtime,c.gift_name,c.base_image,d.nickname')
|
||
->where($where)
|
||
->page($page,$page_size)
|
||
->select();
|
||
foreach ($list as &$v){
|
||
$v['createtime'] = date('Y-m-d H:i:s',$v['createtime']);
|
||
}
|
||
return ['code' => 1, 'msg' => '成功', 'data' => $list];
|
||
}
|
||
}
|