code ?? '') === '' && is_string($role->slug) && $role->slug !== '') { $role->code = $role->slug; } }); } protected $fillable = [ 'slug', 'name', 'code', 'description', 'status', 'is_system', 'sort_order', 'owner_agent_id', 'delegated_from_role_id', 'scope_type', ]; protected function casts(): array { return [ 'owner_agent_id' => 'integer', 'delegated_from_role_id' => 'integer', 'status' => 'integer', 'is_system' => 'boolean', 'sort_order' => 'integer', ]; } public function isAgentScoped(): bool { return $this->scope_type === self::SCOPE_AGENT && $this->owner_agent_id !== null; } public function isReadOnlyTemplate(): bool { return $this->delegated_from_role_id !== null; } /** * @return BelongsToMany */ public function menuActions(): BelongsToMany { return $this->belongsToMany( AdminMenuAction::class, 'admin_role_menu_actions', 'role_id', 'menu_action_id', ); } /** @return BelongsToMany */ public function users(): BelongsToMany { return $this->belongsToMany( AdminUser::class, 'admin_user_site_roles', 'role_id', 'admin_user_id', )->withPivot(['site_id', 'granted_at']); } /** * 由已授权的 menu_action 反推 `prd.*`(与 Registry 映射一致)。 * * @return list */ public function legacyPermissionSlugs(): array { $codes = DB::table('admin_role_menu_actions as rma') ->join('admin_menu_actions as ma', 'ma.id', '=', 'rma.menu_action_id') ->where('rma.role_id', $this->id) ->where('ma.status', 1) ->pluck('ma.permission_code') ->all(); return AdminPermissionBridge::legacySlugsGrantedByMenuActionCodes($codes); } /** * @param list $slugs */ public function syncLegacyPermissionSlugs(array $slugs): void { $legacySlugs = AdminPermissionBridge::normalizeCanonicalLegacySlugs($slugs); $codes = []; foreach ($legacySlugs as $slug) { $codes = array_merge($codes, AdminPermissionBridge::menuActionCodesForLegacy($slug)); } $codes = array_values(array_unique($codes)); $ids = DB::table('admin_menu_actions') ->whereIn('permission_code', $codes) ->where('status', 1) ->pluck('id') ->all(); DB::table('admin_role_menu_actions')->where('role_id', $this->id)->delete(); foreach ($ids as $mid) { DB::table('admin_role_menu_actions')->insert([ 'role_id' => $this->id, 'menu_action_id' => (int) $mid, ]); } } public function assignedUserCount(): int { $agentCount = (int) DB::table('admin_user_agent_roles') ->where('role_id', $this->id) ->distinct() ->count('admin_user_id'); if ($this->isAgentScoped()) { return $agentCount; } return (int) DB::table('admin_user_site_roles') ->where('role_id', $this->id) ->distinct() ->count('admin_user_id'); } }