feat: refactor super admin to use is_super_admin flag and enhance site deletion logic
- Changed super admin detection from role-based to `is_super_admin` flag in AdminUser model
- Added `requireDefaultAdminSiteId()` method to throw validation error when no integration site exists
- Enhanced site deletion to migrate platform role bindings to fallback site and auto-delete site-specific admin accounts
- Made agent line code optional with auto-generation fallback using `{site_code}-agent-{counter}` format
This commit is contained in:
@@ -5,26 +5,14 @@ namespace App\Services\Integration;
|
||||
use App\Models\AdminSite;
|
||||
use App\Models\AdminRole;
|
||||
use App\Models\AdminUser;
|
||||
use App\Support\AdminPermissionInheritance;
|
||||
use App\Models\Player;
|
||||
use App\Support\SitePlatformRole;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
final class IntegrationSiteService
|
||||
{
|
||||
/** @var list<string> */
|
||||
private const SITE_ADMIN_PERMISSION_SLUGS = [
|
||||
'prd.agent.manage',
|
||||
'prd.agent.profile.manage',
|
||||
'prd.agent.user.manage',
|
||||
'prd.agent.role.manage',
|
||||
'prd.users.manage',
|
||||
'prd.tickets.view',
|
||||
'prd.report.view',
|
||||
'prd.settlement.agent.view',
|
||||
'prd.settlement.agent.manage',
|
||||
];
|
||||
|
||||
public function __construct(
|
||||
private readonly PartnerSiteConfigResolver $configResolver,
|
||||
) {}
|
||||
@@ -59,7 +47,7 @@ final class IntegrationSiteService
|
||||
'wallet_api_key_encrypted' => encrypt($secrets['wallet_api_key']),
|
||||
]);
|
||||
|
||||
$role = $this->createSiteAdminRole($site);
|
||||
$role = SitePlatformRole::resolve();
|
||||
$adminUser = $this->createSiteAdminUser($site, $role, $adminAccount);
|
||||
|
||||
return [
|
||||
@@ -108,6 +96,79 @@ final class IntegrationSiteService
|
||||
return $site->fresh();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{site: AdminSite, secrets: array{sso_jwt_secret: string, wallet_api_key: string}}
|
||||
*/
|
||||
public function destroy(AdminSite $site): void
|
||||
{
|
||||
$siteCode = (string) $site->code;
|
||||
$siteId = (int) $site->id;
|
||||
$siteAdminRoleId = SitePlatformRole::resolve()->id;
|
||||
|
||||
if (AdminSite::query()->count() <= 1) {
|
||||
$fallbackSiteId = null;
|
||||
} else {
|
||||
$fallbackSiteId = (int) AdminSite::query()
|
||||
->where('id', '!=', $siteId)
|
||||
->orderBy('id')
|
||||
->value('id');
|
||||
}
|
||||
|
||||
DB::transaction(function () use ($site, $siteCode, $siteId, $siteAdminRoleId, $fallbackSiteId): void {
|
||||
$superRoleId = AdminRole::query()
|
||||
->where('slug', AdminUser::ROLE_SUPER_ADMIN)
|
||||
->value('id');
|
||||
|
||||
$platformBindings = DB::table('admin_user_site_roles')
|
||||
->where('site_id', $siteId)
|
||||
->when($siteAdminRoleId !== null, static fn ($query) => $query->where('role_id', '!=', $siteAdminRoleId))
|
||||
->when($superRoleId !== null, static fn ($query) => $query->where('role_id', '!=', $superRoleId))
|
||||
->get(['admin_user_id', 'role_id', 'granted_at']);
|
||||
|
||||
foreach ($platformBindings as $binding) {
|
||||
if ($fallbackSiteId === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DB::table('admin_user_site_roles')->updateOrInsert(
|
||||
[
|
||||
'admin_user_id' => (int) $binding->admin_user_id,
|
||||
'site_id' => $fallbackSiteId,
|
||||
'role_id' => (int) $binding->role_id,
|
||||
],
|
||||
['granted_at' => $binding->granted_at ?? now()],
|
||||
);
|
||||
}
|
||||
|
||||
Player::query()->where('site_code', $siteCode)->delete();
|
||||
|
||||
if ($siteAdminRoleId !== null) {
|
||||
$siteAdminUserIds = DB::table('admin_user_site_roles')
|
||||
->where('site_id', $siteId)
|
||||
->where('role_id', $siteAdminRoleId)
|
||||
->pluck('admin_user_id');
|
||||
|
||||
foreach ($siteAdminUserIds as $userId) {
|
||||
$bindings = DB::table('admin_user_site_roles')
|
||||
->where('admin_user_id', $userId)
|
||||
->get(['site_id', 'role_id']);
|
||||
|
||||
$onlyAutoSiteAdmin = $bindings->count() === 1
|
||||
&& (int) $bindings[0]->site_id === $siteId
|
||||
&& (int) $bindings[0]->role_id === (int) $siteAdminRoleId;
|
||||
|
||||
if ($onlyAutoSiteAdmin) {
|
||||
AdminUser::query()->where('id', $userId)->delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$site->delete();
|
||||
});
|
||||
|
||||
$this->configResolver->forgetCache($siteCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{site: AdminSite, secrets: array{sso_jwt_secret: string, wallet_api_key: string}}
|
||||
*/
|
||||
@@ -147,26 +208,6 @@ final class IntegrationSiteService
|
||||
return $trimmed === '' ? null : $trimmed;
|
||||
}
|
||||
|
||||
private function createSiteAdminRole(AdminSite $site): AdminRole
|
||||
{
|
||||
$slug = sprintf('site_admin_%s', (string) $site->code);
|
||||
$role = AdminRole::query()->create([
|
||||
'slug' => $slug,
|
||||
'name' => sprintf('%s 站点后台管理员', (string) $site->name),
|
||||
'description' => sprintf('自动创建:站点 %s (%s) 后台管理账号专用角色', (string) $site->name, (string) $site->code),
|
||||
'status' => 1,
|
||||
'is_system' => true,
|
||||
'sort_order' => 900,
|
||||
'scope_type' => AdminRole::SCOPE_SYSTEM,
|
||||
]);
|
||||
|
||||
$role->syncLegacyPermissionSlugs(
|
||||
AdminPermissionInheritance::expand(self::SITE_ADMIN_PERMISSION_SLUGS),
|
||||
);
|
||||
|
||||
return $role;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array{username: string, nickname: string, password: string, email?: string|null} $adminAccount
|
||||
*/
|
||||
@@ -191,7 +232,7 @@ final class IntegrationSiteService
|
||||
'status' => 0,
|
||||
]);
|
||||
|
||||
$user->syncSystemRoleSlugsForSite((int) $site->id, [(string) $role->slug]);
|
||||
$user->syncSystemRoleSlugsForSite((int) $site->id, [SitePlatformRole::SLUG]);
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user