318 lines
11 KiB
PHP
318 lines
11 KiB
PHP
<?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\GomokuGame;
|
||
use App\Models\HorseBet;
|
||
use App\Models\HorseRace;
|
||
use App\Models\LotteryIssue;
|
||
use App\Models\LotteryTicket;
|
||
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(),
|
||
];
|
||
|
||
// 彩票
|
||
$lottery = [
|
||
'total_issues' => LotteryIssue::query()->count(),
|
||
'total_bets' => LotteryTicket::query()->count(),
|
||
'total_pool' => LotteryIssue::query()->where('status', 'settled')->sum('pool_amount'),
|
||
'today_issues' => LotteryIssue::query()->whereDate('created_at', today())->count(),
|
||
];
|
||
|
||
// 五子棋
|
||
$gomoku = [
|
||
'total_games' => GomokuGame::query()->count(),
|
||
'pvp_count' => GomokuGame::query()->where('mode', 'pvp')->count(),
|
||
'pve_count' => GomokuGame::query()->where('mode', 'pve')->count(),
|
||
'today_games' => GomokuGame::query()->whereDate('created_at', today())->count(),
|
||
];
|
||
|
||
return response()->json([
|
||
'baccarat' => $baccarat,
|
||
'slot' => $slot,
|
||
'horse' => $horse,
|
||
'mystery_box' => $mysteryBox,
|
||
'fortune' => $fortune,
|
||
'lottery' => $lottery,
|
||
'gomoku' => $gomoku,
|
||
]);
|
||
}
|
||
|
||
/**
|
||
* 百家乐历史记录页面(局次列表,支持分页)。
|
||
*/
|
||
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'),
|
||
// 会员实际输掉的金币:所有已结算落败注单的押注金额合计
|
||
'total_lost' => (int) BaccaratBet::query()->where('status', 'lost')->sum('amount'),
|
||
'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'));
|
||
}
|
||
|
||
/**
|
||
* 双色球彩票历史记录页面(期号列表,支持分页)。
|
||
*/
|
||
public function lottery(Request $request): View
|
||
{
|
||
$summary = [
|
||
'total_issues' => LotteryIssue::query()->count(),
|
||
'total_tickets' => LotteryTicket::query()->count(),
|
||
'total_pool' => (int) LotteryIssue::query()->sum('pool_amount'),
|
||
'drawn_count' => LotteryIssue::query()->where('status', 'settled')->count(),
|
||
];
|
||
|
||
$issues = LotteryIssue::query()
|
||
->latest()
|
||
->paginate(20);
|
||
|
||
return view('admin.game-history.lottery', compact('issues', 'summary'));
|
||
}
|
||
|
||
/**
|
||
* 双色球单期购买明细与中奖详情。
|
||
*/
|
||
public function lotteryIssue(LotteryIssue $issue): View
|
||
{
|
||
$tickets = $issue->tickets()->with('user')->latest()->paginate(30);
|
||
|
||
return view('admin.game-history.lottery-issue', compact('issue', 'tickets'));
|
||
}
|
||
|
||
/**
|
||
* 五子棋历史记录页面。
|
||
*/
|
||
public function gomoku(Request $request): View
|
||
{
|
||
$summary = [
|
||
'total_games' => GomokuGame::query()->count(),
|
||
'pvp_count' => GomokuGame::query()->where('mode', 'pvp')->count(),
|
||
'pve_count' => GomokuGame::query()->where('mode', 'pve')->count(),
|
||
'completed' => GomokuGame::query()->where('status', 'finished')->count(),
|
||
'today_games' => GomokuGame::query()->whereDate('created_at', today())->count(),
|
||
];
|
||
|
||
$games = GomokuGame::query()
|
||
->with(['playerBlack', 'playerWhite'])
|
||
->latest()
|
||
->paginate(30);
|
||
|
||
return view('admin.game-history.gomoku', compact('games', 'summary'));
|
||
}
|
||
}
|