You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

12 KiB

角色管理 — 前端对接文档

遵循《业务中台产品接口说明书》全局契约
接口基础路径:/api/roles
权限控制:纯 hasAuthority,权限码由 DataInitializer 种子化到权限资源树


1. 接口总览

方法 路径 用途 权限码
POST /api/roles/page 分页查询角色列表 crm:role:list
POST /api/roles/saveOrUpdate 新增或编辑角色 crm:role:save
GET /api/roles/detail 角色详情(含已授权资源集合) crm:role:detail
POST /api/roles/assign-resources 分配角色权限资源(祖先补全 + 全量替换) crm:role:assign
POST /api/roles/delete 删除角色(级联清理关联表) crm:role:delete

认证方式:所有接口需在请求头携带 Authorization: Bearer {token},且 token 对应用户必须拥有对应权限码。

请求格式

  • GET 请求:参数放 URL query
  • POST 请求:Content-Type: application/x-www-form-urlencoded,参数为表单字段

⚠️ 注意:POST 请求不使用 JSON body,复杂字段(对象/数组)各自 JSON.stringify 后作为普通表单字段传递。


2. 数据模型

2.1 SysRole(列表/编辑)

interface SysRole {
  id: string;              // 角色 ID(字符串,雪花 ID)
  roleName: string;        // 角色名称
  roleCode: string;        // 角色编码(如 ROLE_SALES)
  dataScope: number;       // 数据范围:1=本人 2=本部门 3=本部门及子部门 4=全部
  sort: number;            // 排序号,值越小越靠前
  remark: string | null;   // 备注
  builtin: boolean;        // 是否内置角色(true=系统内置,不可删除、不可改编码)
}

2.2 RoleDetailVO(详情接口返回)

interface RoleDTO {
  id: string;              // 角色 ID
  roleName: string;        // 角色名称
  roleCode: string;        // 角色编码
  dataScope: number;       // 数据范围:1=本人 2=本部门 3=本部门及子部门 4=全部
  sort: number;            // 排序
  remark: string | null;   // 备注
  builtin: boolean;        // 是否内置角色
  resourceIds: string[];   // 已授权的资源 ID 集合(存储态,已含祖先补全)
}

⚠️ ID 一律按字符串收发。后端返回的 id 是字符串(雪花 ID 超出 JS Number 安全范围),前端回传原样传字符串即可,不要转 Number。

2.3 dataScope 枚举

含义 说明
1 仅本人 只能看到自己创建的数据
2 本部门 能看到本部门所有成员的数据
3 本部门及子部门 能看到本部门及其下属部门的数据
4 全部数据 能看到所有数据

注:值 5(自定义)存在于枚举中,但角色接口不允许设置,仅 1-4 合法。


3. 统一响应结构

所有接口返回统一结构:

interface Result<T> {
  code: number;       // 0=成功,非 0=失败
  success: boolean;   // 是否成功
  message: string;    // 错误信息(成功时为 null)
  data: T;            // 业务数据(无数据时为 null)
}

分页接口的 dataPageResult

interface PageResult<T> {
  content: T[];     // 数据列表
  total: number;    // 总条数
  size: number;     // 每页条数
  current: number;  // 当前页码(从 1 开始)
  pages: number;    // 总页数
  empty: boolean;   // 是否为空结果
}

4. 接口详情

4.1 分页查询角色列表

POST /api/roles/page

权限码crm:role:list

请求参数(表单字段):

字段 类型 必填 默认值 说明
current number 1 当前页码
size number 10 每页条数
keyword string - 按角色名称模糊搜索

请求示例

POST /api/roles/page
Content-Type: application/x-www-form-urlencoded
Authorization: Bearer {token}

current=1&size=10&keyword=销售

响应示例

{
  "code": 0,
  "success": true,
  "data": {
    "content": [
      {
        "id": "1",
        "roleName": "管理员",
        "roleCode": "ROLE_ADMIN",
        "dataScope": 4,
        "sort": 0,
        "remark": null,
        "builtin": true
      },
      {
        "id": "2",
        "roleName": "销售",
        "roleCode": "ROLE_SALES",
        "dataScope": 2,
        "sort": 1,
        "remark": "销售团队角色",
        "builtin": false
      }
    ],
    "total": 2,
    "size": 10,
    "current": 1,
    "pages": 1,
    "empty": false
  }
}

4.2 新增或编辑角色

POST /api/roles/saveOrUpdate

权限码crm:role:save

请求参数(表单字段):

字段 类型 必填 默认值 说明
id string - 不传=新增,传=编辑
roleName string - 角色名称
roleCode string - 角色编码(编辑内置角色时不可修改)
dataScope number 1 数据范围 1-4
sort number 0 排序号
remark string - 备注

⚠️ builtin 字段不接受前端传入。新建角色固定 builtin=false,内置角色由系统初始化创建。

校验规则

规则 触发条件 错误码 错误信息
角色名称为空 roleName 为空 61010 角色名称不能为空
角色编码为空 roleCode 为空 61010 角色编码不能为空
数据范围不合法 dataScope 不在 1-4 61010 数据范围不合法
编码已存在 roleCode 与其他角色重复 61011 角色编码已存在:{roleCode}
内置角色改编码 编辑内置角色时修改了 roleCode 61012 内置角色的编码不可修改
非法创建内置角色 尝试设置 builtin=true 61012 不允许通过接口创建内置角色

新增请求示例

POST /api/roles/saveOrUpdate
Content-Type: application/x-www-form-urlencoded
Authorization: Bearer {token}

roleName=销售&roleCode=ROLE_SALES&dataScope=2&sort=1&remark=销售团队角色

编辑请求示例

POST /api/roles/saveOrUpdate
Content-Type: application/x-www-form-urlencoded
Authorization: Bearer {token}

id=2&roleName=销售&roleCode=ROLE_SALES&dataScope=3&sort=1&remark=改为本部门及子部门

响应

{
  "code": 0,
  "success": true,
  "data": null
}

4.3 角色详情

GET /api/roles/detail

权限码crm:role:detail

请求参数(URL query):

字段 类型 必填 说明
roleId string 角色 ID

请求示例

GET /api/roles/detail?roleId=2
Authorization: Bearer {token}

响应示例

{
  "code": 0,
  "success": true,
  "data": {
    "id": "2",
    "roleName": "销售",
    "roleCode": "ROLE_SALES",
    "dataScope": 2,
    "sort": 1,
    "remark": "销售团队角色",
    "builtin": false,
    "resourceIds": ["1", "10", "100", "200"]
  }
}

resourceIds 是存储态的完整授权集合(已含祖先补全)。前端在回显权限树勾选状态时,需要用这个集合与资源树做交集——但只需勾选叶子节点,祖先节点会自动包含在集合中但不需要在前端勾选。


4.4 分配角色权限资源

POST /api/roles/assign-resources

权限码crm:role:assign

请求参数(表单字段):

字段 类型 必填 说明
roleId string 角色 ID
resourceIds string 逗号分隔的资源 ID,不传或空字符串=清空权限

⚠️ 前端只需传用户勾选的叶子节点 ID。后端会自动沿 parentId 向上遍历补全所有祖先节点(ADR-0005),确保菜单可见性链路完整。
例如:前端勾选了叶子节点 100,其祖先为 101,后端会自动补全为 {1, 10, 100} 写入数据库。

请求示例

POST /api/roles/assign-resources
Content-Type: application/x-www-form-urlencoded
Authorization: Bearer {token}

roleId=2&resourceIds=100,200,300

清空权限示例

POST /api/roles/assign-resources
Content-Type: application/x-www-form-urlencoded
Authorization: Bearer {token}

roleId=2&resourceIds=

响应

{
  "code": 0,
  "success": true,
  "data": null
}

实现说明

  1. 后端调用 getAncestorIds 补全全部祖先 ID
  2. 先删除该角色的所有旧关联(全量替换,非增量)
  3. 批量插入补全后的完整 ID 集合
  4. 整个操作在 @Transactional 事务中执行

4.5 删除角色

POST /api/roles/delete

权限码crm:role:delete

请求参数(表单字段):

字段 类型 必填 说明
id string 角色 ID

请求示例

POST /api/roles/delete
Content-Type: application/x-www-form-urlencoded
Authorization: Bearer {token}

id=2

响应

{
  "code": 0,
  "success": true,
  "data": null
}

级联清理说明

步骤 操作 说明
1 内置角色检查 builtin=true 的角色拒绝删除,返回错误码 61012
2 清理 sys_role_menu 删除该角色与所有菜单/权限点的关联
3 清理 sys_user_role 解除该角色与所有用户的绑定
4 删除角色记录 sys_role 表删除
5 全部在事务中执行 任一步骤失败则回滚

内置角色删除失败示例

{
  "code": 61012,
  "success": false,
  "message": "内置角色不允许删除"
}

5. 错误码

错误码 含义 触发场景
61010 角色参数非法 角色名称/编码为空、数据范围不合法
61011 角色编码已存在 新建或编辑时 roleCode 与其他角色重复
61012 内置角色保护 删除内置角色、修改内置角色编码、尝试创建内置角色

6. 权限码与前端按钮控制

角色管理页面的按钮需要根据权限码控制显示:

权限码 对应按钮 说明
crm:role:list 角色列表页面访问 控制菜单可见性
crm:role:detail 查看/编辑按钮 点击后调用详情接口
crm:role:save 新增/编辑保存按钮 弹窗保存时调用
crm:role:assign 权限分配按钮 打开权限树弹窗时调用
crm:role:delete 删除按钮 列表行操作列

这些权限码在系统启动时由 DataInitializer 自动创建为 button 类型权限点,并分配给管理员角色。其他角色需要通过权限分配接口授予。


7. 前端典型流程

7.1 角色列表页

1. 进入页面 → POST /api/roles/page?current=1&size=10
2. 输入关键词搜索 → POST /api/roles/page?current=1&size=10&keyword=销售
3. 点击"新增" → 弹窗填写 → POST /api/roles/saveOrUpdate
4. 点击"编辑" → GET /api/roles/detail?roleId=xxx → 回填表单 → POST /api/roles/saveOrUpdate
5. 点击"删除" → 确认 → POST /api/roles/delete?id=xxx

7.2 权限分配弹窗

1. 打开弹窗 → 调用 /api/resources/list 获取资源树
2. 回显已选 → GET /api/roles/detail?roleId=xxx → 取 resourceIds 与资源树做交集
3. 用户勾选/取消勾选叶子节点
4. 点击"保存" → POST /api/roles/assign-resources?roleId=xxx&resourceIds=100,200,300

前端只需提交用户勾选的叶子节点 ID。后端自动补全祖先,无需前端处理。

7.3 内置角色处理

  • 管理员角色(builtin=true)在列表中展示时,删除按钮应置灰或隐藏
  • 编辑内置角色时,角色编码字段应设为只读(后端会拒绝修改)