| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258 |
- -- 排水基础数据(工程设施 / 易积水点):菜单、按钮、角色授权
- --
- -- 覆盖范围:
- -- 页面菜单(menu_type='C')
- -- · 工程设施基础数据管理 subSystem/drainage/jcsj/gcssgl
- -- · 易积水点管理 subSystem/drainage/jcsj/yjsdgl
- -- 按钮权限(menu_type='F')
- -- · drainage:facility:add / edit / remove
- -- · drainage:waterlogging:add / edit / remove
- -- 角色授权(sys_role_menu)
- -- · 新建页面菜单 → 授予「已经拥有其父级目录(基础数据)权限」的角色
- -- · 新建按钮 → 授予「已经拥有该页面菜单权限」的角色
- -- 这样只跟随既有授权扩散,不会把按钮放开给原本没权限的角色。
- --
- -- 父级定位(多路兜底):
- -- 1) 用兄弟页面 component='subSystem/drainage/jcsj/psfqgl' 反查 parent_id(最可靠)
- -- 2) 任意 drainage/jcsj 页面的 parent_id
- -- 3) menu_type='M' 且 menu_name='基础数据'
- --
- -- 幂等:菜单按 component 判重,按钮按 parent_id + perms 判重,授权按 (role_id, menu_id) 判重,
- -- 可重复执行;已存在的菜单只更新名称/路径/组件/权限标识,不改排序与父级。
- -- 主键:menu_id 显式取 max+1 —— 本库由 MySQL 迁移而来,自增计数器可能未推进。
- --
- -- 执行后建议重新登录一次,让前端重新拉取菜单与权限。
- --
- -- 前置:结束上一次失败执行遗留的 aborted 事务(事务外执行只会告警,不报错)
- ROLLBACK;
- BEGIN;
- SET search_path TO app_user, public;
- DO $$
- DECLARE
- v_parent bigint;
- v_page bigint;
- v_next bigint;
- v_role record;
- r record;
- -- 【按需修改】需要直接授予这套菜单/按钮的角色 role_key。
- -- 上面的步骤只会「跟随既有授权」扩散(谁原本能进基础数据,谁就拿到新页面;
- -- 谁原本能进该页面,谁就拿到新按钮)。如果目标角色原本连基础数据目录都没有,
- -- 就在这里显式列出它的 role_key,脚本会额外给它授权。
- -- 先执行 `SELECT role_id, role_key, role_name FROM sys_role;` 查清 role_key 再填。
- -- 留空数组表示不做额外授权。
- v_extra_role_keys text[] := ARRAY[]::text[];
- BEGIN
- -- ================================================================
- -- 1. 定位「基础数据」目录
- -- ================================================================
- SELECT parent_id INTO v_parent
- FROM sys_menu
- WHERE component = 'subSystem/drainage/jcsj/psfqgl'
- LIMIT 1;
- IF v_parent IS NULL THEN
- SELECT parent_id INTO v_parent
- FROM sys_menu
- WHERE component LIKE '%drainage/jcsj/%'
- AND parent_id IS NOT NULL
- AND parent_id <> 0
- LIMIT 1;
- END IF;
- IF v_parent IS NULL THEN
- SELECT menu_id INTO v_parent
- FROM sys_menu
- WHERE menu_type = 'M'
- AND menu_name = '基础数据'
- LIMIT 1;
- END IF;
- IF v_parent IS NULL THEN
- RAISE NOTICE '未找到「基础数据」目录菜单,请先确认排水子系统菜单结构后手工添加。';
- RETURN;
- END IF;
- RAISE NOTICE '「基础数据」目录 menu_id = %', v_parent;
- -- ================================================================
- -- 2. 页面菜单(menu_type = 'C')
- -- ================================================================
- FOR r IN
- SELECT * FROM (VALUES
- ('工程设施基础数据管理', 'gcssgl', 'subSystem/drainage/jcsj/gcssgl',
- 'drainage:facility:list', 'guide', 3),
- ('易积水点管理', 'yjsdgl', 'subSystem/drainage/jcsj/yjsdgl',
- 'drainage:waterlogging:list', 'location', 4)
- ) AS x(menu_name, path, component, perms, icon, order_num)
- LOOP
- -- 先按「组件 + 基础数据目录」精确定位,避免多子系统复用同一组件时取错记录
- SELECT menu_id INTO v_page
- FROM sys_menu
- WHERE component = r.component AND parent_id = v_parent
- LIMIT 1;
- IF v_page IS NULL THEN
- SELECT menu_id INTO v_page
- FROM sys_menu
- WHERE component = r.component
- LIMIT 1;
- END IF;
- IF v_page IS NULL THEN
- SELECT COALESCE(MAX(menu_id), 0) + 1 INTO v_next FROM sys_menu;
- INSERT INTO sys_menu
- (menu_id, menu_name, parent_id, order_num, path, component,
- is_frame, is_cache, menu_type, visible, status, perms, icon,
- create_by, create_time, remark)
- VALUES
- (v_next, r.menu_name, v_parent, r.order_num, r.path, r.component,
- 1, 0, 'C', '0', '0', r.perms, r.icon,
- 'admin', CURRENT_TIMESTAMP, r.menu_name);
- v_page := v_next;
- RAISE NOTICE '已新增页面菜单:% (menu_id=%)', r.menu_name, v_page;
- -- 跟随父级授权:拥有「基础数据」目录的角色,一并获得新页面
- INSERT INTO sys_role_menu (role_id, menu_id)
- SELECT DISTINCT rm.role_id, v_page
- FROM sys_role_menu rm
- WHERE rm.menu_id = v_parent
- AND NOT EXISTS (
- SELECT 1 FROM sys_role_menu e
- WHERE e.role_id = rm.role_id AND e.menu_id = v_page
- );
- RAISE NOTICE ' → 已按「基础数据」目录的授权同步给角色';
- ELSE
- UPDATE sys_menu
- SET menu_name = r.menu_name,
- path = r.path,
- component = r.component,
- menu_type = 'C',
- visible = '0',
- status = '0',
- perms = r.perms,
- icon = r.icon,
- update_by = 'admin',
- update_time = CURRENT_TIMESTAMP
- WHERE menu_id = v_page;
- RAISE NOTICE '页面菜单已存在,已同步名称/路径/组件:% (menu_id=%)', r.menu_name, v_page;
- END IF;
- END LOOP;
- -- ================================================================
- -- 3. 按钮权限(menu_type = 'F')
- -- ================================================================
- FOR r IN
- SELECT * FROM (VALUES
- ('subSystem/drainage/jcsj/gcssgl', '新增工程设施', 'drainage:facility:add', 1),
- ('subSystem/drainage/jcsj/gcssgl', '修改工程设施', 'drainage:facility:edit', 2),
- ('subSystem/drainage/jcsj/gcssgl', '删除工程设施', 'drainage:facility:remove', 3),
- ('subSystem/drainage/jcsj/yjsdgl', '新增易积水点', 'drainage:waterlogging:add', 1),
- ('subSystem/drainage/jcsj/yjsdgl', '修改易积水点', 'drainage:waterlogging:edit', 2),
- ('subSystem/drainage/jcsj/yjsdgl', '删除易积水点', 'drainage:waterlogging:remove', 3)
- ) AS x(parent_component, menu_name, perms, order_num)
- LOOP
- SELECT menu_id INTO v_page
- FROM sys_menu
- WHERE component = r.parent_component
- ORDER BY menu_id
- LIMIT 1;
- IF v_page IS NULL THEN
- RAISE NOTICE '跳过按钮 %:未找到页面菜单 %', r.perms, r.parent_component;
- CONTINUE;
- END IF;
- IF EXISTS (
- SELECT 1 FROM sys_menu
- WHERE perms = r.perms AND parent_id = v_page
- ) THEN
- RAISE NOTICE '按钮已存在,跳过:%', r.perms;
- CONTINUE;
- END IF;
- SELECT COALESCE(MAX(menu_id), 0) + 1 INTO v_next FROM sys_menu;
- INSERT INTO sys_menu
- (menu_id, menu_name, parent_id, order_num, path, component,
- is_frame, is_cache, menu_type, visible, status, perms, icon,
- create_by, create_time, remark)
- VALUES
- (v_next, r.menu_name, v_page, r.order_num, '', NULL,
- 1, 0, 'F', '0', '0', r.perms, '#',
- 'admin', CURRENT_TIMESTAMP, '页面按钮权限');
- RAISE NOTICE '已新增按钮:% (%)', r.menu_name, r.perms;
- -- 跟随页面授权:拥有该页面菜单的角色,一并获得新按钮
- INSERT INTO sys_role_menu (role_id, menu_id)
- SELECT DISTINCT rm.role_id, v_next
- FROM sys_role_menu rm
- WHERE rm.menu_id = v_page
- AND NOT EXISTS (
- SELECT 1 FROM sys_role_menu e
- WHERE e.role_id = rm.role_id AND e.menu_id = v_next
- );
- END LOOP;
- -- ================================================================
- -- 4. 显式角色授权(按需启用)
- -- 给 v_extra_role_keys 里列出的角色,一次性授齐:
- -- 两个页面菜单 + 六个按钮。
- -- ================================================================
- IF v_extra_role_keys IS NOT NULL AND array_length(v_extra_role_keys, 1) > 0 THEN
- FOR v_role IN
- SELECT role_id, role_key, role_name FROM sys_role WHERE role_key = ANY(v_extra_role_keys)
- LOOP
- INSERT INTO sys_role_menu (role_id, menu_id)
- SELECT v_role.role_id, m.menu_id
- FROM sys_menu m
- WHERE (
- m.component IN ('subSystem/drainage/jcsj/gcssgl', 'subSystem/drainage/jcsj/yjsdgl')
- OR m.perms IN ('drainage:facility:add', 'drainage:facility:edit', 'drainage:facility:remove',
- 'drainage:waterlogging:add', 'drainage:waterlogging:edit',
- 'drainage:waterlogging:remove')
- )
- AND NOT EXISTS (
- SELECT 1 FROM sys_role_menu e
- WHERE e.role_id = v_role.role_id AND e.menu_id = m.menu_id
- );
- RAISE NOTICE '已显式授权角色:% (%)', v_role.role_name, v_role.role_key;
- END LOOP;
- IF NOT FOUND THEN
- RAISE NOTICE '警告:v_extra_role_keys 中的 role_key 在 sys_role 里一个都没匹配到,请核对。';
- END IF;
- END IF;
- RAISE NOTICE '菜单与按钮处理完成。若某个角色仍看不到按钮,请在「角色管理」中手工勾选。';
- END $$;
- -- =====================================================================
- -- 结果核验(可选,取消注释执行)
- -- =====================================================================
- -- 页面菜单与按钮(应返回 2 个 'C' + 6 个 'F')
- -- SELECT m.menu_id, m.menu_name, m.parent_id, m.menu_type, m.perms, m.order_num
- -- FROM sys_menu m
- -- WHERE m.component IN ('subSystem/drainage/jcsj/gcssgl', 'subSystem/drainage/jcsj/yjsdgl')
- -- OR m.perms IN ('drainage:facility:add','drainage:facility:edit','drainage:facility:remove',
- -- 'drainage:waterlogging:add','drainage:waterlogging:edit','drainage:waterlogging:remove')
- -- ORDER BY m.menu_type DESC, m.order_num;
- -- 角色授权情况
- -- SELECT rm.role_id, r.role_name, m.menu_name, m.menu_type, m.perms
- -- FROM sys_role_menu rm
- -- JOIN sys_role r ON r.role_id = rm.role_id
- -- JOIN sys_menu m ON m.menu_id = rm.menu_id
- -- WHERE m.perms LIKE 'drainage:facility:%'
- -- OR m.perms LIKE 'drainage:waterlogging:%'
- -- OR m.component IN ('subSystem/drainage/jcsj/gcssgl', 'subSystem/drainage/jcsj/yjsdgl')
- -- ORDER BY rm.role_id, m.menu_type DESC, m.order_num;
- COMMIT;
|