From b62a9f62406bf330143056486ce1d477794e72c9 Mon Sep 17 00:00:00 2001 From: lkddi Date: Tue, 3 Mar 2026 23:40:31 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8A=9F=E8=83=BD=EF=BC=9A=E5=90=8E=E5=8F=B0?= =?UTF-8?q?=E6=B8=B8=E6=88=8F=E5=8E=86=E5=8F=B2=E8=AE=B0=E5=BD=95=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=E4=B8=AD=E5=BF=83=20+=20=E6=B8=B8=E6=88=8F=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E9=A1=B5=E5=AE=9E=E6=97=B6=E7=BB=9F=E8=AE=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 GameHistoryController,提供各游戏历史记录查询接口 - 百家乐:局次列表 + 单局下注明细(含结果分布统计) - 老虎机:转动记录含图案分布,支持结果类型/玩家名筛选 - 赛马:场次列表 + 单场下注明细(含马匹信息展示) - 神秘箱子:投放/领取历史,支持箱子类型/领取状态筛选 - 神秘占卜:签文等级分布统计 + 历史记录,支持等级/玩家名筛选 - 新增 /admin/game-history/ 路由组(stats + 各游戏历史 + 单局详情共9条路由) - 游戏管理页(/admin/game-configs)优化: - 每个游戏卡片新增「📋 历史记录」直达按钮 - 新增「📊 加载实时统计」按钮,AJAX 异步拉取并展示各游戏汇总卡片 - 更新 GAMES_TODO.md,标记通用待办已完成 --- GAMES_TODO.md | 8 +- .../Admin/GameHistoryController.php | 244 ++++++++++++++++++ .../views/admin/game-configs/index.blade.php | 186 ++++++++++++- .../game-history/baccarat-round.blade.php | 115 +++++++++ .../admin/game-history/baccarat.blade.php | 139 ++++++++++ .../admin/game-history/fortune.blade.php | 163 ++++++++++++ .../admin/game-history/horse-race.blade.php | 124 +++++++++ .../views/admin/game-history/horse.blade.php | 113 ++++++++ .../admin/game-history/mystery-box.blade.php | 174 +++++++++++++ .../views/admin/game-history/slot.blade.php | 172 ++++++++++++ routes/web.php | 18 ++ 11 files changed, 1442 insertions(+), 14 deletions(-) create mode 100644 app/Http/Controllers/Admin/GameHistoryController.php create mode 100644 resources/views/admin/game-history/baccarat-round.blade.php create mode 100644 resources/views/admin/game-history/baccarat.blade.php create mode 100644 resources/views/admin/game-history/fortune.blade.php create mode 100644 resources/views/admin/game-history/horse-race.blade.php create mode 100644 resources/views/admin/game-history/horse.blade.php create mode 100644 resources/views/admin/game-history/mystery-box.blade.php create mode 100644 resources/views/admin/game-history/slot.blade.php diff --git a/GAMES_TODO.md b/GAMES_TODO.md index 8117dd2..c11b7e1 100644 --- a/GAMES_TODO.md +++ b/GAMES_TODO.md @@ -1,6 +1,6 @@ # 🎮 聊天室游戏开发进度 -> 更新时间:2026-03-03 +> 更新时间:2026-03-04 --- @@ -76,9 +76,9 @@ ## 📌 通用待办(所有游戏共用) -- [ ] 后台游戏管理页面(`/admin/game-configs`)显示各游戏实时统计数据 -- [ ] 各游戏历史记录在后台可查(管理员视角) -- [ ] 生产环境部署:`php artisan db:seed --class=GameConfigSeeder`(初始化游戏配置) 已经完成了 +- [x] 后台游戏管理页面(`/admin/game-configs`)显示各游戏实时统计数据(点击"加载实时统计"异步加载各游戏汇总卡片) +- [x] 各游戏历史记录在后台可查(管理员视角,新增 `/admin/game-history/` 路由组,支持百家乐/老虎机/赛马/神秘箱子/占卜各自的历史记录列表及详情页,含筛选分页) +- [x] 生产环境部署:`php artisan db:seed --class=GameConfigSeeder`(初始化游戏配置) 已经完成了 - [ ] 百家乐/老虎机 全面测试(多用户并发下注) --- diff --git a/app/Http/Controllers/Admin/GameHistoryController.php b/app/Http/Controllers/Admin/GameHistoryController.php new file mode 100644 index 0000000..0b1af7b --- /dev/null +++ b/app/Http/Controllers/Admin/GameHistoryController.php @@ -0,0 +1,244 @@ + BaccaratRound::query()->where('status', 'settled')->count(), + 'total_bets' => BaccaratBet::query()->count(), + 'total_payout' => BaccaratRound::query()->where('status', 'settled')->sum('total_payout'), + 'today_rounds' => BaccaratRound::query()->where('status', 'settled')->whereDate('settled_at', today())->count(), + ]; + + // 老虎机 + $slot = [ + 'total_spins' => SlotMachineLog::query()->count(), + 'total_cost' => SlotMachineLog::query()->sum('cost'), + 'total_payout' => SlotMachineLog::query()->sum('payout'), + 'jackpot_count' => SlotMachineLog::query()->where('result_type', 'jackpot')->count(), + 'today_spins' => SlotMachineLog::query()->whereDate('created_at', today())->count(), + ]; + + // 赛马 + $horse = [ + 'total_races' => HorseRace::query()->where('status', 'settled')->count(), + 'total_bets' => HorseBet::query()->count(), + 'total_pool' => HorseRace::query()->where('status', 'settled')->sum('total_pool'), + 'today_races' => HorseRace::query()->where('status', 'settled')->whereDate('settled_at', today())->count(), + ]; + + // 神秘箱子 + $mysteryBox = [ + 'total_dropped' => MysteryBox::query()->count(), + 'total_claimed' => MysteryBox::query()->where('status', 'claimed')->count(), + 'total_expired' => MysteryBox::query()->where('status', 'expired')->count(), + 'today_dropped' => MysteryBox::query()->whereDate('created_at', today())->count(), + ]; + + // 占卜 + $fortune = [ + 'total_times' => FortuneLog::query()->count(), + 'jackpot_count' => FortuneLog::query()->where('grade', 'jackpot')->count(), + 'curse_count' => FortuneLog::query()->where('grade', 'curse')->count(), + 'today_times' => FortuneLog::query()->whereDate('created_at', today())->count(), + ]; + + return response()->json([ + 'baccarat' => $baccarat, + 'slot' => $slot, + 'horse' => $horse, + 'mystery_box' => $mysteryBox, + 'fortune' => $fortune, + ]); + } + + /** + * 百家乐历史记录页面(局次列表,支持分页)。 + */ + public function baccarat(Request $request): View + { + // 各局统计摘要 + $summary = [ + 'total_rounds' => BaccaratRound::query()->where('status', 'settled')->count(), + 'total_bets' => BaccaratBet::query()->count(), + 'total_payout' => (int) BaccaratRound::query()->where('status', 'settled')->sum('total_payout'), + 'result_dist' => BaccaratRound::query() + ->where('status', 'settled') + ->select('result', \Illuminate\Support\Facades\DB::raw('count(*) as cnt')) + ->groupBy('result') + ->pluck('cnt', 'result'), + ]; + + $rounds = BaccaratRound::query() + ->latest() + ->paginate(20); + + return view('admin.game-history.baccarat', compact('rounds', 'summary')); + } + + /** + * 百家乐单局下注明细。 + */ + public function baccaratRound(BaccaratRound $round): View + { + $bets = $round->bets()->with('user')->latest()->paginate(30); + + return view('admin.game-history.baccarat-round', compact('round', 'bets')); + } + + /** + * 老虎机历史记录页面(支持按结果类型筛选/分页)。 + */ + public function slot(Request $request): View + { + // 统计摘要 + $summary = [ + 'total_spins' => SlotMachineLog::query()->count(), + 'total_cost' => (int) SlotMachineLog::query()->sum('cost'), + 'total_payout' => (int) SlotMachineLog::query()->sum('payout'), + 'net_income' => (int) SlotMachineLog::query()->sum('cost') - (int) SlotMachineLog::query()->sum('payout'), + 'result_dist' => SlotMachineLog::query() + ->select('result_type', \Illuminate\Support\Facades\DB::raw('count(*) as cnt')) + ->groupBy('result_type') + ->pluck('cnt', 'result_type'), + ]; + + $query = SlotMachineLog::query()->with('user')->latest(); + + // 按结果类型筛选 + if ($request->filled('result_type')) { + $query->where('result_type', $request->input('result_type')); + } + + // 按用户名筛选 + if ($request->filled('username')) { + $query->whereHas('user', function ($q) use ($request) { + $q->where('username', 'like', '%'.$request->input('username').'%'); + }); + } + + $logs = $query->paginate(30)->withQueryString(); + + return view('admin.game-history.slot', compact('logs', 'summary')); + } + + /** + * 赛马竞猜历史记录页面(场次列表,支持分页)。 + */ + public function horse(Request $request): View + { + $summary = [ + 'total_races' => HorseRace::query()->where('status', 'settled')->count(), + 'total_bets' => HorseBet::query()->count(), + 'total_pool' => (int) HorseRace::query()->sum('total_pool'), + ]; + + $races = HorseRace::query() + ->latest() + ->paginate(20); + + return view('admin.game-history.horse', compact('races', 'summary')); + } + + /** + * 赛马单场下注明细。 + */ + public function horseRace(HorseRace $race): View + { + $bets = $race->bets()->with('user')->latest()->paginate(30); + + return view('admin.game-history.horse-race', compact('race', 'bets')); + } + + /** + * 神秘箱子历史记录(投放/领取列表,支持分页和类型筛选)。 + */ + public function mysteryBox(Request $request): View + { + $summary = [ + 'total_dropped' => MysteryBox::query()->count(), + 'total_claimed' => MysteryBox::query()->where('status', 'claimed')->count(), + 'total_expired' => MysteryBox::query()->where('status', 'expired')->count(), + 'type_dist' => MysteryBox::query() + ->select('box_type', \Illuminate\Support\Facades\DB::raw('count(*) as cnt')) + ->groupBy('box_type') + ->pluck('cnt', 'box_type'), + ]; + + $query = MysteryBox::query()->with(['claim.user'])->latest(); + + if ($request->filled('box_type')) { + $query->where('box_type', $request->input('box_type')); + } + + if ($request->filled('status')) { + $query->where('status', $request->input('status')); + } + + $boxes = $query->paginate(20)->withQueryString(); + + return view('admin.game-history.mystery-box', compact('boxes', 'summary')); + } + + /** + * 神秘占卜历史记录(支持按用户/签文等级筛选,分页)。 + */ + public function fortune(Request $request): View + { + $summary = [ + 'total_times' => FortuneLog::query()->count(), + 'grade_dist' => FortuneLog::query() + ->select('grade', \Illuminate\Support\Facades\DB::raw('count(*) as cnt')) + ->groupBy('grade') + ->pluck('cnt', 'grade'), + 'total_cost' => (int) FortuneLog::query()->sum('cost'), + 'free_count' => FortuneLog::query()->where('is_free', true)->count(), + ]; + + $query = FortuneLog::query()->with('user')->latest(); + + if ($request->filled('grade')) { + $query->where('grade', $request->input('grade')); + } + + if ($request->filled('username')) { + $query->whereHas('user', function ($q) use ($request) { + $q->where('username', 'like', '%'.$request->input('username').'%'); + }); + } + + $logs = $query->paginate(30)->withQueryString(); + + return view('admin.game-history.fortune', compact('logs', 'summary')); + } +} diff --git a/resources/views/admin/game-configs/index.blade.php b/resources/views/admin/game-configs/index.blade.php index e81bd30..c9f140a 100644 --- a/resources/views/admin/game-configs/index.blade.php +++ b/resources/views/admin/game-configs/index.blade.php @@ -6,9 +6,22 @@
{{-- 页头 --}} -
-

🎮 游戏管理

-

统一管理聊天室所有娱乐游戏的开关状态与核心参数,所有游戏默认关闭。

+
+
+

🎮 游戏管理

+

统一管理聊天室所有娱乐游戏的开关状态与核心参数,所有游戏默认关闭。

+
+ +
+ + {{-- 实时统计摘要区(AJAX 异步加载,默认隐藏) --}} + @if (session('success')) @@ -41,13 +54,33 @@
{{ $game->description }}
- {{-- 大开关按钮 --}} - + {{-- 操作按钮组 --}} +
+ {{-- 历史记录链接 --}} + @php + $historyRoute = match ($game->game_key) { + 'baccarat' => 'admin.game-history.baccarat', + 'slot_machine' => 'admin.game-history.slot', + 'mystery_box' => 'admin.game-history.mystery-box', + 'horse_racing' => 'admin.game-history.horse', + 'fortune_telling' => 'admin.game-history.fortune', + default => null, + }; + @endphp + @if ($historyRoute) + + 📋 历史记录 + + @endif + {{-- 大开关按钮 --}} + +
{{-- 参数配置区域 --}} @@ -231,6 +264,139 @@ ); } + + @endsection @php diff --git a/resources/views/admin/game-history/baccarat-round.blade.php b/resources/views/admin/game-history/baccarat-round.blade.php new file mode 100644 index 0000000..e656e28 --- /dev/null +++ b/resources/views/admin/game-history/baccarat-round.blade.php @@ -0,0 +1,115 @@ +@extends('admin.layouts.app') + +@section('title', "百家乐第 #{$round->id} 局下注明细") + +@section('content') +
+ + {{-- 页头 --}} +
+
+

🎲 百家乐 #{{ $round->id }} 局下注明细

+

+ 结算时间:{{ $round->settled_at?->format('Y-m-d H:i:s') ?? '未结算' }} +  · 结果: + {{ $round->resultLabel() }} +  · 总点数:{{ $round->total_points }} +

+
+ + ← 返回历史列表 + +
+ + {{-- 本局摘要 --}} +
+
+
{{ number_format($round->bet_count ?? 0) }}
+
参与下注人数
+
+
+
{{ number_format($round->total_bet_big ?? 0) }}
+
押大总金额
+
+
+
{{ number_format($round->total_bet_small ?? 0) }}
+
押小总金额
+
+
+
{{ number_format($round->total_payout ?? 0) }}
+
本局派奖总额
+
+
+ + {{-- 下注明细表 --}} +
+ + + + + + + + + + + + + @forelse ($bets as $bet) + @php + $betLabels = ['big' => '大', 'small' => '小', 'triple' => '豹子']; + $betColors = [ + 'big' => 'bg-red-100 text-red-700', + 'small' => 'bg-blue-100 text-blue-700', + 'triple' => 'bg-purple-100 text-purple-700', + ]; + $won = $bet->payout > 0; + @endphp + + + + + + + + + @empty + + + + @endforelse + +
玩家押注方向押注金额实际获得是否中奖下注时间
+ {{ $bet->user?->username ?? '已注销' }} + + + {{ $betLabels[$bet->bet_type] ?? $bet->bet_type }} + + + {{ number_format($bet->amount) }} + + {{ $won ? '+' . number_format($bet->payout) : '0' }} + + @if ($won) + 🎉 + 中奖 + @else + 未中 + @endif + + {{ $bet->created_at->format('H:i:s') }} +
本局无人下注
+ + @if ($bets->hasPages()) +
+ {{ $bets->links() }} +
+ @endif +
+
+@endsection diff --git a/resources/views/admin/game-history/baccarat.blade.php b/resources/views/admin/game-history/baccarat.blade.php new file mode 100644 index 0000000..78c4480 --- /dev/null +++ b/resources/views/admin/game-history/baccarat.blade.php @@ -0,0 +1,139 @@ +@extends('admin.layouts.app') + +@section('title', '百家乐历史记录') + +@section('content') +
+ + {{-- 页头 --}} +
+
+

🎲 百家乐历史记录

+

查询所有已结算的百家乐局次及下注明细。

+
+ + ⚙️ 游戏配置 + +
+ + {{-- 统计卡片 --}} +
+
+
{{ number_format($summary['total_rounds']) }}
+
历史总局数
+
+
+
{{ number_format($summary['total_bets']) }}
+
历史总下注次
+
+
+
{{ number_format($summary['total_payout']) }}
+
累计派奖金币
+
+
+
结果分布
+
+ @foreach (['big' => '大', 'small' => '小', 'triple' => '豹子', 'kill' => '收割'] as $key => $label) +
+ {{ $label }} + {{ $summary['result_dist'][$key] ?? 0 }} 局 +
+ @endforeach +
+
+
+ + {{-- 局次列表 --}} +
+ + + + + + + + + + + + + + + + @forelse ($rounds as $round) + + + + + + + + + + + + @empty + + + + @endforelse + +
局次ID结算时间骰子点数结果押注笔数押大/小/豹派奖金币操作
#{{ $round->id }} + {{ $round->settled_at ? $round->settled_at->format('m-d H:i') : '—' }} + + @if ($round->dice1) + {{ $round->dice1 }} {{ $round->dice2 }} {{ $round->dice3 }} + @else + — + @endif + + {{ $round->total_points ?? '—' }} + + @php + $resultColors = [ + 'big' => 'bg-red-100 text-red-700', + 'small' => 'bg-blue-100 text-blue-700', + 'triple' => 'bg-purple-100 text-purple-700', + 'kill' => 'bg-gray-100 text-gray-600', + ]; + $label = match ($round->result) { + 'big' => '大', + 'small' => '小', + 'triple' => '豹子', + 'kill' => '收割', + default => $round->result ?? '—', + }; + $colorClass = $resultColors[$round->result] ?? 'bg-gray-100 text-gray-600'; + @endphp + @if ($round->result) + + {{ $label }} + + @else + 未结算 + @endif + + {{ number_format($round->bet_count ?? 0) }} + + {{ number_format($round->total_bet_big ?? 0) }} / + {{ number_format($round->total_bet_small ?? 0) }} / + {{ number_format($round->total_bet_triple ?? 0) }} + + {{ number_format($round->total_payout ?? 0) }} + + + 下注明细 + +
暂无记录
+ + {{-- 分页 --}} + @if ($rounds->hasPages()) +
+ {{ $rounds->links() }} +
+ @endif +
+
+@endsection diff --git a/resources/views/admin/game-history/fortune.blade.php b/resources/views/admin/game-history/fortune.blade.php new file mode 100644 index 0000000..859814c --- /dev/null +++ b/resources/views/admin/game-history/fortune.blade.php @@ -0,0 +1,163 @@ +@extends('admin.layouts.app') + +@section('title', '神秘占卜历史记录') + +@section('content') +
+ + {{-- 页头 --}} +
+
+

🔮 神秘占卜历史记录

+

查询所有玩家的占卜记录,支持按等级和玩家名筛选。

+
+ + ⚙️ 游戏配置 + +
+ + {{-- 统计卡片 --}} +
+
+
{{ number_format($summary['total_times']) }}
+
历史总占卜次
+
+
+
{{ number_format($summary['grade_dist']['jackpot'] ?? 0) }} +
+
✨ 上上签次数
+
+
+
{{ number_format($summary['grade_dist']['curse'] ?? 0) }}
+
💀 大凶签次数
+
+
+
签文分布
+
+ @php + $gradeAll = [ + 'jackpot' => ['label' => '上上签', 'color' => 'text-amber-600'], + 'good' => ['label' => '上签', 'color' => 'text-emerald-600'], + 'normal' => ['label' => '中签', 'color' => 'text-gray-500'], + 'bad' => ['label' => '下签', 'color' => 'text-orange-500'], + 'curse' => ['label' => '大凶签', 'color' => 'text-red-600'], + ]; + @endphp + @foreach ($gradeAll as $key => $meta) +
+ {{ $meta['label'] }} + {{ $summary['grade_dist'][$key] ?? 0 }} +
+ @endforeach +
+
+
+ + {{-- 筛选 --}} +
+
+ + +
+
+ + +
+
+ + + 重置 + +
+
+ + {{-- 记录列表 --}} +
+ + + + + + + + + + + + + + @forelse ($logs as $log) + @php + $gradeInfo = match ($log->grade) { + 'jackpot' => ['label' => '✨ 上上签', 'color' => 'bg-amber-100 text-amber-700'], + 'good' => ['label' => '🌸 上签', 'color' => 'bg-emerald-100 text-emerald-700'], + 'normal' => ['label' => '📜 中签', 'color' => 'bg-gray-100 text-gray-600'], + 'bad' => ['label' => '😞 下签', 'color' => 'bg-orange-100 text-orange-700'], + 'curse' => ['label' => '💀 大凶签', 'color' => 'bg-red-100 text-red-700'], + default => ['label' => $log->grade, 'color' => 'bg-gray-100 text-gray-500'], + }; + @endphp + + + + + + + + + + @empty + + + + @endforelse + +
时间玩家签文等级签文内容加成/减益是否免费消耗金币
+ {{ $log->created_at->format('m-d H:i') }} + + {{ $log->user?->username ?? '已注销' }} + + + {{ $gradeInfo['label'] }} + + + {{ \Illuminate\Support\Str::limit($log->text, 50) }} + + {{ $log->buff_desc ?? '—' }} + + @if ($log->is_free) + 免费 + @else + 付费 + @endif + + {{ $log->cost > 0 ? '-' . number_format($log->cost) : '0' }} +
暂无记录
+ + @if ($logs->hasPages()) +
+ {{ $logs->links() }} +
+ @endif +
+
+@endsection diff --git a/resources/views/admin/game-history/horse-race.blade.php b/resources/views/admin/game-history/horse-race.blade.php new file mode 100644 index 0000000..232afaa --- /dev/null +++ b/resources/views/admin/game-history/horse-race.blade.php @@ -0,0 +1,124 @@ +@extends('admin.layouts.app') + +@section('title', "赛马第 #{$race->id} 场下注明细") + +@section('content') +
+ + {{-- 页头 --}} + @php + $horses = $race->horses ?? []; + $winner = collect($horses)->firstWhere('id', $race->winner_horse_id); + @endphp +
+
+

🐎 赛马 #{{ $race->id }} 场下注明细

+

+ 结算时间:{{ $race->settled_at?->format('Y-m-d H:i:s') ?? '未结算' }} + @if ($winner) +  · 胜者:{{ $winner['emoji'] ?? '' }} + {{ $winner['name'] ?? '' }} + @endif +  · 注池:{{ number_format($race->total_pool ?? 0) }} + 金币 +

+
+ + ← 返回场次列表 + +
+ + {{-- 马匹信息 --}} + @if (count($horses) > 0) +
+
参赛马匹
+
+ @foreach ($horses as $horse) +
+
{{ $horse['emoji'] ?? '🐎' }}
+
+ {{ $horse['name'] }} + @if ($horse['id'] === $race->winner_horse_id) + 🏆 + @endif +
+
+ @endforeach +
+
+ @endif + + {{-- 下注明细表 --}} +
+ + + + + + + + + + + + + @forelse ($bets as $bet) + @php + $betHorse = collect($horses)->firstWhere('id', $bet->horse_id); + $isWinner = $bet->horse_id === $race->winner_horse_id; + $won = ($bet->payout ?? 0) > 0; + @endphp + + + + + + + + + @empty + + + + @endforelse + +
玩家押注马匹押注金额实际获得是否中奖下注时间
+ {{ $bet->user?->username ?? '已注销' }} + + @if ($betHorse) + + {{ $betHorse['emoji'] ?? '' }} {{ $betHorse['name'] ?? '' }} + + @else + #{{ $bet->horse_id }} + @endif + + {{ number_format($bet->amount) }} + + {{ $won ? '+' . number_format($bet->payout) : '0' }} + + @if ($won) + 🎉 + 中奖 + @else + 未中 + @endif + + {{ $bet->created_at->format('H:i:s') }} +
本场无人下注
+ + @if ($bets->hasPages()) +
+ {{ $bets->links() }} +
+ @endif +
+
+@endsection diff --git a/resources/views/admin/game-history/horse.blade.php b/resources/views/admin/game-history/horse.blade.php new file mode 100644 index 0000000..44ca99d --- /dev/null +++ b/resources/views/admin/game-history/horse.blade.php @@ -0,0 +1,113 @@ +@extends('admin.layouts.app') + +@section('title', '赛马竞猜历史记录') + +@section('content') +
+ + {{-- 页头 --}} +
+
+

🐎 赛马竞猜历史记录

+

查询所有已完成的赛马场次及下注明细。

+
+ + ⚙️ 游戏配置 + +
+ + {{-- 统计卡片 --}} +
+
+
{{ number_format($summary['total_races']) }}
+
历史总场次
+
+
+
{{ number_format($summary['total_bets']) }}
+
历史总下注笔
+
+
+
{{ number_format($summary['total_pool']) }}
+
累计注池金币
+
+
+ + {{-- 场次列表 --}} +
+ + + + + + + + + + + + + + + @forelse ($races as $race) + @php + $horses = $race->horses ?? []; + $winner = collect($horses)->firstWhere('id', $race->winner_horse_id); + $statusLabel = match ($race->status) { + 'betting' => ['label' => '押注中', 'color' => 'bg-blue-100 text-blue-700'], + 'running' => ['label' => '比赛中', 'color' => 'bg-amber-100 text-amber-700'], + 'settled' => ['label' => '已结算', 'color' => 'bg-emerald-100 text-emerald-700'], + 'canceled' => ['label' => '已取消', 'color' => 'bg-red-100 text-red-600'], + default => ['label' => $race->status, 'color' => 'bg-gray-100 text-gray-500'], + }; + @endphp + + + + + + + + + + + @empty + + + + @endforelse + +
场次ID结算时间参赛马匹胜者状态下注总笔注池总额操作
#{{ $race->id }} + {{ $race->settled_at ? $race->settled_at->format('m-d H:i') : '—' }} + + {{ collect($horses)->pluck('emoji')->implode('') ?: '—' }} + ({{ count($horses) }} 匹) + + @if ($winner) + {{ $winner['emoji'] ?? '' }} {{ $winner['name'] ?? '' }} + @else + + @endif + + + {{ $statusLabel['label'] }} + + + {{ number_format($race->total_bets ?? 0) }} + + {{ number_format($race->total_pool ?? 0) }} + + + 下注明细 + +
暂无记录
+ + @if ($races->hasPages()) +
+ {{ $races->links() }} +
+ @endif +
+
+@endsection diff --git a/resources/views/admin/game-history/mystery-box.blade.php b/resources/views/admin/game-history/mystery-box.blade.php new file mode 100644 index 0000000..a7390b0 --- /dev/null +++ b/resources/views/admin/game-history/mystery-box.blade.php @@ -0,0 +1,174 @@ +@extends('admin.layouts.app') + +@section('title', '神秘箱子历史记录') + +@section('content') +
+ + {{-- 页头 --}} +
+
+

📦 神秘箱子历史记录

+

查询所有投放过的神秘箱子记录,含领取情况。

+
+ + ⚙️ 游戏配置 + +
+ + {{-- 统计卡片 --}} +
+
+
{{ number_format($summary['total_dropped']) }}
+
历史总投放数
+
+
+
{{ number_format($summary['total_claimed']) }}
+
已被领取
+
+
+
{{ number_format($summary['total_expired']) }}
+
已过期/未领取
+
+
+
类型分布
+
+
+ 📦 普通箱 + {{ $summary['type_dist']['normal'] ?? 0 }} +
+
+ 💎 稀有箱 + {{ $summary['type_dist']['rare'] ?? 0 }} +
+
+ ☠️ 黑化箱 + {{ $summary['type_dist']['trap'] ?? 0 }} +
+
+
+
+ + {{-- 筛选条件 --}} +
+
+ + +
+
+ + +
+
+ + + 重置 + +
+
+ + {{-- 箱子列表 --}} +
+ + + + + + + + + + + + + + + @forelse ($boxes as $box) + @php + $typeInfo = match ($box->box_type) { + 'normal' => ['label' => '📦 普通箱', 'color' => 'bg-emerald-100 text-emerald-700'], + 'rare' => ['label' => '💎 稀有箱', 'color' => 'bg-purple-100 text-purple-700'], + 'trap' => ['label' => '☠️ 黑化箱', 'color' => 'bg-red-100 text-red-700'], + default => ['label' => '📦 未知', 'color' => 'bg-gray-100 text-gray-600'], + }; + $statusInfo = match ($box->status) { + 'open' => ['label' => '等待领取', 'color' => 'bg-blue-100 text-blue-700'], + 'claimed' => ['label' => '✅ 已领取', 'color' => 'bg-emerald-100 text-emerald-700'], + 'expired' => ['label' => '⏰ 已过期', 'color' => 'bg-gray-100 text-gray-500'], + default => ['label' => $box->status, 'color' => 'bg-gray-100 text-gray-500'], + }; + $claim = $box->claim; + @endphp + + + + + + + + + + + @empty + + + + @endforelse + +
投放时间类型奖励范围暗号状态领取者实际奖励领取时间
+ {{ $box->created_at->format('m-d H:i:s') }} + + + {{ $typeInfo['label'] }} + + + {{ number_format($box->reward_min) }} ~ {{ number_format($box->reward_max) }} + + + {{ $box->passcode ?? '—' }} + + + + {{ $statusInfo['label'] }} + + + {{ $claim?->user?->username ?? '—' }} + + @if ($claim) + + {{ $claim->reward_amount > 0 ? '+' : '' }}{{ number_format($claim->reward_amount) }} + + @else + + @endif + + {{ $claim?->created_at?->format('m-d H:i:s') ?? '—' }} +
暂无记录
+ + @if ($boxes->hasPages()) +
+ {{ $boxes->links() }} +
+ @endif +
+
+@endsection diff --git a/resources/views/admin/game-history/slot.blade.php b/resources/views/admin/game-history/slot.blade.php new file mode 100644 index 0000000..5f6c415 --- /dev/null +++ b/resources/views/admin/game-history/slot.blade.php @@ -0,0 +1,172 @@ +@extends('admin.layouts.app') + +@section('title', '老虎机历史记录') + +@section('content') +
+ + {{-- 页头 --}} +
+
+

🎰 老虎机历史记录

+

查询所有玩家的老虎机转动记录,支持按结果类型和玩家名筛选。

+
+ + ⚙️ 游戏配置 + +
+ + {{-- 统计卡片 --}} +
+
+
{{ number_format($summary['total_spins']) }}
+
总转动次数
+
+
+
{{ number_format($summary['total_cost']) }}
+
总消耗金币
+
+
+
{{ number_format($summary['total_payout']) }}
+
总派奖金币
+
+
+
{{ number_format($summary['net_income']) }}
+
庄家净收(消耗-派奖)
+
+
+
{{ number_format($summary['result_dist']['jackpot'] ?? 0) }} +
+
🎉 三7大奖次数
+
+
+ + {{-- 结果分布 --}} +
+
结果类型分布
+
+ @php + $resultLabels = [ + 'jackpot' => ['label' => '🎉 三个7', 'color' => 'bg-yellow-100 text-yellow-700'], + 'triple_gem' => ['label' => '💎 三钻', 'color' => 'bg-blue-100 text-blue-700'], + 'triple' => ['label' => '✨ 三同', 'color' => 'bg-green-100 text-green-700'], + 'pair' => ['label' => '🎁 两同', 'color' => 'bg-indigo-100 text-indigo-700'], + 'curse' => ['label' => '☠️ 三骷髅', 'color' => 'bg-red-100 text-red-700'], + 'miss' => ['label' => '😔 未中奖', 'color' => 'bg-gray-100 text-gray-600'], + ]; + @endphp + @foreach ($resultLabels as $key => $meta) +
+
{{ $meta['label'] }}
+
{{ number_format($summary['result_dist'][$key] ?? 0) }} 次
+
+ @endforeach +
+
+ + {{-- 筛选条件 --}} +
+
+ + +
+
+ + +
+
+ + + 重置 + +
+
+ + {{-- 记录列表 --}} +
+ + + + + + + + + + + + + + @forelse ($logs as $log) + @php + $symbols = \App\Models\SlotMachineLog::symbols(); + $r1Emoji = $symbols[$log->reel1]['emoji'] ?? $log->reel1; + $r2Emoji = $symbols[$log->reel2]['emoji'] ?? $log->reel2; + $r3Emoji = $symbols[$log->reel3]['emoji'] ?? $log->reel3; + $net = $log->payout - $log->cost; + $rowBg = match ($log->result_type) { + 'jackpot' => 'bg-yellow-50', + 'triple_gem' => 'bg-blue-50', + 'curse' => 'bg-red-50', + default => '', + }; + @endphp + + + + + + + + + + @empty + + + + @endforelse + +
时间玩家三列图案结果消耗获得净值
+ {{ $log->created_at->format('m-d H:i:s') }} + + {{ $log->user?->username ?? '已注销' }} + + {{ $r1Emoji }} {{ $r2Emoji }} {{ $r3Emoji }} + + + {{ $resultLabels[$log->result_type]['label'] ?? $log->result_type }} + + + -{{ number_format($log->cost) }} + + {{ $log->payout > 0 ? '+' . number_format($log->payout) : '0' }} + + {{ $net >= 0 ? '+' : '' }}{{ number_format($net) }} +
暂无记录
+ + @if ($logs->hasPages()) +
+ {{ $logs->links() }} +
+ @endif +
+
+@endsection diff --git a/routes/web.php b/routes/web.php index 84f43f9..7203763 100644 --- a/routes/web.php +++ b/routes/web.php @@ -392,6 +392,24 @@ Route::middleware(['chat.auth', 'chat.has_position'])->prefix('admin')->name('ad Route::post('/{gameConfig}/params', [\App\Http\Controllers\Admin\GameConfigController::class, 'updateParams'])->name('params'); }); + // 📊 游戏历史记录查询(各游戏历史 + 实时统计摘要) + Route::prefix('game-history')->name('game-history.')->group(function () { + // 各游戏实时统计摘要(JSON 接口,供游戏管理页 AJAX 加载) + Route::get('/stats', [\App\Http\Controllers\Admin\GameHistoryController::class, 'stats'])->name('stats'); + // 百家乐局次历史 + Route::get('/baccarat', [\App\Http\Controllers\Admin\GameHistoryController::class, 'baccarat'])->name('baccarat'); + Route::get('/baccarat/{round}', [\App\Http\Controllers\Admin\GameHistoryController::class, 'baccaratRound'])->name('baccarat.round'); + // 老虎机历史 + Route::get('/slot', [\App\Http\Controllers\Admin\GameHistoryController::class, 'slot'])->name('slot'); + // 赛马场次历史 + Route::get('/horse', [\App\Http\Controllers\Admin\GameHistoryController::class, 'horse'])->name('horse'); + Route::get('/horse/{race}', [\App\Http\Controllers\Admin\GameHistoryController::class, 'horseRace'])->name('horse.race'); + // 神秘箱子投放历史 + Route::get('/mystery-box', [\App\Http\Controllers\Admin\GameHistoryController::class, 'mysteryBox'])->name('mystery-box'); + // 神秘占卜历史 + Route::get('/fortune', [\App\Http\Controllers\Admin\GameHistoryController::class, 'fortune'])->name('fortune'); + }); + // 📦 神秘箱子:管理员手动投放 Route::post('/mystery-box/drop', [\App\Http\Controllers\Admin\GameConfigController::class, 'dropMysteryBox'])->name('mystery-box.drop');