feat: 重构管理员权限管理,移除 AdminPermission 模型,整合权限与角色管理逻辑,优化 API 接口以支持角色与权限的同步,增强数据库填充器以对齐权限配置

This commit is contained in:
2026-05-13 10:40:07 +08:00
parent 3c92bef774
commit edd863764b
18 changed files with 1486 additions and 224 deletions

View File

@@ -2,102 +2,62 @@
namespace Database\Seeders;
use App\Models\AdminPermission;
use App\Models\AdminRole;
use App\Models\AdminUser;
use App\Support\AdminPermissionBridge;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
/**
* 后台 RBAC {@see AdminUser::ROLE_SUPER_ADMIN} PRD 对齐。
*
* - 角色 slug`01-产品文档.md` §3 + `04-领域字典与编码规范.md` §11
* - 权限点 slug`01-产品文档.md` §8「功能」行 `prd.{功能键}.{动作}`,路由中间件引用同表
* 后台 RBAC {@see AdminUser::ROLE_SUPER_ADMIN} `config/admin_permissions.php` 对齐。
*
* 演示账号 **admin** / **123456**(仅限非 production
*/
class AdminRbacAndUserSeeder extends Seeder
{
/** @return list<array{slug: string, name: string}> */
private function permissionDefinitions(): array
/** @param list<string> $legacySlugs */
private function syncRoleMenuActions(AdminRole $role, array $legacySlugs): void
{
return [
['slug' => 'prd.users.manage', 'name' => '用户管理·可管理'],
['slug' => 'prd.users.view_finance', 'name' => '用户管理·财务查看'],
['slug' => 'prd.users.view_cs', 'name' => '用户管理·客服单用户'],
$codes = [];
foreach ($legacySlugs as $slug) {
$codes = array_merge($codes, AdminPermissionBridge::menuActionCodesForLegacy($slug));
}
$codes = array_values(array_unique($codes));
['slug' => 'prd.play_switch.manage', 'name' => '玩法开关·可管理'],
['slug' => 'prd.odds.manage', 'name' => '赔率配置·可管理'],
['slug' => 'prd.risk_cap.manage', 'name' => '封顶配置·可管理'],
['slug' => 'prd.risk_cap.view', 'name' => '封顶配置·查看'],
['slug' => 'prd.rebate.manage', 'name' => '佣金/回水·可管理'],
['slug' => 'prd.rebate.view', 'name' => '佣金/回水·查看'],
['slug' => 'prd.jackpot.manage', 'name' => 'Jackpot 配置·可管理'],
['slug' => 'prd.jackpot.view', 'name' => 'Jackpot 配置·查看'],
$ids = DB::table('admin_menu_actions')
->whereIn('permission_code', $codes)
->where('status', 1)
->pluck('id')
->all();
['slug' => 'prd.draw_result.manage', 'name' => '开奖结果录入·可管理'],
['slug' => 'prd.draw_result.view', 'name' => '开奖结果·查看'],
['slug' => 'prd.draw_reopen.manage', 'name' => '开奖结果重开·可管理'],
['slug' => 'prd.payout.manage', 'name' => '派彩确认·可管理'],
['slug' => 'prd.payout.review', 'name' => '派彩确认·可审核'],
['slug' => 'prd.payout.view', 'name' => '派彩确认·查看'],
['slug' => 'prd.wallet_reconcile.manage', 'name' => '钱包对账·可管理'],
['slug' => 'prd.wallet_reconcile.view', 'name' => '钱包对账·查看'],
['slug' => 'prd.wallet_reconcile.view_cs', 'name' => '钱包对账·客服单用户'],
['slug' => 'prd.wallet_adjust.manage', 'name' => '补单/冲正·可管理'],
['slug' => 'prd.report.all', 'name' => '报表·全部'],
['slug' => 'prd.report.risk', 'name' => '报表·风控'],
['slug' => 'prd.report.finance', 'name' => '报表·财务'],
['slug' => 'prd.report.player', 'name' => '报表·单用户'],
['slug' => 'prd.audit.all', 'name' => '审计日志·全部'],
['slug' => 'prd.audit.self', 'name' => '审计日志·自身相关'],
['slug' => 'prd.audit.finance', 'name' => '审计日志·资金相关'],
['slug' => 'prd.player_freeze.manage', 'name' => '冻结/解冻玩家·可管理'],
['slug' => 'prd.admin_user.manage', 'name' => '后台用户权限管理·可管理'],
];
DB::table('admin_role_menu_actions')->where('role_id', $role->id)->delete();
foreach ($ids as $mid) {
DB::table('admin_role_menu_actions')->insert([
'role_id' => $role->id,
'menu_action_id' => (int) $mid,
]);
}
}
/** @param list<string> $slugs */
private function syncRolePermissions(AdminRole $role, array $slugs): void
/** @return list<string> */
private function allCatalogSlugs(): array
{
$ids = AdminPermission::query()->whereIn('slug', $slugs)->pluck('id')->all();
$role->permissions()->sync($ids);
return AdminPermissionBridge::allLegacySlugs();
}
public function run(): void
{
foreach ($this->permissionDefinitions() as $row) {
AdminPermission::query()->updateOrCreate(
['slug' => $row['slug']],
['name' => $row['name']],
);
}
$legacySlugs = [
'admin.dashboard', 'admin.players.read', 'admin.wallet.read', 'admin.draws.read',
'admin.draws.publish', 'admin.settlement.run', 'admin.settlement.read', 'admin.jackpot.read',
'admin.jackpot.write', 'admin.config.read', 'admin.config.write', 'admin.audit.read',
'admin.reports.manage', 'admin.reconcile.manage',
];
AdminPermission::query()->whereIn('slug', $legacySlugs)->delete();
$super = AdminRole::query()->updateOrCreate(
['slug' => AdminUser::ROLE_SUPER_ADMIN],
['name' => '超级管理员'],
);
$this->syncRolePermissions($super, array_column($this->permissionDefinitions(), 'slug'));
$this->syncRoleMenuActions($super, $this->allCatalogSlugs());
$risk = AdminRole::query()->updateOrCreate(
['slug' => 'risk_operator'],
['name' => '风控运营员'],
);
$this->syncRolePermissions($risk, [
$this->syncRoleMenuActions($risk, [
'prd.play_switch.manage',
'prd.odds.manage',
'prd.risk_cap.manage',
@@ -115,7 +75,7 @@ class AdminRbacAndUserSeeder extends Seeder
['slug' => 'finance'],
['name' => '财务/对账员'],
);
$this->syncRolePermissions($finance, [
$this->syncRoleMenuActions($finance, [
'prd.users.view_finance',
'prd.risk_cap.view',
'prd.rebate.view',
@@ -132,7 +92,7 @@ class AdminRbacAndUserSeeder extends Seeder
['slug' => 'customer_service'],
['name' => '客服人员'],
);
$this->syncRolePermissions($cs, [
$this->syncRoleMenuActions($cs, [
'prd.users.view_cs',
'prd.draw_result.view',
'prd.wallet_reconcile.view_cs',
@@ -152,10 +112,13 @@ class AdminRbacAndUserSeeder extends Seeder
/** @var AdminUser $admin */
$admin = AdminUser::query()->where('username', $username)->firstOrFail();
$admin->roles()->sync([(int) $super->getKey()]);
DB::table('admin_user_roles')->where('admin_user_id', $admin->id)
->whereNotIn('role_id', [(int) $super->getKey()])
->delete();
$siteId = AdminUser::defaultAdminSiteId();
$superId = (int) $super->getKey();
$admin->roles()->sync([
$superId => [
'site_id' => $siteId,
'granted_at' => now(),
],
]);
}
}