Files
midi-php/application/api/model/BlindBoxTurntableGift.php

353 lines
16 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace app\api\model;
use app\common\controller\Push;
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']){
$is_xlh = 1;
$xlh['waiting_start_num'] = $xlh_ext['open_condition']['waiting_start_num'];//等待开奖次数
$xlh['start_num'] = $xlh_ext['open_condition']['start_num'];//开始开奖次数
//本期总次数
$total_number = db::name('vs_gift_bag_detail')->where(['gift_bag_id'=>$gift_bag_id])->sum('quantity')??0;
//本期剩余次数
$remaining_number = db::name('vs_room_pan')->where(['room_id'=>$room_id,'gift_bag_id'=>$gift_bag_id])->sum('remaining_number')??'0';
//当前抽奖次数
$xlh['current_num'] = $total_number - $remaining_number;
//状态
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);
//判断是否有足够的金币
$user_waller = db::name('user_wallet')->where(['user_id'=>$user_id])->find();
if ($user_waller['coin'] < $bag_gift['gift_price'] * $num) {
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];
}
//盲盒转盘抽奖记录
$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()
]);
foreach ($toarray as $gift_user_id){
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'],$bag_data['periods'],$room_id,$box_turntable_log);
$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) {
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()
]);
}
$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,$periods,$room_id=0,$box_turntable_log=0){
//随机获取一个礼物
$where = [
'a.gift_bag_id' => $gift_bag_id,
'a.quantity' => ['>',0],
'b.remaining_number' => ['>',0],
'b.room_id' => $room_id
];
// 优化:基于剩余数量的加权随机选择
$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' => []];
}
//奖池总的抽奖次数
$total_quantity = db::name("vs_gift_bag_detail")->where(['gift_bag_id' => $gift_bag_id])->sum('quantity');
// 实现加权随机算法:剩余数量越多,被抽中的概率越大
$total_remaining = 0;
foreach ($gift_bag_details as $gift) {
$total_remaining += $gift['remaining_number'];
}
//本期当前第多少次后抽奖 总的抽奖次数- 剩余数量
$total_draw_times = $total_quantity - $total_remaining;
$rand_value = mt_rand(1, $total_remaining);
$current_sum = 0;
$gift_bag_detail = null;
foreach ($gift_bag_details as $gift) {
if($gift['remaining_number'] <= 0){
continue;
}
if($total_draw_times < $gift['weight']){
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])->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['id']){
$room_name = Db::name('vs_room')->where(['id' => $room_id, 'apply_status' => 2])->value('room_name');
if($total_draw_times == $xlh_ext['open_condition']['waiting_start_num']){
//即将开始推送飘屏
$text = $room_name."的巡乐会即将开始,请大家尽快参与哦!";
}
if($total_draw_times == $xlh_ext['open_condition']['start_num']){
//正式开始推送飘屏
$text = $room_name."的巡乐会正式开始,请大家尽快参与哦!";
}
//推送礼物横幅
$push = new Push(UID, $room_id);
$room_name = Db::name('vs_room')->where(['id' => $room_id, 'apply_status' => 2])->value('room_name');
$text_list_new = [
'text' => $text,
'gift_picture' => "",
'room_id' => $room_id,
'fromUserName' => "",
'toUserName' => "",
'giftName' => "",
'roomId' => $room_id,
'number' => "",
];
$push->giftBanner($text_list_new);
}
$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,'is_sued'=>0])->select();
if(!$blind_box_turntable_log){
return ['code' => 0, 'msg' => '开奖数据不存在','data' => null];
}
//获取盲盒配置
$bag_data = db::name("vs_gift_bag")->field('id,name,ext,periods')->where('id',$blind_box_turntable['gift_bag_id'])->find();
$ext = json_decode($bag_data['ext'],true);
foreach ($blind_box_turntable_log as $key => $value) {
$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'], $ext['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']);
}
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];
}
}