Files
dafuweng-saiadmin6.x/server/app/dice/controller/DiceDashboardController.php
zhenhui dd264b1e97 1.将部门修改为渠道,并且所有dice_表关联渠道表
2.将所有配置表,记录表设置关联渠道
3.优化后台页面设置
2026-05-19 09:49:02 +08:00

305 lines
13 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
declare(strict_types=1);
namespace app\dice\controller;
use app\dice\helper\AdminScopeHelper;
use app\dice\model\player\DicePlayer;
use app\dice\model\player_wallet_record\DicePlayerWalletRecord;
use app\dice\model\play_record\DicePlayRecord;
use app\dice\model\reward\DiceRewardConfig;
use plugin\saiadmin\basic\BaseController;
use plugin\saiadmin\service\Permission;
use support\Request;
use support\Response;
use support\think\Db;
/**
* 大富翁工作台数据统计
*/
class DiceDashboardController extends BaseController
{
/**
* 工作台卡片统计:玩家注册、充值、提现、游玩次数(含较上周对比)
*/
#[Permission('工作台数据统计', 'core:console:list')]
public function statistics(Request $request): Response
{
$thisWeekStart = date('Y-m-d 00:00:00', strtotime('monday this week'));
$thisWeekEnd = date('Y-m-d 23:59:59', strtotime('sunday this week'));
$lastWeekStart = date('Y-m-d 00:00:00', strtotime('monday last week'));
$lastWeekEnd = date('Y-m-d 23:59:59', strtotime('sunday last week'));
$adminInfo = $this->adminInfo ?? null;
$filterDeptId = $request->input('dept_id');
$playerQueryThis = DicePlayer::whereBetween('create_time', [$thisWeekStart, $thisWeekEnd]);
$playerQueryLast = DicePlayer::whereBetween('create_time', [$lastWeekStart, $lastWeekEnd]);
AdminScopeHelper::applyAdminScope($playerQueryThis, $adminInfo, $filterDeptId);
AdminScopeHelper::applyAdminScope($playerQueryLast, $adminInfo, $filterDeptId);
$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, $filterDeptId);
AdminScopeHelper::applyAdminScope($chargeQueryLast, $adminInfo, $filterDeptId);
$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, $filterDeptId);
AdminScopeHelper::applyAdminScope($withdrawQueryLast, $adminInfo, $filterDeptId);
$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, $filterDeptId);
AdminScopeHelper::applyAdminScope($playQueryLast, $adminInfo, $filterDeptId);
$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(Request $request): Response
{
$adminInfo = $this->adminInfo ?? null;
$deptCondition = $this->buildWalletSqlDeptCondition($adminInfo, $request->input('dept_id'));
if ($deptCondition === '__empty__') {
$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'),
]);
}
$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 {$deptCondition}
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(Request $request): Response
{
$adminInfo = $this->adminInfo ?? null;
$deptCondition = $this->buildWalletSqlDeptCondition($adminInfo, $request->input('dept_id'));
if ($deptCondition === '__empty__') {
$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'),
]);
}
$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 {$deptCondition}
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(Request $request): 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, $request->input('dept_id'));
$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(Request $request): 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, $request->input('dept_id'));
$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'),
'create_time' => $row->getAttr('create_time'),
];
}
return $this->success($rows);
}
/**
* 工作台-玩家游玩记录最新50条
* 返回:玩家账号、中奖档位、赢取平台币、游玩时间
*/
#[Permission('工作台数据统计', 'core:console:list')]
public function playRecordList(Request $request): Response
{
$adminInfo = $this->adminInfo ?? null;
$query = DicePlayRecord::with([
'dicePlayer' => function ($q) {
$q->field('id,username');
},
])
->where('status', 1)
->field('id,player_id,reward_tier,win_coin,create_time')
->order('create_time', 'desc')
->limit(50);
AdminScopeHelper::applyAdminScope($query, $adminInfo, $request->input('dept_id'));
$list = $query->select();
$tierLabels = $this->buildRewardTierLabels();
$rows = [];
foreach ($list as $row) {
$player = $row->dicePlayer;
$tier = $row->getAttr('reward_tier');
$rows[] = [
'player_name' => $player ? $player->getAttr('username') : '',
'reward_tier' => $tier,
'reward_tier_label' => $tierLabels[$tier] ?? $tier,
'win_coin' => $row->getAttr('win_coin'),
'create_time' => $row->getAttr('create_time'),
];
}
return $this->success($rows);
}
/**
* @return array<string, string>
*/
private function buildRewardTierLabels(): array
{
$rows = DiceRewardConfig::field('tier,ui_text')->select();
$labels = [];
foreach ($rows as $row) {
$tier = $row->getAttr('tier');
if ($tier === '' || $tier === null) {
continue;
}
if (!isset($labels[$tier])) {
$labels[$tier] = $row->getAttr('ui_text') ?: $tier;
}
}
return $labels;
}
private function calcWeekChange($current, $last): float
{
if ($last == 0) {
return $current > 0 ? 100.0 : 0.0;
}
return round((($current - $last) / $last) * 100, 1);
}
/**
* 钱包流水 SQL 渠道条件;非超管无渠道时返回 __empty__
*/
private function buildWalletSqlDeptCondition(?array $adminInfo, $requestDeptId): string
{
if (AdminScopeHelper::getDeptId($adminInfo) !== null) {
$deptId = AdminScopeHelper::getDeptId($adminInfo);
if ($deptId <= 0) {
return '__empty__';
}
return ' AND w.dept_id = ' . $deptId;
}
$target = AdminScopeHelper::resolveBusinessDeptId($adminInfo, $requestDeptId);
if ($target !== null && $target > 0) {
return ' AND w.dept_id = ' . $target;
}
return '';
}
}