CREATE SCHEMA IF NOT EXISTS sys; -- 通用更新时间触发函数(用于模拟 MySQL 的 ON UPDATE CURRENT_TIMESTAMP) -- CREATE OR REPLACE FUNCTION sys.set_update_time() -- RETURNS trigger AS $$ -- BEGIN -- NEW.update_time := CURRENT_TIMESTAMP; -- RETURN NEW; -- END; -- $$ LANGUAGE plpgsql; -- 部门表 DROP TABLE IF EXISTS sys.tb_sys_dept CASCADE; CREATE TABLE sys.tb_sys_dept ( optsn VARCHAR(50) NOT NULL, -- 流水号 dept_id VARCHAR(50) NOT NULL, -- 部门ID name VARCHAR(100) NOT NULL, -- 部门名称 parent_id VARCHAR(50) DEFAULT NULL, -- 父部门ID dept_path VARCHAR(255) DEFAULT NULL, -- 部门全路径 description VARCHAR(255) DEFAULT NULL, -- 部门描述 creator VARCHAR(50) DEFAULT NULL, -- 创建者 updater VARCHAR(50) DEFAULT NULL, -- 更新者 create_time timestamptz NOT NULL DEFAULT now(), -- 创建时间 update_time timestamptz DEFAULT NULL, -- 更新时间(由触发器维护) delete_time timestamptz DEFAULT NULL, -- 删除时间 deleted boolean NOT NULL DEFAULT false, -- 是否删除 PRIMARY KEY (dept_id), UNIQUE (optsn) ); -- 创建索引 CREATE INDEX idx_sys_dept_parent ON sys.tb_sys_dept USING btree (parent_id); COMMENT ON TABLE sys.tb_sys_dept IS '部门表'; COMMENT ON COLUMN sys.tb_sys_dept.optsn IS '流水号'; COMMENT ON COLUMN sys.tb_sys_dept.dept_id IS '部门ID'; COMMENT ON COLUMN sys.tb_sys_dept.name IS '部门名称'; COMMENT ON COLUMN sys.tb_sys_dept.parent_id IS '父部门ID'; COMMENT ON COLUMN sys.tb_sys_dept.dept_path IS '部门全路径'; COMMENT ON COLUMN sys.tb_sys_dept.description IS '部门描述'; COMMENT ON COLUMN sys.tb_sys_dept.creator IS '创建者'; COMMENT ON COLUMN sys.tb_sys_dept.updater IS '更新者'; COMMENT ON COLUMN sys.tb_sys_dept.create_time IS '创建时间'; COMMENT ON COLUMN sys.tb_sys_dept.update_time IS '更新时间'; COMMENT ON COLUMN sys.tb_sys_dept.delete_time IS '删除时间'; COMMENT ON COLUMN sys.tb_sys_dept.deleted IS '是否删除'; -- 角色表 DROP TABLE IF EXISTS sys.tb_sys_role CASCADE; CREATE TABLE sys.tb_sys_role ( optsn VARCHAR(50) NOT NULL, -- 流水号 role_id VARCHAR(50) NOT NULL, -- 角色ID name VARCHAR(100) NOT NULL, description VARCHAR(200) DEFAULT NULL, -- 角色名称 scope VARCHAR(20) NOT NULL DEFAULT 'dept', -- 角色作用域:global/dept owner_dept_id VARCHAR(50) DEFAULT NULL, -- 当scope=dept时,所属部门ID creator VARCHAR(50) DEFAULT NULL, -- 创建者 dept_path VARCHAR(255) DEFAULT NULL, status boolean NOT NULL DEFAULT false, -- 部门全路径 updater VARCHAR(50) DEFAULT NULL, -- 更新者 create_time timestamptz NOT NULL DEFAULT now(), -- 创建时间 update_time timestamptz DEFAULT NULL, -- 更新时间(由触发器维护) delete_time timestamptz DEFAULT NULL, -- 删除时间 deleted boolean NOT NULL DEFAULT false, -- 是否删除 PRIMARY KEY (role_id), UNIQUE (optsn) ); COMMENT ON TABLE sys.tb_sys_role IS '角色表'; COMMENT ON COLUMN sys.tb_sys_role.optsn IS '流水号'; COMMENT ON COLUMN sys.tb_sys_role.role_id IS '角色ID'; COMMENT ON COLUMN sys.tb_sys_role.name IS '角色名称'; COMMENT ON COLUMN sys.tb_sys_role.description IS '角色名称'; COMMENT ON COLUMN sys.tb_sys_role.scope IS '角色作用域:global=通用,dept=部门私有'; COMMENT ON COLUMN sys.tb_sys_role.owner_dept_id IS '部门私有角色的所属部门ID(scope=dept 时必填)'; COMMENT ON COLUMN sys.tb_sys_role.status IS '角色状态'; COMMENT ON COLUMN sys.tb_sys_role.creator IS '创建者'; COMMENT ON COLUMN sys.tb_sys_role.dept_path IS '部门全路径'; COMMENT ON COLUMN sys.tb_sys_role.updater IS '更新者'; COMMENT ON COLUMN sys.tb_sys_role.create_time IS '创建时间'; COMMENT ON COLUMN sys.tb_sys_role.update_time IS '更新时间'; COMMENT ON COLUMN sys.tb_sys_role.delete_time IS '删除时间'; COMMENT ON COLUMN sys.tb_sys_role.deleted IS '是否删除'; -- 唯一性: -- 全局角色:name 在未删除且 scope=global 下唯一 -- 部门私有角色:同一部门下 name 唯一(scope=dept) CREATE UNIQUE INDEX IF NOT EXISTS uq_sys_role_global_name ON sys.tb_sys_role USING btree (name) WHERE deleted = false AND scope = 'global'; CREATE UNIQUE INDEX IF NOT EXISTS uq_sys_role_dept_name ON sys.tb_sys_role USING btree (owner_dept_id, name) WHERE deleted = false AND scope = 'dept'; CREATE INDEX IF NOT EXISTS idx_sys_role_owner_dept ON sys.tb_sys_role USING btree (owner_dept_id) WHERE deleted = false; -- 部门角色关联表 DROP TABLE IF EXISTS sys.tb_sys_dept_role CASCADE; CREATE TABLE sys.tb_sys_dept_role ( optsn VARCHAR(50) NOT NULL, -- 流水号 dept_id VARCHAR(50) NOT NULL, -- 部门ID role_id VARCHAR(50) NOT NULL, -- 角色ID dept_path VARCHAR(255) DEFAULT NULL, -- 部门全路径 creator VARCHAR(50) DEFAULT NULL, -- 创建者 updater VARCHAR(50) DEFAULT NULL, -- 更新者 create_time timestamptz NOT NULL DEFAULT now(), -- 创建时间 update_time timestamptz DEFAULT NULL, -- 更新时间(由触发器维护) delete_time timestamptz DEFAULT NULL, -- 删除时间 deleted boolean NOT NULL DEFAULT false, -- 是否删除 PRIMARY KEY (dept_id, role_id), UNIQUE (optsn) ); COMMENT ON TABLE sys.tb_sys_dept_role IS '部门角色关联表'; COMMENT ON COLUMN sys.tb_sys_dept_role.optsn IS '流水号'; COMMENT ON COLUMN sys.tb_sys_dept_role.dept_id IS '部门ID'; COMMENT ON COLUMN sys.tb_sys_dept_role.role_id IS '角色ID'; COMMENT ON COLUMN sys.tb_sys_dept_role.dept_path IS '部门全路径'; COMMENT ON COLUMN sys.tb_sys_dept_role.creator IS '创建者'; COMMENT ON COLUMN sys.tb_sys_dept_role.updater IS '更新者'; COMMENT ON COLUMN sys.tb_sys_dept_role.create_time IS '创建时间'; COMMENT ON COLUMN sys.tb_sys_dept_role.update_time IS '更新时间'; COMMENT ON COLUMN sys.tb_sys_dept_role.delete_time IS '删除时间'; COMMENT ON COLUMN sys.tb_sys_dept_role.deleted IS '是否删除'; -- 用户角色关联表 DROP TABLE IF EXISTS sys.tb_sys_user_role CASCADE; CREATE TABLE sys.tb_sys_user_role ( optsn VARCHAR(50) NOT NULL, -- 流水号 user_id VARCHAR(50) NOT NULL, -- 用户ID role_id VARCHAR(50) NOT NULL, -- 角色ID dept_path VARCHAR(255) DEFAULT NULL, -- 部门全路径 creator VARCHAR(50) DEFAULT NULL, -- 创建者 updater VARCHAR(50) DEFAULT NULL, -- 更新者 create_time timestamptz NOT NULL DEFAULT now(), -- 创建时间 update_time timestamptz DEFAULT NULL, -- 更新时间(由触发器维护) delete_time timestamptz DEFAULT NULL, -- 删除时间 deleted boolean NOT NULL DEFAULT false, -- 是否删除 PRIMARY KEY (user_id, role_id), UNIQUE (optsn) ); COMMENT ON TABLE sys.tb_sys_user_role IS '用户角色关联表'; COMMENT ON COLUMN sys.tb_sys_user_role.optsn IS '流水号'; COMMENT ON COLUMN sys.tb_sys_user_role.user_id IS '用户ID'; COMMENT ON COLUMN sys.tb_sys_user_role.role_id IS '角色ID'; COMMENT ON COLUMN sys.tb_sys_user_role.dept_path IS '部门全路径'; COMMENT ON COLUMN sys.tb_sys_user_role.creator IS '创建者'; COMMENT ON COLUMN sys.tb_sys_user_role.updater IS '更新者'; COMMENT ON COLUMN sys.tb_sys_user_role.create_time IS '创建时间'; COMMENT ON COLUMN sys.tb_sys_user_role.update_time IS '更新时间'; COMMENT ON COLUMN sys.tb_sys_user_role.delete_time IS '删除时间'; COMMENT ON COLUMN sys.tb_sys_user_role.deleted IS '是否删除'; -- 视图表 DROP TABLE IF EXISTS sys.tb_sys_view CASCADE; CREATE TABLE sys.tb_sys_view ( optsn VARCHAR(50) NOT NULL, -- 流水号 view_id VARCHAR(50) NOT NULL, -- 视图ID name VARCHAR(100) NOT NULL, -- 视图名称 parent_id VARCHAR(50) DEFAULT NULL, -- 父视图ID url VARCHAR(255) DEFAULT NULL, -- 视图URL component VARCHAR(255) DEFAULT NULL, -- 视图组件 icon VARCHAR(100) DEFAULT NULL, -- 视图图标 type integer DEFAULT 0, -- 视图类型 layout VARCHAR(100) DEFAULT NULL, -- 布局组件路径名称 order_num integer DEFAULT 0, -- 视图排序号 dept_path VARCHAR(255) DEFAULT NULL, -- 部门全路径 description VARCHAR(255) DEFAULT NULL, -- 视图描述 creator VARCHAR(50) DEFAULT NULL, -- 创建者 updater VARCHAR(50) DEFAULT NULL, -- 更新者 create_time timestamptz NOT NULL DEFAULT now(), -- 创建时间 update_time timestamptz DEFAULT NULL, -- 更新时间(由触发器维护) delete_time timestamptz DEFAULT NULL, -- 删除时间 deleted boolean NOT NULL DEFAULT false, -- 是否删除 PRIMARY KEY (view_id), UNIQUE (optsn) ); COMMENT ON TABLE sys.tb_sys_view IS '视图表'; COMMENT ON COLUMN sys.tb_sys_view.optsn IS '流水号'; COMMENT ON COLUMN sys.tb_sys_view.view_id IS '视图ID'; COMMENT ON COLUMN sys.tb_sys_view.name IS '视图名称'; COMMENT ON COLUMN sys.tb_sys_view.parent_id IS '父视图ID'; COMMENT ON COLUMN sys.tb_sys_view.url IS '视图URL'; COMMENT ON COLUMN sys.tb_sys_view.component IS '视图组件'; COMMENT ON COLUMN sys.tb_sys_view.icon IS '视图图标'; COMMENT ON COLUMN sys.tb_sys_view.type IS '视图类型'; COMMENT ON COLUMN sys.tb_sys_view.layout IS '布局组件路径名称'; COMMENT ON COLUMN sys.tb_sys_view.order_num IS '视图排序号'; COMMENT ON COLUMN sys.tb_sys_view.description IS '视图描述'; COMMENT ON COLUMN sys.tb_sys_view.dept_path IS '部门全路径'; COMMENT ON COLUMN sys.tb_sys_view.creator IS '创建者'; COMMENT ON COLUMN sys.tb_sys_view.updater IS '更新者'; COMMENT ON COLUMN sys.tb_sys_view.create_time IS '创建时间'; COMMENT ON COLUMN sys.tb_sys_view.update_time IS '更新时间'; COMMENT ON COLUMN sys.tb_sys_view.delete_time IS '删除时间'; COMMENT ON COLUMN sys.tb_sys_view.deleted IS '是否删除'; -- 模块表 DROP TABLE IF EXISTS sys.tb_sys_module CASCADE; CREATE TABLE sys.tb_sys_module ( optsn VARCHAR(50) NOT NULL, -- 流水号 module_id VARCHAR(50) NOT NULL, -- 模块ID name VARCHAR(100) NOT NULL, -- 模块名称 description VARCHAR(255) DEFAULT NULL, -- 模块描述 creator VARCHAR(50) DEFAULT NULL, -- 创建者 dept_path VARCHAR(255) DEFAULT NULL, -- 部门全路径 updater VARCHAR(50) DEFAULT NULL, -- 更新者 create_time timestamptz NOT NULL DEFAULT now(), -- 创建时间 update_time timestamptz DEFAULT NULL, -- 更新时间(由触发器维护) delete_time timestamptz DEFAULT NULL, -- 删除时间 deleted boolean NOT NULL DEFAULT false, -- 是否删除 PRIMARY KEY (module_id), UNIQUE (optsn) ); COMMENT ON TABLE sys.tb_sys_module IS '模块表'; COMMENT ON COLUMN sys.tb_sys_module.optsn IS '流水号'; COMMENT ON COLUMN sys.tb_sys_module.module_id IS '模块ID'; COMMENT ON COLUMN sys.tb_sys_module.name IS '模块名称'; COMMENT ON COLUMN sys.tb_sys_module.description IS '模块描述'; COMMENT ON COLUMN sys.tb_sys_module.creator IS '创建者'; COMMENT ON COLUMN sys.tb_sys_module.dept_path IS '部门全路径'; COMMENT ON COLUMN sys.tb_sys_module.updater IS '更新者'; COMMENT ON COLUMN sys.tb_sys_module.create_time IS '创建时间'; COMMENT ON COLUMN sys.tb_sys_module.update_time IS '更新时间'; COMMENT ON COLUMN sys.tb_sys_module.delete_time IS '删除时间'; COMMENT ON COLUMN sys.tb_sys_module.deleted IS '是否删除'; -- 权限表 DROP TABLE IF EXISTS sys.tb_sys_permission CASCADE; CREATE TABLE sys.tb_sys_permission ( optsn VARCHAR(50) NOT NULL, -- 流水号 permission_id VARCHAR(50) NOT NULL, -- 权限ID name VARCHAR(100) NOT NULL, -- 权限名称 code VARCHAR(100) NOT NULL, -- 权限代码 description VARCHAR(255) DEFAULT NULL, -- 权限描述 module_id VARCHAR(50) DEFAULT NULL, -- 所属模块ID creator VARCHAR(50) DEFAULT NULL, -- 创建者 dept_path VARCHAR(255) DEFAULT NULL, status boolean NOT NULL DEFAULT false, -- 部门全路径 updater VARCHAR(50) DEFAULT NULL, -- 更新者 create_time timestamptz NOT NULL DEFAULT now(), -- 创建时间 update_time timestamptz DEFAULT NULL, -- 更新时间(由触发器维护) delete_time timestamptz DEFAULT NULL, -- 删除时间 deleted boolean NOT NULL DEFAULT false, -- 是否删除 PRIMARY KEY (permission_id), UNIQUE (optsn) ); COMMENT ON TABLE sys.tb_sys_permission IS '权限表'; COMMENT ON COLUMN sys.tb_sys_permission.optsn IS '流水号'; COMMENT ON COLUMN sys.tb_sys_permission.permission_id IS '权限ID'; COMMENT ON COLUMN sys.tb_sys_permission.name IS '权限名称'; COMMENT ON COLUMN sys.tb_sys_permission.code IS '权限代码'; COMMENT ON COLUMN sys.tb_sys_permission.description IS '权限描述' ; COMMENT ON COLUMN sys.tb_sys_permission.module_id IS '所属模块ID'; COMMENT ON COLUMN sys.tb_sys_permission.creator IS '创建者'; COMMENT ON COLUMN sys.tb_sys_permission.dept_path IS '部门全路径'; COMMENT ON COLUMN sys.tb_sys_permission.status IS '角色状态'; COMMENT ON COLUMN sys.tb_sys_permission.updater IS '更新者'; COMMENT ON COLUMN sys.tb_sys_permission.create_time IS '创建时间'; COMMENT ON COLUMN sys.tb_sys_permission.update_time IS '更新时间'; COMMENT ON COLUMN sys.tb_sys_permission.delete_time IS '删除时间'; COMMENT ON COLUMN sys.tb_sys_permission.deleted IS '是否删除'; -- 角色权限 DROP TABLE IF EXISTS sys.tb_sys_role_permission CASCADE; CREATE TABLE sys.tb_sys_role_permission ( optsn VARCHAR(50) NOT NULL, -- 流水号 role_id VARCHAR(50) NOT NULL, -- 角色ID permission_id VARCHAR(50) NOT NULL, -- 权限ID creator VARCHAR(50) DEFAULT NULL, -- 创建者 dept_path VARCHAR(255) DEFAULT NULL, -- 部门全路径 updater VARCHAR(50) DEFAULT NULL, -- 更新者 create_time timestamptz NOT NULL DEFAULT now(), -- 创建时间 update_time timestamptz DEFAULT NULL, -- 更新时间(由触发器维护) delete_time timestamptz DEFAULT NULL, -- 删除时间 deleted boolean NOT NULL DEFAULT false, -- 是否删除 PRIMARY KEY (role_id, permission_id), UNIQUE (optsn) ); COMMENT ON TABLE sys.tb_sys_role_permission IS '角色权限表'; COMMENT ON COLUMN sys.tb_sys_role_permission.optsn IS '流水号'; COMMENT ON COLUMN sys.tb_sys_role_permission.role_id IS '角色ID'; COMMENT ON COLUMN sys.tb_sys_role_permission.permission_id IS '权限ID'; COMMENT ON COLUMN sys.tb_sys_role_permission.creator IS '创建者'; COMMENT ON COLUMN sys.tb_sys_role_permission.dept_path IS '部门全路径'; COMMENT ON COLUMN sys.tb_sys_role_permission.updater IS '更新者'; COMMENT ON COLUMN sys.tb_sys_role_permission.create_time IS '创建时间'; COMMENT ON COLUMN sys.tb_sys_role_permission.update_time IS '更新时间'; COMMENT ON COLUMN sys.tb_sys_role_permission.delete_time IS '删除时间'; COMMENT ON COLUMN sys.tb_sys_role_permission.deleted IS '是否删除'; -- 视图权限 DROP TABLE IF EXISTS sys.tb_sys_view_permission CASCADE; CREATE TABLE sys.tb_sys_view_permission ( optsn VARCHAR(50) NOT NULL, -- 流水号 view_id VARCHAR(50) NOT NULL, -- 视图ID permission_id VARCHAR(50) NOT NULL, -- 权限ID creator VARCHAR(50) DEFAULT NULL, -- 创建者 dept_path VARCHAR(255) DEFAULT NULL, -- 部门全路径 updater VARCHAR(50) DEFAULT NULL, -- 更新者 create_time timestamptz NOT NULL DEFAULT now(), -- 创建时间 update_time timestamptz DEFAULT NULL, -- 更新时间(由触发器维护) delete_time timestamptz DEFAULT NULL, -- 删除时间 deleted boolean NOT NULL DEFAULT false, -- 是否删除 PRIMARY KEY (view_id, permission_id), UNIQUE (optsn) ); COMMENT ON TABLE sys.tb_sys_view_permission IS '视图权限表'; COMMENT ON COLUMN sys.tb_sys_view_permission.optsn IS '流水号'; COMMENT ON COLUMN sys.tb_sys_view_permission.view_id IS '视图ID'; COMMENT ON COLUMN sys.tb_sys_view_permission.permission_id IS '权限ID'; COMMENT ON COLUMN sys.tb_sys_view_permission.creator IS '创建者'; COMMENT ON COLUMN sys.tb_sys_view_permission.dept_path IS '部门全路径'; COMMENT ON COLUMN sys.tb_sys_view_permission.updater IS '更新者'; COMMENT ON COLUMN sys.tb_sys_view_permission.create_time IS '创建时间'; COMMENT ON COLUMN sys.tb_sys_view_permission.update_time IS '更新时间'; COMMENT ON COLUMN sys.tb_sys_view_permission.delete_time IS '删除时间'; COMMENT ON COLUMN sys.tb_sys_view_permission.deleted IS '是否删除'; -- 为所有表创建更新时间触发器 -- DROP TRIGGER IF EXISTS trg_tb_sys_dept_update_time ON sys.tb_sys_dept; -- CREATE TRIGGER trg_tb_sys_dept_update_time -- BEFORE UPDATE ON sys.tb_sys_dept -- FOR EACH ROW -- EXECUTE FUNCTION sys.set_update_time(); -- DROP TRIGGER IF EXISTS trg_tb_sys_role_update_time ON sys.tb_sys_role; -- CREATE TRIGGER trg_tb_sys_role_update_time -- BEFORE UPDATE ON sys.tb_sys_role -- FOR EACH ROW -- EXECUTE FUNCTION sys.set_update_time(); -- DROP TRIGGER IF EXISTS trg_tb_sys_dept_role_update_time ON sys.tb_sys_dept_role; -- CREATE TRIGGER trg_tb_sys_dept_role_update_time -- BEFORE UPDATE ON sys.tb_sys_dept_role -- FOR EACH ROW -- EXECUTE FUNCTION sys.set_update_time(); -- DROP TRIGGER IF EXISTS trg_tb_sys_user_role_update_time ON sys.tb_sys_user_role; -- CREATE TRIGGER trg_tb_sys_user_role_update_time -- BEFORE UPDATE ON sys.tb_sys_user_role -- FOR EACH ROW -- EXECUTE FUNCTION sys.set_update_time(); -- DROP TRIGGER IF EXISTS trg_tb_sys_view_update_time ON sys.tb_sys_view; -- CREATE TRIGGER trg_tb_sys_view_update_time -- BEFORE UPDATE ON sys.tb_sys_view -- FOR EACH ROW -- EXECUTE FUNCTION sys.set_update_time(); -- DROP TRIGGER IF EXISTS trg_tb_sys_module_update_time ON sys.tb_sys_module; -- CREATE TRIGGER trg_tb_sys_module_update_time -- BEFORE UPDATE ON sys.tb_sys_module -- FOR EACH ROW -- EXECUTE FUNCTION sys.set_update_time(); -- DROP TRIGGER IF EXISTS trg_tb_sys_permission_update_time ON sys.tb_sys_permission; -- CREATE TRIGGER trg_tb_sys_permission_update_time -- BEFORE UPDATE ON sys.tb_sys_permission -- FOR EACH ROW -- EXECUTE FUNCTION sys.set_update_time(); -- DROP TRIGGER IF EXISTS trg_tb_sys_role_permission_update_time ON sys.tb_sys_role_permission; -- CREATE TRIGGER trg_tb_sys_role_permission_update_time -- BEFORE UPDATE ON sys.tb_sys_role_permission -- FOR EACH ROW -- EXECUTE FUNCTION sys.set_update_time(); -- DROP TRIGGER IF EXISTS trg_tb_sys_view_permission_update_time ON sys.tb_sys_view_permission; -- CREATE TRIGGER trg_tb_sys_view_permission_update_time -- BEFORE UPDATE ON sys.tb_sys_view_permission -- FOR EACH ROW -- EXECUTE FUNCTION sys.set_update_time(); -- ============================= -- 通用对象级权限(ACL) -- 支持对象类型:任意(如 article/file/course/...) -- 支持主体:user/dept/role -- 权限位:1=读(read),2=写(write),4=执行(exec),可相加 -- include_descendants:当主体为 dept/role 时,是否包含其子级(便于“所有子级可查看”场景) -- allow:true=允许;false=显式拒绝(拒绝优先生效) -- dept_path:用于数据范围隔离(与现有规则一致) -- ============================= DROP TABLE IF EXISTS sys.tb_sys_acl CASCADE; CREATE TABLE sys.tb_sys_acl ( optsn VARCHAR(50) NOT NULL, -- 流水号 acl_id VARCHAR(50) NOT NULL, -- ACL主键 object_type VARCHAR(50) NOT NULL, -- 对象类型:article/file/course/... object_id VARCHAR(50) NOT NULL, -- 对象ID principal_type VARCHAR(20) NOT NULL, -- 主体类型:user/dept/role principal_id VARCHAR(50) NOT NULL, -- 主体ID principal_dept_id VARCHAR(50) DEFAULT NULL, -- 当主体为role且限定到某部门时的部门ID(支持“某部门的某角色”) permission SMALLINT NOT NULL, -- 权限位:1读 2写 4执行 allow BOOLEAN NOT NULL DEFAULT true, -- 允许或显式拒绝 include_descendants BOOLEAN NOT NULL DEFAULT false, -- 是否包含子级(对dept/role生效) dept_path VARCHAR(255) DEFAULT NULL, -- 部门全路径(数据隔离) creator VARCHAR(50) DEFAULT NULL, -- 创建者 updater VARCHAR(50) DEFAULT NULL, -- 更新者 create_time timestamptz NOT NULL DEFAULT now(), -- 创建时间 update_time timestamptz DEFAULT NULL, -- 更新时间 delete_time timestamptz DEFAULT NULL, -- 删除时间 deleted boolean NOT NULL DEFAULT false, -- 是否删除 PRIMARY KEY (acl_id), UNIQUE (object_type, object_id, principal_type, principal_id, principal_dept_id, deleted), UNIQUE (optsn) ); COMMENT ON TABLE sys.tb_sys_acl IS '通用对象级权限表(ACL)'; COMMENT ON COLUMN sys.tb_sys_acl.object_type IS '对象类型:article/file/course/...'; COMMENT ON COLUMN sys.tb_sys_acl.object_id IS '对象ID'; COMMENT ON COLUMN sys.tb_sys_acl.principal_type IS '主体类型:user/dept/role'; COMMENT ON COLUMN sys.tb_sys_acl.principal_id IS '主体ID'; COMMENT ON COLUMN sys.tb_sys_acl.principal_dept_id IS '当主体为角色时,可选的限定部门ID(某部门的某角色)'; COMMENT ON COLUMN sys.tb_sys_acl.permission IS '权限位:1读 2写 4执行,可相加'; COMMENT ON COLUMN sys.tb_sys_acl.allow IS '是否允许(false=显式拒绝)'; COMMENT ON COLUMN sys.tb_sys_acl.include_descendants IS '是否包含子级(dept/role时启用)'; COMMENT ON COLUMN sys.tb_sys_acl.dept_path IS '部门全路径(用于数据范围隔离)'; CREATE INDEX idx_sys_acl_object ON sys.tb_sys_acl USING btree (object_type, object_id) WHERE deleted = false; CREATE INDEX idx_sys_acl_principal ON sys.tb_sys_acl USING btree (principal_type, principal_id) WHERE deleted = false; CREATE INDEX idx_sys_acl_dept_path ON sys.tb_sys_acl USING btree (dept_path) WHERE deleted = false; -- 针对“某部门的某角色”的检索优化 CREATE INDEX idx_sys_acl_role_scoped ON sys.tb_sys_acl USING btree (principal_id, principal_dept_id) WHERE deleted = false AND principal_type = 'role'; -- ============================= -- ACL 策略表:定义对象类型的层级可见/可编辑规则 -- 例如: -- - 同级与父级管理员可修改(edit_hierarchy_rule = 'parent_or_same_admin') -- - 子级全部可查看(view_hierarchy_rule = 'children_all') -- - 课程:下级只有指定部门/角色可查看(view_hierarchy_rule = 'children_specified') -- 说明:业务侧需结合“管理员”的判定(通常由角色判定)在应用层实现;本表做规则声明 -- ============================= DROP TABLE IF EXISTS sys.tb_sys_acl_policy CASCADE; CREATE TABLE sys.tb_sys_acl_policy ( optsn VARCHAR(50) NOT NULL, -- 流水号 policy_id VARCHAR(50) NOT NULL, -- 策略ID name VARCHAR(255) NOT NULL, -- 策略名称 object_type VARCHAR(50) NOT NULL, -- 目标对象类型 edit_hierarchy_rule VARCHAR(50) DEFAULT NULL, -- 编辑层级规则:parent_only/parent_or_same_admin/owner_only/none view_hierarchy_rule VARCHAR(50) DEFAULT NULL, -- 查看层级规则:children_all/children_specified/none default_permission SMALLINT DEFAULT 0, -- 默认权限位(无显式ACL时应用) default_allow BOOLEAN DEFAULT true, -- 默认是否允许 apply_to_children BOOLEAN DEFAULT true, -- 是否默认应用到子级 creator VARCHAR(50) DEFAULT NULL, updater VARCHAR(50) DEFAULT NULL, create_time timestamptz NOT NULL DEFAULT now(), update_time timestamptz DEFAULT NULL, delete_time timestamptz DEFAULT NULL, deleted boolean NOT NULL DEFAULT false, PRIMARY KEY (policy_id), UNIQUE (object_type, deleted), UNIQUE (optsn) ); COMMENT ON TABLE sys.tb_sys_acl_policy IS 'ACL对象类型策略表(层级可见/可编辑规则)'; COMMENT ON COLUMN sys.tb_sys_acl_policy.object_type IS '对象类型:article/file/course/...'; COMMENT ON COLUMN sys.tb_sys_acl_policy.edit_hierarchy_rule IS '编辑层级规则:parent_only/parent_or_same_admin/owner_only/none'; COMMENT ON COLUMN sys.tb_sys_acl_policy.view_hierarchy_rule IS '查看层级规则:children_all/children_specified/none'; COMMENT ON COLUMN sys.tb_sys_acl_policy.default_permission IS '默认权限位(无显式ACL时兜底)'; COMMENT ON COLUMN sys.tb_sys_acl_policy.apply_to_children IS '默认是否应用到子级'; CREATE INDEX idx_sys_acl_policy_object ON sys.tb_sys_acl_policy USING btree (object_type) WHERE deleted = false;