BEGIN; -- ============================================================================ -- LeAudit Platform Usage Stats RBAC Seed -- 目标: -- 1. 为“系统使用统计”补齐菜单路由 -- 2. 补齐 usage-stats 相关 API 权限点 -- 3. 为 super_admin / provincial_admin / admin 分配菜单和权限 -- 说明: -- - super_admin / provincial_admin 使用 ALL 数据范围 -- - admin 使用 DEPT 数据范围,对应地区管理员只看本地区 -- - 幂等脚本,可重复执行 -- ============================================================================ WITH settings_root AS ( SELECT id FROM sys_routes WHERE route_path = '/settings' AND deleted_at IS NULL LIMIT 1 ) 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 ) SELECT '/usage-stats', 'usage-stats', 'usage-stats', settings_root.id, '系统使用统计', 'ri-bar-chart-box-line', 4, FALSE, TRUE, '{"group":"settings"}'::jsonb, 0, NOW(), NOW(), NULL FROM settings_root 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; WITH usage_route AS ( SELECT id FROM sys_routes WHERE route_path = '/usage-stats' AND deleted_at IS NULL LIMIT 1 ) INSERT INTO permissions ( permission_key, module, resource, action, description, display_name, permission_type, is_system, metadata, created_at, updated_at, created_by, updated_by, parent_id, sort_order, route_id, api_path, api_method, related_routes ) SELECT seed.permission_key, seed.module, seed.resource, seed.action, seed.description, seed.display_name, seed.permission_type, seed.is_system, seed.metadata, seed.created_at, seed.updated_at, seed.created_by, seed.updated_by, seed.parent_id, seed.sort_order, usage_route.id AS route_id, seed.api_path, seed.api_method, seed.related_routes FROM ( VALUES ('usage_stats:overview:read', 'usage_stats', 'overview', 'read', '查看系统使用统计总览', '查看统计总览', 'API', TRUE, NULL::jsonb, NOW(), NOW(), NULL::bigint, NULL::bigint, NULL::bigint, 210, NULL::bigint, '/api/v3/usage-stats/overview', 'GET', NULL::bigint[]), ('usage_stats:trends:read', 'usage_stats', 'trends', 'read', '查看系统使用趋势', '查看统计趋势', 'API', TRUE, NULL::jsonb, NOW(), NOW(), NULL::bigint, NULL::bigint, NULL::bigint, 211, NULL::bigint, '/api/v3/usage-stats/trends', 'GET', NULL::bigint[]), ('usage_stats:users:read', 'usage_stats', 'users', 'read', '查看用户维度统计', '查看用户统计', 'API', TRUE, NULL::jsonb, NOW(), NOW(), NULL::bigint, NULL::bigint, NULL::bigint, 212, NULL::bigint, '/api/v3/usage-stats/by-users', 'GET', NULL::bigint[]), ('usage_stats:departments:read', 'usage_stats', 'departments', 'read', '查看部门维度统计', '查看部门统计', 'API', TRUE, NULL::jsonb, NOW(), NOW(), NULL::bigint, NULL::bigint, NULL::bigint, 213, NULL::bigint, '/api/v3/usage-stats/by-departments', 'GET', NULL::bigint[]), ('usage_stats:areas:read', 'usage_stats', 'areas', 'read', '查看地区维度统计', '查看地区统计', 'API', TRUE, NULL::jsonb, NOW(), NOW(), NULL::bigint, NULL::bigint, NULL::bigint, 214, NULL::bigint, '/api/v3/usage-stats/by-areas', 'GET', NULL::bigint[]), ('usage_stats:details:read', 'usage_stats', 'details', 'read', '查看统计明细', '查看统计明细', 'API', TRUE, NULL::jsonb, NOW(), NOW(), NULL::bigint, NULL::bigint, NULL::bigint, 215, NULL::bigint, '/api/v3/usage-stats/details', 'GET', NULL::bigint[]) ) AS seed( permission_key, module, resource, action, description, display_name, permission_type, is_system, metadata, created_at, updated_at, created_by, updated_by, parent_id, sort_order, route_id, api_path, api_method, related_routes ) CROSS JOIN usage_route ON CONFLICT (permission_key) DO UPDATE SET module = EXCLUDED.module, resource = EXCLUDED.resource, action = EXCLUDED.action, description = EXCLUDED.description, display_name = EXCLUDED.display_name, permission_type = EXCLUDED.permission_type, is_system = EXCLUDED.is_system, updated_at = NOW(), api_path = EXCLUDED.api_path, api_method = EXCLUDED.api_method, sort_order = EXCLUDED.sort_order; 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 = '/usage-stats' ), seed(role_key, route_path, permission, status) AS ( VALUES ('super_admin', '/usage-stats', 'R', 1), ('provincial_admin', '/usage-stats', 'R', 1), ('admin', '/usage-stats', 'R', 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(); WITH role_map AS ( SELECT id, role_key FROM roles WHERE role_key IN ('super_admin', 'provincial_admin', 'admin') ), perm_map AS ( SELECT id, permission_key FROM permissions WHERE permission_key LIKE 'usage_stats:%' ), seed(role_key, permission_key, grant_type, data_scope) AS ( VALUES ('super_admin', 'usage_stats:overview:read', 'GRANT', 'ALL'), ('super_admin', 'usage_stats:trends:read', 'GRANT', 'ALL'), ('super_admin', 'usage_stats:users:read', 'GRANT', 'ALL'), ('super_admin', 'usage_stats:departments:read', 'GRANT', 'ALL'), ('super_admin', 'usage_stats:areas:read', 'GRANT', 'ALL'), ('super_admin', 'usage_stats:details:read', 'GRANT', 'ALL'), ('provincial_admin', 'usage_stats:overview:read', 'GRANT', 'ALL'), ('provincial_admin', 'usage_stats:trends:read', 'GRANT', 'ALL'), ('provincial_admin', 'usage_stats:users:read', 'GRANT', 'ALL'), ('provincial_admin', 'usage_stats:departments:read', 'GRANT', 'ALL'), ('provincial_admin', 'usage_stats:areas:read', 'GRANT', 'ALL'), ('provincial_admin', 'usage_stats:details:read', 'GRANT', 'ALL'), ('admin', 'usage_stats:overview:read', 'GRANT', 'DEPT'), ('admin', 'usage_stats:trends:read', 'GRANT', 'DEPT'), ('admin', 'usage_stats:users:read', 'GRANT', 'DEPT'), ('admin', 'usage_stats:departments:read', 'GRANT', 'DEPT'), ('admin', 'usage_stats:areas:read', 'GRANT', 'DEPT'), ('admin', 'usage_stats:details:read', 'GRANT', 'DEPT') ) INSERT INTO role_permissions (role_id, permission_id, grant_type, data_scope, created_at, updated_at) SELECT rm.id, pm.id, seed.grant_type, seed.data_scope, NOW(), NOW() FROM seed JOIN role_map rm ON rm.role_key = seed.role_key JOIN perm_map pm ON pm.permission_key = seed.permission_key ON CONFLICT (role_id, permission_id) DO UPDATE SET grant_type = EXCLUDED.grant_type, data_scope = EXCLUDED.data_scope, updated_at = NOW(); COMMIT;