第八章. 系统管理(二):角色与数据权限(RBAC 的核心)

第八章. 系统管理(二):角色与数据权限(RBAC 的核心)

摘要:本章我们将深入 RuoYi-Vue-Plus 权限体系(RBAC)的心脏——角色管理。在上一章掌握了“用户”之后,本章我们将学习“角色”这一核心桥梁,实战演练如何为角色分配“菜单权限”(能看什么)和“数据权限”(能看多少)。


本章学习路径

我们将按照“定义角色 -> 分配权限 -> 授予用户”的 RBAC 最佳实践,分步探索角色管理:

角色管理模块实操解析(RBAC 权限体系)

学习建议

  • 本章是 RVP 权限设计的 精髓。请务必动手实战 8.4 节的五种数据权限8.5 节的权限叠加。理解“菜单权限”和“数据权限”的分离与组合,是二次开发中定义复杂权限的基础。

8.1. 角色管理界面总览

在第七章中,我们已经彻底掌握了“用户管理”的所有操作,我们知道了一个用户(如 Prorise)的权限是 由其角色决定的。但是,这些“角色”本身是在哪里定义的?它们又是如何获得“查看系统管理”或“仅查看本人数据”这些能力的呢?本节,我们就将探索 RBAC 模型的“心脏”——角色管理界面。

我们点击左侧菜单栏 系统管理 -> 角色管理

image-20251111144544195

8.1.1. 界面布局与搜索

与用户管理类似,该界面分为“搜索区”、“操作区”和“列表区”。

  • 搜索区:允许我们按“角色名称”、“权限字符”、“状态”或“创建时间”快速筛选角色。
  • 操作区:提供了“新增”、“修改”、“删除”和“导出”功能。
  • 列表区:展示了系统中已有的所有角色。默认我们可以看到三个内置角色:
    • 超级管理员
    • 本部门及以下
    • 仅本人

8.1.2. 核心操作(导出、修改、删除)

对于普通角色(如“仅本人”),数据行右侧提供了完整的操作按钮:

  • 修改:编辑角色的基本信息和权限。
  • 删除:删除该角色(有安全限制,8.6 节详述)。
  • 分配用户:为这个角色批量“绑定”用户(8.3 节详述)。
  • 数据权限:配置该角色的数据可见范围(8.4 节核心)。

8.1.3. 特殊角色:不可操作的“超级管理员”

我们立刻会发现一个最重要的特性:超级管理员 (admin) 这一行,其右侧没有任何“修改”、“删除”或“数据权限”的操作按钮

这是 RVP 框架内置的 最高安全锁
admin 角色(role_id = 1)拥有系统中所有菜单和所有数据的权限,它 不受任何数据权限的约束。为了防止管理员(甚至 admin 自己)误操作导致系统“锁死”(例如不慎修改了 admin 的权限,导致无人能管理系统),RVP 在界面层 禁止admin 角色进行任何操作。


8.1.4. 本节小结

我们熟悉了角色管理的主界面,这是定义“权限集合”的中心:

  • 界面功能:提供对角色的“增删改查”和“导出”功能。
  • 核心安全超级管理员 角色在界面上被 锁定,无法修改或删除,这是防止系统失控的“防锁死”机制。

8.2. 核心操作(一):创建角色与分配“菜单权限”

在上一节中,我们熟悉了角色列表,并理解了 admin 角色的特殊性。现在,我们来实战创建一个全新的角色,并为它分配“能看哪些菜单”,即 菜单权限

我们点击 新增 按钮,打开“添加角色”模态框。

8.2.1. 新增角色表单

我们需要填写以下核心字段,以“系统管理员”为例:

  • 角色名称系统管理员 (一个易于理解的中文名称)。
  • 权限字符system (一个 全局唯一 的英文字符串,后端代码会使用这个 key 来判断权限,非常重要)。
  • 显示顺序5 (数字越小越靠前)。
  • 状态:保持“正常”。

image-20251111145910381

8.2.2. [重点] 分配菜单权限树

表单下方是“菜单权限”树,这是 RVP 权限体系的第一个核心。它定义了拥有此角色的用户,登录后能在左侧菜单栏看到什么

我们会注意到树上方有三个辅助按钮:展开/折叠全选/全不选父子联动

8.2.3. [重点] 理解“父子联动”的两种使用场景

父子联动 是这里最关键的机制,它默认是 开启 的。

场景一:父子联动(默认开启)

  • 操作:我们展开“系统管理”菜单,只勾选其子菜单“用户管理”。
  • 现象系统管理(父菜单)会被 自动勾选
  • 原因:这是符合逻辑的。用户必须先能看到“系统管理”这个父菜单,才能点击并进入“用户管理”这个子菜单。如果只给子菜单权限,父菜单不给,用户在界面上将永远找不到入口。

场景二:取消父子联动(特殊场景)

  • 操作:假设我们有一个“文件管理”菜单,它有三个子权限:“文件列表”、“文件上传”、“文件下载”。
  • 需求:我们想创建一个角色,只允许他“上传”和“下载”,但 不允许 他点击“文件管理”菜单去查看“文件列表”。
  • 实现
    1. 取消勾选“父子联动”。
    2. 此时,我们可以 只勾选“文件上传”和“文件下载”两个子权限。
    3. 而“文件管理”(父菜单)和“文件列表”(子菜单)保持不勾选
  • 结果:该角色将无法在菜单栏看到“文件管理”,但他访问“文件上传”的 API 接口时,权限会通过。

点击 确定,新角色创建成功。


8.2.4. 本节小结

我们完成了新角色的创建,并掌握了“菜单权限”的分配:

  • 角色表单角色名称 (显示用) 和 权限字符 (代码用) 是核心字段。
  • 菜单权限:定义了用户 能看到的菜单(前端路由)。
  • 父子联动
    • 开启(默认):用于标准的菜单层级,勾选子级会自动勾选父级,保证菜单入口可见。
    • 关闭:用于特殊的权限场景,例如只授予 API 操作权限(如“上传”),而不授予父菜单的访问权限。

8.3. 核心操作(二):为角色“分配用户”

在上一节中,我们成功创建了“系统管理员”角色,并为它分配了“系统管理”的 菜单权限。但此时,这个角色只是一个“权限模板”,它还没有与任何“人”关联。本节,我们将把这个角色授予 Prorise 用户,完成“用户-角色-权限”的完整闭环。

8.3.1. 添加用户与批量取消授权

我们有两种方式将角色分配给用户:

  1. 方式一(用户管理页):[已在 7.4 节演练]
    • 进入“用户管理”,找到 Prorise,点击“修改”或“分配角色”,勾选“系统管理员”。
  2. 方式二(角色管理页):[本节演练]
    • 在“角色管理”列表,找到我们刚创建的“系统管理员”。
    • 点击其右侧的 分配用户 按钮。
    • 在弹出的“分配用户”模态框中,点击 添加用户
    • 在弹出的“选择用户”列表中,勾选 Prorise,点击 确定

Prorise 用户就被添加到了“系统管理员”的已分配列表中。

image-20251111150327055

8.3.3. 本节小结

我们完成了角色和用户的关联,并验证了菜单权限的叠加与更新:

  • 双向分配:我们可以在“角色管理 -> 分配用户”界面,为角色批量添加用户。
  • 权限叠加:用户的最终 菜单权限,是其拥有的 所有角色 菜单权限的 并集
  • 生效时机:菜单权限的变更(增/删角色),用户 刷新浏览器 即可生效。

8.4. [核心] 详解“数据权限”的五种范围

在 8.2 和 8.3 节中,我们彻底解决了“菜单权限”——它决定了用户能“看到哪个页面”(例如能看到“用户管理”菜单)。然而,在企业应用中,还存在一个更精细的权限控制:“这个用户在页面里能看到哪些数据?”

例如,Prorise 用户虽然能打开“用户管理”页面,但他是否应该看到“超级管理员”admin 的信息?或者,他是否只能看到自己所在“测试部门”的同事,而不能看到“研发部门”的同事?

这就是 RVP 权限体系的第二个核心支柱——数据权限。本节,我们将深入实战 RVP 内置的五种数据权限范围。

我们以 admin 身份登录,进入 角色管理,找到“系统管理员”角色,点击其右侧的 数据权限 按钮。

我们会看到一个模态框,包含五种权限范围。我们将从最严格到最宽松的顺序逐一实操。

image-20251111150442658

⚠️ 重要前提:数据权限的“激活”
以下 所有 非“全部数据”的权限范围(如“本部门”、“仅本人”),都必须依赖一个前提:用户(Prorise)必须被分配了一个具体的部门

如果一个用户没有部门归属,RVP 在计算数据权限时会“跳过”限制,导致该用户(在设置了“本部门”权限后)依旧能看到所有数据。这是新手最容易犯的错误。

生效时机

  • 菜单权限 变更:用户 刷新 (F5) 浏览器即可生效。
  • 数据权限 变更:用户必须 退出登录后重新登录 才能生效。

8.4.1. 范围一:仅本人数据权限

这是最严格的权限,没有之一。

  • 含义:用户在(例如)“用户管理”列表,只能看到自己这一条数据。
  • 应用场景:适用于系统中(例如)文件模块,或者某些 C 端用户角色,他们绝不应该看到除自己以外的任何其他人

实操步骤

  1. 配置角色admin 将“系统管理员”的 数据权限 修改为 仅本人数据权限,点击“确定”。
  2. 配置用户admin 进入“用户管理”,确保 Prorise 用户已分配了“系统管理员”角色。
  3. 验证Prorise 用户 退出登录并重新登录
  4. 结果Prorise 访问“系统管理 -> 用户管理”,在数据列表中什么数据都看不到,这是正常的情况,因为无法管理自己

8.4.2. 范围二:本部门数据权限

这是企业中最常用的权限之一。

  • 含义:用户只能看到自己所在部门的数据。
  • 应用场景:适用于普通员工、部门职员。例如,Prorise 在“测试部门”,他打开“用户管理”时,只能看到同在“测试部门”的同事。

实操步骤

  1. 配置用户部门admin 进入“用户管理”,修改 Prorise 用户,将其 归属部门 设置为 测试部门
  2. 配置角色admin 将“系统管理员”的 数据权限 修改为 本部门数据权限
  3. 验证Prorise 用户 退出并重新登录
  4. 结果Prorise 访问“用户管理”,数据列表中将 只显示“测试部门”的所有用户

问题:我按照步骤 2 设置了“本部门数据权限”,但 Prorise 重新登录后,依然能看到“研发部门”和“超级管理员”admin

答案:你 遗漏了步骤 1

你只告诉了角色(系统管理员):“你要按‘本部门’过滤数据”。但是你没有告诉用户(Prorise):“你的‘本部门’是哪个部门?”

当 RVP 发现 Prorise 用户没有分配部门时,它无法执行“本部门”过滤,因此 默认放行了所有数据

修正:必须返回“用户管理”,为 Prorise 用户明确指定一个部门(如“测试部门”),数据权限才会生效。


8.4.3. 范围三:本部门及以下数据权限

这是“本部门”权限的扩展,适用于管理者。

  • 含义:用户不仅能看到自己所在部门的数据,还能看到所有 子部门 的数据。
  • 应用场景:适用于部门经理、团队 Leader。例如,Prorise 是“深圳总公司”的负责人,他需要能看到“深圳总公司”本部、以及其下的“研发部门”和“测试部门”的所有人。

实操步骤

  1. 配置用户部门admin 进入“用户管理”,修改 Prorise 用户,将其 归属部门 设置为 深圳总公司(这是一个父级部门)。
  2. 配置角色admin 将“系统管理员”的 数据权限 修改为 本部门及以下数据权限
  3. 验证Prorise 用户 退出并重新登录
  4. 结果Prorise 访问“用户管理”,数据列表中将显示“深圳总公司”、“研发部门”、“测试部门”的所有用户。他还可以使用左侧的“部门树”进行筛选。

8.4.4. 范围四:指定部门数据权限(自定义)

这是最灵活的权限,用于跨部门的特殊场景。

  • 含义:忽略用户所在的部门,直接指定该角色能看到哪些(一个或多个)特定部门的数据。
  • 应用场景:适用于项目经理、审计员。例如,Prorise 是一个项目经理,他需要同时查看“研发部门”(开发)和“测试部门”(测试)的人员,但他自己可能在“项目部”。

实操步骤

  1. 配置角色admin 将“系统管理员”的 数据权限 修改为 自定义数据权限
  2. 下方的“数据权限(指定部门)”树会变为可用。
  3. 我们勾选 研发部门测试部门
  4. 验证Prorise 用户 退出并重新登录
  5. 结果Prorise 访问“用户管理”,数据列表中将 只显示“研发部门”和“测试部门”的用户,无论 Prorise 自己在哪个部门。

[重点] 自定义权限中的“父子联动”

在“自定义数据权限”的树中,同样存在“父子联动”开关,它也分为两种场景:

  • 场景一:开启父子联动(默认)

    • 操作:我们只勾选 研发部门
    • 现象:其父级 深圳总公司 也会被自动勾选。
    • 结果Prorise 用户能看到“研发部门”和“深圳总公司”的数据。
  • 场景二:关闭父子联动

    • 操作取消勾选 树上方的“父子联动”。
    • 现象:此时我们只勾选 研发部门,父级 深圳总公司 不会 被勾选。
    • 结果Prorise 用户将 只看到“研发部门”的数据,其父级部门的数据不会被关联出来。

8.4.5. 范围五:全部数据权限

这是最宽松的权限,等同于“无限制”。

  • 含义:拥有此权限的角色,可以查看系统中(例如“用户管理”)的 所有数据,无任何部门限制。
  • 应用场景:适用于“超级管理员”或“系统管理员”这类需要总览全局的角色。

实操步骤

  1. 配置角色admin 将“系统管理员”的 数据权限 修改为 全部数据权限
  2. 验证Prorise 用户 退出并重新登录
  3. 结果Prorise 访问“用户管理”,可以看到 admin 在内的 所有 用户数据。

8.4.6. 本节小结

我们实战演练了 RVP 权限体系的第二个核心——数据权限,它控制用户“能看多少数据”。

  • 五种范围
    1. 仅本人:(最严)只能看自己。
    2. 本部门:(常用)只能看自己所在部门。
    3. 本部门及以下:(管理)看本部门 + 所有子部门。
    4. 自定义:(灵活)看勾选的特定部门。
    5. 全部数据:(最宽)看所有数据。
  • 关键陷阱:使用“本部门”或“本部门及以下”权限时,用户必须被分配了部门,否则权限不生效(将看到全部数据)。
  • 生效时机:数据权限的变更,必须 退出重新登录 才能生效。

8.5. [重点] 多角色权限叠加机制

在 8.4 节中,我们假定 Prorise 只有一个“系统管理员”角色。但在真实业务中,一个用户常常身兼数职。例如,Prorise 既是“系统管理员”(负责用户维护),又是一个“运维人员”(负责监控)。

当一个用户拥有多个角色时,他的“菜单权限”和“数据权限”是如何计算的?是取最高权限?最低权限?还是…?

本节,我们就来实战 RVP 的 多角色权限叠加机制


8.5.1. 场景准备:创建“运维”角色

我们先 admin 登录,创建一个新角色作为对比:

当前场景:我们现在有两个角色:

  • 角色 A (系统管理员)
    • 菜单:系统管理
    • 数据:本部门及以下数据权限(假定 Prorise 归属于 深圳总公司
  • 角色 B (运维)
    • 菜单:系统监控
    • 数据:自定义数据权限 (仅 长沙分公司)

8.5.2. 多角色菜单权限:并集效果验证

我们来验证菜单权限的叠加。

  1. 分配角色admin 进入“用户管理”,修改 Prorise 用户,为其 同时 分配 系统管理员运维 两个角色。
  2. 验证:切换到 Prorise 用户的浏览器,刷新页面 (F5)
  3. 结果
    Prorise 的左侧菜单栏 同时出现了“系统管理”和“系统监控” 两个顶级菜单。

核心规则(一):
用户的最终 菜单权限,是其拥有的所有角色菜单权限的 并集(Union)

Prorise 的菜单 = 系统管理员 的菜单 ∪ 运维 的菜单。


8.5.3. 多角色数据权限:并集效果验证

菜单是并集,那么数据权限呢?

  1. 分配角色:同上,Prorise 已拥有两个角色。
  2. 验证Prorise 退出登录,然后重新登录(必须重登!)。
  3. 访问Prorise 登录后,进入“系统管理 -> 用户管理”。
  4. 结果
    Prorise 在用户列表中,既能看到 深圳总公司 及其子部门的数据(来自“系统管理员”角色),也能看到 长沙分公司 的数据(来自“运维”角色)

核心规则(二):
用户的最终 数据权限,也是其拥有的所有角色数据权限范围的 并集(Union)

Prorise 的数据 = 系统管理员 的数据范围 ∪ 运维 的数据范围。


8.5.4. 本节小结

我们揭示了 RVP 权限叠加的核心机制,这对于设计复杂的企业权限至关重要:

  • 权限并集:RVP 对多角色的处理非常简单直观——全是并集。用户的能力是他所有角色能力的 总和
  • 菜单叠加:角色 A 能看菜单 1,角色 B 能看菜单 2;用户拥有 A+B,就能看菜单 1 和 2。
  • 数据叠加:角色 A 能看部门 1,角色 B 能看部门 2;用户拥有 A+B,就能看部门 1 和 2。
  1. 菜单权限 = 所有角色的菜单权限 并集(刷新 F5 生效)
  2. 数据权限 = 所有角色的数据权限 并集(重新登录生效)

8.6. 核心操作(三):禁用与删除角色

在完成了角色的创建、权限分配和用户指派后,我们最后来学习如何安全地维护这些角色——禁用与删除。


8.6.1. 安全约束:无法删除或禁用“已分配”的角色

RVP 内置了强大的安全约束,防止管理员误操作。

  1. 场景:我们的 系统管理员 角色目前正分配给了 Prorise 用户。
  2. 操作(删除)admin 在“角色管理”列表,找到 系统管理员,点击 删除
  3. 结果:系统弹出错误提示:“角色已分配,不能删除”。
  4. 操作(禁用)admin 点击 禁用
  5. 结果:系统弹出错误提示:“角色已分配,不能禁用”。

核心规则(三):
为了保证系统权限的稳定性,RVP 禁止 管理员删除或禁用任何 正在被用户使用 的角色。必须先将角色与所有用户“解绑”,才能进行后续操作。


8.6.2. 角色禁用操作流程

“禁用”是一个非破坏性的“软删除”操作,可以随时恢复。

  1. 步骤一:取消授权

    • admin 找到 系统管理员 角色,点击 分配用户
    • 在“已分配用户列表”中,勾选 Prorise
    • 点击 批量取消授权 按钮,将 Prorise 移除。
  2. 步骤二:执行禁用

    • 回到“角色管理”列表。
    • 此时再点击 系统管理员禁用 按钮。
    • 结果:操作成功。系统管理员 的状态变为灰色“停用”。
  3. 步骤三:验证效果

    • 菜单(立即生效)Prorise 用户浏览器 刷新 (F5),“系统管理”菜单 立刻消失
    • 数据(延迟生效)Prorise 如果不重新登录,他之前的数据权限(例如还能看到 深圳总公司 的数据)依然暂存
    • 管理(立即生效)admin 在“用户管理”中修改任何用户时,“角色”下拉列表里 不再出现“系统管理员”这个选项。

8.6.3. 角色删除安全规范

“删除”是不可逆的,操作流程更严格。

  1. 步骤一:取消所有用户授权
    • 必须确保 没有任何 用户正在使用此角色(同 8.6.2 的步骤一)。
  2. 步骤二:执行删除
    • 在“角色管理”列表,点击(已解绑的)系统管理员删除 按钮。
    • 结果:操作成功,角色从数据库中被永久移除。

8.6.4. 本节小结

我们掌握了角色生命周期的最后两个操作,关键在于理解其安全约束:

  • 安全锁已分配(即有用户正在使用)的角色,严禁 被删除或禁用。
  • 操作流程:必须先 取消授权(解绑所有用户),才能 禁用删除
  • 禁用 (Disable):软删除,可恢复。菜单权限刷新即失效,但角色不再可选。
  • 删除 (Delete):硬删除,不可逆。

8.7 第八章总结

本章我们深入 RVP 权限体系的心脏,彻底掌握了“角色”这一核心概念。角色是连接“用户”和“权限”的桥梁。

  • RBAC 闭环:我们完成了 用户(第七章)-> 角色(本章)-> 菜单/数据权限(本章)的完整实操闭环。
  • 两大权限:我们必须清晰区分:
    • 菜单权限:控制“能看哪个页面”(前端路由),刷新 (F5) 生效。
    • 数据权限:控制“能看多少数据”(后端 SQL 拼接),重登 生效。
  • 五种范围:我们实战了从“仅本人”到“全部数据”的五种数据权限,并掌握了“用户必须分配部门”这一关键前提。
  • 并集机制:我们验证了 RVP 的多角色叠加机制——无论是菜单还是数据,用户的最终权限都是所有角色权限的 并集(总和)
  • 安全维护:我们掌握了“先解绑、再禁用/删除”的安全操作规范。