| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- -- ============================================================================
- -- 1.0.433:把 S5 库存冷链入站管理接口纳入按钮权限管控(P0 权限治理)
- --
- -- 缺陷(CODE VERIFIED + RUNTIME VERIFIED):
- -- JwtHandler.CheckAuthorizeAsync(Admin.NET.Web.Core/Handlers/JwtHandler.cs:74-97)
- -- 的判定是:
- -- ① 超管(AccountType=999) 直接放行;
- -- ② 命中「自有按钮权限」放行;
- -- ③ 否则——**只要该路由名未登记为任何按钮权限,就兜底放行**。
- -- /api/S5InventoryInbound/* 六个 POST 管理接口全部未登记,一律走 ③ 兜底放行,
- -- 任何已登录用户(含 AccountType=777 普通业务账号)都能触发库存贴源/物化/重建。
- -- 实测:UATAdminA(777 普通用户)成功调用 reconcile 与 transform-inventory-std。
- --
- -- 权限名为什么必须是路由派生名:
- -- JwtHandler 把 /api/A/B 映射为权限名 A:B(Path.Value[5..] 把 '/' 换成 ':'),
- -- 再与用户自有权限做**忽略大小写的全等比较**。因此单个 s5InventoryInbound:admin
- -- 无法覆盖多个路由——必须逐接口登记,权限名等于各自路由派生名。
- -- 参照系统内已生效的先例 sysOrg:list ← /api/sysOrg/list(SysMenu Id=1300200030201)。
- -- 注:S8 的 s8:exception:* 属前端 v-auth 权限点,其路由为 /api/aidop/s8/...
- -- (派生名 aidop:s8:...),并不参与 JwtHandler 鉴权,不能作为本次命名依据。
- --
- -- 授权对象(依据真实 AccountType / RoleId,不按账号名猜):
- -- SysMenuService.GetOwnBtnPermList(Service/Menu/SysMenuService.cs:336-357)对
- -- AccountType=888(SysAdmin) 且未绑定任何角色的账号,返回「该租户 SysTenantMenu
- -- 允许的全部按钮权限」。租户 797403760988229 的 AIDopAdmin 正是此形态(888、无角色),
- -- 故只需给该租户加租户级菜单授权即可获得管理能力。
- -- → 本脚本**不新建角色、不写任何 SysRoleMenu**,普通业务角色一律无权。
- --
- -- 明确不做:
- -- - 不给 UAT 租户(838257186181189)加租户级授权(该租户 6 个账号全为 777 普通用户,
- -- 无任何 SysAdmin,不应具备库存重建能力)
- -- - 不给 UAT_FUNCTION_USER / ROLE_WH_* / ROLE_QC 等任何业务角色授权
- -- - 不使用 GrantRoleMenu(其语义是「删角色全部 SysRoleMenu 再全量重建」)
- -- - 不按 RoleCode 跨租户模糊授权
- -- - 不改任何既有菜单、不改任何既有角色权限
- -- - 不改库存同步/STD/LIVE 数据逻辑
- --
- -- 幂等:全部 INSERT 带 NOT EXISTS(菜单按 Permission,租户授权按 TenantId+MenuId)。
- -- 重复执行 affected rows = 0。
- --
- -- ⚠️ 缓存:JwtHandler 用 GetAllBtnPermList(缓存键 sys_user_button:0)判断「是否已登记」,
- -- GetOwnBtnPermList 缓存键 sys_user_button:<userId>,均为进程内 Memory 缓存
- -- (Cache.json:7 CacheType=Memory),SQL 写库不会使其失效。
- -- AutoVersionUpdate 在应用启动时执行本脚本,该进程缓存本就为空,随发布重启天然生效;
- -- 若在已运行实例上手工执行,必须重启后端。
- -- ============================================================================
- -- ---------------------------------------------------------------------------
- -- 0. 作用域解析(不硬编码租户 Id,按 SysOrg.Code 反查,与 1.0.402/1.0.408 一致)
- -- ---------------------------------------------------------------------------
- SET @admin_tenant := (SELECT t.Id FROM SysTenant t JOIN SysOrg o ON o.Id = t.OrgId
- WHERE o.Code = 'AIDOP' AND t.Status = 1 LIMIT 1);
- -- 挂载点:S5 / 库存数据 / 库存查询(Type=2 页面菜单)。冷链入站即该页数据的来源。
- SET @parent_menu := (SELECT Id FROM SysMenu
- WHERE Name = 'aidopS5InventoryStockQuery' AND Type = 2 LIMIT 1);
- -- ---------------------------------------------------------------------------
- -- 1. 登记 6 个按钮权限(权限名 = 路由派生名,逐接口)
- -- ---------------------------------------------------------------------------
- INSERT INTO SysMenu (Id, Pid, Type, Name, Permission, Title, Icon,
- IsIframe, IsHide, IsKeepAlive, IsAffix, OrderNo, Status, Remark, CreateTime)
- SELECT s.Id, @parent_menu, 3, s.Name, s.Permission, s.Title, 'ele-Menu',
- 0, 0, 1, 0, s.OrderNo, 1, s.Remark, NOW()
- FROM (
- SELECT 1329015030101 AS Id, 'aidopS5InvInboundBtn01' AS Name,
- 's5InventoryInbound:bootstrap' AS Permission,
- '库存冷链首刷' AS Title, 910 AS OrderNo,
- 'S5 冷链管理权限点 POST /api/S5InventoryInbound/bootstrap(写 STG + 全量替换 STD)' AS Remark
- UNION ALL SELECT 1329015030102, 'aidopS5InvInboundBtn02',
- 's5InventoryInbound:run-once',
- '库存冷链跑一轮', 920,
- 'S5 冷链管理权限点 POST /api/S5InventoryInbound/run-once(写 STG + UPSERT STD)'
- UNION ALL SELECT 1329015030103, 'aidopS5InvInboundBtn03',
- 's5InventoryInbound:reconcile',
- '库存冷链全量校准', 930,
- 'S5 冷链管理权限点 POST /api/S5InventoryInbound/reconcile(写 STG + 全量替换 STD)'
- UNION ALL SELECT 1329015030104, 'aidopS5InvInboundBtn04',
- 's5InventoryInbound:transform-std',
- '库存流水 stg→std 补转换', 940,
- 'S5 冷链管理权限点 POST /api/S5InventoryInbound/transform-std(写 mdp_std_inv_trans)'
- UNION ALL SELECT 1329015030105, 'aidopS5InvInboundBtn05',
- 's5InventoryInbound:transform-inventory-std',
- '库存余额 stg→std 补物化', 950,
- 'S5 冷链管理权限点 POST /api/S5InventoryInbound/transform-inventory-std(写 mdp_std_inventory)'
- UNION ALL SELECT 1329015030106, 'aidopS5InvInboundBtn06',
- 's5InventoryInbound:daily-recon',
- '库存日终对账(手工)', 960,
- 'S5 冷链管理权限点 POST /api/S5InventoryInbound/daily-recon(写 ado_inventory_recon_diff)'
- ) s
- WHERE @parent_menu IS NOT NULL
- AND NOT EXISTS (SELECT 1 FROM SysMenu m WHERE m.Permission = s.Permission AND m.Type = 3);
- -- ---------------------------------------------------------------------------
- -- 2. 租户级授权:只给拥有真实 SysAdmin 运维账号的租户(AIDOP)
- -- 不给 UAT 租户,不给默认租户(超管走 AccountType=999 旁路,无需授权)
- -- ---------------------------------------------------------------------------
- SET @tm_base := (SELECT IFNULL(MAX(Id), 0) FROM SysTenantMenu);
- INSERT INTO SysTenantMenu (Id, TenantId, MenuId)
- SELECT @tm_base + ROW_NUMBER() OVER (ORDER BY m.Id), @admin_tenant, m.Id
- FROM SysMenu m
- WHERE @admin_tenant IS NOT NULL
- AND m.Type = 3
- AND m.Permission IN (
- 's5InventoryInbound:bootstrap',
- 's5InventoryInbound:run-once',
- 's5InventoryInbound:reconcile',
- 's5InventoryInbound:transform-std',
- 's5InventoryInbound:transform-inventory-std',
- 's5InventoryInbound:daily-recon')
- AND NOT EXISTS (
- SELECT 1 FROM SysTenantMenu tm
- WHERE tm.TenantId = @admin_tenant AND tm.MenuId = m.Id);
|