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

- 在多个控制器中更新权限检查逻辑,确保管理员能够更灵活地管理代理和玩家。
- 在 AdminPlayerStoreController 中引入对玩家创建能力的验证,确保只有具备相应权限的管理员能够创建玩家。
- 更新请求验证逻辑,新增 credit_limit、rebate_rate 和 extra_rebate_rate 字段,以支持更细粒度的玩家管理。
- 在 AgentNodeProfileController 中添加对父代理能力授予的验证,确保子代理的权限在父代理范围内。
- 引入 AgentProfileFieldRules 以简化代理资料更新请求的规则定义,提升代码复用性。
This commit is contained in:
2026-06-04 18:00:50 +08:00
parent 96545f87f6
commit a44679665d
183 changed files with 10054 additions and 857 deletions

View File

@@ -0,0 +1,166 @@
<?php
namespace App\Support;
use App\Models\AdminRole;
use App\Models\AgentNode;
use App\Models\AgentProfile;
/**
* 平台「代理」系统角色slug=agent的默认 prd.* 模板。
* 经营代理主账号只绑定该角色;权限在「平台角色管理」调整,不按线路写 agent_owner_*
*
* @see \App\Support\AgentPlatformRole
*/
final class AgentDefaultRolePermissions
{
/** 所有经营代理主账号均具备的基础能力(不含钱包对账 / 平台配置)。 */
private const BASE_SLUGS = [
'prd.dashboard.view',
'prd.agent.view',
'prd.agent.role.view',
'prd.agent.user.view',
'prd.tickets.view',
'prd.report.view',
'prd.settlement.agent.view',
];
private const CHILD_AGENT_MANAGE_SLUGS = [
'prd.agent.manage',
'prd.agent.profile.manage',
];
private const PLAYER_MANAGE_SLUGS = [
'prd.users.manage',
'prd.users.view_finance',
'prd.users.view_cs',
];
/** 线路根代理depth=0在基础包之上额外具备的经营权限。 */
private const LINE_ROOT_EXTRA_SLUGS = [
'prd.agent.manage',
'prd.agent.profile.manage',
'prd.agent.role.manage',
'prd.agent.user.manage',
'prd.users.manage',
'prd.users.view_finance',
'prd.users.view_cs',
'prd.settlement.agent.manage',
];
/**
* @return list<string>
*/
public static function baseSlugs(): array
{
return self::BASE_SLUGS;
}
/**
* @return list<string>
*/
public static function ownerSlugsForNode(AgentNode $node, ?AgentProfile $profile = null): array
{
if ($node->isRoot()) {
return self::lineRootOwnerSlugs();
}
$profile ??= AgentProfile::query()->where('agent_node_id', $node->id)->first();
if ($profile === null) {
return self::defaultOwnerSlugsWithoutProfile();
}
return self::ownerSlugsFromProfile($profile);
}
/**
* @return list<string>
*/
public static function lineRootOwnerSlugs(): array
{
return array_values(array_unique(array_merge(
self::BASE_SLUGS,
self::LINE_ROOT_EXTRA_SLUGS,
)));
}
/**
* @return list<string>
*/
public static function ownerSlugsFromProfile(AgentProfile $profile): array
{
$slugs = self::BASE_SLUGS;
if ($profile->can_create_child_agent) {
$slugs = array_merge($slugs, self::CHILD_AGENT_MANAGE_SLUGS);
}
if ($profile->can_create_player) {
$slugs = array_merge($slugs, self::PLAYER_MANAGE_SLUGS);
}
return array_values(array_unique($slugs));
}
/**
* @return list<string>
*/
public static function defaultOwnerSlugsWithoutProfile(): array
{
return array_values(array_unique(array_merge(
self::BASE_SLUGS,
self::PLAYER_MANAGE_SLUGS,
)));
}
/**
* @param array<string, mixed> $createPayload
* @return list<string>
*/
public static function ownerSlugsForNewChild(array $createPayload): array
{
$slugs = self::BASE_SLUGS;
if ((bool) ($createPayload['can_create_child_agent'] ?? false)) {
$slugs = array_merge($slugs, self::CHILD_AGENT_MANAGE_SLUGS);
}
if ((bool) ($createPayload['can_create_player'] ?? true)) {
$slugs = array_merge($slugs, self::PLAYER_MANAGE_SLUGS);
}
return array_values(array_unique($slugs));
}
/**
* 平台「代理」系统角色模板(出现在「平台角色管理」列表,供手动分配或作站点 pivot 回退)。
*
* @return list<string>
*/
public static function platformAgentRoleTemplateSlugs(): array
{
return self::defaultOwnerSlugsWithoutProfile();
}
/** 确保存在 slug=agent 的平台系统角色,并同步模板权限。 */
public static function ensurePlatformAgentRole(): AdminRole
{
$role = AdminRole::query()->updateOrCreate(
[
'slug' => 'agent',
'scope_type' => AdminRole::SCOPE_SYSTEM,
],
[
'code' => 'agent',
'name' => '代理',
'description' => '经营代理默认权限模板(与线路内 agent_owner 默认包一致)',
'status' => 1,
'is_system' => true,
'sort_order' => 50,
'owner_agent_id' => null,
'delegated_from_role_id' => null,
],
);
$role->syncLegacyPermissionSlugs(self::platformAgentRoleTemplateSlugs());
return $role->fresh() ?? $role;
}
}