feat: 增强代理和玩家管理功能

- 在 SyncAdminAuthorizationCommand 中新增对代理线路和结算菜单操作的同步功能,确保缺失的菜单操作行能够被创建。
- 更新多个控制器中的权限检查逻辑,使用 hasPermissionCode 替代原有的权限验证方式,提升权限管理的灵活性。
- 在 AdminPlayerStoreController 中引入对玩家创建能力的验证,确保只有具备相应权限的管理员能够创建玩家。
- 更新请求验证逻辑,新增 credit_limit、rebate_rate 和 extra_rebate_rate 字段,以支持更细粒度的玩家管理。
- 在 AdminUser 和 AgentNode 模型中增强角色与用户的权限管理功能,支持更细粒度的权限控制。
This commit is contained in:
2026-06-04 09:17:47 +08:00
parent 240d585f15
commit e3ffffad9c
74 changed files with 3076 additions and 65 deletions

View File

@@ -0,0 +1,112 @@
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
final class AuditAgentLineDataCommand extends Command
{
protected $signature = 'lottery:audit-agent-lines {--json : Output JSON only}';
protected $description = '盘点代理线路历史数据异常(只读)';
public function handle(): int
{
$sites = DB::table('admin_sites')->orderBy('id')->get(['id', 'code', 'name']);
$issues = [];
foreach ($sites as $site) {
$siteId = (int) $site->id;
$roots = DB::table('agent_nodes')
->where('admin_site_id', $siteId)
->where('depth', 0)
->get(['id', 'code', 'name']);
if ($roots->isEmpty()) {
$issues[] = [
'type' => 'site_without_root',
'admin_site_id' => $siteId,
'site_code' => (string) $site->code,
'message' => '站点无 depth=0 根代理节点',
];
} elseif ($roots->count() > 1) {
$issues[] = [
'type' => 'site_multiple_roots',
'admin_site_id' => $siteId,
'site_code' => (string) $site->code,
'root_ids' => $roots->pluck('id')->all(),
'message' => '站点存在多个根节点',
];
} else {
$root = $roots->first();
$expectedCode = (string) $site->code;
$rootCode = (string) $root->code;
if ($rootCode !== $expectedCode && $rootCode !== 'root-'.$expectedCode) {
$issues[] = [
'type' => 'root_code_mismatch',
'admin_site_id' => $siteId,
'site_code' => $expectedCode,
'root_code' => $rootCode,
'message' => '根节点 code 与 site.code 不一致',
];
}
$loginCount = (int) DB::table('admin_user_agents')
->where('agent_node_id', (int) $root->id)
->count();
if ($loginCount === 0) {
$issues[] = [
'type' => 'root_without_login',
'admin_site_id' => $siteId,
'agent_node_id' => (int) $root->id,
'message' => '根代理无绑定后台账号',
];
}
}
$businessAgents = DB::table('agent_nodes')
->where('admin_site_id', $siteId)
->where('depth', '>', 0)
->count();
if ($businessAgents > 0 && $roots->count() === 1) {
// informational only for multi-agent-under-one-site report
}
}
$sitesWithManyBusinessAgents = DB::table('agent_nodes')
->select('admin_site_id', DB::raw('count(*) as cnt'))
->where('depth', '>', 0)
->groupBy('admin_site_id')
->having('cnt', '>', 0)
->get();
foreach ($sitesWithManyBusinessAgents as $row) {
$siteId = (int) $row->admin_site_id;
$siteCode = (string) DB::table('admin_sites')->where('id', $siteId)->value('code');
$rootCount = DB::table('agent_nodes')->where('admin_site_id', $siteId)->where('depth', 0)->count();
if ($rootCount === 1 && (int) $row->cnt >= 1) {
$issues[] = [
'type' => 'site_has_business_agents',
'admin_site_id' => $siteId,
'site_code' => $siteCode,
'business_agent_count' => (int) $row->cnt,
'message' => '站点下存在下级业务代理(需确认是否应拆站)',
];
}
}
if ($this->option('json')) {
$this->line(json_encode(['issues' => $issues], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT));
return self::SUCCESS;
}
$this->info('Agent line audit: '.count($issues).' issue(s)');
foreach ($issues as $issue) {
$this->line('- ['.$issue['type'].'] '.$issue['message'].' (site: '.($issue['site_code'] ?? $issue['admin_site_id'] ?? '?').')');
}
return self::SUCCESS;
}
}

View File

@@ -0,0 +1,22 @@
<?php
namespace App\Console\Commands;
use App\Services\AgentSettlement\AgentSettlementPeriodCloseService;
use Illuminate\Console\Command;
final class SettlementAgentPeriodCloseCommand extends Command
{
protected $signature = 'settlement:agent-period-close {period : Settlement period ID}';
protected $description = '关闭代理账期并生成账单(试运行聚合)';
public function handle(AgentSettlementPeriodCloseService $service): int
{
$periodId = (int) $this->argument('period');
$result = $service->closePeriod($periodId);
$this->info(json_encode($result, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT));
return self::SUCCESS;
}
}

View File

@@ -5,6 +5,7 @@ namespace App\Console\Commands;
use Illuminate\Support\Carbon;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use App\Support\AdminAgentLineSettlementPermissionMenuActionSync;
use App\Support\AdminAgentPermissionMenuActionSync;
use App\Support\AdminAuthorizationRegistry;
use App\Support\AdminDrawPermissionMenuActionSync;
@@ -24,6 +25,11 @@ final class SyncAdminAuthorizationCommand extends Command
$this->info(sprintf('Created %d missing agent menu_action row(s).', $agentCreated));
}
$lineSettlementCreated = AdminAgentLineSettlementPermissionMenuActionSync::syncMissing();
if ($lineSettlementCreated > 0) {
$this->info(sprintf('Created %d missing agent line/settlement menu_action row(s).', $lineSettlementCreated));
}
$drawCreated = AdminDrawPermissionMenuActionSync::syncMissing();
if ($drawCreated > 0) {
$this->info(sprintf('Created %d missing draw menu_action row(s).', $drawCreated));