From 3e7083d7c12c5a1d3efd2d0df1c74bafacf8bf3e Mon Sep 17 00:00:00 2001 From: lizhuoran <625237490@qq.com> Date: Wed, 11 Mar 2026 10:25:43 +0800 Subject: [PATCH] =?UTF-8?q?fix(=E6=9D=83=E9=99=90):=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E6=9D=83=E9=99=90=E7=BC=96=E8=BE=91=E6=97=B6=E7=9A=84=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E5=8B=BE=E9=80=89=E6=98=BE=E7=A4=BA=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 问题: - 使用 Tabs 组件时,每个 Tab 中的 CheckboxList 都使用相同的字段名 'permissions' - 导致字段冲突,无法正确加载和保存已有权限 解决方案: - 为每个模块使用唯一的字段名(permissions_document, permissions_user 等) - 添加 afterStateHydrated 钩子,在编辑时自动加载该模块的已有权限 - 添加隐藏字段 all_permissions 收集所有模块的权限 - 在 mutateFormDataBeforeSave/mutateFormDataBeforeCreate 中处理权限数据 - 在 afterSave/afterCreate 中使用 syncPermissions 同步权限到数据库 改进: - RoleResource: 编辑角色时,每个模块的权限会自动勾选显示 - UserResource: 编辑用户时,直接权限会自动勾选显示 - 保存时正确收集所有模块的权限并同步到数据库 - super-admin 角色的权限字段保持禁用状态 现在编辑角色或用户时,已有的权限会正确显示为勾选状态 --- app/Filament/Resources/RoleResource.php | 34 +++++++++++++++++-- .../RoleResource/Pages/CreateRole.php | 29 ++++++++++++++++ .../Resources/RoleResource/Pages/EditRole.php | 29 ++++++++++++++++ app/Filament/Resources/UserResource.php | 34 +++++++++++++++++-- .../UserResource/Pages/CreateUser.php | 29 ++++++++++++++++ .../Resources/UserResource/Pages/EditUser.php | 29 ++++++++++++++++ 6 files changed, 178 insertions(+), 6 deletions(-) diff --git a/app/Filament/Resources/RoleResource.php b/app/Filament/Resources/RoleResource.php index da5c4e8..86086e9 100644 --- a/app/Filament/Resources/RoleResource.php +++ b/app/Filament/Resources/RoleResource.php @@ -87,9 +87,8 @@ class RoleResource extends Resource $tabs[] = Forms\Components\Tabs\Tab::make($config['name']) ->icon($config['icon']) ->schema([ - Forms\Components\CheckboxList::make('permissions') + Forms\Components\CheckboxList::make("permissions_{$module}") ->label('') - ->relationship('permissions', 'name') ->options($options) ->columns(2) ->bulkToggleable() @@ -98,7 +97,18 @@ class RoleResource extends Resource $record?->name === 'super-admin' ? 'super-admin 角色拥有所有权限,不可修改' : '选择该模块的权限' - ), + ) + ->afterStateHydrated(function ($component, $state, ?Role $record) use ($module) { + if ($record) { + // 获取该角色在当前模块的权限 + $modulePermissions = $record->permissions() + ->where('name', 'like', "{$module}.%") + ->pluck('name') + ->toArray(); + $component->state($modulePermissions); + } + }) + ->dehydrated(false), // 不直接保存,在下面统一处理 ]); } @@ -137,6 +147,24 @@ class RoleResource extends Resource Forms\Components\Section::make('权限配置') ->schema([ + Forms\Components\Hidden::make('all_permissions') + ->afterStateHydrated(function ($component, ?Role $record) { + if ($record) { + $component->state($record->permissions->pluck('name')->toArray()); + } + }) + ->dehydrateStateUsing(function ($state, $get) { + // 收集所有模块的权限 + $allPermissions = []; + $modules = ['document', 'system-setting', 'activity-log', 'terminal', 'sop-template', 'group', 'user', 'role']; + + foreach ($modules as $module) { + $modulePermissions = $get("permissions_{$module}") ?? []; + $allPermissions = array_merge($allPermissions, $modulePermissions); + } + + return $allPermissions; + }), Forms\Components\Tabs::make('权限分组') ->tabs(self::getPermissionTabs()) ->columnSpanFull(), diff --git a/app/Filament/Resources/RoleResource/Pages/CreateRole.php b/app/Filament/Resources/RoleResource/Pages/CreateRole.php index 1cc04ff..9454d8a 100644 --- a/app/Filament/Resources/RoleResource/Pages/CreateRole.php +++ b/app/Filament/Resources/RoleResource/Pages/CreateRole.php @@ -18,4 +18,33 @@ class CreateRole extends CreateRecord { return '角色创建成功'; } + + protected function mutateFormDataBeforeCreate(array $data): array + { + // 从 all_permissions 字段获取权限列表 + if (isset($data['all_permissions'])) { + $permissions = $data['all_permissions']; + unset($data['all_permissions']); + + // 保存权限到记录中,稍后在 afterCreate 中同步 + $this->permissions = $permissions; + } + + // 移除所有 permissions_* 字段 + foreach ($data as $key => $value) { + if (str_starts_with($key, 'permissions_')) { + unset($data[$key]); + } + } + + return $data; + } + + protected function afterCreate(): void + { + // 同步权限 + if (isset($this->permissions)) { + $this->record->syncPermissions($this->permissions); + } + } } diff --git a/app/Filament/Resources/RoleResource/Pages/EditRole.php b/app/Filament/Resources/RoleResource/Pages/EditRole.php index 1f2e33c..f370258 100644 --- a/app/Filament/Resources/RoleResource/Pages/EditRole.php +++ b/app/Filament/Resources/RoleResource/Pages/EditRole.php @@ -29,4 +29,33 @@ class EditRole extends EditRecord { return '角色更新成功'; } + + protected function mutateFormDataBeforeSave(array $data): array + { + // 从 all_permissions 字段获取权限列表 + if (isset($data['all_permissions'])) { + $permissions = $data['all_permissions']; + unset($data['all_permissions']); + + // 保存权限到记录中,稍后在 afterSave 中同步 + $this->permissions = $permissions; + } + + // 移除所有 permissions_* 字段 + foreach ($data as $key => $value) { + if (str_starts_with($key, 'permissions_')) { + unset($data[$key]); + } + } + + return $data; + } + + protected function afterSave(): void + { + // 同步权限 + if (isset($this->permissions)) { + $this->record->syncPermissions($this->permissions); + } + } } diff --git a/app/Filament/Resources/UserResource.php b/app/Filament/Resources/UserResource.php index 74724e0..6a40115 100644 --- a/app/Filament/Resources/UserResource.php +++ b/app/Filament/Resources/UserResource.php @@ -87,13 +87,23 @@ class UserResource extends Resource $tabs[] = Forms\Components\Tabs\Tab::make($config['name']) ->icon($config['icon']) ->schema([ - Forms\Components\CheckboxList::make('permissions') + Forms\Components\CheckboxList::make("permissions_{$module}") ->label('') - ->relationship('permissions', 'name') ->options($options) ->columns(2) ->bulkToggleable() - ->helperText('选择该模块的直接权限(会叠加到角色权限之上)'), + ->helperText('选择该模块的直接权限(会叠加到角色权限之上)') + ->afterStateHydrated(function ($component, $state, ?User $record) use ($module) { + if ($record) { + // 获取该用户在当前模块的直接权限 + $modulePermissions = $record->permissions() + ->where('name', 'like', "{$module}.%") + ->pluck('name') + ->toArray(); + $component->state($modulePermissions); + } + }) + ->dehydrated(false), // 不直接保存,在下面统一处理 ]); } @@ -151,6 +161,24 @@ class UserResource extends Resource Forms\Components\Section::make('直接权限') ->description('为用户分配额外的权限,这些权限会叠加到角色权限之上') ->schema([ + Forms\Components\Hidden::make('all_permissions') + ->afterStateHydrated(function ($component, ?User $record) { + if ($record) { + $component->state($record->permissions->pluck('name')->toArray()); + } + }) + ->dehydrateStateUsing(function ($state, $get) { + // 收集所有模块的权限 + $allPermissions = []; + $modules = ['document', 'system-setting', 'activity-log', 'terminal', 'sop-template', 'group', 'user', 'role']; + + foreach ($modules as $module) { + $modulePermissions = $get("permissions_{$module}") ?? []; + $allPermissions = array_merge($allPermissions, $modulePermissions); + } + + return $allPermissions; + }), Forms\Components\Tabs::make('权限分组') ->tabs(self::getPermissionTabs()) ->columnSpanFull(), diff --git a/app/Filament/Resources/UserResource/Pages/CreateUser.php b/app/Filament/Resources/UserResource/Pages/CreateUser.php index 8bf6cf3..999314d 100644 --- a/app/Filament/Resources/UserResource/Pages/CreateUser.php +++ b/app/Filament/Resources/UserResource/Pages/CreateUser.php @@ -19,4 +19,33 @@ class CreateUser extends CreateRecord { return '用户创建成功'; } + + protected function mutateFormDataBeforeCreate(array $data): array + { + // 从 all_permissions 字段获取权限列表 + if (isset($data['all_permissions'])) { + $permissions = $data['all_permissions']; + unset($data['all_permissions']); + + // 保存权限到记录中,稍后在 afterCreate 中同步 + $this->permissions = $permissions; + } + + // 移除所有 permissions_* 字段 + foreach ($data as $key => $value) { + if (str_starts_with($key, 'permissions_')) { + unset($data[$key]); + } + } + + return $data; + } + + protected function afterCreate(): void + { + // 同步权限 + if (isset($this->permissions)) { + $this->record->syncPermissions($this->permissions); + } + } } diff --git a/app/Filament/Resources/UserResource/Pages/EditUser.php b/app/Filament/Resources/UserResource/Pages/EditUser.php index f2c4d78..68632f3 100644 --- a/app/Filament/Resources/UserResource/Pages/EditUser.php +++ b/app/Filament/Resources/UserResource/Pages/EditUser.php @@ -26,4 +26,33 @@ class EditUser extends EditRecord { return '用户更新成功'; } + + protected function mutateFormDataBeforeSave(array $data): array + { + // 从 all_permissions 字段获取权限列表 + if (isset($data['all_permissions'])) { + $permissions = $data['all_permissions']; + unset($data['all_permissions']); + + // 保存权限到记录中,稍后在 afterSave 中同步 + $this->permissions = $permissions; + } + + // 移除所有 permissions_* 字段 + foreach ($data as $key => $value) { + if (str_starts_with($key, 'permissions_')) { + unset($data[$key]); + } + } + + return $data; + } + + protected function afterSave(): void + { + // 同步权限 + if (isset($this->permissions)) { + $this->record->syncPermissions($this->permissions); + } + } }