1.0.435.sql 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. -- ============================================================================
  2. -- 1.0.435:修复 1.0.433 引入的角色授权回归 —— 按钮权限挂载点选错导致父菜单被丢
  3. --
  4. -- 回归现象(RUNTIME VERIFIED):
  5. -- UATAdminA 打开 /aidop/s5/inventory/stock-query 返回 404;
  6. -- 其菜单树里「库存查询」消失,同级其余 5 个页面均在。
  7. -- 实测 UAT_FUNCTION_USER(838258976469061) 的 SysRoleMenu 已无 MenuId=1329015030003,
  8. -- 而对照租户 B 的同名角色仍有。
  9. --
  10. -- 根因(CODE VERIFIED,SysMenuService.cs:468-486 角色授权树「已勾选」计算):
  11. -- foreach (var id in menuIds) {
  12. -- if (是按钮) continue;
  13. -- var children = menuList.ToChildList(..., id, false);
  14. -- if (children.Count == 0 || children.All(u => menuIds.Contains(u.Id))) continue;
  15. -- exceptList.Add(id); // 有子节点但未全部持有 → 从「已勾选」中排除
  16. -- }
  17. -- 1.0.433 把 6 个按钮权限挂在「库存查询」(1329015030003) 下。该菜单原本是**叶子**
  18. -- (children.Count==0,永不排除);挂上按钮后,业务角色一个按钮都不持有
  19. -- → children.All(...) 为假 → 「库存查询」被排除出已勾选集合。
  20. -- 前端 editRole.vue:118-120 提交的是 checkedKeys ∪ halfCheckedKeys:
  21. -- 它既不在已勾选(被排除),其子节点又全未勾选(不构成半选)
  22. -- → 管理员下一次保存该角色时它被 GrantRoleMenu 全量覆盖删除。
  23. -- 祖先目录(库存数据 / S5 物料仓储 / Ai-DOP)因仍有其他已勾选子节点而处于**半选**,
  24. -- 得以幸存,所以只丢了这一条。
  25. -- 注:该「已勾选」计算用 GetSugarQueryableAndTenantId(0),**不按租户过滤**,
  26. -- 因此 1.0.433 只授权给 AIDOP 租户的按钮,同样会影响 UAT 租户角色的勾选态。
  27. --
  28. -- 修复方案:
  29. -- ① 新建**隐藏管理目录**「库存冷链入站(管理)」挂在 S5 物料仓储下,
  30. -- 6 个按钮权限改挂到它下面 → 「库存查询」恢复为叶子,永不再被排除。
  31. -- 新目录不授予任何业务角色 → 不在任何业务角色的 menuIds 中 → 排除循环不会遍历到它。
  32. -- 其父节点 S5 物料仓储 仍有多个已授权子节点(实测「持有 S5 目录却不持有其任何子节点」
  33. -- 的角色数 = 0),故各角色对该目录仍为半选,不受影响。
  34. -- ② 恢复 UAT_FUNCTION_USER 丢失的「库存查询」授权(精确到单租户单角色单菜单)。
  35. --
  36. -- 明确不做:不改任何按钮权限的 Permission 名、不改租户级授权范围、
  37. -- 不给任何业务角色新增管理权限、不使用 GrantMenu 全量覆盖、不按 RoleCode 跨租户处理。
  38. --
  39. -- 幂等:INSERT 带 NOT EXISTS;UPDATE 带目标状态限定,重复执行影响行数为 0。
  40. -- ============================================================================
  41. -- ---------------------------------------------------------------------------
  42. -- 1. 新建隐藏管理目录(按钮权限的专用挂载点)
  43. -- ---------------------------------------------------------------------------
  44. INSERT INTO SysMenu (Id, Pid, Type, Name, Title, Icon,
  45. IsIframe, IsHide, IsKeepAlive, IsAffix, OrderNo, Status, Remark, CreateTime)
  46. SELECT 1329015030100, 1321000006000, 1, 'aidopS5InvInboundAdmin', '库存冷链入站(管理)', 'ele-Menu',
  47. 0, 1, 1, 0, 900, 1,
  48. 'S5 冷链入站管理权限点的专用挂载目录(隐藏)。刻意独立成节点:SysMenuService 的角色授权树会把「有子节点但未全部持有」的菜单排除出已勾选,若把按钮挂到业务页面下,会导致该页面在下次角色保存时被删除(见 1.0.433 回归)。',
  49. NOW()
  50. FROM DUAL
  51. WHERE NOT EXISTS (SELECT 1 FROM SysMenu WHERE Id = 1329015030100);
  52. -- ---------------------------------------------------------------------------
  53. -- 2. 6 个按钮权限改挂到该隐藏目录(原挂在「库存查询」1329015030003 下)
  54. -- ---------------------------------------------------------------------------
  55. UPDATE SysMenu
  56. SET Pid = 1329015030100, UpdateTime = NOW()
  57. WHERE Type = 3
  58. AND Pid = 1329015030003
  59. AND Permission IN (
  60. 's5InventoryInbound:bootstrap',
  61. 's5InventoryInbound:run-once',
  62. 's5InventoryInbound:reconcile',
  63. 's5InventoryInbound:transform-std',
  64. 's5InventoryInbound:transform-inventory-std',
  65. 's5InventoryInbound:daily-recon');
  66. -- ---------------------------------------------------------------------------
  67. -- 3. 管理租户(AIDOP)对该隐藏目录的租户级授权(与 1.0.433 的按钮授权保持同一租户)
  68. -- ---------------------------------------------------------------------------
  69. INSERT INTO SysTenantMenu (Id, TenantId, MenuId)
  70. SELECT (SELECT IFNULL(MAX(Id), 0) + 1 FROM SysTenantMenu tm2),
  71. t.Id, 1329015030100
  72. FROM SysTenant t
  73. JOIN SysOrg o ON o.Id = t.OrgId
  74. WHERE o.Code = 'AIDOP' AND t.Status = 1
  75. AND EXISTS (SELECT 1 FROM SysMenu WHERE Id = 1329015030100)
  76. AND NOT EXISTS (
  77. SELECT 1 FROM SysTenantMenu tm
  78. WHERE tm.TenantId = t.Id AND tm.MenuId = 1329015030100)
  79. LIMIT 1;
  80. -- ---------------------------------------------------------------------------
  81. -- 4. 恢复被回归删除的「库存查询」角色授权(精确单租户单角色单菜单)
  82. -- TenantId 838257186181189 / RoleId 838258976469061 / MenuId 1329015030003
  83. -- ---------------------------------------------------------------------------
  84. INSERT INTO SysRoleMenu (Id, RoleId, MenuId)
  85. SELECT (SELECT IFNULL(MAX(Id), 0) + 1 FROM SysRoleMenu rm2), r.Id, m.Id
  86. FROM SysRole r
  87. JOIN SysMenu m ON m.Id = 1329015030003 AND m.Type = 2 AND m.Status = 1
  88. WHERE r.Id = 838258976469061
  89. AND r.TenantId = 838257186181189
  90. AND r.Status = 1
  91. AND EXISTS (
  92. SELECT 1 FROM SysTenantMenu t
  93. WHERE t.TenantId = r.TenantId AND t.MenuId = m.Id)
  94. AND NOT EXISTS (
  95. SELECT 1 FROM SysRoleMenu x
  96. WHERE x.RoleId = r.Id AND x.MenuId = m.Id);