功能:后台游戏历史记录查询中心 + 游戏管理页实时统计
- 新增 GameHistoryController,提供各游戏历史记录查询接口 - 百家乐:局次列表 + 单局下注明细(含结果分布统计) - 老虎机:转动记录含图案分布,支持结果类型/玩家名筛选 - 赛马:场次列表 + 单场下注明细(含马匹信息展示) - 神秘箱子:投放/领取历史,支持箱子类型/领取状态筛选 - 神秘占卜:签文等级分布统计 + 历史记录,支持等级/玩家名筛选 - 新增 /admin/game-history/ 路由组(stats + 各游戏历史 + 单局详情共9条路由) - 游戏管理页(/admin/game-configs)优化: - 每个游戏卡片新增「📋 历史记录」直达按钮 - 新增「📊 加载实时统计」按钮,AJAX 异步拉取并展示各游戏汇总卡片 - 更新 GAMES_TODO.md,标记通用待办已完成
This commit is contained in:
244
app/Http/Controllers/Admin/GameHistoryController.php
Normal file
244
app/Http/Controllers/Admin/GameHistoryController.php
Normal file
@@ -0,0 +1,244 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* 文件功能:游戏历史记录后台查询控制器
|
||||
*
|
||||
* 提供百家乐、老虎机、赛马竞猜、神秘箱子、神秘占卜各游戏
|
||||
* 的历史记录查询页面及统计摘要接口,供管理员查阅。
|
||||
*
|
||||
* @author ChatRoom Laravel
|
||||
*
|
||||
* @version 1.0.0
|
||||
*/
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\BaccaratBet;
|
||||
use App\Models\BaccaratRound;
|
||||
use App\Models\FortuneLog;
|
||||
use App\Models\HorseBet;
|
||||
use App\Models\HorseRace;
|
||||
use App\Models\MysteryBox;
|
||||
use App\Models\SlotMachineLog;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class GameHistoryController extends Controller
|
||||
{
|
||||
/**
|
||||
* 各游戏实时统计摘要(JSON 接口,供 game-configs 首页加载)。
|
||||
*/
|
||||
public function stats(): JsonResponse
|
||||
{
|
||||
// 百家乐:最近30天
|
||||
$baccarat = [
|
||||
'total_rounds' => 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'));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user