-- ===================================================================== -- UserBase 双来源部门 · CUSTOM 侧建表(任务书 USERBASE_DEPARTMENT_QODER_TASK.md T1 / 规格书 UB-1) -- 三张新表:ub_custom_dept_category(自定义分类)/ ub_custom_department(自定义部门) -- / ub_custom_department_member(部门成员关系) -- 交付文件,不在本机执行;由人工在 160 执行 -- 执行前请备份;JPA 实体与列同名映射,执行后重启后端即可生效 -- ⚠ application.yml 是 ddl-auto=update,后端先发也会自动建表,但**不带** NOT NULL/DEFAULT/COMMENT/唯一键, -- 且 del_marker 之类参与唯一约束的列必须由本脚本定义,故务必先执行本脚本 -- 口径:school_id = sys_group 中 type=2(学校组)节点的 id,与 AccessScopeService.scopeGroupIds() 同域 -- ===================================================================== -- --------------------------------------------------------------------------- -- 1. 自定义分类(学校的容器层,本身无启停、无成员) -- 名称唯一:del_marker 技巧——MySQL 的 uk 对 NULL 不去重,deleted_at 进 uk 挡不住「软删后再激活同名」, -- 故软删时把 del_marker 置为该行 id,未删行恒为 0,同校同名只能有一条**有效**行; -- name 列永不改写(软删保留原名,保证历史解析拿到原名、旧引用不指向新对象) -- --------------------------------------------------------------------------- CREATE TABLE IF NOT EXISTS ub_custom_dept_category ( id INT NOT NULL AUTO_INCREMENT COMMENT '主键(不可变稳定 ID)', school_id INT NOT NULL COMMENT '学校组 id(sys_group.type=2 的节点 id)', name VARCHAR(64) NOT NULL COMMENT '分类名称,学校自定;永不改写', sort_no INT NOT NULL DEFAULT 0 COMMENT '展示顺序,越小越靠前', is_deleted TINYINT(1) NOT NULL DEFAULT 0 COMMENT '软删标记:0=有效 / 1=已软删(不是业务状态)', del_marker BIGINT NOT NULL DEFAULT 0 COMMENT '软删时置为该行 id;参与唯一键,保证同名只挡有效行', deleted_at DATETIME NULL COMMENT '软删时间', deleted_by INT NULL COMMENT '软删操作人 sys_user.id', create_user INT NOT NULL COMMENT '创建人 sys_user.id(BaseEntity)', create_time DATETIME NOT NULL COMMENT '创建时间(BaseEntity)', update_user INT NULL COMMENT '修改人 sys_user.id(BaseEntity)', update_time DATETIME NULL COMMENT '修改时间(BaseEntity)', PRIMARY KEY (id), UNIQUE KEY uk_school_name_marker (school_id, name, del_marker), KEY idx_school_sort (school_id, is_deleted, sort_no) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COMMENT = '自定义部门分类(学校级容器,非可选部门)'; -- --------------------------------------------------------------------------- -- 2. 自定义部门(可配成员、可启停的实际可选对象) -- 唯一键=同校同分类下未软删的部门名不重复;跨分类、SYSTEM 与 CUSTOM 之间允许重名(A06) -- enabled 语义直读 1=启用/0=停用,**与 sys_group.status(0=启用/1=停用)方向相反,严禁混用** -- 软删不级联删成员:成员关系保留在库,由查询侧按部门 is_deleted 过滤(A12) -- --------------------------------------------------------------------------- CREATE TABLE IF NOT EXISTS ub_custom_department ( id INT NOT NULL AUTO_INCREMENT COMMENT '主键(CUSTOM 侧独立 ID,与 SYSTEM 组 id 不同域,引用须带 departmentType)', school_id INT NOT NULL COMMENT '学校组 id(冗余自分类,写口服务端复核)', category_id INT NOT NULL COMMENT '所属分类 ub_custom_dept_category.id,必须同校', name VARCHAR(64) NOT NULL COMMENT '部门名称,学校自定;永不改写', sort_no INT NOT NULL DEFAULT 0 COMMENT '同分类内展示顺序,越小越靠前', enabled TINYINT(1) NOT NULL DEFAULT 1 COMMENT '启停:1=启用 / 0=停用(新建默认启用)', is_deleted TINYINT(1) NOT NULL DEFAULT 0 COMMENT '软删标记:0=有效 / 1=已软删(删除不是第三种业务状态)', del_marker BIGINT NOT NULL DEFAULT 0 COMMENT '软删时置为该行 id;参与唯一键', deleted_at DATETIME NULL COMMENT '软删时间', deleted_by INT NULL COMMENT '软删操作人 sys_user.id', create_user INT NOT NULL COMMENT '创建人 sys_user.id(BaseEntity)', create_time DATETIME NOT NULL COMMENT '创建时间(BaseEntity)', update_user INT NULL COMMENT '修改人 sys_user.id(BaseEntity)', update_time DATETIME NULL COMMENT '修改时间(BaseEntity)', PRIMARY KEY (id), UNIQUE KEY uk_school_category_name_marker (school_id, category_id, name, del_marker), KEY idx_category_list (category_id, is_deleted, sort_no), KEY idx_school_list (school_id, is_deleted, enabled) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COMMENT = '学校自定义部门(与 SYSTEM 组织树完全分离)'; -- --------------------------------------------------------------------------- -- 3. 自定义部门成员关系(引用 sys_user.id,不复制账号) -- 移除成员=物理删该关系行(本仓无软删惯例,增删审计靠 @OperationLog),不得残留有效成员 -- uk 挡不住并发重复插入之外的场景(如软删部门后重新激活)由服务端逐个复核兜底 -- --------------------------------------------------------------------------- CREATE TABLE IF NOT EXISTS ub_custom_department_member ( id INT NOT NULL AUTO_INCREMENT COMMENT '主键', school_id INT NOT NULL COMMENT '学校组 id(与部门同校,写口服务端复核)', department_id INT NOT NULL COMMENT 'ub_custom_department.id', user_id INT NOT NULL COMMENT 'sys_user.id(本校教职工,排除学生组成员)', create_user INT NOT NULL COMMENT '添加人 sys_user.id(BaseEntity)', create_time DATETIME NOT NULL COMMENT '添加时间(BaseEntity)', update_user INT NULL COMMENT '修改人 sys_user.id(BaseEntity)', update_time DATETIME NULL COMMENT '修改时间(BaseEntity)', PRIMARY KEY (id), UNIQUE KEY uk_department_user (department_id, user_id), KEY idx_department (department_id), KEY idx_school (school_id), KEY idx_user (user_id) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COMMENT = '自定义部门成员关系(一个用户可属同校多个部门)'; -- --------------------------------------------------------------------------- -- 4. 核验(可选,执行后逐条确认) -- --------------------------------------------------------------------------- -- SHOW CREATE TABLE ub_custom_dept_category; -- SHOW CREATE TABLE ub_custom_department; -- SHOW CREATE TABLE ub_custom_department_member; -- SELECT TABLE_NAME, TABLE_COMMENT FROM information_schema.TABLES -- WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME LIKE 'ub_custom%'; -- 唯一键生效自检(手工插入应报 1062): -- INSERT INTO ub_custom_dept_category (school_id, name, create_user, create_time) VALUES (1, '自检分类', 0, NOW()); -- INSERT INTO ub_custom_dept_category (school_id, name, create_user, create_time) VALUES (1, '自检分类', 0, NOW()); -- 期望失败 -- DELETE FROM ub_custom_dept_category WHERE school_id = 1 AND name = '自检分类'; -- --------------------------------------------------------------------------- -- 回滚(本期未上线,回滚即删表;CUSTOM 数据不与 sys_group 有任何写耦合) -- --------------------------------------------------------------------------- -- DROP TABLE IF EXISTS ub_custom_department_member; -- DROP TABLE IF EXISTS ub_custom_department; -- DROP TABLE IF EXISTS ub_custom_dept_category;