This commit is contained in:
2025-10-20 10:02:41 +08:00
parent a4858d47fc
commit dc0a271adf
2805 changed files with 451240 additions and 0 deletions

View File

@@ -0,0 +1,371 @@
<?php
namespace app\adminapi\controller;
use think\Db;
class RoomHourRanking
{
public static function withdraw_status (){
return [
// [25 => '全时段'],
[0 => '00:00-01:00'],
[1 => '01:00-02:00'],
[2 => '02:00-03:00'],
[3 => '03:00-04:00'],
[4 => '04:00-05:00'],
[5 => '05:00-06:00'],
[6 => '06:00-07:00'],
[7 => '07:00-08:00'],
[8 => '08:00-09:00'],
[9 => '09:00-10:00'],
[10 => '10:00-11:00'],
[11 => '11:00-12:00'],
[12 => '12:00-13:00'],
[13 => '13:00-14:00'],
[14 => '14:00-15:00'],
[15 => '15:00-16:00'],
[16 => '16:00-17:00'],
[17 => '17:00-18:00'],
[18 => '18:00-19:00'],
[19 => '19:00-20:00'],
[20 => '20:00-21:00'],
[21 => '21:00-22:00'],
[22 => '22:00-23:00'],
[23 => '23:00-00:00'],
];
}
//房间小时榜列表
public function room_hour_ranking()
{
$page = input('page', 1);
$page_limit = input('page_limit', 20);
$search_ranking = input('search_ranking', '');
$search_stime = input('search_stime', '');
$search_etime = input('search_etime', '');
$where = [];
if ($search_ranking) {
$where[] = ['room_name', 'like', '%' . $search_ranking . '%'];
}
if ($search_stime) {
$where[] = ['stime', '>=', $search_stime];
}
if ($search_etime) {
$where[] = ['etime', '<=', $search_etime];
}
$count = db::name('vs_hour_ranking')->where($where)->count();
$list = db::name('vs_hour_ranking')->where($where)->page($page, $page_limit)->order('id desc')->select();
if($list){
foreach ($list as &$v){
$v['room_name'] = db::name('vs_room')->where(['id'=>$v['room_id']])->value('room_name');
$v['user_id'] = db::name('vs_room')->where(['id'=>$v['room_id']])->value('user_id');
if($v['user_id']){
$v['nickname'] = db::name('user')->where(['id'=>$v['user_id']])->value('nickname');
}
$v['stime'] = date('Y-m-d H:i', $v['stime']);
$v['etime'] = date('Y-m-d H:i', $v['etime']);
}
}
$return_data = [
'page' =>$page,
'page_limit' => $page_limit,
'count' => $count,
'lists' => $list
];
return V(1,"成功", $return_data);
}
//房间小时榜配置
public function room_hour_ranking_config()
{
$list = db::name('vs_hour_ranking_config')->where('id', '1')->find();
if($list){
//open_time 字段转化为2025-09-30 07:00 的格式
$list['open_time'] = $list['open_time'] ? date('Y-m-d H:i', $list['open_time']) : 0;
}
return V(1,"成功", $list);
}
//房间小时榜配置修改
public function room_hour_ranking_config_edit()
{
$id = input('id');
$data['is_open_red_pack'] = 0;//暂时不开启
$data['is_public_server'] = input('is_public_server');
$data['broadcast_times'] = input('broadcast_times');
$data['is_open_xlh'] = input('is_open_xlh');
$data['min_price'] = input('min_price');
$open_time = input('open_time');
$data['open_time'] = $open_time ? strtotime($open_time) : 0;
$data['createtime'] = time();
$data['updatetime'] = time();
$timeSlots = json_decode(input('timeJson'), true);
$timePeriods = $this->withdraw_status();
// 构建正确的时间映射关系
$timeMap = [];
foreach($timePeriods as $period) {
foreach($period as $key => $value) {
$timeMap[$key] = $value;
}
}
//$timeMap 里面 键值互换
$timeMap = array_flip($timeMap);
//开启事务
db::startTrans();
if($timeSlots){
$insertData = [];
foreach ($timeSlots as $timeSlot) {
// $timeRange = ;
$timeRange = $timeMap[$timeSlot['time']] ?? '99';
foreach ($timeSlot['reward'] as $rewardItem) {
$hasReward = !empty($rewardItem['content']);
if ($hasReward) {
// 有奖励内容:为每个奖励内容创建一条记录
foreach ($rewardItem['content'] as $rewardContent) {
if($rewardContent['type'] == 0){
$coin = $rewardContent['value'];
$gift_id = 0;
$gift_name = '';
}else{
$coin = 0;
$gift_id = $rewardContent['value'];
$gift_name = $rewardContent['name'];
}
$insertData[] = [
'time_id' => $timeRange,
'ranking' => $rewardItem['index'],
// 'rank_name' => $rewardItem['name'],
'gift_type' => $rewardContent['type'],
'gift_id' => $gift_id,
'coin' => $coin,
'name' => $gift_name,
'createtime' => time()
];
}
} else {
// 无奖励内容:插入一条空奖励记录
$insertData[] = [
'time_id' => $timeRange,
'ranking' => $rewardItem['index'],
// 'rank_name' => $rewardItem['name'],
'gift_type' => 0,
'gift_id' => 0,
'coin' => 0,
'name' => '',
'createtime' => time(),
];
}
}
}
// 批量插入
if (!empty($insertData)) {
$del = db::name('vs_hour_ranking_gift_config')->where('id','>',0)->delete();
$ins = db::name('vs_hour_ranking_gift_config')->insertAll($insertData);
}else{
$ins = false;
$del = false;
}
}else{
$del = true;
$ins = true;
}
// $res = db::name('vs_hour_ranking_config')->where('id', $id)->update($data);
$res = db::name('vs_hour_ranking_config')->where('id', $id)->update($data);
// if ($del && $ins && $res) {
if ($ins) {
db::commit();
return V(1, "成功");
} else {
db::rollback();
return V(0, "失败");
}
}
//时间段对应关系
public function time_period_correspondence()
{
$list = $this->withdraw_status();
$timePeriods = $this->withdraw_status();
$timeMap = [];
foreach($timePeriods as $period) {
foreach($period as $key => $value) {
$timeMap[$key] = $value;
}
}
return V(1,"成功", $timeMap);
}
//添加核心配置
public function add_core_config()
{
$data['is_public_server'] = input('is_public_server');
$data['createtime'] = time();
$data['updatetime'] = time();
$res = db::name('vs_hour_ranking_config')->insert($data);
}
//核心配置列表
public function core_config_list()
{
$timePeriods = $this->withdraw_status();
// 构建正确的时间映射关系
$timeMap = [];
foreach($timePeriods as $period) {
foreach($period as $key => $value) {
$timeMap[$key] = $value;
}
}
// 先按时间段和排名索引分组查询
$timeRanges = db::name('vs_hour_ranking_gift_config')->distinct(true)
->order('time_id')
->column('time_id');
$result = [];
foreach ($timeRanges as $timeRange) {
// 查询该时间段的所有数据
$rewards = db::name('vs_hour_ranking_gift_config')->where('time_id', $timeRange)
->field('ranking, gift_type, gift_id,coin,name')
->order('ranking')
->select();
$rewardMap = [];
foreach ($rewards as $reward) {
$rankIndex = $reward['ranking'];
if (!isset($rewardMap[$rankIndex])) {
$rewardMap[$rankIndex] = [
'index' => $rankIndex,
// 'name' => $reward['rank_name'],
'content' => []
];
}
// 添加奖励内容到content数组
if ($reward['gift_id'] != 0 || $reward['coin'] != 0) {
if($reward['gift_id'] != 0){
$rewardMap[$rankIndex]['content'][] = [
'type' => $reward['gift_type'],
'value' => $reward['gift_id'],
// 'coin' => $reward['coin'],
'name' => $reward['name'],
];
}
if($reward['coin'] != 0){
$rewardMap[$rankIndex]['content'][] = [
'type' => $reward['gift_type'],
'value' => $reward['coin'],
'name' => $reward['name'],
];
}
}
}
// 按index排序
ksort($rewardMap);
$result[] = [
'time' => $timeMap[$timeRange],
'reward' => array_values($rewardMap)
];
}
return V(1, "成功", $result);
}
// public function core_config_lists()
// {
// $list = db::name('vs_hour_ranking_gift_config')->select();
// $data = [];
//
// // 按 time_id 和 ranking 重组数据
// $reorganizedData = [];
// $timePeriods = $this->withdraw_status();
//
// // 构建正确的时间映射关系
// $timeMap = [];
// foreach($timePeriods as $period) {
// foreach($period as $key => $value) {
// $timeMap[$key] = $value;
// }
// }
//
// foreach ($list as $item) {
//// $timeId = $item['time_id'];
// $timeId = $timeMap[$item['time_id']] ?? '未知时间段';
// $ranking = $item['ranking'];
//
// $gift_name = '';
// if (!isset($reorganizedData[$timeId])) {
// $reorganizedData[$timeId] = [];
// }
// if (!isset($reorganizedData[$timeId][$ranking])) {
// $reorganizedData[$timeId][$ranking] = [];
// }
// if($item['gift_id']){
// if($item['gift_type'] == 2){
// $gift_name = db::name('vs_gift')->where(['gid'=>$item['gift_id']])->value('gift_name');
// }
// if($item['gift_type'] == 3 || $item['gift_type'] == 4){
// $gift_name = db::name('vs_decorate')->where(['did'=>$item['gift_id']])->value('title');
// }
//
// }else{
// $gift_name = '';
// }
// $reorganizedData[$timeId][$ranking][] = [
// 'gift_type' => $item['gift_type'],
// 'gift_id' => $item['gift_id'],
// 'gift_name' => $gift_name,
// 'coin' => $item['coin']
// ];
// }
//
// // 输出重组后的数据
// print_r($reorganizedData);
// return V(1, "成功", $data);
// }
}

View File

@@ -0,0 +1,131 @@
<?php
namespace app\api\controller;
use app\common\controller\BaseCom;
use think\Controller;
use think\Db;
/*
* 盲盒转盘
* 2025-08-16
*/
class BlindBoxTurntable extends BaseCom
{
protected function initialize()
{
//允许跨域
header('Access-Control-Allow-Origin: *');
}
/*
* 获取活动奖池礼物列表
*/
public function get_gift_list(){
$gift_bag_id = input('gift_bag_id',0);
$room_id = input('room_id',0);
$reslut = model('BlindBoxTurntableGift')->get_gift_list($gift_bag_id,$room_id);
return v($reslut['code'], $reslut['msg'], $reslut['data']);
}
/*
* 抽奖
*
*/
public function draw_gift(){
$gift_bag_id = input('gift_bag_id',0);
$user_id = $this->uid;
$room_id = input('room_id',0);
$gift_user_ids = input('gift_user_ids',0);
$num = input('num',1);
$heart_id = input('heart_id',0);
$auction_id = input('auction_id',0);
$reslut = model('BlindBoxTurntableGiftDrawWorld')->draw_gift($gift_bag_id, $user_id, $gift_user_ids,$num,$room_id,$heart_id,$auction_id);
return v($reslut['code'], $reslut['msg'], $reslut['data']);
}
/*
* 礼物发放
*/
public function gift_send(){
// $key_name = "api:blind_box_turntable:gift_send:" . $this->uid;
// redis_lock_exit($key_name);
$send_id = input('send_id',0);
$reslut = model('BlindBoxTurntableGift')->gift_send($send_id);
// redis_unlock($key_name);
return v($reslut['code'], $reslut['msg'], $reslut['data']);
}
/*
* 获取我的抽奖记录
*/
public function get_my_record(){
$user_id = $this->uid;
$gift_bag_id = input('gift_bag_id',0);
$page = input('page',1);
$page_size = input('page_size',12);
$reslut = model('BlindBoxTurntableGift')->get_user_record($gift_bag_id,$user_id,$page,$page_size);
return v($reslut['code'], $reslut['msg'], $reslut['data']);
}
/*
* 获取全服抽奖记录
*/
public function get_all_record(){
$gift_bag_id = input('gift_bag_id',0);
$page = input('page',1);
$page_size = input('page_size',12);
$reslut = model('BlindBoxTurntableGift')->get_all_record($gift_bag_id,$page,$page_size);
return v($reslut['code'], $reslut['msg'], $reslut['data']);
}
/*
* 巡乐会
*/
public function xlh(){
$room_id = input('room_id',0);
$reslut = model('BlindBoxTurntableGift')->xlh_gift_list($room_id);
return v($reslut['code'], $reslut['msg'], $reslut['data']);
}
/*
* 巡乐会抽奖
*/
public function xlh_draw_gift(){
$user_id = $this->uid;
$room_id = input('room_id',0);
$num = input('num',1);
$reslut = model('BlindBoxTurntableGiftDrawWorld')->xlh_draw_gift($user_id,$num,$room_id);
return v($reslut['code'], $reslut['msg'], $reslut['data']);
}
/*
* 获取我的巡乐会记录
*/
public function get_xlh_my_record(){
$page = input('page',1);
$page_size = input('page_size',12);
$user_id = $this->uid;
$room_id = input('room_id',0);
$reslut = model('BlindBoxTurntableGift')->xlh_get_user_record($user_id,$room_id,$page,$page_size);
return v($reslut['code'], $reslut['msg'], $reslut['data']);
}
/*
* 获取全服巡乐会记录(榜单)
*/
public function get_xlh_all_record(){
$page = input('page',1);
$page_size = input('page_size',12);
$room_id = input('room_id',0);
$reslut = model('BlindBoxTurntableGift')->xlh_ranking($room_id,$page,$page_size);
return v($reslut['code'], $reslut['msg'], $reslut['data']);
}
/*
* 巡乐会榜单 (以期数显示)
*/
public function get_xlh_ranking(){
$page = input('page',1);
$page_size = input('page_size',12);
$room_id = input('room_id',0);
$reslut = model('BlindBoxTurntableGift')->xlh_ranking_list($room_id,$page,$page_size);
return v($reslut['code'], $reslut['msg'], $reslut['data']);
}
}

View File

@@ -0,0 +1,65 @@
<?php
namespace app\api\controller;
use app\common\controller\BaseCom;
class Friend extends BaseCom
{
//交友开始
public function start_friend(){
$key_name = "api:friend:start_friend:" . $this->uid;
redis_lock_exits($key_name);
$room_id = input('room_id', '');
$reslut = model('Friend')->start_friend($this->uid,$room_id);
redis_unlocks($key_name);
return V($reslut['code'], $reslut['msg'], $reslut['data']);
}
//交友延时
public function delay(){
$friend_id = input('friend_id', '');
$room_id = input('room_id', '');
$delay_times = input('delay_times', '');//分钟
$reslut = model('Friend')->delay($this->uid,$room_id,$friend_id,$delay_times);
return V($reslut['code'], $reslut['msg'], $reslut['data']);
}
//交友结束
public function end_friend(){
$friend_id = input('friend_id', '');
$room_id = input('room_id', '');
$result = model('Friend')->end_friend($this->uid,$room_id,$friend_id);
return V($result['code'], $result['msg'], $result['data']);
}
//卡关系 创建关系
public function create_relation()
{
$key_name = "api:friend:create_relation:" . $this->uid;
redis_lock_exits($key_name);
$room_id = input('room_id', '');
$friend_id = input('friend_id', '');
$user1_id = input('user1_id', '');
$user2_id = input('user2_id', '');
$relation_id = input('relation_id', '');
$result = model('Friend')->createRelation($this->uid,$room_id,$friend_id,$user1_id,$user2_id,$relation_id);
redis_unlocks($key_name);
return V($result['code'], $result['msg'], $result['data']);
}
//退出私密小屋
public function out_room()
{
$room_id = input('room_id', '');
$result = model('Friend')->outRoom($this->uid,$room_id);
return V($result['code'], $result['msg'], $result['data']);
}
}

View File

@@ -0,0 +1,119 @@
<?php
namespace app\api\controller;
use app\common\controller\BaseCom;
use app\common\service\RedpacketService;
use think\Db;
/**
* 红包接口
*/
class Redpacket extends BaseCom
{
/**
* 发红包
*/
public function create()
{
$data = $this->request->post();
$data['user_id'] = $this->uid;
$service = new RedpacketService();
$reslut = $service->create($data);
return V($reslut['code'], $reslut['msg'], $reslut['data']);
}
/**
* 抢红包
*/
public function grab()
{
$redpacketId = input('redpacket_id', 0);
if (empty($redpacketId)) {
return V(0, '红包ID不能为空');
}
$service = new RedpacketService();
// 在抢红包前确保状态正确
$service->checkAndUpdateRedpacketStatus($redpacketId);
$reslut = $service->grabWithResult($redpacketId, $this->uid);
return V($reslut['code'], $reslut['msg'], $reslut['data']);
}
/**
* 获取抢红包结果
*/
public function grabResult()
{
$redpacketId = $this->request->get('redpacket_id');
if (empty($redpacketId)) {
return V(0, '红包ID不能为空');
}
$service = new RedpacketService();
$result = $service->getGrabResult($redpacketId, $this->uid);
if (!$result) {
return V(0, '红包不存在');
}
return V(1, '获取成功', $result);
}
/**
* 红包详情
*/
public function detail()
{
$redpacketId = input('redpacket_id', 0);
if (empty($redpacketId)) {
return V(0, '红包ID不能为空');
}
$service = new RedpacketService();
// 在获取详情前确保状态正确
$service->checkAndUpdateRedpacketStatus($redpacketId);
$detail = $service->getDetail($redpacketId, $this->uid);
if (!$detail) {
return V(0, '红包不存在');
}
return V(1, '获取成功', $detail);
}
/**
* 获取倒计时选项
*/
public function countdownOptions()
{
$options = \app\common\model\Redpacket::$countdownOptions;
$this->success('获取成功', $options);
}
// 获取房间内红包列表
public function roomRedPackets()
{
$roomId = $this->request->get('room_id');
$result = Db::name('redpacket')->where(['room_id' => $roomId, 'status' => ['<=',1]])->select();
if($result){
foreach ($result as &$item) {
$item['redpacket_id'] = $item['id'];
$item['redpacket_time'] = get_system_config_value('red_packet_time');//展示时间
$item['nickname'] = Db::name('user')->where('id', $item['user_id'])->value('nickname');
$item['avatar'] = Db::name('user')->where('id', $item['user_id'])->value('avatar');
$is_qiang = Db::name('redpacket_record')->where(['redpacket_id' => $item['id'], 'user_id' => $this->uid])->find();
$item['is_qiang'] = $is_qiang ? 1 : 0;
}
}
return V(1, '获取成功', $result);
}
}

View File

@@ -0,0 +1,34 @@
<?php
namespace app\api\controller;
use app\common\controller\BaseCom;
use think\Db;
class RoomHourRanking extends BaseCom
{
//房间小时榜是否开启
public function room_hour_ranking_is_open()
{
$open_time = db::name('vs_hour_ranking_config')->order('id', 'desc')->value('open_time');
return V(1, '获取成功', ['open_time' => $open_time]);
}
//房间小时榜玩法
public function room_hour_ranking_play()
{
$introd = db::name('vs_hour_ranking_config')->order('id', 'desc')->value('introd');
return V(1, '获取成功', ['introd' => $introd]);
}
//房间小时榜
public function room_hour_ranking()
{
$page = input('page', 1);
$page_limit = input('page_limit', 20);
$reslut = model('RoomHourRanking')->room_hour_ranking($page, $page_limit);
return V($reslut['code'], $reslut['msg'], $reslut['data']);
}
}

View File

@@ -0,0 +1,39 @@
<?php
namespace app\api\controller;
use think\Controller;
use think\Db;
use think\Log;
use app\common\controller\BaseCom;
class Xintiao extends BaseCom
{
public function keep_xintiao()
{
$user_id = $this->uid;
$is_xintiao = db::name('vs_xintiao')->where('user_id' , $user_id)->find();
if($is_xintiao){
db::name('vs_xintiao')->where('user_id' , $user_id)->update(['updatetime' => time()]);
}else{
db::name('vs_xintiao')->insert([
'user_id' => $user_id,
'createtime' => time(),
'updatetime' => time()
]);
}
return true;
}
}

View File

@@ -0,0 +1,434 @@
<?php
namespace app\api\controller;
use think\Controller;
use think\Db;
use think\Log;
use app\common\controller\Push;
class Xxiaoshi extends Controller
{
public function send_gift()
{
//获取上一个小时的开始时间和结束时间
$start_time = strtotime(date('Y-m-d H:00:00', strtotime('-1 hour')));
$end_time = strtotime(date('Y-m-d H:00:00'));
echo "开始时间:" .$start_time."\n";
echo "结束时间:" .$end_time."\n";
//当前小时的前一个小时24小时计时法0-23
$pre_hour = date('H', strtotime('-1 hour'));
echo "上个时间段:" .$pre_hour."\n";
$is_open_time = db::name('vs_hour_ranking_config')->where('id', 1)->value('open_time');
if ($is_open_time == 0) {
echo "未开启时间段:" .$is_open_time."\n";
return;
}
//是否全局飘瓶
$is_public_server = db::name('vs_hour_ranking_config')->where('id', 1)->value('is_public_server');
if ($is_public_server == 1) {
//全局飘瓶时间段
$xlh_time_range = db::name('vs_hour_ranking_config')->where('id', 1)->value('broadcast_times');
if($xlh_time_range){
if($xlh_time_range == 25){
$is_piao = 1;
}else{
//当前的前一个小时是否在 $xlh_time_range中
if (in_array($pre_hour, explode(',', $xlh_time_range))) {
$is_piao = 1;
} else {
$is_piao = 0;
}
}
}else{
$is_piao = 0;
}
}else{
$is_piao = 0;
}
//获取上一个时间段的配置
// $gift_list = db::name('vs_hour_ranking_gift_config')->where('time_id',$pre_hour)->group('ranking')->order('id', 'desc')->select();
$gift_list = $this->get_hour_ranking($pre_hour);
// echo "上个时间段的配置:" .json_encode($gift_list)."\n";
// 提取所有有奖励的内容
$allRewards = $this->extractAllRewards($gift_list);
// 按index分组
$groupedRewards = $this->groupRewardsByIndex($allRewards);
// 按名次顺序分配奖励
$distributionResult = $this->distributeByRank($groupedRewards);
//获取上个数组的个数,从而获取配置了多少个名次
$count = count($distributionResult);
echo "上个时间段的配置总数:" .$count."\n";
//获取前一个小时的 前$count名房间排行
$room_list = model('api/RoomHourRanking')->room_hour_ranking(1, $count, $start_time, $end_time);
$room_owner = [];
if ($room_list['code'] == 1) {
//获取房间排行奖励最低值
$min_price = db::name('vs_hour_ranking_config')->where('id', 1)->value('min_price');
if ($room_list['data']['lists']) {
echo "房间列表:" .json_encode($room_list['data']['lists'])."\n";
foreach ($room_list['data']['lists'] as $v){
if ($v['total_price'] >= $min_price) {
$room_owner[] = [
'user_id' => $v['user_id'],
'room_name' => $v['room_name'],
'room_id' => $v['room_id'],
'total_price' => $v['total_price']
];
}
}
}
}
if ($distributionResult && $room_owner) {
$text_list_new = [];
echo "礼物数:" .json_encode($distributionResult)."\n";
echo "房主:" .json_encode($room_owner)."\n";
foreach ($distributionResult as $k => $value) {
//礼物全部给他偷偷放在装扮表及金额 中
//有几个用户就发几个
if(count($room_owner) > $k){
// 为每个房间添加一个标志,表示是否已处理推送信息
$hasProcessedPush = false;
foreach ($value['rewards'] as $v){
// if($v['type'] == 0){//1金币2礼物3头像4坐骑
// echo "发金币:" .$v['value'].'==>'.$room_owner[$k]['user_id']."\n";
// $res = $this->add_coin($v['value'], $room_owner[$k]['user_id'],$k + 1,$room_owner[$k]['room_id'],$room_owner[$k]['total_price'],$is_piao);
// }elseif ($v['type'] == 1){
// echo "发礼物:" .$v['value'].'==>'.$room_owner[$k]['user_id']."\n";
// $res = $this->add_gift($v['value'], $room_owner[$k]['user_id'],$k + 1,$room_owner[$k]['room_id'],$room_owner[$k]['total_price'],$is_piao);
// }elseif ($v['type'] == 2){
// $res = $this->add_decorate($v['value'], $room_owner[$k]['user_id'],$k + 1,$room_owner[$k]['room_id'],$room_owner[$k]['total_price'],$is_piao,3);
// }elseif ($v['type'] == 3){
// $res = $this->add_decorate($v['value'], $room_owner[$k]['user_id'],$k + 1,$room_owner[$k]['room_id'],$room_owner[$k]['total_price'],$is_piao,4);
// }
// 只有在第一次处理奖励时添加推送信息,避免重复推送
if(!$hasProcessedPush && $is_piao == 1) {
$room_name = $room_owner[$k]['room_name'];
//推送礼物横幅
if ($k == 0) {
$text = '新科状元!【' . $room_name . '】独占鳌头!';
} elseif ($k == 1) {
$text = '金榜榜眼!【' . $room_name . '】才气逼人!';
} elseif ($k == 2) {
$text = '风采探花!【' . $room_name . '】实力绽放!';
}
$text_list_new[] = [
'text' => $text ?? '恭喜【' . $room_name . '】获得礼物!',
'room_id' => $room_owner[$k]['room_id'],
'room_name' => $room_name,
'rank_number' => $k + 1,
];
$hasProcessedPush = true; // 标记已处理推送
}
}
}
}
if(!empty($text_list_new)){
$push = new Push();
$push->hourRankingcs($text_list_new);
Log::record("小时榜推送:".json_encode($text_list_new),"infos");
}
}
echo "送礼-共" . count($room_owner) . "个房间房主获益\n";
}
//添加金币到钱包
// public function add_coin($coin,$user_id,$ranking,$room_id,$total_price,$is_piao){
// if($coin > 0){
// $data = [
// 'user_id' => $user_id,
// 'change_value' => $coin,
// // 'room_id' => $room_ids,
// 'money_type' => 1,
// 'change_type' => 27,
// 'from_id' => 0,
// 'remarks' => '小时榜获得',
// 'createtime' => time()
// ];
// //开启事务
// Db::startTrans();
// $res = Db::name('vs_user_money_log')->insert($data);
// if(!$res){
// Db::rollback();
// }
// //增加用户金币
// $res1 = Db::name('user_wallet')->where(['user_id'=>$user_id])->setInc('coin',$coin);
// if(!$res1){
// Db::rollback();
// }
// //添加到排行表
// $start_time = strtotime(date('Y-m-d H:00:00', strtotime('-1 hour')));
// $end_time = strtotime(date('Y-m-d H:00:00')) - 1;
// $res2 = db::name('vs_hour_ranking')->insert([
// 'ranking' => $ranking,
// 'room_id' => $room_id,
// 'flowing_water' => $total_price,
// 'coin' => $coin,
// 'time_id' => date('H', strtotime('-1 hour')),
// 'stime' => $start_time,
// 'etime' => $end_time,
// 'createtime' => time(),
// 'updatetime' => time(),
// 'is_public_server' => $is_piao
// ]);
// if(!$res2){
// Db::rollback();
// }
// Db::commit();
// }
// return true;
// }
// //添加礼物到背包
// public function add_gift($gift_id,$user_id,$ranking,$room_id,$total_price,$is_piao){
// $res = model('api/UserGiftPack')->change_user_gift_pack($user_id,$gift_id,1,model('UserGiftPack')::HOUR_RANK_GET,"小时榜获得");
// if($res['code'] == 0){
// Log::record("小时榜获取礼物失败:".$res['msg'],"info");
// }
// //添加到排行表
// $start_time = strtotime(date('Y-m-d H:00:00', strtotime('-1 hour')));
// $end_time = strtotime(date('Y-m-d H:00:00')) - 1;
// $res2 = db::name('vs_hour_ranking')->insert([
// 'ranking' => $ranking,
// 'room_id' => $room_id,
// 'flowing_water' => $total_price,
// 'gift_id' => $gift_id,
// 'gift_type' => 2,
// 'time_id' => date('H', strtotime('-1 hour')),
// 'stime' => $start_time,
// 'etime' => $end_time,
// 'createtime' => time(),
// 'updatetime' => time(),
// 'is_public_server' => $is_piao
// ]);
// if(!$res2){
// Log::record("小时榜礼物锁定失败","info");
// }
// return true;
// }
// //添加装扮到背包
// public function add_decorate($avatar_id,$user_id,$ranking,$room_id,$total_price,$is_piao,$type){
// $decorate_price_info = db::name('vs_decorate_price')->where(['id'=>$avatar_id])->find();
// if(empty($decorate_price_info)){
// Log::record("小时榜获取装扮失败:没有找到装扮!".$avatar_id,"info");
// }
// $res = model('api/Decorate')->pay_decorate($user_id,$decorate_price_info['did'],$decorate_price_info['day'],2);
// if($res['code'] == 0){
// Log::record("小时榜获取装扮失败:".$res['msg']."-".$avatar_id,"info");
// }
// //添加到排行表
// $start_time = strtotime(date('Y-m-d H:00:00', strtotime('-1 hour')));
// $end_time = strtotime(date('Y-m-d H:00:00')) - 1;
// $res2 = db::name('vs_hour_ranking')->insert([
// 'ranking' => $ranking,
// 'room_id' => $room_id,
// 'flowing_water' => $total_price,
// 'gift_id' => $avatar_id,
// 'gift_type' => $type,
// 'time_id' => date('H', strtotime('-1 hour')),
// 'stime' => $start_time,
// 'etime' => $end_time,
// 'createtime' => time(),
// 'updatetime' => time(),
// 'is_public_server' => $is_piao,
// ]);
// if(!$res2){
// Log::record("小时榜咋装扮锁定失败","info");
// }
// return true;
// }
/**
* 提取所有有奖励的内容
*/
private function extractAllRewards($responseData)
{
$allRewards = [];
foreach ($responseData as $timeSlot) {
foreach ($timeSlot['reward'] as $rewardItem) {
$index = $rewardItem['index'];
$content = $rewardItem['content'];
// 只处理有奖励内容的数据
if (!empty($content)) {
foreach ($content as $rewardContent) {
$allRewards[] = [
'index' => $index,
'type' => $rewardContent['type'],
'value' => $rewardContent['value'],
'name' => $rewardContent['name'] ?? ''
];
}
}
}
}
return $allRewards;
}
/**
* 按index分组奖励
*/
private function groupRewardsByIndex($allRewards)
{
$grouped = [];
foreach ($allRewards as $reward) {
$index = $reward['index'];
if (!isset($grouped[$index])) {
$grouped[$index] = [];
}
$grouped[$index][] = $reward;
}
// 按index排序
ksort($grouped);
return $grouped;
}
/**
* 按名次顺序分配奖励
*/
private function distributeByRank($groupedRewards)
{
$distribution = [];
$currentRank = 0; // 从第1名开始
// 按index顺序分配index 0 = 第1名index 1 = 第2名以此类推
foreach ($groupedRewards as $index => $rewards) {
// 确保名次连续,如果有空缺则填充空名次
while ($currentRank < $index) {
$distribution[] = [
'rank' => $currentRank + 1,
'rewards' => []
];
$currentRank++;
}
// 分配当前名次的奖励
$distribution[] = [
'rank' => $currentRank + 1,
'rewards' => $rewards
];
$currentRank++;
}
return $distribution;
}
public function get_hour_ranking($time){
// 先按时间段和排名索引分组查询
$timeRanges = db::name('vs_hour_ranking_gift_config')->distinct(true)
->where('time_id', '=', $time)
->order('time_id')
->column('time_id');
$result = [];
foreach ($timeRanges as $timeRange) {
// 查询该时间段的所有数据
$rewards = db::name('vs_hour_ranking_gift_config')->where('time_id', $timeRange)
->field('ranking, gift_type, gift_id,coin,name')
->order('ranking')
->select();
$rewardMap = [];
foreach ($rewards as $reward) {
$rankIndex = $reward['ranking'];
if (!isset($rewardMap[$rankIndex])) {
$rewardMap[$rankIndex] = [
'index' => $rankIndex,
// 'name' => $reward['rank_name'],
'content' => []
];
}
// 添加奖励内容到content数组
if ($reward['gift_id'] != 0 || $reward['coin'] != 0) {
if($reward['gift_id'] != 0){
$rewardMap[$rankIndex]['content'][] = [
'type' => $reward['gift_type'],
'value' => $reward['gift_id'],
// 'coin' => $reward['coin'],
'name' => $reward['name'],
];
}
if($reward['coin'] != 0){
$rewardMap[$rankIndex]['content'][] = [
'type' => $reward['gift_type'],
'value' => $reward['coin'],
'name' => $reward['name'],
];
}
}
}
// 按index排序
ksort($rewardMap);
$result[] = [
'time' => $timeRange,
'reward' => array_values($rewardMap)
];
}
return $result;
}
public function give_gifts(){
$data = db::name('vs_give_gift')->where('from_id',5483)->select();
$num = 0;
$i=0;
$j = 0;
foreach($data as $v){
$j += $v['total_price'];
$nuu = db::name('vs_give_gift_ratio_log')->where('give_gift_id',$v['id'])->value('room_owner_earning');
$id = db::name('vs_give_gift_ratio_log')->where('give_gift_id',$v['id'])->value('id');
// echo $id."--".$nuu."\n";
$num += $nuu;
$i++;
}
echo $num;
echo "==".$i."==".$j;
// echo db::name()->where(['user_id' => 10857,'money_type' =>2,'change_type' =>18])-sum('change_value');
}
public function room_liushui(){
// $room = db::name('vs_give_gift')->where(['from_id' => ['<>',5418],'from' => 2])->group('from_id');
$dd = db::name('vs_user_gift_pack')->alias('a')->join('vs_gift b','a.gid = b.gid')->field('a.gid,a.num,b.gift_price')->where(['a.num' =>['>',0]])->select();
$count = 0;
foreach ($dd as $v){
$count += $v['gift_price'] * $v['num'];
}
echo $count;
}
}

View File

@@ -0,0 +1,416 @@
<?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']){
$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'] = Cache::get("xlh_periods_num") ?? 0;
//状态
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"],
'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 gift_send($send_id){
try{
$blind_box_turntable = db('vs_blind_box_turntable_log')->where(['id'=>$send_id,'is_sued'=>0])->find();
if(!$blind_box_turntable){
return ['code' => 1, 'msg' => '成功', 'data' => null];
}
$room_id = $blind_box_turntable['room_id'];
$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];
}
$room_name = Db::name('vs_room')->where(['id' => $room_id, 'apply_status' => 2])->value('room_name');
$FromUserInfo = Db::name('user')->where(['id'=>$blind_box_turntable['user_id']])->find();
$FromUserInfo['icon'][0] = model('UserData')->user_wealth_icon($blind_box_turntable['user_id']);//财富图标
$FromUserInfo['icon'][1] = model('UserData')->user_charm_icon($blind_box_turntable['user_id']);//魅力图标
$user_nickname = $FromUserInfo['nickname'];
$textMessage = $user_nickname;
$text_message = [];
foreach ($blind_box_turntable_log as $key => $value) {
$ToUserInfo = Db::name('user')->where(['id' => $value['gift_user_id']])->field('id as user_id,nickname,avatar,sex')->find();
$draw_gift = Db::name('vs_gift')->where(['gid'=>$value['gift_id']])->find();
$textMessage = $textMessage . ' 送给 ' . $ToUserInfo['nickname']. ' 盲盒转盘礼物 ' . $draw_gift['gift_name'].' x ' .$value['count']."\n";
$play_image[] = $draw_gift['play_image'];
$gift_names[] = $draw_gift['gift_name'];
$text_message = $user_nickname . '在' . $room_name . '房间送给了' . $ToUserInfo['nickname'] . $draw_gift['gift_name'] . 'X' . $value['count']."\n";
if($draw_gift['is_public_server'] == 1) {
$text_list_new[] = [
'text' => $text_message,
'gift_picture' => $draw_gift['base_image'],
'room_id' => $room_id,
'fromUserName' => $FromUserInfo['nickname'],
'toUserName' => $ToUserInfo['nickname'],
'giftName' => $draw_gift['gift_name'],
'roomId' => $room_id,
'number' => $value['count'],
];
}
$ToUserInfosList[$value['gift_user_id']] = $ToUserInfo;
}
foreach($ToUserInfosList as &$userInfo) {
$userInfo['icon'][0] = model('UserData')->user_wealth_icon($userInfo['user_id']);//财富图标
$userInfo['icon'][1] = model('UserData')->user_charm_icon($userInfo['user_id']);//魅力图标
$userInfo['charm'] = db::name('vs_room_user_charm')->where(['user_id' => $userInfo['user_id'],'room_id' => $room_id])->value('charm');//魅力
$ToUserInfos[] = $userInfo;
}
$text = [
'FromUserInfo' => $FromUserInfo,
'ToUserInfos' => $ToUserInfos,
'GiftInfo' => [
'play_image' => implode(',',$play_image),
'gift_name' => implode(',',$gift_names),
],
'text' => rtrim($textMessage, "\n")
];
//聊天室推送系统消息
model('Chat')->sendMsg(1005,$room_id,$text);
$roomtype = Db::name('vs_room')->where(['id' => $room_id])->value('type_id');
if($roomtype == 6){
//推送消息
$hot_value = db::name('vs_give_gift')->where('from_id', $room_id)->where('from',6)
->sum('total_price');
$text1 = [
'room_id' => $room_id,
'hot_value' => $hot_value * 10,
'text' => '房间心动值变化'
];
//聊天室推送系统消息
model('Chat')->sendMsg(1028,$room_id,$text1);
}else{
if(!empty($text_list_new)){
//推送礼物横幅
$push = new Push($blind_box_turntable['user_id'], $room_id);
$push->giftBanner($text_list_new);
}
}
db::name('vs_blind_box_turntable_log')->where('id', $send_id)->update(['is_sued' => 1, 'updatetime' => time()]);
return ['code' => 1, 'msg' => '成功', 'data' => null];
} catch (\Exception $e) {
return ['code' => 0, '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,a.createtime,c.nickname,d.gift_name as gift_name,d.base_image')
->where($where)
->order('a.createtime desc')
->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,a.createtime,c.nickname,d.name as gift_name,e.base_image')
->where($where)
->order('a.createtime desc')
->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 = db::name('user')->where('id',$room_data['user_id'])->find();
//房主礼物
$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();
//中奖用户
$pan_xlh = db::name('vs_room_pan_xlh')->where(['send_time'=>0,'end_time'=>['>',time()]])->order('id desc')->find();
$xlh_periods_num = Cache::get("xlh_periods_num") ?? 0;
if(empty($pan_xlh)){
if($xlh_periods_num >= $xlh_ext['open_condition']['start_num']){
$xlh_periods = Cache::get("this_xlh_periods") ?? 0;
$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' => $xlh_periods+1,
'num' => 0,
'end_time' => time() + $xlh_ext['locking_time']['end_time'] * 60,
'createtime' => time()
]);
Cache::set("this_xlh_periods", $xlh_periods+1, 0);//修改巡乐会期数
$pan_xlh = db::name('vs_room_pan_xlh')->where(['id'=>$pan_xlh_id])->find();
}else{
return ['code' => 0, 'msg' => '巡乐会已结束', 'data' => null];
}
}
$xlh_user_data= null;
$room_user_data = null;
if($pan_xlh && $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'],
];
if($pan_xlh['room_id']){
$room_data = db::name('vs_room')->field('xlh_periods,xlh_periods_num,user_id')-> where('id',$pan_xlh['room_id'])->find();
$room_user = db::name('user')->where('id',$room_data['user_id'])->find();
$room_user_data = [
'user_id' => $room_user['id'],
'nickname' => $room_user['nickname'],
'avatar' => $room_user['avatar'],
];
}
}
//$gift_list 按gift_price 升序排序
usort($gift_list, function($a, $b) {
return $a['gift_price'] - $b['gift_price'];
});
$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']??0,
'give_homeowner_gift' => [
'gift_id' => $room_user_gift['gid'],
'gift_name' => $room_user_gift['gift_name'],
'gift_price' => $room_user_gift['gift_price'],
'base_image' => $room_user_gift['base_image'],
],
'homeowner_user' => $room_user_data,
'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']??0
],
'xlh_user' => $xlh_user_data,
'gift_list' => $gift_list,
];
return ['code' => 1, 'msg' => '获取成功', 'data' => $result_data];
}
/*
* 巡乐会抽奖记录
*/
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;
$list = db('vs_gift_bag_receive_pan_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,a.createtime,c.gift_name as gift_name,c.base_image')
->where($where)
->order('a.createtime desc')
->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['e.is_world_show'] = 1;
$list = db('vs_gift_bag_receive_pan_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,a.createtime,c.gift_name,c.base_image,d.nickname')
->where($where)
->order('a.createtime desc')
->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_user_xlh_info($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);
$xlh_data = db('vs_room_pan_xlh')->where(["send_time"=>0,"end_time"=>[">",time()]])->field('id,room_id,periods,end_time')->order('periods desc')->find();
//寻乐会状态
$xlh_status = 0;
// 状态
$xlh_periods_num = Cache::get("xlh_periods_num") ?? 0;
if($xlh_periods_num >= $xlh_ext['open_condition']['start_num']){
$xlh_status = 1;//状态 1:巡乐会开始 2:即将开始 0:等待开始
} elseif($xlh_periods_num >= $xlh_ext['open_condition']['waiting_start_num'] && $xlh_periods_num < $xlh_ext['open_condition']['start_num']){
$xlh_status = 2;//状态 1:巡乐会开始 2:即将开始开始 0:等待开始
}else{
$xlh_status = 0;//未开始
}
return [
'activities_name' => $xlh_box['name'],
'icon' => null,
'xlh_status'=>$xlh_status,
'end_time'=>$xlh_data['end_time'] ?? 0,
];
}
/*
* 巡乐会榜单
*
*/
public function xlh_ranking_list($room_id,$page=1,$page_size=12){
$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);
$pan_xlh = db::name('vs_room_pan_xlh')
->order('id desc')
->page($page,$page_size)
->select();
$list = [];
foreach ($pan_xlh as $key=>$value){
$list[$key]['periods'] = "".$value['periods']."";
if(!empty($value['user_id'])){
$list[$key]['nickname'] = db::name('user')->where(['id'=>$value['user_id']])->value('nickname');
}else{
$list[$key]['nickname'] = "";
}
if(!empty($value['gift_id'])){
$gift_data = db::name('vs_gift')->field('gift_name,base_image')->where(['gid'=>$value['gift_id']])->find();
$list[$key]['gift_name'] = 'x '.$value['num'].' '.$gift_data['gift_name'];
$list[$key]['base_image'] = $gift_data['base_image']??"";
}else{
$gift_data = db::name('vs_gift')->field('gift_name,base_image')->where(['gid'=>$xlh_ext['locking_condition']['locking_gift_id']])->find();
$list[$key]['gift_name'] = 'x 0 '.$gift_data['gift_name'];
$list[$key]['base_image'] = $gift_data['base_image']??"";
}
$list[$key]['createtime'] = $value['send_time'] ? date('Y-m-d H:i:s',$value['send_time']) : '' ;
}
return [
'code' => 1,
'msg' => '成功',
'data' => $list
];
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,801 @@
<?php
namespace app\api\model;
use think\Db;
use think\Log;
use think\Model;
class Friend extends Model
{
public function start_friend($user_id, $room_id){
// 判断用户是否在主持麦
$host = db::name('vs_room_pit')->where(['room_id' => $room_id, 'pit_number' => 9,'user_id' => $user_id])->find();
if(!$host){
return ['code' => 0, 'msg' => '没有权限操作', 'data' => null];
}
$room_info = db::name('vs_room')->field('id,step,room_status')->where(['id' => $room_id,'room_status' =>1])->find();
if (!$room_info) {
return ['code' => 0, 'msg' => '房间不存在!', 'data' => null];
}
if($room_info['step'] == 2 || $room_info['step'] == 3){
return ['code' => 0, 'msg' => '交友正在进行中!', 'data' => null];
}
//在麦位上的用户
$pit_user = db::name('vs_room_pit')->where(['room_id' => $room_id, 'pit_number' => ['<',7],'user_id' => ['<>',0]])->count();
if($pit_user >= 2) {
$data['room_id'] = $room_id;
$data['end_time'] = time() + get_system_config_value('friend_time') * 60;
$data['create_time'] = time();
$data['status'] = 1;
$id = db::name('vs_user_friending')->insertGetId($data);
if (!$id) {
return ['code' => 0, 'msg' => '操作失败!', 'data' => null];
}
//修改房间状态
db::name('vs_room')->where(['id' => $room_id])->update(['step' => 2]);
//清除房间用户的魅力
model('Room')->clear_user_charm($user_id, $room_id);
//推送给前端消息
$text['text'] = '交友开始';
$text['step'] = 2;
$text['friend_id'] = $id;
$text['end_time'] = $data['end_time'];
model('api/Chat')->sendMsg(1049,$room_id,$text);
return ['code' => 1, 'msg' => '操作成功!', 'data' => ['friend_id' => $id]];
}else{
return ['code' => 0, 'msg' => '交友麦位至少两位用户才能开始', 'data' => null];
}
}
//延时
public function delay($user_id,$room_id,$id,$delay_times){
// 判断用户是否在主持麦
$host = db::name('vs_room_pit')->where(['room_id' => $room_id, 'pit_number' => 9,'user_id' => $user_id])->find();
if(!$host){
return ['code' => 0, 'msg' => '没有权限操作', 'data' => null];
}
if (!$id || !$room_id) {
return ['code' => 0, 'msg' => '参数有误!', 'data' => null];
}
if($delay_times <= 0){
$delay_times = get_system_config_value('friend_delay_times');
}
//修改结束 时间
$res = db::name('vs_user_friending')->where('id', $id)->update([
'end_time' => Db::raw('end_time + ' . ($delay_times * 60))
]);
if(!$res){
return ['code' => 0, 'msg' => '操作失败!', 'data' => null];
}
//推送延时
$text['text'] = '延时';
$text['friend_id'] = $id;
$text['end_time'] = db::name('vs_user_friending')->where('id', $id)->value('end_time');
model('api/Chat')->sendMsg(1050,$room_id,$text);
return ['code' => 1, 'msg' => '操作成功!', 'data' => null];
}
//交友结束(结束牵手良缘)
public function end_friend($user_id,$room_id,$id,$is_system = 0){
if (!$id || !$room_id) {
return ['code' => 0, 'msg' => '参数有误!', 'data' => null];
}
if($is_system == 0){
// 判断用户是否在主持麦
$host = db::name('vs_room_pit')->where(['room_id' => $room_id, 'pit_number' => 9,'user_id' => $user_id])->find();
if(!$host){
return ['code' => 0, 'msg' => '没有权限操作', 'data' => null];
}
}
// 获取心动值最高的
$originalPairs = db::name('vs_user_friending_heart')
->where(['room_id'=>$room_id,'friend_id'=>$id ,'status' =>1])
->order('heart_value DESC')->find();
$friend_heart_value = get_system_config_value('friend_heart_value');
if($originalPairs && $originalPairs['heart_value'] >= $friend_heart_value){
$step = 3;//结束进入牵手良缘卡关系
//心动值达到伐值 返回用户信息与关系列表
$return['user1_id'] =$originalPairs['user1_id'];
$return['user1_avatar'] = db::name('user')->where(['id'=>$originalPairs['user1_id']])->value('avatar');
$return['user1_nickname'] = db::name('user')->where(['id'=>$originalPairs['user1_id']])->value('nickname');
$return['user2_id'] =$originalPairs['user2_id'];
$return['user2_avatar'] = db::name('user')->where(['id'=>$originalPairs['user2_id']])->value('avatar');
$return['user2_nickname'] = db::name('user')->where(['id'=>$originalPairs['user2_id']])->value('nickname');
$return['heart_value'] = $originalPairs['heart_value'];
$return['heart_id'] = $originalPairs['id'];
$room_updatatime = db::name('vs_room')->where(['id' => $room_id,'step' => $step])->value('updatetime');
if($room_updatatime){ //60秒内没操作 则创建关系无
if(time() - $room_updatatime > 60){
$this->createRelation(0,$room_id,$id,$return['user1_id'],$return['user2_id'],0);
return ['code' => 1, 'msg' => '操作成功!', 'data' => $return];
}
}else{
// 修改当前交友阶段
db::name('vs_room')->where(['id' => $room_id])->update(['step' => $step,'updatetime' => time()]);
}
}else{
$step = 1;//结束下一轮
// 修改当前交友阶段 分开写 放到前面是为了下麦
db::name('vs_room')->where(['id' => $room_id])->update(['step' => 1]);
//所有人下麦
$on_pit = db::name('vs_room_pit')->where(['room_id' => $room_id, 'pit_number' => ['<',7],'user_id' => ['<>',0]])->select();
if($on_pit){
foreach ($on_pit as $pit){
model('RoomPit')->DownPit($pit['user_id'], $room_id,$pit['pit_number']);
}
}
$return = null;
}
//结束交友游戏
if($step == 1){
db::name('vs_user_friending')->where(['id' => $id])->update(['status' => 2]);
}
//推送给前端消息
$text['text'] = $step == 1 ? '交友结束' : '牵手良缘';
$text['step'] = $step;//1 等待邂逅 2 心动连线 3 牵手良缘
$text['friend_user'] = $return;
$text['friend_id'] = $id;
model('api/Chat')->sendMsg(1049,$room_id,$text);
model('Room')->clear_user_charm(db::name('vs_room')->where(['id' => $room_id])->value('user_id'), $room_id);
return ['code' => 1, 'msg' => '操作成功!', 'data' => $return];
}
//心动值超过配置值 创建关系
public function createRelation($user_id,$room_id,$friend_id,$user1_id,$user2_id,$friending_config_id){
if (!$user1_id || !$user2_id || !$friend_id || !$room_id) {
return ['code' => 0, 'msg' => '参数有误!', 'data' => null];
}
$user1 = min($user1_id, $user2_id);
$user2 = max($user1_id, $user2_id);
$friending_heart = db::name('vs_user_friending_heart')
->where(['room_id'=>$room_id,'friend_id'=>$friend_id ,'user1_id' =>$user1,'user2_id' => $user2])->order('id desc')->find();
$originalPairs = db::name('vs_user_friending_heart')
->where(['id'=>$friending_heart['id']])
->update(['status' => 3,'friend_config_id' =>$friending_config_id]);
$msg = '';
if ($originalPairs) {
$relation = db::name('vs_relation')->where('id',$friending_config_id)->value('name');
if($friending_heart['heart_value'] >= get_system_config_value('friend_heart_create_room') && $friending_config_id > 0){
//创建小房间
$room_ids = model('api/Room')->user_create_room($user1,'的电影房',get_system_config_value('web_site').'/data/avatar/head_pic.png','交友房产生的一次性房间',7);
if($room_ids['code'] != 1){
$msg = 'cp电影房创建失败';
}else{
//记录小房间
$datda = [
'room_id' => $room_ids['data'],
'relation_id' => $friending_config_id,
'user_id' => $user1,
'user_id1' => $user2,
'time_day' => time() + get_system_config_value('friend_room_timea') * 60,
'createtime' => time(),
'status' => 1,
'type' => 1
];
db::name('vs_room_cp_movie')->insert($datda);
if($room_ids['data']){
$text['text'] = '交友结束并创建房间';
$text['room_id'] = $room_ids['data'];//前端用来让用户跳转的房间id
}
}
}else{
$text['text'] = '交友结束未创建房间';
}
$text['relation_name'] = $relation;
$text['user1_id'] = $user1;
$text['user2_id'] = $user2;
$text['user1_avatar'] = db::name('user')->where(['id'=>$user1])->value('avatar');
$text['user1_nickname'] = db::name('user')->where(['id'=>$user1])->value('nickname');
$text['user2_avatar'] = db::name('user')->where(['id'=>$user2])->value('avatar');
$text['user2_nickname'] = db::name('user')->where(['id'=>$user2])->value('nickname');
model('api/Chat')->sendMsg(1051,$room_id,$text);
// 修改当前交友阶段
db::name('vs_room')->where(['id' => $room_id])->update(['step' => 1]);
db::name('vs_user_friending')->where(['id' => $friend_id])->update(['status' => 2]);
//所有人下麦
$on_pit = db::name('vs_room_pit')->where(['room_id' => $room_id, 'pit_number' => ['<',7],'user_id' => ['<>',0]])->select();
if($on_pit){
foreach ($on_pit as $pit){
model('RoomPit')->DownPit($pit['user_id'], $room_id,$pit['pit_number']);
}
}
$shijian = floor($friending_heart['heart_value']/get_system_config_value('friend_heart_value')) * get_system_config_value('friend_heart_times');
$friendendtime = time() + $shijian * 3600;
//更新关系结束时间
db::name('vs_user_friending_heart')->where(['id'=>$friending_heart['id']])->update(['contact_end_time' => $friendendtime]);
//关系增加时间
$room_auction = model('RoomAuction')->room_auction_create_or_add($user1_id,$user2_id,$friending_config_id,$shijian*3600,0);
//推送给前端消息
$text['text'] = '交友结束';
$text['step'] = 1;//1 等待邂逅 2 心动连线 3 牵手良缘
model('api/Chat')->sendMsg(1049,$room_id,$text);
return ['code' => 1, 'msg' => '创建关系成功!'.$msg, 'data' => null];
} else {
//推送给前端消息
$text['text'] = '交友结束';
$text['step'] = 1;//1 等待邂逅 2 心动连线 3 牵手良缘
model('api/Chat')->sendMsg(1049,$room_id,$text);
db::name('vs_user_friending')->where(['id' => $friend_id])->update(['status' => 2]);
return ['code' => 0, 'msg' => '创建关系失败!', 'data' => null];
}
}
//退出私密房间
public function outRoom($user_id,$room_id){
//推送给前端消息
$text['text'] = '退出私密小屋';
model('api/Chat')->sendMsg(1055,$room_id,$text);
// //查询在房间的用户
// $users = db::name('vs_room_visitor')->where(['room_id'=>$room_id])->select();
// if($users){
// //退出房间
// foreach ($users as $v){
// //退出房间
// model('Room')->quit_room($v['user_id'], $room_id,$v['user_id']);
// }
// }else{
// model('Room')->quit_room($user_id, $room_id,$user_id);
// }
//注销房间
db::name('vs_room')->where(['id'=>$room_id])->update(['room_status'=>3]);
db::name('vs_room_cp_movie')->where(['room_id'=>$room_id])->update(['status'=>4]);
model('api/Tencent')->delete_group('room'.$room_id);
return ['code' => 1, 'msg' => '退出成功!', 'data' => null];
}
//房间内送礼
/*
* @param $uid 用户id
* @param $to_uid 接收用户id组
* @param $gift_id 礼物id
* @param $gift_num 礼物数量
* @param $from_type 来源 1聊天送礼物 2房间语聊送礼 3直播送礼 4动态打赏 5系统任务 6-cp房间送礼
* @param $type 1金币购买 2送背包礼物
* @param $room_id 房间id
* @param $pit_number 坑位
*/
public function room_give_gift($uid, $to_uid, $gift_id, $gift_num, $from_type, $type, $room_id, $pit_number, $heart_id,$give_gift_ext)
{
$res = model('GiveGift')->give_gift($uid, $to_uid, $gift_id, $gift_num, $from_type, $type, $room_id, $pit_number,0,$give_gift_ext);
if($res['code'] != 1){
return $res;
}
//送礼成功后续操作
//查看当前时间是否在交友表的创建时间和结束时间段内 用来区分是否要拉取心动值高的用户上麦
$friend = db::name('vs_user_friending')->where(['room_id' => $room_id,'status' => 1])->order('id desc')->find();
if($friend && time() >= $friend['create_time'] && time() <= $friend['end_time']){
$heart_exp = get_system_config_value('coin_charm_exp');//金币与魅力值转换比
$sumPrice = $res['data']['gift_total'] * $heart_exp;
$user_idd = $to_uid;
if($heart_id){//有这个值就是助力 不参加抢麦操作
db::name('vs_user_friending_heart')->where(['id' => $heart_id])->setInc('heart_value', $sumPrice);
$this->pullHeartChange($room_id,$friend['id']);//聊天室心动值变化通知
//生成新排名 判断抱上麦 还是换麦
$this->pullUserPit($room_id,$friend['id']);
}else{
//判断送礼人或收礼人里面有主持和嘉宾
$host = $this->is_host($uid,$to_uid,$room_id);
$user_idd = explode(",", $user_idd); // 将字符串转换为数组
//判断是否是主持
if($host['is_preside'] == 1){
if(!in_array($uid,$host['is_preside_user'])){//主持不是当前送礼人,那就是在收礼人中
//从数组中剔除主持人 && $is_preside_user!= UID
$user_idd = array_diff($user_idd, $host['is_preside_user']); // 从数组中移除
if($user_idd){
//插入/更新心动表
$this->addUserHeart($uid,$user_idd,$friend['id'],$sumPrice,$room_id,$res['data']['gift_user_data']);
//送礼产生心动值并计算 判断拉取用户上麦还是换麦
//生成新排名 判断抱上麦 还是换麦
$this->pullUserPit($room_id,$friend['id']);
}
}
}else{
//插入/更新心动表
$this->addUserHeart($uid,$user_idd,$friend['id'],$sumPrice,$room_id,$res['data']['gift_user_data']);
//送礼产生心动值并计算 判断拉取用户上麦还是换麦
//生成新排名 判断抱上麦 还是换麦
$this->pullUserPit($room_id,$friend['id']);
}
}
}
return ['code' => 1, 'msg' => '送礼成功', 'data' => null];
}
//是否主持
public function is_host($uid,$to_uid,$room_id){
//获取当前主持人和嘉宾
$host[] = db::name('vs_room_pit')->where(['room_id' => $room_id,'pit_number' => 9])->value('user_id');
$host[] = db::name('vs_room_pit')->where(['room_id' => $room_id,'pit_number' => 10])->value('user_id');
$is_preside_user = [];
$is_preside = 0;
$user_ids = explode(",", $to_uid);
foreach ($user_ids as $value) {
//判断收礼人是否是主持
if (in_array($value, $host)) {
$is_preside = 1;
$is_preside_user[] = $value;
}
}
//送礼人是主持或嘉宾
if (in_array($uid, $host)) {
$is_preside = 1;
$is_preside_user[] = $uid;
}
return ['is_preside' =>$is_preside,'is_preside_user' => $is_preside_user];
}
function pullHeartChange($room_id,$friend_id){
//聊天室心动值变化通知
$newRanking = $this->getRanking($room_id,$friend_id);
//心动值和心动表id
if(!isset($newRanking[0]['heart_value']) || $newRanking[0]['heart_value'] <= 0){
$heart1 = -1;
$heartId1 = -1;
}else{
$heart1 = $newRanking[0]['heart_value'];
$heartId1 = $newRanking[0]['id'];
}
if(!isset($newRanking[1]['heart_value']) || $newRanking[1]['heart_value'] <= 0){
$heart2 = -1;
$heartId2 = -1;
}else{
$heart2 = $newRanking[1]['heart_value'];
$heartId2 = $newRanking[1]['id'];
}
if(!isset($newRanking[2]['heart_value']) || $newRanking[2]['heart_value'] <= 0){
$heart3 = -1;
$heartId3 = -1;
}else{
$heart3 = $newRanking[2]['heart_value'];
$heartId3 = $newRanking[2]['id'];
}
$heart[0] = [
"heartNum" => $heart1,
"heartId" => $heartId1,
];
$heart[1] = [
"heartNum" => $heart2,
"heartId" => $heartId2,
];
$heart[2] = [
"heartNum" => $heart3,
"heartId" => $heartId3,
];
// $push = new Push(0, $this->room_id); //实例化推送类
// $push->heartChatRoom($heart);
//推送给前端消息
$text['text'] = '心动值变化通知';
$text['list'] = $heart;
model('api/Chat')->sendMsg(1054,$room_id,$text);
return $heart;
}
// 获取心跳值排行
public function getRanking($room_id,$friend_id) {
// 获取有心动值的用户对且不重复
$originalPairs = db::name('vs_user_friending_heart')
->where(['room_id'=>$room_id,'friend_id'=>$friend_id])
->order('heart_value DESC')->select();
// 初始化排名数组和已使用用户数组
$ranking = [];
$usedUsers = [];
// 优先选择高价值且无重复用户的对
$heart_ids = [];
foreach ($originalPairs as &$rel) {
// 检查当前用户对是否包含已使用的用户ID
if (!in_array($rel['user1_id'], $usedUsers) &&
!in_array($rel['user2_id'], $usedUsers)) {
// 将符合条件的用户对添加到排名列表中
$ranking[] = [
'heart_value' => $rel['heart_value'],
'id' => $rel['id'],
'user1_id' => $rel['user1_id'],
'user2_id' => $rel['user2_id'],
];
// 更新已使用用户列表
$usedUsers = array_merge($usedUsers, [$rel['user1_id'], $rel['user2_id']]);
$heart_ids[] = $rel['id'];
// 如果排名列表达到3对用户则停止循环
if (count($ranking) >= 3) break;
}
}
$ranking1 = [];
$ranking2 = [];
if(count($ranking)<3){
$make_up_num = 3 - count($ranking);
$ranking_make_up = db::name('vs_user_friending_heart')
->where(['room_id'=>$room_id,'friend_id'=>$friend_id ,'id'=> ['notin',$heart_ids]])
->limit($make_up_num)
->order('heart_value DESC')->select();
foreach ($ranking_make_up as $rel1) {
// 如果两个用户都已使用,跳过这条记录
if(in_array($rel1['user1_id'], $usedUsers) && in_array($rel1['user2_id'], $usedUsers)){
continue;
}
// 如果只有user1已使用将user2加入排名
if(in_array($rel1['user1_id'], $usedUsers)){
$ranking1[] = [
'heart_value' => 0,
'id' => $rel1['id'],
'user1_id' => -1,
'user2_id' => $rel1['user2_id'],
];
$usedUsers[] = $rel1['user2_id'];
$heart_ids[] = $rel1['id'];
}
// 如果只有user2已使用将user1加入排名
elseif(in_array($rel1['user2_id'], $usedUsers)){
$ranking1[] = [
'heart_value' => 0,
'id' => $rel1['id'],
'user1_id' => $rel1['user1_id'],
'user2_id' => -1,
];
$usedUsers[] = $rel1['user1_id'];
$heart_ids[] = $rel1['id'];
}
}
}
// 返回最终的排名列表
$ranking_rut = array_merge($ranking, $ranking1);
$nnum = count($ranking)*2 + count($ranking1);
if($nnum<6){
$make_up_num = 6 - $nnum;
$ranking_make_up = db::name('vs_user_friending_heart')
->where(array('room_id'=>$room_id,'friend_id'=>$friend_id ,'id'=>array('notin',$heart_ids)))
->limit($make_up_num)
->order('heart_value DESC')->select();
if($ranking_make_up){
foreach ($ranking_make_up as $rel1) {
if(in_array($rel1['user1_id'], $usedUsers) && in_array($rel1['user2_id'], $usedUsers)){
continue;
}
if(in_array($rel1['user1_id'], $usedUsers)){
$ranking2[] = [
'heart_value' => 0,
'id' => $rel1['id'],
'user1_id' => -1,
'user2_id' => $rel1['user2_id'],
];
$usedUsers[] = $rel1['user2_id'];
}
if(in_array($rel1['user2_id'], $usedUsers)){
$ranking2[] = [
'heart_value' => 0,
'id' => $rel1['id'],
'user1_id' => $rel1['user1_id'],
'user2_id' => -1,
];
$usedUsers[] = $rel1['user1_id'];
}
}
}
}
return array_merge($ranking_rut, $ranking2);
}
//抱上麦 还是换麦
public function pullUserPit($room_id,$friend_id){
$friendPlayPit = $this->friendPlayPit($room_id,$friend_id); // 获取实际应该对应的麦位
$this->changePitToPosPair($room_id,$friendPlayPit);//换麦,上下麦
$this->pullHeartChange($room_id,$friend_id);//聊天室心动值变化通知
}
//交友处理麦位排名
public function friendPlayPit($room_id,$friend_id){
//查询当前交友心动值表
$heart_data = $this->getRanking($room_id,$friend_id);
//数组根据里面的heart_value 由大到小进行排序
usort($heart_data, function($a, $b) {
return $b['heart_value'] - $a['heart_value'];
});
$pit = [];
$pit_number_array = [2=>5,1=>6,3=>4,5=>2,6=>1,4=>3]; //麦位对应关系
$pit_number_array_reverse = [0=>2,1=>1,2=>3,3=>4,4=>5,5=>6];
if($heart_data){
//排麦位
$pit_unique = [];
$key = 0;
foreach($heart_data as $value) {
if(count($pit) >= 6){
break;
}
// 处理两个用户都存在的情况
if($value['user1_id'] != -1 && $value['user2_id'] != -1){
if(!in_array($value['user1_id'],$pit_unique)){
// 检查目标麦位是否已被占用
if(!isset($pit[$pit_number_array_reverse[$key]])) {
$pit[$pit_number_array_reverse[$key]] = $value['user1_id'];
$pit[$pit_number_array[$pit_number_array_reverse[$key]]] = $value['user2_id'];
$pit_unique = array_merge($pit_unique, [$value['user1_id'], $value['user2_id']]);
}
}
}
// 处理只有user2存在的情况
elseif($value['user1_id'] == -1 && !in_array($value['user2_id'],$pit_unique)){
// 检查该键是否已被使用
if(!isset($pit[$pit_number_array_reverse[$key]])) {
$pit[$pit_number_array_reverse[$key]] = $value['user2_id'];
$pit_unique[] = $value['user2_id'];
}
}
// 处理只有user1存在的情况
elseif($value['user2_id'] == -1 && !in_array($value['user1_id'],$pit_unique)){
// 检查该键是否已被使用
if(!isset($pit[$pit_number_array_reverse[$key]])) {
$pit[$pit_number_array_reverse[$key]] = $value['user1_id'];
$pit_unique[] = $value['user1_id'];
}
}
$key++;
}
}
return $pit;
}
//换麦
public function changePitToPosPairs($room_id,$friendPlayPit){
$now_pit_u = array_flip($friendPlayPit);
//按照键值排序数组
ksort($now_pit_u);
//查询现在麦位上有用户的数据 并且重组结果,键为麦位,值为用户,值必须存在,没值则不展示
$pit_user = db::name('vs_room_pit')->where(['room_id' => $room_id,'pit_number'=>['<',7],'user_id' => ['>', 0]])
->order('pit_number ASC')
->column('pit_number,user_id');
//比较两个数组,无论是键的差异还是值的差异,都输出字符串”有差异“否则输出”没有差异“
$result = array_diff_assoc($pit_user, $now_pit_u);
$result2 = array_diff_assoc($now_pit_u, $pit_user);
if(!empty($result) || !empty($result2)){
// var_dump('有差异');
//获取实际麦位上的用
$newPitUser = array_keys($friendPlayPit);
//获取当前麦位上的用户
$oldPitUser = db::name('vs_room_pit')->where(['room_id' => $room_id,'pit_number'=>['<',7]])->column('user_id');
//获取交集
$intersection = array_intersect($newPitUser,$oldPitUser);
//取差集
$diff = array_diff($newPitUser,$oldPitUser);
$changeData = [];
if($diff){
//推下麦
foreach($diff as $key => $value){
if(in_array($value,$oldPitUser)){
//查询当前空麦位
$pit_null = model('api/RoomPit')->getRoomNullPitWithout($room_id, [7,8,9,10]);
if($pit_null){
// $this->room_pit_model->getOnPit($this->room_id, $value, $pit_null);
model('api/RoomPit')->OnPit($value, $room_id, $pit_null);
// db::name('vs_room_pit')->where(['room_id' => $room_id, 'pit_number' => $pit_null])->update(['user_id' => $value]);
}else{
//下麦
$UserRoomPit = db::name('vs_room_pit')->where(['room_id' => $room_id, 'user_id' => $value])->value('pit_number');
model('api/RoomPit')->DownPit($value, $room_id, $UserRoomPit);
}
}
if(in_array($value,$newPitUser)){
//推上麦
//获取目标麦位是否有人
$getRoomPitUser= db::name('vs_room_pit')->where(['room_id' => $room_id, 'pit_number' => $friendPlayPit[$value]])->value('user_id');
if($getRoomPitUser){
//查询当前空麦位
$getRoomNullPitss = model('api/RoomPit')->getRoomNullPitWithout($room_id, [7,8,9,10,$friendPlayPit[$value]]);
if($getRoomNullPitss){
// $this->room_pit_model->getOnPit($this->room_id, $getRoomPitUser, $getRoomNullPitss);
db::name('vs_room_pit')->where(['room_id' => $room_id, 'pit_number' => $getRoomNullPitss])->update(['user_id' => $getRoomPitUser]);
}else{
model('api/RoomPit')->DownPit($getRoomPitUser, $room_id, $friendPlayPit[$value]);
}
}
model('api/RoomPit')->OnPit($value, $room_id, $friendPlayPit[$value]);
}
}
}
if($intersection){//交换麦位
//查询麦上的用户
$newPitUserStr = implode(',',$newPitUser);
$getRoomPit = db::name('vs_room_pit')->where("room_id=".$room_id." AND user_id in (".$newPitUserStr.")")->column('pit_number');
db::name('vs_room_pit')->where(['room_id' => $room_id, 'pit_number' => ['in', $getRoomPit]])->update(['user_id' => 0]);
$changePitUser = [];
foreach ($friendPlayPit as $key => $value){
if(empty($value)){
$value = model('api/RoomPit')->getRoomNullPitWithout($room_id, [7,8,9,10]);
}
//获取目标麦位是否有人
$isPitHaveUser= db::name('vs_room_pit')->where(['room_id' => $room_id, 'pit_number' => $value])->value('user_id');
if($isPitHaveUser && !in_array($isPitHaveUser,$newPitUser)){
$changePitUser[$key]['user_id'] = $isPitHaveUser;
$changePitUser[$key]['pit_number'] = $value;
}
db::name('vs_room_pit')->where(['room_id' => $room_id, 'pit_number' => $value])->update(['user_id' => $key]);
}
//处理原麦位上的用户
foreach ($changePitUser as $key_change => $value_change){
//判断是否在左边 1,2,3 麦位上
if(in_array($value_change['pit_number'],[1,2,3])){
$null_pit = model('api/RoomPit')->getRoomNullPitWithout($room_id, [4,5,6,7,8,9,10]);
if(empty($null_pit)){
$null_pit = model('api/RoomPit')->getRoomNullPitWithout($room_id, [7,8,9,10]);
}
}else{
$null_pit = model('api/RoomPit')->getRoomNullPitWithout($room_id, [1,2,3,7,8,9,10]);
if(empty($null_pit)){
$null_pit = model('api/RoomPit')->getRoomNullPitWithout($room_id, [7,8,9,10]);
}
}
db::name('vs_room_pit')->where(['room_id' => $room_id, 'pit_number' => $null_pit])->update(['user_id' => $value_change['user_id']]);
}
// $getRoomNullPit = $this->room_pit_model->where(['room_id'=>$room_id,'pit_number'=>['notin',[7,9]]])->select();
$getRoomNullPit = db::name('vs_room_pit')->where(['room_id' => $room_id, 'pit_number' => ['<',7]])->select();
$data_users = [];
foreach($getRoomNullPit as $key_data => $value_data){
$data_users[$key_data]['user_id'] = $value_data['user_id'];
$data_users[$key_data]['nickname'] = db::name('user')->where('id',$value_data['user_id'])->value('nickname');
$data_users[$key_data]['avatar'] = db::name('user')->where('id',$value_data['user_id'])->value('avatar');
$data_users[$key_data]['sex'] = db::name('user')->where('id',$value_data['user_id'])->value('sex');
//获取用户在此房间今天的魅力值
$charm =[];
if($value_data['user_id']){
$charm = db::name('vs_room_user_charm')->where(['user_id' => $value_data['user_id'],'room_id' => $room_id])->value('charm');
}
$data_users[$key_data]['dress'] = model('Decorate')->user_decorate_detail($value_data['user_id'],1);
$data_users[$key_data]['charm'] = $charm??0;
$data_users[$key_data]['pit_number'] = $value_data['pit_number'];
}
//推送给前端消息
$text['text'] = '房间换麦位';
$text['list'] = $data_users;
model('api/Chat')->sendMsg(1053,$room_id,$text);
}
}
}
//换麦
public function changePitToPosPair($room_id,$friendPlayPit){
$new_pit_u = $friendPlayPit;
//按照键值排序数组
ksort($new_pit_u);
//查询原有麦位上有用户的数据 并且重组结果,键为麦位,值为用户,值必须存在,没值则不展示
$pit_users = db::name('vs_room_pit')->where(['room_id' => $room_id,'pit_number'=>['<',7],'user_id' => ['>', 0]])
->order('pit_number ASC')
->field('pit_number,user_id')->select();
$pit_user = [];
foreach ($pit_users as $value_pit_user){
$pit_user[$value_pit_user['pit_number']] = $value_pit_user['user_id'];
}
//比较两个数组,无论是键的差异还是值的差异,都输出字符串”有差异“否则输出”没有差异“
$result = array_diff_assoc($pit_user, $new_pit_u);//第一个数组中存在但其他数组中不存在的键/值对
$result2 = array_diff_assoc($new_pit_u, $pit_user);
if(!empty($result) || !empty($result2)){//换麦
db::name('vs_room_pit')->where(['room_id' => $room_id,'pit_number' => ['<',7]])->update(['user_id' => 0]);
//新麦位上的用户
foreach ($new_pit_u as $key_result2 => $value_result2){
db::name('vs_room_pit')->where(['room_id' => $room_id, 'pit_number' => $key_result2])->update(['user_id' => $value_result2]);
}
if($result){//原有麦位上的用户,且不在新麦位上的用户
foreach ($result as $key_result => $value_result){
$pit_null = model('api/RoomPit')->getRoomNullPitWithout($room_id, [7,8,9,10]);
$onPitUser = db::name('vs_room_pit')->where(['room_id' => $room_id, 'user_id' => $value_result])->find();
if($pit_null && !$onPitUser){
db::name('vs_room_pit')->where(['room_id' => $room_id, 'pit_number' => $pit_null])->update(['user_id' => $value_result]);
}
}
}
$getRoomNullPit = db::name('vs_room_pit')->where(['room_id' => $room_id, 'pit_number' => ['<',7]])->select();
$data_users = [];
foreach($getRoomNullPit as $key_data => $value_data){
$data_users[$key_data]['user_id'] = $value_data['user_id'];
$data_users[$key_data]['nickname'] = db::name('user')->where('id',$value_data['user_id'])->value('nickname');
$data_users[$key_data]['avatar'] = db::name('user')->where('id',$value_data['user_id'])->value('avatar');
$data_users[$key_data]['sex'] = db::name('user')->where('id',$value_data['user_id'])->value('sex');
//获取用户在此房间今天的魅力值
$charm =[];
if($value_data['user_id']){
$charm = db::name('vs_room_user_charm')->where(['user_id' => $value_data['user_id'],'room_id' => $room_id])->value('charm');
}
$data_users[$key_data]['dress'] = model('Decorate')->user_decorate_detail($value_data['user_id'],1);
$data_users[$key_data]['charm'] = $charm??0;
$data_users[$key_data]['pit_number'] = $value_data['pit_number'];
}
//推送给前端消息
$text['text'] = '房间换麦位';
$text['list'] = $data_users;
model('api/Chat')->sendMsg(1053,$room_id,$text);
}
}
//交友厅游戏开始后送礼后一系列操作
//插入/更新心动表
public function addUserHeart($uid,$user_id,$friend_id,$value,$room_id,$user_data){
//给多个用户送礼
//数组重组 下标从0开始
$user_ids = array_values($user_id);
// $heart_value = $value;//心动值
$heart_value = 0;
$heart_exp = get_system_config_value('coin_charm_exp');//金币与魅力值转换比
for ($i = 0; $i < count($user_ids); $i++) {
foreach ($user_data as $cv){
if($user_ids[$i] == $cv['user_id']){
$heart_value = $cv['gift_price'] * $heart_exp;
}
}
// 处理用户ID顺序
$user1 = min($uid, $user_ids[$i]);
$user2 = max($uid, $user_ids[$i]);
// 更新心动关系表
$relation = db::name('vs_user_friending_heart')->where([
'user1_id' => $user1,
'user2_id' => $user2,
'friend_id' => $friend_id
])->find();
if ($relation) {
db::name('vs_user_friending_heart')->where([
'room_id' => $room_id,
'user1_id' => $user1,
'user2_id' => $user2,
'friend_id' => $friend_id
])->setInc('heart_value', $heart_value);
} else {
$relation['id'] = db::name('vs_user_friending_heart')->insert([
'room_id' => $room_id,
'user1_id' => $user1,
'user2_id' => $user2,
'friend_id' => $friend_id,
'heart_value' => $heart_value
]);
}
}
//修改用户心动连线状态
// $relation = db::name('vs_user_friending_heart')->where("(user1_id=".$uid." OR user2_id=".$uid.") AND friend_id=$friend_id AND room_id=$room_id AND status!=3")->order('heart_value desc')->find();
// if($relation){
// db::name('vs_user_friending_heart')->where("(user1_id=".$uid." OR user2_id=".$uid.") AND friend_id=$friend_id AND room_id=$room_id AND status!=3")->update(['status'=>2]);
// db::name('vs_user_friending_heart')->where(['id'=>$relation['id']])->update(['status'=>1]);
// }
}
}

View File

@@ -0,0 +1,73 @@
<?php
namespace app\api\model;
use think\Db;
use think\Model;
class RoomHourRanking extends Model
{
//房间小时榜
public function room_hour_ranking($page, $page_limit,$start_time = null, $end_time = null)
{
//当前小时开始时间
if($start_time == null){
$start_time = strtotime(date('Y-m-d H:00:00'));
}
//结束时间
if($end_time == null){
$end_time = strtotime(date('Y-m-d H:59:59'));
}
//判断是否开启
$open_time = db::name('vs_hour_ranking_config')->where('id', 1)->value('open_time');
if ($open_time == 0) {
return ['code' => 0, 'msg' => '排行榜暂未开启', 'data' => null];
}
//是否开启巡乐会
$is_open_xlh = db::name('vs_hour_ranking_config')->where('id', 1)->value('is_open_xlh');
// 更进一步的优化版本:
$subQuery = Db::name('vs_give_gift')
->where('from', 2)
->whereBetween('createtime', [$start_time, $end_time])
->buildSql();
$profit = db::name('vs_room')->alias('a')
->join([$subQuery => 'b'], 'a.id = b.from_id', 'left')
->join('vs_room_label c', 'a.label_id = c.id','left')
->field('a.id as room_id,a.user_id,a.room_name,a.label_id,a.room_cover,IFNULL(SUM(b.total_price), 0) as total_price,c.label_icon')
->where('a.room_status', 1)
->where('a.apply_status', 2)
->where('a.type_id', '<>', 6)
->group('a.id')
->order('total_price', 'desc')
->page($page, $page_limit)
->select();
if($profit){
foreach ($profit as &$v) {
$v['total_price'] = $v['total_price'] * get_system_config_value('coin_charm_exp');
if($v['room_id'] > 0 && $is_open_xlh == 1){
$xlh_status = model('BlindBoxTurntableGift')->get_user_xlh_info($v['room_id']);
$v['xlh_status'] = $xlh_status['xlh_status'];
}else{
$v['xlh_status'] = 0;
}
//查询房间是否有红包
if($v['room_id'] > 0){
$red_pack_status = Db::name('redpacket')->where(['room_id' => $v['room_id'], 'status' => ['<=',1]])->count();
$v['redpacket_status'] = $red_pack_status;
}else{
$v['redpacket_status'] = 0;
}
}
}
//当前小时开始时间 和结束时间 00:00-00:59 这样的格式
$time_range = date('H:') . '00-' . date('H:'). '59';
return ['code' => 1, 'msg' => '获取成功', 'data' => ['time_range' => $time_range, 'lists' =>$profit]];
}
}

View File

@@ -0,0 +1,114 @@
<?php
namespace app\common\library;
class RedpacketLua
{
/**
* 抢红包Lua脚本
* 保证原子性操作,防止超抢
*/
public static function grabRedpacketScript()
{
return <<<LUA
-- KEYS[1]: 红包key, KEYS[2]: 用户集合key, KEYS[3]: 用户ID
-- ARGV[1]: 当前时间
local redpacketKey = KEYS[1]
local userSetKey = KEYS[2]
local userId = KEYS[3]
local currentTime = tonumber(ARGV[1])
-- 检查红包是否存在
local redpacketData = redis.call('HGETALL', redpacketKey)
if not redpacketData or #redpacketData == 0 then
return {0, "红包不存在", 0}
end
-- 将哈希数据转为table
local redpacket = {}
for i = 1, #redpacketData, 2 do
redpacket[redpacketData[i]] = redpacketData[i + 1]
end
-- 检查红包状态
local status = tonumber(redpacket['status'])
local startTime = tonumber(redpacket['start_time'])
local endTime = tonumber(redpacket['end_time'])
if status == 0 then
if currentTime < startTime then
return {0, "红包还未开始", 0}
else
-- 更新状态为进行中(1)
redis.call('HSET', redpacketKey, 'status', 1)
status = 1
end
end
if status ~= 1 then
return {0, "红包已结束", 0}
end
if currentTime > endTime then
redis.call('HSET', redpacketKey, 'status', 2)
return {0, "红包已结束", 0}
end
-- 检查是否已经抢过
local hasGrabbed = redis.call('SISMEMBER', userSetKey, userId)
if hasGrabbed == 1 then
return {0, "已经抢过该红包", 0}
end
-- 检查是否还有剩余
local leftAmount = tonumber(redpacket['left_amount'])
local leftCount = tonumber(redpacket['left_count'])
if leftCount <= 0 or leftAmount <= 0 then
return {0, "红包已抢完", 0}
end
-- 计算红包金额
local amount = 0
local isFinished = 0
if leftCount == 1 then
-- 最后一个红包,获得剩余所有金额
amount = leftAmount
isFinished = 1
else
-- 随机算法:二倍均值法,保证公平性
local maxAmount = leftAmount / leftCount * 2
amount = math.random(1, math.floor(maxAmount))
-- 确保金额不会超过剩余金额
if amount > leftAmount then
amount = leftAmount
end
-- 检查是否是最后一个(由于浮点数计算可能有误差)
if leftCount == 1 or (leftAmount - amount) < 0.01 then
isFinished = 1
end
end
-- 更新红包数据
local newLeftAmount = leftAmount - amount
local newLeftCount = leftCount - 1
redis.call('HSET', redpacketKey, 'left_amount', newLeftAmount)
redis.call('HSET', redpacketKey, 'left_count', newLeftCount)
-- 标记用户已抢
redis.call('SADD', userSetKey, userId)
-- 如果抢完了,更新状态为已结束(2)
if isFinished == 1 then
redis.call('HSET', redpacketKey, 'status', 2)
end
return {1, tostring(amount), isFinished}
LUA;
}
}

View File

@@ -0,0 +1,171 @@
<?php
namespace app\common\model;
use app\common\controller\Push;
use think\Model;
use think\Db;
class Redpacket extends Model
{
// 红包状态
const STATUS_PENDING = 0; // 未开始
const STATUS_ACTIVE = 1; // 进行中
const STATUS_FINISHED = 2; // 已结束
const STATUS_REFUNDED = 3; // 已退回
// 红包类型
const TYPE_NORMAL = 1; // 普通红包
const TYPE_PASSWORD = 2; // 口令红包
// 币种类型
const COIN_GOLD = 1; // 金币
const COIN_DIAMOND = 2; // 钻石
// 倒计时选项
public static $countdownOptions = [
0 => '立刻',
60 => '1分钟',
120 => '2分钟',
300 => '5分钟',
600 => '10分钟'
];
// 领取条件
const CONDITION_NONE = 0;
const CONDITION_COLLECT_ROOM = 1;
const CONDITION_MIC_USER = 2;
protected $autoWriteTimestamp = true;
protected $createTime = 'createtime';
protected $updateTime = 'updatetime';
/**
* 发红包
*/
public function createRedpacket($data)
{
// var_dump($data);exit;
Db::startTrans();
try {
// 验证用户余额
$wallet = Db::name('user_wallet')->where('user_id', $data['user_id'])->find();
$coinField = $data['coin_type'] == self::COIN_GOLD ? 'coin' : 'earnings';
if ($wallet[$coinField] < $data['total_amount']) {
return ['code' => 0, 'msg' => '余额不足', 'data' => null];
}
// 扣除余额
$delres = Db::name('user_wallet')
->where('user_id', $data['user_id'])
->dec($coinField, $data['total_amount'])
->update();
//记录日志 32-发红包金币29-发红包钻石30-抢红包金币31-抢红包(钻石)
//记录用户金币日志
$data_log = [
'user_id' => $data['user_id'],
'change_value' => $data['total_amount'],
'room_id' => $data['room_id'],
'money_type' => $data['coin_type'],
'change_type' => $data['coin_type'] == self::COIN_GOLD ? 32 : 29,
'from_id' => $data['room_id'],
'remarks' => $data['coin_type'] == self::COIN_GOLD ? '金币(发红包)' : '钻石(发红包)',
'createtime' => time()
];
$res = Db::name('vs_user_money_log')->insert($data_log);
if(!$res || !$delres){
Db::rollback();
}
// 计算开始时间
$startTime = $data['countdown'] > 0 ? (time() + $data['countdown']) : time();
//获取配置项 红包没有抢完所展示时间
$endTime = $startTime + get_system_config_value('red_packet_time') ?? 120; // 默认2分钟后结束
// 创建红包
$redpacketData = [
'user_id' => $data['user_id'],
'room_id' => $data['room_id'],
'type' => $data['type'],
'password' => $data['password'] ?? '',
'countdown' => $data['countdown'],
'coin_type' => $data['coin_type'],
'total_amount' => $data['total_amount'],
'total_count' => $data['total_count'],
'left_amount' => $data['total_amount'],
'left_count' => $data['total_count'],
'conditions' => $data['conditions'] ?? '',
'status' => $data['countdown'] > 0 ? self::STATUS_PENDING : self::STATUS_ACTIVE,
'start_time' => $startTime,
'end_time' => $endTime,
'createtime' => time(),
'remark' => (!empty($data['remark']) && trim($data['remark']) !== '') ? trim($data['remark']) : '大吉大利,红包拿来啦!'
];
$redpacketId = $this->insertGetId($redpacketData);
// 设置Redis缓存
$redis = \think\Cache::store('redis')->handler();
$redisKey = "redpacket:{$redpacketId}";
$redis->hMSet($redisKey, [
'total_amount' => $data['total_amount'],
'left_amount' => $data['total_amount'],
'total_count' => $data['total_count'],
'left_count' => $data['total_count'],
'status' => $redpacketData['status'],
'start_time' => $startTime,
'end_time' => $endTime
]);
// 设置过期时间
$redis->expireAt($redisKey, $endTime + 3600); // 结束后保留1小时
Db::commit();
//给前端推送信息
$data['nickname'] = Db::name('user')->where('id', $data['user_id'])->value('nickname');
$data['avatar'] = Db::name('user')->where('id', $data['user_id'])->value('avatar');
$data['redpacket_id'] = $redpacketId;
$data['start_time'] = $startTime;//红包开抢时间
$data['redpacket_time'] = get_system_config_value('red_packet_time');//展示时间
$data['room_name'] = Db::name('vs_room')->where('id', $data['room_id'])->value('room_name');
$text = [
'redpacketInfo' => $data,
'text' => ''
];
model('api/Chat')->sendMsg(1060,$data['room_id'],$text);
$push = new Push(UID, $data['room_id']);
$texts = [
'room_id' => $data['room_id'],
'text' => $data['nickname'].'在'.$data['room_name'].'房间发了一个红包!',
'room_name' => $data['room_name'],
'nickname' => $data['nickname']
];
$push->redpacketArrive($texts);
return ['code' => 1, 'msg' => '发红包成功', 'data' => $redpacketId];
} catch (\Exception $e) {
Db::rollback();
return ['code' => 0, 'msg' => $e->getMessage(), 'data' => null];
}
}
/**
* 获取红包信息
*/
public function getRedpacketInfo($id)
{
$redpacket = $this->find($id);
if (!$redpacket) {
return null;
}
$redpacket = $redpacket->toArray();
$redpacket['nickname'] = Db::name('user')->where('id', $redpacket['user_id'])->value('nickname');
$redpacket['avatar'] = Db::name('user')->where('id', $redpacket['user_id'])->value('avatar');
$redpacket['redpacket_id'] = $redpacket['id'];
return $redpacket;
}
}

View File

@@ -0,0 +1,12 @@
<?php
namespace app\common\model;
use think\Model;
class RedpacketRecord extends Model
{
protected $autoWriteTimestamp = true;
protected $createTime = 'createtime';
protected $updateTime = false;
}

View File

@@ -0,0 +1,707 @@
<?php
namespace app\common\service;
use think\Db;
use think\Cache;
use app\common\model\Redpacket;
use app\common\model\RedpacketRecord;
use app\common\model\UserWallet;
use app\common\library\RedpacketLua;
class RedpacketService
{
/**
* 发红包
*/
public function create($data)
{
// 验证数据
$res = $this->validateCreateData($data);
if ($res['code'] == 0) {
return $res;
}
$redpacketModel = new Redpacket();
return $redpacketModel->createRedpacket($data);
}
/**
* 抢红包并返回详细结果
*/
public function grabWithResult($redpacketId, $userId)
{
$redpacketModel = new Redpacket();
$redpacket = $redpacketModel->getRedpacketInfo($redpacketId);
if (!$redpacket) {
return [
'code' => 0,
'msg' => '红包不存在',
'data' => null
];
}
// 验证领取条件
$conditionCheck = $this->checkConditionsWithResult($redpacket, $userId);
if ($conditionCheck['code'] != 1) {
return $conditionCheck;
}
// 检查红包状态
$statusCheck = $this->checkRedpacketStatus($redpacket);
if ($statusCheck['code'] != 1) {
return $statusCheck;
}
// 检查是否已经抢过
if ($this->hasUserGrabbed($redpacketId, $userId)) {
// $detail = $this->getGrabResult($redpacketId, $userId);
return [
'code' => 1,
'msg' => '已经抢过该红包',
'data' => ['code' => 2] //1-抢到了2-已经抢过红包3-没有抢到
];
}
// 使用Redis+Lua保证原子性操作
$redis = Cache::store('redis')->handler();
$script = RedpacketLua::grabRedpacketScript();
$redpacketKey = "redpacket:{$redpacketId}";
$userSetKey = "redpacket_users:{$redpacketId}";
$result = $redis->eval($script, [
$redpacketKey,
$userSetKey,
$userId,
time()
], 3);
if ($result[0] == 0) {
$message = $result[1];
if ($message == '红包已抢完') {
return [
'code' => 1,
'msg' => '手慢了,红包已抢完',
'data' => ['code' => 3] //1-抢到了2-已经抢过红包3-没有抢到
];
} elseif ($message == '已经抢过该红包') {
return [
'code' => 1,
'msg' => '已经抢过该红包',
'data' => ['code' => 2] //1-抢到了2-已经抢过红包3-没有抢到
];
}elseif ($message == '红包已结束') {
return [
'code' => 1,
'msg' => '手慢了,红包已抢完',
'data' => ['code' => 3] //1-抢到了2-已经抢过红包3-没有抢到
];
}
else{
return [
'code' => 0,
'msg' => $message,
'data' => null
];
}
}
$amount = floatval($result[1]);
$isFinished = $result[2] == 1; // Lua脚本返回是否抢完
//给前端推送销毁这个红包
// redis 记录该红包是否已经推送过了 只推送一次
if($isFinished){
$redisKey = "redpacket:{$redpacketId}:is_finished";
if (!Cache::get($redisKey)) {
Cache::set($redisKey, 1, $redpacket['countdown']+get_system_config_value('red_packet_time')+60);
$text = [
'redpacket_id' => $redpacketId,
'text' => '抢完了,请销毁该红包'
];
model('api/Chat')->sendMsg(1061,$redpacket['room_id'],$text);
}
}
// Lua脚本执行成功记录到数据库
Db::startTrans();
try {
// 创建领取记录
$recordData = [
'redpacket_id' => $redpacketId,
'user_id' => $userId,
'amount' => $amount
];
$recordModel = new RedpacketRecord();
$recordModel->save($recordData);
// 更新用户钱包
$coinField = $redpacket['coin_type'] == 1 ? 'coin' : 'earnings';
//增加余额
$addres = Db::name('user_wallet')
->where('user_id', $userId)
->inc($coinField, $amount)
->update();
//记录用户金币日志
$data = [
'user_id' => $userId,
'change_value' => $amount,
'room_id' => $redpacket['room_id'],
'money_type' => $redpacket['coin_type'],
//记录日志 32-发红包金币29-发红包钻石30-抢红包金币31-抢红包(钻石)
'change_type' => $redpacket['coin_type'] == 1 ? 30 : 31,
'from_id' => $redpacket['room_id'],
'remarks' => '抢红包收入',
'createtime' => time()
];
$res = Db::name('vs_user_money_log')->insert($data);
if(!$res || !$addres){
Db::rollback();
}
// 更新红包剩余数量和金额,如果抢完了更新状态
$updateData = [
'left_amount' => Db::raw('left_amount - ' . $amount),
'left_count' => Db::raw('left_count - 1'),
'updatetime' => time()
];
if ($isFinished) {
$updateData['status'] = Redpacket::STATUS_FINISHED;
}
Db::name('redpacket')
->where('id', $redpacketId)
->update($updateData);
Db::commit();
// 获取抢红包结果详情
$grabResult = $this->getGrabResult($redpacketId, $userId);
unset($grabResult['previous_records']);//前端不要
unset($grabResult['all_records']);//前端不要
unset($grabResult['statistics']);//前端不要
return [
'code' => 1,
'msg' => '抢红包成功',
// 'data' => $grabResult
// 'data' => null
'data' => ['code' => 1] //1-抢到了2-已经抢过红包3-没有抢到
];
} catch (\Exception $e) {
Db::rollback();
// 回滚Redis操作
$redis->hIncrByFloat($redpacketKey, 'left_amount', $amount);
$redis->hIncrBy($redpacketKey, 'left_count', 1);
$redis->sRem($userSetKey, $userId);
return [
'code' => 0,
'msg' => '系统错误,请重试'.$e->getMessage(),
'data' => null
];
}
}
/**
* 获取抢红包结果详情
*/
public function getGrabResult($redpacketId, $userId)
{
// 获取红包基本信息
$redpacket = Db::name('redpacket')
->where('id', $redpacketId)
->find();
if (!$redpacket) {
return null;
}
// 获取当前用户的领取记录
$myRecord = Db::name('redpacket_record')
->alias('r')
->field('r.*, u.nickname, u.avatar')
->join('user u', 'u.id = r.user_id')
->where('r.redpacket_id', $redpacketId)
->where('r.user_id', $userId)
->find();
// 获取在我之前抢到的用户记录
$previousRecords = [];
if ($myRecord) {
$previousRecords = Db::name('redpacket_record')
->alias('r')
->field('r.*, u.nickname, u.avatar')
->join('user u', 'u.id = r.user_id')
->where('r.redpacket_id', $redpacketId)
->where('r.createtime', '<', $myRecord['createtime'])
->order('r.createtime ASC')
->select();
}
// 获取所有记录用于统计
$allRecords = Db::name('redpacket_record')
->alias('r')
->field('r.*, u.nickname, u.avatar')
->join('user u', 'u.id = r.user_id')
->where('r.redpacket_id', $redpacketId)
->order('r.createtime ASC')
->select();
// 统计信息
$totalGrabbed = count($allRecords);
$totalAmount = array_sum(array_column($allRecords, 'amount'));
// 手气最佳
$bestRecord = null;
if ($allRecords) {
$maxAmount = max(array_column($allRecords, 'amount'));
foreach ($allRecords as $record) {
if ($record['amount'] == $maxAmount) {
$bestRecord = $record;
break;
}
}
}
return [
'redpacket_info' => [
'id' => $redpacket['id'],
'total_amount' => $redpacket['total_amount'],
'total_count' => $redpacket['total_count'],
'left_amount' => $redpacket['left_amount'],
'left_count' => $redpacket['left_count'],
'coin_type' => $redpacket['coin_type'],
'status' => $redpacket['status'],
'nickname' => Db::name('user')->where('id', $redpacket['user_id'])->value('nickname')
],
'my_record' => $myRecord ? [
'amount' => $myRecord['amount'],
'createtime' => $myRecord['createtime'],
'nickname' => $myRecord['nickname'],
'avatar' => $myRecord['avatar']
] : null,
'previous_records' => $previousRecords,
'all_records' => $allRecords,
'statistics' => [
'total_grabbed' => $totalGrabbed,
'total_amount_grabbed' => $totalAmount,
'best_luck' => $bestRecord ? [
'nickname' => $bestRecord['nickname'],
'avatar' => $bestRecord['avatar'],
'amount' => $bestRecord['amount']
] : null
]
];
}
/**
* 检查红包状态
*/
private function checkRedpacketStatus($redpacket)
{
$now = time();
if ($redpacket['status'] == Redpacket::STATUS_PENDING) {
if ($now < $redpacket['start_time']) {
return [
'code' => 0,
'msg' => '红包还未开始',
'data' => null
];
}
}
// if ($redpacket['status'] == Redpacket::STATUS_FINISHED ||
// $redpacket['status'] == Redpacket::STATUS_REFUNDED) {
// return [
// 'code' => 0,
// 'msg' => '红包已结束',
// 'data' => null
// ];
// }
//
// if ($now > $redpacket['end_time']) {
// return [
// 'code' => 0,
// 'msg' => '红包已结束',
// 'data' => null
// ];
// }
return ['code' => 1];
}
/**
* 检查用户是否已经抢过
*/
private function hasUserGrabbed($redpacketId, $userId)
{
$record = Db::name('redpacket_record')
->where('redpacket_id', $redpacketId)
->where('user_id', $userId)
->find();
return !empty($record);
}
/**
* 检查领取条件(返回结果格式)
*/
private function checkConditionsWithResult($redpacket, $userId)
{
$conditions = $redpacket['conditions'] ? explode(',', $redpacket['conditions']): [];
if (empty($conditions)) {
return ['code' => 1];
}
if (in_array(Redpacket::CONDITION_NONE, $conditions)) {
return ['code' => 1];
}
foreach ($conditions as $condition) {
switch ($condition) {
case Redpacket::CONDITION_COLLECT_ROOM:
if (!$this->checkUserCollectedRoom($userId, $redpacket['room_id'])) {
return [
'code' => 0,
'msg' => '不满足收藏房间条件',
'data' => null
];
}
break;
case Redpacket::CONDITION_MIC_USER:
if (!$this->checkUserOnMic($userId, $redpacket['room_id'])) {
return [
'code' => 0,
'msg' => '您不是麦上用户',
'data' => null
];
}
break;
}
}
return ['code' => 1];
}
/**
* 获取红包详情和领取记录
*/
public function getDetail($redpacketId, $currentUserId = 0)
{
$redpacketModel = new Redpacket();
$redpacket['redpacket_info'] = $redpacketModel->getRedpacketInfo($redpacketId);
if (!$redpacket) {
return null;
}
// 获取领取记录
$records = Db::name('redpacket_record')
->alias('r')
->field('r.*, u.nickname, u.avatar')
->join('user u', 'u.id = r.user_id')
->where('r.redpacket_id', $redpacketId)
->order('r.createtime ASC')
->select();
//处理createtime 字段
$records = array_map(function ($record) {
$record['createtime'] = date('Y-m-d H:i:s', $record['createtime']);
return $record;
}, $records);
$redpacket['records'] = $records;
// 检查当前用户是否已抢
$redpacket['has_grabbed'] = false;
$redpacket['my_record'] = null;
if ($currentUserId > 0) {
foreach ($records as $record) {
if ($record['user_id'] == $currentUserId) {
$redpacket['has_grabbed'] = true;
$redpacket['my_record'] = $record;
break;
}
}
}
return $redpacket;
}
/**
* 处理过期红包退款
*/
public function processExpiredRedpackets()
{
$now = time();
$redpacketModel = new Redpacket();
// 查找已结束但未退款的红包
$expiredRedpackets = Db::name('redpacket')
->where('status', Redpacket::STATUS_ACTIVE)
->where('end_time', '<', $now)
->where('left_count', '>', 0)
->select();
foreach ($expiredRedpackets as $redpacket) {
Db::startTrans();
try {
// 退款给发红包用户
if ($redpacket['left_amount'] > 0) {
$walletModel = new UserWallet();
$walletModel->increaseBalance(
$redpacket['user_id'],
$redpacket['coin_type'],
$redpacket['left_amount']
);
}
// 更新红包状态
Db::name('redpacket')
->where('id', $redpacket['id'])
->update([
'status' => Redpacket::STATUS_REFUNDED,
'updatetime' => $now
]);
// 清理Redis缓存
$redis = Cache::store('redis')->handler();
$redisKey = "redpacket:{$redpacket['id']}";
$redis->del($redisKey);
Db::commit();
} catch (\Exception $e) {
Db::rollback();
// 记录日志
\think\Log::error("红包退款失败: {$redpacket['id']}, 错误: " . $e->getMessage());
}
}
}
/**
* 验证创建红包数据
*/
private function validateCreateData($data)
{
if (empty($data['user_id'])) {
return ['code' => 0, 'msg' => '用户ID不能为空', 'data' => null];
}
if (empty($data['room_id'])) {
return ['code' => 0, 'msg' => '房间ID不能为空', 'data' => null];
}
if (!in_array($data['type'], [Redpacket::TYPE_NORMAL, Redpacket::TYPE_PASSWORD])) {
return ['code' => 0, 'msg' => '红包类型错误', 'data' => null];
}
if ($data['type'] == Redpacket::TYPE_PASSWORD && empty($data['password'])) {
return ['code' => 0, 'msg' => '口令红包必须设置口令', 'data' => null];
}
if (!in_array($data['coin_type'], [Redpacket::COIN_GOLD, Redpacket::COIN_DIAMOND])) {
return ['code' => 0, 'msg' => '币种类型错误', 'data' => null];
}
if ($data['total_amount'] <= 0 || $data['total_count'] <= 0) {
return ['code' => 0, 'msg' => '金额和数量必须大于0', 'data' => null];
}
if ($data['total_amount'] < $data['total_count']) {
return ['code' => 0, 'msg' => '总金额不能小于总个数', 'data' => null];
}
// 验证领取条件
if (isset($data['conditions'])) {
$res_con = $this->validateConditions($data['conditions']);
if ($res_con !== true) {
return $res_con;
}
}
return ['code' => 1, 'msg' => '验证成功', 'data' => null];
}
/**
* 验证领取条件
*/
private function validateConditions($conditions)
{
if (empty($conditions)) {
return true;
}
//字符串转为数组
$conditions = explode(',', $conditions);
if (in_array(Redpacket::CONDITION_NONE, $conditions) && count($conditions) > 1) {
return V(0, '选择"无"条件时不能选择其他条件');
}
return true;
}
/**
* 检查用户是否满足领取条件
*/
private function checkConditions($redpacket, $userId)
{
$conditions = $redpacket['conditions'] ?: [];
if (empty($conditions)) {
return true;
}
if (in_array(Redpacket::CONDITION_NONE, $conditions)) {
return true;
}
foreach ($conditions as $condition) {
switch ($condition) {
case Redpacket::CONDITION_COLLECT_ROOM:
// 检查用户是否收藏了房间
if (!$this->checkUserCollectedRoom($userId)) {
throw new \Exception('不满足收藏房间条件');
}
break;
case Redpacket::CONDITION_MIC_USER:
// 检查用户是否在麦位上
if (!$this->checkUserOnMic($userId)) {
throw new \Exception('不满足麦位用户条件');
}
break;
}
}
return true;
}
/**
* 检查用户是否收藏了房间(需要根据实际业务实现)
*/
private function checkUserCollectedRoom($userId,$roomId)
{
$collect = Db::name('user_follow')->where(['user_id' => $userId,'type' => 2,'follow_id' => $roomId])->find();
if (!$collect) {
return false;
}
return true;
}
/**
* 检查用户是否在麦位上(需要根据实际业务实现)
*/
private function checkUserOnMic($userId,$roomId)
{
$room_type = Db::name('vs_room')->where('id',$roomId)->field('type_id,label_id')->find();
//实际麦位
if($room_type['type_id'] == 1 || $room_type['type_id'] == 7 || $room_type['type_id'] == 8){
$onPit = Db::name('vs_room_pit')->where(['user_id' => $userId,'room_id' => $roomId])->value('pit_number');
if ($onPit <= 0){
return false;
}
}elseif($room_type['type_id'] ==2){//拍卖
//获取房间的当前拍卖ID
$auctionId = Db::name('vs_room_auction')->where(['room_id' => $roomId,'status' => 2])->value('auction_id');
$onPit = [];
if($auctionId){
$onPits = model('api/RoomAuction')->room_auction_list_on($auctionId);
//提取数组里面的user_id的值 来判断用户是否在里面
$onPit = array_column($onPits,'user_id');
//拍卖位 从缓存中取 Cache::get('auction_user_'.$room_id)
$onpitNumber_10 = Cache::get('auction_user_'.$roomId);
if($onpitNumber_10){
$onPit[] = $onpitNumber_10;
}
}
$onpitNumber_9 = Db::name('vs_room_pit')->where(['pit_number' => 9,'room_id' => $roomId])->value('user_id');
if($onpitNumber_9){
$onPit[] = $onpitNumber_9;
}
if (!in_array($userId,$onPit)){
return false;
}
}
return true;
}
/**
* 检查并更新红包状态
* 在抢红包前调用,确保状态正确
*/
public function checkAndUpdateRedpacketStatus($redpacketId)
{
$redpacket = Db::name('redpacket')->where('id', $redpacketId)->find();
if (!$redpacket) {
return false;
}
$now = time();
$redis = Cache::store('redis')->handler();
$redpacketKey = "redpacket:{$redpacketId}";
// 如果红包状态为未开始(0),但当前时间已超过开始时间,则更新为进行中(1)
if ($redpacket['status'] == Redpacket::STATUS_PENDING && $now >= $redpacket['start_time']) {
Db::name('redpacket')
->where('id', $redpacketId)
->update([
'status' => Redpacket::STATUS_ACTIVE,
'updatetime' => $now
]);
// 更新Redis中的状态
$redis->hSet($redpacketKey, 'status', Redpacket::STATUS_ACTIVE);
return true;
}
// 如果红包状态为进行中(1),但已抢完,则更新为已结束(2)
if ($redpacket['status'] == Redpacket::STATUS_ACTIVE && $redpacket['left_count'] <= 0) {
Db::name('redpacket')
->where('id', $redpacketId)
->update([
'status' => Redpacket::STATUS_FINISHED,
'updatetime' => $now
]);
// 更新Redis中的状态
$redis->hSet($redpacketKey, 'status', Redpacket::STATUS_FINISHED);
return true;
}
// 如果红包状态为进行中(1),但已超过结束时间,则更新为已结束(2)
if ($redpacket['status'] == Redpacket::STATUS_ACTIVE && $now > $redpacket['end_time']) {
Db::name('redpacket')
->where('id', $redpacketId)
->update([
'status' => Redpacket::STATUS_FINISHED,
'updatetime' => $now
]);
// 更新Redis中的状态
$redis->hSet($redpacketKey, 'status', Redpacket::STATUS_FINISHED);
return true;
}
return false;
}
}

View File

@@ -0,0 +1,56 @@
<?php
namespace app\cron\controller;
use think\Db;
class FriendEnd
{
/*
* 运行函数
*/
function index()
{
echo "清除交友房过期未结束数据开始:\n";
$this->clearFriendingEndRoom();//清除交友房过期未结束数据
echo "清除结束 \n";
echo "清除私密小屋过期数据开始:\n";
$this->clear_room_end();//清除私密小屋过期数据
echo "清除私密小屋过期数据结束 \n";
}
//清除交友房过期未结束数据
public function clearFriendingEndRoom()
{
//清除交友房过期数据
$room_list = db::name('vs_room')->where(['type_id'=>7])->whereIn('step', [2,3])
->field(['id','step'])->select();
if(!empty($room_list)){
foreach ($room_list as $room) {
//查询交友信息
$friending_info = db::name('vs_user_friending')->where('room_id', $room['id'])->where('status', 1)->order('id', 'desc')->find();
if($friending_info){
//判断结束时间是否到期
if($friending_info['end_time'] <= time() || $room['step'] == 3){
model('Friend')->end_friend(0,$room['id'],$friending_info['id'],1);
}
}
}
}
}
//清除私密小屋过期数据
public function clear_room_end()
{
$room_list = db::name('vs_room_cp_movie')->where(['status' => 1,'type'=>1,'time_day' =>['<',time()]])->select();
if(!empty($room_list)){
foreach ($room_list as $room) {
model('Friend')->outRoom(0,$room['room_id']);
}
}
}
}

View File

@@ -0,0 +1,405 @@
<?php
namespace app\cron\controller;
use app\common\controller\Push;
use think\Db;
use think\Log;
class RoomHourRanking
{
/*
* 运行函数
*/
function index()
{
echo "小时榜 开始发礼物:\n";
$this->send_gift();//小时榜 送礼物
echo "发礼物结束 \n";
}
public function send_gift()
{
//获取上一个小时的开始时间和结束时间
$start_time = strtotime(date('Y-m-d H:00:00', strtotime('-1 hour')));
$end_time = strtotime(date('Y-m-d H:00:00'));
echo "开始时间:" .$start_time."\n";
echo "结束时间:" .$end_time."\n";
//当前小时的前一个小时24小时计时法0-23
$pre_hour = date('H', strtotime('-1 hour'));
echo "上个时间段:" .$pre_hour."\n";
$is_open_time = db::name('vs_hour_ranking_config')->where('id', 1)->value('open_time');
if ($is_open_time == 0) {
echo "未开启时间段:" .$is_open_time."\n";
return;
}
//是否全局飘瓶
$is_public_server = db::name('vs_hour_ranking_config')->where('id', 1)->value('is_public_server');
if ($is_public_server == 1) {
//全局飘瓶时间段
$xlh_time_range = db::name('vs_hour_ranking_config')->where('id', 1)->value('broadcast_times');
if($xlh_time_range){
if($xlh_time_range == 25){
$is_piao = 1;
}else{
//当前的前一个小时是否在 $xlh_time_range中
if (in_array($pre_hour, explode(',', $xlh_time_range))) {
$is_piao = 1;
} else {
$is_piao = 0;
}
}
}else{
$is_piao = 0;
}
}else{
$is_piao = 0;
}
//获取上一个时间段的配置
// $gift_list = db::name('vs_hour_ranking_gift_config')->where('time_id',$pre_hour)->group('ranking')->order('id', 'desc')->select();
$gift_list = $this->get_hour_ranking($pre_hour);
// echo "上个时间段的配置:" .json_encode($gift_list)."\n";
// 提取所有有奖励的内容
$allRewards = $this->extractAllRewards($gift_list);
// 按index分组
$groupedRewards = $this->groupRewardsByIndex($allRewards);
// 按名次顺序分配奖励
$distributionResult = $this->distributeByRank($groupedRewards);
//获取上个数组的个数,从而获取配置了多少个名次
$count = count($distributionResult);
echo "上个时间段的配置总数:" .$count."\n";
//获取前一个小时的 前$count名房间排行
$room_list = model('api/RoomHourRanking')->room_hour_ranking(1, $count, $start_time, $end_time);
$room_owner = [];
if ($room_list['code'] == 1) {
//获取房间排行奖励最低值
$min_price = db::name('vs_hour_ranking_config')->where('id', 1)->value('min_price');
if ($room_list['data']['lists']) {
echo "房间列表:" .json_encode($room_list['data']['lists'])."\n";
foreach ($room_list['data']['lists'] as $v){
if ($v['total_price'] >= $min_price) {
$room_owner[] = [
'user_id' => $v['user_id'],
'room_name' => $v['room_name'],
'room_id' => $v['room_id'],
'total_price' => $v['total_price']
];
}
}
}
}
if ($distributionResult && $room_owner) {
$text_list_new = [];
echo "礼物数:" .json_encode($distributionResult)."\n";
echo "房主:" .json_encode($room_owner)."\n";
foreach ($distributionResult as $k => $value) {
//礼物全部给他偷偷放在装扮表及金额 中
//有几个用户就发几个
if(count($room_owner) > $k){
// 为每个房间添加一个标志,表示是否已处理推送信息
$hasProcessedPush = false;
foreach ($value['rewards'] as $v){
if($v['type'] == 0){//1金币2礼物3头像4坐骑
echo "发金币:" .$v['value'].'==>'.$room_owner[$k]['user_id']."\n";
$res = $this->add_coin($v['value'], $room_owner[$k]['user_id'],$k + 1,$room_owner[$k]['room_id'],$room_owner[$k]['total_price'],$is_piao);
}elseif ($v['type'] == 1){
echo "发礼物:" .$v['value'].'==>'.$room_owner[$k]['user_id']."\n";
$res = $this->add_gift($v['value'], $room_owner[$k]['user_id'],$k + 1,$room_owner[$k]['room_id'],$room_owner[$k]['total_price'],$is_piao);
}elseif ($v['type'] == 2){
$res = $this->add_decorate($v['value'], $room_owner[$k]['user_id'],$k + 1,$room_owner[$k]['room_id'],$room_owner[$k]['total_price'],$is_piao,3);
}elseif ($v['type'] == 3){
$res = $this->add_decorate($v['value'], $room_owner[$k]['user_id'],$k + 1,$room_owner[$k]['room_id'],$room_owner[$k]['total_price'],$is_piao,4);
}
// 只有在第一次处理奖励时添加推送信息,避免重复推送
if(!$hasProcessedPush && $is_piao == 1) {
$room_name = $room_owner[$k]['room_name'];
//推送礼物横幅
if ($k == 0) {
$text = '新科状元!【' . $room_name . '】独占鳌头!';
} elseif ($k == 1) {
$text = '金榜榜眼!【' . $room_name . '】才气逼人!';
} elseif ($k == 2) {
$text = '风采探花!【' . $room_name . '】实力绽放!';
}
$text_list_new[] = [
'text' => $text ?? '恭喜【' . $room_name . '】获得礼物!',
'room_id' => $room_owner[$k]['room_id'],
'room_name' => $room_name,
'rank_number' => $k + 1,
];
$hasProcessedPush = true; // 标记已处理推送
}
}
}
}
if(!empty($text_list_new)){
$push = new Push();
$push->hourRanking($text_list_new);
}
}
echo "送礼-共" . count($room_owner) . "个房间房主获益\n";
}
//添加金币到钱包
public function add_coin($coin,$user_id,$ranking,$room_id,$total_price,$is_piao){
if($coin > 0){
$data = [
'user_id' => $user_id,
'change_value' => $coin,
// 'room_id' => $room_ids,
'money_type' => 1,
'change_type' => 27,
'from_id' => 0,
'remarks' => '小时榜获得',
'createtime' => time()
];
//开启事务
Db::startTrans();
$res = Db::name('vs_user_money_log')->insert($data);
if(!$res){
Db::rollback();
}
//增加用户金币
$res1 = Db::name('user_wallet')->where(['user_id'=>$user_id])->setInc('coin',$coin);
if(!$res1){
Db::rollback();
}
//添加到排行表
$start_time = strtotime(date('Y-m-d H:00:00', strtotime('-1 hour')));
$end_time = strtotime(date('Y-m-d H:00:00')) - 1;
$res2 = db::name('vs_hour_ranking')->insert([
'ranking' => $ranking,
'room_id' => $room_id,
'flowing_water' => $total_price,
'coin' => $coin,
'time_id' => date('H', strtotime('-1 hour')),
'stime' => $start_time,
'etime' => $end_time,
'createtime' => time(),
'updatetime' => time(),
'is_public_server' => $is_piao
]);
if(!$res2){
Db::rollback();
}
Db::commit();
}
return true;
}
//添加礼物到背包
public function add_gift($gift_id,$user_id,$ranking,$room_id,$total_price,$is_piao){
$res = model('api/UserGiftPack')->change_user_gift_pack($user_id,$gift_id,1,model('UserGiftPack')::HOUR_RANK_GET,"小时榜获得");
if($res['code'] == 0){
Log::record("小时榜获取礼物失败:".$res['msg'],"info");
}
//添加到排行表
$start_time = strtotime(date('Y-m-d H:00:00', strtotime('-1 hour')));
$end_time = strtotime(date('Y-m-d H:00:00')) - 1;
$res2 = db::name('vs_hour_ranking')->insert([
'ranking' => $ranking,
'room_id' => $room_id,
'flowing_water' => $total_price,
'gift_id' => $gift_id,
'gift_type' => 2,
'time_id' => date('H', strtotime('-1 hour')),
'stime' => $start_time,
'etime' => $end_time,
'createtime' => time(),
'updatetime' => time(),
'is_public_server' => $is_piao
]);
if(!$res2){
Log::record("小时榜礼物锁定失败","info");
}
return true;
}
//添加装扮到背包
public function add_decorate($avatar_id,$user_id,$ranking,$room_id,$total_price,$is_piao,$type){
$decorate_price_info = db::name('vs_decorate_price')->where(['id'=>$avatar_id])->find();
if(empty($decorate_price_info)){
Log::record("小时榜获取装扮失败:没有找到装扮!".$avatar_id,"info");
}
$res = model('api/Decorate')->pay_decorate($user_id,$decorate_price_info['did'],$decorate_price_info['day'],2);
if($res['code'] == 0){
Log::record("小时榜获取装扮失败:".$res['msg']."-".$avatar_id,"info");
}
//添加到排行表
$start_time = strtotime(date('Y-m-d H:00:00', strtotime('-1 hour')));
$end_time = strtotime(date('Y-m-d H:00:00')) - 1;
$res2 = db::name('vs_hour_ranking')->insert([
'ranking' => $ranking,
'room_id' => $room_id,
'flowing_water' => $total_price,
'gift_id' => $avatar_id,
'gift_type' => $type,
'time_id' => date('H', strtotime('-1 hour')),
'stime' => $start_time,
'etime' => $end_time,
'createtime' => time(),
'updatetime' => time(),
'is_public_server' => $is_piao,
]);
if(!$res2){
Log::record("小时榜咋装扮锁定失败","info");
}
return true;
}
/**
* 提取所有有奖励的内容
*/
private function extractAllRewards($responseData)
{
$allRewards = [];
foreach ($responseData as $timeSlot) {
foreach ($timeSlot['reward'] as $rewardItem) {
$index = $rewardItem['index'];
$content = $rewardItem['content'];
// 只处理有奖励内容的数据
if (!empty($content)) {
foreach ($content as $rewardContent) {
$allRewards[] = [
'index' => $index,
'type' => $rewardContent['type'],
'value' => $rewardContent['value'],
'name' => $rewardContent['name'] ?? ''
];
}
}
}
}
return $allRewards;
}
/**
* 按index分组奖励
*/
private function groupRewardsByIndex($allRewards)
{
$grouped = [];
foreach ($allRewards as $reward) {
$index = $reward['index'];
if (!isset($grouped[$index])) {
$grouped[$index] = [];
}
$grouped[$index][] = $reward;
}
// 按index排序
ksort($grouped);
return $grouped;
}
/**
* 按名次顺序分配奖励
*/
private function distributeByRank($groupedRewards)
{
$distribution = [];
$currentRank = 0; // 从第1名开始
// 按index顺序分配index 0 = 第1名index 1 = 第2名以此类推
foreach ($groupedRewards as $index => $rewards) {
// 确保名次连续,如果有空缺则填充空名次
while ($currentRank < $index) {
$distribution[] = [
'rank' => $currentRank + 1,
'rewards' => []
];
$currentRank++;
}
// 分配当前名次的奖励
$distribution[] = [
'rank' => $currentRank + 1,
'rewards' => $rewards
];
$currentRank++;
}
return $distribution;
}
public function get_hour_ranking($time){
// 先按时间段和排名索引分组查询
$timeRanges = db::name('vs_hour_ranking_gift_config')->distinct(true)
->where('time_id', '=', $time)
->order('time_id')
->column('time_id');
$result = [];
foreach ($timeRanges as $timeRange) {
// 查询该时间段的所有数据
$rewards = db::name('vs_hour_ranking_gift_config')->where('time_id', $timeRange)
->field('ranking, gift_type, gift_id,coin,name')
->order('ranking')
->select();
$rewardMap = [];
foreach ($rewards as $reward) {
$rankIndex = $reward['ranking'];
if (!isset($rewardMap[$rankIndex])) {
$rewardMap[$rankIndex] = [
'index' => $rankIndex,
// 'name' => $reward['rank_name'],
'content' => []
];
}
// 添加奖励内容到content数组
if ($reward['gift_id'] != 0 || $reward['coin'] != 0) {
if($reward['gift_id'] != 0){
$rewardMap[$rankIndex]['content'][] = [
'type' => $reward['gift_type'],
'value' => $reward['gift_id'],
// 'coin' => $reward['coin'],
'name' => $reward['name'],
];
}
if($reward['coin'] != 0){
$rewardMap[$rankIndex]['content'][] = [
'type' => $reward['gift_type'],
'value' => $reward['coin'],
'name' => $reward['name'],
];
}
}
}
// 按index排序
ksort($rewardMap);
$result[] = [
'time' => $timeRange,
'reward' => array_values($rewardMap)
];
}
return $result;
}
}

View File

@@ -0,0 +1,195 @@
<?php
namespace app\cron\controller;
use app\common\controller\Push;
use think\Cache;
use think\Db;
/*
* 定时任务,每秒执行的方法
*/
class RoomPan
{
/*
* 运行函数
*/
function index()
{
echo "巡乐会礼物发放开始:\n";
$this->xlh_gift_send();//拍卖房结束提醒
echo "礼物发放结束 \n";
echo "盲盒转盘礼物补发:\n";
$this->blind_box_turntable_gift_send();//盲盒转盘礼物补发
echo "盲盒转盘礼物补发结束 \n";
}
/*
* 盲盒转盘礼物推送补发
*/
public function blind_box_turntable_gift_send(){
$blind_box_turntable = db('vs_blind_box_turntable_log')->where(['is_sued'=>0,'createtime'=>['>=',time()-60*30]])->limit(1000)->select();
if(empty($blind_box_turntable)){
echo "没有需要发放的礼物 \n";
}
echo "开始发放".count($blind_box_turntable)." \n";
foreach ($blind_box_turntable as $k => $v) {
$blind_box_turntable_results_log = db('vs_blind_box_turntable_results_log')->where('tid',$v['id'])->select();
if(empty($blind_box_turntable_results_log)){
echo $v['id']." 没有需要发放的礼物 \n";
continue;
}
$room_id = $v['room_id'];
$room_name = Db::name('vs_room')->where(['id' => $room_id, 'apply_status' => 2])->value('room_name');
$FromUserInfo = Db::name('user')->where(['id'=>$v['user_id']])->find();
$FromUserInfo['user_id'] = $FromUserInfo['id'];
$FromUserInfo['icon'][0] = model('UserData')->user_wealth_icon($v['user_id']);//财富图标
$FromUserInfo['icon'][1] = model('UserData')->user_charm_icon($v['user_id']);//魅力图标
$user_nickname = $FromUserInfo['nickname'];
$textMessage = $user_nickname;
$text_message = $user_nickname;
foreach ($blind_box_turntable_results_log as $key => $value) {
$ToUserInfo = Db::name('user')->where(['id' => $value['gift_user_id']])->field('id as user_id,nickname,avatar,sex')->find();
$draw_gift = Db::name('vs_gift')->where(['gid'=>$value['gift_id']])->find();
$textMessage = $textMessage . ' 送给 ' . $ToUserInfo['nickname']. ' 盲盒转盘礼物 ' . $draw_gift['gift_name'].' x ' .$value['count']."\n";
$play_image[] = $draw_gift['play_image'];
$gift_names[] = $draw_gift['gift_name'];
$text_message = $text_message . '在' . $room_name . '房间送给了' . $ToUserInfo['nickname'] . $draw_gift['gift_name'] . 'X' . $value['count']."\n";
if($draw_gift['is_public_server'] == 1) {
$text_list_new[] = [
'text' => $text_message,
'gift_picture' => $draw_gift['base_image'],
'room_id' => $room_id,
'fromUserName' => $FromUserInfo['nickname'],
'toUserName' => $ToUserInfo['nickname'],
'giftName' => $draw_gift['gift_name'],
'roomId' => $room_id,
'number' => $value['count'],
];
}
$ToUserInfosList[$value['gift_user_id']] = $ToUserInfo;
}
foreach($ToUserInfosList as &$userInfo) {
$userInfo['icon'][0] = model('UserData')->user_wealth_icon($userInfo['user_id']);//财富图标
$userInfo['icon'][1] = model('UserData')->user_charm_icon($userInfo['user_id']);//魅力图标
$userInfo['charm'] = db::name('vs_room_user_charm')->where(['user_id' => $userInfo['user_id'],'room_id' => $room_id])->value('charm');//魅力
$ToUserInfos[] = $userInfo;
}
$text = [
'FromUserInfo' => $FromUserInfo,
'ToUserInfos' => $ToUserInfos,
'GiftInfo' => [
'play_image' => implode(',',$play_image),
'gift_name' => implode(',',$gift_names),
],
'text' => rtrim($textMessage, "\n")
];
//聊天室推送系统消息
model('Chat')->sendMsg(1005,$room_id,$text);
$roomtype = Db::name('vs_room')->where(['id' => $room_id])->value('type_id');
if($roomtype == 6){
//推送消息
$hot_value = db::name('vs_give_gift')->where('from_id', $room_id)->where('from',6)
->sum('total_price');
$text1 = [
'room_id' => $room_id,
'hot_value' => $hot_value * 10,
'text' => '房间心动值变化'
];
//聊天室推送系统消息
model('Chat')->sendMsg(1028,$room_id,$text1);
}else{
if(!empty($text_list_new)){
//推送礼物横幅
$push = new Push($v['user_id'], $room_id);
$push->giftBanner($text_list_new);
}
}
db::name('vs_blind_box_turntable_log')->where('id', $v['id'])->update(['is_sued' => 1, 'updatetime' => time()]);
}
}
/*
* 巡乐会结束 礼物发放 【定时脚本】
*/
public function xlh_gift_send(){
$xlh_list = db::name('vs_room_pan_xlh')->where(['send_time'=>0,'end_time'=>['<=',time()]])->select();
if(empty($xlh_list)){
echo "没有需要发放的礼物 \n";
}
foreach ($xlh_list as $key=>$value){
try{
if($value['user_id'] == 0){
echo "第.".$value['periods']." 巡乐会结束 没有中奖用户 \n";
$res = db::name('vs_room_pan_xlh')->where('id',$value['id'])->update([
'send_time' => time()
]);
// db::name("vs_room")->where('id',$value['room_id'])->update([
// 'xlh_periods_num' => 0
// ]);
Cache::set("xlh_periods_num", 0, 0);
//推送礼物横幅
$text = "本轮巡乐会已结束,请大家重新开始下一轮巡乐会";
$push = new Push(0, $value['room_id']);
$text_list_new = [
'text' => $text,
'room_id' => $value['room_id'],
'from_type' => 104
];
$push->xunlehui($text_list_new);
continue;
}
//发放
//抽中礼物落包
$res = [];
$res = model('api/UserGiftPack')->change_user_gift_pack($value['user_id'],$value['gift_id'],$value['num'],model('UserGiftPack')::XLH_DRAW_GIFT_GET,"巡乐会中奖发放");
if ($res['code'] != 1) {
echo $res['msg']."\n";
continue;
}
echo "巡乐会中奖礼物发放成功 用户Id".$value['user_id']."\n";
//房主礼物落包
$res = [];
//获取房主id
$user_id = db::name('vs_room')->where(['id'=>$value['room_id']])->value('user_id');
$res = model('api/UserGiftPack')->change_user_gift_pack($user_id,$value['homeowner_gift_id'],1,model('UserGiftPack')::XLH_DRAW_GIFT_GET,"巡乐会中奖后房主礼物发放");
if ($res['code'] != 1) {
echo $res['msg']."\n";
continue;
}
echo "巡乐会中奖后房主礼物发放成功 房主Id".$user_id."\n";
//处理发放记录
$res = [];
$res = db::name('vs_room_pan_xlh')->where('id',$value['id'])->update([
'send_time' => time()
]);
$xlh_log = db::name('vs_room_pan_xlh_log')->where(['xlh_id'=>$value['id'],'user_id'=>$value['user_id']])->order('id desc')->find();
$res = db::name('vs_room_pan_xlh_log')->where('id',$xlh_log['id'])->update([
'is_send' => 1
]);
if ($res === false) {
echo "处理发放记录失败 \n";
continue;
}
Cache::set("xlh_periods_num", 0, 0);
//推送
$FromUserInfo = db::name('user')->field('nickname,avatar')->where(['id'=>$value['user_id']])->find();
$gift_name = db::name('vs_gift')->where(['gid'=>$value['gift_id']])->value('gift_name');
$text = $FromUserInfo['nickname'] . ' 用户在巡乐会中 ' .$gift_name.'礼物 x ' .$value['num']." 已收入背包";
//推送礼物横幅
$push = new Push(0, $value['room_id']);
$text_list_new = [
'text' => $text,
'room_id' => $value['room_id'],
'from_type' => 104
];
$push->xunlehui($text_list_new);
}catch (\Exception $e){
echo $e->getMessage()."\n";
}
}
}
}

View File

@@ -0,0 +1,158 @@
<?php
namespace app\cron\controller;
use think\Db;
use Yzh\YunPay;
/*
* 定时任务,每秒执行的方法
*/
class Test
{
/*
* 运行函数
*/
function index()
{
// 设置脚本执行时间无限
set_time_limit(0);
echo "统计盲盒转盘错误数据\n";
$this->blind_box_error();
echo "\n";
}
//统计盲盒转盘错误数据
public function blind_box_error()
{
die("暂停");
// 设置数据库查询超时时间
Db::query("SET SESSION wait_timeout=600");
Db::query("SET SESSION interactive_timeout=600");
// 使用连表查询,直接找出送给多人的数据
echo "开始查询送给多人的数据...\n";
// 先查询所有有多个不同 gift_user_id 的 tid
$multipleGiftRecords = Db::name('vs_blind_box_turntable_results_log')
->group('tid')
->having('COUNT(DISTINCT gift_user_id) > 1')
->field('tid, COUNT(DISTINCT gift_user_id) as user_count,gift_user_id')
->select();
echo "找到 " . count($multipleGiftRecords) . " 条送给多人的记录\n";
// 输出详细信息
foreach ($multipleGiftRecords as $record) {
echo "转盘ID: {$record['tid']}, 接收人数: {$record['user_count']}\n";
// 获取该转盘的详细信息
$turntableInfo = Db::name('vs_blind_box_turntable_log')
->where('id', $record['tid'])
->find();
if ($turntableInfo) {
echo " 开奖用户ID: {$turntableInfo['user_id']}, 礼包ID: {$turntableInfo['gift_bag_id']}\n";
}
}
echo "统计盲盒转盘错误数据完成\n";
}
//统计盲盒转盘错误数据
public function blind_box_error1()
{
die("暂停");
// 设置数据库查询超时时间
Db::query("SET SESSION wait_timeout=600");
Db::query("SET SESSION interactive_timeout=600");
// 分批处理数据,避免一次性加载大量数据到内存
$batchSize = 1000;
$offset = 0;
$data_multiple = [];
$totalProcessed = 0;
do {
// 分批获取数据
$turntable_log = Db::name('vs_blind_box_turntable_log')
->limit($offset, $batchSize)
->select();
// 如果没有更多数据,退出循环
if (empty($turntable_log)) {
break;
}
foreach ($turntable_log as $key => $value) {
//查询本轮是否有多个接收礼物的人
$turntable_results_log = Db::name('vs_blind_box_turntable_results_log')
->where('tid', $value['id'])
->group('gift_user_id')
->select();
// 统计送给多人的数据
if (count($turntable_results_log) > 1) {
$data_multiple[] = [
'turntable_id' => $value['id'],
'recipient_count' => count($turntable_results_log),
'data' => $value
];
}
$totalProcessed++;
// 每处理100条记录输出一次进度
if ($totalProcessed % 100 == 0) {
echo "已处理 {$totalProcessed} 条记录...\n";
// 每100条记录后清理内存
gc_collect_cycles();
}
}
// 更新偏移量
$offset += $batchSize;
// 释放内存
unset($turntable_log);
unset($turntable_results_log);
} while ($totalProcessed <= 1400);
echo "送给多人的数据共 " . count($data_multiple) . " 条记录\n";
echo "统计盲盒转盘错误数据完成-共处理 " . $totalProcessed . " 条数据\n";
// 输出详细信息
foreach ($data_multiple as $item) {
echo "转盘ID: {$item['turntable_id']}, 接收人数: {$item['recipient_count']}\n";
}
}
public function RoomOwners()
{
$room = Db::name('vs_room')->where(['room_status' => 1,'apply_status' => 2])->select();
$arr = [];
foreach ($room as $key => $value) {
$liushui = Db::name('vs_give_gift')->where(['from_id' => $value['id'],'from' => 2])->sum('total_price');
$usercode = Db::name('user')->where(['id' => $value['user_id']])->value('user_code');
$nickname = Db::name('user')->where(['id' => $value['user_id']])->value('nickname');
$arr[] = [
'room_id' => $value['id'],
'user_id' => $value['user_id'],
'user_code' => $usercode,
'nickname' => $nickname,
'liushui' => $liushui
];
}
//房主的收益
foreach ($arr as $key => $v){
$shouyi = db::name('vs_user_money_log')->where(['user_id' => $v['user_id'],'change_type' => 18,'money_type' =>2,'createtime'=>['<',1759585380]])->sum('change_value');
$arr[$key]['shouyi'] = $shouyi;
$arr[$key]['duibi'] = $shouyi.'-'.$v['liushui']/10/10;
$arr[$key]['chazhi'] = $v['liushui']/10/10 - $shouyi;
}
var_dump($arr);
}
}

View File

@@ -0,0 +1,12 @@
<?php
return [
'host' => '127.0.0.1',
'port' => 6379,
'password' => '',
'select' => 0,
'timeout' => 0,
'expire' => 0,
'persistent' => false,
'prefix' => 'fa_redpacket_',
];