20261027_wechat_cert_notice_role.sql 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. -- MySQL 5.7:证件到期通知接收人角色(可重复执行)。
  2. -- 仅建立角色及 Web 证件提醒列表菜单/祖先授权,不自动绑定任何用户。
  3. -- 新角色为 data_scope=5 且无自定义明细:不扩大用户已有多角色数据范围。
  4. -- 既有同名角色的状态、数据权限及自定义明细保持不变。
  5. -- 使用临时过程遍历任意深度祖先;需要 CREATE ROUTINE 权限。
  6. SET NAMES utf8mb4;
  7. DELIMITER $$
  8. DROP PROCEDURE IF EXISTS migrate_20261027_cert_notice_role$$
  9. CREATE PROCEDURE migrate_20261027_cert_notice_role()
  10. BEGIN
  11. DECLARE added_rows INT DEFAULT 1;
  12. DECLARE EXIT HANDLER FOR SQLEXCEPTION
  13. BEGIN
  14. ROLLBACK;
  15. DROP TEMPORARY TABLE IF EXISTS tmp_cert_notice_valid;
  16. DROP TEMPORARY TABLE IF EXISTS tmp_cert_notice_next;
  17. DROP TEMPORARY TABLE IF EXISTS tmp_cert_notice_frontier;
  18. DROP TEMPORARY TABLE IF EXISTS tmp_cert_notice_chain;
  19. RESIGNAL;
  20. END;
  21. DROP TEMPORARY TABLE IF EXISTS tmp_cert_notice_valid;
  22. DROP TEMPORARY TABLE IF EXISTS tmp_cert_notice_next;
  23. DROP TEMPORARY TABLE IF EXISTS tmp_cert_notice_frontier;
  24. DROP TEMPORARY TABLE IF EXISTS tmp_cert_notice_chain;
  25. CREATE TEMPORARY TABLE tmp_cert_notice_chain (
  26. tenant_no VARCHAR(64) NOT NULL,
  27. leaf_id VARCHAR(64) NOT NULL,
  28. menu_id VARCHAR(64) NOT NULL,
  29. parent_id VARCHAR(64) NOT NULL,
  30. path VARCHAR(200) NOT NULL,
  31. PRIMARY KEY (tenant_no, leaf_id, menu_id)
  32. ) ENGINE=InnoDB ROW_FORMAT=DYNAMIC DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
  33. CREATE TEMPORARY TABLE tmp_cert_notice_frontier LIKE tmp_cert_notice_chain;
  34. CREATE TEMPORARY TABLE tmp_cert_notice_next LIKE tmp_cert_notice_chain;
  35. CREATE TEMPORARY TABLE tmp_cert_notice_valid (
  36. tenant_no VARCHAR(64) NOT NULL,
  37. leaf_id VARCHAR(64) NOT NULL,
  38. PRIMARY KEY (tenant_no, leaf_id)
  39. ) ENGINE=InnoDB ROW_FORMAT=DYNAMIC DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
  40. START TRANSACTION;
  41. INSERT INTO sys_role (
  42. id, role_name, data_scope, status, tenant_no, order_num, remark,
  43. create_by, create_dept_id, create_time, update_by, update_time, del_flag
  44. )
  45. SELECT UUID(), '证件到期通知接收人', '5', '1', t.tenant_no, 0,
  46. '接收每日证件到期汇总;数据权限由已有角色并集决定,请手动绑定接收用户',
  47. 'system', '', NOW(), 'system', NOW(), 0
  48. FROM (SELECT DISTINCT tenant_no FROM sys_tenant WHERE del_flag=0) t
  49. WHERE NOT EXISTS (
  50. SELECT 1 FROM sys_role r WHERE r.tenant_no=t.tenant_no
  51. AND r.role_name='证件到期通知接收人' AND r.del_flag=0
  52. );
  53. INSERT INTO tmp_cert_notice_chain
  54. SELECT m.tenant_no, m.id, m.id, m.parent_id, m.path
  55. FROM sys_menu m
  56. WHERE m.del_flag=0 AND m.status='1' AND m.menu_type='C'
  57. AND m.path='document-reminder'
  58. AND m.component='pl/inventory/document-reminder'
  59. AND m.perms='pl:document:list'
  60. AND EXISTS (SELECT 1 FROM sys_tenant t WHERE t.tenant_no=m.tenant_no AND t.del_flag=0);
  61. INSERT INTO tmp_cert_notice_frontier SELECT * FROM tmp_cert_notice_chain;
  62. -- 始终同租户向上遍历,仅授予目录祖先,绝不加入按钮或修改权限。
  63. WHILE added_rows > 0 DO
  64. DELETE FROM tmp_cert_notice_next;
  65. INSERT INTO tmp_cert_notice_next
  66. SELECT DISTINCT f.tenant_no, f.leaf_id, p.id, p.parent_id, p.path
  67. FROM tmp_cert_notice_frontier f
  68. JOIN sys_menu p ON p.id=f.parent_id AND p.tenant_no=f.tenant_no
  69. LEFT JOIN tmp_cert_notice_chain seen
  70. ON seen.tenant_no=f.tenant_no AND seen.leaf_id=f.leaf_id AND seen.menu_id=p.id
  71. WHERE p.del_flag=0 AND p.status='1' AND p.menu_type='M'
  72. AND (p.perms IS NULL OR p.perms='' OR p.perms LIKE '%:list')
  73. AND seen.menu_id IS NULL;
  74. SET added_rows = ROW_COUNT();
  75. INSERT INTO tmp_cert_notice_chain SELECT * FROM tmp_cert_notice_next;
  76. DELETE FROM tmp_cert_notice_frontier;
  77. INSERT INTO tmp_cert_notice_frontier SELECT * FROM tmp_cert_notice_next;
  78. END WHILE;
  79. -- 只有完整抵达本租户 /web 虚拟根的链有效;小程序或跨租户/断裂链不授权。
  80. INSERT INTO tmp_cert_notice_valid
  81. SELECT DISTINCT tenant_no, leaf_id FROM tmp_cert_notice_chain
  82. WHERE parent_id='0' AND path='/web';
  83. INSERT INTO sys_role_menu (
  84. id, role_id, menu_id, tenant_no, order_num, remark,
  85. create_by, create_dept_id, create_time, update_by, update_time, del_flag
  86. )
  87. SELECT UUID(), assignments.role_id, assignments.menu_id, assignments.tenant_no, 0,
  88. '证件到期通知接收人:Web 证件提醒列表及祖先目录',
  89. 'system', '', NOW(), 'system', NOW(), 0
  90. FROM (
  91. SELECT DISTINCT r.id AS role_id, c.menu_id, r.tenant_no
  92. FROM sys_role r
  93. JOIN tmp_cert_notice_chain c ON c.tenant_no=r.tenant_no
  94. JOIN tmp_cert_notice_valid v ON v.tenant_no=c.tenant_no AND v.leaf_id=c.leaf_id
  95. WHERE r.role_name='证件到期通知接收人' AND r.del_flag=0
  96. ) assignments
  97. WHERE NOT EXISTS (
  98. SELECT 1 FROM sys_role_menu rm
  99. WHERE rm.role_id=assignments.role_id AND rm.menu_id=assignments.menu_id
  100. AND rm.tenant_no=assignments.tenant_no AND rm.del_flag=0
  101. );
  102. COMMIT;
  103. DROP TEMPORARY TABLE tmp_cert_notice_valid;
  104. DROP TEMPORARY TABLE tmp_cert_notice_next;
  105. DROP TEMPORARY TABLE tmp_cert_notice_frontier;
  106. DROP TEMPORARY TABLE tmp_cert_notice_chain;
  107. END$$
  108. CALL migrate_20261027_cert_notice_role()$$
  109. DROP PROCEDURE migrate_20261027_cert_notice_role$$
  110. DELIMITER ;