# 6.2 角色管理 :::tip 概述 角色管理是 RBAC 权限体系的核心,通过角色关联菜单实现权限分配。 ::: ## 模块特点 | 特性 | 说明 | |------|------| | 基类 | BaseLogic(系统共享,不隔离) | | 关联 | 与 Menu 多对多(通过 RoleMenu 中间表) | | 数据权限 | data_scope 字段控制(1=全部 2=本部门 3=仅本人) | ## 套餐化角色预置 系统内置三套租户角色模板,用于按套餐等级快速授权: | 角色名称 | 定位 | 菜单范围 | |----------|------|----------| | 租户-标准版 | 基础功能 | 核心业务模块 | | 租户-专业版 | 进阶功能 | 核心 + 高级模块 | | 租户-旗舰版 | 全功能 | 全部菜单(最全) | 创建租户后,通过「角色管理 → 授权菜单」为对应角色分配菜单权限。详见 [租户管理](/zh/modules/tenant.html)。 ## API 接口 | 方法 | 路径 | 权限码 | 说明 | |------|------|--------|------| | GET | `/api/role/page` | sys:role:page | 分页列表 | | GET | `/api/role/list` | sys:role:list | 全量列表 | | GET | `/api/role/detail/:id` | sys:role:detail | 详情 | | POST | `/api/role/add` | sys:role:add | 新增 | | PUT | `/api/role/update` | sys:role:update | 修改 | | DELETE | `/api/role/delete/:id` | sys:role:delete | 删除 | | DELETE | `/api/role/batchDelete` | sys:role:batchDelete | 批量删除 | | GET | `/api/role/menu/list/:id` | - | 获取角色菜单 | | POST | `/api/role/menu/save` | sys:role:authorize | 保存角色菜单 | ## 菜单权限分配 ```php // app/logic/RoleLogic.php /** * 保存角色菜单关联(事务保护) * * 处理流程: * 1. 开启事务 * 2. 先删除该角色原有的全部菜单关联(全量覆盖式保存) * 3. 遍历新菜单 ID,组装关联记录 * 4. 批量写入关联记录 * 5. 提交事务 */ public function saveMenus(int $roleId, array $menuIds): bool { Db::startTrans(); try { RoleMenu::where('role_id', $roleId)->delete(); $data = []; foreach ($menuIds as $menuId) { $data[] = [ 'role_id' => $roleId, 'menu_id' => $menuId, 'create_user' => request()->userInfo->username ?? '', 'create_time' => date('Y-m-d H:i:s'), ]; } if (!empty($data)) { (new RoleMenu())->saveAll($data); } Db::commit(); return true; } catch (\Exception $e) { Db::rollback(); throw $e; } } ``` ### Controller 代码 ```php // app/controller/RoleController.php class RoleController extends BaseController { protected RoleLogic $logic; protected function initialize(): void { $this->logic = new RoleLogic(); } #[Log('角色管理-查询分页记录', Log::TYPE_QUERY)] #[Permission('sys:role:page', '角色分页')] public function page(): Json { return parent::_index($this->logic); } #[Log('角色管理-查询全量列表', Log::TYPE_QUERY)] public function list(): Json { return parent::_list($this->logic); } #[Log('角色管理-查询详情', Log::TYPE_QUERY, '查询角色ID:{id}')] public function detail(int $id): Json { return parent::_detail($this->logic, $id); } #[Log('角色管理-新增记录', Log::TYPE_ADD, '新增角色:{name}')] #[Permission('sys:role:add', '添加角色')] public function add(): Json { return parent::_add($this->logic, $this->getJsonBody()); } #[Log('角色管理-修改记录', Log::TYPE_UPDATE, '修改角色ID:{id}')] #[Permission('sys:role:update', '修改角色')] public function update(): Json { $data = $this->getJsonBody(); $id = $data['id'] ?? 0; if (empty($id)) { return $this->fail('缺少id参数'); } return parent::_edit($this->logic, $id, $data); } #[Log('角色管理-删除记录', Log::TYPE_DELETE, '删除角色ID:{id}')] #[Permission('sys:role:delete', '删除角色')] public function delete(int $id): Json { return parent::_remove($this->logic, $id); } #[Log('角色管理-批量删除记录', Log::TYPE_DELETE)] #[Permission('sys:role:delete', '删除角色')] public function batchDelete(): Json { $ids = $this->getJsonBody()['ids'] ?? []; return parent::_batchRemove($this->logic, $ids); } // 获取角色菜单(带选中状态) #[Log('角色管理-查询菜单权限', Log::TYPE_QUERY, '查询角色ID:{id}的菜单权限')] public function menuList(int $id): Json { $result = $this->logic->getMenuListWithChecked($id); return $this->success($result); } // 保存角色菜单 #[Log('角色管理-保存菜单权限', Log::TYPE_AUTHORIZE, '保存角色ID:{roleId}的菜单权限')] #[Permission('sys:role:authorize', '授权角色菜单')] public function menuSave(): Json { $data = $this->getJsonBody(); $roleId = $data['roleId'] ?? 0; $menuIds = $data['menuIds'] ?? []; if (empty($roleId)) { return $this->fail('缺少roleId参数'); } try { $this->logic->saveMenus($roleId, $menuIds); return $this->success(null, '保存成功'); } catch (\Exception $e) { return $this->fail($e->getMessage()); } } } ``` :::warning 权限生效 权限分配后,拥有该角色的用户需重新登录才能获取最新权限。权限变更时相关缓存会自动失效。 :::