# 角色管理API ## 概述 角色管理模块是权限系统的重要组成部分,负责管理系统角色、角色权限分配和用户角色关联。基于RBAC权限模型,实现了灵活的角色权限管理机制。 ## 权限说明 角色管理接口需要相应的权限才能访问: | 操作 | 权限码 | 说明 | |------|--------|------| | 查询角色列表 | `system:role:list` | 查看角色列表权限 | | 新增角色 | `system:role:add` | 新增角色权限 | | 修改角色 | `system:role:edit` | 修改角色信息权限 | | 删除角色 | `system:role:remove` | 删除角色权限 | | 分配权限 | `system:role:assign` | 分配角色权限 | | 用户授权 | `system:user:role` | 分配用户角色权限 | ## 接口列表 ### 1. 分页查询角色列表 **接口地址**: `GET /coder/sysRole/listPage` **接口描述**: 分页查询系统角色列表 **是否需要认证**: 是 **权限要求**: `system:role:list` **请求头**: ``` Authorization: your-token-value ``` **请求参数**: | 参数名 | 类型 | 必填 | 说明 | 示例 | |--------|------|------|------|------| | pageNo | Integer | 否 | 页码 | 1 | | pageSize | Integer | 否 | 每页大小 | 10 | | roleName | String | 否 | 角色名称 | 管理员 | | roleCode | String | 否 | 角色编码 | admin | | roleStatus | String | 否 | 角色状态 | 0 | | beginTime | String | 否 | 开始时间 | 2024-01-01 | | endTime | String | 否 | 结束时间 | 2024-12-31 | **响应示例**: ```json { "status": 200, "msg": "SUCCESS", "data": { "records": [ { "roleId": 1, "roleName": "超级管理员", "roleCode": "admin", "roleStatus": "0", "dataScope": "1", "deptCheckStrictly": "1", "menuCheckStrictly": "1", "sorted": 1, "remark": "超级管理员", "createBy": "admin", "createTime": "2024-01-01 10:00:00", "updateBy": "admin", "updateTime": "2024-01-01 10:00:00", "menuIds": [1, 2, 3, 4, 5], "deptIds": [100, 101, 102] } ], "total": 1, "size": 10, "current": 1, "pages": 1 }, "traceId": "trace-123456" } ``` **调用示例**: ```bash curl -X GET \ "http://localhost:18099/coder/sysRole/listPage?pageNo=1&pageSize=10&roleName=管理员" \ -H "Authorization: your-token-value" ``` --- ### 2. 查询所有角色 **接口地址**: `GET /coder/sysRole/list` **接口描述**: 查询所有系统角色(不分页) **是否需要认证**: 是 **权限要求**: `system:role:list` **请求参数**: 同分页查询(除pageNo、pageSize外) **响应示例**: ```json { "status": 200, "msg": "SUCCESS", "data": [ { "roleId": 1, "roleName": "超级管理员", "roleCode": "admin", "roleStatus": "0", "dataScope": "1", "deptCheckStrictly": "1", "menuCheckStrictly": "1", "sorted": 1, "remark": "超级管理员", "createBy": "admin", "createTime": "2024-01-01 10:00:00", "updateBy": "admin", "updateTime": "2024-01-01 10:00:00" } ], "traceId": "trace-123456" } ``` **调用示例**: ```bash curl -X GET \ "http://localhost:18099/coder/sysRole/list" \ -H "Authorization: your-token-value" ``` --- ### 3. 根据ID查询角色 **接口地址**: `GET /coder/sysRole/getById/{id}` **接口描述**: 根据角色ID查询角色详细信息 **是否需要认证**: 是 **权限要求**: `system:role:list` **路径参数**: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | id | Long | 是 | 角色ID | **响应示例**: ```json { "status": 200, "msg": "SUCCESS", "data": { "roleId": 1, "roleName": "超级管理员", "roleCode": "admin", "roleStatus": "0", "dataScope": "1", "deptCheckStrictly": "1", "menuCheckStrictly": "1", "sorted": 1, "remark": "超级管理员", "createBy": "admin", "createTime": "2024-01-01 10:00:00", "updateBy": "admin", "updateTime": "2024-01-01 10:00:00", "menuIds": [1, 2, 3, 4, 5], "deptIds": [100, 101, 102] }, "traceId": "trace-123456" } ``` **调用示例**: ```bash curl -X GET \ http://localhost:18099/coder/sysRole/getById/1 \ -H "Authorization: your-token-value" ``` --- ### 4. 新增角色 **接口地址**: `POST /coder/sysRole/add` **接口描述**: 新增系统角色 **是否需要认证**: 是 **权限要求**: `system:role:add` **请求参数**: ```json { "roleName": "普通用户", "roleCode": "user", "roleStatus": "0", "dataScope": "2", "deptCheckStrictly": "1", "menuCheckStrictly": "1", "sorted": 2, "remark": "普通用户角色", "menuIds": [1, 2, 3], "deptIds": [100, 101] } ``` **请求参数说明**: | 参数名 | 类型 | 必填 | 说明 | 校验规则 | |--------|------|------|------|----------| | roleName | String | 是 | 角色名称 | 不能为空,最长30字符 | | roleCode | String | 是 | 角色编码 | 不能为空,最长100字符,唯一 | | roleStatus | String | 是 | 角色状态 | 0-正常 1-停用 | | dataScope | String | 否 | 数据范围 | 1-全部数据 2-自定义数据 3-本部门数据 4-本部门及以下数据 5-仅本人数据 | | deptCheckStrictly | String | 否 | 部门树选择项是否关联显示 | 0-父子不互相关联显示 1-父子互相关联显示 | | menuCheckStrictly | String | 否 | 菜单树选择项是否关联显示 | 0-父子不互相关联显示 1-父子互相关联显示 | | sorted | Integer | 是 | 显示顺序 | 不能为空 | | remark | String | 否 | 备注信息 | 最长200字符 | | menuIds | Long[] | 否 | 菜单ID数组 | 有效的菜单ID | | deptIds | Long[] | 否 | 部门ID数组 | 有效的部门ID | **响应示例**: ```json { "status": 200, "msg": "SUCCESS", "data": "新增成功", "traceId": "trace-123456" } ``` **调用示例**: ```bash curl -X POST \ http://localhost:18099/coder/sysRole/add \ -H "Content-Type: application/json" \ -H "Authorization: your-token-value" \ -d '{ "roleName": "普通用户", "roleCode": "user", "roleStatus": "0", "dataScope": "2", "deptCheckStrictly": "1", "menuCheckStrictly": "1", "sorted": 2, "remark": "普通用户角色", "menuIds": [1, 2, 3], "deptIds": [100, 101] }' ``` --- ### 5. 获取最新排序号 **接口地址**: `GET /coder/sysRole/getSorted` **接口描述**: 获取角色的最新排序号 **是否需要认证**: 是 **权限要求**: `system:role:add` **请求参数**: 无 **响应示例**: ```json { "status": 200, "msg": "SUCCESS", "data": 10, "traceId": "trace-123456" } ``` **调用示例**: ```bash curl -X GET \ http://localhost:18099/coder/sysRole/getSorted \ -H "Authorization: your-token-value" ``` --- ### 6. 修改角色信息 **接口地址**: `POST /coder/sysRole/update` **接口描述**: 修改系统角色信息 **是否需要认证**: 是 **权限要求**: `system:role:edit` **请求参数**: ```json { "roleId": 1, "roleName": "超级管理员", "roleCode": "admin", "roleStatus": "0", "dataScope": "1", "deptCheckStrictly": "1", "menuCheckStrictly": "1", "sorted": 1, "remark": "超级管理员", "menuIds": [1, 2, 3, 4, 5], "deptIds": [100, 101, 102] } ``` **请求参数说明**: | 参数名 | 类型 | 必填 | 说明 | 校验规则 | |--------|------|------|------|----------| | roleId | Long | 是 | 角色ID | 必须是有效的角色ID | | 其他参数 | - | - | 同新增角色 | - | **响应示例**: ```json { "status": 200, "msg": "SUCCESS", "data": "修改成功", "traceId": "trace-123456" } ``` **调用示例**: ```bash curl -X POST \ http://localhost:18099/coder/sysRole/update \ -H "Content-Type: application/json" \ -H "Authorization: your-token-value" \ -d '{ "roleId": 1, "roleName": "超级管理员", "roleCode": "admin", "roleStatus": "0", "sorted": 1 }' ``` --- ### 7. 删除角色 **接口地址**: `POST /coder/sysRole/deleteById/{id}` **接口描述**: 根据ID删除角色 **是否需要认证**: 是 **权限要求**: `system:role:remove` **路径参数**: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | id | Long | 是 | 角色ID | **响应示例**: ```json { "status": 200, "msg": "SUCCESS", "data": "删除成功", "traceId": "trace-123456" } ``` **调用示例**: ```bash curl -X POST \ http://localhost:18099/coder/sysRole/deleteById/1 \ -H "Authorization: your-token-value" ``` --- ### 8. 批量删除角色 **接口地址**: `POST /coder/sysRole/batchDelete` **接口描述**: 批量删除角色 **是否需要认证**: 是 **权限要求**: `system:role:remove` **请求参数**: ```json { "ids": [1, 2, 3] } ``` **请求参数说明**: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | ids | Long[] | 是 | 角色ID数组 | **响应示例**: ```json { "status": 200, "msg": "SUCCESS", "data": "删除成功", "traceId": "trace-123456" } ``` **调用示例**: ```bash curl -X POST \ http://localhost:18099/coder/sysRole/batchDelete \ -H "Content-Type: application/json" \ -H "Authorization: your-token-value" \ -d '{ "ids": [1, 2, 3] }' ``` --- ### 9. 修改角色状态 **接口地址**: `POST /coder/sysRole/updateStatus/{roleId}/{roleStatus}` **接口描述**: 修改角色状态(正常/停用) **是否需要认证**: 是 **权限要求**: `system:role:edit` **路径参数**: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | roleId | Long | 是 | 角色ID | | roleStatus | String | 是 | 角色状态(0-正常 1-停用) | **响应示例**: ```json { "status": 200, "msg": "SUCCESS", "data": "修改成功", "traceId": "trace-123456" } ``` **调用示例**: ```bash curl -X POST \ http://localhost:18099/coder/sysRole/updateStatus/1/0 \ -H "Authorization: your-token-value" ``` --- ### 10. 查询正常角色穿梭框 **接口地址**: `GET /coder/sysRole/listNormalRole/{userId}` **接口描述**: 查询正常状态的角色用于穿梭框显示 **是否需要认证**: 是 **权限要求**: `system:user:role` **路径参数**: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | userId | Long | 是 | 用户ID | **响应示例**: ```json { "status": 200, "msg": "SUCCESS", "data": [ { "label": "超级管理员", "value": 1, "parentId": "" }, { "label": "普通用户", "value": 2, "parentId": "" } ], "traceId": "trace-123456" } ``` **调用示例**: ```bash curl -X GET \ http://localhost:18099/coder/sysRole/listNormalRole/1 \ -H "Authorization: your-token-value" ``` --- ### 11. 分配用户角色 **接口地址**: `GET /coder/sysRole/assignUserRole/{userId}/{roleIds}` **接口描述**: 为用户分配角色 **是否需要认证**: 是 **权限要求**: `system:user:role` **路径参数**: | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | userId | Long | 是 | 用户ID | | roleIds | String | 是 | 角色ID列表(逗号分隔) | **响应示例**: ```json { "status": 200, "msg": "SUCCESS", "data": "分配成功", "traceId": "trace-123456" } ``` **调用示例**: ```bash curl -X GET \ http://localhost:18099/coder/sysRole/assignUserRole/1/1,2,3 \ -H "Authorization: your-token-value" ``` --- ### 12. 获取角色下拉框 **接口地址**: `GET /coder/sysRole/listRoleElSelect` **接口描述**: 获取角色下拉框数据 **是否需要认证**: 是 **权限要求**: `system:role:list` **请求参数**: 无 **响应示例**: ```json { "status": 200, "msg": "SUCCESS", "data": [ { "label": "超级管理员", "value": 1 }, { "label": "普通用户", "value": 2 } ], "traceId": "trace-123456" } ``` **调用示例**: ```bash curl -X GET \ http://localhost:18099/coder/sysRole/listRoleElSelect \ -H "Authorization: your-token-value" ``` --- ## 角色字段说明 ### 基础字段 | 字段名 | 类型 | 说明 | 示例 | |--------|------|------|------| | roleId | Long | 角色ID | 1 | | roleName | String | 角色名称 | 超级管理员 | | roleCode | String | 角色编码 | admin | | roleStatus | String | 角色状态 | 0-正常 1-停用 | | sorted | Integer | 显示顺序 | 1 | | remark | String | 备注信息 | 超级管理员 | ### 权限字段 | 字段名 | 类型 | 说明 | 示例 | |--------|------|------|------| | dataScope | String | 数据权限范围 | 1-全部数据 2-自定义数据 3-本部门数据 4-本部门及以下数据 5-仅本人数据 | | deptCheckStrictly | String | 部门树选择项是否关联显示 | 0-父子不互相关联显示 1-父子互相关联显示 | | menuCheckStrictly | String | 菜单树选择项是否关联显示 | 0-父子不互相关联显示 1-父子互相关联显示 | ### 关联字段 | 字段名 | 类型 | 说明 | 示例 | |--------|------|------|------| | menuIds | Long[] | 菜单ID数组 | [1, 2, 3, 4, 5] | | deptIds | Long[] | 部门ID数组 | [100, 101, 102] | --- ## 数据字典 ### 角色状态 (roleStatus) | 值 | 说明 | |----|------| | 0 | 正常 | | 1 | 停用 | ### 数据权限范围 (dataScope) | 值 | 说明 | |----|------| | 1 | 全部数据权限 | | 2 | 自定数据权限 | | 3 | 本部门数据权限 | | 4 | 本部门及以下数据权限 | | 5 | 仅本人数据权限 | ### 树选择项关联显示 | 值 | 说明 | |----|------| | 0 | 父子不互相关联显示 | | 1 | 父子互相关联显示 | --- ## 权限验证机制 ### 1. 角色权限验证 ```java // Sa-Token权限验证 @SaCheckPermission("system:role:list") public List list() { // 业务逻辑 } ``` ### 2. 数据权限控制 ```java // 根据用户数据权限过滤数据 public List getRolesByDataScope(Long userId) { SysUser user = getCurrentUser(); String dataScope = user.getDataScope(); switch (dataScope) { case "1": // 全部数据权限 return getAllRoles(); case "2": // 自定义数据权限 return getRolesByDeptIds(user.getDeptIds()); case "3": // 本部门数据权限 return getRolesByDept(user.getDeptId()); case "4": // 本部门及以下数据权限 return getRolesByDeptAndChildren(user.getDeptId()); case "5": // 仅本人数据权限 return getRolesByUserId(userId); default: return new ArrayList<>(); } } ``` ### 3. 角色权限缓存 ```java // 缓存用户角色权限 @Cacheable(value = "userRoles", key = "#userId") public List getRolesByUserId(Long userId) { return roleMapper.selectRolePermissionByUserId(userId); } // 清除角色权限缓存 @CacheEvict(value = "userRoles", key = "#userId") public void clearUserRoleCache(Long userId) { // 角色变更时清除缓存 } ``` --- ## 错误码说明 | 错误码 | 错误信息 | 说明 | |--------|----------|------| | 400 | 角色名称不能为空 | 角色名称为空 | | 400 | 角色权限编码不能为空 | 角色编码为空 | | 400 | 显示顺序不能为空 | 排序值为空 | | 400 | 角色不存在 | 角色ID不存在 | | 400 | 角色编码已存在 | 角色编码重复 | | 400 | 角色已分配用户,不允许删除 | 角色已分配给用户时不能删除 | | 400 | 不能删除超级管理员角色 | 超级管理员角色不能删除 | | 400 | 不能停用超级管理员角色 | 超级管理员角色不能停用 | | 400 | 用户不存在 | 用户ID不存在 | | 400 | 角色ID列表不能为空 | 分配角色时角色ID为空 | | 401 | 当前会话未登录 | 未登录或Token无效 | | 403 | 权限不足 | 没有相应的操作权限 | | 500 | 系统异常 | 服务器内部错误 | --- ## RBAC权限模型 ### 1. 基本概念 - **用户 (User)**: 系统的使用者 - **角色 (Role)**: 权限的集合,连接用户和权限的桥梁 - **权限 (Permission)**: 对系统资源的操作权限 - **会话 (Session)**: 用户与系统的一次交互过程 ### 2. 关系模型 ``` 用户 ←→ 用户角色关系 ←→ 角色 ←→ 角色权限关系 ←→ 权限 ``` ### 3. 数据库设计 ```sql -- 用户表 CREATE TABLE sys_login_user ( user_id BIGINT PRIMARY KEY, login_name VARCHAR(32) UNIQUE NOT NULL, user_name VARCHAR(32) NOT NULL, -- 其他字段... ); -- 角色表 CREATE TABLE sys_role ( role_id BIGINT PRIMARY KEY, role_name VARCHAR(32) NOT NULL, role_code VARCHAR(32) UNIQUE NOT NULL, role_status CHAR(1) DEFAULT '0', -- 其他字段... ); -- 权限表(菜单表) CREATE TABLE sys_menu ( menu_id BIGINT PRIMARY KEY, menu_name VARCHAR(64) NOT NULL, auth VARCHAR(128), -- 其他字段... ); -- 用户角色关联表 CREATE TABLE sys_user_role ( user_id BIGINT NOT NULL, role_id BIGINT NOT NULL, PRIMARY KEY (user_id, role_id) ); -- 角色权限关联表 CREATE TABLE sys_role_menu ( role_id BIGINT NOT NULL, menu_id BIGINT NOT NULL, PRIMARY KEY (role_id, menu_id) ); ``` --- ## 使用建议 ### 1. 角色设计原则 - **最小权限原则**: 每个角色只分配必要的权限 - **职责分离**: 不同职责的操作分配给不同角色 - **角色层次**: 建立角色层次结构,高级角色继承低级角色权限 - **定期审查**: 定期审查角色权限,及时调整 ### 2. 权限分配策略 - **默认无权限**: 新建角色默认无任何权限 - **逐步授权**: 根据业务需要逐步授权 - **权限组合**: 通过多个角色组合实现复杂权限需求 - **临时授权**: 支持临时权限授权机制 ### 3. 数据权限控制 - **部门数据权限**: 基于用户所属部门控制数据访问范围 - **自定义数据权限**: 支持自定义数据访问范围 - **数据隔离**: 确保不同用户只能访问授权范围内的数据 - **审计日志**: 记录数据访问日志 ### 4. 性能优化 - **权限缓存**: 将用户权限信息缓存到Redis - **批量操作**: 支持批量分配和撤销权限 - **索引优化**: 对关联表建立合适的索引 - **分页查询**: 大数据量时使用分页查询 --- ## 安全考虑 ### 1. 权限验证 - **双重验证**: 前后端都要进行权限验证 - **接口鉴权**: 每个接口都要验证权限 - **数据鉴权**: 数据层面的权限验证 - **操作鉴权**: 敏感操作的二次验证 ### 2. 权限变更 - **变更日志**: 记录所有权限变更操作 - **审批流程**: 重要权限变更需要审批 - **通知机制**: 权限变更及时通知相关人员 - **回滚机制**: 支持权限变更回滚 ### 3. 会话安全 - **会话超时**: 设置会话超时时间 - **单点登录**: 防止重复登录 - **强制下线**: 支持强制用户下线 - **设备绑定**: 支持设备级别的访问控制 --- ## 注意事项 1. **角色删除**: 删除角色前需要检查是否有用户关联 2. **权限继承**: 考虑角色之间的权限继承关系 3. **缓存一致性**: 角色权限变更后需要清理相关缓存 4. **数据完整性**: 保证角色权限数据的完整性 5. **超级管理员**: 超级管理员角色不能删除和停用 6. **权限验证**: 前后端都需要进行权限验证 7. **审计日志**: 记录所有角色操作日志 8. **性能考虑**: 大量用户时注意权限验证性能 9. **数据权限**: 正确配置数据权限范围 10. **定期清理**: 定期清理无效的角色和权限关联