adminInfo ?? null; $playerQueryThis = DicePlayer::whereBetween('create_time', [$thisWeekStart, $thisWeekEnd]); $playerQueryLast = DicePlayer::whereBetween('create_time', [$lastWeekStart, $lastWeekEnd]); AdminScopeHelper::applyAdminScope($playerQueryThis, $adminInfo); AdminScopeHelper::applyAdminScope($playerQueryLast, $adminInfo); $playerThis = $playerQueryThis->count(); $playerLast = $playerQueryLast->count(); $chargeQueryThis = DicePlayerWalletRecord::where('type', 0) ->where('coin', '>', 0) ->whereBetween('create_time', [$thisWeekStart, $thisWeekEnd]); $chargeQueryLast = DicePlayerWalletRecord::where('type', 0) ->where('coin', '>', 0) ->whereBetween('create_time', [$lastWeekStart, $lastWeekEnd]); AdminScopeHelper::applyAdminScope($chargeQueryThis, $adminInfo); AdminScopeHelper::applyAdminScope($chargeQueryLast, $adminInfo); $chargeThis = $chargeQueryThis->sum('coin'); $chargeLast = $chargeQueryLast->sum('coin'); $withdrawQueryThis = DicePlayerWalletRecord::where('type', 1) ->whereBetween('create_time', [$thisWeekStart, $thisWeekEnd]); $withdrawQueryLast = DicePlayerWalletRecord::where('type', 1) ->whereBetween('create_time', [$lastWeekStart, $lastWeekEnd]); AdminScopeHelper::applyAdminScope($withdrawQueryThis, $adminInfo); AdminScopeHelper::applyAdminScope($withdrawQueryLast, $adminInfo); $withdrawThis = $withdrawQueryThis->sum(Db::raw('ABS(coin)')); $withdrawLast = $withdrawQueryLast->sum(Db::raw('ABS(coin)')); $playQueryThis = DicePlayRecord::whereBetween('create_time', [$thisWeekStart, $thisWeekEnd]); $playQueryLast = DicePlayRecord::whereBetween('create_time', [$lastWeekStart, $lastWeekEnd]); AdminScopeHelper::applyAdminScope($playQueryThis, $adminInfo); AdminScopeHelper::applyAdminScope($playQueryLast, $adminInfo); $playThis = $playQueryThis->count(); $playLast = $playQueryLast->count(); $playerChange = $this->calcWeekChange($playerThis, $playerLast); $chargeChange = $this->calcWeekChange((float) $chargeThis, (float) $chargeLast); $withdrawChange = $this->calcWeekChange((float) $withdrawThis, (float) $withdrawLast); $playChange = $this->calcWeekChange($playThis, $playLast); return $this->success([ 'player_count' => $playerThis, 'player_count_change' => $playerChange, 'charge_amount' => (float) $chargeThis, 'charge_amount_change' => $chargeChange, 'withdraw_amount' => (float) $withdrawThis, 'withdraw_amount_change' => $withdrawChange, 'play_count' => $playThis, 'play_count_change' => $playChange, ]); } /** * 近期玩家充值统计(近10天每日充值金额) */ #[Permission('工作台数据统计', 'core:console:list')] public function rechargeChart(): Response { $adminInfo = $this->adminInfo ?? null; $allowedIds = AdminScopeHelper::getAllowedAdminIds($adminInfo); $adminCondition = ''; if ($allowedIds !== null) { if (empty($allowedIds)) { $data = []; foreach (range(0, 9) as $n) { $data[] = ['recharge_date' => date('Y-m-d', strtotime("-{$n} days")), 'recharge_amount' => 0]; } $data = array_reverse($data); return $this->success([ 'recharge_amount' => array_map('floatval', array_column($data, 'recharge_amount')), 'recharge_date' => array_column($data, 'recharge_date'), ]); } $idsStr = implode(',', array_map('intval', $allowedIds)); $adminCondition = " AND w.admin_id IN ({$idsStr})"; } $sql = " SELECT d.date AS recharge_date, IFNULL(SUM(w.coin), 0) AS recharge_amount FROM (SELECT CURDATE() - INTERVAL (a.N) DAY AS date FROM (SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) a ) d LEFT JOIN dice_player_wallet_record w ON DATE(w.create_time) = d.date AND w.type = 0 AND w.coin > 0 {$adminCondition} GROUP BY d.date ORDER BY d.date ASC "; $data = Db::query($sql); return $this->success([ 'recharge_amount' => array_map('floatval', array_column($data, 'recharge_amount')), 'recharge_date' => array_column($data, 'recharge_date'), ]); } /** * 月度玩家充值汇总(当年1-12月每月充值金额) */ #[Permission('工作台数据统计', 'core:console:list')] public function rechargeBarChart(): Response { $adminInfo = $this->adminInfo ?? null; $allowedIds = AdminScopeHelper::getAllowedAdminIds($adminInfo); $adminCondition = ''; if ($allowedIds !== null) { if (empty($allowedIds)) { $data = []; for ($m = 1; $m <= 12; $m++) { $data[] = ['recharge_month' => sprintf('%02d月', $m), 'recharge_amount' => 0]; } return $this->success([ 'recharge_amount' => array_map('floatval', array_column($data, 'recharge_amount')), 'recharge_month' => array_column($data, 'recharge_month'), ]); } $idsStr = implode(',', array_map('intval', $allowedIds)); $adminCondition = " AND w.admin_id IN ({$idsStr})"; } $sql = " SELECT CONCAT(LPAD(m.month_num, 2, '0'), '月') AS recharge_month, IFNULL(SUM(w.coin), 0) AS recharge_amount FROM (SELECT 1 AS month_num UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 UNION ALL SELECT 10 UNION ALL SELECT 11 UNION ALL SELECT 12) m LEFT JOIN dice_player_wallet_record w ON YEAR(w.create_time) = YEAR(CURDATE()) AND MONTH(w.create_time) = m.month_num AND w.type = 0 AND w.coin > 0 {$adminCondition} GROUP BY m.month_num ORDER BY m.month_num ASC "; $data = Db::query($sql); return $this->success([ 'recharge_amount' => array_map('floatval', array_column($data, 'recharge_amount')), 'recharge_month' => array_column($data, 'recharge_month'), ]); } /** * 工作台-玩家充值记录:最新50条(admin_id=当前管理员及子管理员,type=0) * 返回:玩家账号(DicePlayer.username)、充值金额(coin)、充值时间(create_time) */ #[Permission('工作台数据统计', 'core:console:list')] public function walletRecordList(): Response { $adminInfo = $this->adminInfo ?? null; $query = DicePlayerWalletRecord::with([ 'dicePlayer' => function ($q) { $q->field('id,username'); }, ]) ->where('type', 0) ->order('create_time', 'desc') ->limit(50); AdminScopeHelper::applyAdminScope($query, $adminInfo); $list = $query->select(); $rows = []; foreach ($list as $row) { $player = $row->dicePlayer; $rows[] = [ 'player_name' => $player ? $player->getAttr('username') : '', 'coin' => $row->getAttr('coin'), 'create_time' => $row->getAttr('create_time'), ]; } return $this->success($rows); } /** * 工作台-新增玩家记录:最新50条(admin_id=当前管理员及子管理员) * 返回:玩家账号(username)、余额(coin)、抽奖券(total_ticket_count) */ #[Permission('工作台数据统计', 'core:console:list')] public function newPlayerList(): Response { $adminInfo = $this->adminInfo ?? null; $query = DicePlayer::field('username,coin,total_ticket_count,create_time') ->order('create_time', 'desc') ->limit(50); AdminScopeHelper::applyAdminScope($query, $adminInfo); $list = $query->select(); $rows = []; foreach ($list as $row) { $rows[] = [ 'name' => $row->getAttr('username'), 'coin' => $row->getAttr('coin'), 'total_ticket_count' => $row->getAttr('total_ticket_count'), ]; } return $this->success($rows); } private function calcWeekChange($current, $last): float { if ($last == 0) { return $current > 0 ? 100.0 : 0.0; } return round((($current - $last) / $last) * 100, 1); } }