第九章. 系统管理(三):菜单管理(定义系统的“功能地图”)

第九章. 系统管理(三):菜单管理(定义系统的“功能地图”)

摘要:本章我们将学习 RVP 权限体系的“蓝图”——菜单管理。菜单不仅定义了用户在前端能看到的导航栏,更定义了后端 API 的访问权限。我们将深入理解“目录、菜单、按钮”三种类型的本质区别,并实战如何创建新功能模块并将其精确授权给角色。


本章学习路径

我们将聚焦于菜单管理的核心三要素,快速带领您理解菜单权限的设置

菜单管理


9.1. [核心] 菜单类型详解:目录(M)、菜单©与按钮(F)

在上一章中,我们花了很多时间在“角色管理”界面,为角色勾选各种权限。我们当时勾选的那个“权限树”,你是否好奇过:它是从哪里来的?

我们为什么能给角色分配一个叫 system:user:list 的权限?系统又是如何知道要把“用户管理”显示在“系统管理”下面的?

所有这些“系统蓝图”的定义,都存放在一个地方——系统管理 -> 菜单管理

我们现在就点开它。你会看到一个树状列表,它和我们左侧的导航栏长得一模一样。没错,这个界面就是用来“画”出我们整个系统前端导航和后端权限的。

RVP 的这套设计非常经典,它把一个复杂系统拆解成了三种最基本的“零件”,我们必须彻底搞懂它们。

image-20251111163832576


9.1.1. 零件一:目录(M)- 系统的“文件夹”

我们先看第一层,比如列表中的 系统管理系统监控。这些都是我们导航栏上的一级菜单。

在 RVP 中,这种只用于“归类”的一级导航,被称为 目录(Menu)

它存在的意义非常纯粹:组织和分类

试想一下,如果 RVP 有 50 个功能,但没有“系统管理”这样的“文件夹”来组织它们,那我们的左侧导航栏岂不是要平铺 50 个菜单项?那将是一场灾难。

所以,“目录”就是“文件夹”。我们点一下 系统管理 右侧的“修改”按钮看看它的配置:

  • 上级菜单主目录(意思是它自己就是根目录下的“文件夹”)
  • 菜单类型目录
  • 配置特点:你会发现它的配置项非常少。它不需要“组件路径”,也不需要“权限字符”。为什么?因为它只是个“文件夹”,它本身并不能点击后打开某个页面,它的唯一使命就是“展开”和“折叠”,显示它里面的“文件”。

image-20251111163933423


9.1.2. 零件二:菜单(C)- 能打开的“页面”

好,我们现在展开 系统管理 这个“文件夹”。

你会看到 用户管理角色管理菜单管理 等。这些才是我们真正能点击、能跳转、能看到界面的“页面”。

在 RVP 中,这种能被用户访问的、承载业务功能的页面,被称为 菜单(Component)

这是我们功能的核心载体。我们点击 用户管理 右侧的“修改”按钮:

  • 上级菜单系统管理(清楚地表明它被存放在“系统管理”这个“文件夹”里)
  • 菜单类型菜单
  • 配置特点:哇,你会发现这里的配置项瞬间变得复杂起来。它有“路由地址”、“组件路径”、“权限字符”等等。这很正常,因为它是一个真正的“页面”,系统需要知道:
    1. 用户访问的 URL 是什么?(路由地址)
    2. 该去加载哪个前端 Vue 文件?(组件路径)
    3. 访问这个页面需要什么权限?(权限字符)

image-20251111164053410

我们将在 9.2 节详细拆解这些配置。现在你只需要记住:“菜单(C)”就是我们能看到的、能操作的“业务页面”。


9.1.3. 零件三:按钮(F)- 控制功能的“开关”

我们继续展开 用户管理 这个“页面”。

你会看到 用户查询用户新增用户修改用户删除。这些是什么?它们会显示在左侧导航栏吗?

当然不会。这些是在 RVP 中用于 精细化权限控制 的“功能点”,被称为 按钮(Function)

它们存在的意义是:让权限控制深入到页面内部

比如,某个运营角色,我们希望他能“查看”用户列表(即拥有 用户管理 菜单 C 的权限),但我们 不希望 他有“删除”用户的能力。这时候,我们就可以只给他分配 用户查询 (F) 的权限,而不给他 用户删除 (F) 的权限。

我们点击 用户查询 右侧的“修改”按钮:

  • 上级菜单用户管理(表明这个“开关”是属于“用户管理”这个“页面”的)
  • 菜单类型按钮
  • 配置特点:它的配置项比“目录”还简单。它不关心 URL,也不关心前端组件。它只关心一件事:
    • 权限字符(例如 system:user:query

image-20251111164211226

这个字符串,就是它唯一的“身份证”。它就是我们在上一章“角色管理”里勾选的那个权限。后端代码会用这个字符串来判断:“嘿,Prorise,你虽然能进这个页面,但你有 system:user:delete 这个’删除’的’通行证’吗?”


本节小节

我们来总结一下这三种“零件”的关系,用一个比喻就非常清晰了:

  • 目录(M):就像你电脑里的 “文件夹”(例如 D:\工作)。它只管分类。
  • 菜单(C):就像文件夹里的 “Excel 文件”(例如 D:\工作\用户列表.xlsx)。它是你真正要打开和查看的。
  • 按钮(F):就像这个 Excel 文件是否 “只读” 还是 “可编辑/可删除”。它控制你“能对这个文件做什么”。

我们新增功能时,也必须遵循这个 M -> C -> F 的层级关系来创建。


9.2. [重点] 菜单关键配置项解析

在上一节中,我们搞清楚了 M、C、F 三种类型的不同定位。我们知道,“菜单(C)”类型的配置是最复杂的,因为它承载了连接前端路由和后端权限的核心任务。

现在,我们就聚焦于“菜单(C)”,把那几个最关键、最容易混淆的配置项彻底讲透。我们再次打开 系统管理 -> 用户管理 的“修改”界面。


9.2.1. 路由地址 vs 组件路径(前端核心映射)

这是新手 100% 会搞混的两个配置:

  • 路由地址 (Route Path)
    • 配置值user
    • 它是干嘛的?:它定义的是前端 vue-router 在浏览器地址栏上显示和匹配的 URL 路径
    • 最终效果:它的上级“目录”的路由地址是 system,它自己的路由地址是 user。两者一拼接,就构成了我们访问这个页面的最终 URL:/system/user
  • 组件路径 (Component Path)
    • 配置值system/user/index
    • 它是干嘛的?:它告诉 vue-router:“当用户访问 /system/user 这个 URL 时,你应该去 加载哪个 Vue 文件来渲染页面?”
    • 映射规则system/user/index 对应的就是前端项目 src/views/system/user/index.vue 这个文件。

9.2.2. 权限字符(Permission Key):后端的“通行证”

注意,这个是基于原版若依的解释,后续深入章节会对于RVP的完整最新权限认证流程有源码级别的阅读,所以不需要太在意,了解原理即可

  • 配置值system:user:list
  • 它是干嘛的?:这是 后端 API 的“通行证”,也是“按钮(F)”类型里最重要的那个“身份证”。
  • 联动机制
    1. Prorise 登录并访问“用户管理”页面(/system/user)时…
    2. 前端会立刻调用后端 API(比如 GET /system/user/list)来获取用户列表。
    3. 在 RVP 后端,UserController.java 里的 list() 方法上,一定有一个这样的注解:@PreAuthorize("@ss.hasPermi('system:user:list')")
    4. Spring Security 会在此时介入,检查 Prorise 拥有的所有角色的权限“并集”中,是否包含 system:user:list 这个字符串。
    5. 如果包含,放行,API 返回数据。
    6. 如果不包含,立刻 抛出 403 Forbidden(无权限)异常,页面一片空白。

这就是 RVP 权限体系从前端菜单、到角色、再到后端 API 的完整闭环。


9.2.3. 外链菜单的实现

RVP 还允许我们将一个外部网站(比如公司官网、产品文档)像模像样地嵌入到系统导航栏中。

我们找到 Plus 官网 这个菜单,点击“修改”:

  • 是否外链:选择
  • 路由地址:这里不再是 user 这样的短路径,而是填写一个完整的 https:// 开头的 URL。

当用户点击这个菜单时,系统就会自动跳转到这个外部地址。