From 875e2598e507a8490c214cb8d021b56492a9cdd2 Mon Sep 17 00:00:00 2001 From: hongawen <83944980@qq.com> Date: Thu, 26 Mar 2026 16:14:46 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dal/dataobject/user/AdminUserDO.java | 3 + .../rdms-system-boot/src/表结构调整建议.md | 556 ------------------ 2 files changed, 3 insertions(+), 556 deletions(-) delete mode 100644 rdms-system/rdms-system-boot/src/表结构调整建议.md diff --git a/rdms-system/rdms-system-boot/src/main/java/com/njcn/rdms/module/system/dal/dataobject/user/AdminUserDO.java b/rdms-system/rdms-system-boot/src/main/java/com/njcn/rdms/module/system/dal/dataobject/user/AdminUserDO.java index 8056969..dafcb3d 100644 --- a/rdms-system/rdms-system-boot/src/main/java/com/njcn/rdms/module/system/dal/dataobject/user/AdminUserDO.java +++ b/rdms-system/rdms-system-boot/src/main/java/com/njcn/rdms/module/system/dal/dataobject/user/AdminUserDO.java @@ -1,5 +1,7 @@ package com.njcn.rdms.module.system.dal.dataobject.user; +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import com.njcn.rdms.framework.common.enums.CommonStatusEnum; @@ -68,6 +70,7 @@ public class AdminUserDO extends BaseDO { /** * 离职时间 */ + @TableField(updateStrategy = FieldStrategy.ALWAYS) private LocalDateTime resignedAt; /** diff --git a/rdms-system/rdms-system-boot/src/表结构调整建议.md b/rdms-system/rdms-system-boot/src/表结构调整建议.md deleted file mode 100644 index 5cd2a7a..0000000 --- a/rdms-system/rdms-system-boot/src/表结构调整建议.md +++ /dev/null @@ -1,556 +0,0 @@ -# 表结构调整建议 - -## 1. 先说结论 - -这个项目按“新项目、严格对齐设计文档”落地,不考虑历史兼容、降级或兜底。要满足《权限设计方案》,至少要做这 4 类调整: - -1. `system_dept` 从“普通部门表”升级成“可表达多层组织树的组织节点表”。 -2. 把“组织负责人”“直接管理关系”“特殊可见范围”从主表字段里拆出去,改成独立关系表。 -3. 把 `system_users` 的“多岗位逗号字段”改成“主岗位单字段”,否则和设计文档的“一人一岗”冲突。 -4. `system_role` 只保留 RBAC 角色能力,不引入设计文档中没有的 `data_scope` 一类字段,避免混淆数据范围模型。 - -其中 `system_dept.leader_user_id` 的最终处理原则是: - -- 不保留在最终模型中 -- 直接从 `system_dept` 删除 -- 组织负责人统一改由 `system_org_leader_relation` 维护 -- 后续所有权限判断都不再读取 `leader_user_id` - ---- - -## 2. 现有表和设计文档的主要冲突 - -### 2.1 `system_dept` 的问题 - -现状:[`system_dept.sql`](/C:/code/gitee/rdms-requirements-compilation/04-设计阶段/权限设计/system_dept.sql) 第 24 行开始的 `system_dept` 只有 `parent_id`,没有物化路径、组织类型;并且用 `leader_user_id` 单字段存负责人。 - -对应设计文档: -- 组织树需要 `path` 物化路径,见 [`权限设计方案.md`](/C:/code/gitee/rdms-requirements-compilation/04-设计阶段/权限设计/权限设计方案.md#L93) -- 负责人要独立成 `system_org_leader_relation`,支持一人负责多个节点、一个节点多个负责人、且支持生效失效时间,见 [`权限设计方案.md`](/C:/code/gitee/rdms-requirements-compilation/04-设计阶段/权限设计/权限设计方案.md#L104) 和 [`权限设计方案.md`](/C:/code/gitee/rdms-requirements-compilation/04-设计阶段/权限设计/权限设计方案.md#L218) - -结论: -- `leader_user_id` 不应出现在最终模型中,需要从 `system_dept` 直接删除,组织负责人统一改由 `system_org_leader_relation` 维护。 -- 后续所有权限判断都不再读取 `leader_user_id`。 -- `system_dept` 至少要补 `path`、`org_type`、`code`。 -- `org_type` 是“组织节点类型”,不是“研发专属方向类型”。 - -### 2.2 `system_users` 的问题 - -现状:[`system_dept.sql`](/C:/code/gitee/rdms-requirements-compilation/04-设计阶段/权限设计/system_dept.sql#L161) 的 `system_users` 里有: -- `dept_id` -- `post_ids` - -同时还有 [`system_user_post`](/C:/code/gitee/rdms-requirements-compilation/04-设计阶段/权限设计/system_dept.sql#L129) 关联表。 - -对应设计文档: -- 用户主组织归属只有一个:`department_id` -- 岗位是单值:`users.position_id` -- 岗位不等于负责人身份,见 [`权限设计方案.md`](/C:/code/gitee/rdms-requirements-compilation/04-设计阶段/权限设计/权限设计方案.md#L118) 和 [`权限设计方案.md`](/C:/code/gitee/rdms-requirements-compilation/04-设计阶段/权限设计/权限设计方案.md#L188) - -结论: -- `dept_id` 可以保留,但语义要改成“主组织归属”。 -- `post_ids` 和 `system_user_post` 与当前设计冲突,最终模型中应删除。 -- 用户岗位的唯一事实来源改成 `position_id`。 - -### 2.3 `system_role` 的问题 - -现状:[`system_role`](/C:/code/gitee/rdms-requirements-compilation/04-设计阶段/权限设计/system_dept.sql#L91) 是通用 RBAC 角色表。 - -对应设计文档: -- RBAC 角色只决定“能不能进模块” -- 数据范围由“自己参与项目 + 组织负责人关系 + 特殊可见性配置”决定 -- 角色与数据范围无直接绑定,见 [`权限设计方案.md`](/C:/code/gitee/rdms-requirements-compilation/04-设计阶段/权限设计/权限设计方案.md#L301) 和 [`权限设计方案.md`](/C:/code/gitee/rdms-requirements-compilation/04-设计阶段/权限设计/权限设计方案.md#L1132) - -结论: -- `system_role` 在本项目中只承担 RBAC 角色定义。 -- 设计文档中没有的 `data_scope`、`data_scope_dept_ids` 不进入最终模型。 -- 数据范围全部由 `system_project_member`、`system_org_leader_relation`、`system_user_visibility_config` 体系计算。 - -### 2.4 缺失的核心表 - -设计文档明确依赖但当前 SQL 中没有、且最终落库应统一使用 `system_` 前缀的表: - -- `system_org_leader_relation` -- `system_user_management_relation` -- `system_user_visibility_config` -- `system_project_member` - -这 4 张表是本方案真正的核心。 - ---- - -## 3. 推荐的目标模型 - -最终落库表名统一使用 `system_*` 前缀;设计文档中的无前缀名称仅作为业务别名理解,不作为最终建表名称。 - -### 3.1 保留并改造 - -- `system_dept` -- `system_users` -- `system_post` -- `system_role` -- `system_user_role` -- `system_menu` -- `system_role_menu` - -### 3.2 新增 - -- `system_org_leader_relation` -- `system_user_management_relation` -- `system_user_visibility_config` -- `system_project_member` - ---- - -## 4. 建议如何改表 - -## 4.1 `system_dept` - -### 建议保留字段 - -- `id` -- `name` -- `parent_id` -- `sort` -- `status` -- 审计字段 - -### 建议新增字段 - -```sql -ALTER TABLE system_dept - ADD COLUMN org_type VARCHAR(20) NOT NULL DEFAULT 'dept' COMMENT '组织节点类型: company/dept/direction/team', - ADD COLUMN path VARCHAR(1024) CHARACTER SET ascii NOT NULL DEFAULT '/' COMMENT '物化路径,如 /1/3/6/,适配雪花ID场景', - ADD COLUMN level INT NOT NULL DEFAULT 1 COMMENT '层级,从1开始', - ADD COLUMN code VARCHAR(64) NULL COMMENT '组织编码,可选,用于标识具体方向或组织节点', - ADD KEY idx_parent_id (parent_id), - ADD KEY idx_org_type (org_type), - ADD KEY idx_path (path(191)), - ADD UNIQUE KEY uk_dept_code (code); -``` - -### 字段口径 - -- `org_type` 必填,默认值建议为 `dept` -- `code` 非必填 -- `code` 如果填写,必须唯一 - -### `org_type` 如何理解 - -`org_type` 表示“组织树中的节点层级”,不是“研发部专属分类”。 - -推荐枚举: - -- `company`:公司 -- `dept`:部门,例如研发部、工程部、财务部 -- `direction`:部门下的业务/专业方向,例如系统方向、嵌入式方向、电气方向、结构方向 -- `team`:更细的小组,例如前端组、后端组、技术支持组 - -这意味着: - -- 研发部下面可以有 `direction` -- 工程部下面也可以有 `direction` -- 财务部如果没有方向层,直接挂在 `dept` 即可 - -### 如何区分“系统方向 / 嵌入式方向 / 电力电子方向” - -区分方式不是只靠 `org_type`,而是三者一起看: - -- `org_type`:说明它是一个方向节点 -- `name`:说明它叫“系统方向”还是“嵌入式方向” -- `code`:提供更稳定的程序识别标识 - -例如: - -```text -研发部 org_type=dept code=NULL -系统方向 org_type=direction code=RD_SYS -嵌入式方向 org_type=direction code=RD_EMBEDDED -电力电子方向 org_type=direction code=RD_POWER_ELEC -工程部 org_type=dept code=NULL -电气方向 org_type=direction code=ENG_ELEC -``` - -结论: - -- `org_type` 负责表达层级 -- `code` 负责表达“具体是谁” -- 对没有稳定编码需求的普通部门,`code` 可以为空 - -### `path` 为什么仍然建议使用 ID - -- 即使当前主键使用雪花 ID,组织树层级通常也不会太深,`VARCHAR(1024)` 足够承载 -- `path` 使用主键 ID 最稳定,不受名称修改、编码调整影响 -- `path` 只包含数字和 `/`,建议使用 `ascii` 字符集即可 - -### 建议删除字段 - -- `leader_user_id` - -原因: -- 一个节点可能有多个负责人。 -- 负责人需要带时效。 -- 负责人关系不应写死在组织节点表中。 - -最终要求: -- `system_dept` 不再保存负责人字段。 -- 负责人全部通过 `system_org_leader_relation` 表达。 - ---- - -## 4.2 `system_users` - -### 建议保留字段 - -- `id` -- `username` -- `password` -- `nickname` -- `dept_id` -- `email` -- `mobile` -- `status` -- 审计字段 - -### 建议新增字段 - -```sql -ALTER TABLE system_users - ADD COLUMN position_id BIGINT NULL COMMENT '主岗位ID', - ADD COLUMN resigned_at DATETIME NULL COMMENT '离职时间', - ADD KEY idx_user_dept (dept_id), - ADD KEY idx_user_position (position_id); -``` - -### 建议调整语义 - -- `dept_id`:从“部门ID”调整为“主组织归属ID” -- `status`:继续表示账号可用性 -- `resigned_at`:表示内部员工离职时间 - -这样可以区分: -- 账号被禁用 -- 人员已离职(通过 `resigned_at` 标识) - -### 用户状态判断建议 - -- `status`:手工控制是否停用 -- `resigned_at`:只表示“是否离职” - -建议判定口径: - -```text -账号可用 = - status = 正常 - 且 (resigned_at 为空 或 resigned_at > 当前时间) -``` - -离职状态判断建议: - -- 如果 `resigned_at` 为空:未离职 -- 如果 `resigned_at` 大于当前时间:未离职,但表示未来计划离职 -- 如果 `resigned_at` 小于等于当前时间:已离职 - -说明: - -- 可以通过定时任务在 `resigned_at <= 当前时间` 时自动把 `status` 更新为停用 -- `resigned_at` 不再承担临时账号到期语义 - -### 建议删除字段 - -- `post_ids` - -原因: -- 设计文档明确是一人一岗。 -- 逗号字段无法做约束,也不利于查询和迁移。 - -### `system_user_post` 怎么处理 - -按设计文档,直接删除,不进入最终模型。 - -原因: -- 设计文档定义的是“一人一岗”。 -- 岗位是正式职位,不是可叠加的临时职责。 -- 组织负责人、项目负责人、产品经理等身份,分别由: - - `system_org_leader_relation` - - `system_project_member.project_role` - 来表达,不应复用岗位表。 - ---- - -## 4.3 `system_post` - -当前 `system_post` 可以保留,但建议补齐岗位属性,便于表达文档里的“岗位体系”和职级。 - -```sql -ALTER TABLE system_post - ADD COLUMN post_type VARCHAR(20) NULL COMMENT '岗位类型: management/technical', - ADD COLUMN level_rank INT NULL COMMENT '职级,如 4/5/6/7/8/9/10'; -``` - -说明: -- 岗位仍然只表达正式职位。 -- 不表达“某方向 Leader”这类组织负责关系。 - ---- - -## 4.4 `system_role` - -`system_role` 继续保留给 RBAC 使用,但职责要收敛: - -- `system_role` 负责菜单、接口、模块访问权限 -- 不再负责 RDMS 项目数据范围计算 - -最终要求: - -- `system_role` 只保留 RBAC 必需字段 -- `data_scope` 直接删除 -- `data_scope_dept_ids` 直接删除 -- 字段裁剪如有需要,后续根据部门或角色做展示层/查询层控制,不混入 RBAC 主模型 - ---- - -## 5. 建议新增的关系表 - -## 5.1 `system_org_leader_relation` - -用于替代 `system_dept.leader_user_id`。 - -```sql -CREATE TABLE system_org_leader_relation ( - id BIGINT NOT NULL COMMENT '主键', - dept_id BIGINT NOT NULL COMMENT '组织节点ID', - user_id BIGINT NOT NULL COMMENT '负责人用户ID', - effective_from DATETIME NULL COMMENT '生效时间', - effective_until DATETIME NULL COMMENT '失效时间', - remark VARCHAR(500) NULL COMMENT '备注', - creator VARCHAR(64) NULL DEFAULT '' COMMENT '创建者', - create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - updater VARCHAR(64) NULL DEFAULT '' COMMENT '更新者', - update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', - deleted BIT(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', - PRIMARY KEY (id), - KEY idx_org_leader_user (user_id, deleted, effective_from, effective_until), - KEY idx_org_leader_dept (dept_id, deleted, effective_from, effective_until), - UNIQUE KEY uk_org_leader_once (dept_id, user_id, effective_from) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='组织负责人关系表'; -``` - -说明: -- 支持一个人负责多个组织节点。 -- 支持一个组织节点多个负责人。 -- 权限计算时只取当前有效记录。 - ---- - -## 5.2 `system_user_management_relation` - -用于“直接管理谁”,只支撑“看人”视图,不支撑项目可见范围反推。 - -```sql -CREATE TABLE system_user_management_relation ( - id BIGINT NOT NULL COMMENT '主键', - manager_user_id BIGINT NOT NULL COMMENT '直接管理者', - subordinate_user_id BIGINT NOT NULL COMMENT '被管理者', - effective_from DATETIME NULL COMMENT '生效时间', - effective_until DATETIME NULL COMMENT '失效时间', - remark VARCHAR(500) NULL COMMENT '备注', - creator VARCHAR(64) NULL DEFAULT '' COMMENT '创建者', - create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - updater VARCHAR(64) NULL DEFAULT '' COMMENT '更新者', - update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', - deleted BIT(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', - PRIMARY KEY (id), - KEY idx_mgr_user (manager_user_id, deleted, effective_from, effective_until), - KEY idx_sub_user (subordinate_user_id, deleted, effective_from, effective_until), - UNIQUE KEY uk_mgr_sub_once (manager_user_id, subordinate_user_id, effective_from) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户直接管理关系表'; -``` - ---- - -## 5.3 `system_user_visibility_config` - -这里应严格对齐设计文档,不再拆成主表+明细表,直接使用单表配置模型。 - -```sql -CREATE TABLE system_user_visibility_config ( - id BIGINT NOT NULL COMMENT '主键', - user_id BIGINT NOT NULL COMMENT '用户ID', - visibility_type VARCHAR(20) NOT NULL COMMENT 'all/directions/projects', - visible_direction_ids JSON NULL COMMENT '补充可见方向ID列表', - visible_project_ids JSON NULL COMMENT '补充可见项目ID列表', - remark VARCHAR(500) NULL COMMENT '配置原因说明', - creator VARCHAR(64) NULL DEFAULT '' COMMENT '创建者', - create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - updater VARCHAR(64) NULL DEFAULT '' COMMENT '更新者', - update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', - deleted BIT(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', - PRIMARY KEY (id), - UNIQUE KEY uk_visibility_user (user_id), - KEY idx_visibility_type (visibility_type) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户补充可见范围配置表'; -``` - -### 字段口径 - -- `visibility_type = 'all'` - - 表示补充全部项目可见范围 - - `visible_direction_ids`、`visible_project_ids` 应为空 - -- `visibility_type = 'directions'` - - 表示补充指定方向可见范围 - - `visible_direction_ids` 必填 - - `visible_project_ids` 应为空 - -- `visibility_type = 'projects'` - - 表示补充指定项目可见范围 - - `visible_project_ids` 必填 - - `visible_direction_ids` 应为空 - -### 约束原则 - -- 一人一条配置记录 -- 只做补充,不做减权 -- 不用这张表表达组织负责人关系 -- 不用这张表表达项目内操作权限 -- 已经通过 `system_project_member` 或 `system_org_leader_relation` 默认可见的项目,不再重复写入 `visible_project_ids` -- `visibility_type = 'projects'` 只用于补充“默认权限链路拿不到,但业务上需要额外查看”的项目 - -### JSON 规模判断 - -- `visibility_type = 'all'` 时不使用 JSON 列表 -- `visibility_type = 'directions'` 时,方向数量通常很少 -- `visibility_type = 'projects'` 时,只记录补充项目,不记录项目成员或组织负责人本来就可见的项目 - -因此在当前设计下,`visible_direction_ids` 和 `visible_project_ids` 的规模通常都会比较小,当前阶段没有必要为了低概率的大规模列表场景提前拆表。 - ---- - -## 5.4 `system_project_member` - -这张表是项目权限的事实来源,必须单独建。 - -```sql -CREATE TABLE system_project_member ( - id BIGINT NOT NULL COMMENT '主键', - project_id BIGINT NOT NULL COMMENT '项目ID', - user_id BIGINT NOT NULL COMMENT '用户ID', - project_role VARCHAR(20) NOT NULL COMMENT 'pm/product/developer/tester/viewer', - member_type VARCHAR(20) NOT NULL DEFAULT 'core' COMMENT 'core/support', - joined_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '加入时间', - left_at DATETIME NULL COMMENT '离开时间,NULL表示当前成员', - remark VARCHAR(500) NULL COMMENT '备注', - creator VARCHAR(64) NULL DEFAULT '' COMMENT '创建者', - create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - updater VARCHAR(64) NULL DEFAULT '' COMMENT '更新者', - update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', - deleted BIT(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', - active_user_id BIGINT GENERATED ALWAYS AS ( - CASE WHEN left_at IS NULL THEN user_id ELSE NULL END - ) STORED, - active_pm_project_id BIGINT GENERATED ALWAYS AS ( - CASE WHEN project_role = 'pm' AND left_at IS NULL THEN project_id ELSE NULL END - ) STORED, - PRIMARY KEY (id), - UNIQUE KEY uk_project_active_member (project_id, active_user_id), - UNIQUE KEY uk_project_active_pm (active_pm_project_id), - KEY idx_pm_user_active (user_id, left_at), - KEY idx_pm_project_role_active (project_id, project_role, left_at), - CONSTRAINT chk_project_role CHECK (project_role IN ('pm', 'product', 'developer', 'tester', 'viewer')), - CONSTRAINT chk_member_type CHECK (member_type IN ('core', 'support')) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='项目成员表'; -``` - -### 这里有一个关键点 - -设计文档中的这段 SQL: - -```sql -CREATE UNIQUE INDEX uk_one_pm_per_project -ON system_project_member(project_id) -WHERE project_role = 'pm' AND left_at IS NULL; -``` - -在 MySQL 8 里不能直接这样写,因为 MySQL 不支持带 `WHERE` 的部分唯一索引。 - -所以推荐用上面的“生成列 + 唯一索引”实现: -- `active_pm_project_id` -- `UNIQUE KEY uk_project_active_pm (active_pm_project_id)` - -这是这份设计文档里最需要提前修正的一个点。 - ---- - -## 6. 最终建议的职责边界 - -### 6.1 组织与人员 - -- `system_dept`:组织树节点 -- `system_users.dept_id`:用户主组织归属 -- `system_users.position_id`:用户主岗位 -- `system_org_leader_relation`:组织负责人关系 -- `system_user_management_relation`:直接管理关系 - -### 6.2 功能权限 - -- `system_role` -- `system_user_role` -- `system_menu` -- `system_role_menu` - -只管“能不能访问模块/菜单/接口”。 - -### 6.3 数据范围 - -- `system_project_member` -- `system_org_leader_relation` -- `system_user_visibility_config` - -只管“能看哪些项目/哪些人的数据”。 - ---- - -## 7. 推荐迁移顺序 - -### 第一阶段:建立正确主模型 - -1. 给 `system_dept` 增加 `org_type`、`path`、`level` -2. 给 `system_users` 增加 `position_id`、`employment_status`、`resigned_at` -3. 给 `system_post` 增加 `post_type`、`level_rank` - -### 第二阶段:建立关系表 - -1. 新建 `system_org_leader_relation` -2. 把 `system_dept.leader_user_id` 迁移进去 -3. 新建 `system_user_management_relation` -4. 新建 `system_user_visibility_config` - -### 第三阶段:建立项目权限模型 - -1. 新建 `system_project_member` -2. 所有项目角色改从 `system_project_member` 读取 -3. 所有项目可见范围改从“自己参与 + 组织负责人 + 特殊配置”计算 - -### 第四阶段:按最终模型收口 - -1. 删除 `system_dept.leader_user_id` -2. 删除 `system_users.post_ids` -3. 删除 `system_user_post` -4. 保持 `system_role` 仅承载 RBAC 角色定义 - ---- - -## 8. 你这次最应该优先改的地方 - -如果你想最小成本先把模型拉正,我建议优先级按下面来: - -1. `system_dept` 补 `path`、`org_type`、`code`,删除 `leader_user_id` -2. `system_users` 增加 `position_id`,删除 `post_ids` -3. 新建 `system_org_leader_relation` -4. 新建 `system_project_member` -5. 新建 `system_user_visibility_config` 体系 -6. 删除 `system_user_post`,并让岗位只保留单一事实来源 -7. 保持 `system_role` 精简,只保留设计文档需要的 RBAC 能力 - -这 7 步做完,表结构才算真正和当前权限设计文档一致。