|
|
@@ -0,0 +1,63 @@
|
|
|
+-- 菜单树盘点 —— **只读**,不改任何数据
|
|
|
+--
|
|
|
+-- 【怎么跑】
|
|
|
+-- Navicat 里整段执行(三段 SELECT 会各出一个结果页签)。
|
|
|
+-- 本文件**不含 psql 元命令**(\echo 之类)—— Navicat 跑不了那个。
|
|
|
+-- ★ 上一版写了 \echo 导致跑不动,本版已去掉;若你看到这行说明拿到的是新版。
|
|
|
+--
|
|
|
+-- 【为什么要这个东西】
|
|
|
+-- 仓库里看不到线上菜单树:`java/all_schema.sql` 是纯 schema 无数据,
|
|
|
+-- 而「代付」「操作指南」「授信额度」这几个菜单名在全仓源码(sql/java/vue/ts/md)
|
|
|
+-- **零命中** —— 它们是人在界面上手工建的(同「银联收单」当年手工改名的先例)。
|
|
|
+-- ⇒ 凡是「改菜单」的事,动手前必须先把真实现状量出来。
|
|
|
+--
|
|
|
+-- 【本次要回答的问题】
|
|
|
+-- ① 完整的菜单树长什么样(父子关系 + 排序 + 显示名)
|
|
|
+-- ② 每个角色被授了哪些菜单,以及**父节点有没有一起授**
|
|
|
+-- ——② 里 parent_also_granted = false 的行是**隐形炸弹**:
|
|
|
+-- `UserService#buildMenuTree` 对「父节点不在授权集合里」的子节点
|
|
|
+-- **静默丢弃**(既不进树也不挂到父上,日志一个字都不打)。
|
|
|
+-- 所以合并菜单(改 parent_id)时,若不同步补授新的父目录,
|
|
|
+-- 角色 2 那边的页面会**直接消失且没有任何报错**。
|
|
|
+
|
|
|
+-- ========== ① 全量菜单树(status = '0') ==========
|
|
|
+-- type: 1=目录 2=菜单 3=按钮 4=链接
|
|
|
+SELECT m.id,
|
|
|
+ m.parent_id,
|
|
|
+ m.type,
|
|
|
+ m."order",
|
|
|
+ m.title,
|
|
|
+ m.name,
|
|
|
+ m.route_path,
|
|
|
+ m.component_path,
|
|
|
+ m.permission
|
|
|
+ FROM sys_menu m
|
|
|
+ WHERE m.status = '0'
|
|
|
+ ORDER BY m.parent_id NULLS FIRST, m."order", m.id;
|
|
|
+
|
|
|
+-- ========== ② 角色 → 已授权菜单 ==========
|
|
|
+-- parent_also_granted = false 的行会被 buildMenuTree 静默丢弃
|
|
|
+SELECT rm.role_id,
|
|
|
+ r.name AS role_name,
|
|
|
+ m.id AS menu_id,
|
|
|
+ m.parent_id,
|
|
|
+ m.type,
|
|
|
+ m.title,
|
|
|
+ (prm.menu_id IS NOT NULL) AS parent_also_granted
|
|
|
+ FROM sys_role_menus rm
|
|
|
+ JOIN sys_menu m ON m.id = rm.menu_id AND m.status = '0'
|
|
|
+ JOIN sys_role r ON r.id = rm.role_id
|
|
|
+ LEFT JOIN sys_role_menus prm
|
|
|
+ ON prm.role_id = rm.role_id AND prm.menu_id = m.parent_id
|
|
|
+ ORDER BY rm.role_id, m."order", m.id;
|
|
|
+
|
|
|
+-- ========== ③ 只列「会被静默丢弃」的行(理想结果:0 行) ==========
|
|
|
+SELECT rm.role_id, r.name AS role_name, m.id AS menu_id, m.title, m.parent_id,
|
|
|
+ p.title AS parent_title
|
|
|
+ FROM sys_role_menus rm
|
|
|
+ JOIN sys_menu m ON m.id = rm.menu_id AND m.status = '0'
|
|
|
+ JOIN sys_role r ON r.id = rm.role_id
|
|
|
+ JOIN sys_menu p ON p.id = m.parent_id
|
|
|
+ WHERE NOT EXISTS (SELECT 1 FROM sys_role_menus x
|
|
|
+ WHERE x.role_id = rm.role_id AND x.menu_id = m.parent_id)
|
|
|
+ ORDER BY rm.role_id, m.id;
|