接口调整
This commit is contained in:
@@ -1,5 +1,7 @@
|
|||||||
package com.njcn.rdms.module.system.dal.dataobject.user;
|
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.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
import com.njcn.rdms.framework.common.enums.CommonStatusEnum;
|
import com.njcn.rdms.framework.common.enums.CommonStatusEnum;
|
||||||
@@ -68,6 +70,7 @@ public class AdminUserDO extends BaseDO {
|
|||||||
/**
|
/**
|
||||||
* 离职时间
|
* 离职时间
|
||||||
*/
|
*/
|
||||||
|
@TableField(updateStrategy = FieldStrategy.ALWAYS)
|
||||||
private LocalDateTime resignedAt;
|
private LocalDateTime resignedAt;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -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 步做完,表结构才算真正和当前权限设计文档一致。
|
|
||||||
Reference in New Issue
Block a user