import{_ as i,o as a,c as t,a2 as n}from"./chunks/framework.BbmSSMjL.js";const o=JSON.parse('{"title":"6.2 角色管理","description":"","frontmatter":{},"headers":[],"relativePath":"zh/modules/role.md","filePath":"zh/modules/role.md"}'),h={name:"zh/modules/role.md"};function e(l,s,k,p,d,r){return a(),t("div",null,[...s[0]||(s[0]=[n(`

6.2 角色管理 ​

概述

角色管理是 RBAC 权限体系的核心,通过角色关联菜单实现权限分配。RoleService 继承 BaseTenantService(角色按租户隔离),并提供菜单授权、权限缓存清理等专用能力。

模块特点 ​

特性说明
基类BaseTenantService(租户隔离,角色含 tenant_id)
关联与 Menu 多对多(通过 RoleMenu 中间表)
唯一校验code 按租户分组唯一(['code','tenant_id'])
数据权限范围由 HasDataScope 解析(当前表无 data_scope 字段,默认全部数据)
缓存联动菜单授权后 clearRolePermissions() 清除该角色权限缓存(配合 RoleMenuObserver)

套餐化角色预置 ​

系统内置三套租户角色模板,用于按套餐等级快速授权:

角色名称定位菜单范围
租户-标准版基础功能核心业务模块
租户-专业版进阶功能核心 + 高级模块
租户-旗舰版全功能全部菜单(最全)

创建租户后,通过「角色管理 → 授权菜单」为对应角色分配菜单权限。详见 6.13 租户管理。

API 接口 ​

方法路径权限码说明
GET/api/role/pagesys:role:page分页列表
GET/api/role/listsys:role:list全量列表
GET/api/role/detail/{id}sys:role:detail详情
POST/api/role/addsys:role:add新增
PUT/api/role/updatesys:role:update修改
DELETE/api/role/delete/{id}sys:role:delete删除
DELETE/api/role/batchDeletesys:role:batchDelete批量删除
GET/api/role/menu/list/{id}—获取角色菜单(含选中状态)
POST/api/role/menu/savesys:role:savePermission保存角色菜单

Service 属性配置 ​

php
// app/Services/RoleService.php(来自项目实际代码)

class RoleService extends BaseTenantService
{
    // HasDataScope(数据权限 + 租户隔离)由 BaseTenantService 继承提供
    use HasCrudOperations, HasQueryScopes, HasUniqueCheck;

    protected string $modelClass = Role::class;

    protected array $pageLikeFields = ['name', 'code'];
    protected array $pageEqFields = [];
    protected array $pageOrderBy = ['field' => 'sort', 'type' => 'asc'];

    // code 在同一租户内唯一
    protected array $uniqueFields = [['code', 'tenant_id']];
}

菜单权限分配 ​

专用方法 ​

方法说明
getMenuListWithChecked($roleId)获取平铺菜单列表(id / name / parent_id / checked),供前端授权弹窗回显
saveMenus($roleId, $menuIds)全量覆盖式保存角色菜单(事务保护)
getMenuIds($roleId)获取角色已有菜单 ID 数组
clearRolePermissions($roleId)清除该角色的权限缓存(授权即时生效)

保存流程(saveMenus) ​

text
saveMenus($roleId, $menuIds)
    │
    ▼
DB::transaction {
    1. 删除该角色原有全部 role_menu 关联(全量覆盖)
    2. 遍历新菜单 ID,组装关联记录(含审计字段)
    3. 批量写入 role_menu
    4. clearRolePermissions() 清除该角色权限缓存
}
    │ 任一步骤异常 → 自动回滚
    ▼
返回成功

授权即时生效

保存成功即清除该角色在 Redis(perms:{uid})与 Laravel Cache 中的权限缓存,拥有该角色的用户下一次请求即按新权限校验,无需重新登录。

控制器(menuSave) ​

php
// app/Http/Controllers/Api/RoleController.php(行为说明)

#[OperationLog('角色管理-保存菜单权限', OperationLog::TYPE_AUTHORIZE, '保存角色ID:{roleId}的菜单权限')]
#[Permission('sys:role:savePermission', '授权角色菜单')]
public function menuSave(): JsonResponse
{
    $data = $this->getJsonBody();
    $roleId = $data['roleId'] ?? 0;
    $menuIds = $data['menuIds'] ?? [];
    if (empty($roleId)) {
        return $this->fail('缺少roleId参数');
    }

    $this->roleService->saveMenus($roleId, $menuIds);

    return $this->success(null, '保存成功');
}

请求参数:

参数类型必填说明
roleIdint是角色 ID
menuIdsarray是菜单 ID 数组(含目录/菜单/按钮)

删除保护(beforeDelete / afterDelete 钩子) ​

php
// 删除前:校验业务约束(如角色已被用户使用时阻止删除)
protected function beforeDelete(int $id): void
{
    // 检查 user_role 是否存在关联 → 存在则抛 BizException 阻止删除
}

// 删除后:清理 role_menu 关联 + 清除权限缓存
protected function afterDelete(int $id): void
{
    RoleMenu::where('role_id', $id)->delete();
    $this->clearRolePermissions($id);
}

数据权限 ​

数据范围语义由 HasDataScope 解析(详见 5.9 数据权限):

值范围
1全部数据(当前默认)
2本部门数据
3仅本人数据(无角色用户默认)

当前版本现状

laravel_role 表不包含 data_scope 字段(按当前表设计),getRoleDataScope() 读取缺省为 1——角色一律按全部数据处理。

`,28)])])}const y=i(h,[["render",e]]);export{o as __pageData,y as default};