HRMS-组织架构管理系分

目录

  1. 变更记录
  2. 项目背景
  3. 相关资料
  4. 参与人
  5. 功能模块
  6. 流程图
  7. UML 图
  8. 时序图
  9. 数据库设计
  10. API 设计
  11. 关键技术设计
  12. 排期

变更记录

记录每次修订的内容,方便追溯。

日期版本修订说明作者
2026-07-091.0初稿,组织架构管理(部门管理、职位管理)系统分析设计系分自动生成

项目背景

对本项目的背景以及目标进行描述,方便开发者理解需求,对齐上下文。

本模块来源于 HRMS(人资管理系统)产品规格说明书中第 3 部分——组织架构管理。组织架构是整个人资管理系统的数据基座,部门树与职位体系向上承载员工档案、入转调离、考勤、薪资等业务模块的归属与权限判定,向下决定工号生成规则、数据权限范围与汇报关系链路。当前公司组织信息散落在多份 Excel 与 OA 系统中,存在部门层级混乱、编码不统一、负责人信息缺失、合并拆分无审计等问题,导致工号生成口径不一致、部门主管数据权限边界模糊、跨部门统计口径失真。

当前主要痛点包括:部门层级深度无约束,历史数据中存在 8 级以上嵌套,导致递归查询性能差、前端树渲染卡顿;部门编码人工维护且无唯一性校验,工号生成出现重复风险;部门人数统计依赖人工导表核对,无法实时反映"试用期 + 正式"口径的在职人数;部门合并/拆分直接改库,缺乏员工转移校验与变更历史审计,事后无法追溯。本模块旨在建立统一的多级组织架构数字化管理能力,覆盖部门 CRUD、层级深度限制、闭包表递归查询优化、人数实时统计、部门合并,以及职位序列(M/P/S)与职级范围管理,为后续员工档案、入转调离、薪资核算等模块提供稳定、高性能的组织数据支撑。

本次系统设计的目标是:以"部门树缓存 + 闭包表递归查询优化"为核心,保证部门树查询性能在 1000 部门规模下毫秒级响应;通过应用层校验与数据库唯一索引双重保障部门编码唯一性,确保工号生成稳定可靠;建立部门变更历史审计机制,所有合并、层级调整均可追溯;实现部门人数(含下属部门)实时统计,口径严格限定为"试用期或正式"在职员工。

相关资料

参与人

角色姓名
项目负责人...
产品经理...
设计师...
工程师...

功能模块

描述组织架构管理涉及的功能与场景。

本模块核心功能包括:

  1. 部门管理:维护公司多级组织架构,支持部门 CRUD、层级深度限制(最大 5 级)、人数实时统计(含下属部门)、部门合并(需先转移员工)
  2. 职位管理:维护职位体系,支持职位 CRUD、职位序列(M 管理序列 / P 专业序列 / S 支持序列)、职级范围(M1-M5 / P1-P10 / S1-S5)、默认试用期配置(发起入职时自动填充)
  3. 部门编码管理:部门编码用于工号生成(年份 + 部门编码 + 序号),保证全局唯一,支持数据权限判定
  4. 部门负责人管理:部门负责人决定该部门数据权限范围,支持负责人变更与权限联动
  5. 组织变更审计:部门合并、层级调整、负责人变更等操作均记录变更历史,便于追溯

功能模块树

组织架构管理
├── 部门管理
│   ├── 部门 CRUD(新增/编辑/删除/查询)
│   ├── 部门层级(最大 5 级,子部门数量不限)
│   ├── 部门人数统计(含下属部门,口径:试用期/正式)
│   ├── 部门合并(源部门员工先转移至目标部门)
│   ├── 部门编码唯一性校验(用于工号生成)
│   └── 部门负责人管理(决定数据权限)
└── 职位管理
    ├── 职位 CRUD(新增/编辑/删除/查询)
    ├── 职位序列(M 管理 / P 专业 / S 支持)
    ├── 职级范围(M1-M5 / P1-P10 / S1-S5)
    ├── 默认试用期(发起入职时自动填充)
    └── 职位所属部门(空表示全公司通用)

流程图

对组织架构管理涉及的核心流程进行梳理。

6-1 部门创建/编辑流程

用户填写部门信息(名称/编码/上级/负责人/排序/描述)
│
▼
校验部门编码唯一性(应用层 + DB 唯一索引)
│
├── 编码已存在 ────────────────────> 返回错误"部门编码已存在"
│
▼
校验上级部门是否存在(空表示根部门)
│
▼
校验层级深度 ≤ 5(结合闭包表 depth 字段)
│
├── 当前层级 + 1 > 5 ─────────────> 返回错误"超出最大层级深度5级"
│
▼
持久化部门记录 + 维护闭包表(ancestor/descendant/depth)
│
▼
记录部门变更历史到 department_change_log
│
▼
主动刷新 Redis 部门树缓存(DEL + 重建)
│
▼
返回操作结果,部门创建/编辑完成

6-2 部门合并流程

用户选择源部门(被合并)和目标部门(保留)
│
▼
校验源部门与目标部门不同
│
├── 相同部门 ──────────────────────> 返回错误"源部门与目标部门不能相同"
│
▼
校验源部门无在职员工(试用期/正式状态)
│
├── 存在在职员工 ──────────────────> 返回错误"源部门存在在职员工,请先转移"
│
▼
执行合并事务:
│  1. 源部门子部门的 parent_id 更新为目标部门 ID
│  2. 重建闭包表关系(迁移祖先-后代记录)
│  3. 源部门标记为已删除(is_deleted = 1)
│
▼
记录合并变更历史到 department_change_log
│
▼
主动刷新 Redis 部门树缓存 + 人数统计缓存
│
▼
返回合并结果,部门合并完成

6-3 职位创建流程

用户选择职位序列(M 管理 / P 专业 / S 支持)
│
▼
根据序列确定职级范围选项
│  ├── M 序列 ─> M1-M5
│  ├── P 序列 ─> P1-P10
│  └── S 序列 ─> S1-S5
│
▼
填写职位名称(必填)+ 职级范围(必填)
│
▼
关联所属部门(可选,空表示全公司通用)
│
▼
配置默认试用期月数(发起入职时自动填充)
│
▼
校验职位名称在同部门/全公司范围内唯一
│
├── 名称重复 ──────────────────────> 返回错误"职位名称已存在"
│
▼
校验职级范围与所选序列匹配
│
├── 范围越界 ──────────────────────> 返回错误"职级范围超出序列允许范围"
│
▼
持久化职位记录
│
▼
返回操作结果,职位创建完成

UML 图

描述组织架构管理的核心类和依赖关系。

组织架构核心领域模型

@startuml
class Department {
  - id: Long
  - name: String "部门名称"
  - code: String "部门编码,用于工号生成"
  - parentId: Long "上级部门ID,空表示根部门"
  - managerId: Long "部门负责人ID,决定数据权限"
  - sortOrder: Integer "排序序号,越小越靠前"
  - description: String "部门描述"
  - status: Integer "状态:1=启用 0=停用"
  - createTime: LocalDateTime
  - updateTime: LocalDateTime
  - isDeleted: Integer "逻辑删除"
  --
  + getChildren(): List<Department>
  + getDepth(): Integer "当前层级深度"
  + getOnlineCount(): Integer "在职人数含子部门"
}

class Position {
  - id: Long
  - name: String "职位名称,如Java开发工程师"
  - sequence: PositionSequence "职位序列 M/P/S"
  - departmentId: Long "所属部门ID,空表示全公司通用"
  - levelRange: String "职级范围,如P1-P10"
  - defaultProbationMonths: Integer "默认试用期月数"
  - description: String "职位描述"
  - status: Integer "状态:1=启用 0=停用"
  - createTime: LocalDateTime
  - updateTime: LocalDateTime
  - isDeleted: Integer "逻辑删除"
  --
  + isGeneralPosition(): boolean "是否全公司通用"
}

class DepartmentClosure {
  - ancestorId: Long "祖先部门ID"
  - descendantId: Long "后代部门ID"
  - depth: Integer "层级深度,0=自身,1=直接子级"
  --
  + getDescendants(deptId): List<Long>
  + getAncestors(deptId): List<Long>
}

class DepartmentStat {
  - deptId: Long "部门ID"
  - totalCount: Integer "总人数"
  - onlineCount: Integer "在职人数(试用期+正式)"
  - updateTime: LocalDateTime
  --
  + refresh(): void
}

enum PositionSequence {
  M "管理序列 M1-M5:M1主管、M2经理、M3总监、M5VP"
  P "专业序列 P1-P10:P3初级、P5中级、P7高级、P9专家"
  S "支持序列 S1-S5:职能等级"
}

enum DepartmentStatus {
  ENABLED "启用"
  DISABLED "停用"
}

Department "1" *-- "0..*" DepartmentClosure : ancestor
Department "1" *-- "0..*" DepartmentClosure : descendant
Department "1" *-- "0..1" DepartmentStat
Department "1" o-- "0..*" Position : 关联职位
Position --> PositionSequence
Department --> DepartmentStatus

note right of DepartmentClosure
  闭包表:存储祖先-后代关系
  避免递归SQL查询子部门
  depth=0 自身,depth=1 直接子级
end note

note right of DepartmentStat
  统计口径:在职状态为
  "试用期"或"正式"的员工
  含所有下属部门
end note

@enduml

时序图

描述组织架构管理核心交互的调用时序。

8-1 部门树查询时序

@startuml
actor User as user
participant "前端" as fe
participant "网关/鉴权" as gateway
participant "组织架构服务" as orgSvc
database "Redis" as cache
database "MySQL" as db

user -> fe : 进入组织架构页面
fe -> gateway : GET /api/v1/departments/tree
gateway -> orgSvc : 查询部门树
orgSvc -> cache : GET dept:tree:all

alt 缓存命中
  cache --> orgSvc : 返回部门树JSON
else 缓存未命中
  orgSvc -> db : SELECT 全量部门 + 闭包表
  db --> orgSvc : 返回部门列表与层级关系
  orgSvc -> orgSvc : 内存构建树结构
  orgSvc -> cache : SET dept:tree:all (TTL 1h)
end

orgSvc --> fe : 返回部门树(含人数统计)
fe --> user : 渲染部门树
@enduml

8-2 部门人数统计时序

@startuml
actor HR as hr
participant "前端" as fe
participant "组织架构服务" as orgSvc
participant "统计服务" as statSvc
database "Redis" as cache
database "MySQL" as db

hr -> fe : 点击部门查看人数
fe -> orgSvc : GET /api/v1/departments/{id}/member-count
orgSvc -> cache : GET dept:stat:{id}

alt 缓存命中
  cache --> orgSvc : 返回统计结果
else 缓存未命中
  orgSvc -> db : 查询部门闭包表获取所有子部门ID
  db --> orgSvc : 返回子部门ID列表(含自身)
  orgSvc -> statSvc : 统计在职人数(部门ID集合)
  statSvc -> db : 统计在职人数
  note right of db
    SELECT COUNT(*) FROM employee_work_info ew
    JOIN employee e ON e.id = ew.employee_id
    WHERE ew.department_id IN (:deptIds)
    AND e.status IN (1, 2)
    -- 1=试用期 2=正式
  end note
  db --> statSvc : 返回在职人数
  statSvc --> orgSvc : 返回 onlineCount
  orgSvc -> cache : SET dept:stat:{id} (TTL 5min)
end

orgSvc --> fe : 返回 { totalCount, onlineCount, subDeptCount }
fe --> hr : 展示部门人数(含下属部门)
@enduml

8-3 部门创建时序

@startuml
actor HR as hr
participant "前端" as fe
participant "组织架构服务" as orgSvc
database "MySQL" as db
database "Redis" as cache

hr -> fe : 填写部门信息并提交
fe -> orgSvc : POST /api/v1/departments
orgSvc -> db : 校验部门编码唯一性
db --> orgSvc : 编码可用
orgSvc -> orgSvc : 校验层级深度 ≤ 5(查询父部门 depth)
alt 层级超限
  orgSvc --> fe : 返回错误"超出最大层级深度5级"
else 层级合法
  orgSvc -> db : INSERT department + 维护闭包表(事务)
  orgSvc -> db : INSERT department_change_log(变更历史)
  orgSvc -> cache : DEL dept:tree:all(失效缓存)
  orgSvc -> cache : DEL dept:stat:*(失效人数缓存)
  orgSvc --> fe : 返回部门ID
  fe --> hr : 创建成功,刷新部门树
end
@enduml

数据库设计

组织架构管理模块涉及的核心数据表。技术栈:Spring Boot + MyBatis + MySQL + Redis。

部门表 department

CREATE TABLE IF NOT EXISTS `department` (
  `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `name` VARCHAR(64) NOT NULL COMMENT '部门名称,如"技术部"',
  `code` VARCHAR(8) NOT NULL COMMENT '部门编码,用于工号生成(年份+部门编码+序号),全局唯一',
  `parent_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '上级部门ID,空表示根部门',
  `manager_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '部门负责人ID,关联employee.id,决定数据权限范围',
  `sort_order` INT NOT NULL DEFAULT 0 COMMENT '排序序号,越小越靠前',
  `description` VARCHAR(256) DEFAULT NULL COMMENT '部门描述,职能说明',
  `status` TINYINT NOT NULL DEFAULT 1 COMMENT '状态:1=启用 0=停用',
  `create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  `is_deleted` TINYINT NOT NULL DEFAULT 0 COMMENT '逻辑删除:0=否 1=是',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_code` (`code`),
  KEY `idx_parent_id` (`parent_id`),
  KEY `idx_manager_id` (`manager_id`),
  KEY `idx_status_sort` (`status`, `sort_order`)
) DEFAULT CHARACTER SET = utf8mb4 COMMENT = '部门表,维护多级组织架构';

部门闭包表 department_closure

CREATE TABLE IF NOT EXISTS `department_closure` (
  `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `ancestor_id` BIGINT UNSIGNED NOT NULL COMMENT '祖先部门ID,关联department.id',
  `descendant_id` BIGINT UNSIGNED NOT NULL COMMENT '后代部门ID,关联department.id',
  `depth` INT NOT NULL COMMENT '层级深度:0=自身,1=直接子级,2=孙级...最大4(共5级)',
  `create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_ancestor_descendant` (`ancestor_id`, `descendant_id`),
  KEY `idx_ancestor_id` (`ancestor_id`),
  KEY `idx_descendant_id` (`descendant_id`),
  KEY `idx_depth` (`depth`)
) DEFAULT CHARACTER SET = utf8mb4 COMMENT = '部门闭包表,存储祖先-后代关系,优化递归查询';

-- 说明:查询某部门所有子孙部门:SELECT descendant_id FROM department_closure WHERE ancestor_id = ?
--       查询某部门所有祖先:SELECT ancestor_id FROM department_closure WHERE descendant_id = ?
--       查询某部门层级深度:SELECT MAX(depth) FROM department_closure WHERE descendant_id = ?

职位表 position

CREATE TABLE IF NOT EXISTS `position` (
  `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `name` VARCHAR(64) NOT NULL COMMENT '职位名称,如"Java开发工程师"',
  `sequence` VARCHAR(2) NOT NULL COMMENT '职位序列:M=管理序列 P=专业序列 S=支持序列',
  `department_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '所属部门ID,空表示全公司通用',
  `level_range` VARCHAR(16) NOT NULL COMMENT '职级范围,如P1-P10、M1-M5、S1-S5',
  `default_probation_months` INT NOT NULL DEFAULT 3 COMMENT '默认试用期月数,发起入职时自动填充',
  `description` VARCHAR(512) DEFAULT NULL COMMENT '职位描述,岗位职责说明',
  `status` TINYINT NOT NULL DEFAULT 1 COMMENT '状态:1=启用 0=停用',
  `create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  `is_deleted` TINYINT NOT NULL DEFAULT 0 COMMENT '逻辑删除:0=否 1=是',
  PRIMARY KEY (`id`),
  KEY `idx_sequence` (`sequence`),
  KEY `idx_department_id` (`department_id`),
  KEY `idx_status` (`status`),
  KEY `idx_name_sequence` (`name`, `sequence`)
) DEFAULT CHARACTER SET = utf8mb4 COMMENT = '职位表,维护职位序列与职级范围';

部门统计表 department_stat

CREATE TABLE IF NOT EXISTS `department_stat` (
  `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `dept_id` BIGINT UNSIGNED NOT NULL COMMENT '部门ID,关联department.id',
  `total_count` INT NOT NULL DEFAULT 0 COMMENT '总人数(含所有在职状态)',
  `online_count` INT NOT NULL DEFAULT 0 COMMENT '在职人数,口径:试用期或正式状态',
  `sub_dept_count` INT NOT NULL DEFAULT 0 COMMENT '下属部门数量',
  `update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '统计更新时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_dept_id` (`dept_id`),
  KEY `idx_online_count` (`online_count`)
) DEFAULT CHARACTER SET = utf8mb4 COMMENT = '部门统计表,缓存部门人数统计结果';

部门变更历史表 department_change_log

CREATE TABLE IF NOT EXISTS `department_change_log` (
  `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `dept_id` BIGINT UNSIGNED NOT NULL COMMENT '部门ID,关联department.id',
  `change_type` VARCHAR(32) NOT NULL COMMENT '变更类型:CREATE/UPDATE/DELETE/MERGE/MOVE/STATUS_CHANGE',
  `field_name` VARCHAR(64) DEFAULT NULL COMMENT '变更字段名(UPDATE时记录)',
  `old_value` VARCHAR(512) DEFAULT NULL COMMENT '变更前值',
  `new_value` VARCHAR(512) DEFAULT NULL COMMENT '变更后值',
  `operator_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '操作人ID,关联employee.id',
  `remark` VARCHAR(256) DEFAULT NULL COMMENT '备注,如合并时记录源部门与目标部门',
  `create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '变更时间',
  PRIMARY KEY (`id`),
  KEY `idx_dept_id` (`dept_id`),
  KEY `idx_change_type` (`change_type`),
  KEY `idx_operator_id` (`operator_id`),
  KEY `idx_create_time` (`create_time`)
) DEFAULT CHARACTER SET = utf8mb4 COMMENT = '部门变更历史表,记录合并/层级调整/负责人变更等操作';

API 设计

组织架构管理对外提供的核心接口。

1. 获取部门树

GET /api/v1/departments/tree

请求参数

参数类型必填描述
includeCountBoolean是否包含人数统计,默认 true
statusInteger部门状态筛选:1=启用 0=停用,默认全部

响应格式

{
  "code": 0,
  "message": "success",
  "data": [
    {
      "id": 1,
      "name": "总公司",
      "code": "00",
      "parentId": null,
      "managerId": 1000,
      "managerName": "张总",
      "sortOrder": 1,
      "status": 1,
      "onlineCount": 156,
      "subDeptCount": 3,
      "children": [
        {
          "id": 10,
          "name": "技术部",
          "code": "01",
          "parentId": 1,
          "managerId": 1001,
          "managerName": "李工",
          "sortOrder": 1,
          "status": 1,
          "onlineCount": 45,
          "subDeptCount": 2,
          "children": [
            {
              "id": 101,
              "name": "后端组",
              "code": "0101",
              "parentId": 10,
              "managerId": 1002,
              "sortOrder": 1,
              "status": 1,
              "onlineCount": 20,
              "subDeptCount": 0,
              "children": []
            }
          ]
        }
      ]
    }
  ]
}
说明:部门树整体缓存于 Redis(key: dept:tree:all,TTL 1 小时),部门变更时主动失效重建。onlineCount 为在职人数(试用期+正式),含所有下属部门。

2. 创建部门

POST /api/v1/departments

请求参数

参数类型必填描述
nameString部门名称,如"技术部"
codeString部门编码,用于工号生成,全局唯一
parentIdLong上级部门ID,空表示根部门
managerIdLong部门负责人ID,决定数据权限
sortOrderInteger排序序号,越小越靠前
descriptionString部门描述,职能说明

响应格式

{
  "code": 0,
  "message": "success",
  "data": {
    "id": 102,
    "name": "前端组",
    "code": "0102",
    "parentId": 10,
    "depth": 3
  }
}
说明:服务端校验部门编码唯一性(DB 唯一索引 + 应用层校验),校验层级深度 ≤ 5(结合闭包表 depth 字段)。创建成功后主动刷新 Redis 部门树缓存。

3. 更新部门

PUT /api/v1/departments/{id}

请求参数

参数类型必填描述
idLong部门ID(路径参数)
nameString部门名称
codeString部门编码(变更影响工号生成,谨慎)
parentIdLong上级部门ID(变更需校验层级深度)
managerIdLong部门负责人ID
sortOrderInteger排序序号
descriptionString部门描述
statusInteger状态:1=启用 0=停用

响应格式

{
  "code": 0,
  "message": "success",
  "data": {
    "id": 102,
    "updatedFields": ["name", "managerId", "sortOrder"],
    "depth": 3
  }
}
说明:变更 parentId 时需重新校验层级深度 ≤ 5,并重建闭包表关系。所有变更记录写入 department_change_log 表,便于追溯。

4. 删除部门

DELETE /api/v1/departments/{id}

请求参数

参数类型必填描述
idLong部门ID(路径参数)

响应格式

{
  "code": 0,
  "message": "success",
  "data": {
    "id": 102,
    "deleted": true
  }
}
说明:删除前需校验:(1) 部门无子部门(subDeptCount = 0);(2) 部门无在职员工(onlineCount = 0)。任一条件不满足返回错误提示。删除为逻辑删除(is_deleted = 1),同时清理闭包表相关记录并刷新缓存。

5. 获取部门人数统计

GET /api/v1/departments/{id}/member-count

请求参数

参数类型必填描述
idLong部门ID(路径参数)
includeSubDeptBoolean是否包含下属部门,默认 true

响应格式

{
  "code": 0,
  "message": "success",
  "data": {
    "deptId": 10,
    "deptName": "技术部",
    "totalCount": 50,
    "onlineCount": 45,
    "probationCount": 5,
    "regularCount": 40,
    "subDeptCount": 2,
    "subDeptBreakdown": [
      { "deptId": 101, "deptName": "后端组", "onlineCount": 20 },
      { "deptId": 102, "deptName": "前端组", "onlineCount": 25 }
    ],
    "updateTime": "2026-07-09T14:30:00"
  }
}
说明:统计口径为在职状态为"试用期"(1) 或"正式"(2) 的员工,含所有下属部门(通过闭包表递归查询子部门ID)。结果缓存于 Redis(key: dept:stat:{id},TTL 5 分钟),定时任务每 5 分钟刷新。

6. 职位列表查询

GET /api/v1/positions

请求参数

参数类型必填描述
keywordString职位名称模糊搜索
sequenceString职位序列筛选:M=管理 P=专业 S=支持
departmentIdLong所属部门ID筛选
includeGeneralBoolean是否包含全公司通用职位(departmentId 为空),默认 true
statusInteger状态筛选:1=启用 0=停用,默认启用
pageInteger页码,默认 1
sizeInteger每页条数,默认 20

响应格式

{
  "code": 0,
  "message": "success",
  "data": {
    "total": 35,
    "page": 1,
    "size": 20,
    "records": [
      {
        "id": 20,
        "name": "Java开发工程师",
        "sequence": "P",
        "sequenceDesc": "专业序列",
        "departmentId": 10,
        "departmentName": "技术部",
        "levelRange": "P3-P9",
        "defaultProbationMonths": 3,
        "description": "负责后端服务开发",
        "status": 1,
        "createTime": "2026-06-01T10:00:00"
      }
    ]
  }
}

7. 创建职位

POST /api/v1/positions

请求参数

参数类型必填描述
nameString职位名称,如"Java开发工程师"
sequenceString职位序列:M=管理序列 P=专业序列 S=支持序列
departmentIdLong所属部门ID,空表示全公司通用
levelRangeString职级范围,如 P1-P10,需与 sequence 匹配
defaultProbationMonthsInteger默认试用期月数,发起入职时自动填充
descriptionString职位描述,岗位职责说明

响应格式

{
  "code": 0,
  "message": "success",
  "data": {
    "id": 21,
    "name": "前端开发工程师",
    "sequence": "P",
    "levelRange": "P3-P8",
    "defaultProbationMonths": 3
  }
}
说明:服务端校验职级范围与所选序列匹配(M 对应 M1-M5,P 对应 P1-P10,S 对应 S1-S5),校验职位名称在同部门/全公司范围内唯一。

关键技术设计

部门树缓存方案

部门树是组织架构管理中查询频率最高的数据,采用 Redis 缓存完整部门树 JSON,避免每次查询都读取 MySQL 全表并内存构建树。

闭包表递归查询优化

传统递归查询子部门使用 MySQL 8.0 的 CTE 或多次查询,性能差且不可控。采用闭包表(Closure Table)存储祖先-后代关系,将递归查询转化为单次 JOIN。

部门编码唯一性校验

部门编码用于工号生成(年份 + 部门编码 + 序号),其唯一性直接影响工号生成的正确性,采用数据库唯一索引 + 应用层校验双重保障。

部门人数实时统计

部门人数统计需实时反映"试用期 + 正式"口径的在职员工数,并含所有下属部门。采用缓存 + 定时刷新策略平衡实时性与性能。

部门层级深度限制

规格要求部门最大层级深度为 5 级,采用应用层校验结合闭包表 depth 字段实现严格限制。

排期

对研发时间计划进行排期。

阶段内容预估工期
需求评审评审产品规格,确认部门/职位字段定义、层级限制、合并规则1天
技术方案完成系分文档评审,确认闭包表方案、缓存策略、接口方案2天
数据库开发建表(department/closure/position/stat/change_log)、索引优化、闭包表初始化脚本2天
后端开发部门CRUD、闭包表维护、职位CRUD、人数统计、合并流程、变更审计6天
前端开发部门树页面、部门编辑页、职位列表页、职位编辑页、人数统计展示4天
联调测试前后端联调、层级深度校验、合并流程测试、缓存命中率测试2天
回归上线全量回归、历史数据治理、预发验证、正式上线1天

总预估工期:约 18 个工作日