BEGIN; -- 补齐当前前端真实菜单树里仍需要暴露的模块路由: -- 1. AI 对话 -- 2. 合同管理(搜索/列表) -- 3. 交叉评查 WITH upsert_routes AS ( INSERT INTO sys_routes ( route_path, route_name, component, parent_id, route_title, icon, sort_order, is_hidden, is_cache, meta, status, created_at, updated_at, deleted_at ) VALUES ('/chat-with-llm', 'chat-with-llm', 'chat-with-llm', NULL, 'AI对话', 'ri-chat-smile-2-line', 20, FALSE, TRUE, '{"group":"assistant"}'::jsonb, 0, NOW(), NOW(), NULL), ('/contract-template', 'contract-template', 'contract-template', NULL, '合同管理', 'ri-file-search-line', 50, FALSE, TRUE, '{"group":"contract"}'::jsonb, 0, NOW(), NOW(), NULL), ('/cross-checking', 'cross-checking', 'cross-checking', NULL, '交叉评查', 'ri-color-filter-line', 70, FALSE, TRUE, '{"group":"cross-review"}'::jsonb, 0, NOW(), NOW(), NULL) ON CONFLICT (route_path) WHERE deleted_at IS NULL DO UPDATE SET route_name = EXCLUDED.route_name, component = EXCLUDED.component, route_title = EXCLUDED.route_title, icon = EXCLUDED.icon, sort_order = EXCLUDED.sort_order, is_hidden = EXCLUDED.is_hidden, is_cache = EXCLUDED.is_cache, meta = EXCLUDED.meta, status = 0, updated_at = NOW(), deleted_at = NULL RETURNING id, route_path ), all_root_routes AS ( SELECT id, route_path FROM sys_routes WHERE deleted_at IS NULL AND route_path IN ('/chat-with-llm', '/contract-template', '/cross-checking') ), template_root AS ( SELECT id FROM all_root_routes WHERE route_path = '/contract-template' ), cross_root AS ( SELECT id FROM all_root_routes WHERE route_path = '/cross-checking' ) INSERT INTO sys_routes ( route_path, route_name, component, parent_id, route_title, icon, sort_order, is_hidden, is_cache, meta, status, created_at, updated_at, deleted_at ) VALUES ('/contract-template/search', 'contract-template.search', 'contract-template.search', (SELECT id FROM template_root), '模板搜索', 'ri-search-line', 1, FALSE, TRUE, '{"group":"contract"}'::jsonb, 0, NOW(), NOW(), NULL), ('/contract-template/list', 'contract-template.list', 'contract-template.list', (SELECT id FROM template_root), '模板列表', 'ri-folder-line', 2, FALSE, TRUE, '{"group":"contract"}'::jsonb, 0, NOW(), NOW(), NULL), ('/cross-checking/upload', 'cross-checking.upload', 'cross-checking.upload', (SELECT id FROM cross_root), '创建任务', 'ri-upload-cloud-line', 1, FALSE, TRUE, '{"group":"cross-review"}'::jsonb, 0, NOW(), NOW(), NULL), ('/cross-checking/result', 'cross-checking.result', 'cross-checking.result', (SELECT id FROM cross_root), '评查结果', 'ri-file-list-3-line', 2, FALSE, TRUE, '{"group":"cross-review"}'::jsonb, 0, NOW(), NOW(), NULL) ON CONFLICT (route_path) WHERE deleted_at IS NULL DO UPDATE SET route_name = EXCLUDED.route_name, component = EXCLUDED.component, parent_id = EXCLUDED.parent_id, route_title = EXCLUDED.route_title, icon = EXCLUDED.icon, sort_order = EXCLUDED.sort_order, is_hidden = EXCLUDED.is_hidden, is_cache = EXCLUDED.is_cache, meta = EXCLUDED.meta, status = 0, updated_at = NOW(), deleted_at = NULL; -- 修正旧环境已存在记录的父子关系与显示名,避免菜单被拆成多个平级项 UPDATE sys_routes AS child SET parent_id = root.id, route_title = CASE WHEN child.route_path = '/contract-template/search' THEN '模板搜索' WHEN child.route_path = '/contract-template/list' THEN '模板列表' WHEN child.route_path = '/cross-checking/upload' THEN '创建任务' WHEN child.route_path = '/cross-checking/result' THEN '评查结果' ELSE child.route_title END, updated_at = NOW() FROM sys_routes root WHERE child.deleted_at IS NULL AND root.deleted_at IS NULL AND ( (child.route_path IN ('/contract-template/search', '/contract-template/list') AND root.route_path = '/contract-template') OR (child.route_path IN ('/cross-checking/upload', '/cross-checking/result') AND root.route_path = '/cross-checking') ); UPDATE sys_routes SET route_title = CASE WHEN route_path = '/contract-template' THEN '合同管理' WHEN route_path = '/contract-template/search' THEN '模板搜索' WHEN route_path = '/contract-template/list' THEN '模板列表' ELSE route_title END, updated_at = NOW() WHERE deleted_at IS NULL AND route_path IN ('/contract-template', '/contract-template/search', '/contract-template/list'); WITH role_map AS ( SELECT id, role_key FROM roles WHERE role_key IN ('super_admin', 'provincial_admin', 'admin') ), route_map AS ( SELECT id, route_path FROM sys_routes WHERE deleted_at IS NULL AND route_path IN ( '/chat-with-llm', '/contract-template', '/contract-template/search', '/contract-template/list', '/cross-checking', '/cross-checking/upload', '/cross-checking/result' ) ), seed(role_key, route_path, permission, status) AS ( VALUES ('super_admin', '/chat-with-llm', 'RW', 1), ('super_admin', '/contract-template', 'RW', 1), ('super_admin', '/contract-template/search', 'RW', 1), ('super_admin', '/contract-template/list', 'RW', 1), ('super_admin', '/cross-checking', 'RW', 1), ('super_admin', '/cross-checking/upload', 'RW', 1), ('super_admin', '/cross-checking/result', 'RW', 1), ('provincial_admin', '/chat-with-llm', 'RW', 1), ('provincial_admin', '/contract-template', 'RW', 1), ('provincial_admin', '/contract-template/search', 'RW', 1), ('provincial_admin', '/contract-template/list', 'RW', 1), ('provincial_admin', '/cross-checking', 'RW', 1), ('provincial_admin', '/cross-checking/upload', 'RW', 1), ('provincial_admin', '/cross-checking/result', 'RW', 1), ('admin', '/chat-with-llm', 'RW', 1), ('admin', '/contract-template', 'RW', 1), ('admin', '/contract-template/search', 'RW', 1), ('admin', '/contract-template/list', 'RW', 1), ('admin', '/cross-checking', 'RW', 1), ('admin', '/cross-checking/upload', 'RW', 1), ('admin', '/cross-checking/result', 'RW', 1) ) INSERT INTO role_route (role_id, route_id, permission, status, created_at, updated_at) SELECT rm.id, tm.id, s.permission, s.status, NOW(), NOW() FROM seed s JOIN role_map rm ON rm.role_key = s.role_key JOIN route_map tm ON tm.route_path = s.route_path ON CONFLICT (role_id, route_id) DO UPDATE SET permission = EXCLUDED.permission, status = EXCLUDED.status, updated_at = NOW(); COMMIT;