Skip to content

角色权限管理 PRD

文档信息

项目内容
产品名称PMForge - 角色权限管理
文档版本v2.0
创建日期2026-09-13
最后更新2026-09-24
文档状态评审中
优先级P0

一、功能概述

1.1 功能定位

角色权限管理是 PMForge 平台安全体系的"门禁中枢"——就像一栋写字楼的门禁系统:角色是"门禁卡类型"(如高管卡、员工卡、访客卡),菜单权限决定"能进哪些房间",数据权限决定"能看到哪些楼层的文件"。

本模块基于 RBAC(基于角色的访问控制) 模型,通过"用户 → 角色 → 权限"的间接绑定方式,实现两大核心能力:

  • 功能权限:控制用户"能做什么"——能看到哪些菜单、能点哪些按钮、能调哪些接口
  • 数据权限:控制用户"能看什么数据"——全部数据、本部门数据、还是仅自己的数据

为什么不直接把权限分配给用户?因为人员会流动、岗位会调整。如果每个人单独配权限,100 人的团队就要配 100 次。有了"角色"这层中间层,只需要给"项目经理"这个角色配一次权限,然后把张三调到项目经理岗位——把"项目经理"角色分配给张三即可。

1.2 目标用户

用户类型使用场景核心诉求
超级管理员配置系统全部角色、菜单、权限策略搭建和维护整个权限体系
租户管理员在租户套餐范围内配置角色与权限在自己购买的"功能菜单"内灵活配置
部门管理员在权限范围内进行角色成员的查看与管理了解本部门人员权限情况
普通用户通过角色间接享有权限,无需直接操作本模块登录后只看到自己该看的功能和数据

1.3 业务价值

价值维度说明
🔐 精细化管控菜单权限精确到按钮级别,数据权限精确到部门级别
🧩 灵活扩展新增功能只需添加菜单项,分配给对应角色即可生效
🏢 多租户适配通过租户套餐控制每个租户可用的功能范围,防止越权
📊 审计合规完整的权限分配记录,满足安全审计要求
⚡ 即时生效权限变更后缓存即时刷新,无需用户重新登录

1.4 功能范围

功能分类后台管理端前台用户端
角色管理(CRUD)
角色状态管理
菜单管理(树形CRUD)
菜单权限分配
数据权限配置
角色成员管理
用户角色分配
角色导出
动态路由加载
按钮级权限控制

1.5 权限标识规划

权限标识说明
system:role:create创建角色
system:role:update修改角色
system:role:delete删除角色
system:role:query查询角色
system:role:export导出角色
system:menu:create创建菜单
system:menu:update修改菜单
system:menu:delete删除菜单
system:menu:query查询菜单
system:permission:assign-role-menu分配角色菜单权限
system:permission:assign-role-data-scope分配角色数据权限
system:permission:assign-user-role分配用户角色

二、用户场景

2.1 用户角色

角色描述核心诉求
超级管理员系统最高权限,不受任何权限限制搭建和维护整个权限体系
租户管理员租户内最高权限,受套餐约束在已购功能范围内灵活配置权限
权限管理员被赋予权限管理权限的角色日常维护角色与菜单权限分配
普通用户系统使用者登录后只看到自己该用的功能,无感知使用

2.2 使用场景

场景1:新项目启动——搭建权限体系

  • 用户:超级管理员老李
  • 场景:公司新启动一个"智慧城市"项目 → 老李需要在系统中为这个项目搭建权限体系 → 进入角色管理 → 创建"项目经理""技术负责人""开发人员""测试人员"等角色 → 分别为每个角色分配菜单权限(如项目经理可看项目看板、任务管理、团队管理;开发人员只能看任务管理、代码仓库) → 为项目经理设置数据权限为"本部门及子部门" → 为开发人员设置数据权限为"仅本人"
  • 期望:一次性完成角色创建和权限配置,后续只需把人员分配到对应角色即可
  • 异常处理:如果创建角色时名称重复,系统提示"角色名称已存在";如果角色标识(code)重复,提示"角色标识已存在"

场景2:系统升级——新增功能模块的权限适配

  • 用户:权限管理员小王
  • 场景:系统新增了"AI 助手"模块 → 小王需要让项目经理角色也能使用这个新功能 → 进入菜单管理 → 在菜单树中找到"AI 助手"目录 → 进入角色管理 → 选择"项目经理"角色 → 点击"分配菜单权限" → 在弹出的菜单树中勾选"AI 助手"及其子菜单 → 保存
  • 期望:菜单权限以树形结构展示,支持展开/折叠和全选/反选,操作直观
  • 异常处理:如果租户套餐未包含"AI 助手"模块,菜单树中不会显示该模块——需要先联系超级管理员扩展套餐

场景3:财务人员需要看全公司数据

  • 用户:超级管理员老李
  • 场景:财务部门的小赵需要做全公司的成本核算 → 但小赵的角色数据权限默认是"仅本人" → 老李进入角色管理 → 选择"财务专员"角色 → 点击"分配数据权限" → 将数据范围改为"全部数据权限" → 保存
  • 期望:数据权限支持多种粒度选择,"指定部门"模式下可以用树形勾选具体部门
  • 异常处理:如果选择了"指定部门"但没有勾选任何部门,系统提示"请至少选择一个部门"

场景4:员工调岗——角色调整

  • 用户:权限管理员小王
  • 场景:开发人员小张要调岗到产品部门 → 小王进入角色成员管理 → 找到小张 → 移除"开发人员"角色 → 分配"产品经理"角色 → 保存
  • 期望:可以看到小张当前有哪些角色,快速调整;调整后小张的权限即时变更
  • 异常处理:如果试图移除小张正在使用的最后一个角色,系统提示"该用户至少需要保留一个角色"

场景5:临时项目结束——禁用角色

  • 用户:超级管理员老李
  • 场景:"智慧城市"一期项目结束 → 老李禁用该项目对应的临时角色"一期开发组" → 该角色下所有开发人员不再享有对应权限
  • 期望:禁用即时生效,不影响这些用户的其他角色权限
  • 异常处理:如果试图禁用自己正在使用的角色,系统提示"不能禁用当前登录用户正在使用的角色"

场景6:新员工入职——分配角色

  • 用户:部门经理陈姐
  • 场景:团队新入职 3 名开发 → 陈姐在用户管理中创建用户 → 为每人分配"开发人员"角色 → 3 人登录后自动获得任务管理、代码仓库等菜单权限,数据权限为"仅本人"
  • 期望:角色分配后新用户登录即可看到正确的菜单和数据,无需额外配置

场景7:权限审计——导出角色清单

  • 用户:超级管理员老李
  • 场景:年底安全审计 → 老李进入角色管理 → 点击"导出" → 下载角色清单 Excel → 包含每个角色的名称、标识、状态、数据范围、备注 → 配合角色成员列表一起提交给安全审计部门
  • 期望:导出的 Excel 字段完整、状态和数据范围用中文显示(而非数字编码)

2.3 用户故事

编号用户故事优先级验收标准
US-01作为管理员,我希望能创建和管理角色,以便为不同岗位配置不同权限P0① 创建角色后可在列表中看到 ② 角色标识全局唯一,重复时提示错误 ③ 内置角色不可删除、标识不可修改
US-02作为管理员,我希望能以树形结构管理菜单,以便维护系统功能入口P0① 菜单以树形表格展示,支持展开/折叠 ② 目录、菜单、按钮三种类型各有对应字段 ③ 有子菜单的父级不可直接删除
US-03作为管理员,我希望能给角色分配菜单权限,以便控制角色可见功能P0① 菜单树以复选框形式展示 ② 支持全选/反选/展开/折叠 ③ 保存后该角色用户即时看到变化
US-04作为管理员,我希望能给角色配置数据权限,以便控制角色可见数据范围P0① 5 种数据范围可选 ② 选择"指定部门"时展示部门树 ③ 保存后列表数据过滤即时生效
US-05作为管理员,我希望能查看角色下的成员列表,以便了解角色分配情况P0① 点击"查看成员"展示该角色下所有用户 ② 显示用户名、昵称、部门、手机号等信息
US-06作为管理员,我希望能给用户分配/移除角色,以便管理用户权限P0① 可查看用户已有角色 ② 新增/移除后权限缓存即时刷新 ③ 不能移除超管的超管角色
US-07作为管理员,我希望能启用/禁用角色,以便快速控制一组权限的生效状态P0① 禁用后该角色用户立即失去对应权限 ② 不能禁用自己正在使用的角色
US-08作为管理员,我希望能导出角色列表,以便进行权限审计P1① 导出 Excel 包含完整字段 ② 状态和数据范围翻译为中文
US-09作为管理员,我希望能批量删除角色/菜单,以便提升管理效率P1① 支持勾选多条批量删除 ② 内置角色不在可选范围内 ③ 删除前弹出二次确认
US-10作为用户,我希望登录后动态加载我有权限的菜单,以便只看到我能使用的功能P0① 登录后 300ms 内返回菜单树 ② 侧边栏只展示有权限的菜单 ③ 无权限的按钮不渲染

三、功能需求

3.1 后台管理端

3.1.1 功能清单

功能优先级说明
角色列表P0分页展示角色,支持搜索筛选
新增角色P0创建自定义角色
编辑角色P0修改角色基本信息
删除角色P0删除角色(单个)
批量删除角色P1批量删除多个角色
角色状态切换P0启用/禁用角色
角色导出P1导出角色数据Excel
角色精简列表P0获取已启用角色列表(用于下拉选择)
菜单列表P0树形展示菜单列表
新增菜单P0创建目录/菜单/按钮
编辑菜单P0修改菜单信息
删除菜单P0删除菜单(单个)
批量删除菜单P1批量删除多个菜单
菜单精简列表P0获取已启用菜单列表(用于权限分配)
分配角色菜单权限P0为角色勾选菜单权限
查看角色菜单权限P0查看角色已拥有的菜单权限
分配角色数据权限P0为角色配置数据范围
查看用户角色P0查看用户已分配的角色
分配用户角色P0为用户分配角色

3.1.2 角色列表

页面描述:

角色列表页面线框图

业务规则:

规则编号规则描述为什么这样设计
R-01默认按排序值升序排列,排序相同按创建时间倒序常用角色排在前面,方便查找
R-02支持按角色名称模糊搜索角色名是管理员最熟悉的查找方式
R-03支持按角色标识模糊搜索开发人员可能更习惯用标识查找
R-04支持按状态筛选(启用/禁用)快速定位禁用角色
R-05支持按创建时间范围筛选审计场景需要查找某段时间创建的角色
R-06内置角色(type=1)不可删除、不可修改标识系统基础角色是权限体系的根基,不能被破坏
R-07租户管理员只能管理本租户下的角色租户间数据隔离的基本要求
R-08不能删除当前登录用户正在使用的角色防止管理员误操作导致自己失去权限
R-09角色标识(code)全局唯一权限标识依赖角色标识的唯一性
R-10角色名称长度不超过30个字符数据库字段约束 + 界面展示友好

数据字段:

字段名类型说明
idLong角色编号
nameString角色名称
codeString角色标识
sortInteger显示顺序
statusInteger状态(0-启用 1-禁用)
typeInteger角色类型(1-内置角色 2-自定义角色)
remarkString备注
dataScopeInteger数据范围(1-全部 2-指定部门 3-本部门 4-本部门及子部门 5-仅本人)
dataScopeDeptIdsLong[]数据范围-指定部门ID列表(仅dataScope=2时有效)
createTimeDateTime创建时间

接口设计:

接口名称请求方式接口路径说明
获取角色分页GET/admin-api/system/role/page获取角色分页列表
获取角色详情GET/admin-api/system/role/get获取角色详细信息
获取角色精简列表GET/admin-api/system/role/simple-list获取已启用角色列表(用于下拉选择)

请求参数(分页查询):

参数名类型必填说明
nameString角色名称(模糊匹配)
codeString角色标识(模糊匹配)
statusInteger状态(0-启用 1-禁用)
createTimeDateTime[]创建时间范围
pageNoInteger页码
pageSizeInteger每页条数

返回结果(分页):

字段名类型说明
listRole[]角色列表
totalLong总记录数

返回结果(角色详情):

字段名类型说明
idLong角色编号
nameString角色名称
codeString角色标识
sortInteger显示顺序
statusInteger状态
typeInteger角色类型
remarkString备注
dataScopeInteger数据范围
dataScopeDeptIdsLong[]指定部门ID列表
createTimeDateTime创建时间

3.1.3 新增角色

页面描述:

新增角色对话框

表单字段:

字段类型必填说明
角色名称输入框最多30个字符
角色标识输入框最多100个字符,全局唯一,如 PROJECT_MANAGER
显示顺序数字输入用于排序
状态开关启用/禁用,默认启用
备注文本域最多500个字符

业务规则:

规则编号规则描述为什么这样设计
R-01角色标识全局唯一,创建后不可修改角色标识是权限体系的关键引用,修改会导致历史数据不一致
R-02角色名称不可重复避免管理员混淆相似角色
R-03角色类型默认为自定义角色(type=2)内置角色由系统预置,手动创建的都是自定义角色
R-04数据范围默认为"仅本人数据权限"(dataScope=5)最小权限原则——新建角色默认给最小范围,需要时再扩大
R-05创建成功后需手动分配菜单权限和数据权限角色创建只是第一步,权限分配是独立操作,避免误操作

接口设计:

接口名称请求方式接口路径说明
创建角色POST/admin-api/system/role/create创建新角色

请求参数:

参数名类型必填说明
nameString角色名称,最多30字符
codeString角色标识,最多100字符
sortInteger显示顺序
statusInteger状态(0-启用 1-禁用)
remarkString备注,最多500字符

返回结果:

字段名类型说明
dataLong新创建的角色ID

3.1.4 编辑角色

页面描述:

  • 弹窗/抽屉形式,预填现有数据
  • 内置角色的标识(code)不可修改(置灰显示)

接口设计:

接口名称请求方式接口路径说明
更新角色PUT/admin-api/system/role/update更新角色信息

请求参数:

参数名类型必填说明
idLong角色编号
nameString角色名称
codeString角色标识
sortInteger显示顺序
statusInteger状态
remarkString备注

3.1.5 删除角色

业务规则:

规则编号规则描述为什么这样设计
R-01逻辑删除,不物理删除保留历史数据,便于审计追溯
R-02内置角色(type=1)不可删除系统基础角色不可破坏
R-03已分配给用户的角色删除前需二次确认防止误删导致大量用户权限丢失
R-04删除角色时同步清理角色-菜单关联、角色-用户关联避免产生"孤儿"关联数据
R-05删除后相关用户的权限缓存即时刷新确保权限变更实时生效

接口设计:

接口名称请求方式接口路径说明
删除角色DELETE/admin-api/system/role/delete删除单个角色
批量删除角色DELETE/admin-api/system/role/delete-list批量删除角色

请求参数(删除单个):

参数名类型必填说明
idLong角色编号

请求参数(批量删除):

参数名类型必填说明
idsLong[]角色编号列表

3.1.6 角色状态切换

业务规则:

规则编号规则描述为什么这样设计
R-01禁用后该角色下所有用户不再享有该角色的权限禁用角色的本质就是"冻结"这组权限
R-02禁用后权限缓存即时刷新确保变更实时生效
R-03不能禁用当前登录用户自身正在使用的角色防止管理员"锁住自己"
R-04精简列表接口仅返回启用状态的角色分配角色时不应出现已禁用的角色

接口设计:

接口名称请求方式接口路径说明
更新角色状态PUT/admin-api/system/role/update通过更新接口修改status字段实现

请求参数:

参数名类型必填说明
idLong角色编号
statusInteger状态(0-启用 1-禁用)

3.1.7 角色导出

页面描述:

  • 支持导出当前筛选条件下的所有角色
  • 导出字段:角色序号、角色名称、角色标志、角色排序、角色状态、数据范围、备注

业务规则:

规则编号规则描述
R-01导出格式为 xls
R-02导出当前筛选条件下的所有数据(不分页)
R-03状态和数据范围字段使用字典翻译后导出

接口设计:

接口名称请求方式接口路径说明
导出角色ExcelGET/admin-api/system/role/export-excel导出角色数据

请求参数:

参数名类型必填说明
nameString角色名称筛选
codeString角色标识筛选
statusInteger状态筛选
createTimeDateTime[]创建时间范围

3.1.8 菜单列表

页面描述:

菜单管理树形表格页面

  • 采用树形表格展示(非分页)
  • 支持按菜单名称、状态搜索筛选
  • 操作列:编辑、新增子菜单、删除
  • 展示字段:菜单名称、图标、排序、权限标识、组件路径、状态、创建时间

业务规则:

规则编号规则描述为什么这样设计
R-01菜单不分页,全量返回树形结构菜单总量通常不超过几百条,树形展示更直观
R-02按排序值升序排列管理员可自定义展示顺序
R-03菜单为多租户共享资源(不随租户隔离),但受租户套餐约束菜单定义是系统级资源,但每个租户只能用已购买的功能
R-04根节点的父ID为0统一根节点标识,简化树形结构处理
R-05支持按名称模糊搜索(搜索时保留父级链路)搜索子菜单时需要看到它的父级目录,否则找不到位置
R-06支持按状态筛选快速定位禁用菜单

数据字段:

字段名类型说明
idLong菜单编号
nameString菜单名称
permissionString权限标识(如 system:role:create)
typeInteger菜单类型(1-目录 2-菜单 3-按钮)
sortInteger显示顺序
parentIdLong父菜单ID(0为根节点)
pathString路由地址
iconString菜单图标
componentString组件路径
componentNameString组件名称
statusInteger状态(0-启用 1-禁用)
visibleBoolean是否可见(侧边栏是否展示)
keepAliveBoolean是否缓存(Vue keep-alive)
alwaysShowBoolean是否总是显示
createTimeDateTime创建时间

接口设计:

接口名称请求方式接口路径说明
获取菜单列表GET/admin-api/system/menu/list获取菜单树形列表(用于菜单管理页面)
获取菜单详情GET/admin-api/system/menu/get获取菜单详细信息
获取菜单精简列表GET/admin-api/system/menu/simple-list获取已启用菜单列表(用于角色分配菜单权限时的树形选项)

请求参数(菜单列表查询):

参数名类型必填说明
nameString菜单名称(模糊匹配)
statusInteger状态

3.1.9 新增菜单

页面描述:

新增菜单对话框

说明:
- 选择"菜单"类型时,额外显示:组件路径、组件名称
- 选择"按钮"类型时,只显示:名称、权限标识、排序、状态
  • 根据菜单类型(目录/菜单/按钮)动态展示不同字段

表单字段:

字段类型必填说明
菜单类型单选目录(1) / 菜单(2) / 按钮(3)
上级菜单树形选择选择父级菜单,默认根节点
菜单名称输入框最多50个字符
菜单图标图标选择器仅目录/菜单需要
路由地址输入框仅目录/菜单需要,最多200字符,支持外链(http)
组件路径输入框仅菜单类型需要,最多200字符
组件名称输入框用于keep-alive缓存,需与组件文件名一致
权限标识输入框仅按钮类型需要,格式如 system:role:create
显示排序数字输入控制显示顺序
状态开关启用/禁用
是否可见开关仅目录/菜单有效,控制侧边栏是否展示
是否缓存开关仅目录/菜单有效,使用Vue keep-alive
是否总是显示开关仅目录/菜单有效,为false时只有一个子菜单则直接展示子菜单

业务规则:

规则编号规则描述为什么这样设计
R-01菜单名称最多50个字符侧边栏空间有限,过长影响展示
R-02权限标识格式规范:${系统}😒{模块}😒统一命名规范,便于管理和查找
R-03权限标识最多100个字符,建议全局唯一避免不同模块的按钮权限冲突
R-04路由地址为http(s)开头时作为外链处理支持在系统内嵌入外部链接
R-05开启缓存时必须填写组件名称keep-alive 依赖组件名称来匹配缓存
R-06菜单资源为全局共享,所有租户可见(但受套餐控制)菜单定义一次,通过套餐控制各租户的可见范围
R-07根节点父ID为0统一约定

接口设计:

接口名称请求方式接口路径说明
创建菜单POST/admin-api/system/menu/create创建新菜单

请求参数:

参数名类型必填说明
nameString菜单名称,最多50字符
permissionString权限标识,最多100字符(按钮类型必填)
typeInteger菜单类型(1-目录 2-菜单 3-按钮)
sortInteger显示顺序
parentIdLong父菜单ID(0为根节点)
pathString路由地址,最多200字符
iconString菜单图标
componentString组件路径,最多200字符
componentNameString组件名称
statusInteger状态(0-启用 1-禁用)
visibleBoolean是否可见
keepAliveBoolean是否缓存
alwaysShowBoolean是否总是显示

返回结果:

字段名类型说明
dataLong新创建的菜单ID

3.1.10 编辑菜单

页面描述:

  • 弹窗/抽屉形式,预填现有数据
  • 不可修改菜单类型(type)

为什么类型不可修改? 因为不同类型的菜单关联的子节点不同——如果把"目录"改成"按钮",它下面的子菜单就无处安放。

接口设计:

接口名称请求方式接口路径说明
更新菜单PUT/admin-api/system/menu/update更新菜单信息

请求参数:

参数名类型必填说明
idLong菜单编号
nameString菜单名称
permissionString权限标识
typeInteger菜单类型
sortInteger显示顺序
parentIdLong父菜单ID
pathString路由地址
iconString菜单图标
componentString组件路径
componentNameString组件名称
statusInteger状态
visibleBoolean是否可见
keepAliveBoolean是否缓存
alwaysShowBoolean是否总是显示

3.1.11 删除菜单

业务规则:

规则编号规则描述为什么这样设计
R-01逻辑删除,不物理删除保留历史数据用于审计
R-02存在子菜单的父级菜单不可删除,需先删除子菜单防止产生"悬空"子节点
R-03已分配给角色的菜单删除前需二次确认避免影响多个角色的权限
R-04删除菜单时同步清理角色-菜单关联避免产生无效关联数据
R-05删除后相关权限缓存即时刷新确保变更实时生效

接口设计:

接口名称请求方式接口路径说明
删除菜单DELETE/admin-api/system/menu/delete删除单个菜单
批量删除菜单DELETE/admin-api/system/menu/delete-list批量删除菜单

请求参数(删除单个):

参数名类型必填说明
idLong菜单编号

请求参数(批量删除):

参数名类型必填说明
idsLong[]菜单编号列表

3.1.12 分配角色菜单权限

页面描述:

分配菜单权限对话框

  • 在角色列表中点击"分配菜单权限"按钮
  • 弹窗展示菜单树(复选框形式)
  • 支持全选/反选/展开/折叠
  • 已勾选的菜单为当前角色已有的菜单权限
  • 支持父子联动(勾选父节点自动全选子节点)

业务规则:

规则编号规则描述为什么这样设计
R-01仅展示启用状态的菜单禁用的菜单不应该被分配
R-02多租户场景下,仅展示该租户套餐内包含的菜单防止租户分配到自己未购买的功能
R-03保存时采用全量覆盖模式(先清空再写入)简化逻辑,避免增量更新的复杂性
R-04按钮类型菜单需关联其所属的菜单/目录权限按钮必须依附于某个页面才有意义
R-05保存后即时刷新该角色下用户的权限缓存确保变更实时生效

接口设计:

接口名称请求方式接口路径说明
获取角色菜单编号列表GET/admin-api/system/permission/list-role-menus获取角色已有的菜单ID集合
分配角色菜单权限POST/admin-api/system/permission/assign-role-menu为角色分配菜单权限

请求参数(获取角色菜单):

参数名类型必填说明
roleIdLong角色编号

返回结果(获取角色菜单):

字段名类型说明
dataLong[]角色拥有的菜单ID集合

请求参数(分配角色菜单):

参数名类型必填说明
roleIdLong角色编号
menuIdsLong[]菜单ID集合(全量)

3.1.13 分配角色数据权限

页面描述:

分配数据权限对话框

数据范围选项:

选项说明适用场景举例
全部数据权限1可查看系统所有数据超级管理员、高层管理者
指定部门数据权限2仅可查看指定部门的数据财务需要看多个部门的数据
本部门数据权限3仅可查看所属部门的数据部门经理只看本部门
本部门及以下数据权限4可查看所属部门及所有子部门的数据总监看整个事业部
仅本人数据权限5仅可查看自己创建/负责的数据普通员工只看自己的

业务规则:

规则编号规则描述为什么这样设计
R-01数据范围为"指定部门"时,必须选择至少一个部门选了"指定部门"却不指定部门等于没有数据权限
R-02保存后即时刷新该角色下用户的数据权限缓存确保数据过滤即时生效
R-03超级管理员默认为"全部数据权限"且不可修改超管需要管理全系统,数据范围不应受限
R-04数据权限影响列表类接口的数据过滤这是数据权限的核心作用——在 SQL 查询时自动拼接过滤条件

接口设计:

接口名称请求方式接口路径说明
分配角色数据权限POST/admin-api/system/permission/assign-role-data-scope为角色配置数据权限范围

请求参数:

参数名类型必填说明
roleIdLong角色编号
dataScopeInteger数据范围(1-全部 2-指定部门 3-本部门 4-本部门及子部门 5-仅本人)
dataScopeDeptIdsLong[]部门ID列表(仅dataScope=2时必填)

3.1.14 角色成员管理

页面描述:

角色成员对话框

  • 在角色列表中点击"查看成员"按钮
  • 弹窗/抽屉展示该角色下的用户列表
  • 支持为用户新增角色(分配)
  • 支持移除用户的该角色

数据字段:

字段名类型说明
userIdLong用户编号
usernameString用户名
nicknameString昵称
deptNameString部门名称
mobileString手机号
statusInteger用户状态
createTimeDateTime加入时间

业务规则:

规则编号规则描述为什么这样设计
R-01一个用户可拥有多个角色一个人可能身兼多职(如既是开发又是测试)
R-02移除角色后该用户的权限缓存即时刷新确保权限变更实时生效
R-03不可移除超级管理员的超级管理员角色防止系统失去最高管理权限

接口设计:

接口名称请求方式接口路径说明
获取用户角色列表GET/admin-api/system/permission/list-user-roles获取用户已分配的角色ID集合
分配用户角色POST/admin-api/system/permission/assign-user-role为用户分配角色(全量覆盖)

请求参数(获取用户角色):

参数名类型必填说明
userIdLong用户编号

返回结果(获取用户角色):

字段名类型说明
dataLong[]用户拥有的角色ID集合

请求参数(分配用户角色):

参数名类型必填说明
userIdLong用户编号
roleIdsLong[]角色ID集合(全量)

3.2 前台用户端(登录态)

3.2.1 功能清单

功能优先级说明
获取路由菜单P0登录后获取当前用户有权限的菜单树,用于动态生成路由
获取权限标识列表P0获取当前用户的权限标识集合,用于按钮级权限控制
按钮级权限控制P0根据权限标识控制按钮/操作的显隐

3.2.2 获取路由菜单

页面描述:

  • 用户登录后自动请求
  • 后端根据用户角色查询关联的菜单列表
  • 过滤掉按钮类型菜单和禁用菜单
  • 组装为树形结构返回
  • 前端根据返回数据动态生成路由和侧边栏导航

接口设计:

接口名称请求方式接口路径说明
获取路由菜单GET/admin-api/system/auth/get-permission-info获取当前用户的路由菜单和权限信息

返回结果:

字段名类型说明
menusMenuTree[]菜单树(仅目录和菜单类型,排除按钮)
permissionsString[]权限标识列表(如 ["system:role:create", "system:role:query"])

菜单树节点字段:

字段名类型说明
idLong菜单编号
nameString菜单名称
parentIdLong父菜单ID
pathString路由地址
iconString菜单图标
componentString组件路径
componentNameString组件名称
sortInteger显示顺序
visibleBoolean是否可见
keepAliveBoolean是否缓存
alwaysShowBoolean是否总是显示

3.2.3 按钮级权限控制

实现方案:

  • 前端获取权限标识列表后存储到全局状态(如 Pinia)
  • 页面中使用自定义指令(如 v-hasPermission)控制按钮的显隐
  • 示例:v-hasPermission="'system:role:create'"
  • 无权限的按钮不渲染,而非禁用——用户根本看不到他没有的操作入口

四、非功能需求

4.1 性能要求

指标要求说明
角色列表查询响应时间< 500ms包含分页查询
菜单树查询响应时间< 300ms菜单管理页加载
权限分配保存响应时间< 500ms菜单权限/数据权限保存
登录后获取路由菜单响应时间< 300ms影响用户登录后的首屏体验
权限标识列表返回响应时间< 200ms与路由菜单一起返回
权限缓存刷新时间< 100ms权限变更后缓存刷新必须快速完成

4.2 安全要求

要求说明实现方式
权限隔离内置角色不可被普通管理员删除或修改标识后端校验 type 字段
租户隔离多租户场景下角色权限受套餐约束,不可越权分配分配菜单时过滤套餐外的菜单
防越权分配菜单权限时过滤租户套餐未开通的菜单菜单树查询时与租户套餐取交集
权限缓存权限变更后即时刷新缓存,确保权限变更实时生效Redis 缓存 + 变更时主动清除
操作日志所有角色/菜单/权限变更操作记录操作日志AOP 切面自动记录
接口鉴权所有管理接口使用 @PreAuthorize + 权限标识校验Spring Security 注解

4.3 兼容性要求

要求
PC浏览器Chrome 80+、Firefox 75+、Safari 13+

五、数据设计

5.1 数据模型

ER关系说明

ER关系图

  • 角色与菜单为多对多关系,通过 system_role_menu 关联
  • 用户与角色为多对多关系,通过 system_user_role 关联
  • 一个用户可以有多个角色,一个角色可以有多个用户
  • 一个角色可以关联多个菜单,一个菜单可以被多个角色使用

角色表(system_role)

字段名类型必填说明
idBIGINT角色ID(主键,自增)
nameVARCHAR(30)角色名称
codeVARCHAR(100)角色标识(唯一)
sortINT显示顺序
statusTINYINT角色状态(0-启用 1-禁用)
typeTINYINT角色类型(1-内置角色 2-自定义角色)
remarkVARCHAR(500)备注
data_scopeTINYINT数据范围(1-全部 2-指定部门 3-本部门 4-本部门及子部门 5-仅本人)
data_scope_dept_idsVARCHAR(2048)数据范围-指定部门ID列表(JSON数组格式)
tenant_idBIGINT租户ID
creatorVARCHAR(64)创建者
create_timeDATETIME创建时间
updaterVARCHAR(64)更新者
update_timeDATETIME更新时间
deletedBIT(1)删除标记(0-未删除 1-已删除)

索引设计:

  • 唯一索引:uk_code_tenant (code, tenant_id) — 同一租户内角色标识唯一
  • 普通索引:idx_tenant_status (tenant_id, status) — 按租户和状态查询

菜单表(system_menu)

字段名类型必填说明
idBIGINT菜单编号(主键,自增)
nameVARCHAR(50)菜单名称
permissionVARCHAR(100)权限标识(格式:${系统}😒{模块}😒{操作})
typeTINYINT菜单类型(1-目录 2-菜单 3-按钮)
sortINT显示顺序
parent_idBIGINT父菜单ID(0为根节点)
pathVARCHAR(200)路由地址(http(s)开头为外链)
iconVARCHAR(100)菜单图标
componentVARCHAR(200)组件路径
component_nameVARCHAR(100)组件名称(用于keep-alive)
statusTINYINT状态(0-启用 1-禁用)
visibleBIT(1)是否可见(侧边栏是否展示)
keep_aliveBIT(1)是否缓存(Vue keep-alive)
always_showBIT(1)是否总是显示
creatorVARCHAR(64)创建者
create_timeDATETIME创建时间
updaterVARCHAR(64)更新者
update_timeDATETIME更新时间
deletedBIT(1)删除标记

说明:system_menu 为全局共享表,不随租户隔离。

索引设计:

  • 普通索引:idx_parent_id (parent_id) — 查询子菜单
  • 普通索引:idx_status_sort (status, sort) — 按状态和排序查询

角色-菜单关联表(system_role_menu)

字段名类型必填说明
idBIGINT编号(主键,自增)
role_idBIGINT角色ID
menu_idBIGINT菜单ID
tenant_idBIGINT租户ID
creatorVARCHAR(64)创建者
create_timeDATETIME创建时间
updaterVARCHAR(64)更新者
update_timeDATETIME更新时间
deletedBIT(1)删除标记

索引设计:

  • 联合索引:idx_role_menu (role_id, menu_id) — 查询角色的菜单列表
  • 普通索引:idx_menu_id (menu_id) — 反查菜单被哪些角色使用

用户-角色关联表(system_user_role)

字段名类型必填说明
idBIGINT编号(主键,自增)
user_idBIGINT用户ID
role_idBIGINT角色ID
creatorVARCHAR(64)创建者
create_timeDATETIME创建时间
updaterVARCHAR(64)更新者
update_timeDATETIME更新时间
deletedBIT(1)删除标记

索引设计:

  • 联合索引:idx_user_role (user_id, role_id) — 查询用户的角色列表
  • 普通索引:idx_role_id (role_id) — 反查角色下有哪些用户(角色成员管理)

5.2 数据字典

字典类型字典值说明
system_role_status0-启用 1-禁用角色状态
system_role_type1-内置角色 2-自定义角色角色类型
system_data_scope1-全部数据权限 2-指定部门数据权限 3-本部门数据权限 4-本部门及以下数据权限 5-仅本人数据权限数据范围
system_menu_type1-目录 2-菜单 3-按钮菜单类型
system_menu_status0-启用 1-禁用菜单状态
system_common_status0-正常 1-停用通用状态

六、跨模块联动

6.1 联动关系总览

角色权限管理作为权限体系的核心,与多个模块存在紧密联动:

关联模块联动方式联动说明
认证授权登录后加载权限用户登录成功后,认证模块调用权限模块获取用户的菜单树和权限标识列表
用户管理角色分配用户管理中为用户分配/移除角色,角色变更后刷新权限缓存
组织架构数据权限依赖数据权限的"指定部门""本部门"等选项依赖部门树结构
租户管理套餐约束租户套餐决定该租户可用的菜单范围,角色分配菜单时受套餐约束
日志审计操作记录角色/菜单/权限的所有变更操作记录到操作日志
数据字典状态翻译角色状态、数据范围、菜单类型等使用数据字典进行翻译

6.2 关键联动流程

6.2.1 用户登录 → 权限加载流程

登录权限加载流程

6.2.2 权限变更 → 缓存刷新流程

权限变更缓存刷新流程

6.2.3 租户套餐 → 菜单过滤流程

租户套餐菜单过滤流程

6.3 数据一致性要求

场景一致性要求
删除角色同步清理 role_menu、user_role 关联数据
删除菜单同步清理 role_menu 关联数据
修改菜单权限标识前端缓存的权限标识列表需要刷新
租户套餐变更已分配的角色权限如果超出新套餐范围,需要提示管理员调整

七、附录

7.1 名词解释

术语解释类比
RBAC基于角色的访问控制(Role-Based Access Control)。核心思想是:不直接给用户配权限,而是先给角色配权限,再把角色分配给用户就像公司的门禁系统——不是给每个人单独配门禁,而是按"员工类型"发卡,高管卡能进所有房间,普通员工卡只能进办公区
菜单权限控制用户"能看哪些页面、能点哪些按钮"。分为目录、菜单、按钮三个层级目录是"楼层",菜单是"房间号",按钮是"房间里的抽屉"
数据权限控制用户"能看到哪些数据"。比如同样是"项目列表",项目经理能看到本部门所有项目,普通开发只能看到自己负责的项目同一份文件柜,经理能打开所有柜子,员工只能打开标有自己名字的格子
权限标识一个唯一的字符串标签,格式为"系统:模块:操作",如 system:role:create。后端用它校验接口权限,前端用它控制按钮显隐就像钥匙上的编号——"A栋-3楼-302"精确标识了这把钥匙能开哪个门
内置角色系统预置的角色(如超级管理员、租户管理员),不可删除、标识不可修改就像大楼的"总钥匙",是物业自带的,不能被注销
租户套餐多租户场景下,每个租户购买的功能菜单集合。就像手机套餐——基础版只能用基础功能,旗舰版可以用全部功能SaaS 软件的"定价策略"——免费版看 3 个菜单,专业版看 10 个,企业版看全部
动态路由前端根据用户权限动态生成页面路由。不同用户登录后看到的侧边栏菜单不同就像每个人走进大楼,电梯面板上只亮他能去的楼层按钮
keep-aliveVue 的页面缓存机制。开启后切换页面再回来,之前的表单内容和滚动位置都还在相当于给页面"拍照存档",回来时直接恢复原样
数据范围数据权限的具体级别,从"全部"到"仅本人"共 5 个级别像图书馆的借阅权限——有的馆员能借所有区的书,有的只能借本区的
权限缓存将用户的权限数据存储在 Redis 中,避免每次请求都查数据库就像把常用电话号码存在手机通讯录里,不用每次都翻通讯录本
全量覆盖保存权限时先清空旧数据再写入新数据,而非增量修改像重新排版一面照片墙——先把所有照片取下来,再按新布局全部钉上去
父子联动菜单权限树中,勾选父节点自动选中所有子节点,取消父节点自动取消所有子节点像关总闸就断了所有分路的电,开总闸才恢复供电

7.2 权限标识命名规范

场景命名格式示例
查看列表${系统}😒{模块}:querysystem:role:query
查看详情${系统}😒{模块}:querysystem:role:query
新增${系统}😒{模块}:createsystem:role:create
修改${系统}😒{模块}:updatesystem:role:update
删除${系统}😒{模块}:deletesystem:role:delete
导出${系统}😒{模块}:exportsystem:role:export
分配菜单${系统}:permission:assign-role-menusystem:permission:assign-role-menu
分配数据权限${系统}:permission:assign-role-data-scopesystem:permission:assign-role-data-scope
分配用户角色${系统}:permission:assign-user-rolesystem:permission:assign-user-role

7.3 内置角色说明

角色名称角色标识说明
超级管理员super_admin拥有系统全部权限,不可删除/禁用
租户管理员tenant_admin租户内最高权限,受套餐约束

7.4 接口汇总

序号接口名称请求方式接口路径所属功能
1获取角色分页GET/admin-api/system/role/page角色列表
2获取角色详情GET/admin-api/system/role/get角色列表
3获取角色精简列表GET/admin-api/system/role/simple-list角色列表
4创建角色POST/admin-api/system/role/create新增角色
5更新角色PUT/admin-api/system/role/update编辑角色/状态切换
6删除角色DELETE/admin-api/system/role/delete删除角色
7批量删除角色DELETE/admin-api/system/role/delete-list批量删除
8导出角色ExcelGET/admin-api/system/role/export-excel角色导出
9获取菜单列表GET/admin-api/system/menu/list菜单列表
10获取菜单详情GET/admin-api/system/menu/get菜单列表
11获取菜单精简列表GET/admin-api/system/menu/simple-list菜单列表
12创建菜单POST/admin-api/system/menu/create新增菜单
13更新菜单PUT/admin-api/system/menu/update编辑菜单
14删除菜单DELETE/admin-api/system/menu/delete删除菜单
15批量删除菜单DELETE/admin-api/system/menu/delete-list批量删除
16获取角色菜单编号列表GET/admin-api/system/permission/list-role-menus分配菜单权限
17分配角色菜单权限POST/admin-api/system/permission/assign-role-menu分配菜单权限
18分配角色数据权限POST/admin-api/system/permission/assign-role-data-scope分配数据权限
19获取用户角色列表GET/admin-api/system/permission/list-user-roles角色成员管理
20分配用户角色POST/admin-api/system/permission/assign-user-role角色成员管理
21获取路由菜单和权限GET/admin-api/system/auth/get-permission-info前台动态路由

7.5 变更记录

版本日期修改内容修改人
v1.02026-09-13初始版本PM Team
v2.02026-09-19增强版:补充业务场景细节、验收标准、跨模块联动、名词解释、ASCII线框图、索引设计PM Team

本文档为角色权限管理模块PRD,如有问题请联系产品负责人。