Просмотр исходного кода

chore(汇安融): 退款权限点的菜单 SQL 交付件(待用户执行)

只新增一个 type=3 权限点,挂在「订单管理」页下:
module_payment:har:order:refund,授权给 role 1(ADMIN)与 role 2(tenant)。

给租户是**与现状一致**的:租户本来就能通过开放 API(POST /payment/openapi/har/refund)
退自己商户的单,后台按钮只是同一能力的界面。不想给的话文件里写了替代的 DELETE。

幂等:两处 INSERT 都带 NOT EXISTS,重复执行不会产生第二行。
授权**只给这一个权限点**,不像 har-menu.sql 那样按 `module_payment:har:order:%`
通配 —— 免得将来加权限点时这份脚本被重跑一次就顺带全授出去。
末尾附只读核对 SELECT(可随时复量,不写数据)。

★ 执行后必须**重新登录**:权限集合在登录时进 token / 权限 store,不重登的话
菜单里不会有这一项,后端也照旧 403。

★ 执行人是用户,执行读数未经我方独立复核(照 har-order-refund-reason.sql 的同款约定:
  脚本由我编写、只由用户执行;文件末尾的只读 SELECT 供随时复量)。
alphaH 2 недель назад
Родитель
Сommit
ebe99d6221
1 измененных файлов с 58 добавлено и 0 удалено
  1. 58 0
      java/src/main/resources/db/har-order-refund-menu.sql

+ 58 - 0
java/src/main/resources/db/har-order-refund-menu.sql

@@ -0,0 +1,58 @@
+-- 汇安融订单管理:新增「退款」权限点(2026-09-28)
+--
+-- 执行人:用户。本平台没有直连该库的通道,所以这份脚本**由我编写、只由你执行**。
+-- 本脚本是幂等的:重复执行不会产生第二行(两处 INSERT 都带 NOT EXISTS)。
+--
+-- 为什么是新增一个权限点,而不是复用 sync / create:
+--   PermissionCheck.hasAny 是按 authorities 集合做**精确匹配**(全等)。
+--   复用 sync 的后果不是「少一层保护」而是**放大权限** —— 能查一笔单的人就能把钱退了。
+--   后端那一侧由 HarOrderControllerTest#refund_hasItsOwnPermission_notReusedFromAnyOtherEndpoint
+--   钉住,这里这一行必须与它逐字一致:module_payment:har:order:refund
+--
+-- 谁拿到这个权限:
+--   role 1 = ADMIN、role 2 = tenant 都授予 —— 与现状一致,租户本来就能通过
+--   开放 API(POST /payment/openapi/har/refund)退自己商户的单,后台按钮只是同一能力的界面。
+--   若要**只给 ADMIN、不给租户**:执行完把最后那段 role 2 的 INSERT 换成它下面注释里的 DELETE。
+
+-- ---------- 权限点:挂在「订单管理」页面下 ----------
+-- type=3 = 按钮级权限点。parent 必须指向已存在的那一页,否则 UserService.buildMenuTree
+-- 会把父节点不在集合里的子节点**直接丢弃**(静默消失,不报错)。
+INSERT INTO sys_menu (parent_id, name, title, permission, type, "order",
+                      hidden, keep_alive, always_show, affix, status, created_time, updated_time)
+SELECT (SELECT id FROM sys_menu WHERE route_path = '/payment/har/order' AND type = 2),
+       '订单退款', '订单退款', 'module_payment:har:order:refund', 3,
+       (SELECT COALESCE(MAX("order"), 0) + 1 FROM sys_menu
+        WHERE parent_id = (SELECT id FROM sys_menu WHERE route_path = '/payment/har/order' AND type = 2)),
+       false, false, false, false, '0', now(), now()
+WHERE NOT EXISTS (SELECT 1 FROM sys_menu WHERE permission = 'module_payment:har:order:refund');
+
+-- ---------- 角色授权 ----------
+-- 只授权**这一个**权限点(不像 har-menu.sql 那样按 `module_payment:har:order:%` 通配),
+-- 免得将来加权限点时这份脚本被重跑一次就顺带全授出去。
+INSERT INTO sys_role_menus (role_id, menu_id)
+SELECT 1, id FROM sys_menu WHERE permission = 'module_payment:har:order:refund'
+   AND NOT EXISTS (SELECT 1 FROM sys_role_menus rm
+                   WHERE rm.role_id = 1
+                     AND rm.menu_id = (SELECT id FROM sys_menu WHERE permission = 'module_payment:har:order:refund'));
+
+INSERT INTO sys_role_menus (role_id, menu_id)
+SELECT 2, id FROM sys_menu WHERE permission = 'module_payment:har:order:refund'
+   AND NOT EXISTS (SELECT 1 FROM sys_role_menus rm
+                   WHERE rm.role_id = 2
+                     AND rm.menu_id = (SELECT id FROM sys_menu WHERE permission = 'module_payment:har:order:refund'));
+
+-- 若不想给租户(role 2),改用下面这句代替上面那段 role 2 的 INSERT:
+--   DELETE FROM sys_role_menus
+--   WHERE role_id = 2
+--     AND menu_id = (SELECT id FROM sys_menu WHERE permission = 'module_payment:har:order:refund');
+
+-- ---------- 只读核对(可随时复量,不写任何数据)----------
+-- 期望:一行,type=3,parent 指向 /payment/har/order 那一页,两个角色各有一条授权。
+SELECT m.id, m.parent_id, m.title, m.permission, m.type, m."order",
+       (SELECT string_agg(rm.role_id::text, ',' ORDER BY rm.role_id)
+        FROM sys_role_menus rm WHERE rm.menu_id = m.id) AS granted_roles
+FROM sys_menu m
+WHERE m.permission = 'module_payment:har:order:refund';
+
+-- ★ 执行后必须**重新登录**才生效:权限集合在登录时进 token / 权限 store,
+--   不重登的话菜单里不会有这一项,后端也会照旧 403。