db = $db; } public function index() { $this->checkLogin(); $this->checkAdmin(); $dateFrom = $_GET['from'] ?? date('Y-m-d', strtotime('-7 days')); $dateTo = $_GET['to'] ?? date('Y-m-d'); $reportService = new \App\Services\ReportService($this->db); // 总体统计 $overview = $reportService->getOverviewStats($dateFrom, $dateTo); extract($overview); // totalBet, totalWin, profit, profitRate, totalDeposit, totalWithdraw, totalCommission, totalRebate, totalUsers, newUsers, activeUsers // 日明细统计 $dailyStats = $reportService->getDailyStats($dateFrom, $dateTo); // 用户排行(投注前20) $topUsers = $reportService->getTopUsers($dateFrom, $dateTo, 20); // 代理报表 $agentStats = $reportService->getAgentStats($dateFrom, $dateTo); // 用户输赢明细 $winLossData = $reportService->getUserWinLoss($dateFrom, $dateTo); $userSummary = $winLossData['summary']; $this->render('Admin/reports.php', compact( 'dateFrom','dateTo','totalBet','totalWin','profit','profitRate', 'totalDeposit','totalWithdraw','totalCommission','totalRebate', 'totalUsers','newUsers','activeUsers','dailyStats','topUsers','agentStats', 'userSummary' )); } /** * CSV 导出 */ public function export() { $this->checkLogin(); $this->checkAdmin(); $dateFrom = $_GET['from'] ?? date('Y-m-d', strtotime('-7 days')); $dateTo = $_GET['to'] ?? date('Y-m-d'); $reportService = new \App\Services\ReportService($this->db); // 通过 Service 获取数据 $dailyStats = $reportService->getDailyStats($dateFrom, $dateTo); $topUsers = $reportService->getTopUsers($dateFrom, $dateTo, 0); // 不限条数 $winLossData = $reportService->getUserWinLoss($dateFrom, $dateTo); $userSummary = $winLossData['summary']; $userWinLossRaw = $winLossData['raw']; // 输出 CSV header('Content-Type: text/csv; charset=utf-8'); header('Content-Disposition: attachment; filename="report_' . $dateFrom . '_' . $dateTo . '.csv"'); // BOM 头(Excel 兼容中文) echo "\xEF\xBB\xBF"; $out = fopen('php://output', 'w'); // 日明细 fputcsv($out, ['=== 日明细报表 ===']); fputcsv($out, ['日期', '投注额', '派彩额', '利润', '投注笔数', '中奖笔数', '胜率']); foreach ($dailyStats as $day) { $totalBet = floatval($day['total_bet'] ?? 0); $totalWin = floatval($day['total_win'] ?? 0); $betCount = intval($day['bet_count'] ?? 0); $winCount = intval($day['win_count'] ?? 0); $winRate = $betCount > 0 ? round($winCount / $betCount * 100, 1) . '%' : '0%'; fputcsv($out, [ $day['date'], number_format($totalBet, 2, '.', ''), number_format($totalWin, 2, '.', ''), number_format($totalBet - $totalWin, 2, '.', ''), $betCount, $winCount, $winRate ]); } fputcsv($out, []); fputcsv($out, ['=== 用户投注排行 ===']); fputcsv($out, ['排名', '用户名', '投注额', '派彩额', '平台盈亏', '投注笔数']); $rank = 1; foreach ($topUsers as $user) { fputcsv($out, [ $rank++, $user['username'], number_format(floatval($user['total_bet']), 2, '.', ''), number_format(floatval($user['total_win']), 2, '.', ''), number_format(floatval($user['profit']), 2, '.', ''), intval($user['bet_count']) ]); } // 用户输赢明细 fputcsv($out, []); fputcsv($out, ['=== 用户输赢明细 ===']); fputcsv($out, ['用户名', '当前余额', '总投注', '总派彩', '平台盈亏(投注-派彩)', '投注笔数', '中奖笔数', '胜率']); foreach ($userSummary as $ud) { $tb = $ud['total_bet']; $tw = $ud['total_win']; $bc = $ud['bet_count']; $wc = $ud['win_count']; $wr = $bc > 0 ? round($wc / $bc * 100, 1) . '%' : '0%'; fputcsv($out, [ $ud['username'], number_format($ud['balance'], 2, '.', ''), number_format($tb, 2, '.', ''), number_format($tw, 2, '.', ''), number_format($tb - $tw, 2, '.', ''), $bc, $wc, $wr ]); } // 用户日输赢明细 fputcsv($out, []); fputcsv($out, ['=== 用户日输赢明细 ===']); fputcsv($out, ['用户名', '日期', '投注额', '派彩额', '平台盈亏', '笔数']); foreach ($userWinLossRaw as $dd) { $tb = floatval($dd['total_bet']); $tw = floatval($dd['total_win']); fputcsv($out, [ $dd['username'], $dd['date'], number_format($tb, 2, '.', ''), number_format($tw, 2, '.', ''), number_format($tb - $tw, 2, '.', ''), intval($dd['bet_count']) ]); } fclose($out); exit; } private function json($data) { header('Content-Type: application/json'); echo json_encode($data); } }