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:
@@ -29,6 +29,7 @@ final class AdminUser extends Authenticatable
|
||||
'email',
|
||||
'password',
|
||||
'status',
|
||||
'is_super_admin',
|
||||
];
|
||||
|
||||
protected $hidden = [
|
||||
@@ -42,27 +43,40 @@ final class AdminUser extends Authenticatable
|
||||
'email_verified_at' => 'datetime',
|
||||
'last_login_at' => 'datetime',
|
||||
'password' => 'hashed',
|
||||
'is_super_admin' => 'boolean',
|
||||
];
|
||||
}
|
||||
|
||||
public static function defaultAdminSiteId(): int
|
||||
public static function defaultAdminSiteId(): ?int
|
||||
{
|
||||
static $cached = null;
|
||||
if ($cached !== null) {
|
||||
static $resolved = false;
|
||||
if ($resolved) {
|
||||
return $cached;
|
||||
}
|
||||
$resolved = true;
|
||||
|
||||
$id = DB::table('admin_sites')->where('is_default', true)->value('id');
|
||||
if ($id === null) {
|
||||
$id = DB::table('admin_sites')->orderBy('id')->value('id');
|
||||
}
|
||||
if ($id === null) {
|
||||
throw new \RuntimeException('No admin_sites row found.');
|
||||
}
|
||||
$cached = (int) $id;
|
||||
$cached = $id !== null ? (int) $id : null;
|
||||
|
||||
return $cached;
|
||||
}
|
||||
|
||||
public static function requireDefaultAdminSiteId(): int
|
||||
{
|
||||
$siteId = self::requireDefaultAdminSiteId();
|
||||
if ($siteId === null) {
|
||||
throw ValidationException::withMessages([
|
||||
'admin_site_id' => [__('admin.no_integration_site')],
|
||||
]);
|
||||
}
|
||||
|
||||
return $siteId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户在各站点上的角色(多站点 RBAC)。
|
||||
*
|
||||
@@ -188,7 +202,7 @@ final class AdminUser extends Authenticatable
|
||||
|
||||
public function syncRoleSlugsForDefaultSite(array $slugs): void
|
||||
{
|
||||
$siteId = self::defaultAdminSiteId();
|
||||
$siteId = self::requireDefaultAdminSiteId();
|
||||
$slugs = array_values(array_unique($slugs));
|
||||
$roleIds = DB::table('admin_roles')
|
||||
->whereIn('slug', $slugs)
|
||||
@@ -225,7 +239,7 @@ final class AdminUser extends Authenticatable
|
||||
*/
|
||||
public function syncSystemRoleSlugs(array $slugs): void
|
||||
{
|
||||
$this->syncSystemRoleSlugsForSite(self::defaultAdminSiteId(), $slugs);
|
||||
$this->syncSystemRoleSlugsForSite(self::requireDefaultAdminSiteId(), $slugs);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -236,6 +250,8 @@ final class AdminUser extends Authenticatable
|
||||
public function syncSystemRoleSlugsForSite(int $siteId, array $slugs): void
|
||||
{
|
||||
$slugs = array_values(array_unique($slugs));
|
||||
\App\Support\SuperAdminAccount::assertNotSiteRoleAssignment($slugs);
|
||||
|
||||
$roleIds = DB::table('admin_roles')
|
||||
->where('scope_type', AdminRole::SCOPE_SYSTEM)
|
||||
->whereIn('slug', $slugs)
|
||||
@@ -269,11 +285,7 @@ final class AdminUser extends Authenticatable
|
||||
|
||||
public function isSuperAdmin(): bool
|
||||
{
|
||||
if ($this->relationLoaded('roles')) {
|
||||
return $this->roles->contains('slug', self::ROLE_SUPER_ADMIN);
|
||||
}
|
||||
|
||||
return $this->roles()->where('admin_roles.slug', self::ROLE_SUPER_ADMIN)->exists();
|
||||
return (bool) $this->is_super_admin;
|
||||
}
|
||||
|
||||
public function primaryAgentNodeId(): ?int
|
||||
@@ -348,16 +360,25 @@ final class AdminUser extends Authenticatable
|
||||
*/
|
||||
public function directMenuActionPermissionCodes(): array
|
||||
{
|
||||
if ($this->isSuperAdmin()) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$siteId = self::defaultAdminSiteId();
|
||||
$rows = DB::table('admin_user_menu_actions as uma')
|
||||
$query = DB::table('admin_user_menu_actions as uma')
|
||||
->join('admin_menu_actions as ma', 'ma.id', '=', 'uma.menu_action_id')
|
||||
->where('uma.admin_user_id', $this->id)
|
||||
->where(function ($q) use ($siteId): void {
|
||||
->where('ma.status', 1);
|
||||
|
||||
if ($siteId !== null) {
|
||||
$query->where(function ($q) use ($siteId): void {
|
||||
$q->where('uma.site_id', $siteId)->orWhereNull('uma.site_id');
|
||||
})
|
||||
->where('ma.status', 1)
|
||||
->pluck('ma.permission_code')
|
||||
->all();
|
||||
});
|
||||
} else {
|
||||
$query->whereNull('uma.site_id');
|
||||
}
|
||||
|
||||
$rows = $query->pluck('ma.permission_code')->all();
|
||||
|
||||
$out = [];
|
||||
foreach ($rows as $code) {
|
||||
@@ -485,11 +506,17 @@ final class AdminUser extends Authenticatable
|
||||
{
|
||||
$this->loadMissing('roles');
|
||||
|
||||
return $this->roles
|
||||
$slugs = $this->roles
|
||||
->pluck('slug')
|
||||
->filter(static fn ($slug): bool => is_string($slug) && $slug !== '')
|
||||
->unique()
|
||||
->values()
|
||||
->all();
|
||||
|
||||
if ($this->isSuperAdmin()) {
|
||||
$slugs = array_values(array_unique(array_merge([self::ROLE_SUPER_ADMIN], $slugs)));
|
||||
}
|
||||
|
||||
return $slugs;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user