feat: bootstrap user rbac foundation
This commit is contained in:
@@ -0,0 +1,137 @@
|
||||
-- ==========================================================================
|
||||
-- LeAudit Platform RBAC / User 中文注释补丁
|
||||
-- 目标:补齐 sso_users / roles / user_role / permissions / role_permissions /
|
||||
-- sys_routes / role_route 的表注释与列注释
|
||||
-- ============================================================================
|
||||
|
||||
BEGIN;
|
||||
|
||||
-- --------------------------------------------------------------------------
|
||||
-- 1. sso_users
|
||||
-- --------------------------------------------------------------------------
|
||||
COMMENT ON TABLE sso_users IS '用户主表:统一承载认证身份、组织信息、登录信息与单地区隔离核心字段';
|
||||
COMMENT ON COLUMN sso_users.id IS '主键ID';
|
||||
COMMENT ON COLUMN sso_users.sub IS '统一身份唯一标识,OAuth/SSO 主键';
|
||||
COMMENT ON COLUMN sso_users.username IS '登录名/工号/展示账号';
|
||||
COMMENT ON COLUMN sso_users.nick_name IS '用户真实姓名';
|
||||
COMMENT ON COLUMN sso_users.phone_number IS '手机号';
|
||||
COMMENT ON COLUMN sso_users.email IS '邮箱地址';
|
||||
COMMENT ON COLUMN sso_users.ou_id IS '所属组织单位ID/部门ID';
|
||||
COMMENT ON COLUMN sso_users.ou_name IS '所属组织单位名称/部门名称';
|
||||
COMMENT ON COLUMN sso_users.status IS '账户状态:0=正常,1=禁用';
|
||||
COMMENT ON COLUMN sso_users.is_leader IS '是否为负责人';
|
||||
COMMENT ON COLUMN sso_users.created_at IS '创建时间';
|
||||
COMMENT ON COLUMN sso_users.updated_at IS '更新时间';
|
||||
COMMENT ON COLUMN sso_users.deleted_at IS '软删除时间';
|
||||
COMMENT ON COLUMN sso_users.password IS '密码字段:当前阶段兼容旧值,后续应迁移为哈希';
|
||||
COMMENT ON COLUMN sso_users.try_count IS '尝试登录次数';
|
||||
COMMENT ON COLUMN sso_users.try_login_time IS '最近一次尝试登录时间';
|
||||
COMMENT ON COLUMN sso_users.area IS '用户主地区,当前系统唯一数据隔离字段';
|
||||
COMMENT ON COLUMN sso_users.mq_person_uuid IS '关联组织/人员同步系统中的人员UUID';
|
||||
COMMENT ON COLUMN sso_users.mq_account_uuid IS '关联组织/账号同步系统中的账号UUID';
|
||||
COMMENT ON COLUMN sso_users.mq_synced_at IS '最近一次组织/账号同步时间';
|
||||
COMMENT ON COLUMN sso_users.tenant_name IS '租户名称/管理单元名称';
|
||||
COMMENT ON COLUMN sso_users.dep_short_name IS '组织简称';
|
||||
COMMENT ON COLUMN sso_users.dep_name IS '组织名称';
|
||||
|
||||
-- --------------------------------------------------------------------------
|
||||
-- 2. roles
|
||||
-- --------------------------------------------------------------------------
|
||||
COMMENT ON TABLE roles IS '角色表:定义系统角色及其默认数据范围,当前主业务角色为 provincial_admin/admin/common';
|
||||
COMMENT ON COLUMN roles.id IS '主键ID';
|
||||
COMMENT ON COLUMN roles.role_key IS '角色机器标识,例如 provincial_admin/admin/common';
|
||||
COMMENT ON COLUMN roles.role_name IS '角色展示名称';
|
||||
COMMENT ON COLUMN roles.data_scope IS '默认数据范围:ALL=全部,DEPT=同地区,SELF=仅自己,GROUP仅保留兼容';
|
||||
COMMENT ON COLUMN roles.description IS '角色描述';
|
||||
COMMENT ON COLUMN roles.created_at IS '创建时间';
|
||||
COMMENT ON COLUMN roles.updated_at IS '更新时间';
|
||||
COMMENT ON COLUMN roles.parent_role_id IS '父角色ID,用于角色继承';
|
||||
COMMENT ON COLUMN roles.priority IS '角色优先级,数值越大优先级越高';
|
||||
COMMENT ON COLUMN roles.is_system_role IS '是否系统内置角色';
|
||||
COMMENT ON COLUMN roles.permissions_cache IS '权限缓存JSON,当前阶段不作为核心依赖';
|
||||
COMMENT ON COLUMN roles.metadata IS '扩展元数据JSON';
|
||||
|
||||
-- --------------------------------------------------------------------------
|
||||
-- 3. user_role
|
||||
-- --------------------------------------------------------------------------
|
||||
COMMENT ON TABLE user_role IS '用户角色关联表:一个用户可挂多个角色,用于聚合功能权限与数据范围';
|
||||
COMMENT ON COLUMN user_role.id IS '主键ID';
|
||||
COMMENT ON COLUMN user_role.user_id IS '用户ID,关联 sso_users.id';
|
||||
COMMENT ON COLUMN user_role.role_id IS '角色ID,关联 roles.id';
|
||||
COMMENT ON COLUMN user_role.created_at IS '创建时间';
|
||||
COMMENT ON COLUMN user_role.updated_at IS '更新时间';
|
||||
|
||||
-- --------------------------------------------------------------------------
|
||||
-- 4. permissions
|
||||
-- --------------------------------------------------------------------------
|
||||
COMMENT ON TABLE permissions IS '权限点定义表:统一定义 API/UI/数据权限点,权限键采用 module:resource:action 风格';
|
||||
COMMENT ON COLUMN permissions.id IS '主键ID';
|
||||
COMMENT ON COLUMN permissions.permission_key IS '权限键,例如 documents:list:read、audit:run:execute';
|
||||
COMMENT ON COLUMN permissions.module IS '所属模块,例如 auth/documents/audit/rules/users/rbac';
|
||||
COMMENT ON COLUMN permissions.resource IS '资源名,例如 list/detail/upload/run';
|
||||
COMMENT ON COLUMN permissions.action IS '动作名,例如 read/write/delete/execute';
|
||||
COMMENT ON COLUMN permissions.description IS '权限描述';
|
||||
COMMENT ON COLUMN permissions.display_name IS '权限展示名称';
|
||||
COMMENT ON COLUMN permissions.permission_type IS '权限类型:API/UI/DATA/RPC';
|
||||
COMMENT ON COLUMN permissions.is_system IS '是否系统内置权限';
|
||||
COMMENT ON COLUMN permissions.metadata IS '扩展元数据JSON';
|
||||
COMMENT ON COLUMN permissions.created_at IS '创建时间';
|
||||
COMMENT ON COLUMN permissions.updated_at IS '更新时间';
|
||||
COMMENT ON COLUMN permissions.created_by IS '创建人用户ID';
|
||||
COMMENT ON COLUMN permissions.updated_by IS '更新人用户ID';
|
||||
COMMENT ON COLUMN permissions.parent_id IS '父权限ID,用于构建权限树';
|
||||
COMMENT ON COLUMN permissions.sort_order IS '排序顺序';
|
||||
COMMENT ON COLUMN permissions.route_id IS '主关联路由ID,关联 sys_routes.id';
|
||||
COMMENT ON COLUMN permissions.api_path IS '对应后端 API 路径';
|
||||
COMMENT ON COLUMN permissions.api_method IS '对应后端 HTTP 方法';
|
||||
COMMENT ON COLUMN permissions.related_routes IS '共享权限可关联的多个路由ID列表';
|
||||
|
||||
-- --------------------------------------------------------------------------
|
||||
-- 5. role_permissions
|
||||
-- --------------------------------------------------------------------------
|
||||
COMMENT ON TABLE role_permissions IS '角色权限关联表:定义某角色拥有哪些权限点,以及该权限点对应的数据范围';
|
||||
COMMENT ON COLUMN role_permissions.id IS '主键ID';
|
||||
COMMENT ON COLUMN role_permissions.role_id IS '角色ID,关联 roles.id';
|
||||
COMMENT ON COLUMN role_permissions.permission_id IS '权限点ID,关联 permissions.id';
|
||||
COMMENT ON COLUMN role_permissions.grant_type IS '授权类型:GRANT=授予,DENY=拒绝';
|
||||
COMMENT ON COLUMN role_permissions.data_scope IS '数据范围:ALL=全部,DEPT=同地区,SELF=仅自己,GROUP仅保留兼容';
|
||||
COMMENT ON COLUMN role_permissions.condition_filter IS '高级条件过滤JSON,当前阶段不作为核心依赖';
|
||||
COMMENT ON COLUMN role_permissions.metadata IS '扩展元数据JSON';
|
||||
COMMENT ON COLUMN role_permissions.created_at IS '创建时间';
|
||||
COMMENT ON COLUMN role_permissions.created_by IS '创建人用户ID';
|
||||
COMMENT ON COLUMN role_permissions.updated_at IS '更新时间';
|
||||
COMMENT ON COLUMN role_permissions.updated_by IS '更新人用户ID';
|
||||
|
||||
-- --------------------------------------------------------------------------
|
||||
-- 6. sys_routes
|
||||
-- --------------------------------------------------------------------------
|
||||
COMMENT ON TABLE sys_routes IS '前端菜单/页面路由表:用于控制角色可见菜单,不替代 API 权限表';
|
||||
COMMENT ON COLUMN sys_routes.id IS '主键ID';
|
||||
COMMENT ON COLUMN sys_routes.route_path IS '前端路由路径';
|
||||
COMMENT ON COLUMN sys_routes.route_name IS '路由名称/内部标识';
|
||||
COMMENT ON COLUMN sys_routes.component IS '前端组件路径';
|
||||
COMMENT ON COLUMN sys_routes.parent_id IS '父路由ID';
|
||||
COMMENT ON COLUMN sys_routes.route_title IS '路由标题/菜单显示名';
|
||||
COMMENT ON COLUMN sys_routes.icon IS '菜单图标标识';
|
||||
COMMENT ON COLUMN sys_routes.sort_order IS '排序顺序';
|
||||
COMMENT ON COLUMN sys_routes.is_hidden IS '是否隐藏路由';
|
||||
COMMENT ON COLUMN sys_routes.is_cache IS '是否启用前端缓存';
|
||||
COMMENT ON COLUMN sys_routes.meta IS '路由扩展元数据JSON';
|
||||
COMMENT ON COLUMN sys_routes.status IS '状态:0=启用,1=禁用';
|
||||
COMMENT ON COLUMN sys_routes.created_at IS '创建时间';
|
||||
COMMENT ON COLUMN sys_routes.updated_at IS '更新时间';
|
||||
COMMENT ON COLUMN sys_routes.deleted_at IS '软删除时间';
|
||||
|
||||
-- --------------------------------------------------------------------------
|
||||
-- 7. role_route
|
||||
-- --------------------------------------------------------------------------
|
||||
COMMENT ON TABLE role_route IS '角色路由关联表:定义某角色可访问哪些菜单/页面路由';
|
||||
COMMENT ON COLUMN role_route.id IS '主键ID';
|
||||
COMMENT ON COLUMN role_route.role_id IS '角色ID,关联 roles.id';
|
||||
COMMENT ON COLUMN role_route.route_id IS '路由ID,关联 sys_routes.id';
|
||||
COMMENT ON COLUMN role_route.permission IS '路由权限类型:R=读,W=写,RW=读写';
|
||||
COMMENT ON COLUMN role_route.created_at IS '创建时间';
|
||||
COMMENT ON COLUMN role_route.updated_at IS '更新时间';
|
||||
COMMENT ON COLUMN role_route.status IS '状态:0=禁用,1=启用';
|
||||
|
||||
COMMIT;
|
||||
@@ -0,0 +1,85 @@
|
||||
-- ==========================================================================
|
||||
-- 老系统用户权限迁移前审计 SQL
|
||||
-- 目标库:docauditai
|
||||
-- 用途:在正式迁移 sso_users / roles / user_role / permissions / role_permissions / sys_routes / role_route 前,
|
||||
-- 先出质量统计,识别脏数据、空地区、无角色用户、历史脏角色。
|
||||
-- ============================================================================
|
||||
|
||||
-- 1. 基础行数
|
||||
SELECT 'sso_users' AS table_name, COUNT(*) AS total FROM sso_users
|
||||
UNION ALL SELECT 'roles', COUNT(*) FROM roles
|
||||
UNION ALL SELECT 'user_role', COUNT(*) FROM user_role
|
||||
UNION ALL SELECT 'permissions', COUNT(*) FROM permissions
|
||||
UNION ALL SELECT 'role_permissions', COUNT(*) FROM role_permissions
|
||||
UNION ALL SELECT 'sys_routes', COUNT(*) FROM sys_routes
|
||||
UNION ALL SELECT 'role_route', COUNT(*) FROM role_route;
|
||||
|
||||
-- 2. 用户地区分布
|
||||
SELECT COALESCE(NULLIF(BTRIM(area), ''), '<EMPTY>') AS area_value, COUNT(*) AS user_count
|
||||
FROM sso_users
|
||||
GROUP BY 1
|
||||
ORDER BY user_count DESC, area_value;
|
||||
|
||||
-- 3. 重复 sub
|
||||
SELECT sub, COUNT(*) AS dup_count
|
||||
FROM sso_users
|
||||
GROUP BY sub
|
||||
HAVING COUNT(*) > 1
|
||||
ORDER BY dup_count DESC, sub;
|
||||
|
||||
-- 4. 重复 username
|
||||
SELECT username, COUNT(*) AS dup_count
|
||||
FROM sso_users
|
||||
GROUP BY username
|
||||
HAVING COUNT(*) > 1
|
||||
ORDER BY dup_count DESC, username;
|
||||
|
||||
-- 5. 空地区 / 禁用 / 软删除 用户统计
|
||||
SELECT
|
||||
COUNT(*) FILTER (WHERE area IS NULL OR BTRIM(area) = '') AS empty_area_count,
|
||||
COUNT(*) FILTER (WHERE status <> 0) AS disabled_count,
|
||||
COUNT(*) FILTER (WHERE deleted_at IS NOT NULL) AS deleted_count
|
||||
FROM sso_users;
|
||||
|
||||
-- 6. 无角色用户
|
||||
SELECT u.id, u.sub, u.username, u.nick_name, u.area
|
||||
FROM sso_users u
|
||||
LEFT JOIN user_role ur ON ur.user_id = u.id
|
||||
WHERE ur.id IS NULL
|
||||
ORDER BY u.id;
|
||||
|
||||
-- 7. 角色分布
|
||||
SELECT r.role_key, r.role_name, COUNT(ur.user_id) AS user_count
|
||||
FROM roles r
|
||||
LEFT JOIN user_role ur ON ur.role_id = r.id
|
||||
GROUP BY r.id, r.role_key, r.role_name
|
||||
ORDER BY user_count DESC, r.role_key;
|
||||
|
||||
-- 8. 历史角色排查(重点看是否还有不应带入新系统的角色)
|
||||
SELECT role_key, role_name, data_scope, description
|
||||
FROM roles
|
||||
ORDER BY role_key;
|
||||
|
||||
-- 9. user_role 脏引用
|
||||
SELECT ur.*
|
||||
FROM user_role ur
|
||||
LEFT JOIN sso_users u ON u.id = ur.user_id
|
||||
LEFT JOIN roles r ON r.id = ur.role_id
|
||||
WHERE u.id IS NULL OR r.id IS NULL
|
||||
ORDER BY ur.id;
|
||||
|
||||
-- 10. role_permissions 脏引用
|
||||
SELECT rp.*
|
||||
FROM role_permissions rp
|
||||
LEFT JOIN roles r ON r.id = rp.role_id
|
||||
LEFT JOIN permissions p ON p.id = rp.permission_id
|
||||
WHERE r.id IS NULL OR p.id IS NULL
|
||||
ORDER BY rp.id;
|
||||
|
||||
-- 11. role_route 脏引用
|
||||
SELECT rr.*
|
||||
FROM role_route rr
|
||||
LEFT JOIN roles r ON r.id = rr.role_id
|
||||
LEFT JOIN sys_routes sr ON sr.id = rr.route_id
|
||||
WHERE r.id IS NULL OR sr.id IS NULL
|
||||
ORDER BY rr.id;
|
||||
@@ -0,0 +1,287 @@
|
||||
-- ==========================================================================
|
||||
-- LeAudit Platform RBAC / User Schema Patch
|
||||
-- 目标:在当前 leaudit_platform 新库中补齐用户、角色、权限、路由核心表
|
||||
-- 设计原则:
|
||||
-- 1. 兼容老系统 docauditai 的核心字段语义
|
||||
-- 2. 新系统只做单地区隔离,地区字段统一使用 sso_users.area
|
||||
-- 3. 采用 bigint 主键,兼容新库现有 leaudit_* bigint 引用字段
|
||||
-- 4. 当前库里尚不存在 sso_users / roles / permissions / role_permissions / sys_routes / role_route / user_role
|
||||
-- ============================================================================
|
||||
|
||||
BEGIN;
|
||||
|
||||
-- --------------------------------------------------------------------------
|
||||
-- 1. 用户主表 sso_users
|
||||
-- --------------------------------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS sso_users (
|
||||
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||
sub VARCHAR(128) NOT NULL,
|
||||
username VARCHAR(128) NOT NULL,
|
||||
nick_name VARCHAR(128) NOT NULL,
|
||||
phone_number VARCHAR(64),
|
||||
email VARCHAR(256),
|
||||
ou_id VARCHAR(128) NOT NULL,
|
||||
ou_name VARCHAR(255) NOT NULL,
|
||||
status SMALLINT NOT NULL DEFAULT 0,
|
||||
is_leader BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
deleted_at TIMESTAMP WITHOUT TIME ZONE,
|
||||
password VARCHAR(255),
|
||||
try_count INTEGER,
|
||||
try_login_time TIMESTAMP WITHOUT TIME ZONE,
|
||||
area VARCHAR(64),
|
||||
mq_person_uuid VARCHAR(64),
|
||||
mq_account_uuid VARCHAR(64),
|
||||
mq_synced_at TIMESTAMP WITHOUT TIME ZONE,
|
||||
tenant_name VARCHAR(255),
|
||||
dep_short_name VARCHAR(255),
|
||||
dep_name VARCHAR(255),
|
||||
CONSTRAINT sso_users_sub_key UNIQUE (sub)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_sso_users_sub ON sso_users(sub);
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_sso_users_sub_unique ON sso_users(sub);
|
||||
CREATE INDEX IF NOT EXISTS idx_sso_users_username ON sso_users(username);
|
||||
CREATE INDEX IF NOT EXISTS idx_sso_users_area ON sso_users(area) WHERE area IS NOT NULL;
|
||||
CREATE INDEX IF NOT EXISTS idx_sso_users_status ON sso_users(status);
|
||||
CREATE INDEX IF NOT EXISTS idx_sso_users_deleted_at ON sso_users(deleted_at);
|
||||
CREATE INDEX IF NOT EXISTS idx_sso_users_ou_id ON sso_users(ou_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_sso_users_is_leader ON sso_users(is_leader);
|
||||
CREATE INDEX IF NOT EXISTS idx_sso_users_mq_person ON sso_users(mq_person_uuid);
|
||||
CREATE INDEX IF NOT EXISTS idx_sso_users_mq_account ON sso_users(mq_account_uuid);
|
||||
|
||||
COMMENT ON TABLE sso_users IS '用户主表:认证身份、组织信息、地区隔离基础字段统一沉淀在这里';
|
||||
COMMENT ON COLUMN sso_users.sub IS '统一身份唯一标识,OAuth / SSO 主键';
|
||||
COMMENT ON COLUMN sso_users.username IS '登录名/工号/展示账号';
|
||||
COMMENT ON COLUMN sso_users.nick_name IS '用户真实姓名';
|
||||
COMMENT ON COLUMN sso_users.area IS '用户主地区,当前系统唯一数据隔离字段';
|
||||
COMMENT ON COLUMN sso_users.password IS '密码字段:当前阶段兼容旧值,后续应迁移为哈希';
|
||||
COMMENT ON COLUMN sso_users.status IS '账户状态:0=正常,1=禁用';
|
||||
COMMENT ON COLUMN sso_users.deleted_at IS '软删除时间';
|
||||
|
||||
-- --------------------------------------------------------------------------
|
||||
-- 2. 角色表 roles
|
||||
-- --------------------------------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS roles (
|
||||
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||
role_key VARCHAR(64) NOT NULL,
|
||||
role_name VARCHAR(128) NOT NULL,
|
||||
data_scope VARCHAR(16) DEFAULT 'SELF',
|
||||
description VARCHAR(255) DEFAULT '',
|
||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
parent_role_id BIGINT,
|
||||
priority INTEGER DEFAULT 0,
|
||||
is_system_role BOOLEAN DEFAULT FALSE,
|
||||
permissions_cache JSONB,
|
||||
metadata JSONB,
|
||||
CONSTRAINT roles_role_key_key UNIQUE (role_key),
|
||||
CONSTRAINT fk_parent_role FOREIGN KEY (parent_role_id) REFERENCES roles(id) ON DELETE SET NULL,
|
||||
CONSTRAINT chk_roles_data_scope CHECK (data_scope IN ('ALL', 'DEPT', 'SELF', 'GROUP'))
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_roles_parent_role_id ON roles(parent_role_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_roles_priority ON roles(priority DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_roles_permissions_cache ON roles USING GIN (permissions_cache);
|
||||
|
||||
COMMENT ON TABLE roles IS '角色表:当前主业务角色只使用 provincial_admin/admin/common,可选 super_admin';
|
||||
COMMENT ON COLUMN roles.role_key IS '角色机器标识,例如 provincial_admin/admin/common';
|
||||
COMMENT ON COLUMN roles.role_name IS '角色展示名称';
|
||||
COMMENT ON COLUMN roles.data_scope IS '默认数据范围:ALL/DEPT/SELF;GROUP 仅保留兼容';
|
||||
COMMENT ON COLUMN roles.priority IS '角色优先级,数值越大优先级越高';
|
||||
|
||||
-- --------------------------------------------------------------------------
|
||||
-- 3. 菜单/路由表 sys_routes
|
||||
-- --------------------------------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS sys_routes (
|
||||
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||
route_path VARCHAR(255) NOT NULL,
|
||||
route_name VARCHAR(128) NOT NULL,
|
||||
component VARCHAR(255),
|
||||
parent_id BIGINT,
|
||||
route_title VARCHAR(255),
|
||||
icon VARCHAR(128),
|
||||
sort_order INTEGER DEFAULT 0,
|
||||
is_hidden BOOLEAN DEFAULT FALSE,
|
||||
is_cache BOOLEAN DEFAULT TRUE,
|
||||
meta JSONB,
|
||||
status INTEGER DEFAULT 0,
|
||||
created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
deleted_at TIMESTAMP WITHOUT TIME ZONE,
|
||||
CONSTRAINT fk_parent_route FOREIGN KEY (parent_id) REFERENCES sys_routes(id) ON DELETE SET NULL
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_routes_path ON sys_routes(route_path) WHERE deleted_at IS NULL;
|
||||
CREATE INDEX IF NOT EXISTS idx_routes_parent_id ON sys_routes(parent_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_routes_status ON sys_routes(status);
|
||||
|
||||
COMMENT ON TABLE sys_routes IS '前端菜单/页面路由表:用于控制角色可见菜单,不替代 API 权限表';
|
||||
COMMENT ON COLUMN sys_routes.route_path IS '前端路由路径';
|
||||
COMMENT ON COLUMN sys_routes.status IS '状态:0=启用,1=禁用';
|
||||
|
||||
-- --------------------------------------------------------------------------
|
||||
-- 4. 角色路由关系表 role_route
|
||||
-- --------------------------------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS role_route (
|
||||
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||
role_id BIGINT NOT NULL,
|
||||
route_id BIGINT NOT NULL,
|
||||
permission VARCHAR(8) DEFAULT 'RW',
|
||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
status SMALLINT NOT NULL DEFAULT 1,
|
||||
CONSTRAINT role_route_role_id_route_id_key UNIQUE (role_id, route_id),
|
||||
CONSTRAINT fk_role_route_role FOREIGN KEY (role_id) REFERENCES roles(id) ON DELETE CASCADE,
|
||||
CONSTRAINT fk_role_route_route FOREIGN KEY (route_id) REFERENCES sys_routes(id) ON DELETE CASCADE,
|
||||
CONSTRAINT chk_role_route_status CHECK (status IN (0, 1)),
|
||||
CONSTRAINT chk_role_route_permission CHECK (permission IN ('R', 'W', 'RW'))
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_role_route_status ON role_route(status);
|
||||
CREATE INDEX IF NOT EXISTS idx_role_route_role_status ON role_route(role_id, status);
|
||||
|
||||
COMMENT ON TABLE role_route IS '角色与菜单路由关联表';
|
||||
COMMENT ON COLUMN role_route.permission IS '路由权限类型:R=读,W=写,RW=读写';
|
||||
|
||||
-- --------------------------------------------------------------------------
|
||||
-- 5. 权限点表 permissions
|
||||
-- --------------------------------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS permissions (
|
||||
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||
permission_key VARCHAR(100) NOT NULL,
|
||||
module VARCHAR(50) NOT NULL,
|
||||
resource VARCHAR(50) NOT NULL,
|
||||
action VARCHAR(50) NOT NULL,
|
||||
description TEXT,
|
||||
display_name VARCHAR(200),
|
||||
permission_type VARCHAR(20) NOT NULL DEFAULT 'API',
|
||||
is_system BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
metadata JSONB,
|
||||
created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
created_by BIGINT,
|
||||
updated_by BIGINT,
|
||||
parent_id BIGINT,
|
||||
sort_order INTEGER DEFAULT 0,
|
||||
route_id BIGINT,
|
||||
api_path VARCHAR(255),
|
||||
api_method VARCHAR(16),
|
||||
related_routes BIGINT[],
|
||||
CONSTRAINT permissions_permission_key_key UNIQUE (permission_key),
|
||||
CONSTRAINT permissions_parent_id_fkey FOREIGN KEY (parent_id) REFERENCES permissions(id) ON DELETE SET NULL,
|
||||
CONSTRAINT permissions_route_id_fkey FOREIGN KEY (route_id) REFERENCES sys_routes(id) ON DELETE SET NULL,
|
||||
CONSTRAINT permissions_key_format_check CHECK (permission_key ~ '^[a-zA-Z0-9_*]+:[a-zA-Z0-9_*]+:[a-zA-Z0-9_*]+$')
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_permissions_module ON permissions(module);
|
||||
CREATE INDEX IF NOT EXISTS idx_permissions_parent_id ON permissions(parent_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_permissions_route_id ON permissions(route_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_permissions_sort_order ON permissions(sort_order);
|
||||
CREATE INDEX IF NOT EXISTS idx_permissions_system ON permissions(is_system);
|
||||
CREATE INDEX IF NOT EXISTS idx_permissions_type ON permissions(permission_type);
|
||||
CREATE INDEX IF NOT EXISTS idx_permissions_metadata ON permissions USING GIN (metadata);
|
||||
|
||||
COMMENT ON TABLE permissions IS '权限点定义表:统一使用 module:resource:action 风格 permission_key';
|
||||
COMMENT ON COLUMN permissions.permission_key IS '权限键,例如 documents:list:read、audit:run:execute';
|
||||
COMMENT ON COLUMN permissions.related_routes IS '共享权限可关联多个路由 ID';
|
||||
|
||||
-- --------------------------------------------------------------------------
|
||||
-- 6. 角色权限关系表 role_permissions
|
||||
-- --------------------------------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS role_permissions (
|
||||
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||
role_id BIGINT NOT NULL,
|
||||
permission_id BIGINT NOT NULL,
|
||||
grant_type VARCHAR(10) NOT NULL DEFAULT 'GRANT',
|
||||
data_scope VARCHAR(20),
|
||||
condition_filter JSONB,
|
||||
metadata JSONB,
|
||||
created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
created_by BIGINT,
|
||||
updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_by BIGINT,
|
||||
CONSTRAINT unique_role_permission UNIQUE (role_id, permission_id),
|
||||
CONSTRAINT role_permissions_role_id_fkey FOREIGN KEY (role_id) REFERENCES roles(id) ON DELETE CASCADE,
|
||||
CONSTRAINT role_permissions_permission_id_fkey FOREIGN KEY (permission_id) REFERENCES permissions(id) ON DELETE CASCADE,
|
||||
CONSTRAINT chk_role_permissions_grant_type CHECK (grant_type IN ('GRANT', 'DENY')),
|
||||
CONSTRAINT chk_role_permissions_data_scope CHECK (data_scope IS NULL OR data_scope IN ('ALL', 'DEPT', 'SELF', 'GROUP'))
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_role_permissions_role_id ON role_permissions(role_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_role_permissions_permission_id ON role_permissions(permission_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_role_permissions_grant_type ON role_permissions(grant_type);
|
||||
CREATE INDEX IF NOT EXISTS idx_role_permissions_data_scope ON role_permissions(data_scope);
|
||||
CREATE INDEX IF NOT EXISTS idx_role_permissions_lookup ON role_permissions(role_id, grant_type);
|
||||
CREATE INDEX IF NOT EXISTS idx_role_permissions_condition ON role_permissions USING GIN (condition_filter);
|
||||
|
||||
COMMENT ON TABLE role_permissions IS '角色权限关联表:grant_type 兼容旧系统 DENY 语义,当前新系统默认只配置 GRANT';
|
||||
COMMENT ON COLUMN role_permissions.data_scope IS '数据范围:ALL/DEPT/SELF,GROUP 仅保留兼容';
|
||||
|
||||
-- --------------------------------------------------------------------------
|
||||
-- 7. 用户角色关系表 user_role
|
||||
-- --------------------------------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS user_role (
|
||||
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||
user_id BIGINT NOT NULL,
|
||||
role_id BIGINT NOT NULL,
|
||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
CONSTRAINT user_role_user_id_role_id_key UNIQUE (user_id, role_id),
|
||||
CONSTRAINT fk_user_role_user FOREIGN KEY (user_id) REFERENCES sso_users(id) ON DELETE CASCADE,
|
||||
CONSTRAINT fk_user_role_role FOREIGN KEY (role_id) REFERENCES roles(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_user_role_user_role ON user_role(user_id, role_id);
|
||||
|
||||
COMMENT ON TABLE user_role IS '用户与角色关联表;一个用户允许挂多个角色';
|
||||
|
||||
-- --------------------------------------------------------------------------
|
||||
-- 8. 给现有 leaudit_* 业务表补用户外键
|
||||
-- 当前库中这些字段均为 bigint,且当前全为空,可安全补充外键。
|
||||
-- --------------------------------------------------------------------------
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (
|
||||
SELECT 1 FROM pg_constraint WHERE conname = 'fk_leaudit_document_files_created_by'
|
||||
) THEN
|
||||
ALTER TABLE leaudit_document_files
|
||||
ADD CONSTRAINT fk_leaudit_document_files_created_by
|
||||
FOREIGN KEY (created_by) REFERENCES sso_users(id) ON DELETE SET NULL;
|
||||
END IF;
|
||||
|
||||
IF NOT EXISTS (
|
||||
SELECT 1 FROM pg_constraint WHERE conname = 'fk_leaudit_audit_runs_trigger_user_id'
|
||||
) THEN
|
||||
ALTER TABLE leaudit_audit_runs
|
||||
ADD CONSTRAINT fk_leaudit_audit_runs_trigger_user_id
|
||||
FOREIGN KEY (trigger_user_id) REFERENCES sso_users(id) ON DELETE SET NULL;
|
||||
END IF;
|
||||
|
||||
IF NOT EXISTS (
|
||||
SELECT 1 FROM pg_constraint WHERE conname = 'fk_leaudit_rule_sets_owner_user_id'
|
||||
) THEN
|
||||
ALTER TABLE leaudit_rule_sets
|
||||
ADD CONSTRAINT fk_leaudit_rule_sets_owner_user_id
|
||||
FOREIGN KEY (owner_user_id) REFERENCES sso_users(id) ON DELETE SET NULL;
|
||||
END IF;
|
||||
|
||||
IF NOT EXISTS (
|
||||
SELECT 1 FROM pg_constraint WHERE conname = 'fk_leaudit_rule_versions_editor_user_id'
|
||||
) THEN
|
||||
ALTER TABLE leaudit_rule_versions
|
||||
ADD CONSTRAINT fk_leaudit_rule_versions_editor_user_id
|
||||
FOREIGN KEY (editor_user_id) REFERENCES sso_users(id) ON DELETE SET NULL;
|
||||
END IF;
|
||||
|
||||
IF NOT EXISTS (
|
||||
SELECT 1 FROM pg_constraint WHERE conname = 'fk_leaudit_rule_versions_publisher_user_id'
|
||||
) THEN
|
||||
ALTER TABLE leaudit_rule_versions
|
||||
ADD CONSTRAINT fk_leaudit_rule_versions_publisher_user_id
|
||||
FOREIGN KEY (publisher_user_id) REFERENCES sso_users(id) ON DELETE SET NULL;
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
COMMIT;
|
||||
@@ -0,0 +1,271 @@
|
||||
-- ==========================================================================
|
||||
-- LeAudit Platform RBAC / User Seed
|
||||
-- 说明:
|
||||
-- 1. 本文件依赖 scripts/user_rbac_schema_patch.sql 已执行
|
||||
-- 2. 权限键统一采用 module:resource:action 风格
|
||||
-- 3. 当前只初始化新系统当前开发真正需要的最小权限集
|
||||
-- ============================================================================
|
||||
|
||||
BEGIN;
|
||||
|
||||
-- --------------------------------------------------------------------------
|
||||
-- 1. 角色初始化
|
||||
-- --------------------------------------------------------------------------
|
||||
INSERT INTO roles (role_key, role_name, data_scope, description, priority, is_system_role, created_at, updated_at)
|
||||
VALUES
|
||||
('super_admin', '系统超级管理员', 'ALL', '可选,仅系统维护/排障使用', 100, TRUE, NOW(), NOW()),
|
||||
('provincial_admin', '省级管理员', 'ALL', '查看全局数据并维护系统配置', 90, TRUE, NOW(), NOW()),
|
||||
('admin', '地区管理员', 'DEPT', '仅管理本地区数据', 50, TRUE, NOW(), NOW()),
|
||||
('common', '普通用户', 'SELF', '仅处理本人数据', 10, TRUE, NOW(), NOW())
|
||||
ON CONFLICT (role_key) DO UPDATE SET
|
||||
role_name = EXCLUDED.role_name,
|
||||
data_scope = EXCLUDED.data_scope,
|
||||
description = EXCLUDED.description,
|
||||
priority = EXCLUDED.priority,
|
||||
is_system_role = EXCLUDED.is_system_role,
|
||||
updated_at = NOW();
|
||||
|
||||
-- --------------------------------------------------------------------------
|
||||
-- 2. 路由初始化
|
||||
-- --------------------------------------------------------------------------
|
||||
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
|
||||
('/documents', 'documents', 'Layout', NULL, '文档管理', 'files', 10, FALSE, TRUE, '{"group":"documents"}'::jsonb, 0, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, NULL),
|
||||
('/documents/list', 'documents.list', 'documents/list', NULL, '文档列表', 'table', 11, FALSE, TRUE, '{"group":"documents"}'::jsonb, 0, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, NULL),
|
||||
('/audit', 'audit', 'Layout', NULL, '评查任务', 'audit', 20, FALSE, TRUE, '{"group":"audit"}'::jsonb, 0, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, NULL),
|
||||
('/audit/runs', 'audit.runs', 'audit/runs', NULL, '评查运行', 'history', 21, FALSE, TRUE, '{"group":"audit"}'::jsonb, 0, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, NULL),
|
||||
('/rules', 'rules', 'Layout', NULL, '规则管理', 'rule', 30, FALSE, TRUE, '{"group":"rules"}'::jsonb, 0, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, NULL),
|
||||
('/rules/sets', 'rules.sets', 'rules/sets', NULL, '规则集管理', 'yaml', 31, FALSE, TRUE, '{"group":"rules"}'::jsonb, 0, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, NULL),
|
||||
('/system', 'system', 'Layout', NULL, '系统管理', 'setting', 90, FALSE, TRUE, '{"group":"system"}'::jsonb, 0, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, NULL),
|
||||
('/system/users', 'system.users', 'system/users', NULL, '用户管理', 'user', 91, FALSE, TRUE, '{"group":"system"}'::jsonb, 0, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, NULL),
|
||||
('/system/roles', 'system.roles', 'system/roles', NULL, '角色权限', 'shield', 92, FALSE, TRUE, '{"group":"system"}'::jsonb, 0, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, NULL)
|
||||
ON CONFLICT DO NOTHING;
|
||||
|
||||
-- --------------------------------------------------------------------------
|
||||
-- 3. 权限点初始化
|
||||
-- --------------------------------------------------------------------------
|
||||
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
|
||||
)
|
||||
VALUES
|
||||
('auth:me:read', 'auth', 'me', 'read', '查看当前登录用户信息', '当前用户信息', 'API', TRUE, NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, NULL, NULL, NULL, 10, NULL, '/api/auth/me', 'GET', NULL),
|
||||
|
||||
('documents:upload:write', 'documents', 'upload', 'write', '上传文档', '上传文档', 'API', TRUE, NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, NULL, NULL, NULL, 20, NULL, '/api/upload', 'POST', NULL),
|
||||
('documents:list:read', 'documents', 'list', 'read', '查看文档列表', '文档列表', 'API', TRUE, NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, NULL, NULL, NULL, 21, NULL, '/api/documents/list', 'GET', NULL),
|
||||
('documents:detail:read', 'documents', 'detail', 'read', '查看文档详情', '文档详情', 'API', TRUE, NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, NULL, NULL, NULL, 22, NULL, '/api/documents/{document_id}', 'GET', NULL),
|
||||
('documents:history:read', 'documents', 'history', 'read', '查看文档历史版本', '文档历史版本', 'API', TRUE, NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, NULL, NULL, NULL, 23, NULL, '/api/documents/{document_id}/versions', 'GET', NULL),
|
||||
('documents:delete:delete', 'documents', 'delete', 'delete', '删除文档', '删除文档', 'API', TRUE, NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, NULL, NULL, NULL, 24, NULL, '/api/documents/{document_id}', 'DELETE', NULL),
|
||||
|
||||
('audit:run:execute', 'audit', 'run', 'execute', '发起评查任务', '发起评查', 'API', TRUE, NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, NULL, NULL, NULL, 30, NULL, '/api/audit/run', 'POST', NULL),
|
||||
('audit:status:read', 'audit', 'status', 'read', '查看评查运行状态', '评查状态', 'API', TRUE, NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, NULL, NULL, NULL, 31, NULL, '/api/audit/run/{run_id}', 'GET', NULL),
|
||||
('audit:result:read', 'audit', 'result', 'read', '查看评查结果', '评查结果', 'API', TRUE, NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, NULL, NULL, NULL, 32, NULL, '/api/audit/result/{run_id}', 'GET', NULL),
|
||||
|
||||
('rules:list:read', 'rules', 'list', 'read', '查看规则集列表', '规则集列表', 'API', TRUE, NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, NULL, NULL, NULL, 40, NULL, '/api/rule-sets', 'GET', NULL),
|
||||
('rules:version_list:read', 'rules', 'version_list', 'read', '查看规则版本列表', '规则版本列表', 'API', TRUE, NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, NULL, NULL, NULL, 41, NULL, '/api/rule-sets/{rule_type}/versions', 'GET', NULL),
|
||||
('rules:content:read', 'rules', 'content', 'read', '查看规则正文', '规则正文', 'API', TRUE, NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, NULL, NULL, NULL, 42, NULL, '/api/rule-sets/versions/{version_id}/content', 'GET', NULL),
|
||||
('rules:validate:execute', 'rules', 'validate', 'execute', '校验规则 YAML', '规则校验', 'API', TRUE, NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, NULL, NULL, NULL, 43, NULL, '/api/rule-sets/{rule_type}/validate', 'POST', NULL),
|
||||
('rules:version_create:write', 'rules', 'version_create', 'write', '创建规则版本', '创建规则版本', 'API', TRUE, NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, NULL, NULL, NULL, 44, NULL, '/api/rule-sets/{rule_type}/versions', 'POST', NULL),
|
||||
('rules:publish:write', 'rules', 'publish', 'write', '发布规则版本', '发布规则', 'API', TRUE, NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, NULL, NULL, NULL, 45, NULL, '/api/rule-sets/{rule_type}/publish', 'POST', NULL),
|
||||
('rules:rollback:write', 'rules', 'rollback', 'write', '回滚规则版本', '回滚规则', 'API', TRUE, NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, NULL, NULL, NULL, 46, NULL, '/api/rule-sets/{rule_type}/rollback', 'POST', NULL),
|
||||
('rules:binding_list:read', 'rules', 'binding_list', 'read', '查看规则绑定列表', '规则绑定列表', 'API', TRUE, NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, NULL, NULL, NULL, 47, NULL, '/api/rule-sets/bindings', 'GET', NULL),
|
||||
('rules:binding_create:write', 'rules', 'binding_create', 'write', '创建规则绑定', '创建规则绑定', 'API', TRUE, NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, NULL, NULL, NULL, 48, NULL, '/api/rule-sets/{rule_type}/bindings', 'POST', NULL),
|
||||
('rules:binding_update:write', 'rules', 'binding_update', 'write', '更新规则绑定', '更新规则绑定', 'API', TRUE, NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, NULL, NULL, NULL, 49, NULL, '/api/rule-sets/bindings/{binding_id}', 'PUT', NULL),
|
||||
('rules:binding_delete:delete', 'rules', 'binding_delete', 'delete', '删除规则绑定', '删除规则绑定', 'API', TRUE, NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, NULL, NULL, NULL, 50, NULL, '/api/rule-sets/bindings/{binding_id}', 'DELETE', NULL),
|
||||
|
||||
('users:list:read', 'users', 'list', 'read', '查看用户列表', '用户列表', 'API', TRUE, NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, NULL, NULL, NULL, 60, NULL, '/api/users/list', 'GET', NULL),
|
||||
('users:create:write', 'users', 'create', 'write', '创建用户', '创建用户', 'API', TRUE, NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, NULL, NULL, NULL, 61, NULL, '/api/users', 'POST', NULL),
|
||||
('users:update:write', 'users', 'update', 'write', '更新用户', '更新用户', 'API', TRUE, NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, NULL, NULL, NULL, 62, NULL, '/api/users/{user_id}', 'PUT', NULL),
|
||||
('users:disable:write', 'users', 'disable', 'write', '禁用/启用用户', '禁用用户', 'API', TRUE, NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, NULL, NULL, NULL, 63, NULL, '/api/users/{user_id}/disable', 'PUT', NULL),
|
||||
('users:roles_assign:write', 'users', 'roles_assign', 'write', '分配用户角色', '分配用户角色', 'API', TRUE, NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, NULL, NULL, NULL, 64, NULL, '/api/users/{user_id}/roles', 'POST', NULL),
|
||||
|
||||
('rbac:roles:read', 'rbac', 'roles', 'read', '查看角色列表', '角色列表', 'API', TRUE, NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, NULL, NULL, NULL, 70, NULL, '/api/rbac/roles', 'GET', NULL),
|
||||
('rbac:roles:update', 'rbac', 'roles', 'update', '维护角色信息', '维护角色', 'API', TRUE, NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, NULL, NULL, NULL, 71, NULL, '/api/rbac/roles/{role_id}', 'PUT', NULL),
|
||||
('rbac:permissions:read', 'rbac', 'permissions', 'read', '查看权限点列表', '权限点列表', 'API', TRUE, NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, NULL, NULL, NULL, 72, NULL, '/api/rbac/permissions', 'GET', NULL),
|
||||
('rbac:role_permissions:write', 'rbac', 'role_permissions', 'write', '分配角色权限', '分配角色权限', 'API', TRUE, NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, NULL, NULL, NULL, 73, NULL, '/api/rbac/roles/{role_id}/permissions', 'POST', NULL),
|
||||
('rbac:role_routes:write', 'rbac', 'role_routes', 'write', '分配角色菜单', '分配角色菜单', 'API', TRUE, NULL, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, NULL, NULL, NULL, 74, NULL, '/api/rbac/roles/{role_id}/routes', 'PUT', NULL)
|
||||
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 = CURRENT_TIMESTAMP,
|
||||
api_path = EXCLUDED.api_path,
|
||||
api_method = EXCLUDED.api_method,
|
||||
sort_order = EXCLUDED.sort_order;
|
||||
|
||||
-- --------------------------------------------------------------------------
|
||||
-- 4. 角色菜单授权
|
||||
-- --------------------------------------------------------------------------
|
||||
WITH role_map AS (
|
||||
SELECT id, role_key FROM roles WHERE role_key IN ('super_admin', 'provincial_admin', 'admin', 'common')
|
||||
),
|
||||
route_map AS (
|
||||
SELECT id, route_path FROM sys_routes WHERE deleted_at IS NULL
|
||||
),
|
||||
seed(role_key, route_path, permission, status) AS (
|
||||
VALUES
|
||||
('super_admin', '/documents', 'RW', 1),
|
||||
('super_admin', '/documents/list', 'RW', 1),
|
||||
('super_admin', '/audit', 'RW', 1),
|
||||
('super_admin', '/audit/runs', 'RW', 1),
|
||||
('super_admin', '/rules', 'RW', 1),
|
||||
('super_admin', '/rules/sets', 'RW', 1),
|
||||
('super_admin', '/system', 'RW', 1),
|
||||
('super_admin', '/system/users', 'RW', 1),
|
||||
('super_admin', '/system/roles', 'RW', 1),
|
||||
|
||||
('provincial_admin', '/documents', 'RW', 1),
|
||||
('provincial_admin', '/documents/list', 'RW', 1),
|
||||
('provincial_admin', '/audit', 'RW', 1),
|
||||
('provincial_admin', '/audit/runs', 'RW', 1),
|
||||
('provincial_admin', '/rules', 'RW', 1),
|
||||
('provincial_admin', '/rules/sets', 'RW', 1),
|
||||
('provincial_admin', '/system', 'RW', 1),
|
||||
('provincial_admin', '/system/users', 'RW', 1),
|
||||
('provincial_admin', '/system/roles', 'RW', 1),
|
||||
|
||||
('admin', '/documents', 'RW', 1),
|
||||
('admin', '/documents/list', 'RW', 1),
|
||||
('admin', '/audit', 'RW', 1),
|
||||
('admin', '/audit/runs', 'RW', 1),
|
||||
('admin', '/rules', 'RW', 1),
|
||||
('admin', '/rules/sets', 'RW', 1),
|
||||
('admin', '/system', 'RW', 1),
|
||||
('admin', '/system/users', 'RW', 1),
|
||||
|
||||
('common', '/documents', 'R', 1),
|
||||
('common', '/documents/list', 'R', 1),
|
||||
('common', '/audit', 'R', 1),
|
||||
('common', '/audit/runs', '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();
|
||||
|
||||
-- --------------------------------------------------------------------------
|
||||
-- 5. 角色权限授权
|
||||
-- --------------------------------------------------------------------------
|
||||
WITH role_map AS (
|
||||
SELECT id, role_key FROM roles WHERE role_key IN ('super_admin', 'provincial_admin', 'admin', 'common')
|
||||
),
|
||||
perm_map AS (
|
||||
SELECT id, permission_key FROM permissions
|
||||
),
|
||||
seed(role_key, permission_key, grant_type, data_scope) AS (
|
||||
VALUES
|
||||
('super_admin', 'auth:me:read', 'GRANT', 'ALL'),
|
||||
('super_admin', 'documents:upload:write', 'GRANT', 'ALL'),
|
||||
('super_admin', 'documents:list:read', 'GRANT', 'ALL'),
|
||||
('super_admin', 'documents:detail:read', 'GRANT', 'ALL'),
|
||||
('super_admin', 'documents:history:read', 'GRANT', 'ALL'),
|
||||
('super_admin', 'documents:delete:delete', 'GRANT', 'ALL'),
|
||||
('super_admin', 'audit:run:execute', 'GRANT', 'ALL'),
|
||||
('super_admin', 'audit:status:read', 'GRANT', 'ALL'),
|
||||
('super_admin', 'audit:result:read', 'GRANT', 'ALL'),
|
||||
('super_admin', 'rules:list:read', 'GRANT', 'ALL'),
|
||||
('super_admin', 'rules:version_list:read', 'GRANT', 'ALL'),
|
||||
('super_admin', 'rules:content:read', 'GRANT', 'ALL'),
|
||||
('super_admin', 'rules:validate:execute', 'GRANT', 'ALL'),
|
||||
('super_admin', 'rules:version_create:write', 'GRANT', 'ALL'),
|
||||
('super_admin', 'rules:publish:write', 'GRANT', 'ALL'),
|
||||
('super_admin', 'rules:rollback:write', 'GRANT', 'ALL'),
|
||||
('super_admin', 'rules:binding_list:read', 'GRANT', 'ALL'),
|
||||
('super_admin', 'rules:binding_create:write', 'GRANT', 'ALL'),
|
||||
('super_admin', 'rules:binding_update:write', 'GRANT', 'ALL'),
|
||||
('super_admin', 'rules:binding_delete:delete', 'GRANT', 'ALL'),
|
||||
('super_admin', 'users:list:read', 'GRANT', 'ALL'),
|
||||
('super_admin', 'users:create:write', 'GRANT', 'ALL'),
|
||||
('super_admin', 'users:update:write', 'GRANT', 'ALL'),
|
||||
('super_admin', 'users:disable:write', 'GRANT', 'ALL'),
|
||||
('super_admin', 'users:roles_assign:write', 'GRANT', 'ALL'),
|
||||
('super_admin', 'rbac:roles:read', 'GRANT', 'ALL'),
|
||||
('super_admin', 'rbac:roles:update', 'GRANT', 'ALL'),
|
||||
('super_admin', 'rbac:permissions:read', 'GRANT', 'ALL'),
|
||||
('super_admin', 'rbac:role_permissions:write', 'GRANT', 'ALL'),
|
||||
('super_admin', 'rbac:role_routes:write', 'GRANT', 'ALL'),
|
||||
|
||||
('provincial_admin', 'auth:me:read', 'GRANT', 'ALL'),
|
||||
('provincial_admin', 'documents:upload:write', 'GRANT', 'ALL'),
|
||||
('provincial_admin', 'documents:list:read', 'GRANT', 'ALL'),
|
||||
('provincial_admin', 'documents:detail:read', 'GRANT', 'ALL'),
|
||||
('provincial_admin', 'documents:history:read', 'GRANT', 'ALL'),
|
||||
('provincial_admin', 'documents:delete:delete', 'GRANT', 'ALL'),
|
||||
('provincial_admin', 'audit:run:execute', 'GRANT', 'ALL'),
|
||||
('provincial_admin', 'audit:status:read', 'GRANT', 'ALL'),
|
||||
('provincial_admin', 'audit:result:read', 'GRANT', 'ALL'),
|
||||
('provincial_admin', 'rules:list:read', 'GRANT', 'ALL'),
|
||||
('provincial_admin', 'rules:version_list:read', 'GRANT', 'ALL'),
|
||||
('provincial_admin', 'rules:content:read', 'GRANT', 'ALL'),
|
||||
('provincial_admin', 'rules:validate:execute', 'GRANT', 'ALL'),
|
||||
('provincial_admin', 'rules:version_create:write', 'GRANT', 'ALL'),
|
||||
('provincial_admin', 'rules:publish:write', 'GRANT', 'ALL'),
|
||||
('provincial_admin', 'rules:rollback:write', 'GRANT', 'ALL'),
|
||||
('provincial_admin', 'rules:binding_list:read', 'GRANT', 'ALL'),
|
||||
('provincial_admin', 'rules:binding_create:write', 'GRANT', 'ALL'),
|
||||
('provincial_admin', 'rules:binding_update:write', 'GRANT', 'ALL'),
|
||||
('provincial_admin', 'rules:binding_delete:delete', 'GRANT', 'ALL'),
|
||||
('provincial_admin', 'users:list:read', 'GRANT', 'ALL'),
|
||||
('provincial_admin', 'users:create:write', 'GRANT', 'ALL'),
|
||||
('provincial_admin', 'users:update:write', 'GRANT', 'ALL'),
|
||||
('provincial_admin', 'users:disable:write', 'GRANT', 'ALL'),
|
||||
('provincial_admin', 'users:roles_assign:write', 'GRANT', 'ALL'),
|
||||
('provincial_admin', 'rbac:roles:read', 'GRANT', 'ALL'),
|
||||
('provincial_admin', 'rbac:roles:update', 'GRANT', 'ALL'),
|
||||
('provincial_admin', 'rbac:permissions:read', 'GRANT', 'ALL'),
|
||||
('provincial_admin', 'rbac:role_permissions:write', 'GRANT', 'ALL'),
|
||||
('provincial_admin', 'rbac:role_routes:write', 'GRANT', 'ALL'),
|
||||
|
||||
('admin', 'auth:me:read', 'GRANT', 'DEPT'),
|
||||
('admin', 'documents:upload:write', 'GRANT', 'DEPT'),
|
||||
('admin', 'documents:list:read', 'GRANT', 'DEPT'),
|
||||
('admin', 'documents:detail:read', 'GRANT', 'DEPT'),
|
||||
('admin', 'documents:history:read', 'GRANT', 'DEPT'),
|
||||
('admin', 'documents:delete:delete', 'GRANT', 'DEPT'),
|
||||
('admin', 'audit:run:execute', 'GRANT', 'DEPT'),
|
||||
('admin', 'audit:status:read', 'GRANT', 'DEPT'),
|
||||
('admin', 'audit:result:read', 'GRANT', 'DEPT'),
|
||||
('admin', 'rules:list:read', 'GRANT', 'DEPT'),
|
||||
('admin', 'rules:version_list:read', 'GRANT', 'DEPT'),
|
||||
('admin', 'rules:content:read', 'GRANT', 'DEPT'),
|
||||
('admin', 'rules:validate:execute', 'GRANT', 'DEPT'),
|
||||
('admin', 'rules:binding_list:read', 'GRANT', 'DEPT'),
|
||||
('admin', 'rules:binding_create:write', 'GRANT', 'DEPT'),
|
||||
('admin', 'rules:binding_update:write', 'GRANT', 'DEPT'),
|
||||
('admin', 'users:list:read', 'GRANT', 'DEPT'),
|
||||
('admin', 'users:update:write', 'GRANT', 'DEPT'),
|
||||
|
||||
('common', 'auth:me:read', 'GRANT', 'SELF'),
|
||||
('common', 'documents:upload:write', 'GRANT', 'SELF'),
|
||||
('common', 'documents:list:read', 'GRANT', 'SELF'),
|
||||
('common', 'documents:detail:read', 'GRANT', 'SELF'),
|
||||
('common', 'documents:history:read', 'GRANT', 'SELF'),
|
||||
('common', 'audit:run:execute', 'GRANT', 'SELF'),
|
||||
('common', 'audit:status:read', 'GRANT', 'SELF'),
|
||||
('common', 'audit:result:read', 'GRANT', 'SELF'),
|
||||
('common', 'rules:list:read', 'GRANT', 'DEPT'),
|
||||
('common', 'rules:version_list:read', 'GRANT', 'DEPT'),
|
||||
('common', 'rules:content:read', 'GRANT', 'DEPT'),
|
||||
('common', 'rules:binding_list:read', 'GRANT', 'DEPT')
|
||||
)
|
||||
INSERT INTO role_permissions (role_id, permission_id, grant_type, data_scope, created_at, updated_at)
|
||||
SELECT rm.id, pm.id, s.grant_type, s.data_scope, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP
|
||||
FROM seed s
|
||||
JOIN role_map rm ON rm.role_key = s.role_key
|
||||
JOIN perm_map pm ON pm.permission_key = s.permission_key
|
||||
ON CONFLICT (role_id, permission_id) DO UPDATE SET
|
||||
grant_type = EXCLUDED.grant_type,
|
||||
data_scope = EXCLUDED.data_scope,
|
||||
updated_at = CURRENT_TIMESTAMP;
|
||||
|
||||
COMMIT;
|
||||
Reference in New Issue
Block a user