diff --git a/application/adminapi/controller/Guild.php b/application/adminapi/controller/Guild.php index 85f7f44..41a0d74 100644 --- a/application/adminapi/controller/Guild.php +++ b/application/adminapi/controller/Guild.php @@ -379,8 +379,8 @@ class Guild extends adminApi $page = input('page', 1); $page_limit = input('page_limit', 30); $guild_id = input('guild_id', 0); - $search_stime = input('search_stime',''); - $search_etime = input('search_etime',''); + $search_stime_str = input('search_stime',''); + $search_etime_str = input('search_etime',''); $room_id = input('room_id', 0); $where=['a.status'=>1]; $where=['a.room_id'=>['>',0]]; @@ -399,23 +399,37 @@ class Guild extends adminApi ->where(['a.guild_id'=>$guild_id])->where($where)->count(); $list = db::name($this->table_guild_user)->alias('a') ->join('vs_room b', 'a.room_id = b.id', 'left') - ->where(['a.guild_id'=>$guild_id])->where($where)->page($page, $page_limit)->select(); + ->where(['a.guild_id'=>$guild_id])->where($where) +// ->page($page, $page_limit) + ->select(); if(!$list){ return V(0,"暂无数据"); } $rum_lists = []; foreach ($list as $k=>$v){ - if($search_stime!="" && $v['createtime'] < strtotime($search_stime)){ - $search_stime = $search_stime; - }else{ - $search_stime = date('Y-m-d H:i:s',$v['createtime']) ; - } - if($v['quit_time']){ - if($search_etime!="" && $v['quit_time'] > strtotime($search_etime)){ - $search_etime = $search_etime; + $search_stime = $search_stime_str; + $search_etime = $search_etime_str; + if($search_stime!=""){ + if($search_stime!="" && $v['createtime'] < strtotime($search_stime)){ + $search_stime = $search_stime; }else{ - $search_etime = date('Y-m-d H:i:s',$v['quit_time']); + $search_stime = date('Y-m-d H:i:s',$v['createtime']) ; } + }else{ + $search_stime = $search_stime; + } + if($search_etime!=""){ + if($v['quit_time']){ + if($search_etime!="" && $v['quit_time'] > strtotime($search_etime)){ + $search_etime = $search_etime; + }else{ + $search_etime = date('Y-m-d H:i:s',$v['quit_time']); + } + }else{ + $search_etime = $search_etime; + } + }else{ + $search_etime = $search_etime; } $room_info = db::name('vs_room')->where(['id'=>$v['room_id']])->find(); @@ -428,6 +442,11 @@ class Guild extends adminApi $rum_lists[$k]['consumption']= model('Room')->getRoomFlow($v['room_id'],$search_stime,$search_etime); $rum_lists[$k]['add_time'] = date('Y-m-d H:i:s',$v['createtime']); } + usort($rum_lists, function($a, $b) { + return $b['consumption'] - $a['consumption']; + }); + //分页 + $rum_lists = array_slice($rum_lists, ($page-1)*$page_limit, $page_limit); $return_data = [ 'page' =>$page, 'page_limit' => $page_limit, @@ -661,7 +680,7 @@ class Guild extends adminApi $lists_data = db::name($this->table_guild_subsidy)->alias('a') ->join('vs_guild b','a.guild_id = b.id') ->where($where) - ->order('a.id desc') + ->order('a.total_transaction desc') ->field('a.*,b.guild_name,b.user_id,b.guild_special_id') ->page($page,$page_limit) ->select(); diff --git a/application/adminapi/controller/User.php b/application/adminapi/controller/User.php index 91b80ff..793d7fe 100644 --- a/application/adminapi/controller/User.php +++ b/application/adminapi/controller/User.php @@ -436,7 +436,15 @@ class User extends adminApi $page = input('page',1); $page_limit = input('page_limit',10); $type = input('type',''); - $return = model('UserWallet')->money_change_log($user_id,$type,$page,$page_limit); + $stime = input('stime',''); + $etime = input('etime',''); + $change_type = input('change_type',''); + $seach = [ + 'stime' => $stime, + 'etime' => $etime, + 'change_type' => $change_type + ]; + $return = model('UserWallet')->money_change_log($user_id,$seach,$type,$page,$page_limit); $list = []; foreach($return['list'] as $k=>$v){ $list[$k] = [ @@ -456,6 +464,14 @@ class User extends adminApi return V(1,"操作成功", $return_data); } + /* + * 获取用户资金类型 + */ + public function get_money_type(){ + $reslut = model('UserWallet')->getChangeTypeLableList(); + return V(1,"操作成功", $reslut); + } + /* * 相册列表 */ diff --git a/application/api/model/BlindBoxTurntableGiftDrawWorld.php b/application/api/model/BlindBoxTurntableGiftDrawWorld.php index 87c42c2..b205a7f 100644 --- a/application/api/model/BlindBoxTurntableGiftDrawWorld.php +++ b/application/api/model/BlindBoxTurntableGiftDrawWorld.php @@ -37,98 +37,116 @@ class BlindBoxTurntableGiftDrawWorld extends Model public function draw_gift($gift_bag_id, $user_id, $gift_user_ids, $num = 1, $room_id = 0, $heart_id = 0,$auction_id = 0) { // 最大重试次数 - $maxRetries = 3; - for ($attempt = 0; $attempt < $maxRetries; $attempt++) { - try { - // 1. 验证参数并提前处理错误 - $validationResult = $this->validateDrawParameters($gift_bag_id, $user_id, $gift_user_ids); - if ($validationResult !== true) { - return $validationResult; - } - // 2. 预加载必要数据 - $loadResult = $this->loadDrawData($gift_bag_id, $user_id, $room_id, $num, $gift_user_ids); - if ($loadResult['code'] !== 1) { - return $loadResult; - } - // 添加以下检查以防止 null 错误 - if (!isset($loadResult['data']) || !is_array($loadResult['data'])) { - return ['code' => 0, 'msg' => '数据加载失败', 'data' => null]; - } - ['bag_data' => $bag_data, 'room' => $room, 'xlh_ext' => $xlh_ext] = $loadResult['data']; + try { + // 1. 验证参数并提前处理错误 + $validationResult = $this->validateDrawParameters($gift_bag_id, $user_id, $gift_user_ids); + if ($validationResult !== true) { + return $validationResult; + } + // 2. 预加载必要数据 + $loadResult = $this->loadDrawData($gift_bag_id, $user_id, $room_id, $num, $gift_user_ids); + if ($loadResult['code'] !== 1) { + return $loadResult; + } + // 添加以下检查以防止 null 错误 + if (!isset($loadResult['data']) || !is_array($loadResult['data'])) { + return ['code' => 0, 'msg' => '数据加载失败', 'data' => null]; + } + ['bag_data' => $bag_data, 'room' => $room, 'xlh_ext' => $xlh_ext] = $loadResult['data']; - // 3. 预计算抽奖结果 - $precomputeResult = $this->precomputeDrawResults( - $bag_data, - $gift_user_ids, - $num - ); - if ($precomputeResult['code'] !== 1) { - return $precomputeResult; + // 3. 预计算抽奖结果 + $precomputeResult = $this->precomputeDrawResults( + $bag_data, + $gift_user_ids, + $num + ); + if ($precomputeResult['code'] !== 1) { + return $precomputeResult; + } + $precomputedResults = $precomputeResult['data']['results']; + $availableGiftss = $precomputeResult['data']['availableGifts']; + $currentXlhPeriodsNum = $precomputeResult['data']['current_xlh_periods_num']; + $addcurrentXlhPeriodsNum = $precomputeResult['data']['addcurrentXlhPeriodsNum']; + $expectedCount = count(explode(',', $gift_user_ids)) * $num; + if (count($precomputedResults) != $expectedCount) { + // 记录错误到Redis + $this->recordDrawErrorToRedis($expectedCount, count($precomputedResults), $room_id, $user_id, $gift_bag_id, $num, $gift_user_ids, $precomputedResults); + return ['code' => 0, 'msg' => '网络加载失败,请重试!', 'data' => null]; + } + foreach ($precomputedResults as $result) { + $key = $result['gift_user_id'] . '_' . $result['gift_bag_detail']['foreign_id']; + if (!isset($giftUserCountsJianCha[$key])) { + $giftUserCountsJianCha[$key] = [ + 'gift_user_id' => $result['gift_user_id'], + 'gift_id' => $result['gift_bag_detail']['foreign_id'], + 'count' => 0, + 'gift_price' => $result['gift']['gift_price'], + 'quantity' => $result['gift_bag_detail']['quantity'], + ]; } - $precomputedResults = $precomputeResult['data']['results']; - $availableGiftss = $precomputeResult['data']['availableGifts']; - $currentXlhPeriodsNum = $precomputeResult['data']['current_xlh_periods_num']; - $addcurrentXlhPeriodsNum = $precomputeResult['data']['addcurrentXlhPeriodsNum']; - $expectedCount = count(explode(',', $gift_user_ids)) * $num; - if (count($precomputedResults) != $expectedCount) { + $giftUserCountsJianCha[$key]['count']++; + if($giftUserCountsJianCha[$key]['count'] > $result['gift_bag_detail']['quantity']){ // 记录错误到Redis - $this->recordDrawErrorToRedis($expectedCount, count($precomputedResults), $room_id, $user_id, $gift_bag_id, $num, $gift_user_ids, $precomputedResults); + // 使用正确的Redis方法存储数据 + $key = 'blind_box_draw_world_errors_' . date('Y-m-d-H-i-s'); + $errorData = [ + 'gift_bag_id' => $gift_bag_id, + 'user_id' => $user_id, + 'gift_user_ids' => $gift_user_ids, + 'num' => $num, + 'giftUserCountsJianCha' => $giftUserCountsJianCha, + ]; + $this->redis->setex($key, 86400 * 7, "礼物数量超出限制 ".json_encode($errorData)); return ['code' => 0, 'msg' => '网络加载失败,请重试!', 'data' => null]; } - // 4. 执行抽奖事务(核心操作) - $transactionResult = $this->executeDrawTransaction( - $bag_data, - $user_id, - $room_id, - $num, - $precomputedResults, - $availableGiftss, - $gift_user_ids, - $heart_id, - $auction_id - ); - if ($transactionResult['code'] !== 1) { - return $transactionResult; - } - $boxTurntableLog = $transactionResult['data']['log_id']; - $giftCounts = $transactionResult['data']['gift_counts']; - - // 5. 处理后续操作(非事务性操作) - $this->handlePostDrawOperations( - $precomputedResults, - $boxTurntableLog, - $room_id, - $xlh_ext, - $currentXlhPeriodsNum, - $addcurrentXlhPeriodsNum, - $room - ); - - // 6. 构建并返回结果 - return $this->buildDrawResult($boxTurntableLog, $giftCounts); - - } catch (\Exception $e) { - $key = 'blind_box_draw_errors_' . date('Y-m-d-H-i-s'); - $errorData = [ - 'gift_bag_id' => $gift_bag_id, - 'user_id' => $user_id, - 'gift_user_ids' => $gift_user_ids, - 'num' => $num, - 'room_id' => $room_id, - 'heart_id' => $heart_id, - 'auction_id' => $auction_id, - ]; - if ($this->redis) { - $this->redis->setex($key, 86400 * 7, $e->getMessage() . ' ' . json_encode($errorData)); - } - // 如果是死锁且还有重试机会 - if (strpos($e->getMessage(), 'Deadlock') !== false && $attempt < $maxRetries - 1) { - // 随机延迟后重试 - usleep(rand(50000, 200000)); // 50-200ms - continue; - } - return ['code' => 0, 'msg' => "网络加载失败,请重试!", 'data' => null]; } + // 4. 执行抽奖事务(核心操作) + $transactionResult = $this->executeDrawTransaction( + $bag_data, + $user_id, + $room_id, + $num, + $precomputedResults, + $availableGiftss, + $gift_user_ids, + $heart_id, + $auction_id + ); + if ($transactionResult['code'] !== 1) { + return $transactionResult; + } + $boxTurntableLog = $transactionResult['data']['log_id']; + $giftCounts = $transactionResult['data']['gift_counts']; + + // 5. 处理后续操作(非事务性操作) + $this->handlePostDrawOperations( + $precomputedResults, + $boxTurntableLog, + $room_id, + $xlh_ext, + $currentXlhPeriodsNum, + $addcurrentXlhPeriodsNum, + $room + ); + + // 6. 构建并返回结果 + return $this->buildDrawResult($boxTurntableLog, $giftCounts); + + } catch (\Exception $e) { + $key = 'blind_box_draw_errors_' . date('Y-m-d-H-i-s'); + $errorData = [ + 'gift_bag_id' => $gift_bag_id, + 'user_id' => $user_id, + 'gift_user_ids' => $gift_user_ids, + 'num' => $num, + 'room_id' => $room_id, + 'heart_id' => $heart_id, + 'auction_id' => $auction_id, + ]; + if ($this->redis) { + $this->redis->setex($key, 86400 * 7, $e->getMessage() . ' ' . json_encode($errorData)); + } + return ['code' => 0, 'msg' => "网络加载失败,请重试!", 'data' => null]; } } /** @@ -495,65 +513,55 @@ class BlindBoxTurntableGiftDrawWorld extends Model $bagGiftPrice = $bag_data['gift_price'] * $num * $gift_user_num; // 增加重试机制 - $maxRetries = 3; - for ($retry = 0; $retry < $maxRetries; $retry++) { - try { - db::startTrans(); - // 按照固定顺序处理事务步骤 - // 1. 扣除用户金币(优先处理) - $this->deductUserCoins($user_id, $bagGiftPrice, $room_id); + try { + db::startTrans(); + // 按照固定顺序处理事务步骤 + // 1. 扣除用户金币(优先处理) + $this->deductUserCoins($user_id, $bagGiftPrice, $room_id); - // 2. 创建抽奖记录 - $boxTurntableLog = db::name('vs_blind_box_turntable_log')->insertGetId([ - 'user_id' => $user_id, - 'gift_bag_id' => $bag_data['id'], - 'num' => $num, - 'room_id' => $room_id, - 'bag_price' => $bag_data['gift_price'], - 'createtime' => time() - ]); + // 2. 创建抽奖记录 + $boxTurntableLog = db::name('vs_blind_box_turntable_log')->insertGetId([ + 'user_id' => $user_id, + 'gift_bag_id' => $bag_data['id'], + 'num' => $num, + 'room_id' => $room_id, + 'bag_price' => $bag_data['gift_price'], + 'createtime' => time() + ]); - if (!$boxTurntableLog) { - throw new \Exception('添加盲盒转盘记录失败'); - } - - // 3. 批量更新库存(按ID排序避免死锁) - $this->batchUpdateGiftInventory($availableGiftss, $room_id); - - // 4. 批量插入礼包发放记录 - $this->batchInsertGiftBagReceiveLog($user_id, $boxTurntableLog, $bag_data, $room_id, $precomputedResults); - - // 5. 发送礼物 - $result = $this->sendGiftsToRecipients($precomputedResults, $room_id,$user_id,$heart_id,$auction_id); - if (isset($result['code']) && $result['code'] !== 1) { - throw new \Exception($result['msg']); - } - - db::commit(); - - // 统计礼物数量 - $giftCounts = $this->countGifts($precomputedResults); - - return [ - 'code' => 1, - 'msg' => '事务执行成功', - 'data' => [ - 'log_id' => $boxTurntableLog, - 'gift_counts' => $giftCounts - ] - ]; - } catch (\Exception $e) { - db::rollback(); - // 检查是否是死锁错误 - if (strpos($e->getMessage(), 'Deadlock') !== false && $retry < $maxRetries - 1) { - // 等待随机时间后重试 - usleep(rand(10000, 100000)); // 10-100ms - continue; - } - return ['code' => 0, 'msg' => $e->getMessage(), 'data' => null]; + if (!$boxTurntableLog) { + throw new \Exception('添加盲盒转盘记录失败'); } + + // 3. 批量更新库存(按ID排序避免死锁) + $this->batchUpdateGiftInventory($availableGiftss, $room_id); + + // 4. 批量插入礼包发放记录 + $this->batchInsertGiftBagReceiveLog($user_id, $boxTurntableLog, $bag_data, $room_id, $precomputedResults); + + // 5. 发送礼物 + $result = $this->sendGiftsToRecipients($precomputedResults, $room_id,$user_id,$heart_id,$auction_id); + if (isset($result['code']) && $result['code'] !== 1) { + throw new \Exception($result['msg']); + } + + db::commit(); + + // 统计礼物数量 + $giftCounts = $this->countGifts($precomputedResults); + + return [ + 'code' => 1, + 'msg' => '事务执行成功', + 'data' => [ + 'log_id' => $boxTurntableLog, + 'gift_counts' => $giftCounts + ] + ]; + } catch (\Exception $e) { + db::rollback(); + return ['code' => 0, 'msg' => $e->getMessage(), 'data' => null]; } - return ['code' => 0, 'msg' => '操作超时,请重试', 'data' => null]; } /** @@ -692,7 +700,6 @@ class BlindBoxTurntableGiftDrawWorld extends Model } $giftUserCounts[$key]['count']++; } - // 批量插入 $batchInsertData = []; foreach ($giftUserCounts as $userGift) { diff --git a/application/common/model/UserWallet.php b/application/common/model/UserWallet.php index c490830..ed1ba8c 100644 --- a/application/common/model/UserWallet.php +++ b/application/common/model/UserWallet.php @@ -125,7 +125,7 @@ class UserWallet extends Model return isset($status[$value]) ? $status[$value] : ''; } - public static function ChangeTypeLable($type) + public static function ChangeTypeLable($type="") { $status = [ self::OPERATION_SYSTEM => '系统调节', @@ -163,7 +163,12 @@ class UserWallet extends Model self::RED_PACKET_LEFT_COIN => '红包剩余退回(金币)', self::RED_PACKET_LEFT_DIAMOND => '红包剩余退回(钻石)', ]; - return $status[$type] ?? ''; + if($type){ + return $status[$type] ?? ''; + }else{ + return $status; + } + } /** @@ -269,10 +274,19 @@ class UserWallet extends Model /* * 用户资金变动日志 */ - public function money_change_log($user_id, $money_type=0, $page=0,$page_limit=30){ + public function money_change_log($user_id,$seach, $money_type=0, $page=0,$page_limit=30){ if($money_type){ $where['money_type'] =$money_type; } + if($seach['stime']){ + $where['createtime'] = ['>=',strtotime($seach['stime'])]; + } + if($seach['etime']){ + $where['createtime'] = ['<=',strtotime($seach['etime'])]; + } + if($seach['change_type']){ + $where['change_type'] =$seach['change_type']; + } $log['count'] = Db::name('vs_user_money_log')->where($where)->where('user_id',$user_id)->count(); $log_select = Db::name('vs_user_money_log') ->where($where) @@ -306,4 +320,11 @@ class UserWallet extends Model } return $log; } + + /* + * 获取用户资金类型 + */ + public function getChangeTypeLableList(){ + return $this->ChangeTypeLable(); + } } \ No newline at end of file