design: 一期批次1组织人事底座(F01~F17)设计评审定稿(对齐SRS v3.1:范围扩入编制F16/项目式F17、49表DDL、约120端点、UI页面组件树、降级项D1/D3/D4/D9方案与二期预留、面向develop任务拆解T01~T27、部署口径9182/MariaDB hrs)

This commit is contained in:
Pipeline Agent 2026-08-19 16:08:16 +08:00
parent d5ab31da8b
commit e6b266fee7
7 changed files with 1106 additions and 411 deletions

View File

@ -1 +1,397 @@
见 git 仓库 git@git.opencomputing.cn:yumoqing/hr-system.gitmain 分支,提交 7926505路径 docs/00-requirement/requirement-spec.md —— 《人事系统一期需求规格说明书》SRS v3.1 全文12 章29 项 FEAT 规格。配套文档同目录approved-features.md29 项 feature 基线、requirement-traceability.mdxlsx→feature 100% 覆盖追溯矩阵、iteration1-function-detail.mdF01~F15 共 81 条可验收项);应用/模块定义见 apps/hr-web.md 与 modules/hr-*.md8 个模块)。 # 人事系统一期 需求规格说明书SRS
- 文档编号HR-SRS-2026-001
- 版本v3.12026-08-18针对 QC 退回意见复核修订修正批次条目计数、统一模块文档引用口径、补充中文标题命名v3.0 补齐全部规格内容并落仓)
- 状态提交评审agent.requirement 正式交付件;本文档即《人事系统一期需求规格说明书》)
- 迭代:人事系统-初始迭代IDk1bIV7ab0-_EHo6E680kv单迭代交付
- 需求来源《开元云100人钉钉睿人事报价方案》功能清单工作空间 `xlsx_dump.txt` / `docs/需求来源_钉钉睿人事功能清单.md`
- 功能基线:已批准功能 29 项(见 `docs/00-requirement/approved-features.md`,含 feature ID 与优先级)
- 追溯矩阵:`docs/00-requirement/requirement-traceability.md`
- 配套文档:应用 `apps/hr-web.md`;模块 `modules/hr-org|hr-roster|hr-flow|hr-contract|hr-report|hr-system|hr-salary|hr-recruit.md`;设计基线 `docs/01-design/*`迭代1组织人事底座 F01~F15
- 技术口径ocai 规范 —— 前端 bricks 组件体系 + dspy 声明式页面,后端 ahserverPython数据层 apppublic/sqlorMariaDB
---
## 1. 项目概述
### 1.1 背景
开元云拟采购对标「钉钉睿人事」的人事管理系统,账号规模 100 人,预算方案含组织人事(必选底座)、薪酬管理、招聘管理三大模块及部署服务。为摆脱按年付费的 SaaS 依赖,决定自研 Web 版人事系统(应用代号 **hr-web****一期(初始迭代)交付组织人事、薪酬管理、招聘管理三大模块的本地功能闭环**;所有外部系统对接(钉钉、税局、招聘平台、电子签、硬件等)统一放二期。
### 1.2 项目目标
1. 交付 100 人账号规模可用的组织人事 + 薪酬 + 招聘本地闭环系统。
2. 员工主数据(花名册)成为全系统唯一事实来源,入转调离全流程线上闭环。
3. 薪酬本地算税算薪(累计预扣法),工资条在线发放确认。
4. 招聘从职位/需求 → 简历/人才库 → 流程(初筛/面试/offer/入职)本地闭环。
5. 全部外部依赖留桩,二期可平滑接入。
### 1.3 一期范围总览29 项已批准功能)
| 域 | 功能项数 | P0 | P1 | P2 |
|---|---|---|---|---|
| 组织人事(底座) | 12 | 5 | 6 | 1 |
| 薪酬管理 | 10 | 4 | 4 | 2 |
| 招聘管理 | 7 | 1 | 3 | 3 |
| 合计 | **29** | **10** | **13** | **6** |
**一期明确不做(范围外)**:钉钉通讯录/智能人事同步、考勤系统、电子签、视频面试、身份证硬件读卡、税局在线申报缴纳、招聘平台/猎企第三方真实对接、招聘官网对外公网发布内网部署形态、浏览器插件助手、AI 算薪公式解析(提供基础公式编辑器)。以上均在一期做**字段/接口/流程桩位预留**(见 §9
### 1.4 交付批次建议(同属一个迭代,分三批开发组织)
> 一期功能量大29 feature建议按依赖关系分三批滚动开发、分批验收整体仍在「人事系统-初始迭代」内交付。
| 批次 | 内容 | feature 数 | 进入条件 |
|---|---|---|---|
| 批次1底座+组织人事 | 系统管理与权限基座、组织管理、职位职级、花名册(含兼岗)、入职、转正与调动、离职、合同管理、员工服务与工作台、编制管理、项目式组织、人事报表 | 12 | 迭代启动即开始 |
| 批次2薪酬 | 薪资档案与岗酬体系、薪资方案与算薪规则引擎、定调薪、发薪活动与薪资核算、薪资校验/锁定/发薪审批、个税(本地)、社保公积金、工资条、薪酬报表、成本与预算 | 10 | 批次1花名册/组织/流程/报表基线完成 |
| 批次3招聘 | 招聘职位与需求、人才库与简历、招聘流程、招聘邮件与消息提醒、招聘渠道与猎企(本地)、招聘报表与面试登记、招聘官网与内推官网 | 7 | 批次1基线完成批次2、3可并行批次2 先行约 2 周以稳定算薪基线) |
批次依赖批次2/3 均依赖批次1的「花名册员工主数据 + hr-flow 审批引擎 + 权限/日志基座 + 消息提醒通道」。
---
## 2. 用户角色与权限
### 2.1 角色定义
| 角色 | 代码 | 职责与权限概要 |
|---|---|---|
| 系统管理员 | admin | 角色/管理员/数据范围配置、操作日志、全部数据与配置、系统管理基座 |
| 人事HR | hr | 组织/花名册/入转调离/合同/薪酬核算/招聘全流程操作、流程配置、报表 |
| 部门经理 | manager | 数据范围内入转调离与薪酬/招聘审批、团队统计、下属关怀提醒;招聘中可作为用人经理/面试官 |
| 员工(自助) | employee | 个人档案查看与自助修改、发起人事审批、待办处理、工资条查看确认、企业政策/公告、招聘中可作为内推人 |
| 招聘扩展角色批次3 | — | 招聘负责人(唯一,职位全权限)、招聘协助人(多位)、用人经理、面试官、候选人(仅官网/内推投递与登记表填写,无需系统账号) |
### 2.2 权限模型(可验收)
1. **管理角色**admin 可创建角色并配置菜单/操作权限;未注册路径默认拒绝。
2. **数据范围**:支持「组织维度(部门集合含子树)」与「花名册字段维度(可见字段集合)」两类范围叠加;查询、报表、导出全部强制叠加数据范围。
3. **管理员管理**admin 可创建管理员并授权角色与数据范围。
4. **敏感脱敏**身份证号全角色脱敏前3后3、手机号前3后4薪资/职级等敏感字段仅 admin/hr 可见(字段定义 sensitive 标记驱动)。
5. **操作日志**全量写操作留痕操作人、时间、IP、前后值对比可按时间/类型查询。
6. 招聘模块角色批次3职位级授权招聘负责人/协助人/用人经理/面试官),数据范围与职位绑定。
---
## 3. 功能需求29 项,输入/处理/输出/验收标准)
> 编号规则FEAT-<批次>-<序号>P0/P1/P2 为已批准 feature 基线优先级。
### 3.1 批次1底座 + 组织人事12 项)
#### FEAT-B1-01 系统管理与权限基座(流程引擎/权限/日志/API[P0]
- **输入**:表单定义(字段引用花名册字段)、流程定义(节点/条件/审批角色)、角色与数据范围配置、操作行为。
- **处理**:①自定义入转调离等表单,花名册字段可被审批引用,多条件审批、节点字段权限;②审批角色管理(范围/操作/数据查看三维配置);③预置四类流程模板:人事流程(入职/转正/异动/离职/离职交接——一期落地)、考勤流程(桩位,表单可建但不联动考勤系统)、薪酬流程(定薪/调薪/发薪——批次2落地、组合审批入职定薪/转正调薪/异动调薪——批次2落地审批通过自动回写花名册/薪资档案;④审批数据按表单/状态/发起人/编号/时间多条件查询、导出、在线打印;⑤权限管理(管理角色/人员范围/管理员⑥操作日志前后对比⑦API 开放接口一期仅预留鉴权与端点规范(外部集成对接二期)。
- **输出**:可配置表单/流程、流转中审批单、回写后的花名册与薪资数据、审批查询结果与打印件、日志记录。
- **验收标准**:①不写代码配置出入转调离 4 类审批流并完整流转;②审批通过自动更新花名册对应字段(状态/部门/职位/转正日期等);③数据范围外用户查询/导出不可见该数据;④敏感字段按角色脱敏展示;⑤任意写操作可在日志中查到前后值;⑥审批单可打印为 A4 版式。
#### FEAT-B1-02 组织管理(组织架构/时间轴/合同公司)[P0]
- **输入**组织信息编码、名称、类型、负责人、上级、生效时间、自定义字段、Excel 导入模板、历史日期(架构图回溯)。
- **处理**:组织树查看/筛选;新建/编辑/变更/停用/移动组织Excel 模板批量导入;组织字段自定义;组织架构图按层级/根节点展开、自定义显示内容、**按选定日期查看历史架构并导出图片**;时间轴记录节点新增/删除/拆分/合并/修改;合同公司管理(名称、统一社会信用代码等)。
- **输出**:组织树、历史架构图(图片导出)、变更时间轴、合同公司台账。
- **验收标准**:①三级以上组织树 CRUD 与移动生效且引用联动(员工任职部门随组织移动);②批量导入 ≥200 行成功率 100%(模板校验提示错误行);③选择任意历史日期可查看并导出当时架构图;④每次结构变更在时间轴留痕;⑤合同公司可被合同模块与入职流程引用。
#### FEAT-B1-03 职位职级体系(职位/职务/职级/职等/序列)[P0]
- **输入**:职位(编码/应用部门/职务/序列/类别/描述)、职务、职级(层级/类别/起止职等)、职等、序列(类别/名称/关联职级类别定义Excel 文件。
- **处理**:五套体系独立 CRUD、停用/启用、Excel 批量导入导出;体系间关联校验(职位→职务/序列,职级→职等)。
- **输出**:五套体系台账、导入导出文件、供花名册/薪酬引用的 options 数据。
- **验收标准**:①五套体系可独立维护且相互关联引用正确;②停用后不可被新业务引用,存量引用不受影响;③批量导入导出往返数据一致;④花名册任职信息引用职位/职级选项来自本体系。
#### FEAT-B1-04 花名册管理(含兼岗)[P0]
- **输入**:字段定义(文本/数字/选项/日期/附件等)、分组、员工数据、导入模板、员工自助修改申请。
- **处理**:①字段自定义与分组管理(工作信息/个人信息/绩效/培训等);②在线查看(附件预览、字段拖拽排序);③工号多规则自动生成(如子公司独立前缀);④员工自助修改(可配置可改范围与审核环节);⑤时间轴查看/编辑全周期信息;⑥员工分类规则(正式工/临时工等不同必填规则);⑦个性化搜索筛选;⑧批量导入(新增+修改)与自定义导出(指定数据日期/字段/顺序);⑨兼岗:一人多条兼岗记录(起止日期、兼岗职位),兼岗审批通过自动同步。
- **输出**:员工主数据(唯一事实源)、花名册视图、导入导出结果、时间轴、兼岗记录。
- **验收标准**:①字段增删改即时生效于列表/详情/导入导出模板;②工号按规则唯一生成,冲突报错;③自助修改走审核后生效并留痕;④导入 ≥500 行员工数据正确(含更新匹配),导出字段与顺序与配置一致;⑤兼岗审批通过后兼岗信息即时可用于查看与后续薪酬核算;⑥敏感字段按 §2.2 脱敏。
#### FEAT-B1-05 入职管理 [P0]
- **输入**:候选人信息(审批入职单/手动录入/登记表)、入职条件(人员类型/合同公司/办公地点)、黑名单库。
- **处理**:①审批入职:自定义入职审批单,按员工类型/部门匹配审批流,通过自动关联花名册;②手动入职:批量快速添加;③批量邀请待入职员工填写自定义入职登记表,上传完善信息;④**身份证信息一期手工录入**(字段:姓名/号码/有效期等,读卡硬件二期);⑤复职:离职员工再入职自动查找关联原任职记录;⑥黑名单校验:入职自动匹配拦截,待入职界面高亮标注;⑦入职通知/欢迎模板(数据自动填充,站内消息渠道)。⑧扫码入职:一期**降级**为系统内生成入职登记链接/二维码(内网可访问),候选人扫码填表进审批流(对外渠道二维码二期)。
- **输出**:待入职名单、审批流、转正后的花名册员工、入职通知。
- **验收标准**:①三种入职方式(审批/手动/登记表邀请)均走通并落花名册;②黑名单命中 100% 拦截且高亮提示;③复职自动关联历史任职记录;④登记表字段可配置、必填校验生效;⑤身份证手工录入保存并在档案展示(脱敏)。
#### FEAT-B1-06 转正与调动管理 [P1]
- **输入**:转正申请(员工自助/主管/管理员代发)、调动申请(类型:晋升/降级/调岗/组织架构调整)、批量人员名单、预计转正日期。
- **处理**:转正审批/手动转正,通过自动更新花名册状态与转正日期;按预计转正日期提前提醒管理员与直属主管(默认提前 7 天可配);调动查询(待确定/已确定/已取消 + 类型/生效日期筛选)、调动审批通过后关联员工档案、批量调动一单多人。
- **输出**:转正/调动记录、更新后的花名册、提醒消息、调动查询结果。
- **验收标准**:①转正/调动审批通过自动联动花名册与时间轴;②转正提醒按配置日期准确触达;③批量调动一次审批处理 ≥20 人且逐人生效正确;④调动记录可按状态/类型/日期完整检索。
#### FEAT-B1-07 离职管理 [P1]
- **输入**:离职申请(员工自助/主管/管理员代发)、离职原因、交接清单、黑名单操作。
- **处理**:①审批离职:通过后进入待离职名单,离职日期到达后员工状态转离职;②手动离职:管理员直接添加离职记录;③离职交接:审批、管理职责、团队信息交接,支持离职流程与交接的自动化规则(**钉钉资源交接二期**,交接项字段已含占位);④离职员工信息存储:可查可改,离职后仍可参与薪酬计算与报表;⑤离职证明自动开具,员工自助下载;⑥黑名单:离职人员一键加入黑名单,入职校验联动拦截。
- **输出**:待离职/已离职名单、交接记录、离职证明PDF、黑名单库。
- **验收标准**:①离职全流程闭环(申请→审批→交接→离职生效);②离职证明按模板自动生成并可下载;③一键加入黑名单后再入职被拦截;④离职员工数据保留且报表/薪酬可引用;⑤交接项完成率可视化。
#### FEAT-B1-08 合同管理(电子签除外)[P1]
- **输入**:合同台账记录(员工、合同公司、类型、起止日期)、合同类型定义、合同模板、审批单、提醒规则。
- **处理**:①台账在线管理,新增与批量导入;②合同类型自定义(劳动合同/保密协议/竞业协议等);③模板管理(为二期电子签自动生成合同文件预留,一期支持按模板生成合同文本供打印/下载);④合同审批:新签/续签/变更/终止;⑤到期提醒:自定义规则(提前天数、提醒对象:本人或管理人员)。
- **输出**:合同台账、审批记录、合同文本文件、到期提醒消息。
- **验收标准**:①台账 CRUD 与批量导入正常;②四类合同审批闭环;③到期提醒按规则准确触发(误差 ≤1 天④合同关联员工与合同公司主数据⑤esign_stub 桩接口与 esign_status 字段预留可查。
#### FEAT-B1-09 员工服务与工作台 [P1]
- **输入**:员工/经理/管理员登录会话、关怀文案配置、政策/公告文档、提醒规则配置。
- **处理**:①员工工作台:个人档案、工资条、个人绩效(桩位,绩效系统二期)、发起人事审批、待处理/已处理/我发起/我收到的审批管理;②经理工作台:权限范围内入转调离数据及审批、团队人事统计、关怀提醒(考勤/团队绩效桩位);③管理员工作台:权限范围内入转调离、合同、人事统计、关怀提醒;④生日/周年关怀:个性化文案到期自动推送;⑤企业政策发布(适用范围/查阅范围/下载权限);⑥企业公告在线查询预览;⑦多场景到期提醒:入职/转正/离职/退休/合同到期/健康证到期/社保缴纳等,自定义内容与时间,推送管理员或员工。
- **输出**:三类工作台页面、关怀与提醒消息、政策/公告库。
- **验收标准**:①三类工作台按角色与数据范围展示,越权不可见;②生日/入职周年当天按配置文案自动推送;③政策可设查阅范围与下载权限,范围外不可见/不可下载④≥6 类提醒场景可配置并按期触发。
#### FEAT-B1-10 编制管理 [P1]
- **输入**:编制方案(周期:年度/季度/月度)、占编范围条件(员工类型/状态/职位/职级/自定义字段)、细分编制数量、人员异动事件。
- **处理**:多套编制方案;占编范围多条件筛选;编制细分并设定数量;实时计算超编/缺编及细分情况;人员异动(入职/离职/调动)联动编制自动校验并管控提醒(超编预警,一期为提醒不硬拦截);历史编制按时间查询。
- **输出**:编制方案台账、编制状态看板(超编/缺编)、管控提醒、历史编制快照。
- **验收标准**:①编制数据实时准确(异动生效后 1 分钟内刷新可见);②异动触发管控校验提醒;③历史任意时间点编制可回溯;④多套方案并行互不干扰。
#### FEAT-B1-11 项目式组织架构管理 [P1]
- **输入**:项目式组织定义(属性/编码/负责人/时间范围)、横向职务体系定义。
- **处理**:多维度多层级项目式组织创建,纵向部门与横向项目组/业务线自由组合;横向组织信息维护;横向组织职务体系维护并可被人事管理、薪资核算引用。
- **输出**:项目式组织台账、横向职务数据。
- **验收标准**:①项目组织可建可维护,员工可同时挂纵向部门与横向项目;②横向职务信息能被花名册/薪酬模块引用;③项目时间范围到期状态自动标识。
#### FEAT-B1-12 人事报表 [P2]
- **输入**:花名册、入转调离异动数据、维度配置。
- **处理**:①花名册信息分析:按员工类型/状态/年龄/学历/办公地点/性别等多维度分布,维度可自定义;②入职分析:按部门/地区/岗位多维度的数量与趋势;③转正分析:数量趋势 + 近期待转正数据;④调岗分析:近期调动数据;⑤离职分析:待离职人数、离职原因、离职率、同环比。数据全部受数据范围控制,可导出。
- **输出**:报表看板(图表)、明细列表、导出文件。
- **验收标准**:①五类分析齐备且维度可配置;②报表数据与花名册/异动数据实时一致(延迟 ≤5 分钟);③导出与页面数据一致;④数据范围外数据不出现在任何报表。
### 3.2 批次2薪酬管理10 项)
#### FEAT-B2-01 薪资档案与岗酬体系 [P0]
- **输入**:薪资档案字段定义(基本工资/岗位工资/固定补贴等,文本/数字/选项)、薪资标准(按职位/职级/序列匹配,固定值或带宽)、薪资包结构(按员工类型/岗位/签约主体)。
- **处理**:薪资档案字段自定义;薪资标准匹配与管控(固定值/带宽强弱管控);薪资包搭建并关联薪资标准;每字段可设管控规则(带宽管控、试用期折算比例、公式维护)。
- **输出**:员工薪资档案、岗酬标准库、薪资包模板。
- **验收标准**:①档案字段可配置并参与后续算薪;②定薪时按职位/职级自动匹配标准;③超出带宽的定薪按强/弱管控分别拦截或告警;④试用期折算比例自动生效。
#### FEAT-B2-02 薪资方案与算薪规则引擎 [P0]
- **输入**:薪资方案(薪资组分类、可复制创建)、算薪周期、核算项目与公式(计算因子:员工信息/手工数据)、手动录入数据。
- **处理**:①多薪资组统一设置,支持复制创建;②自定义算薪周期;③算薪规则:核算方式=系统自动集成/自定义公式/手动录入;公式引擎提供常用 Excel 函数与薪资专用函数(支持司龄补助、高温补贴、节假日补贴等场景),员工信息(部门/职位/司龄/学历/职称/职级)可作计算因子;薪资项备注;④薪酬累加器:累加同月同类薪资数据(合并计税);⑤离职结薪:按人员范围/离职日期选取结算;⑥薪资分段计算:人事信息/薪资数据变动自动分段(月中转正/异动各段匹配对应规则。AI 公式解析为增强项,一期提供基础公式编辑器。)
- **输出**:薪资方案、算薪规则、分段后的算薪结果。
- **验收标准**:①规则可配置且公式计算正确(抽样 20 组用例与 Excel 基准一致);②月中转正/异动分段计算结果准确;③同月多笔同类数据累加正确;④离职结薪可按条件选人结算。
#### FEAT-B2-03 定调薪管理 [P0]
- **输入**:定/调薪申请(生效时间/薪资包/明细)、审批流配置、批量人员名单。
- **处理**:①手工定/调薪直接改档案;②审批定/调薪(自定义样式/流程/发起人)通过后自动更新薪资档案;③批量定/调薪一单多人;④自动匹配薪资体系并联动薪资包管控规则,异常薪资报错提醒;⑤人事流程合并:转正调薪/调岗调薪等异动与调薪合并审批;⑥调薪历史完整记录。
- **输出**:薪资档案更新、审批记录、调薪历史。
- **验收标准**:①三种定调薪方式闭环;②管控校验与报错生效;③调薪历史可追溯(含操作人/时间/前后值);④转正调薪合并审批一次完成双回写。
#### FEAT-B2-04 发薪活动与薪资核算 [P0]
- **输入**:核算组选人条件(组织架构/员工类型/合同公司主体)、发薪活动定义、手动导入数据表格、算薪周期。
- **处理**:①核算组管理;②一月多次发薪,一人可在多个活动算薪,多结果合并计税;③人员核对:按入离职时间与周期自动生成算薪名单,比对上月入职/离职/差异名单,当月调薪人员校验提醒;④兼岗核对:展示兼岗周期与算薪周期匹配名单;⑤数据接入:一期手动导入(自动解析表格、识别内容、一键导入),考勤/绩效/审批/宜搭同步**二期钉钉对接,一期预留数据接入接口与导入模板**;⑥算税算薪:结合规则与本地个税计算得出个税明细与薪资结果(税局申报二期);⑦薪资结果一键导出 Excel。
- **输出**:算薪名单、算薪结果(含个税明细)、导出文件。
- **验收标准**:①算薪名单自动生成准确(与花名册入离职一致);②导入数据自动解析入库并与人员匹配;③算薪结果与公式引擎基准一致;④一月多次发薪合并计税正确;⑤导出 Excel 与页面一致。
#### FEAT-B2-05 薪资校验、锁定与发薪审批 [P1]
- **输入**:校验规则(与上月/固定值按差额或比例对比)、锁定操作、发薪审批配置。
- **处理**:①每项薪资数据可配校验规则;②智能校验:差异分析、异常识别、汇总异常人员名单;③薪资锁定:锁定后不可修改,解锁可更正(留痕);④发薪审批:自定义审批内容自动生成一键发送,审批内嵌薪资明细表在线预览。
- **输出**:异常名单、锁定状态、发薪审批单。
- **验收标准**:①校验规则命中异常并出名单(差额/比例两种模式);②锁定后写操作被拒绝,解锁留痕;③发薪审批含明细可在线预览并通过。
#### FEAT-B2-06 个税管理(本地计算,税局对接除外)[P1]
- **输入**:报税主体定义、员工个税档案(专项附加扣除手工维护)、工资数据、税后工资(倒算场景)。
- **处理**:①多报税主体在线管理及验证;②单一主体多地经营报税;③一人多主体报税管理;④员工增减员申报的**本地记录管理**(在线报送税务系统二期);⑤本地个税计算:累计预扣法自动计算,专项附加扣除手工维护(税局自动获取二期);⑥个税倒算:税后工资反算个税与当期收入额;⑦申报/缴纳记录管理(在线申报缴纳二期)。
- **输出**:个税明细、申报/缴纳记录台账、倒算结果。
- **验收标准**:①多主体场景数据隔离正确;②累计预扣法结果与税法计算一致(抽样 30 组用例含跨月累计);③倒算误差 ≤0.01 元;④专项附加扣除参与计算正确。
#### FEAT-B2-07 社保公积金管理 [P1]
- **输入**:企业社保账单文件、参保方案(地区/险种/基数范围/缴纳比例/取整规则)、员工社保档案。
- **处理**:①导入企业社保账单用于薪资计算;②参保方案按地区分别设置;③参保管理:在线维护员工社保档案(参保基数/险种/起止月份),可被算薪引用。
- **输出**:账单解析数据、参保方案、员工社保档案。
- **验收标准**:①账单导入解析正确(字段映射可配置);②参保方案计算准确(基数上下限与取整规则生效);③社保数据作为计算因子参与薪资核算正确。
#### FEAT-B2-08 工资条管理 [P1]
- **输入**:工资条内容配置(项目/备注/隐藏空项)、发放名单与时间、员工操作(查看/确认/签名/反馈)。
- **处理**:①工资条设置:自定义内容、单项备注、隐藏空数据项;阅后即焚、手写签名确认、员工反馈、自动确认;推送样式/背景图/关怀文案;②发放:匹配员工一对一发送(站内消息),分类定时发送,实时追踪查看/确认/签名状态;③查询:员工端查询,二次加密与水印;④留档:确认签字情况线上留档,导出 PDF。
- **输出**:工资条消息、确认/签名记录、留档 PDF。
- **验收标准**:①工资条一对一准确发放,状态追踪实时;②二次加密与水印显示生效;③签名确认后留档并可导出 PDF④定时发送按配置时间执行。
#### FEAT-B2-09 薪酬报表 [P2]
- **输入**:薪资结果数据、维度配置。
- **处理**:①人员薪资明细表:任意周期(月/季/半年/年/自定义),按部门/职能/员工类型筛选;②成本拆分:按项目/门店/生产小组等自定义维度;③同岗位薪酬分析:对比同岗位/同职级薪酬带宽;④薪酬总量分析:按部门/职能/地区/合同主体多维度总量;⑤人均薪酬分析(层级/类型对比)。(人效分析依赖产出数据,一期仅预留指标位。)
- **输出**:薪酬报表看板、明细与导出。
- **验收标准**:①五类分析齐备;②数据与薪资核算结果一致;③全程受数据范围与薪资敏感权限控制(仅 admin/hr
#### FEAT-B2-10 成本与预算管理 [P2]
- **输入**:成本中心定义、成本方案(维度/成本项目/汇总逻辑)、拆分规则、预算方案与填报数据。
- **处理**:①成本中心架构搭建(属性自定义);②成本方案按部门/成本中心等多维度统计,成本项目关联薪资数据;③拆分规则(按人事信息/项目投入等多逻辑,一人多规则、成本项目单独拆解);④成本明细报表多维度联动薪酬总成本自动拆分统计;⑤预算方案多视角多周期;⑥预算在线填报与执行自动追踪;⑦预算分析(执行明细/成本占比)。
- **输出**:成本拆分结果、成本报表、预算执行追踪与分析。
- **验收标准**:①成本拆分结果可与薪资总额核对一致;②预算执行数据实时追踪;③多维度报表数据一致。
> 批次2合计 10 项(含薪酬报表、成本与预算两个 P2
### 3.3 批次3招聘管理7 项)
#### FEAT-B3-01 招聘职位与招聘需求管理 [P1]
- **输入**:职位信息(名称/部门/类型/级别/HC/招聘流程/负责人设置)、招聘需求(人数/要求)、审批流。
- **处理**①职位审批创建职位审批流程HR/管理员发起,审批操作与结果页面展示;②职位发布:新建职位,设置招聘状态/招聘流程/关联 HC负责人设置招聘负责人唯一拥有职位全部权限协助人多可多位③职位下四类角色账号招聘负责人/招聘协助人/用人经理/面试官;④职位类型、级别设置;⑤招聘需求:单个/多个创建HR/用人经理),需求审批(选审批流/发起/查看),需求状态调整(草稿/未进行中/已完成)。
- **输出**:职位台账、需求台账、审批记录、职位角色授权。
- **验收标准**①职位与需求审批闭环②HC 关联正确(需求→职位→候选人占用);③职位级角色权限生效(负责人唯一且全权限);④状态流转(草稿→进行中→完成)可操作可查询。
#### FEAT-B3-02 人才库与简历管理 [P1]
- **输入**:简历数据(手工录入/文件导入/登记表)、标签、字段定义、筛选规则、人才库分类。
- **处理**:①企业人才库:分类管理在职/离职/淘汰人才,站内消息/邮件(配置后)激活库内人选;②简历设置:简历关联职位、敏感信息对用人经理可见性控制、来源管理;③标签管理(手动/职位/简历标签;智能标签一期为基础规则标签);④简历导出:按字段配置导出并**带水印**;⑤筛选规则:评分/筛选/运算规则与条件动作;⑥字段管理:自定义简历字段(基本信息/求职意向/工作/教育/项目/语言/附件/培训/自我描述);⑦标准简历编辑与导出;⑧申请/应聘表设置:官网/内推投递信息收集登记表;⑨面试登记表:扫码填写(内网二维码),签到牌/登记表/候选人端。
- **输出**:人才库、简历库、标签体系、筛选命中结果、登记表数据。
- **验收标准**:①人才库分类与激活可用;②简历手工录入与文件导入入库正确;③筛选规则命中正确;④导出带水印(含查看者标识);⑤登记表扫码填写入库并关联候选人。
#### FEAT-B3-03 招聘流程管理(初筛/面试/offer/自动化)[P0]
- **输入**招聘阶段与流程配置、候选人、面试安排与评价、offer 信息、自动化规则、锁定配置。
- **处理**①全流程节点管理初筛→面试→offer→入职/转正,阶段与流程可配置;②面试管理:面试评价、轮次、反馈、面试官评价、添加评价(**视频面试二期,一期降级为线下面试记录**:面试时间/地点/参与人/结论字段③offer 管理:字段管理、审批管理、规则设置、审批 offer、候选人满意度评价④自动化设置按筛选/面试结果自动进入下一阶段或人才库、自动淘汰进淘汰库、自动转正含预设日期、重新分配职位后原流程自动淘汰、全员协助招聘开关、简历入库自动推给用人经理、offer 确认后自动进入待入职、用人经理上传简历自动推给上传者、offer 有效期;⑤锁定:候选人/流程锁定,锁定天数/人数/动作、自动解除;⑥其他:激活候选人、通知、保温期提醒、推荐给用人部门;⑦评价模板(面试官/候选人);⑧归档原因管理(淘汰/离职/拒绝面试/拒绝 offer⑨招聘目标设置月/周目标与显示规则)。
- **输出**候选人流程看板、面试评价记录、offer 审批单、自动化流转日志、目标完成率。
- **验收标准**:①流程可配置可流转(阶段自定义 + 状态机正确);②自动化规则按配置触发并留痕;③锁定与自动解除按天数生效;④评价模板/归档原因可配置;⑤目标统计与实际流程数据一致。
#### FEAT-B3-04 招聘邮件与消息提醒 [P1]
- **输入**邮箱收发配置SMTP可选、邮件模板、提醒规则时机/渠道/接收角色)。
- **处理**①邮件设置配置收发邮箱②邮件模板候选人面试、offer、激活、通知候选人/面试官、叫号面试模板变量替换③消息及提醒覆盖简历、初筛、面试、offer、职位、审批、@我的等场景,可配提醒时机、发送渠道(站内必选/邮件可选/短信二期)、接收角色。
- **输出**:邮件、站内消息、提醒记录。
- **验收标准**:①邮件可配置发送,模板变量替换正确;②提醒按角色触达;③未配置邮件时站内渠道兜底不丢消息。
#### FEAT-B3-05 招聘渠道与猎企管理(本地管理)[P2]
- **输入**:猎企信息、渠道定义(系统渠道/自定义渠道)、简历来源标记。
- **处理**:①猎企管理:渠道分类管理,自动查重避免重复推荐,猎头质量数据追踪;②渠道配置:系统渠道、自定义渠道管理(第三方渠道真实对接二期,预留渠道接入接口);③简历来源标记与渠道效果统计基础数据。
- **输出**:猎企台账、渠道台账、带来源的简历、渠道统计。
- **验收标准**:①猎企 CRUD 与查重生效(同名/同联系方式拦截提示);②简历带渠道来源可统计;③渠道台账可增删改查。
#### FEAT-B3-06 招聘报表与面试登记 [P2]
- **输入**:招聘流程数据、报表/图表配置、面试到访候选人。
- **处理**①招聘报表招聘概览、候选人质量、职位360、HR效率、面试分析、offer 分析、渠道分析看板;添加报表/图表、全流程数据导出、授权管理;②面试登记:无纸化面试登记(扫码登记),部门协作共享签到信息。
- **输出**:招聘看板、导出报表、面试签到记录。
- **验收标准**:①看板数据与招聘流程数据实时一致;②图表可自定义、导出与授权生效;③面试登记扫码可用并共享签到信息。
#### FEAT-B3-07 招聘官网与内推官网 [P2]
- **输入**:官网配置(基本信息/样式/在招职位/投递限制)、内推规则(认证/保护期/邀请码)、内推奖励规则、员工内推操作。
- **处理**:①招聘官网搭建:基本信息、样式设置、分享(链接/二维码)、在招职位展示、投递限制;②内推官网:网站搭建与分享、职位设置、投递设置、内推规则(认证设置、内容保护期、淘汰原因展示、认证时效、员工注册信息、内推邀请码);③内推奖励:基础奖励规则(积分/现金)、特殊奖励规则(叠加于基础,职位先关联基础再关联特殊)、奖励必填项;④内推人及奖励统计:总发放/已兑换/未兑换积分、总发放/已提取/未提取现金。(一期为**内网部署形态**,公网域名/证书二期补齐后对外。)
- **输出**:官网页面、投递数据入库、内推链路记录、奖励统计。
- **验收标准**:①官网可配置发布并接收投递(投递自动入人才库并关联职位);②内推链路(邀请码→投递→奖励)闭环;③奖励统计四类数值准确;④投递限制规则生效。
> 批次3合计 7 项。
---
## 4. 业务流程
### 4.1 员工入职主流程
```
候选人(审批入职单/登记表邀请/手动) → 黑名单校验(命中拦截高亮)
→ 入职审批(hr-flow, 按员工类型/部门匹配) → 通过
→ [直接入花名册 | 进待入职名单→完善信息→入职]
→ 生成工号(规则引擎) → 花名册建档 → 入职通知/欢迎(站内)
→ 试用期 → 转正(审批/手动) → 花名册状态更新(可联动调薪, 批次2)
```
### 4.2 异动流程(调动/离职)
```
调动:发起(单/批量) → 调动审批 → 通过 → 花名册任职信息更新 + 时间轴留痕 → (编制校验提醒)
离职:发起(员工自助/代发) → 离职审批 → 待离职名单 → 离职交接(审批/管理职责)
→ 离职生效 → 离职证明自动开具(可下载) → [可选]一键加入黑名单
复职:再入职 → 自动关联原任职记录
```
### 4.3 薪酬月度核算流程批次2
```
发薪活动创建(核算组选人) → 算薪名单自动生成(比对上月入离职/调薪差异提醒)
→ 数据接入(手动导入/兼岗核对) → 算税算薪(公式引擎+本地累计预扣法, 分段计算)
→ 薪资校验(规则命中异常名单) → 修正 → 薪资锁定
→ 发薪审批(内嵌明细在线预览) → 工资条发放(一对一, 状态追踪)
→ 员工确认/签名留档 → 薪资结果导出/薪酬报表
```
### 4.4 招聘主流程批次3
```
招聘需求创建(HR/用人经理) → 需求审批 → 职位发布(职位审批, 关联HC, 负责人设置)
→ 渠道(本地猎企/内推/官网投递) → 简历入库(人才库, 筛选规则命中)
→ 初筛 → 面试(多轮, 评价; 线下面试记录) → offer(字段/审批/规则; 确认后进待入职)
→ 自动化规则(进下一阶段/人才库/淘汰/锁定) → 候选人入职(联动批次1入职流程)
→ 招聘报表/目标统计
```
### 4.5 审批通用流程hr-flow 引擎)
```
发起(表单引用花名册字段) → 流程匹配(多条件) → 节点审批(串行, any/all 通过规则, 字段权限, 抄送)
→ 通过/驳回/撤销 → 通过回调 hook 回写业务(花名册/薪资档案/合同/招聘状态) → 全程留痕(操作日志)
```
---
## 5. 数据需求
### 5.1 核心实体模型批次1已在设计中落 43 张表批次2/3 为规划)
| 域 | 核心实体 | 表前缀 | 说明 |
|---|---|---|---|
| 组织 | org_unit(组织+变更/字段)、org_job/position/sequence/grade_level/grade_rank、org_contract_company、org_blacklist | org_ | 已设计 18 表database-design.md §4.1 |
| 花名册 | roster_employee(主表)、roster_field_def/value(EAV 自定义字段)、roster_field_group、roster_empno_rule、roster_timeline、roster_type_rule、org_concurrent_post(兼岗) | roster_ | 已设计 7 表;员工主数据唯一事实源 |
| 流程 | flow_form_def、flow_def、flow_node_def、flow_role、flow_instance、flow_task、flow_op_log | flow_ | 已设计 7 表 |
| 合同 | contract_type、contract_template、contract_info、contract_remind_rule | contract_ | 已设计 4 表 |
| 系统 | sys_role/sys_user_role、sys_data_scope、sys_audit_log、sys_message、sys_remind_rule、sys_announcement、sys_policy、sys_care_config | sys_ | 已设计 7 表 |
| 薪酬批次2规划 | 薪资档案/薪资包/薪资标准/定调薪记录/薪资方案/算薪规则/发薪活动/算薪结果(分段)/个税主体与计算记录/社保方案与档案/工资条/成本中心与拆分/预算 | sal_ | 约 25~30 表,设计阶段细化 |
| 招聘批次3规划 | 职位/招聘需求/人才库/简历(+自定义字段EAV)/标签/流程阶段与候选人流转/面试评价/offer/渠道与猎企/邮件模板/内推与奖励/面试登记 | rcrt_ | 约 30~35 表,设计阶段细化 |
### 5.2 数据规则
1. 员工主数据唯一事实源 = 花名册入转调离审批通过后经唯一回写入口roster_writeback写入。
2. 全表统一主键/创建修改时间/操作人字段;删除以状态标记为主,物理删除仅 admin 且留审计。
3. 敏感字段(身份证/手机/薪资)字段级标记 + 角色脱敏。
4. 数据初始化:系统初始化内置 admin 账号、四类角色、基础审批流模板、组织/职位职级空体系、花名册基础字段集;支持从旧 staff-mgr 员工数据一次性迁移(见 database-design.md §6
## 6. 接口需求(一期边界)
1. **内部接口**:全部为 `.dspy` 端点(`/{module}/api/{name}.dspy`session 鉴权 + rbac 路径级控制查询强制叠加数据范围。批次1端点清单见 `docs/01-design/api-design.md`(约 30+16+其余端点)。
2. **模块间服务内调用**hr-flow 完成回调 → hr-roster 回写hr-org/hr-contract → hr-system 权限与日志。
3. **对外接口(一期全部预留桩位,二期实现)**:钉钉通讯录/智能人事同步、考勤/绩效/审批/宜搭数据同步、税局个税申报、电子签平台、招聘平台简历同步、身份证读卡硬件、视频面试服务、短信网关。预留方式:桩端点(如 `esign_stub.dspy`+ 状态字段 + 接口规范文档。
4. **API 开放能力**:一期仅定义鉴权与端点规范,不交付第三方集成。
## 7. 非功能需求(可量化)
| # | 类别 | 需求 |
|---|---|---|
| NFR-1 | 性能 | 列表页查询 ≤500ms100 人规模、1000 条以内数据集);报表聚合 ≤3s批量导入 500 行 ≤30s |
| NFR-2 | 容量 | 账号规模 100 人;并发在线 ≥30简历库 ≥2 万份、花名册 ≥2000 条(含离职) |
| NFR-3 | 可用性 | 单实例部署,月度可用率 ≥99%工作时间服务异常自动重启systemd |
| NFR-4 | 安全 | session 鉴权+rbac未注册路径默认拒绝全量写操作审计留痕敏感字段脱敏SQL 全部参数绑定;密码加盐哈希存储 |
| NFR-5 | 备份 | MariaDB 每日全量备份,保留 ≥30 天;附件随应用数据一并备份 |
| NFR-6 | 兼容性 | Chrome/Edge 最近 2 个大版本员工自助页面移动端浏览器兼容ResponsableBox 自适应) |
| NFR-7 | 可维护 | ocai 规范模块结构;配置化(表单/流程/字段 JSON 化,不写代码可配);每模块 load_xxx() 装配 |
| NFR-8 | 数据迁移 | 旧 staff-mgr 员工数据一次性迁移脚本,迁移核对报告(总数/抽样一致) |
## 8. 部署环境需求(已由任务明确)
| 项 | 测试环境 | 生产环境 |
|---|---|---|
| 主机 | hrstest@192.168.16.12:22免密已验证 | hrs@192.168.16.10:22 |
| 应用端口 | 9182Web + ahserver 统一入口) | 9182 |
| 数据库 | MariaDB 本地,账号 test/test123库名 hrs | 同库配置(生产账号口令部署时另行安全配置) |
| 会话依赖 | Redis本地 | Redis本地仅内网 |
| 域名/证书 | 无IP 直连) | **待补**(见 §11 问题清单 Q1 |
| 备份 | 无要求 | 每日全量备份,保留 ≥30 天 |
| 监控告警 | — | 进程存活 + 端口探活 + 备份结果告警(基础项;详细方案待设计阶段明确) |
> 注此前设计文档architecture.md中 dev/test 8080 / ahserver 9080 / prod 443 的端口口径,以本任务明确口径为准:**测试/生产应用端口统一 9182**。apps/hr-web.md 已同步更新。
## 9. 一期降级项说明(逐项)
| # | 原始功能(需求来源) | 一期降级方案 | 二期恢复方式 |
|---|---|---|---|
| D1 | 身份证硬件读卡(入职) | 手工录入身份证信息字段 | 读卡硬件接入后回填同一字段 |
| D2 | 视频面试(招聘) | 线下面试记录(时间/地点/参与人/结论字段) | 视频面试服务对接后扩展面试记录类型 |
| D3 | 钉钉同步(组织/人员/智能人事/离职资源交接) | 不同步;离职交接项保留占位字段 | 钉钉开放平台对接迭代 |
| D4 | 电子签(合同) | 模板生成合同文本供打印/下载esign_stub.dspy + esign_status 字段预留 | 电子签平台对接 |
| D5 | 考勤/绩效/审批/宜搭数据一键同步(算薪) | 手动导入数据表格;数据接入接口与导入模板预留 | 钉钉对接迭代 |
| D6 | 税局在线申报/缴纳/专项附加自动获取 | 本地累计预扣法计算 + 申报缴纳记录手工管理 | 税局接口对接 |
| D7 | 第三方招聘渠道真实对接、浏览器插件简历解析 | 本地渠道台账 + 手工/文件导入简历 | 渠道 API 对接 |
| D8 | AI 自动解析生成算薪公式 | 基础公式编辑器Excel 函数 + 薪资专用函数) | AI 解析增强 |
| D9 | 短信通知渠道 | 站内消息兜底(邮件渠道可配置) | 短信网关对接 |
| D10 | 官网公网发布 | 内网部署形态,配置项预留 | 域名/证书补齐后对外 |
## 10. 验收标准总纲
1. 29 项 feature 的验收标准§3全部通过为迭代验收基线P0 必须 100%P1/P2 按批次验收计划执行。
2. 每批次交付提供功能验收记录逐项、性能抽测记录NFR-1、权限与脱敏抽测记录。
3. 数据迁移staff-mgr核对报告通过。
4. 部署验证:测试环境全链路冒烟通过后,方可进入生产部署。
## 11. 待明确问题清单(需向用户/PM 确认)
| # | 问题 | 影响 | 状态 |
|---|---|---|---|
| Q1 | 生产环境域名与 HTTPS 证书何时提供?一期是否接受 9182 端口 HTTP 直连交付? | 部署形态、官网对外 | 待明确 |
| Q2 | 生产 MariaDB 账号口令由谁提供/如何交接(任务参数中生产为「同库配置」)? | 部署安全 | 待明确 |
| Q3 | 旧 staff-mgr 员工数据迁移范围(仅在职?含历史?)与切换时间点? | 数据迁移 | 待明确 |
| Q4 | 薪酬历史数据是否需要初始化导入(影响累计预扣法跨期计算)? | 个税计算 | 待明确 |
| Q5 | 招聘官网一期是否必须内网可用还是可推迟至批次3末期 | 批次3排期 | 待明确 |
| Q6 | 邮件 SMTP 服务(发件账号)由谁提供?未提供时是否接受仅站内消息? | 招聘邮件 | 待明确 |
| Q7 | 100 人账号中 manager/employee 之外的 admin/hr 数量规模(影响授权设计验证)? | 权限测试 | 待明确 |
| Q8 | 生产环境监控告警接收渠道(邮件/钉钉群 webhook | 运维 | 待明确 |
## 12. 文档索引
| 文档 | 路径 |
|---|---|
| 需求规格说明书(本文档) | docs/00-requirement/requirement-spec.md |
| 已批准功能清单29 项基线) | docs/00-requirement/approved-features.md |
| 需求追溯矩阵xlsx→feature→模块→批次 | docs/00-requirement/requirement-traceability.md |
| 需求来源(原始功能清单) | 工作空间 docs/需求来源_钉钉睿人事功能清单.md、xlsx_dump.txt |
| 应用定义 | apps/hr-web.md |
| 模块定义 | modules/hr-org.md、hr-roster.md、hr-flow.md、hr-contract.md、hr-report.md、hr-system.md、hr-salary.md、hr-recruit.md |
| 迭代1组织人事底座设计 | docs/01-design/*.mdF01~F15 |

View File

@ -1,14 +1,14 @@
# 迭代1总体设计 —— API/接口设计hr-webocai 口径) # 一期批次1总体设计 —— API/接口设计hr-webocai 口径)
- 版本v2.0迭代1-总体设计,取代 v1 Spring Boot/JWT RESTful 口径v1 已归档至 `docs/_archive/01-design-v1-old/api-design.md` - 版本v3.0批次1设计定稿v3.0 变更:对齐 SRS v3.1 —— 新增编制管理(F16)/项目式组织(F17)端点、入职登记链接与二维码端点扫码入职降级、合同文本生成端点D4、证件手工录入字段契约D1、开放接口桩端点、错误码扩充
- 状态:评审通过主agent评审基线冻结 - 状态:**设计定稿批次1评审修订版**
- 规范依据ocai 技能集 module-development-spec、dspy-file-implementation-spec、crud-definition-spec架构基线 `docs/01-design/architecture.md` - 规范依据ocai 技能集 module-development-spec、dspy-file-implementation-spec、crud-definition-spec架构基线 `docs/01-design/architecture.md`
## 1. 接口范式与通用约定(取代 v1 RESTful/JWT ## 1. 接口范式与通用约定
1. **端点形态**:全部接口为 `.dspy` 端点(受控 Python路径 `/{module}/api/{name}.dspy`,由 ahserver wwwroot 自动路由无需注册GET query 与 POST body 统一解析进 `params_kw`。dspy 必须显式 `return`,且不得在 `async with db.sqlorContext` 块内 returnNoneType 陷阱)。 1. **端点形态**:全部接口为 `.dspy` 端点(受控 Python路径 `/{module}/api/{name}.dspy`,由 ahserver wwwroot 自动路由无需注册GET query 与 POST body 统一解析进 `params_kw`。dspy 必须显式 `return`,且不得在 `async with db.sqlorContext` 块内 returnNoneType 陷阱)。
2. **鉴权**session cookieRedis 会话)+ rbac 路径级角色控制;每条路径经各模块 `scripts/load_path.py` 注册,角色:`admin / hr / manager / employee / logined`;未注册路径默认拒绝。不使用 JWT。 2. **鉴权**session cookieRedis 会话)+ rbac 路径级角色控制;每条路径经各模块 `scripts/load_path.py` 注册,角色:`admin / hr / manager / employee / logined`;未注册路径默认拒绝SRS §2.2-1。不使用 JWT。
3. **数据范围**:查询类接口强制叠加 `get_data_scope(user_id)`hr-system 提供),范围外数据不可见。 3. **数据范围**:查询、报表、**导出**类接口强制叠加 `get_data_scope(user_id)`hr-system 提供),范围外数据不可见、不可导出SRS §2.2-2
4. **CRUD 列表/表单接口**:由 json/*.json 经 xls2ui 自动生成列表查询、add/update/delete 包装 dspy不在本文逐一列出本文列出业务自定义端点。CRUD 自动生成部分约定 `new_data_url/update_data_url/delete_data_url` 位于 params 顶层。 4. **CRUD 列表/表单接口**:由 json/*.json 经 xls2ui 自动生成列表查询、add/update/delete 包装 dspy不在本文逐一列出本文列出业务自定义端点。CRUD 自动生成部分约定 `new_data_url/update_data_url/delete_data_url` 位于 params 顶层。
5. **统一响应结构** 5. **统一响应结构**
- 列表:`{"status":"success","data":{"rows":[...],"total":N}}`DataViewer 强制格式) - 列表:`{"status":"success","data":{"rows":[...],"total":N}}`DataViewer 强制格式)
@ -20,85 +20,102 @@
|---|---|---| |---|---|---|
| PARAM_INVALID | 参数缺失/格式错误 | 必填项为空、日期格式错 | | PARAM_INVALID | 参数缺失/格式错误 | 必填项为空、日期格式错 |
| NOT_FOUND | 对象不存在 | id 无效 | | NOT_FOUND | 对象不存在 | id 无效 |
| DUPLICATE | 唯一冲突 | 工号/编码重复 | | DUPLICATE | 唯一冲突 | 工号/组织编码/项目编码重复 |
| NO_PERMISSION | 数据范围外/角色不足 | 越权访问他人档案 | | NO_PERMISSION | 数据范围外/角色不足 | 越权访问他人档案 |
| BLACKLIST_HIT | 黑名单命中 | 入职校验拦截 | | BLACKLIST_HIT | 黑名单命中 | 入职校验拦截F04-6 |
| STATUS_CONFLICT | 状态不允许 | 已离职再调动、重复审批 | | STATUS_CONFLICT | 状态不允许 | 已离职再调动、重复审批 |
| FLOW_NOT_MATCH | 无匹配审批流 | 该员工类型/部门未配置流程 | | FLOW_NOT_MATCH | 无匹配审批流 | 该员工类型/部门未配置流程 |
| SCOPE_OVERDRAFT | 编制/范围超限 | 预留(编制管理范围外) | | HEADCOUNT_OVER | 编制超编提醒(不硬拦截) | 入转调联动编制校验F16SRS 验收"提醒不硬拦截" |
| NOT_ENABLED | 功能未启用(桩位) | esign_stub / openapi ping降级项 |
| REGISTER_EXPIRED | 登记表链接过期 | 入职登记二维码超时 |
| INTERNAL_ERROR | 服务异常 | 兜底 | | INTERNAL_ERROR | 服务异常 | 兜底 |
7. **审计**:所有写接口成功后调用 `write_audit_log(module,target_type,target_id,op,before,after)`hr-system 7. **审计**:所有写接口成功后调用 `write_audit_log(module,target_type,target_id,op,before,after)`hr-system
8. **敏感字段**响应中身份证一律脱敏前3后3、手机前3后4、sensitive=1 字段按角色矩阵过滤,服务端处理后返回。
## 2. 端点清单(按模块) ## 2. 端点清单(按模块)
> 角色列A=adminH=hrM=managerE=employeeL=任意登录。数据范围=是 表示叠加数据范围过滤。 > 角色列A=adminH=hrM=managerE=employeeL=任意登录。数据范围=是 表示叠加数据范围过滤。
> CRUD 列:该表的标准增删改查由 json/*.json 自动生成,路径为 `/{module}/{tblname}_list`(页面) + `add_/update_/delete_{tblname}.dspy` > CRUD 列:该表的标准增删改查由 json/*.json 自动生成,路径为 `/{module}/{tblname}_list`(页面) + `add_/update_/delete_{tblname}.dspy`
### 2.1 hr-org/hrorgF01/F02/F04~F08 ### 2.1 hr-org/hrorgF01/F02/F04~F08/F16/F17
| 端点 | 方法 | 功能 | 关键请求参数 | 响应 data | 角色 | CRUD | | 端点 | 方法 | 功能 | 关键请求参数 | 响应 data | 角色 | CRUD |
|---|---|---|---|---|---|---| |---|---|---|---|---|---|---|
| /hrorg/api/org_tree.dspy | GET | 组织树(支持 as_of 历史日期、status 过滤) | as_of?, status?, keyword? | 树形节点数组(id,name,parent_id,children,status,leader_name) | L | — | | /hrorg/api/org_tree.dspy | GET | 组织树(支持 as_of 历史日期、status 过滤) | as_of?, status?, keyword? | 树形节点数组(id,name,parent_id,children,status,leader_name) | L | — |
| /hrorg/api/org_unit_create.dspy | POST | 新建组织(编码唯一校验、写 org_unit_change | org_code,org_name,parent_id,org_type,leader_id,effective_date,自定义字段kv | {id} | A,H | org_unit | | /hrorg/api/org_unit_create.dspy | POST | 新建组织(编码唯一校验、写 org_unit_change、触发编制校验 | org_code,org_name,parent_id,org_type,leader_id,effective_date,自定义字段kv | {id} | A,H | org_unit |
| /hrorg/api/org_unit_update.dspy | POST | 编辑组织(留痕) | id,... | {} | A,H | org_unit | | /hrorg/api/org_unit_update.dspy | POST | 编辑组织(留痕) | id,... | {} | A,H | org_unit |
| /hrorg/api/org_unit_move.dspy | POST | 移动组织(变更上级) | id,new_parent_id,effective_date | {} | A,H | — | | /hrorg/api/org_unit_move.dspy | POST | 移动组织(变更上级,子树整体迁移,员工任职部门联动 | id,new_parent_id,effective_date | {} | A,H | — |
| /hrorg/api/org_unit_disable.dspy | POST | 停用组织(校验无在职员工引用) | id | {} | A,H | — | | /hrorg/api/org_unit_disable.dspy | POST | 停用组织(校验无在职员工引用) | id | {} | A,H | — |
| /hrorg/api/org_change_timeline.dspy | GET | 组织时间轴 | org_id | {rows:[{change_type,before_json,after_json,operator,created_at}]} | L | — | | /hrorg/api/org_change_timeline.dspy | GET | 组织时间轴 | org_id | {rows:[{change_type,before_json,after_json,operator,created_at}]} | L | — |
| /hrorg/api/org_import.dspy | POST | Excel 批量导入组织(后台任务+结果文件) | file(上传) | {task_id} | A,H | — | | /hrorg/api/org_import.dspy | POST | Excel 批量导入组织(后台任务+结果文件≥200 行成功率 100%,错误行回报 | file(上传) | {task_id} | A,H | — |
| /hrorg/api/org_import_result.dspy | GET | 导入结果(成功/失败行下载) | task_id | {rows,total,error_file} | A,H | — | | /hrorg/api/org_import_result.dspy | GET | 导入结果(成功/失败行下载) | task_id | {rows,total,error_file} | A,H | — |
| /hrorg/api/org_chart_export.dspy | GET | 架构图导出(图片/XMind | as_of?, root_id?, fmt=png/xmind | 文件下载 | A,H | — | | /hrorg/api/org_chart_export.dspy | GET | 架构图导出(按 as_of 日期 | as_of?, root_id?, fmt=png/xmind | 文件下载 | A,H | — |
| /hrorg/api/org_field_def_save.dspy | POST | 组织字段自定义 | fields[] | {} | A,H | org_field_def | | /hrorg/api/org_field_def_save.dspy | POST | 组织字段自定义 | fields[] | {} | A,H | org_field_def |
| /hrorg/api/company_save.dspy | POST | 合同公司维护(供合同/入职引用) | company_code,company_name,credit_code,... | {id} | A,H | org_contract_company |
| /hrorg/api/job_import.dspy / job_export.dspy | POST/GET | 职务批量导入导出 | file / 筛选条件 | {task_id} / 文件 | A,H | org_job | | /hrorg/api/job_import.dspy / job_export.dspy | POST/GET | 职务批量导入导出 | file / 筛选条件 | {task_id} / 文件 | A,H | org_job |
| /hrorg/api/position_import.dspy / position_export.dspy | POST/GET | 职位批量导入导出 | file / dept_id?,status? | {task_id} / 文件 | A,H | org_position | | /hrorg/api/position_import.dspy / position_export.dspy | POST/GET | 职位批量导入导出 | file / dept_id?,status? | {task_id} / 文件 | A,H | org_position |
| /hrorg/api/job_options.dspy / position_options.dspy / grade_options.dspy / rank_options.dspy / sequence_options.dspy / org_options.dspy / company_options.dspy | GET | 主数据下拉选项(状态=active供花名册/异动表单引用) | 无/keyword | {rows:[{id,name}]} | L | org_job 等 | | /hrorg/api/job_options.dspy / position_options.dspy / grade_options.dspy / rank_options.dspy / sequence_options.dspy / org_options.dspy / company_options.dspy | GET | 主数据下拉选项(状态=active供花名册/异动/薪酬引用) | 无/keyword | {rows:[{id,name}]} | L | org_job 等 |
| /hrorg/api/entry_approval.dspy | POST | 发起入职审批(单个,匹配审批流) | name,id_number,employee_type,org_id,position_id,hire_date,... | {instance_id} 或 BLACKLIST_HIT/FLOW_NOT_MATCH | A,H | org_entry | | /hrorg/api/entry_approval.dspy | POST | 发起入职审批(单个,匹配审批流;含证件字段组手工录入 D1 | name,id_type,id_number,id_valid_from,id_valid_to,id_authority,employee_type,org_id,position_id,company_id,work_location,hire_date,... | {instance_id} 或 BLACKLIST_HIT/FLOW_NOT_MATCH | A,H | org_entry |
| /hrorg/api/entry_manual.dspy | POST | 手动入职(批量,直接入花名册或待入职) | entries[]:{...}, to=pending/roster | {entered:[],pending:[],blocked:[]} | A,H | — | | /hrorg/api/entry_manual.dspy | POST | 手动入职(批量,直接入花名册或待入职) | entries[]:{...}, to=pending/roster | {entered:[],pending:[],blocked:[]} | A,H | — |
| /hrorg/api/entry_invite_register.dspy | POST | 邀请待入职填写登记表(站内消息) | entry_ids[] | {} | A,H | — | | /hrorg/api/entry_invite_register.dspy | POST | 批量邀请待入职填写登记表(生成 register_token/url/二维码图片,站内消息发送) | entry_ids[],expire_days? | {} | A,H | — |
| /hrorg/api/entry_register_submit.dspy | POST | 待入职员工提交登记表 | entry_id,字段kv | {} | E(本人) | — | | /hrorg/api/entry_register_page.dspy | GET | 登记表渲染页(按 flow_form_def biz_type=entry 表单定义动态渲染;**内网可访问,免登录 token 鉴权** | token | 表单结构 JSON | 匿名(token) | — |
| /hrorg/api/entry_register_submit.dspy | POST | 待入职员工提交登记表(校验 token 有效期) | token,字段kv | {} 或 REGISTER_EXPIRED | 匿名(token) | — |
| /hrorg/api/entry_qrcode.dspy | GET | 入职登记二维码图片获取/重新生成 | entry_id | {qrcode_file,url,expire} | A,H | — |
| /hrorg/api/entry_blacklist_check.dspy | GET | 黑名单校验 | id_number 或 name | {hit:bool,blacklist_id?} | A,H | — | | /hrorg/api/entry_blacklist_check.dspy | GET | 黑名单校验 | id_number 或 name | {hit:bool,blacklist_id?} | A,H | — |
| /hrorg/api/entry_notify.dspy | POST | 入职通知/欢迎(模板填充发送) | entry_ids[],template_id | {} | A,H | — | | /hrorg/api/entry_notify.dspy | POST | 入职通知/欢迎(模板填充发送,站内渠道) | entry_ids[],template_id | {} | A,H | — |
| /hrorg/api/entry_rehire_match.dspy | GET | 复职匹配(按证件号哈希查历史档案) | id_number | {matched:bool,prev_employee_id?,last_org?,last_position?} | A,H | — |
| /hrorg/api/regular_apply.dspy | POST | 发起转正审批(自助/代发) | employee_id,regular_date | {instance_id} | E(自助),H,M | org_regularization | | /hrorg/api/regular_apply.dspy | POST | 发起转正审批(自助/代发) | employee_id,regular_date | {instance_id} | E(自助),H,M | org_regularization |
| /hrorg/api/regular_manual.dspy | POST | 手动转正(直接更新花名册) | employee_id,regular_date | {} | A,H | — | | /hrorg/api/regular_manual.dspy | POST | 手动转正(直接更新花名册) | employee_id,regular_date | {} | A,H | — |
| /hrorg/api/transfer_apply.dspy | POST | 发起调动审批(支持批量人员) | transfer_type,effective_date,details[]:{employee_id,to_org_id,to_position_id,...} | {instance_id} | A,H,M | org_transfer | | /hrorg/api/transfer_apply.dspy | POST | 发起调动审批(支持批量人员 ≥20 人 | transfer_type,effective_date,details[]:{employee_id,to_org_id,to_position_id,to_grade_level_id} | {instance_id} | A,H,M | org_transfer |
| /hrorg/api/transfer_cancel.dspy | POST | 取消调动(保留历史不改现职) | transfer_id | {} | A,H | — | | /hrorg/api/transfer_cancel.dspy | POST | 取消调动(保留历史不改现职) | transfer_id | {} | A,H | — |
| /hrorg/api/leave_apply.dspy | POST | 发起离职审批(自助/代发) | employee_id,leave_type,leave_reason,leave_date | {instance_id} | E(自助),H,M | org_leave | | /hrorg/api/leave_apply.dspy | POST | 发起离职审批(自助/代发) | employee_id,leave_type,leave_reason,leave_date | {instance_id} | E(自助),H,M | org_leave |
| /hrorg/api/leave_manual.dspy | POST | 手动离职(直接入待离职/已离职) | employee_id,leave_date,leave_reason | {} | A,H | — | | /hrorg/api/leave_manual.dspy | POST | 手动离职(直接入待离职/已离职) | employee_id,leave_date,leave_reason | {} | A,H | — |
| /hrorg/api/leave_handover_save.dspy | POST | 离职交接项保存 | leave_id,items[] | {} | A,H,M | org_leave_handover | | /hrorg/api/leave_handover_save.dspy | POST | 离职交接项保存(含 dingtalk_resource 占位项,手工登记内容) | leave_id,items[]:{item_type,item_content,handover_to_id} | {} | A,H,M | org_leave_handover |
| /hrorg/api/leave_certificate.dspy | GET | 离职证明生成下载 | employee_id | 文件 | E(本人),A,H | — | | /hrorg/api/leave_effect.dspy | 内部 | 离职生效处理离职日期到达状态转离职remind_scan 触发) | employee_id | {} | 服务内 | — |
| /hrorg/api/leave_certificate.dspy | GET | 离职证明生成下载(按模板 PDF | employee_id | 文件 | E(本人),A,H | — |
| /hrorg/api/blacklist_add.dspy | POST | 一键加入黑名单 | leave_id 或 id_number_hash,reason | {} | A,H | org_blacklist | | /hrorg/api/blacklist_add.dspy | POST | 一键加入黑名单 | leave_id 或 id_number_hash,reason | {} | A,H | org_blacklist |
| /hrorg/api/concurrent_apply.dspy | POST | 发起兼岗审批 | employee_id,org_id,position_id,start_date,end_date | {instance_id} | A,H,M | org_concurrent_post | | /hrorg/api/concurrent_apply.dspy | POST | 发起兼岗审批 | employee_id,org_id,position_id,start_date,end_date | {instance_id} | A,H,M | org_concurrent_post |
| /hrorg/api/headcount_scheme_save.dspy | POST | 编制方案创建/编辑(多套方案并行) | scheme_name,cycle_type,cycle_start,cycle_end | {id} | A,H | org_headcount_scheme |
| /hrorg/api/headcount_item_save.dspy | POST | 编制细分项维护(占编范围条件+细分+数量) | scheme_id,items[]:{scope_json,seg_json,head_limit} | {} | A,H | headcount_item |
| /hrorg/api/headcount_status.dspy | GET | 编制状态看板(超编/缺编+细分实时数) | scheme_id?,as_of? | {rows:[{item,head_limit,used,over,gap}]} | A,H,M(范围) | — |
| /hrorg/api/headcount_history.dspy | GET | 历史编制查询(任意时间点快照) | scheme_id,as_of | {rows:[{snap_date,used_count,over_count}]} | A,H | — |
| /hrorg/api/headcount_check.dspy | 内部 | 异动联动编制校验(入转调回写后调用,超编写提醒消息,不拦截) | employee_id,event_type | {over:bool,scheme_id?} | 服务内 | — |
| /hrorg/api/project_save.dspy | POST | 项目式组织创建/维护(多层级/属性/负责人/时间范围;到期自动标识 expired | project_code,project_name,parent_id,owner_id,start_date,end_date,attrs_json | {id} | A,H | org_project |
| /hrorg/api/project_tree.dspy | GET | 项目组织树 | keyword?,status? | 树形节点数组 | L | — |
| /hrorg/api/project_post_save.dspy | POST | 项目任职维护(员工挂横向项目+横向职务) | project_id,employee_id,job_id,start_date,end_date | {id} | A,H | org_project_post |
| /hrorg/api/horizontal_job_options.dspy | GET | 横向职务选项org_job.job_category=horizontal供花名册/薪酬引用) | keyword | {rows:[{id,name}]} | L | — |
| /hrorg/api/workbench_transfer.dspy | GET | 工作台入转调离汇总(经理/管理员视图) | scope=team/all | {entry_n,regular_n,transfer_n,leave_n,rows} | M,H,A | — | | /hrorg/api/workbench_transfer.dspy | GET | 工作台入转调离汇总(经理/管理员视图) | scope=team/all | {entry_n,regular_n,transfer_n,leave_n,rows} | M,H,A | — |
### 2.2 hr-roster/hrrosterF03 ### 2.2 hr-roster/hrrosterF03
| 端点 | 方法 | 功能 | 关键请求参数 | 响应 data | 角色 | CRUD | | 端点 | 方法 | 功能 | 关键请求参数 | 响应 data | 角色 | CRUD |
|---|---|---|---|---|---|---| |---|---|---|---|---|---|---|
| /hrroster/api/roster_list.dspy | GET | 花名册列表(主表条件分页 + EAV 拼装 + 范围过滤 + 脱敏) | keyword?,org_id?,status?,type?,field_filters?,page,size | {rows,total} | A,H(范围),M(团队) | roster_employee | | /hrroster/api/roster_list.dspy | GET | 花名册列表(主表条件分页 + EAV 拼装 + 范围过滤 + 脱敏) | keyword?,org_id?,status?,type?,field_filters?(≤3 自定义字段等值),page,size | {rows,total} | A,H(范围),M(团队) | roster_employee |
| /hrroster/api/roster_employee_create.dspy | POST | 新增员工(自动生成工号、写时间轴) | 主档字段+自定义字段kv | {id,employee_no} | A,H | roster_employee | | /hrroster/api/roster_employee_create.dspy | POST | 新增员工(工号规则自动生成、写时间轴;含证件字段组手工录入 D1id_type/id_number/id_valid_from/id_valid_to/id_authorityid_source='manual' | 主档字段+证件字段组+自定义字段kv | {id,employee_no} | A,H | roster_employee |
| /hrroster/api/roster_employee_update.dspy | POST | 更新员工(含自助修改路径:可改范围+可选审核) | id,字段kv | {} 或 {need_audit:true,instance_id} | A,H,E(本人受限) | roster_employee | | /hrroster/api/roster_employee_update.dspy | POST | 更新员工(含自助修改路径:editable_self 范围校验+need_audit 走审批;二期读卡器回填证件同字段 | id,字段kv | {} 或 {need_audit:true,instance_id} | A,H,E(本人受限) | roster_employee |
| /hrroster/api/employee_detail.dspy | GET | 员工档案详情(主档+分组字段+兼岗+合同摘要,按角色脱敏/字段可见) | id | {main,groups:[{group_name,fields:[...]}],concurrent,contracts} | L(按范围) | — | | /hrroster/api/employee_detail.dspy | GET | 员工档案详情(主档+分组字段+兼岗+合同摘要+项目任职,按角色脱敏/字段可见) | id | {main,groups:[{group_name,fields:[...]}],concurrent,contracts,projects} | L(按范围) | — |
| /hrroster/api/roster_field_def_save.dspy | POST | 字段定义维护(类型/必填/敏感/自助/审核/适用类型/排序) | fields[] | {} | A,H | roster_field_def | | /hrroster/api/roster_field_def_save.dspy | POST | 字段定义维护(类型/必填/敏感/自助/审核/适用类型/排序,即时生效于列表/详情/导入导出 | fields[] | {} | A,H | roster_field_def |
| /hrroster/api/roster_field_group_save.dspy | POST | 分组维护(含拖拽排序持久化) | groups[] | {} | A,H | roster_field_group | | /hrroster/api/roster_field_group_save.dspy | POST | 分组维护(含拖拽排序持久化) | groups[] | {} | A,H | roster_field_group |
| /hrroster/api/roster_type_rule_save.dspy | POST | 员工类型字段规则 | employee_type,field_rules_json | {} | A,H | roster_type_rule | | /hrroster/api/roster_type_rule_save.dspy | POST | 员工类型字段规则(正式/临时等必填差异) | employee_type,field_rules_json | {} | A,H | roster_type_rule |
| /hrroster/api/empno_rule_save.dspy | POST | 工号规则维护 | rules[] | {} | A,H | roster_empno_rule | | /hrroster/api/empno_rule_save.dspy | POST | 工号规则维护(多规则,如子公司独立前缀) | rules[]:{rule_name,prefix,match_field,match_value,seq_length} | {} | A,H | roster_empno_rule |
| /hrroster/api/check_employee_no.dspy | GET | 工号查重 | employee_no,exclude_id? | {exists} | A,H | — | | /hrroster/api/check_employee_no.dspy | GET | 工号查重 | employee_no,exclude_id? | {exists} | A,H | — |
| /hrroster/api/roster_import.dspy | POST | 自定义导入(批量新增/批量修改,模板按当前字段定义生成) | file,mode=new/update | {task_id} | A,H | — | | /hrroster/api/roster_import.dspy | POST | 自定义导入(批量新增/批量修改,≥500 行正确;模板按当前字段定义+类型规则生成) | file,mode=new/update | {task_id} | A,H | — |
| /hrroster/api/roster_import_template.dspy | GET | 导入模板下载(按字段定义+类型规则) | employee_type? | 文件 | A,H | — | | /hrroster/api/roster_import_template.dspy | GET | 导入模板下载(按字段定义+类型规则) | employee_type? | 文件 | A,H | — |
| /hrroster/api/roster_export.dspy | GET | 自定义导出(指定数据日期/字段/顺序) | as_of?,field_ids[],filters | {task_id}→文件 | A,H | — | | /hrroster/api/roster_export.dspy | GET | 自定义导出(指定数据日期/字段/顺序,拖拽排序;强制数据范围 | as_of?,field_ids[],filters | {task_id}→文件 | A,H | — |
| /hrroster/api/timeline.dspy | GET | 员工时间轴(全周期记录) | employee_id,event_type? | {rows:[{event_type,event_date,title,content_json}]} | L(按范围) | — | | /hrroster/api/timeline.dspy | GET | 员工时间轴(全周期记录,可编辑 | employee_id,event_type? | {rows:[{event_type,event_date,title,content_json}]} | L(按范围) | — |
| /hrroster/api/timeline_add.dspy | POST | 时间轴记录编辑 | employee_id,event_type,event_date,title,content | {} | A,H | — | | /hrroster/api/timeline_add.dspy | POST | 时间轴记录编辑 | employee_id,event_type,event_date,title,content | {} | A,H | — |
| /hrroster/api/file_preview_url.dspy | GET | 附件在线预览 URLfiles/ 受控访问) | file_id | {url} | L(按范围) | — | | /hrroster/api/file_preview_url.dspy | GET | 附件在线预览 URLfiles/ 受控访问) | file_id | {url} | L(按范围) | — |
| /hrroster/api/roster_writeback.dspy | 内部 | 异动回写入口(仅 hr-org/hr-flow 服务内调用,注册于 ServerEnv不注册 HTTP 路径) | biz_type,biz_id,instance_id | {} | 服务内 | — | | /hrroster/api/roster_writeback.dspy | 内部 | 异动回写唯一入口(仅 hr-org/hr-flow 服务内调用,注册于 ServerEnv不注册 HTTP 路径;回写后触发 headcount_check 与 timeline | biz_type,biz_id,instance_id | {} | 服务内 | — |
### 2.3 hr-flow/hrflowF10 ### 2.3 hr-flow/hrflowF10
| 端点 | 方法 | 功能 | 关键请求参数 | 响应 data | 角色 | CRUD | | 端点 | 方法 | 功能 | 关键请求参数 | 响应 data | 角色 | CRUD |
|---|---|---|---|---|---|---| |---|---|---|---|---|---|---|
| /hrflow/api/form_def_save.dspy | POST | 表单定义维护(引用花名册字段) | form_code,form_name,biz_type,fields_json | {id} | A,H | flow_form_def | | /hrflow/api/form_def_save.dspy | POST | 表单定义维护(引用花名册字段;含考勤类桩位表单 attendance_* | form_code,form_name,biz_type,fields_json | {id} | A,H | flow_form_def |
| /hrflow/api/flow_def_save.dspy | POST | 流程定义(匹配条件、版本) | flow_code,form_id,biz_type,match_cond_json | {id} | A,H | flow_def | | /hrflow/api/flow_def_save.dspy | POST | 流程定义(匹配条件、版本;预置人事四类模板初始化 | flow_code,form_id,biz_type,match_cond_json | {id} | A,H | flow_def |
| /hrflow/api/flow_node_save.dspy | POST | 节点维护(审批人/通过规则/字段权限/抄送) | flow_id,nodes[] | {} | A,H | flow_node_def | | /hrflow/api/flow_node_save.dspy | POST | 节点维护(审批人/通过规则 any/all/字段权限/抄送) | flow_id,nodes[] | {} | A,H | flow_node_def |
| /hrflow/api/flow_role_save.dspy | POST | 审批角色(流程范围/操作权限/数据范围 | role_name,flow_scope_json,op_perm_json,data_scope_json | {id} | A | flow_role | | /hrflow/api/flow_role_save.dspy | POST | 审批角色(流程范围/操作权限/数据查看三维配置 | role_name,flow_scope_json,op_perm_json,data_scope_json | {id} | A | flow_role |
| /hrflow/api/flow_match.dspy | GET | 按员工类型/部门匹配流程 | biz_type,employee_type,org_id | {flow_id,flow_name} 或 FLOW_NOT_MATCH | 服务内/HR | — | | /hrflow/api/flow_match.dspy | GET | 按员工类型/部门匹配流程 | biz_type,employee_type,org_id | {flow_id,flow_name} 或 FLOW_NOT_MATCH | 服务内/HR | — |
| /hrflow/api/flow_start.dspy | POST | 发起审批(通用:业务模块统一入口) | biz_type,biz_id,form_data_json | {instance_id,inst_no} | L | — | | /hrflow/api/flow_start.dspy | POST | 发起审批(通用:业务模块统一入口) | biz_type,biz_id,form_data_json | {instance_id,inst_no} | L | — |
| /hrflow/api/task_todo.dspy | GET | 我的待办 | page,size | {rows,total} | L | — | | /hrflow/api/task_todo.dspy | GET | 我的待办 | page,size | {rows,total} | L | — |
@ -106,36 +123,38 @@
| /hrflow/api/inst_mine.dspy | GET | 我发起的 | status?,page,size | {rows,total} | L | — | | /hrflow/api/inst_mine.dspy | GET | 我发起的 | status?,page,size | {rows,total} | L | — |
| /hrflow/api/inst_received.dspy | GET | 我收到的(抄送/知会) | page,size | {rows,total} | L | — | | /hrflow/api/inst_received.dspy | GET | 我收到的(抄送/知会) | page,size | {rows,total} | L | — |
| /hrflow/api/inst_detail.dspy | GET | 审批单详情(表单数据+流转记录+字段权限) | instance_id | {form_data,nodes:[{op,operator,time,comment}],status} | L(参与者) | — | | /hrflow/api/inst_detail.dspy | GET | 审批单详情(表单数据+流转记录+字段权限) | instance_id | {form_data,nodes:[{op,operator,time,comment}],status} | L(参与者) | — |
| /hrflow/api/task_approve.dspy | POST | 同意 | task_id,comment? | {} | L(任务归属) | — | | /hrflow/api/task_approve.dspy | POST | 同意(末节点通过触发完成回调回写业务) | task_id,comment? | {} | L(任务归属) | — |
| /hrflow/api/task_reject.dspy | POST | 驳回 | task_id,comment | {} | L(任务归属) | — | | /hrflow/api/task_reject.dspy | POST | 驳回 | task_id,comment | {} | L(任务归属) | — |
| /hrflow/api/task_forward.dspy | POST | 转交 | task_id,to_user_id | {} | L(任务归属) | — | | /hrflow/api/task_forward.dspy | POST | 转交 | task_id,to_user_id | {} | L(任务归属) | — |
| /hrflow/api/inst_withdraw.dspy | POST | 撤回(发起人,仅首节点未处理) | instance_id | {} | L(发起人) | — | | /hrflow/api/inst_withdraw.dspy | POST | 撤回(发起人,仅首节点未处理) | instance_id | {} | L(发起人) | — |
| /hrflow/api/inst_query.dspy | GET | 审批数据查询(表单/状态/发起人/编号/时间) | form_name?,status?,initiator?,inst_no?,date_range | {rows,total} | A,H | — | | /hrflow/api/inst_query.dspy | GET | 审批数据查询(表单/状态/发起人/编号/时间多条件 | form_name?,status?,initiator?,inst_no?,date_range | {rows,total} | A,H | — |
| /hrflow/api/inst_export.dspy | GET | 审批数据导出 | 同上 | 文件 | A,H | — | | /hrflow/api/inst_export.dspy | GET | 审批数据导出 | 同上 | 文件 | A,H | — |
| /hrflow/api/inst_print.dspy | GET | 审批单打印视图 | instance_id | 打印 HTML | L(参与者) | — | | /hrflow/api/inst_print.dspy | GET | 审批单打印视图A4 版式) | instance_id | 打印 HTML | L(参与者) | — |
### 2.4 hr-contract/hrcontractF09 ### 2.4 hr-contract/hrcontractF09
| 端点 | 方法 | 功能 | 关键请求参数 | 响应 data | 角色 | CRUD | | 端点 | 方法 | 功能 | 关键请求参数 | 响应 data | 角色 | CRUD |
|---|---|---|---|---|---|---| |---|---|---|---|---|---|---|
| /hrcontract/api/contract_list.dspy | GET | 合同台账列表(范围过滤) | employee_id?,status?,type_id?,end_before? | {rows,total} | A,H | contract_info | | /hrcontract/api/contract_list.dspy | GET | 合同台账列表(范围过滤) | employee_id?,status?,type_id?,end_before? | {rows,total} | A,H | contract_info |
| /hrcontract/api/contract_create.dspy | POST | 新增合同(模板引用 | employee_id,type_id,company_id,start_date,end_date,file | {id} | A,H | contract_info | | /hrcontract/api/contract_create.dspy | POST | 新增合同(关联员工+合同公司+模板) | employee_id,type_id,company_id,template_id?,start_date,end_date,file | {id} | A,H | contract_info |
| /hrcontract/api/contract_import.dspy | POST | 批量导入 | file | {task_id} | A,H | — | | /hrcontract/api/contract_import.dspy | POST | 批量导入 | file | {task_id} | A,H | — |
| /hrcontract/api/contract_apply.dspy | POST | 合同审批(新签/续签/变更/终止) | contract_id?,biz_type=contract_sign/renew/change/stop,form_data_json | {instance_id} | A,H | — | | /hrcontract/api/contract_apply.dspy | POST | 合同审批(新签/续签/变更/终止四类) | contract_id?,biz_type=contract_sign/renew/change/stop,form_data_json | {instance_id} | A,H | — |
| /hrcontract/api/contract_remind_rule_save.dspy | POST | 到期提醒规则 | rule_name,days_before,target_role,content_template | {id} | A,H | contract_remind_rule | | /hrcontract/api/contract_text_gen.dspy | GET | 按模板生成合同文本占位符填充docx/pdf 供打印下载;电子签二期 D4 | contract_id,template_id?,fmt=docx/pdf | 文件 | A,H | — |
| /hrcontract/api/contract_remind_rule_save.dspy | POST | 到期提醒规则(提前天数/提醒对象本人或管理人员) | rule_name,days_before,target_role,content_template | {id} | A,H | contract_remind_rule |
| /hrcontract/api/contract_template_save.dspy | POST | 模板维护 | template_name,type_id,file,field_marks_json | {id} | A,H | contract_template | | /hrcontract/api/contract_template_save.dspy | POST | 模板维护 | template_name,type_id,file,field_marks_json | {id} | A,H | contract_template |
| /hrcontract/api/contract_expire_soon.dspy | GET | 即将到期列表(工作台/提醒) | days | {rows} | A,H | — | | /hrcontract/api/contract_expire_soon.dspy | GET | 即将到期列表(工作台/提醒;误差 ≤1 天 | days | {rows} | A,H | — |
| /hrcontract/api/esign_stub.dspy | POST | 电子签预留桩(返回未启用提示) | contract_id | {status:'error',code:'NOT_ENABLED'} | A,H | — | | /hrcontract/api/esign_stub.dspy | POST | 电子签预留桩(D4返回未启用验证路由可达 | contract_id | {status:'error',data:{code:'NOT_ENABLED'}} | A,H | — |
### 2.5 hr-report/hrreportF13全部只读 ### 2.5 hr-report/hrreportF13全部只读
| 端点 | 方法 | 功能 | 关键请求参数 | 响应 data | 角色 | | 端点 | 方法 | 功能 | 关键请求参数 | 响应 data | 角色 |
|---|---|---|---|---|---| |---|---|---|---|---|---|
| /hrreport/api/roster_analysis.dspy | GET | 花名册多维分布(维度可自定义) | dim=type/status/age/edu/location/gender/custom_field_id | {rows:[{dim_value,count}],total} | A,H,M(范围) | | /hrreport/api/roster_analysis.dspy | GET | 花名册多维分布(维度可自定义,含自定义字段 | dim=type/status/age/edu/location/gender/custom_field_id | {rows:[{dim_value,count}],total} | A,H,M(范围) |
| /hrreport/api/entry_analysis.dspy | GET | 入职数量与趋势 | dim=org/location/position,period=month/quarter | {trend:[],rows:[]} | A,H,M | | /hrreport/api/entry_analysis.dspy | GET | 入职数量与趋势(部门/地区/岗位) | dim=org/location/position,period=month/quarter | {trend:[],rows:[]} | A,H,M |
| /hrreport/api/regular_analysis.dspy | GET | 转正分析与近期待转正 | period? | {trend:[],upcoming:[]} | A,H,M | | /hrreport/api/regular_analysis.dspy | GET | 转正分析(趋势+近期待转正) | period? | {trend:[],upcoming:[]} | A,H,M |
| /hrreport/api/transfer_analysis.dspy | GET | 近期调动分析 | date_range? | {rows:[{type,count}]} | A,H,M | | /hrreport/api/transfer_analysis.dspy | GET | 近期调动分析 | date_range? | {rows:[{type,count}]} | A,H,M |
| /hrreport/api/leave_analysis.dspy | GET | 离职分析(待离职数/原因/离职率/同环比) | period? | {pending_n,reasons:[],rate:{cur,yoy,mom}} | A,H,M | | /hrreport/api/leave_analysis.dspy | GET | 离职分析(待离职数/原因/离职率/同环比) | period? | {pending_n,reasons:[],rate:{cur,yoy,mom}} | A,H,M |
| /hrreport/api/report_export.dspy | GET | 报表数据导出(与页面数据一致,强制数据范围) | report_code,同各分析参数 | 文件 | A,H,M |
| /hrreport/api/team_stats.dspy | GET | 团队人事统计(经理工作台卡片) | org_id? | {headcount,entry_n,leave_n,...} | M,H,A | | /hrreport/api/team_stats.dspy | GET | 团队人事统计(经理工作台卡片) | org_id? | {headcount,entry_n,leave_n,...} | M,H,A |
### 2.6 hr-system/hrsystemF11/F12/F14/F15 ### 2.6 hr-system/hrsystemF11/F12/F14/F15
@ -143,59 +162,86 @@
| 端点 | 方法 | 功能 | 关键请求参数 | 响应 data | 角色 | CRUD | | 端点 | 方法 | 功能 | 关键请求参数 | 响应 data | 角色 | CRUD |
|---|---|---|---|---|---|---| |---|---|---|---|---|---|---|
| /hrsystem/api/role_save.dspy | POST | 管理角色创建与权限设置rbac 角色+路径) | role_name,paths[] | {id} | A | sys_role(rbac) | | /hrsystem/api/role_save.dspy | POST | 管理角色创建与权限设置rbac 角色+路径) | role_name,paths[] | {id} | A | sys_role(rbac) |
| /hrsystem/api/data_scope_save.dspy | POST | 人员范围(组织维度/花名册字段维度) | admin_user_id,scope_type,org_ids[]/field_ids[] | {} | A | sys_data_scope | | /hrsystem/api/data_scope_save.dspy | POST | 人员范围(组织维度含子树/花名册字段维度,可叠加 | admin_user_id,scope_type,org_ids[]/field_ids[] | {} | A | sys_data_scope |
| /hrsystem/api/admin_save.dspy | POST | 管理员管理(创建/调整权限) | user_id,roles[] | {} | A | — | | /hrsystem/api/admin_save.dspy | POST | 管理员管理(创建管理员并授权角色与数据范围) | user_id,roles[],scope | {} | A | — |
| /hrsystem/api/get_data_scope.dspy | 内部 | 数据范围查询ServerEnv 注册,供各模块查询叠加) | user_id | {scope_type,org_ids,field_ids} | 服务内 | — | | /hrsystem/api/get_data_scope.dspy | 内部 | 数据范围查询ServerEnv 注册,供各模块查询叠加) | user_id | {scope_type,org_ids,field_ids} | 服务内 | — |
| /hrsystem/api/audit_log_list.dspy | GET | 操作日志查询(时间/类型/模块) | module?,operation?,date_range,target? | {rows,total} | A | sys_audit_log | | /hrsystem/api/audit_log_list.dspy | GET | 操作日志查询(时间/类型/模块) | module?,operation?,date_range,target? | {rows,total} | A | sys_audit_log |
| /hrsystem/api/audit_log_detail.dspy | GET | 日志详情(前后对比) | id | {before_json,after_json,operator,ip,time} | A | — | | /hrsystem/api/audit_log_detail.dspy | GET | 日志详情(前后对比) | id | {before_json,after_json,operator,ip,time} | A | — |
| /hrsystem/api/workbench_employee.dspy | GET | 员工工作台聚合(档案摘要/待办数/可发起流程) | — | {profile,todo_n,flows:[...]} | E | — | | /hrsystem/api/workbench_employee.dspy | GET | 员工工作台聚合(档案摘要/工资条入口桩/绩效桩/待办数/可发起流程) | — | {profile,todo_n,flows:[...],salary_stub:null,perf_stub:null} | E | — |
| /hrsystem/api/workbench_manager.dspy | GET | 经理工作台聚合(团队统计/待审批/关怀提醒) | — | {stats,todos:[],care:[...]} | M | — | | /hrsystem/api/workbench_manager.dspy | GET | 经理工作台聚合(团队统计/待审批/关怀提醒;考勤/团队绩效桩位 | — | {stats,todos:[],care:[...],attendance_stub:null} | M | — |
| /hrsystem/api/workbench_admin.dspy | GET | 管理员工作台聚合(人事统计/合同到期/提醒) | — | {stats,contracts:[],care:[...]} | A,H | — | | /hrsystem/api/workbench_admin.dspy | GET | 管理员工作台聚合(人事统计/合同到期/提醒) | — | {stats,contracts:[],care:[...]} | A,H | — |
| /hrsystem/api/remind_rule_save.dspy | POST | 通用提醒规则(多场景自定义 | scene_code,rule_name,days_before,content_template,target_role | {id} | A,H | sys_remind_rule | | /hrsystem/api/remind_rule_save.dspy | POST | 通用提醒规则(≥6 场景自定义内容与时间 | scene_code,rule_name,days_before,content_template,target_role | {id} | A,H | sys_remind_rule |
| /hrsystem/api/care_config_save.dspy | POST | 生日/周年关怀文案配置 | care_type,template,enable | {} | A,H | sys_care_config | | /hrsystem/api/care_config_save.dspy | POST | 生日/周年关怀文案配置 | care_type,template,enable | {} | A,H | sys_care_config |
| /hrsystem/api/announcement_save.dspy | POST | 公告发布 | title,content,publish_scope_json | {id} | A,H | sys_announcement | | /hrsystem/api/announcement_save.dspy | POST | 公告发布(在线查询预览) | title,content,publish_scope_json | {id} | A,H | sys_announcement |
| /hrsystem/api/policy_save.dspy | POST | 政策发布(查阅范围/下载权限) | title,file,view_scope_json,downloadable | {id} | A,H | sys_policy | | /hrsystem/api/policy_save.dspy | POST | 政策发布(适用范围/查阅范围/下载权限) | title,file,view_scope_json,downloadable | {id} | A,H | sys_policy |
| /hrsystem/api/policy_download.dspy | GET | 政策文件下载(校验 downloadable 与查阅范围) | id | 文件 或 NO_PERMISSION | L(按范围) | — |
| /hrsystem/api/message_list.dspy | GET | 我的站内消息 | is_read?,msg_type? | {rows,total} | L | — | | /hrsystem/api/message_list.dspy | GET | 我的站内消息 | is_read?,msg_type? | {rows,total} | L | — |
| /hrsystem/api/message_read.dspy | POST | 标记已读 | ids[] | {} | L | — | | /hrsystem/api/message_read.dspy | POST | 标记已读 | ids[] | {} | L | — |
| /hrsystem/api/remind_scan.dspy | 内部 | 提醒扫描cron/启动任务:转正/合同/生日等到期扫描推送) | — | {sent_n} | 服务内 | — | | /hrsystem/api/message_unread_count.dspy | GET | 未读数(全局铃铛) | — | {n} | L | — |
| /hrsystem/api/remind_scan.dspy | 内部 | 提醒扫描cron 每日+启动补扫:转正/合同/生日/周年/退休/健康证等到期推送;离职日期到达触发 leave_effect | — | {sent_n} | 服务内 | — |
| /openapi/v1/ping.dspy | GET | API 开放接口桩(一期仅验证路由/鉴权框架,返回 NOT_ENABLED规范见 architecture.md §9 | — | {status:'error',data:{code:'NOT_ENABLED'}} | 匿名(桩) | — |
### 2.7 appbase/rbac 沿用(不自研) ### 2.7 appbase/rbac 沿用(不自研)
登录/登出、用户管理、字典 appcodes 维护、rbac 角色路径绑定由 appbase/rbac 包自带页面与端点承载(`/appbase/*``/rbac/*`迭代1仅在各模块 init/data.json 中初始化字典与角色 登录/登出、用户管理、字典 appcodes 维护、rbac 角色路径绑定由 appbase/rbac 包自带页面与端点承载(`/appbase/*``/rbac/*`批次1仅在各模块 init/data.json 中初始化字典、角色与四类流程模板
## 3. 典型调用链示例 ## 3. 典型调用链示例
### 3.1 转正审批F05 流程2 ### 3.1 转正审批F05
1. `POST /hrorg/api/regular_apply.dspy` {employee_id, regular_date} → hr-org 校验员工状态probation 1. `POST /hrorg/api/regular_apply.dspy` {employee_id, regular_date} → hr-org 校验员工状态probation
2. 内部调用 `flow_match(biz_type=regular, employee_type, org_id)``POST /hrflow/api/flow_start.dspy` {biz_type:'regular', biz_id:regularization_id, form_data_json} → 生成 flow_instance + 首节点 flow_task发站内消息给审批人 2. 内部调用 `flow_match(biz_type=regular, employee_type, org_id)``POST /hrflow/api/flow_start.dspy` {biz_type:'regular', biz_id:regularization_id, form_data_json} → 生成 flow_instance + 首节点 flow_task发站内消息给审批人
3. 审批人 `POST /hrflow/api/task_approve.dspy` → 全部节点通过 → flow_instance.inst_status=approved 3. 审批人 `POST /hrflow/api/task_approve.dspy` → 全部节点通过 → flow_instance.inst_status=approved
4. hr-flow 完成回调 → hr-org `regular_confirm` → hr-roster `roster_writeback`roster_employee.employee_status=regular、regular_date 更新,写 roster_timeline 4. hr-flow 完成回调 → hr-org `regular_confirm` → hr-roster `roster_writeback`roster_employee.employee_status=regular、regular_date 更新,写 roster_timeline`headcount_check`(编制联动提醒)
5. 各步均写 sys_audit_log转正提醒由 `remind_scan`预计日期提前推送管理员与直属主管。 5. 各步均写 sys_audit_log转正提醒由 `remind_scan` probation_end_date 提前(默认 7 天可配)推送管理员与直属主管。
### 3.2 花名册列表F03 ### 3.2 花名册列表F03
`GET /hrroster/api/roster_list.dspy?keyword=张&org_id=..&status=regular&page=1&size=50` → 权限校验(数据范围 org_ids/field_ids→ 主表条件分页 → 值表批量拼装显示字段 → 敏感字段按角色脱敏 → `{"status":"success","data":{"rows":[...],"total":N}}` `GET /hrroster/api/roster_list.dspy?keyword=张&org_id=..&status=regular&page=1&size=50` → 权限校验(数据范围 org_ids/field_ids→ 主表条件分页 → 值表批量拼装显示字段 → 敏感字段按角色脱敏 → `{"status":"success","data":{"rows":[...],"total":N}}`
### 3.3 入职黑名单拦截F04 ### 3.3 入职黑名单拦截F04-6
`POST /hrorg/api/entry_approval.dspy` → id_number 哈希匹配 org_blacklist → 命中返回 `{"status":"error","data":{"code":"BLACKLIST_HIT"}}`,前端待入职列表高亮标注;手动入职返回 blocked 名单。 `POST /hrorg/api/entry_approval.dspy` → id_number 哈希匹配 org_blacklist → 命中返回 `{"status":"error","data":{"code":"BLACKLIST_HIT"}}`,前端待入职列表高亮标注;手动入职返回 blocked 名单。
### 3.4 入职登记表邀请(扫码入职降级)
1. HR 在待入职列表选中记录 → `POST entry_invite_register.dspy` → 生成 register_token/register_url + 二维码图片files/),站内消息发送邀请;
2. 候选人(内网)扫码访问 `entry_register_page.dspy?token=..` → 按表单定义渲染登记表(字段可配置、必填校验);
3. 提交 `entry_register_submit.dspy` → register_status=filled数据写入 org_entry/扩展字段 → 进入入职审批流或直接待入职。
### 3.5 离职全流程F07
`leave_apply/leave_manual` → 待离职名单status=pending_leave`leave_handover_save`(含 dingtalk_resource 占位项手工登记)→ remind_scan 到期触发 `leave_effect`(状态 left、写时间轴`leave_certificate` 生成证明 → 可选 `blacklist_add`
### 3.6 编制联动F16
入职/调动/离职回写成功 → `headcount_check(employee_id, event)` → 按 scope_json 匹配编制细分项重算 used_count → 写 headcount_snapshot当日→ 超编时向 hr/admin 发 sys_message提醒不硬拦截`headcount_status`/`headcount_history` 展示。
## 4. 与 v1 接口的替代关系(衔接 staff-mgr ## 4. 与 v1 接口的替代关系(衔接 staff-mgr
| v1 端点JWT RESTful | 迭代1替代 | | v1 端点JWT RESTful | 一期替代 |
|---|---| |---|---|
| POST /api/v1/staff | /hrorg/api/entry_manual.dspy 或 /hrroster/api/roster_employee_create.dspy | | POST /api/v1/staff | /hrorg/api/entry_manual.dspy 或 /hrroster/api/roster_employee_create.dspy |
| GET /api/v1/staff | /hrroster/api/roster_list.dspy+ CRUD 列表页) | | GET /api/v1/staff | /hrroster/api/roster_list.dspy+ CRUD 列表页) |
| GET /api/v1/staff/{id} | /hrroster/api/employee_detail.dspy | | GET /api/v1/staff/{id} | /hrroster/api/employee_detail.dspy |
| PUT /api/v1/staff/{id} | /hrroster/api/roster_employee_update.dspy | | PUT /api/v1/staff/{id} | /hrroster/api/roster_employee_update.dspy |
| DELETE /api/v1/staff/{id}、batch-delete | 离职流程 /hrorg/api/leave_manual.dspy迭代1不做删除语义裁决 Q6 | | DELETE /api/v1/staff/{id}、batch-delete | 离职流程 /hrorg/api/leave_manual.dspy一期不做删除语义 |
| GET /api/v1/staff/{id}/change-logs | /hrroster/api/timeline.dspy | | GET /api/v1/staff/{id}/change-logs | /hrroster/api/timeline.dspy |
| GET /api/v1/staff/audit-logs | /hrsystem/api/audit_log_list.dspy | | GET /api/v1/staff/audit-logs | /hrsystem/api/audit_log_list.dspy |
| GET /api/v1/staff/check/employee-no | /hrroster/api/check_employee_no.dspy | | GET /api/v1/staff/check/employee-no | /hrroster/api/check_employee_no.dspy |
| GET /api/v1/staff/departments | /hrorg/api/org_tree.dspy | | GET /api/v1/staff/departments | /hrorg/api/org_tree.dspy |
## 5. 安全设计要点 ## 5. 降级项桩端点汇总(二期恢复入口)
| 降级项 | 一期端点/字段 | 二期恢复方式 |
|---|---|---|
| D1 身份证读卡 | roster_employee/org_entry 证件字段组手工录入id_source=manual | 读卡硬件接入后经 roster_employee_update 回填同字段id_source=card_reader |
| D3 钉钉交接 | leave_handover_saveitem_type=dingtalk_resource 手工登记) | 钉钉开放平台对接后该类型项自动拉取资源清单 |
| D4 电子签 | esign_stub.dspyNOT_ENABLED+ contract_text_gen.dspy 打印下载 | 对接电子签平台esign_status 状态机流转 |
| D9 短信渠道 | sys_message.send_channel=site 兜底 | 短信网关接入扩展发送器send_channel=sms 生效 |
| 扫码入职 | entry_register_page/entry_register_submit/entry_qrcode内网 token | 对外渠道启用后 register_url 切公网域名 |
| API 开放 | /openapi/v1/ping.dspyNOT_ENABLED+ sys_openapp 表 | 按 architecture.md §9 规范启用签名鉴权 |
| 考勤/绩效桩位 | flow_form_def biz_type=attendance_*workbench_*_stub 字段 | 二期绩效/考勤系统接入后填充 |
## 6. 安全设计要点
1. 所有路径 load_path.py 注册;未注册即拒绝(含 .css/.js 静态资源)。 1. 所有路径 load_path.py 注册;未注册即拒绝(含 .css/.js 静态资源)。
2. 敏感字段身份证全角色脱敏前3后3手机前3后4职级/薪资类字段仅 admin/hr由 roster_field_def.sensitive + 角色矩阵驱动,服务端脱敏后返回。 2. 敏感字段身份证全角色脱敏前3后3手机前3后4职级/薪资类字段仅 admin/hr由 roster_field_def.sensitive + 角色矩阵驱动,服务端脱敏后返回。
3. 全部 SQL 经 sqlor 绑定参数(`${var}$` 占位),禁止拼接用户输入。 3. 全部 SQL 经 sqlor 绑定参数(`${var}$` 占位),禁止拼接用户输入。
4. 审批操作校验任务归属人;员工自助类接口校验本人(或白名单字段)。 4. 审批操作校验任务归属人;员工自助类接口校验本人(或白名单字段);登记表接口以一次性 token 鉴权并校验过期时间
5. 导入导出、登录、权限变更全量写 sys_audit_log含 IP 5. 导入导出、登录、权限变更全量写 sys_audit_log含 IP
6. 开放接口桩不注册业务处理;二期启用时按签名鉴权 + 数据出口授权管控。

View File

@ -1,33 +1,31 @@
# 迭代1总体设计 —— 系统架构与技术选型hr-web # 一期批次1总体设计 —— 系统架构与技术选型hr-web
- 版本v1.1迭代1-总体设计v1.1 变更database/api/ui 三份配套文档已按 ocai 口径重写为 v2.0,表数量与端点数量同步修正 - 版本v2.0批次1设计定稿v2.0 变更:对齐 SRS v3.1 —— 批次1范围扩入编制管理(F16)/项目式组织(F17)、数据库口径修正 MariaDB/库hrs、部署端口统一 9182、新增降级项设计专章 §10、新增 API 开放接口规范 §9、F01~F15↔FEAT-B1 编号映射
- 状态:评审通过主agent评审基线冻结 - 状态:**设计定稿批次1评审修订版随本批次冻结契约变更须走设计评审**
- 需求基线:`docs/00-requirement/requirement-spec.md`SRS v2+ `docs/00-requirement/iteration1-function-detail.md`F01~F15 - 需求基线:`docs/00-requirement/requirement-spec.md`SRS v3.12026-08-18+ `docs/00-requirement/iteration1-function-detail.md`F01~F1581 条)+ `docs/00-requirement/approved-features.md`FEAT-B1-01~12
- 应用定义:`apps/hr-web.md`;模块定义:`modules/hr-org.md``hr-roster.md``hr-flow.md``hr-contract.md``hr-report.md``hr-system.md` - 应用定义:`apps/hr-web.md`;模块定义:`modules/hr-org.md``hr-roster.md``hr-flow.md``hr-contract.md``hr-report.md``hr-system.md`
- 开发规范ocai 技能集 —— web-application-spec、module-development-spec、database-table-definition-spec、crud-definition-spec、dspy-file-implementation-spec - 开发规范ocai 技能集 —— web-application-spec、module-development-spec、database-table-definition-spec、crud-definition-spec、dspy-file-implementation-spec
## 0. 审核退回意见响应索引 ## 0. 与需求基线的对齐说明
PM 退回意见要求交付件至少包含 6 项内容,落点如下: | # | 对齐项 | 结论 |
| # | 退回意见要求 | 落点文档/章节 |
|---|---|---| |---|---|---|
| 1 | 系统总体架构与模块划分hr-system、staff-mgr 职责边界) | 本文 §2、§4、§6 | | 1 | 批次1范围 | SRS v3.1 §1.4 批次1 = 12 featureFEAT-B1-01~12。其中 FEAT-B1-10 编制管理、FEAT-B1-11 项目式组织在原 F01~F1581 条验收项)基线之外,本设计新增 **F16 编制管理6 条验收项、F17 项目式组织3 条验收项)**批次1合计 **90 条可验收项** |
| 2 | 数据库设计(核心表、字段、索引、关系、迁移策略) | `database-design.md` 全文§4 表结构、§5 索引策略、§7 迁移策略) | | 2 | 功能编号映射 | F01 组织↔FEAT-B1-02F02 职位职级↔FEAT-B1-03F03 花名册+F08 兼岗↔FEAT-B1-04F04 入职↔FEAT-B1-05F05 转正+F06 调动↔FEAT-B1-06F07 离职↔FEAT-B1-07F09 合同↔FEAT-B1-08F14 工作台+F15 员工服务↔FEAT-B1-09F10 流程审批+F11 权限+F12 日志↔FEAT-B1-01F13 报表↔FEAT-B1-12F16↔FEAT-B1-10F17↔FEAT-B1-11 |
| 3 | API 设计(路径、方法、请求/响应、鉴权、错误码) | `api-design.md` 全文§1 通用约定、§2 端点清单、§3 示例) | | 3 | 技术口径 | ocai 规范:前端 bricks + dspy后端 ahserver(Python);数据层 apppublic/sqlor(MariaDB);应用 hr-web。与 SRS v3.1 头注一致 |
| 4 | UI 设计(页面结构、核心交互、组件/路由) | `ui-design.md` 全文§2 路由、§3 组件树、§4 交互流程) | | 4 | 部署口径 | 测试/生产应用统一端口 **9182**、库名 **hrs**SRS §8v1.1 文档中 dev:9080/prod:443/库hr 口径作废 |
| 5 | 与现有 staff-mgr 员工管理模块的衔接方案 | 本文 §6 + `database-design.md` §6 数据迁移 | | 5 | 降级项 | 批次1涉及 D1 身份证读卡→手工录入、D3 钉钉交接→占位字段、D4 电子签→模板生成+桩、D9 短信→站内兜底、扫码入职→内网登记链接/二维码;专章见 §10二期预留接口清单见 §10.4 |
| 6 | 技术可行性说明与后续开发任务拆解 | `iteration1-task-breakdown.md` 全文 |
## 1. 概述 ## 1. 概述
迭代1交付「Web 版人事系统hr-web」组织人事底座功能范围 F01~F15:组织架构、职位职级体系、花名册、入职/转正/调动/离职/兼岗、合同台账(不含电子签)、流程审批、权限/日志、报表、工作台、员工服务与提醒。规模规格 100 人账号。 批次1交付「Web 版人事系统hr-web」**组织人事底座 + 系统管理与权限基座**,功能范围 F01~F17:组织架构、职位职级体系、花名册、入职/转正/调动/离职/兼岗、合同台账(不含电子签)、流程审批、权限/日志、报表、工作台、员工服务与提醒、**编制管理、项目式组织**。规模规格 100 人账号。
设计原则: 设计原则:
1. **全栈遵循 ocai 规范**:前端 bricks 组件体系(.ui 纯 JSON 声明式页面 + dspy 驱动的 CRUD后端 ahserverPython/aiohttp数据层 apppublic/sqlor基础模块 appbase字典/用户)+ rbac角色权限 1. **全栈遵循 ocai 规范**:前端 bricks 组件体系(.ui 纯 JSON 声明式页面 + dspy 驱动的 CRUD后端 ahserverPython/aiohttp数据层 apppublic/sqlorMariaDB,基础模块 appbase字典/用户)+ rbac角色权限
2. **配置驱动**表结构models/*.json、CRUD 界面json/*.json、字典appcodes全部声明式定义减少硬编码,支撑 SRS 的"字段/流程/表单自定义"诉求。 2. **配置驱动**表结构models/*.json、CRUD 界面json/*.json、字典appcodes全部声明式定义支撑 SRS 的"字段/流程/表单自定义"诉求FEAT-B1-01 验收①不写代码配置 4 类审批流)
3. **模块宿主无关**:每个模块仅依赖基础包与自己的数据表,通过 `load_{module}()` 注册 ServerEnv可被任意宿主应用加载module-development-spec 3. **模块宿主无关**:每个模块仅依赖基础包与自己的数据表,通过 `load_{module}()` 注册 ServerEnv可被任意宿主应用加载module-development-spec
4. **单一事实来源**花名册roster_employee是全系统员工数据唯一事实来源入转调离审批通过后统一回写花名册。 4. **单一事实来源**花名册roster_employee是全系统员工数据唯一事实来源入转调离审批通过后统一经 `roster_writeback` 回写SRS §5.2-1
5. **降级留桩**一期降级项SRS §9一律"字段/桩端点/流程位"预留,二期对接不改表结构主干。
## 2. 总体架构 ## 2. 总体架构
@ -36,28 +34,27 @@ PM 退回意见要求交付件至少包含 6 项内容,落点如下:
│ 浏览器PC Web 为主) │ │ 浏览器PC Web 为主) │
│ bricks.js 渲染引擎:.ui(JSON) 页面 + DataViewer/Tree/Form/Chart │ │ bricks.js 渲染引擎:.ui(JSON) 页面 + DataViewer/Tree/Form/Chart │
└──────────────────────────────┬─────────────────────────────────────┘ └──────────────────────────────┬─────────────────────────────────────┘
│ HTTP(S) session cookieRedis 会话) │ HTTP session cookieRedis 会话)
┌──────────────────────────────▼─────────────────────────────────────┐ ┌──────────────────────────────▼─────────────────────────────────────┐
│ nginx 反向代理prod: 443 │ ahserver 应用进程hr-web直接监听 9182systemd 守护) │
└──────────────────────────────┬─────────────────────────────────────┘ │ (二期补齐域名/证书后可选引入 nginx:9182 HTTPS 反代,见 §7.3
┌──────────────────────────────▼─────────────────────────────────────┐
│ ahserver 应用进程hr-webdev:9080
│ 路由wwwroot 自动路由 /{module}/{file}.ui|.dspy|.css|.js │ │ 路由wwwroot 自动路由 /{module}/{file}.ui|.dspy|.css|.js │
│ processors: .tmpl→tmpl, .ui→bui, .dspy→dspy │ │ processors: .tmpl→tmpl, .ui→bui, .dspy→dspy │
│ ┌─────────────────────────────────────────────────────────────┐ │ │ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 业务模块load_xxx 注册 ServerEnv │ │ │ │ 业务模块load_xxx 注册 ServerEnv │ │
│ │ hr-org | hr-roster | hr-flow | hr-contract | hr-report | │ │ │ │ hr-org | hr-roster | hr-flow | hr-contract | hr-report | │ │
│ │ hr-system │ │ │ │ hr-system │ │
│ ├─────────────────────────────────────────────────────────────┤ │ │ ├─────────────────────────────────────────────────────────────┤ │
│ │ 基础模块appbaseusers/appcodes 字典)+ rbac角色/权限) │ │ │ │ 基础模块appbaseusers/orgs/appcodes 字典)+ rbac角色权限│ │
│ │ bricks_for_pythonUiWindow 等 pybricks │ │ │ │ bricks_for_pythonUiWindow 等 pybricks │ │
│ └─────────────────────────────────────────────────────────────┘ │ │ └─────────────────────────────────────────────────────────────┘ │
│ 后台任务remind_scan提醒扫描/ headcount 联动校验 / 导入导出任务 │
└──────────┬───────────────────────────────┬─────────────────────────┘ └──────────┬───────────────────────────────┬─────────────────────────┘
│ sqlor 连接池sor.C/U/D/R/I/sqlExe │ Redis session │ sqlor 连接池sor.C/U/D/R/I/sqlExe │ Redis session
┌──────────▼──────────┐ ┌────────▼────────┐ ┌──────────▼──────────┐ ┌────────▼────────┐
MySQL 8.0(库 hr │ │ Redis会话 MariaDB库 hrs │ │ Redis会话
json2ddl 生成 DDL │ └─────────────────┘ │ json2ddl 生成 DDL │ └─────────────────┘
└─────────────────────┘ files/ 目录:附件存储(合同文件、头像、导入导出文件 └─────────────────────┘ files/ 目录:附件存储(合同文件、离职证明、导入导出文件、登记表二维码
``` ```
请求处理链路(以花名册列表为例): 请求处理链路(以花名册列表为例):
@ -71,52 +68,54 @@ PM 退回意见要求交付件至少包含 6 项内容,落点如下:
| 层 | 选型 | 选型理由 | | 层 | 选型 | 选型理由 |
|---|---|---| |---|---|---|
| 前端 | bricks 组件体系 + .ui 纯 JSON 页面 | ocai 强制规范CRUD JSON 自动生成列表/表单/树页面,F01~F15 中 80% 的增删改查页面零 Vue 代码DataViewer 自带筛选data_filter、子表subtables、工具栏 bind | | 前端 | bricks 组件体系 + .ui 纯 JSON 页面 | ocai 强制规范CRUD JSON 自动生成列表/表单/树页面,批次1中 80% 的增删改查页面零 Vue 代码DataViewer 自带筛选data_filter、子表subtables、工具栏 bind |
| 声明式页面脚本 | .dspy受控 Python | 后端 API 与页面逻辑统一语言栈Pythonahserver 自动解析参数、自动 JSON 序列化;禁止 import/print天然受控 | | 声明式页面脚本 | .dspy受控 Python | 后端 API 与页面逻辑统一语言栈Pythonahserver 自动解析参数、自动 JSON 序列化;禁止 import/print天然受控 |
| 后端框架 | ahserveraiohttp 异步) | ocai 强制规范;内置会话/RBAC/文件上传/后台任务wwwroot 自动路由免手写路由注册100 人规模单实例足够 | | 后端框架 | ahserveraiohttp 异步) | ocai 强制规范;内置会话/RBAC/文件上传/后台任务wwwroot 自动路由免手写路由注册100 人规模单实例足够 |
| 数据访问 | apppublic/sqlor | 异步连接池 + 绑定参数防注入;`sor.C/U/D/R/I/sqlExe` 六元 API 覆盖全部数据操作;与 models JSON 配套 | | 数据访问 | apppublic/sqlor | 异步连接池 + 绑定参数防注入;`sor.C/U/D/R/I/sqlExe` 六元 API 覆盖全部数据操作;与 models JSON 配套 |
| 表定义 | models/*.json + json2ddl | database-table-definition-spec 标准数据库无关的抽象类型DDL 自动生成,保证 collate utf8mb4_unicode_ci 一致 | | 表定义 | models/*.json + json2ddl | database-table-definition-spec 标准数据库无关的抽象类型DDL 自动生成,保证 collate utf8mb4_unicode_ci 一致 |
| CRUD 生成 | json/*.json + xls2ui | crud-definition-spec 标准;自动产出列表页 .ui 与 add/update/delete dspy 包装 | | CRUD 生成 | json/*.json + xls2ui | crud-definition-spec 标准;自动产出列表页 .ui 与 add/update/delete dspy 包装 |
| 字典 | appbase appcodes/appcodes_kv | 性别/员工类型/异动类型/离职原因等枚举统一管理CRUD 下拉直接引用codes 段) | | 字典 | appbase appcodes/appcodes_kv | 性别/员工类型/异动类型/离职原因/提醒场景/编制周期等枚举统一管理CRUD 下拉直接引用codes 段) |
| 权限 | rbac 模块 + 自研数据范围表 | rbac 管"功能权限(路径级)"hr-system 扩展"数据范围(组织维度/花名册字段维度)",满足 SRS §3.1.14 | | 权限 | rbac 模块 + 自研数据范围表 | rbac 管"功能权限(路径级)"hr-system 扩展"数据范围(组织维度/花名册字段维度)",满足 SRS §2.2 |
| 数据库 | MySQL 8.0 | 产线既有设施staff-mgr 亦为 MySQLsqlor DDL 模板成熟 | | 数据库 | **MariaDB库 hrs** | 任务明确口径SRS §8sqlor DDL 模板成熟;每日全量备份保留 ≥30 天 |
| 会话 | Redis + aiohttp_session | web-application-spec 推荐;服务重启不丢登录 | | 会话 | Redis + aiohttp_session | web-application-spec 推荐;服务重启不丢登录 |
| 附件 | ahserver files/ 文件存储 | 合同附件、离职证明、导入导出文件100 人规模本地目录足够 | | 附件 | ahserver files/ 文件存储 | 合同附件、离职证明、导入导出文件、入职登记表二维码图片100 人规模本地目录足够随应用数据一并备份NFR-5 |
v1Java/Spring Boot/JPA/JWT口径的差异已全部废弃归档(`docs/_archive/`),不保留双栈:鉴权由"自研 JWT Filter"改为"ahserver session + rbac"ORM 由 JPA 改为 sqlor前端由"无"改为 bricks/dspy。 v1Java/Spring Boot/JPA/JWT口径已全部废弃归档`docs/_archive/`),不保留双栈:鉴权由"自研 JWT Filter"改为"ahserver session + rbac"ORM 由 JPA 改为 sqlor前端由"无"改为 bricks/dspy。
## 4. 模块划分与职责边界 ## 4. 模块划分与职责边界
### 4.1 迭代1模块清单6 个,均挂载于 hr-web 应用) ### 4.1 批次1模块清单6 个,均挂载于 hr-web 应用)
| 模块 | 路由前缀 | 职责 | 数据表前缀 | 迭代1功能 | | 模块 | 路由前缀 | 职责 | 数据表前缀 | 批次1功能 |
|---|---|---|---|---| |---|---|---|---|---|
| hr-org | /hrorg | 组织架构、职位职级体系、入转调离兼岗异动业务、黑名单、合同公司 | org_ | F01/F02/F04~F08 | | hr-org | /hrorg | 组织架构、职位职级体系、入转调离兼岗异动业务、黑名单、合同公司、**编制管理、项目式组织** | org_ | F01/F02/F04~F08/**F16/F17** |
| hr-roster | /hrroster | 花名册(字段定义/字段值 EAV/员工主档/时间轴/工号规则)、导入导出 | roster_ | F03 | | hr-roster | /hrroster | 花名册(字段定义/字段值 EAV/员工主档/时间轴/工号规则)、导入导出 | roster_ | F03 |
| hr-flow | /hrflow | 表单定义、流程定义、流程实例、审批任务(待办/已办/我发起) | flow_ | F10 | | hr-flow | /hrflow | 表单定义、流程定义、流程实例、审批任务(待办/已办/我发起/我收到 | flow_ | F10FEAT-B1-01 流程引擎部分) |
| hr-contract | /hrcontract | 合同台账、合同模板、到期提醒规则、合同审批 | contract_ | F09 | | hr-contract | /hrcontract | 合同台账、合同类型/模板、到期提醒规则、合同审批、esign 桩 | contract_ | F09 |
| hr-report | /hrreport | 只读聚合报表(花名册分析/入职/转正/调岗/离职分析),无自有表 | — | F13 | | hr-report | /hrreport | 只读聚合报表(花名册/入职/转正/调岗/离职五类分析),无自有表 | — | F13 |
| hr-system | /hrsystem | 角色/管理员/数据范围、操作日志、工作台聚合、提醒规则、公告政策、站内消息 | sys_ | F11/F12/F14/F15 | | hr-system | /hrsystem | 角色/管理员/数据范围、操作日志、工作台聚合、提醒规则、公告政策、站内消息 | sys_ | F11/F12/F14/F15FEAT-B1-01 权限日志部分 + FEAT-B1-09 |
### 4.2 职责边界规则 ### 4.2 职责边界规则
1. **员工主数据唯一入口**:所有模块读写员工信息必须经 hr-roster 的注册函数ServerEnv 暴露),禁止跨模块直接 SQL 写 roster_ 表。入转调离审批通过后由 hr-flow 回调 hr-org 的业务函数,再调用 hr-roster 回写接口更新员工状态 1. **员工主数据唯一入口**:所有模块读写员工信息必须经 hr-roster 的注册函数ServerEnv 暴露),禁止跨模块直接 SQL 写 roster_ 表。入转调离审批通过后由 hr-flow 回调 hr-org 的业务函数,再调用 hr-roster `roster_writeback` 更新员工主档与时间轴
2. **审批引擎与业务解耦**hr-flow 只管"表单+流程+实例+任务"的流转,不含业务语义;业务回写通过 `biz_type + biz_id` 关联 + 流程完成回调ServerEnv 注册的 hook 函数)实现。 2. **审批引擎与业务解耦**hr-flow 只管"表单+流程+实例+任务"的流转,不含业务语义;业务回写通过 `biz_type + biz_id` 关联 + 流程完成回调ServerEnv 注册的 hook 函数)实现。考勤流程桩位FEAT-B1-01仅允许建表单定义biz_type=attendance_* 无回写 hook。
3. **权限横切**:功能权限(路径级 RBAC由 rbac 模块统一拦截(各模块 scripts/load_path.py 注册路径与角色);数据范围由 hr-system 提供 `get_data_scope(user_id)` 公共函数hr-org/hr-roster/hr-report 在查询时强制叠加。 3. **权限横切**:功能权限(路径级 RBAC由 rbac 模块统一拦截(各模块 scripts/load_path.py 注册路径与角色);数据范围由 hr-system 提供 `get_data_scope(user_id)` 公共函数hr-org/hr-roster/hr-report 在查询、报表、**导出**时强制叠加SRS §2.2-2
4. **操作日志横切**所有写操作sor.C/U/D统一经 hr-system 的 `write_audit_log(...)` 记录前后值before/after JSONF12 查询页只读 sys_audit_log。 4. **操作日志横切**所有写操作sor.C/U/D统一经 hr-system 的 `write_audit_log(...)` 记录前后值before/after JSONF12 查询页只读 sys_audit_log。
5. **字典统一**:任何枚举值不得硬编码在 dspy 中,一律走 appcodesinit/data.json 初始化CRUD 下拉用 models codes 段引用。 5. **编制联动**入转调离回写成功后hr-org 同步调用 `headcount_check(employee, event)` 重算所属编制方案占编并写快照/超编提醒服务内同步执行100 人规模满足"1 分钟内刷新"验收)。
6. **字典统一**:任何枚举值不得硬编码在 dspy 中,一律走 appcodesinit/data.json 初始化CRUD 下拉用 models codes 段引用。
### 4.3 hr-system 与 staff-mgr 的职责边界(重点澄清) ### 4.3 hr-system 与 staff-mgr 的职责边界
| 对象 | 性质 | 职责 | 状态 | | 对象 | 性质 | 职责 | 状态 |
|---|---|---|---| |---|---|---|---|
| **hr-system**模块repos/hr-system | 迭代1 ocai 规范模块 | 系统支撑层F11 权限管理、F12 操作日志、F14 工作台、F15 员工服务与提醒;并承载全应用横切能力(数据范围、审计、站内消息 | 迭代1新建复用现有空仓 hr-system.git | | **hr-system**模块repos/hr-system | ocai 规范模块 | 系统支撑层F11 权限管理、F12 操作日志、F14 工作台、F15 员工服务与提醒;并承载全应用横切能力(数据范围、审计、站内消息、提醒扫描) | 批次1新建复用现有空仓 hr-system.git |
| **staff-mgr**repos/staff-mgr | v1 遗留 Java 模块 | 旧员工 CRUD REST 服务(/api/v1/staff/*Spring Boot + JPA + JWT | **已归档,冻结不再开发**;仅作迭代1数据迁移来源与参考实现(见 §6 | | **staff-mgr**遗留 Java 模块) | v1 遗留 | 旧员工 CRUD REST 服务(/api/v1/staff/*Spring Boot + JPA + JWT | **已归档,冻结不再开发**;仅作数据迁移来源与参考实现(见 §6 |
边界结论: 边界结论:
- 迭代1上线后 staff-mgr **不再承担任何线上职责**;其员工数据一次性迁移至 hr-rosterroster_employee + roster_field_value部门缓存迁移至 hr-orgorg_unit日志迁移/归档至 hr-systemsys_audit_log - 一期上线后 staff-mgr 不再承担任何线上职责;其员工数据一次性迁移至 hr-roster部门缓存迁移至 hr-org日志迁移至 hr-system详见 database-design.md §8、任务 T23
- 旧模块的"员工 CRUD"职责由 **hr-roster** 承接(不是 hr-systemhr-system 只承接其"操作日志/权限"类横切职责。详见 §6 衔接方案。 - 旧模块的"员工 CRUD"职责由 **hr-roster** 承接(不是 hr-systemhr-system 只承接"操作日志/权限"类横切职责。
- v1 应用定义 `apps/hr-system.md`Java 后端服务)已废弃,与模块 hr-systemocai 支撑模块)仅重名,无继承关系。 - v1 应用定义 `apps/hr-system.md`Java 后端服务)已废弃,与模块 hr-system 仅重名,无继承关系。
- 迁移范围(仅在职/含历史)与切换时间点待 PM 确认SRS §11-Q3脚本按"可配置范围"实现,默认在职+离职保留档案。
## 5. 模块结构与依赖关系 ## 5. 模块结构与依赖关系
@ -147,14 +146,14 @@ PM 退回意见要求交付件至少包含 6 项内容,落点如下:
│ ▲ ▲ │ ▲ ▲
│ │ 路径注册/数据范围 │ 字典/用户 │ │ 路径注册/数据范围 │ 字典/用户
┌─────────┴──┐ ┌──────┴─────┐ ┌──────┴─────┐ ┌─────────┴──┐ ┌──────┴─────┐ ┌──────┴─────┐
│ hr-system │◄─────│ hr-flow │◄──────────│ hr-contract│ │ hr-system │◄─────│ hr-flow │◄──────────│ hr-contract
F11/12/14/15│ 审批回调/权限 │ 合同审批 │ │F11/12/14/15│ 审批回调/权限 │ 合同审批 │
└─────▲──────┘ └──────▲─────┘ └──────┬─────┘ └─────▲──────┘ └──────▲─────┘ └──────┬─────┘
│ 审计/数据范围 │ 入转调离审批 │ 员工/公司引用 │ 审计/数据范围 │ 入转调离/兼岗审批 │ 员工/公司引用
│ │ │ │ │ │
┌─────┴──────┐ ┌──────┴─────┐ │ ┌─────┴──────┐ ┌──────┴─────┐ │
│ hr-report │─────►│ hr-org │◄─────────────────┘ │ hr-report │─────►│ hr-org │◄─────────────────┘
│ (只读聚合) │ 异动数据 │ 组织/职位/异动 │ (只读聚合) │ 异动数据 │组织/职位/异动/编制/项目
└─────▲──────┘ └──────┬─────┘ └─────▲──────┘ └──────┬─────┘
│ 花名册分析 │ 员工主数据读写(唯一入口) │ 花名册分析 │ 员工主数据读写(唯一入口)
│ ┌──────▼─────┐ │ ┌──────▼─────┐
@ -168,47 +167,46 @@ PM 退回意见要求交付件至少包含 6 项内容,落点如下:
| ↓依赖→ | hr-org | hr-roster | hr-flow | hr-contract | hr-report | hr-system | | ↓依赖→ | hr-org | hr-roster | hr-flow | hr-contract | hr-report | hr-system |
|---|---|---|---|---|---|---| |---|---|---|---|---|---|---|
| hr-org | — | 回写花名册/黑名单 | 异动审批流转 | — | — | 权限/日志 | | hr-org | — | 回写花名册/黑名单 | 异动审批流转 | — | — | 权限/日志/提醒通道 |
| hr-roster | 组织/职位主数据 | — | 自助修改审核 | — | — | 字段级权限/脱敏/日志 | | hr-roster | 组织/职位主数据 | — | 自助修改审核 | — | — | 字段级权限/脱敏/日志 |
| hr-flow | — | 表单引用字段/完成回调 | — | — | — | 审批角色权限/日志 | | hr-flow | — | 表单引用字段/完成回调 | — | — | — | 审批角色权限/日志 |
| hr-contract | 合同公司主数据 | 员工关联 | 合同审批 | — | — | 提醒通道/日志 | | hr-contract | 合同公司主数据 | 员工关联 | 合同审批 | — | — | 提醒通道/日志 |
| hr-report | 异动数据 | 花名册数据 | — | — | — | 数据范围 | | hr-report | 异动/编制数据 | 花名册数据 | — | — | — | 数据范围 |
| hr-system | 工作台引用组织 | 工作台引用档案 | 工作台引用待办 | 工作台引用合同 | — | — | | hr-system | 工作台引用组织/异动/编制 | 工作台引用档案 | 工作台引用待办 | 工作台引用合同 | — | — |
### 5.3 应用装配与部署 ### 5.3 应用装配
- 应用入口 `app/hr_web.py``init()` 中依次 `ServerEnv()` → 设置 `get_module_dbname`(返回 `hr`)→ `load_appbase()``load_rbac()``load_pybricks()``load_hrsystem/load_hrorg/load_hrroster/load_hrflow/load_hrcontract/load_hrreport()` - 应用入口 `app/hr_web.py``init()` 中依次 `ServerEnv()` → 设置 `get_module_dbname`(返回 `hrs`)→ `load_appbase()``load_rbac()``load_pybricks()``load_hrsystem/load_hrorg/load_hrroster/load_hrflow/load_hrcontract/load_hrreport()`
- `conf/config.json`processors 必含 `[".tmpl","tmpl"], [".ui","bui"], [".dspy","dspy"]`indexes 含 `index.ui`databases 配置 hr 库Redis sessionsession_max_time/session_issue_time - `conf/config.json`processors 必含 `[".tmpl","tmpl"], [".ui","bui"], [".dspy","dspy"]`indexes 含 `index.ui`databases 配置 **hrs** 库(测试环境 test/test123Redis sessionsession_max_time/session_issue_time
- build.sh 顺序:建 venv → pip install apppublic/sqlor/ahserver/bricks/appbase/rbac → clone 6 个业务模块 pip install → 各模块 models/ 执行 `json2ddl mysql . > mysql.ddl.sql` 并导入 → init/data.json 导入 → json/ 执行 `xls2ui` 生成 CRUD → symlink 各模块 wwwroot 与 bricks dist → systemd 服务。 - build.sh 顺序:建 venv → pip install apppublic/sqlor/ahserver/bricks/appbase/rbac → clone 6 个业务模块 pip install → 各模块 models/ 执行 `json2ddl mysql . > mysql.ddl.sql` 并导入 hrs 库 → init/data.json 导入(含四类流程模板、基础字段集、内置 admin 与角色SRS §5.2-4→ json/ 执行 `xls2ui` 生成 CRUD → symlink 各模块 wwwroot 与 bricks dist → systemd 服务。
- 环境dev/test 单实例容器nginx:8080 → ahserver:9080prod nginx:443 反代ahserver 不直接暴露MySQL/Redis 仅内网数据每日备份。100 人规模单实例即可满足"列表页 ≤500ms"指标(见 §8
## 6. 与现有 staff-mgr 员工管理模块的衔接方案 ## 6. 与现有 staff-mgr 员工管理模块的衔接方案
### 6.1 衔接定位 ### 6.1 衔接定位
staff-mgr 是 v1 Java 口径下的员工 CRUD 模块(已通过端到端验证,见其 README),与 ocai 规范冲突,不改造、不并行演进,采取**一次性数据迁移 + 接口替代 + 退役**策略。 staff-mgr 是 v1 Java 口径下的员工 CRUD 模块(已通过端到端验证),与 ocai 规范冲突,不改造、不并行演进,采取**一次性数据迁移 + 接口替代 + 退役**策略。
### 6.2 职责与接口替代映射 ### 6.2 职责与接口替代映射
| staff-mgr 旧接口(/api/v1/staff | 迭代1替代hr-roster/hr-system dspy | 说明 | | staff-mgr 旧接口(/api/v1/staff | 批次1替代hr-roster/hr-org/hr-system dspy | 说明 |
|---|---|---| |---|---|---|
| POST /(创建员工) | /hrroster/api/roster_employee_create.dspy或手动入职 /hrorg/api/entry_manual.dspy | 新建一律走入职流程或花名册新增 | | POST /(创建员工) | /hrroster/api/roster_employee_create.dspy或手动入职 /hrorg/api/entry_manual.dspy | 新建一律走入职流程或花名册新增 |
| GET /(分页列表) | /hrroster/roster_listCRUD 列表 + data_filter | 筛选能力增强(自定义字段) | | GET /(分页列表) | /hrroster/roster_listCRUD 列表 + data_filter | 筛选能力增强(自定义字段) |
| GET /{id}(详情) | /hrroster/employee_detail.dspy | 档案 Tabs + 时间轴 | | GET /{id}(详情) | /hrroster/api/employee_detail.dspy | 档案 Tabs + 时间轴 |
| PUT /{id}(更新) | /hrroster/api/roster_employee_update.dspy | 可配置自助修改 + 审核 | | PUT /{id}(更新) | /hrroster/api/roster_employee_update.dspy | 可配置自助修改 + 审核 |
| DELETE /{id}、POST /batch-delete | 离职流程 /hrorg/api/leave_manual.dspy | 迭代1不做物理/逻辑删除员工,统一走离职 | | DELETE /{id}、POST /batch-delete | 离职流程 /hrorg/api/leave_manual.dspy | 一期不做物理/逻辑删除员工,统一走离职 |
| GET /{id}/change-logs | /hrroster/timeline.dspy | 时间轴(含迁移进来的旧变更记录) | | GET /{id}/change-logs | /hrroster/api/timeline.dspy | 时间轴(含迁移进来的旧变更记录) |
| GET /audit-logs | /hrsystem/audit_log_listCRUD | 历史日志迁入 sys_audit_log | | GET /audit-logs | /hrsystem/api/audit_log_list.dspy | 历史日志迁入 sys_audit_log |
| GET /check/employee-no | /hrroster/api/check_employee_no.dspy | 工号查重保留 | | GET /check/employee-no | /hrroster/api/check_employee_no.dspy | 工号查重保留 |
| GET /departments | /hrorg/api/org_tree.dspy | 部门缓存表废弃,直接查 org_unit | | GET /departments | /hrorg/api/org_tree.dspy | 部门缓存表废弃,直接查 org_unit |
脱敏规则延续并按 SRS 加强身份证号全角色脱敏前3后3、手机号前3后4、薪资职级类字段仅 admin/hr 可见——由 hr-system 字段级权限表驱动,替代 staff-mgr 硬编码 MaskUtil。 脱敏规则延续并按 SRS §2.2-4 加强身份证号全角色脱敏前3后3、手机号前3后4、薪资职级类字段仅 admin/hr 可见——由 roster_field_def.sensitive 驱动,替代 staff-mgr 硬编码 MaskUtil。
### 6.3 数据迁移方案(详见 database-design.md §6 ### 6.3 数据迁移方案(详见 database-design.md §8
- 迁移对象staff_employee → roster_employeestaff_employee_extra → roster_field_value(学历/专业等映射到预置字段定义)+ contract_info合同起止staff_department_cache → org_unitstaff_change_log → roster_timelinestaff_audit_log → sys_audit_log。 - 迁移对象staff_employee → roster_employeestaff_employee_extra → roster_field_value + contract_infostaff_department_cache → org_unitstaff_change_log → roster_timelinestaff_audit_log → sys_audit_log。
- 迁移工具hr-system 仓内 `scripts/migrate_staff_mgr.py`Python + sqlor幂等、按 employee_no 去重、输出核对报告)。 - 迁移工具hr-system 仓内 `scripts/migrate_staff_mgr.py`Python + sqlor幂等、按 employee_no 去重、输出核对报告:总数/抽样一致NFR-8)。
- 切换策略:迭代1 UAT 通过后一次性切换;切换后 staff-mgr 服务下线、仓库冻结归档(保留只读访问一个迭代周期)。 - 切换策略UAT 通过后一次性切换;切换后 staff-mgr 服务下线、仓库冻结归档(保留只读访问一个迭代周期)。迁移范围待 PM 确认SRS §11-Q3
### 6.4 风险与对策 ### 6.4 风险与对策
@ -216,28 +214,81 @@ staff-mgr 是 v1 Java 口径下的员工 CRUD 模块(已通过端到端验证
|---|---| |---|---|
| 旧数据字段语义不一致(如 status 枚举) | 迁移脚本内置映射表 + 人工核对报告UAT 期间双库比对 | | 旧数据字段语义不一致(如 status 枚举) | 迁移脚本内置映射表 + 人工核对报告UAT 期间双库比对 |
| 旧 department_id 无组织主数据 | 先迁 staff_department_cache 建 org_unit再按 department_id 关联 | | 旧 department_id 无组织主数据 | 先迁 staff_department_cache 建 org_unit再按 department_id 关联 |
| 身份证号加密算法不同AesCipher | 迁移时解密后按 hr-web 统一加密方案重新落库 | | 身份证号加密算法不同AesCipher | 迁移时解密后按 hr-web 统一加密方案重新落库cipher+hash |
## 7. 安全设计 ## 7. 部署与运维设计SRS §8 落地)
1. **鉴权**ahserver sessionRedis+ rbac 角色。迭代1角色`admin`(系统管理员)、`hr`(人事)、`manager`(部门经理)、`employee`(员工自助);所有路径经 scripts/load_path.py 注册,未注册路径默认拒绝。 ### 7.1 环境矩阵
2. **数据范围**F11sys_role_data_scope 支持两类范围——组织维度org_id 集合含子树、花名册字段维度field_id 可见集合)。查询层强制拼接范围条件;报表同样受控。
3. **脱敏**:敏感字段(身份证/手机/薪资级)在 roster_field_def 标记 sensitivedspy 返回前按角色脱敏。 | 项 | 测试环境 | 生产环境 |
4. **审计**F12全量写操作记录前后值 JSON、操作人、IP审批、导入导出同样记录。 |---|---|---|
| 主机 | hrstest@192.168.16.12:22免密已验证 | hrs@192.168.16.10:22 |
| 应用端口 | **9182**ahserver 直接监听HTTP | **9182**(同左;域名/证书补齐前接受 IP 直连SRS §11-Q1 |
| 数据库 | MariaDB 本地test/test123库 hrs | MariaDB 本地,库 hrs生产账号口令部署时安全配置SRS §11-Q2 |
| 会话 | Redis 本地(仅内网监听) | Redis 本地(仅内网监听) |
| 进程守护 | systemd hr-web.service异常自动重启NFR-3 | 同左 |
| 备份 | 无要求 | MariaDB 每日全量备份mysqldump+crontab保留 ≥30 天files/ 附件目录随应用数据备份NFR-5 |
| 监控告警 | — | 进程存活 + 9182 端口探活 + 备份结果告警(基础三项;接收渠道待明确 SRS §11-Q8默认本地日志+邮件占位) |
### 7.2 部署形态决策
一期采用**单实例直连形态**ahserver 直接监听 9182systemd 守护(`Restart=always`),满足 NFR-3月度可用率 ≥99% 工作时间、异常自动重启)。不强制引入 nginx。
### 7.3 HTTPS 升级路径(预留)
生产域名与证书补齐后SRS §11-Q1引入 nginx 监听 9182HTTPS反代 ahserver 内部端口(如 127.0.0.1:9183ahserver 改绑 loopback配置变更仅涉及 conf/config.json 端口与 systemd unit无代码改动。招聘官网对外批次3 FEAT-B3-07依赖此升级。
## 8. 安全设计
1. **鉴权**ahserver sessionRedis+ rbac 角色。批次1角色`admin`(系统管理员)、`hr`(人事)、`manager`(部门经理)、`employee`(员工自助);所有路径经 scripts/load_path.py 注册,**未注册路径默认拒绝**SRS §2.2-1
2. **数据范围**F11sys_data_scope 支持两类范围——组织维度org_id 集合含子树、花名册字段维度field_id 可见集合),两类可叠加;查询、报表、导出层强制拼接范围条件。
3. **脱敏**SRS §2.2-4敏感字段身份证/手机/薪资级)在 roster_field_def 标记 sensitive身份证号全角色脱敏前3后3、手机号前3后4、薪资/职级等敏感字段仅 admin/hr 可见dspy 返回前按角色矩阵脱敏。
4. **审计**F12全量写操作记录前后值 JSON、操作人、时间、IP审批、导入导出、登录同样记录可按时间/类型查询。
5. **SQL 注入**:全部经 sqlor 绑定参数dspy 禁止拼接用户输入sqlExe 使用 `${var}$` 占位)。 5. **SQL 注入**:全部经 sqlor 绑定参数dspy 禁止拼接用户输入sqlExe 使用 `${var}$` 占位)。
6. **口令**密码加盐哈希存储appbase users 既有机制NFR-4
7. **API 开放接口鉴权**一期仅规范§9桩路径不注册业务处理注册即按"未启用"拒绝。
## 8. 非功能设计响应 ## 9. API 开放接口规范一期预留FEAT-B1-01⑦
| SRS 非功能项 | 设计响应 | 一期不交付第三方集成,仅交付**鉴权与端点规范**
|---|---|
| 列表响应 ≤500ms | 100 人规模 + 索引设计database-design.md §5列表页分页默认 50组织树一次性加载≤200 节点) |
| 批量导入导出 100 人量级 | openpyxl 同步处理ahserver 已内置),导入走后台任务 + 结果文件下载 |
| 字段/流程/表单自定义 | roster_field_defEAV、flow_form_def/flow_def JSON 化配置,无硬编码 |
| PC 为主 + 员工自助移动端兼容 | 员工自助页面(个人档案/发起审批/待办)使用 ResponsableBox 自适应布局 |
## 9. 配套设计文档 1. **端点形态**`/openapi/v1/{resource}.dspy`resource 规划 `employees|orgs|changes`(员工/组织/异动事件推送),与内部 dspy 同框架。
2. **鉴权方案(二期启用)**app_key + app_secret 签名HMAC-SHA256含时间戳防重放密钥由 admin 在系统管理页生成sys_openapp 表已预留,见 database-design.md §4.5);限流默认 10 req/s/app。
3. **响应契约**:与内部接口一致的 `{status,message,data}` 结构;批量接口统一分页参数 `page/size`size ≤200
4. **数据出口管控**:开放接口同样强制数据范围与脱敏规则,导出字段需在管理端显式授权。
5. **一期落位**:不注册业务端点;`/openapi/v1/ping.dspy` 返回 `{status:'error', code:'NOT_ENABLED'}` 作为桩位,验证路由与鉴权框架可达。
- `database-design.md`v2.0ER、43 张表结构、索引、字典、models JSON 示例、staff-mgr 迁移策略 ## 10. 降级项设计批次1相关SRS §9
- `api-design.md`v2.0dspy 端点清单(约 100 个)、请求/响应、鉴权角色、错误码
- `ui-design.md`v2.0):页面结构、组件树、路由表、核心交互流程 | # | 降级项 | 一期降级方案(设计落点) | 二期预留接口/字段 |
- `iteration1-task-breakdown.md`v1.0可行性分析、风险、开发任务拆解T01~T24 |---|---|---|---|
| D1 | 身份证硬件读卡 | 入职/档案**手工录入**证件信息roster_employee 设 `id_type/id_number_cipher/id_number_hash/id_valid_from/id_valid_to/id_authority/id_source(='manual')`入职审批单与登记表含证件信息分组展示脱敏前3后3 | `id_source` 枚举预留 `card_reader`;读卡硬件对接后经 `roster_employee_update` 回填同一组字段,无需改表 |
| D3 | 钉钉同步/离职资源交接 | 不同步;离职交接项 `org_leave_handover.item_type`**`dingtalk_resource`(占位类型)**,交接内容手工登记;组织/人员无同步入口 | 交接项类型字典可扩展;二期钉钉开放平台对接后 item_type=dingtalk_resource 项改为自动拉取资源清单 |
| D4 | 电子签 | contract_template 按占位符生成合同文本docx/pdf供**打印/下载**contract_text_gen.dspy`contract_info.esign_status` 字段not_enabled+ `esign_stub.dspy` 桩端点返回 NOT_ENABLED | esign_status 状态机not_enabled→signing→signed已定义二期对接电子签平台后流转 |
| D9 | 短信通知渠道 | sys_message.send_channel 一期仅 `site`(站内)生效;提醒/关怀/审批通知全部站内送达;未配置 SMTP 时不尝试邮件 | send_channel 枚举含 `sms/email` 预留位;二期短信网关/SMTP 接入仅扩展发送器 |
| —(扫码入职降级) | 对外渠道扫码入职 | 系统内生成**入职登记链接 + 二维码图片**内网可访问org_entry 增 `register_token/register_url/qrcode_file/register_expire`;候选人扫码填登记表进审批流 | register_url 域名部分走配置项,二期对外渠道启用后切换公网域名 |
| —(考勤流程桩位) | 考勤流程联动 | FEAT-B1-01考勤类表单换班/加班/请假等可建表单定义biz_type=attendance_*),无回写 hook、不联动考勤系统 | flow_def.biz_type 字典预留 attendance_* 值 |
| —(工作台绩效/考勤统计桩位) | 经理/管理员工作台绩效考勤卡片 | F14工作台留"绩效/考勤"桩位卡片,显示"未接入"占位,不取数 | workbench 聚合端点预留 perf/attendance 空结构字段 |
## 11. 非功能设计响应SRS §7
| NFR | 指标 | 设计响应 |
|---|---|---|
| NFR-1 | 列表 ≤500ms报表聚合 ≤3s导入 500 行 ≤30s | 100 人规模 + 索引设计database-design.md §6列表默认分页 50组织树一次性加载≤200 节点);报表直接 SQL 聚合;导入走后台任务 + 结果文件 |
| NFR-2 | 100 账号/并发 30/简历 2 万/花名册 2000 | 单实例 ahserver 异步模型足够;花名册含离职档案 2000 行在索引覆盖下无压力 |
| NFR-3 | 月度可用率 ≥99%,异常自动重启 | systemd Restart=always单实例无状态会话在 Redis |
| NFR-4 | session+rbac/默认拒绝/审计/脱敏/参数绑定/密码哈希 | §8 安全设计逐项覆盖 |
| NFR-5 | 每日全量备份 ≥30 天 | §7.1mysqldump crontab + files/ 目录备份 |
| NFR-6 | Chrome/Edge 最近 2 版;员工自助移动端兼容 | bricks 标准组件兼容;员工自助页面(工作台/档案/待办/服务/消息ResponsableBox 自适应 |
| NFR-7 | ocai 模块结构/配置化/load_xxx 装配 | §3/§5 全栈声明式;表单/流程/字段 JSON 化 |
| NFR-8 | staff-mgr 迁移核对报告 | §6.3 + database-design.md §8总数/抽样一致) |
## 12. 配套设计文档
| 文档 | 版本 | 内容 |
|---|---|---|
| database-design.md | v3.0 | ER、**49 张表**结构(含编制/项目式 6 新表 + sys_openapp 预留、索引、字典、models JSON、staff-mgr 迁移 |
| api-design.md | v3.0 | dspy 端点清单(约 120 个)、请求/响应契约、鉴权角色、错误码、降级桩端点汇总、开放接口规范 |
| ui-design.md | v3.0 | 页面结构、组件树、路由表、核心交互流程、降级项交互说明 |
| iteration1-task-breakdown.md | v2.0 | 可行性分析、风险、开发任务拆解T01~T27面向 develop 角色可直接建任务) |
| feature-list.md | v2.1 | F01~F17 功能清单与 FEAT-B1 映射批次1范围基线 |

View File

@ -1,19 +1,20 @@
# 迭代1总体设计 —— 数据库设计hr-webocai 口径) # 一期批次1总体设计 —— 数据库设计hr-webocai 口径)
- 版本v2.0迭代1-总体设计,取代 v1 Java/JPA 口径v1 已归档至 `docs/_archive/01-design-v1-old/` - 版本v3.0批次1设计定稿v3.0 变更:对齐 SRS v3.1 —— 库名 hrs/MariaDB、新增编制(F16)/项目式(F17) 5 张表与 sys_openapp 预留表43→**49** 张、roster_employee 证件字段扩展D1 手工录入、org_entry 登记链接/二维码字段扫码入职降级、org_leave_handover 钉钉交接占位、字典扩充
- 状态:评审通过主agent评审基线冻结 - 状态:**设计定稿批次1评审修订版**
- 需求基线:`docs/00-requirement/requirement-spec.md`SRS v2+ `iteration1-function-detail.md`F01~F15 - 需求基线:`docs/00-requirement/requirement-spec.md`SRS v3.1+ `iteration1-function-detail.md`F01~F15+ approved-features.mdFEAT-B1-01~12
- 架构基线:`docs/01-design/architecture.md` - 架构基线:`docs/01-design/architecture.md`
- 规范依据ocai 技能集 database-table-definition-specmodels/*.json + json2ddl、crud-definition-spec、sqlor-database-module - 规范依据ocai 技能集 database-table-definition-specmodels/*.json + json2ddl、crud-definition-spec、sqlor-database-module
## 1. 设计总则 ## 1. 设计总则
1. **表定义声明式管理**:所有表以 `models/{table}.json`summary/fields/indexes/codes 四段定义build.sh 中 `json2ddl mysql . > mysql.ddl.sql` 生成 DDL 导入 `hr` 库。本文 DDL 为生成物等价示例,开发以 models JSON 为准。 1. **表定义声明式管理**:所有表以 `models/{table}.json`summary/fields/indexes/codes 四段定义build.sh 中 `json2ddl mysql . > mysql.ddl.sql` 生成 DDL 导入 **hrs** 库。本文 DDL 为生成物等价示例,开发以 models JSON 为准。
2. **统一约定**InnoDButf8mb4 / utf8mb4_unicode_ci主键 `id VARCHAR(32)`getID() 雪花串sqlor 惯例);公共审计列 `created_by/updated_by/created_at/updated_at``sor.C` 不自动填时间戳,写入时显式 `created_at=curDateString()` 2. **统一约定**InnoDButf8mb4 / utf8mb4_unicode_ci数据库 MariaDB库名 `hrs`;主键 `id VARCHAR(32)`getID() 雪花串sqlor 惯例);公共审计列 `created_by/updated_by/created_at/updated_at``sor.C` 不自动填时间戳,写入时显式 `created_at=curDateString()`
3. **逻辑删除策略**迭代1员工与组织**不做物理删除**,统一走"停用(status=inactive)/离职流程"(对 baseline-decision Q6 的裁决落地)。 3. **逻辑删除策略**:员工与组织**不做物理删除**,统一走"停用(status=inactive)/离职流程";物理删除仅 admin 可执行且必须留审计SRS §5.2-2
4. **自定义字段EAV**花名册字段F03与组织字段F01采用"字段定义表 + 字段值表"EAV 方案,支撑字段/分组/类型规则自定义;固定高频查询字段(组织、职位、状态、入离职日期)冗余在员工主表保证列表性能。 4. **自定义字段EAV**花名册字段F03与组织字段F01采用"字段定义表 + 字段值表"EAV 方案;固定高频查询字段(组织、职位、状态、入离职日期)冗余在员工主表保证列表性能。
5. **敏感字段**:身份证号密文列 + 哈希列(确定性,供唯一性与黑名单匹配),手机号明文存储、按角色脱敏展示;`roster_field_def.sensitive` 驱动字段级脱敏与可见性。 5. **敏感字段**:身份证号密文列 + 哈希列(确定性哈希,供唯一性与黑名单匹配),手机号明文存储、按角色脱敏展示;`roster_field_def.sensitive` 驱动字段级脱敏与可见性SRS §2.2-4
6. **库划分**:单库 `hr`,表前缀区分模块:`org_`(hr-org)、`roster_`(hr-roster)、`flow_`(hr-flow)、`contract_`(hr-contract)、`sys_`(hr-system)appbaseusers/orgs/appcodes与 rbac 表沿用基础包自带结构,不在本文重复。 6. **库划分**:单库 `hrs`,表前缀区分模块:`org_`(hr-org)、`roster_`(hr-roster)、`flow_`(hr-flow)、`contract_`(hr-contract)、`sys_`(hr-system)appbaseusers/orgs/appcodes与 rbac 表沿用基础包自带结构,不在本文重复。
7. **预留字段约定**:二期对接预留字段一律带明确默认值与字典枚举位(如 esign_status='not_enabled'、id_source='manual'、send_channel='site'),不参与一期业务分支。
## 2. ER 图(实体关系描述) ## 2. ER 图(实体关系描述)
@ -29,13 +30,13 @@
│ 组织 │ │ │ sys_audit_log │ 操作日志(F12) │ 组织 │ │ │ sys_audit_log │ 操作日志(F12)
└──┬───┬──────┘ │ │ sys_message │ 站内消息(F15) └──┬───┬──────┘ │ │ sys_message │ 站内消息(F15)
│ │org_field_value │ │ sys_remind_rule │ 提醒规则 │ │org_field_value │ │ sys_remind_rule │ 提醒规则
│ ▼ │ └────────▲─────────┘ │ ▼ │ │ sys_openapp │ API开放预留
│ org_field_def │ │ 推送 │ org_field_def │ └────────▲─────────┘
│ │ │ │ │ │ 推送
│ ┌─────────────┐ ┌─────▼───────────────┴───┐ │ ┌─────────────┐ ┌─────▼───────────────┴───┐
│ │org_job/ │ │ roster_employee │ 员工唯一事实源(F03) │ │org_job/ │ │ roster_employee │ 员工唯一事实源(F03)
│ │org_position◄─┼──│ org_id/position_id/ │ │ │org_position◄─┼──│ org_id/position_id/ │
│ │org_sequence/ │ │ employee_status/... │ │org_sequence/ │ │ employee_status/证件字段组
│ │org_grade_* │ └──┬──────┬──────┬─────────┘ │ │org_grade_* │ └──┬──────┬──────┬─────────┘
│ └─────────────┘ │ │ │ │ └─────────────┘ │ │ │
│ │ │ ▼ │ │ │ ▼
@ -48,26 +49,27 @@
│ org_transfer(+detail)│ contract_remind_rule │ org_transfer(+detail)│ contract_remind_rule
│ org_leave(+handover) │ │审批 │ org_leave(+handover) │ │审批
│ org_concurrent_post │ ▼ │ org_concurrent_post │ ▼
│审批流转 │ ┌──────────────┐ org_headcount_scheme │ ┌──────────────┐
└────────┴──────────────┴────►│ flow_def │ 流程定义 │ └ headcount_item │ │ flow_def │ 流程定义
biz_type+biz_id │ flow_form_def│ 表单定义(引用花名册字段) │ └ headcount_snapshot│ │ flow_form_def│ 表单定义(引用花名册字段)
│ flow_node_def│ 节点(审批人/字段权限) │ org_project(F17) │ │ flow_node_def│ 节点(审批人/字段权限)
│ flow_role │ 审批角色 │ └ org_project_post │ │ flow_role │ 审批角色
│ flow_instance│ 实例 ──► flow_task(待办) │ │审批流转 │ │ flow_instance│ 实例 ──► flow_task(待办)
│ │ └► flow_op_log └────────┴──────────────┴────►│ │ └► flow_op_log
└──────────────┘ biz_type+biz_id └──────────────┘
hr-report 无自有表:只读聚合 org_/roster_/flow_ 表,叠加 sys_data_scope 范围过滤。 hr-report 无自有表:只读聚合 org_/roster_/flow_ 表,叠加 sys_data_scope 范围过滤。
``` ```
核心关系说明: 核心关系说明:
- `roster_employee` 为全系统员工数据唯一事实源;`org_entry/regularization/transfer/leave/concurrent_post` 通过 `employee_id`(入职审批阶段可为空)关联,审批通过后经 hr-roster 回写接口更新主档。 - `roster_employee` 为全系统员工数据唯一事实源;`org_entry/regularization/transfer/leave/concurrent_post` 通过 `employee_id`(入职审批阶段可为空)关联,审批通过后经 hr-roster `roster_writeback` 更新主档。
- 所有审批类记录通过 `flow_instance_id` 关联流程实例;`flow_instance.biz_type + biz_id` 反向定位业务单据,流程完成后回调业务模块回写。 - 所有审批类记录通过 `flow_instance_id` 关联流程实例;`flow_instance.biz_type + biz_id` 反向定位业务单据,流程完成后回调业务模块回写。
- `roster_field_value`/`org_field_value` 为 EAV 值表,外键指向 `roster_field_def`/`org_field_def` - **编制F16**`org_headcount_scheme` 1─N `headcount_item`(细分额度);`headcount_snapshot` 按日快照历史;员工异动回写后同步触发占编重算。占编范围条件以 JSON 表达(员工类型/状态/职位/职级/自定义字段),与 roster_employee + roster_field_value 联查计数。
- **项目式组织F17**`org_project` 为横向组织(自引用多层级),员工经 `org_project_post` 同时挂纵向部门roster_employee.org_id与横向项目横向职务体系复用 org_job 表org_job.job_category=horizontal 区分,被花名册/薪酬引用)。
- 所有表与 appbase.users 之间为逻辑外键operator_id/leader_id/approver_id不建物理外键sqlor 惯例,跨模块解耦)。 - 所有表与 appbase.users 之间为逻辑外键operator_id/leader_id/approver_id不建物理外键sqlor 惯例,跨模块解耦)。
## 3. models JSON 示例规范格式json2ddl 输入) ## 3. models JSON 示例规范格式json2ddl 输入)
`hr-roster/models/roster_employee.json` `hr-roster/models/roster_employee.json`(含 D1 证件字段组扩展)
```json ```json
{ {
@ -79,8 +81,13 @@ hr-report 无自有表:只读聚合 org_/roster_/flow_ 表,叠加 sys_data_s
{"name": "employee_no", "title": "工号", "type": "varchar", "length": 32}, {"name": "employee_no", "title": "工号", "type": "varchar", "length": 32},
{"name": "name", "title": "姓名", "type": "varchar", "length": 64}, {"name": "name", "title": "姓名", "type": "varchar", "length": 64},
{"name": "gender", "title": "性别", "type": "varchar", "length": 16}, {"name": "gender", "title": "性别", "type": "varchar", "length": 16},
{"name": "id_type", "title": "证件类型", "type": "varchar", "length": 16, "default": "id_card"},
{"name": "id_number_cipher", "title": "证件号密文", "type": "varchar", "length": 256}, {"name": "id_number_cipher", "title": "证件号密文", "type": "varchar", "length": 256},
{"name": "id_number_hash", "title": "证件号哈希", "type": "varchar", "length": 64}, {"name": "id_number_hash", "title": "证件号哈希", "type": "varchar", "length": 64},
{"name": "id_valid_from", "title": "证件有效期起", "type": "date"},
{"name": "id_valid_to", "title": "证件有效期止(长期=9999-12-31)", "type": "date"},
{"name": "id_authority", "title": "证件签发机关", "type": "varchar", "length": 128},
{"name": "id_source", "title": "证件信息来源", "type": "varchar", "length": 16, "default": "manual"},
{"name": "birthday", "title": "出生日期", "type": "date"}, {"name": "birthday", "title": "出生日期", "type": "date"},
{"name": "phone", "title": "手机号", "type": "varchar", "length": 20}, {"name": "phone", "title": "手机号", "type": "varchar", "length": 20},
{"name": "email", "title": "邮箱", "type": "varchar", "length": 128}, {"name": "email", "title": "邮箱", "type": "varchar", "length": 128},
@ -93,11 +100,13 @@ hr-report 无自有表:只读聚合 org_/roster_/flow_ 表,叠加 sys_data_s
{"name": "employee_type", "title": "员工类型", "type": "varchar", "length": 16}, {"name": "employee_type", "title": "员工类型", "type": "varchar", "length": 16},
{"name": "employee_status", "title": "员工状态", "type": "varchar", "length": 16}, {"name": "employee_status", "title": "员工状态", "type": "varchar", "length": 16},
{"name": "hire_date", "title": "入职日期", "type": "date"}, {"name": "hire_date", "title": "入职日期", "type": "date"},
{"name": "probation_end_date", "title": "试用期止(预计转正日)", "type": "date"},
{"name": "regular_date", "title": "转正日期", "type": "date"}, {"name": "regular_date", "title": "转正日期", "type": "date"},
{"name": "leave_date", "title": "离职日期", "type": "date"}, {"name": "leave_date", "title": "离职日期", "type": "date"},
{"name": "company_id", "title": "合同公司", "type": "varchar", "length": 32}, {"name": "company_id", "title": "合同公司", "type": "varchar", "length": 32},
{"name": "work_location", "title": "办公地点", "type": "varchar", "length": 128}, {"name": "work_location", "title": "办公地点", "type": "varchar", "length": 128},
{"name": "direct_leader_id", "title": "直属主管", "type": "varchar", "length": 32}, {"name": "direct_leader_id", "title": "直属主管", "type": "varchar", "length": 32},
{"name": "prev_employee_id", "title": "复职关联原档案ID", "type": "varchar", "length": 32},
{"name": "remark", "title": "备注", "type": "text"}, {"name": "remark", "title": "备注", "type": "text"},
{"name": "created_by", "title": "创建人", "type": "varchar", "length": 32}, {"name": "created_by", "title": "创建人", "type": "varchar", "length": 32},
{"name": "updated_by", "title": "更新人", "type": "varchar", "length": 32}, {"name": "updated_by", "title": "更新人", "type": "varchar", "length": 32},
@ -110,23 +119,27 @@ hr-report 无自有表:只读聚合 org_/roster_/flow_ 表,叠加 sys_data_s
{"name": "idx_org_id", "fields": ["org_id"]}, {"name": "idx_org_id", "fields": ["org_id"]},
{"name": "idx_status", "fields": ["employee_status"]}, {"name": "idx_status", "fields": ["employee_status"]},
{"name": "idx_hire_date", "fields": ["hire_date"]}, {"name": "idx_hire_date", "fields": ["hire_date"]},
{"name": "idx_direct_leader", "fields": ["direct_leader_id"]} {"name": "idx_probation_end", "fields": ["probation_end_date"]},
{"name": "idx_direct_leader", "fields": ["direct_leader_id"]},
{"name": "idx_prev_employee", "fields": ["prev_employee_id"]}
], ],
"codes": [ "codes": [
{"name": "gender", "source": "appcodes", "code": "GENDER"}, {"name": "gender", "source": "appcodes", "code": "GENDER"},
{"name": "employee_type", "source": "appcodes", "code": "EMP_TYPE"}, {"name": "employee_type", "source": "appcodes", "code": "EMP_TYPE"},
{"name": "employee_status", "source": "appcodes", "code": "EMP_STATUS"} {"name": "employee_status", "source": "appcodes", "code": "EMP_STATUS"},
{"name": "id_source", "source": "appcodes", "code": "ID_SOURCE"}
] ]
} }
``` ```
CRUD 侧配套 `hr-roster/json/roster_employee_list.json`crud-definition-spec`tblname=roster_employee``params` 顶层配置 `new_data_url/update_data_url/delete_data_url` 指向 `wwwroot/api/roster_employee_{create,update,delete}.dspy``data_filter` 声明姓名/工号/组织/状态筛选项,`browserfields.alters` 引用 GENDER/EMP_TYPE/EMP_STATUS 字典。 CRUD 侧配套 `hr-roster/json/roster_employee_list.json`crud-definition-spec`tblname=roster_employee``params` 顶层配置 `new_data_url/update_data_url/delete_data_url` 指向 `wwwroot/api/roster_employee_{create,update,delete}.dspy``data_filter` 声明姓名/工号/组织/状态筛选项,`browserfields.alters` 引用 GENDER/EMP_TYPE/EMP_STATUS 字典。
## 4. 表结构设计43 张业务表) ## 4. 表结构设计49 张业务表)
> 公共列约定:凡标【审计】的表均含 `created_by/updated_by/created_at/updated_at`;日志类表仅含 `created_at`。DDL 示例见 §4.6。 > 公共列约定:凡标【审计】的表均含 `created_by/updated_by/created_at/updated_at`;日志/快照类表仅含 `created_at`。DDL 示例见 §5。
> v3.0 变化hr-org 18→23+编制 3 表+项目式 2 表、hr-system 7→8+sys_openapp 预留、roster_employee/org_entry/org_leave_handover 字段扩展;合计 **49 张**
### 4.1 hr-org 组织人事(18 张,前缀 org_ ### 4.1 hr-org 组织人事(23 张,前缀 org_
| # | 表 | 用途 | 关键字段 | 关键索引 | | # | 表 | 用途 | 关键字段 | 关键索引 |
|---|---|---|---|---| |---|---|---|---|---|
@ -134,77 +147,88 @@ CRUD 侧配套 `hr-roster/json/roster_employee_list.json`crud-definition-spec
| 2 | org_unit_change | 组织变更时间轴F01 | id, org_id, change_type(add/edit/disable/move/split/merge/delete), before_json, after_json, effective_date, operator_id, flow_instance_id, created_at | idx_org_id; idx_created_at | | 2 | org_unit_change | 组织变更时间轴F01 | id, org_id, change_type(add/edit/disable/move/split/merge/delete), before_json, after_json, effective_date, operator_id, flow_instance_id, created_at | idx_org_id; idx_created_at |
| 3 | org_field_def | 组织自定义字段F01 | id, field_code, field_name, field_type(text/number/date/select/file), options_json, required, sort_no, status【审计】 | uk_field_code | | 3 | org_field_def | 组织自定义字段F01 | id, field_code, field_name, field_type(text/number/date/select/file), options_json, required, sort_no, status【审计】 | uk_field_code |
| 4 | org_field_value | 组织字段值 EAV | id, org_id, field_id, value_text, value_date, value_file, updated_at | uk(org_id,field_id) | | 4 | org_field_value | 组织字段值 EAV | id, org_id, field_id, value_text, value_date, value_file, updated_at | uk(org_id,field_id) |
| 5 | org_job | 职务F02 | id, job_code, job_name, status, sort_no, remark【审计】 | uk_job_code | | 5 | org_job | 职务F02/F17 | id, job_code, job_name, job_category(vertical/horizontalF17 横向职务), status, sort_no, remark【审计】 | uk_job_code; idx_job_category |
| 6 | org_position | 职位F02 | id, position_code, position_name, job_id, sequence_id, category(字典POS_CATEGORY), dept_ids(多值,逗号分隔), description, status, sort_no【审计】 | uk_position_code; idx_job_id | | 6 | org_position | 职位F02 | id, position_code, position_name, job_id, sequence_id, category(字典POS_CATEGORY), dept_ids(多值,逗号分隔), description, status, sort_no【审计】 | uk_position_code; idx_job_id |
| 7 | org_sequence | 序列F02 | id, seq_category, seq_name, grade_level_ids(关联职级类别), status【审计】 | — | | 7 | org_sequence | 序列F02 | id, seq_category, seq_name, grade_level_ids(关联职级类别), status【审计】 | — |
| 8 | org_grade_level | 职级F02 | id, level_code, level_name, level_category, start_rank_id, end_rank_id, sort_no【审计】 | uk_level_code | | 8 | org_grade_level | 职级F02 | id, level_code, level_name, level_category, start_rank_id, end_rank_id, sort_no【审计】 | uk_level_code |
| 9 | org_grade_rank | 职等F02 | id, rank_code, rank_name, rank_level(int), sort_no【审计】 | uk_rank_code | | 9 | org_grade_rank | 职等F02 | id, rank_code, rank_name, rank_level(int), sort_no【审计】 | uk_rank_code |
| 10 | org_blacklist | 黑名单F04/F07 | id, name, id_number_hash, id_number_cipher, reason, source(leave/manual), source_employee_id, created_by, created_at | idx_id_number_hash | | 10 | org_blacklist | 黑名单F04/F07 | id, name, id_number_hash, id_number_cipher, reason, source(leave/manual), source_employee_id, created_by, created_at | idx_id_number_hash |
| 11 | org_contract_company | 合同公司F01/F09 | id, company_code, company_name, credit_code, legal_person, contact_info, status【审计】 | uk_company_code | | 11 | org_contract_company | 合同公司F01/F09 | id, company_code, company_name, credit_code(统一社会信用代码), legal_person, contact_info, status【审计】 | uk_company_code |
| 12 | org_entry | 入职记录F04 | id, employee_id(可空,待入职), name, id_number_cipher/hash, employee_type, org_id, position_id, company_id, work_location, hire_date, entry_status(pending_approval/pending_entry/entered/cancelled/blocked), is_rehire, register_status(登记表填写状态), flow_instance_id, remark【审计】 | idx_entry_status; idx_hire_date; idx_flow_instance_id | | 12 | org_entry | 入职记录F04 | id, employee_id(可空,待入职), name, id_type, id_number_cipher/hash, id_valid_from/id_valid_to/id_authority/id_source(手工录入 D1), employee_type, org_id, position_id, company_id, work_location, hire_date, entry_status(pending_approval/pending_entry/entered/cancelled/blocked), is_rehire, register_status(none/invited/filled), **register_token, register_url, qrcode_file, register_expire**(登记链接/二维码,扫码入职降级), flow_instance_id, remark【审计】 | idx_entry_status; idx_hire_date; idx_flow_instance_id; uk_register_token |
| 13 | org_regularization | 转正记录F05 | id, employee_id, probation_end_date, regular_date, apply_type(self/proxy/manual), status(pending/approved/rejected/cancelled), flow_instance_id, remark【审计】 | idx_employee_id; idx_regular_date | | 13 | org_regularization | 转正记录F05 | id, employee_id, probation_end_date, regular_date, apply_type(self/proxy/manual), status(pending/approved/rejected/cancelled), flow_instance_id, remark【审计】 | idx_employee_id; idx_regular_date |
| 14 | org_transfer | 调动单F06支持批量 | id, transfer_type(promotion/demotion/position_change/org_adjust), status(pending/confirmed/cancelled), effective_date, batch_no, flow_instance_id, remark【审计】 | idx_status; idx_effective_date | | 14 | org_transfer | 调动单F06支持批量 | id, transfer_type(promotion/demotion/position_change/org_adjust), status(pending/confirmed/cancelled), effective_date, batch_no, flow_instance_id, remark【审计】 | idx_status; idx_effective_date |
| 15 | org_transfer_detail | 调动明细(逐人) | id, transfer_id, employee_id, from_org_id, to_org_id, from_position_id, to_position_id, from_grade_level_id, to_grade_level_id, status | idx_transfer_id; idx_employee_id | | 15 | org_transfer_detail | 调动明细(逐人) | id, transfer_id, employee_id, from_org_id, to_org_id, from_position_id, to_position_id, from_grade_level_id, to_grade_level_id, status | idx_transfer_id; idx_employee_id |
| 16 | org_leave | 离职记录F07 | id, employee_id, leave_type(辞职/劝退/合同到期/退休), leave_reason(字典LEAVE_REASON), leave_date, apply_type(self/proxy/manual), status(pending_leave/left/cancelled), handover_status, certificate_file, blacklist_flag, flow_instance_id, remark【审计】 | idx_employee_id; idx_status; idx_leave_date | | 16 | org_leave | 离职记录F07 | id, employee_id, leave_type(辞职/劝退/合同到期/退休), leave_reason(字典LEAVE_REASON), leave_date, apply_type(self/proxy/manual), status(pending_leave/left/cancelled), handover_status, certificate_file, blacklist_flag, flow_instance_id, remark【审计】 | idx_employee_id; idx_status; idx_leave_date |
| 17 | org_leave_handover | 离职交接项 | id, leave_id, item_type(approval/file/subordinate/permission/other), item_content, handover_to_id, status(pending/done), remark | idx_leave_id | | 17 | org_leave_handover | 离职交接项 | id, leave_id, item_type(approval/file/subordinate/permission/**dingtalk_resource(钉钉资源交接占位,D3)**/other), item_content, handover_to_id, status(pending/done), remark | idx_leave_id |
| 18 | org_concurrent_post | 兼岗F08 | id, employee_id, org_id, position_id, start_date, end_date, status(awaiting/active/expired), flow_instance_id【审计】 | idx_employee_id; idx_status | | 18 | org_concurrent_post | 兼岗F08 | id, employee_id, org_id, position_id, start_date, end_date, status(awaiting/active/expired), flow_instance_id【审计】 | idx_employee_id; idx_status |
| 19 | org_headcount_scheme | 编制方案F16 | id, scheme_name, cycle_type(year/quarter/month字典HEADCOUNT_CYCLE), cycle_start, cycle_end, status(active/inactive), remark【审计】 | idx_cycle(cycle_start,cycle_end); idx_status |
| 20 | headcount_item | 编制细分项F16 | id, scheme_id, scope_json(占编范围:员工类型/状态/职位/职级/自定义字段条件), seg_json(细分维度,可空=整体), head_limit(int), remark【审计】 | idx_scheme_id |
| 21 | headcount_snapshot | 编制快照F16 历史回溯/实时计数) | id, scheme_id, item_id, snap_date, used_count(int), over_count(int超编数), created_at | uk(scheme_id,item_id,snap_date); idx_snap_date |
| 22 | org_project | 项目式组织F17 | id, project_code, project_name, parent_id(自引用多层级), owner_id(负责人), start_date, end_date, project_status(active/expired/inactive), attrs_json(项目属性), sort_no【审计】 | uk_project_code; idx_parent_id; idx_project_status |
| 23 | org_project_post | 项目任职F17 员工挂横向组织) | id, project_id, employee_id, job_id(横向职务,引用 org_job job_category=horizontal), start_date, end_date, status(active/expired)【审计】 | uk(project_id,employee_id,job_id,start_date); idx_employee_id |
### 4.2 hr-roster 花名册7 张,前缀 roster_ ### 4.2 hr-roster 花名册7 张,前缀 roster_
| # | 表 | 用途 | 关键字段 | 关键索引 | | # | 表 | 用途 | 关键字段 | 关键索引 |
|---|---|---|---|---| |---|---|---|---|---|
| 19 | roster_field_group | 字段分组F03 | id, group_code, group_name(工作信息/个人信息/绩效结果/培训记录), sort_no, status【审计】 | uk_group_code | | 24 | roster_field_group | 字段分组F03 | id, group_code, group_name(工作信息/个人信息/绩效结果/培训记录), sort_no, status【审计】 | uk_group_code |
| 20 | roster_field_def | 字段定义F03 核心) | id, group_id, field_code, field_name, field_type(text/number/date/select/multiselect/file), options_json(字典code或自定义项), required, sensitive(0/1), editable_self(0/1), need_audit(0/1自助修改审核), apply_types(JSON适用员工类型), sort_no, status【审计】 | uk_field_code; idx_group_id | | 25 | roster_field_def | 字段定义F03 核心) | id, group_id, field_code, field_name, field_type(text/number/date/select/multiselect/file), options_json(字典code或自定义项), required, sensitive(0/1), editable_self(0/1), need_audit(0/1自助修改审核), apply_types(JSON适用员工类型), sort_no, status【审计】 | uk_field_code; idx_group_id |
| 21 | roster_employee | 员工主档F03 | 见 §3 models 示例 | 见 §3 | | 26 | roster_employee | 员工主档F03 | 见 §3 models 示例(含证件字段组/probation_end_date/prev_employee_id | 见 §3 |
| 22 | roster_field_value | 字段值 EAV | id, employee_id, field_id, value_text, value_number(decimal(18,4)), value_date, value_file, updated_by, updated_at | uk(employee_id,field_id); idx_field_id | | 27 | roster_field_value | 字段值 EAV | id, employee_id, field_id, value_text, value_number(decimal(18,4)), value_date, value_file, updated_by, updated_at | uk(employee_id,field_id); idx_field_id |
| 23 | roster_empno_rule | 工号规则F03 | id, rule_name, prefix, match_field(如company_id), match_value, seq_length, current_seq(int), status【审计】 | — | | 28 | roster_empno_rule | 工号规则F03 | id, rule_name, prefix, match_field(如company_id), match_value, seq_length, current_seq(int), status【审计】 | — |
| 24 | roster_timeline | 员工时间轴F03/F12 联动) | id, employee_id, event_type(entry/regular/transfer/leave/concurrent/contract/field_change/migrate), event_date, title, content_json, source_type, source_id, created_at | idx_emp_date(employee_id,event_date) | | 29 | roster_timeline | 员工时间轴F03/F12 联动) | id, employee_id, event_type(entry/regular/transfer/leave/concurrent/contract/field_change/headcount/project/migrate), event_date, title, content_json, source_type, source_id, created_at | idx_emp_date(employee_id,event_date) |
| 25 | roster_type_rule | 员工类型字段规则F03 分类管理) | id, employee_type, field_rules_json(按类型必填/隐藏字段), status【审计】 | uk(employee_type) | | 30 | roster_type_rule | 员工类型字段规则F03 分类管理) | id, employee_type, field_rules_json(按类型必填/隐藏字段), status【审计】 | uk(employee_type) |
### 4.3 hr-flow 流程审批7 张,前缀 flow_ ### 4.3 hr-flow 流程审批7 张,前缀 flow_
| # | 表 | 用途 | 关键字段 | 关键索引 | | # | 表 | 用途 | 关键字段 | 关键索引 |
|---|---|---|---|---| |---|---|---|---|---|
| 26 | flow_form_def | 表单定义F10 | id, form_code, form_name, biz_type(entry/regular/transfer/leave/handover/concurrent/contract_sign/contract_renew/contract_change/contract_stop/roster_self_edit), fields_json(引用roster_field_def或自定义项), status【审计】 | uk_form_code | | 31 | flow_form_def | 表单定义F10 | id, form_code, form_name, biz_type(entry/regular/transfer/leave/handover/concurrent/contract_sign/contract_renew/contract_change/contract_stop/roster_self_edit/**attendance_\*桩位**), fields_json(引用roster_field_def或自定义项), status【审计】 | uk_form_code |
| 27 | flow_def | 流程定义F10 | id, flow_code, flow_name, form_id, biz_type, match_cond_json(员工类型/部门匹配条件), version, status【审计】 | uk_flow_code; idx_biz_type | | 32 | flow_def | 流程定义F10 | id, flow_code, flow_name, form_id, biz_type, match_cond_json(员工类型/部门匹配条件), version, status【审计】 | uk_flow_code; idx_biz_type |
| 28 | flow_node_def | 流程节点 | id, flow_id, node_seq, node_name, approver_type(user/role/leader/admin/flow_role), approver_value, pass_rule(any/all), field_perm_json(节点字段可读写), cc_to(抄送) | idx_flow_id | | 33 | flow_node_def | 流程节点 | id, flow_id, node_seq, node_name, approver_type(user/role/leader/admin/flow_role), approver_value, pass_rule(any/all), field_perm_json(节点字段可读写), cc_to(抄送) | idx_flow_id |
| 29 | flow_role | 审批角色F10 | id, role_name, flow_scope_json(可用流程), op_perm_json(操作权限), data_scope_json(数据查看范围), status【审计】 | — | | 34 | flow_role | 审批角色F10 | id, role_name, flow_scope_json(可用流程), op_perm_json(操作权限), data_scope_json(数据查看范围), status【审计】 | — |
| 30 | flow_instance | 流程实例 | id, inst_no(审批编号), flow_id, form_id, biz_type, biz_id, title, initiator_id, inst_status(running/approved/rejected/cancelled), submit_data_json, start_time, finish_time | uk_inst_no; idx_biz(biz_type,biz_id); idx_initiator; idx_status | | 35 | flow_instance | 流程实例 | id, inst_no(审批编号), flow_id, form_id, biz_type, biz_id, title, initiator_id, inst_status(running/approved/rejected/cancelled), submit_data_json, start_time, finish_time | uk_inst_no; idx_biz(biz_type,biz_id); idx_initiator; idx_status |
| 31 | flow_task | 审批任务(待办/已办) | id, instance_id, node_id, node_name, approver_id, task_status(pending/approved/rejected/forwarded/cancelled), comment, handle_time, created_at | idx_approver_status(approver_id,task_status); idx_instance | | 36 | flow_task | 审批任务(待办/已办) | id, instance_id, node_id, node_name, approver_id, task_status(pending/approved/rejected/forwarded/cancelled), comment, handle_time, created_at | idx_approver_status(approver_id,task_status); idx_instance |
| 32 | flow_op_log | 流转日志 | id, instance_id, op_type(submit/approve/reject/forward/cancel/withdraw), operator_id, comment, created_at | idx_instance | | 37 | flow_op_log | 流转日志 | id, instance_id, op_type(submit/approve/reject/forward/cancel/withdraw), operator_id, comment, created_at | idx_instance |
### 4.4 hr-contract 合同4 张,前缀 contract_ ### 4.4 hr-contract 合同4 张,前缀 contract_
| # | 表 | 用途 | 关键字段 | 关键索引 | | # | 表 | 用途 | 关键字段 | 关键索引 |
|---|---|---|---|---| |---|---|---|---|---|
| 33 | contract_type | 合同类型F09 自定义) | id, type_code, type_name(劳动合同/保密协议/竞业协议…), status【审计】 | uk_type_code | | 38 | contract_type | 合同类型F09 自定义) | id, type_code, type_name(劳动合同/保密协议/竞业协议…), status【审计】 | uk_type_code |
| 34 | contract_template | 合同模板F09 | id, template_name, type_id, file_path, field_marks_json(占位符映射), status【审计】 | — | | 39 | contract_template | 合同模板F09 | id, template_name, type_id, file_path, field_marks_json(占位符映射), status【审计】 | — |
| 35 | contract_info | 合同台账F09 | id, contract_no, employee_id, type_id, company_id, template_id, start_date, end_date, sign_date, contract_status(active/expired/stopped/renewing), file_path, flow_instance_id, remind_rule_id, esign_status(预留), remark【审计】 | idx_employee; idx_end_date; idx_status | | 40 | contract_info | 合同台账F09 | id, contract_no, employee_id, type_id, company_id, template_id, start_date, end_date, sign_date, contract_status(active/expired/stopped/renewing), file_path, text_file_path(模板生成合同文本,D4), flow_instance_id, remind_rule_id, esign_status(not_enabled/待二期流转,D4), remark【审计】 | idx_employee; idx_end_date; idx_status |
| 36 | contract_remind_rule | 到期提醒规则F09 | id, rule_name, days_before(int), target_role(self/leader/hr), content_template, status【审计】 | — | | 41 | contract_remind_rule | 到期提醒规则F09 | id, rule_name, days_before(int), target_role(self/leader/hr), content_template, status【审计】 | — |
### 4.5 hr-system 权限日志与通用服务(7 张,前缀 sys_ ### 4.5 hr-system 权限日志与通用服务(8 张,前缀 sys_
| # | 表 | 用途 | 关键字段 | 关键索引 | | # | 表 | 用途 | 关键字段 | 关键索引 |
|---|---|---|---|---| |---|---|---|---|---|
| 37 | sys_data_scope | 数据范围F11 | id, admin_user_id(管理员), scope_type(org/field), org_ids_json(组织维度,含子树), field_ids_json(花名册字段维度), remark【审计】 | idx_admin_user | | 42 | sys_data_scope | 数据范围F11 | id, admin_user_id(管理员), scope_type(org/field), org_ids_json(组织维度,含子树), field_ids_json(花名册字段维度), remark【审计】 | idx_admin_user |
| 38 | sys_audit_log | 操作日志F12只增不改 | id, module, target_type, target_id, operation(create/update/delete/import/export/approve/login), operator_id, operator_name, before_json, after_json, request_ip, created_at | idx_target(target_type,target_id); idx_operator; idx_created_at; idx_module_op(module,operation) | | 43 | sys_audit_log | 操作日志F12只增不改 | id, module, target_type, target_id, operation(create/update/delete/import/export/approve/login/migrate), operator_id, operator_name, before_json, after_json, request_ip, created_at | idx_target(target_type,target_id); idx_operator; idx_created_at; idx_module_op(module,operation) |
| 39 | sys_message | 站内消息F15 | id, receiver_id, msg_type(todo/approval/remind/care/notice), title, content, biz_type, biz_id, send_channel(site; sms/email预留), is_read, created_at | idx_receiver_read(receiver_id,is_read); idx_created_at | | 44 | sys_message | 站内消息F15 | id, receiver_id, msg_type(todo/approval/remind/care/notice), title, content, biz_type, biz_id, send_channel(site; sms/email预留 D9), is_read, created_at | idx_receiver_read(receiver_id,is_read); idx_created_at |
| 40 | sys_remind_rule | 通用提醒规则F12 场景) | id, scene_code(entry/regular/leave/retire/contract_expire/health_cert/social_insurance/custom), rule_name, days_before, content_template, target_role(admin/employee/leader), status【审计】 | uk(scene_code,rule_name) | | 45 | sys_remind_rule | 通用提醒规则F15 多场景) | id, scene_code(entry/regular/leave/retire/contract_expire/health_cert/social_insurance/custom), rule_name, days_before, content_template, target_role(admin/employee/leader), status【审计】 | uk(scene_code,rule_name) |
| 41 | sys_announcement | 企业公告F15 | id, title, content, publish_scope_json, publish_time, status(draft/published/offline), created_by【审计】 | idx_status | | 46 | sys_announcement | 企业公告F15 | id, title, content, publish_scope_json, publish_time, status(draft/published/offline), created_by【审计】 | idx_status |
| 42 | sys_policy | 企业政策F15 | id, title, file_path, view_scope_json, downloadable(0/1), publish_time, status, created_by【审计】 | idx_status | | 47 | sys_policy | 企业政策F15 | id, title, file_path, view_scope_json, downloadable(0/1), publish_time, status, created_by【审计】 | idx_status |
| 43 | sys_care_config | 关怀配置F15 生日/周年) | id, care_type(birthday/anniversary), template, enable(0/1), push_target(employee/leader), updated_by, updated_at | uk_care_type | | 48 | sys_care_config | 关怀配置F15 生日/周年) | id, care_type(birthday/anniversary), template, enable(0/1), push_target(employee/leader), updated_by, updated_at | uk_care_type |
| 49 | sys_openapp | API 开放应用一期预留FEAT-B1-01⑦ | id, app_key, app_secret_cipher, app_name, scope_json(授权资源), rate_limit(int), status(active/inactive)【审计】 | uk_app_key |
### 4.6 核心表 DDL 示例json2ddl 生成等价物) ## 5. 核心表 DDL 示例json2ddl 生成等价物)
```sql ```sql
-- roster_employee完整 DDL 见 §3 models JSON -- roster_employee完整字段见 §3 models JSON此处为等价 DDL 含证件字段组
CREATE TABLE roster_employee ( CREATE TABLE roster_employee (
id VARCHAR(32) NOT NULL COMMENT '主键', id VARCHAR(32) NOT NULL COMMENT '主键',
employee_no VARCHAR(32) NOT NULL COMMENT '工号', employee_no VARCHAR(32) NOT NULL COMMENT '工号',
name VARCHAR(64) NOT NULL COMMENT '姓名', name VARCHAR(64) NOT NULL COMMENT '姓名',
gender VARCHAR(16) DEFAULT NULL COMMENT '性别(字典GENDER)', gender VARCHAR(16) DEFAULT NULL COMMENT '性别(字典GENDER)',
id_type VARCHAR(16) DEFAULT 'id_card' COMMENT '证件类型',
id_number_cipher VARCHAR(256) DEFAULT NULL COMMENT '证件号密文', id_number_cipher VARCHAR(256) DEFAULT NULL COMMENT '证件号密文',
id_number_hash VARCHAR(64) DEFAULT NULL COMMENT '证件号哈希(唯一)', id_number_hash VARCHAR(64) DEFAULT NULL COMMENT '证件号哈希(唯一)',
id_valid_from DATE DEFAULT NULL COMMENT '证件有效期起',
id_valid_to DATE DEFAULT NULL COMMENT '证件有效期止(长期=9999-12-31)',
id_authority VARCHAR(128) DEFAULT NULL COMMENT '证件签发机关',
id_source VARCHAR(16) DEFAULT 'manual' COMMENT '证件来源(字典ID_SOURCE: manual/card_reader预留)',
birthday DATE DEFAULT NULL, birthday DATE DEFAULT NULL,
phone VARCHAR(20) DEFAULT NULL, phone VARCHAR(20) DEFAULT NULL,
email VARCHAR(128) DEFAULT NULL, email VARCHAR(128) DEFAULT NULL,
@ -217,23 +241,25 @@ CREATE TABLE roster_employee (
employee_type VARCHAR(16) DEFAULT NULL COMMENT '员工类型(字典EMP_TYPE)', employee_type VARCHAR(16) DEFAULT NULL COMMENT '员工类型(字典EMP_TYPE)',
employee_status VARCHAR(16) DEFAULT NULL COMMENT '状态(字典EMP_STATUS)', employee_status VARCHAR(16) DEFAULT NULL COMMENT '状态(字典EMP_STATUS)',
hire_date DATE DEFAULT NULL, hire_date DATE DEFAULT NULL,
probation_end_date DATE DEFAULT NULL COMMENT '试用期止(预计转正日,转正提醒依据)',
regular_date DATE DEFAULT NULL, regular_date DATE DEFAULT NULL,
leave_date DATE DEFAULT NULL, leave_date DATE DEFAULT NULL,
company_id VARCHAR(32) DEFAULT NULL COMMENT '合同公司', company_id VARCHAR(32) DEFAULT NULL COMMENT '合同公司',
work_location VARCHAR(128) DEFAULT NULL, work_location VARCHAR(128) DEFAULT NULL,
direct_leader_id VARCHAR(32) DEFAULT NULL COMMENT '直属主管', direct_leader_id VARCHAR(32) DEFAULT NULL COMMENT '直属主管',
prev_employee_id VARCHAR(32) DEFAULT NULL COMMENT '复职关联原档案ID(F04-5)',
remark TEXT DEFAULT NULL, remark TEXT DEFAULT NULL,
created_by VARCHAR(32) DEFAULT NULL, created_by VARCHAR(32) DEFAULT NULL, updated_by VARCHAR(32) DEFAULT NULL,
updated_by VARCHAR(32) DEFAULT NULL, created_at TIMESTAMP NULL DEFAULT NULL, updated_at TIMESTAMP NULL DEFAULT NULL,
created_at TIMESTAMP NULL DEFAULT NULL,
updated_at TIMESTAMP NULL DEFAULT NULL,
PRIMARY KEY (id), PRIMARY KEY (id),
UNIQUE KEY uk_employee_no (employee_no), UNIQUE KEY uk_employee_no (employee_no),
UNIQUE KEY uk_id_number_hash (id_number_hash), UNIQUE KEY uk_id_number_hash (id_number_hash),
KEY idx_org_id (org_id), KEY idx_org_id (org_id),
KEY idx_status (employee_status), KEY idx_status (employee_status),
KEY idx_hire_date (hire_date), KEY idx_hire_date (hire_date),
KEY idx_direct_leader (direct_leader_id) KEY idx_probation_end (probation_end_date),
KEY idx_direct_leader (direct_leader_id),
KEY idx_prev_employee (prev_employee_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='员工主档'; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='员工主档';
CREATE TABLE org_unit ( CREATE TABLE org_unit (
@ -260,7 +286,8 @@ CREATE TABLE flow_instance (
id VARCHAR(32) NOT NULL, id VARCHAR(32) NOT NULL,
inst_no VARCHAR(32) NOT NULL COMMENT '审批编号', inst_no VARCHAR(32) NOT NULL COMMENT '审批编号',
flow_id VARCHAR(32) NOT NULL, form_id VARCHAR(32) NOT NULL, flow_id VARCHAR(32) NOT NULL, form_id VARCHAR(32) NOT NULL,
biz_type VARCHAR(32) NOT NULL COMMENT '业务类型', biz_id VARCHAR(32) DEFAULT NULL COMMENT '业务单据ID', biz_type VARCHAR(32) NOT NULL COMMENT '业务类型(字典FLOW_BIZ_TYPE)',
biz_id VARCHAR(32) DEFAULT NULL COMMENT '业务单据ID',
title VARCHAR(256) DEFAULT NULL, title VARCHAR(256) DEFAULT NULL,
initiator_id VARCHAR(32) NOT NULL, initiator_id VARCHAR(32) NOT NULL,
inst_status VARCHAR(16) NOT NULL DEFAULT 'running' COMMENT 'running/approved/rejected/cancelled', inst_status VARCHAR(16) NOT NULL DEFAULT 'running' COMMENT 'running/approved/rejected/cancelled',
@ -278,7 +305,7 @@ CREATE TABLE sys_audit_log (
module VARCHAR(32) NOT NULL COMMENT 'hr-org/hr-roster/...', module VARCHAR(32) NOT NULL COMMENT 'hr-org/hr-roster/...',
target_type VARCHAR(32) NOT NULL COMMENT 'roster_employee/org_unit/...', target_type VARCHAR(32) NOT NULL COMMENT 'roster_employee/org_unit/...',
target_id VARCHAR(32) NOT NULL, target_id VARCHAR(32) NOT NULL,
operation VARCHAR(16) NOT NULL COMMENT 'create/update/delete/import/export/approve/login', operation VARCHAR(16) NOT NULL COMMENT 'create/update/delete/import/export/approve/login/migrate',
operator_id VARCHAR(32) NOT NULL, operator_name VARCHAR(64) DEFAULT '', operator_id VARCHAR(32) NOT NULL, operator_name VARCHAR(64) DEFAULT '',
before_json TEXT DEFAULT NULL COMMENT '变更前快照', before_json TEXT DEFAULT NULL COMMENT '变更前快照',
after_json TEXT DEFAULT NULL COMMENT '变更后快照', after_json TEXT DEFAULT NULL COMMENT '变更后快照',
@ -290,17 +317,92 @@ CREATE TABLE sys_audit_log (
KEY idx_created_at (created_at), KEY idx_created_at (created_at),
KEY idx_module_op (module, operation) KEY idx_module_op (module, operation)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='操作日志(只增)'; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='操作日志(只增)';
-- F16 编制管理(新增)
CREATE TABLE org_headcount_scheme (
id VARCHAR(32) NOT NULL,
scheme_name VARCHAR(128) NOT NULL COMMENT '方案名称',
cycle_type VARCHAR(16) NOT NULL COMMENT '周期(字典HEADCOUNT_CYCLE: year/quarter/month)',
cycle_start DATE NOT NULL, cycle_end DATE NOT NULL,
status VARCHAR(16) NOT NULL DEFAULT 'active',
remark TEXT DEFAULT NULL,
created_by VARCHAR(32) DEFAULT NULL, updated_by VARCHAR(32) DEFAULT NULL,
created_at TIMESTAMP NULL DEFAULT NULL, updated_at TIMESTAMP NULL DEFAULT NULL,
PRIMARY KEY (id),
KEY idx_cycle (cycle_start, cycle_end),
KEY idx_status (status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='编制方案';
CREATE TABLE headcount_item (
id VARCHAR(32) NOT NULL,
scheme_id VARCHAR(32) NOT NULL COMMENT '编制方案',
scope_json TEXT NOT NULL COMMENT '占编范围条件(员工类型/状态/职位/职级/自定义字段)',
seg_json TEXT DEFAULT NULL COMMENT '细分维度(空=整体)',
head_limit INT NOT NULL DEFAULT 0 COMMENT '编制数量',
remark TEXT DEFAULT NULL,
created_by VARCHAR(32) DEFAULT NULL, updated_by VARCHAR(32) DEFAULT NULL,
created_at TIMESTAMP NULL DEFAULT NULL, updated_at TIMESTAMP NULL DEFAULT NULL,
PRIMARY KEY (id),
KEY idx_scheme_id (scheme_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='编制细分项';
CREATE TABLE headcount_snapshot (
id VARCHAR(32) NOT NULL,
scheme_id VARCHAR(32) NOT NULL,
item_id VARCHAR(32) NOT NULL COMMENT '细分项',
snap_date DATE NOT NULL COMMENT '快照日期',
used_count INT NOT NULL DEFAULT 0 COMMENT '占编人数',
over_count INT NOT NULL DEFAULT 0 COMMENT '超编数(0=未超编)',
created_at TIMESTAMP NULL DEFAULT NULL,
PRIMARY KEY (id),
UNIQUE KEY uk_scheme_item_date (scheme_id, item_id, snap_date),
KEY idx_snap_date (snap_date)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='编制快照(历史回溯)';
-- F17 项目式组织(新增)
CREATE TABLE org_project (
id VARCHAR(32) NOT NULL,
project_code VARCHAR(32) NOT NULL COMMENT '项目编码',
project_name VARCHAR(128) NOT NULL COMMENT '项目名称',
parent_id VARCHAR(32) DEFAULT NULL COMMENT '上级项目(多层级)',
owner_id VARCHAR(32) DEFAULT NULL COMMENT '负责人',
start_date DATE DEFAULT NULL, end_date DATE DEFAULT NULL COMMENT '时间范围',
project_status VARCHAR(16) NOT NULL DEFAULT 'active' COMMENT 'active/expired/inactive(到期自动标识)',
attrs_json TEXT DEFAULT NULL COMMENT '项目属性',
sort_no INT DEFAULT 0,
created_by VARCHAR(32) DEFAULT NULL, updated_by VARCHAR(32) DEFAULT NULL,
created_at TIMESTAMP NULL DEFAULT NULL, updated_at TIMESTAMP NULL DEFAULT NULL,
PRIMARY KEY (id),
UNIQUE KEY uk_project_code (project_code),
KEY idx_parent_id (parent_id),
KEY idx_project_status (project_status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='项目式组织';
CREATE TABLE org_project_post (
id VARCHAR(32) NOT NULL,
project_id VARCHAR(32) NOT NULL COMMENT '项目组织',
employee_id VARCHAR(32) NOT NULL COMMENT '员工',
job_id VARCHAR(32) DEFAULT NULL COMMENT '横向职务(org_job.job_category=horizontal)',
start_date DATE DEFAULT NULL, end_date DATE DEFAULT NULL,
status VARCHAR(16) NOT NULL DEFAULT 'active' COMMENT 'active/expired',
created_by VARCHAR(32) DEFAULT NULL, updated_by VARCHAR(32) DEFAULT NULL,
created_at TIMESTAMP NULL DEFAULT NULL, updated_at TIMESTAMP NULL DEFAULT NULL,
PRIMARY KEY (id),
UNIQUE KEY uk_proj_emp_job (project_id, employee_id, job_id, start_date),
KEY idx_employee_id (employee_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='项目任职(横向)';
``` ```
## 5. 索引与性能策略 ## 6. 索引与性能策略
1. 100 人规模全表扫描亦可满足 ≤500ms但仍按查询模式建索引列表筛选列status/org_id/hire_date/end_date、EAV 值表 uk(employee_id,field_id)、待办 idx(approver_id,task_status)。 1. 100 人规模全表扫描亦可满足 ≤500ms但仍按查询模式建索引列表筛选列status/org_id/hire_date/end_date、EAV 值表 uk(employee_id,field_id)、待办 idx(approver_id,task_status)、转正提醒 idx(probation_end_date)
2. 组织树、职位职级主数据一次性全量加载≤200/≤500 行),前端缓存,无需分页。 2. 组织树、职位职级主数据一次性全量加载≤200/≤500 行),前端缓存,无需分页。
3. EAV 查询模式:花名册列表先按主表条件分页取员工,再批量 `IN` 查值表拼装(每页 ≤50 人 × 显示字段数),避免 EAV 行转列大 JOIN。 3. EAV 查询模式:花名册列表先按主表条件分页取员工,再批量 `IN` 查值表拼装(每页 ≤50 人 × 显示字段数),避免 EAV 行转列大 JOIN。
4. 报表hr-report直接 SQL 聚合sor.sqlExe 只读100 人规模不建物化视图sys_audit_log 按月保留,冷数据归档不删除。 4. 报表hr-report直接 SQL 聚合sor.sqlExe 只读100 人规模不建物化视图,满足"延迟 ≤5 分钟"实为实时sys_audit_log 按月保留,冷数据归档不删除。
5. 唯一性:工号、组织编码、职位/职务/职级/职等编码、审批编号均唯一索引;证件号经哈希列唯一(加密为非确定性,哈希列承担唯一与黑名单匹配)。 5. 编制计数headcount_snapshot 以"异动事件触发 + 每日兜底扫描"双机制维护;实时查询取最新 snap_date历史回溯按 snap_date 精确取数F16 验收③)。
6. 唯一性:工号、组织编码、项目编码、职位/职务/职级/职等编码、审批编号、登记表 token 均唯一索引;证件号经哈希列唯一(密文为非确定性加密,哈希列承担唯一性与黑名单匹配)。
## 6. 数据字典appbase appcodesinit/data.json 初始化) ## 7. 数据字典appbase appcodesinit/data.json 初始化)
| code | 值 | 说明 | | code | 值 | 说明 |
|---|---|---| |---|---|---|
@ -308,48 +410,69 @@ CREATE TABLE sys_audit_log (
| ORG_TYPE | group/subsidiary/dept/team | 组织类型 | | ORG_TYPE | group/subsidiary/dept/team | 组织类型 |
| EMP_TYPE | formal/temp/dispatch/intern | 员工类型(正式/临时/派遣/实习) | | EMP_TYPE | formal/temp/dispatch/intern | 员工类型(正式/临时/派遣/实习) |
| EMP_STATUS | pending_entry/probation/regular/pending_leave/left | 员工状态(待入职/试用/正式/待离职/离职) | | EMP_STATUS | pending_entry/probation/regular/pending_leave/left | 员工状态(待入职/试用/正式/待离职/离职) |
| ID_TYPE | id_card/passport/other | 证件类型 |
| ID_SOURCE | manual/card_reader(预留,二期) | 证件信息来源D1 |
| POS_CATEGORY | management/professional/skill | 职位类别 | | POS_CATEGORY | management/professional/skill | 职位类别 |
| JOB_CATEGORY | vertical/horizontal | 职务类别F17 横向职务) |
| TRANSFER_TYPE | promotion/demotion/position_change/org_adjust | 调动类型 | | TRANSFER_TYPE | promotion/demotion/position_change/org_adjust | 调动类型 |
| LEAVE_REASON | personal/company/contract_expire/retire/other | 离职原因 | | LEAVE_REASON | personal/company/contract_expire/retire/other | 离职原因 |
| HANDOVER_TYPE | approval/file/subordinate/permission/dingtalk_resource(占位)/other | 离职交接项类型D3 |
| CONTRACT_STATUS | active/expired/stopped/renewing | 合同状态 | | CONTRACT_STATUS | active/expired/stopped/renewing | 合同状态 |
| FLOW_BIZ_TYPE | entry/regular/transfer/leave/handover/concurrent/contract_sign/contract_renew/contract_change/contract_stop/roster_self_edit | 审批业务类型 | | ESIGN_STATUS | not_enabled/signing/signed(后两者二期启用) | 电子签状态D4 预留) |
| FLOW_BIZ_TYPE | entry/regular/transfer/leave/handover/concurrent/contract_sign/contract_renew/contract_change/contract_stop/roster_self_edit/attendance_*(桩位) | 审批业务类型 |
| INST_STATUS | running/approved/rejected/cancelled | 实例状态 | | INST_STATUS | running/approved/rejected/cancelled | 实例状态 |
| REMIND_SCENE | entry/regular/leave/retire/contract_expire/health_cert/social_insurance/custom | 提醒场景 | | REMIND_SCENE | entry/regular/leave/retire/contract_expire/health_cert/social_insurance/custom | 提醒场景≥6 类F15 验收④) |
| AUDIT_OP | create/update/delete/import/export/approve/login | 操作类型 | | HEADCOUNT_CYCLE | year/quarter/month | 编制周期F16 |
| PROJECT_STATUS | active/expired/inactive | 项目状态F17到期自动 expired |
| MSG_CHANNEL | site/sms(预留)/email(预留) | 消息渠道D9 |
| AUDIT_OP | create/update/delete/import/export/approve/login/migrate | 操作类型 |
| ENTRY_STATUS | pending_approval/pending_entry/entered/cancelled/blocked | 入职状态 |
| REGISTER_STATUS | none/invited/filled | 登记表状态 |
枚举一律不硬编码于 dspyCRUD 下拉经 models `codes` 段引用。 枚举一律不硬编码于 dspyCRUD 下拉经 models `codes` 段引用。
## 7. staff-mgr 数据迁移策略v1 → 迭代1 ## 8. staff-mgr 数据迁移策略v1 → 一期NFR-8
迁移工具:`repos/hr-system` 仓内规划 `scripts/migrate_staff_mgr.py`Python + sqlor幂等可重跑输出核对报告 迁移工具:`repos/hr-system` 仓内规划 `scripts/migrate_staff_mgr.py`Python + sqlor幂等可重跑输出核对报告:总数一致 + 抽样字段一致)。
| v1 源表staff-mgr | 目标表 | 映射规则 | | v1 源表staff-mgr | 目标表 | 映射规则 |
|---|---|---| |---|---|---|
| staff_department_cache | org_unit | 按树形重建 parent_idorg_code=DEPT{id}status 映射 active/inactive | | staff_department_cache | org_unit | 按树形重建 parent_idorg_code=DEPT{id}status 映射 active/inactive |
| staff_employee | roster_employee | employee_no/name/gender/phone/email 直映id_number AES 解密后按新方案重加密cipher+hashdepartment_id→org_idposition 文本→预置 org_position无匹配则建"未定职"status: active→regular、probation→probation、inactive→lefthire_date 直映 | | staff_employee | roster_employee | employee_no/name/gender/phone/email 直映id_number AES 解密后按新方案重加密cipher+hashid_source='manual',证件有效期/签发机关置空待补department_id→org_idposition 文本→预置 org_position无匹配则建"未定职"status: active→regular、probation→probation、inactive→lefthire_date 直映 |
| staff_employee_extra | roster_field_value + contract_info | education/major/school/graduation_date/previous_company/work_years → 预置 roster_field_def 字段值technical_level/salary_grade → 预置敏感字段值contract_type/start/end → contract_infotype_id 映射正式/外包/实习协议) | | staff_employee_extra | roster_field_value + contract_info | education/major/school/graduation_date/previous_company/work_years → 预置 roster_field_def 字段值technical_level/salary_grade → 预置敏感字段值contract_type/start/end → contract_infotype_id 映射正式/外包/实习协议) |
| staff_change_log | roster_timeline | change_type→event_type(transfer/field_change)old/new 值入 content_jsonevent_type 前缀 `migrate:` 标识迁移来源 | | staff_change_log | roster_timeline | change_type→event_type(transfer/field_change)old/new 值入 content_jsonevent_type 前缀 `migrate:` 标识迁移来源 |
| staff_audit_log | sys_audit_log | 字段直映module 标记 `staff-mgr-legacy` | | staff_audit_log | sys_audit_log | 字段直映module 标记 `staff-mgr-legacy` |
策略与约束: 策略与约束:
1. **顺序**org_unit → org_position预置→ roster_field_def/group预置→ roster_employee → roster_field_value → contract_info → timeline/audit。 1. **顺序**org_unit → org_position预置→ roster_field_def/group预置→ roster_employee → roster_field_value → contract_info → timeline/audit。
2. **幂等**:按 employee_no/org_code 去重,重跑仅补差;证件号哈希冲突时输出冲突报告人工裁决(对 baseline-decision Q6冲突员工按离职记录保留不入在职 2. **幂等**:按 employee_no/org_code 去重,重跑仅补差;证件号哈希冲突时输出冲突报告人工裁决(冲突员工按离职记录保留,不入在职)。
3. **切换**迭代1 UAT 通过后一次性迁移+双库比对 → staff-mgr 服务下线、仓库冻结只读(保留一个迭代周期)。 3. **范围**:默认"在职 + 离职保留档案"全量;仅迁在职/含历史的最终范围与切换时间点待 PM 确认SRS §11-Q3脚本参数 `--scope=active|all` 支持两种口径。
4. 迁移全程写 sys_audit_logoperation=migrate迁移数据在时间轴/日志中可辨识。 4. **切换**UAT 通过后一次性迁移+双库比对 → staff-mgr 服务下线、仓库冻结只读(保留一个迭代周期)。
5. 迁移全程写 sys_audit_logoperation=migrate迁移数据在时间轴/日志中可辨识。
## 8. 与需求验收项的映射(摘选) ## 9. 与需求验收项的映射(摘选)
| 验收项function-detail | 数据支撑 | | 验收项 | 数据支撑 |
|---|---| |---|---|
| F01-4 时间轴留痕 | org_unit_change | | F01-4 时间轴留痕 | org_unit_change |
| F01-5 历史架构图 | org_unit.effective_date/expire_date + org_unit_change 回放 |
| F02-1~5 五套体系 | org_job/position/sequence/grade_level/grade_rank |
| F03-1/2 自定义字段与分组 | roster_field_def/group/value | | F03-1/2 自定义字段与分组 | roster_field_def/group/value |
| F03-3 多规则工号 | roster_empno_rule | | F03-3 多规则工号 | roster_empno_rule |
| F03-4 自助修改审核 | roster_field_def.editable_self/need_audit + flow biz_type=roster_self_edit | | F03-4 自助修改审核 | roster_field_def.editable_self/need_audit + flow biz_type=roster_self_edit |
| F03-6 类型差异规则 | roster_type_rule + apply_types | | F03-6 类型差异规则 | roster_type_rule + apply_types |
| F04-4 黑名单拦截 | org_blacklistid_number_hash 匹配) | | F04-4 身份证手工录入D1 | roster_employee/org_entry 证件字段组 + id_source='manual' |
| F04-5 复职 | roster_employee.prev_employee_id |
| F04-6 黑名单拦截 | org_blacklistid_number_hash 匹配) |
| F05-3 转正提醒 | roster_employee.probation_end_date + sys_remind_rule(scene=regular) |
| F07-3 钉钉交接占位D3 | org_leave_handover.item_type=dingtalk_resource |
| F07-5 离职证明 | org_leave.certificate_filefiles/ 存储) | | F07-5 离职证明 | org_leave.certificate_filefiles/ 存储) |
| F09-6 电子签预留 | contract_info.esign_status | | F09-6 电子签预留D4 | contract_info.esign_status + contract_template.text_file_path |
| F10-2 字段权限 | flow_node_def.field_perm_json | | F10-2 字段权限 | flow_node_def.field_perm_json |
| F11-2 双维度数据范围 | sys_data_scope(scope_type=org/field) | | F11-2 双维度数据范围 | sys_data_scope(scope_type=org/field) |
| F12-3 前后对比 | sys_audit_log.before_json/after_json | | F12-3 前后对比 | sys_audit_log.before_json/after_json |
| F15-4 多场景提醒 | sys_remind_rule(scene_code) | | F13-6 报表数据范围受控 | 聚合查询叠加 sys_data_scope |
| F15-4 多场景提醒≥6 类) | sys_remind_rule(scene_code) + REMIND_SCENE 字典 |
| F16-1~6 编制 | org_headcount_scheme/headcount_item/headcount_snapshot |
| F17-1~3 项目式组织 | org_project/org_project_post + org_job(job_category=horizontal) |
| FEAT-B1-01⑦ API 开放预留 | sys_openapp一期不启用 |

View File

@ -1,67 +1,71 @@
# 迭代1功能清单F01~F15ocai 口径) # 一期批次1功能清单F01~F17ocai 口径)
- 版本v2.0替换原 299B 占位文件;占位文件内容为 v1 Java 口径描述,已废弃 - 版本v2.1批次1设计定稿v2.1 变更:对齐 SRS v3.1 —— 批次1范围扩入 F16 编制管理FEAT-B1-10、F17 项目式组织FEAT-B1-11合计 90 条验收项;补充 F01~F15 ↔ FEAT-B1 编号映射
- 需求基线:`docs/00-requirement/requirement-spec.md`SRS v2+ `docs/00-requirement/iteration1-function-detail.md` - 需求基线:`docs/00-requirement/requirement-spec.md`SRS v3.1+ `docs/00-requirement/iteration1-function-detail.md`
- 应用hr-web`apps/hr-web.md`);模块定义:`modules/hr-*.md` - 应用hr-web`apps/hr-web.md`);模块定义:`modules/hr-*.md`
## 0. 范围与角色 ## 0. 范围与角色
迭代1 = 组织人事底座,规模 100 人账号。技术口径统一 ocai前端 bricks + dspy 声明式页面,后端 ahserverPython数据层 apppublic/sqlor。 一期批次1 = 组织人事底座 + 系统管理与权限基座,规模 100 人账号。技术口径统一 ocai前端 bricks + dspy 声明式页面,后端 ahserverPython数据层 apppublic/sqlorMariaDB库 hrs
| 角色 | 代码 | 主要能力 | | 角色 | 代码 | 主要能力 |
|---|---|---| |---|---|---|
| 系统管理员 | admin | 全部数据与配置、角色/管理员/数据范围、操作日志 | | 系统管理员 | admin | 全部数据与配置、角色/管理员/数据范围、操作日志 |
| 人事 | hr | 组织、花名册、入转调离、合同、流程配置、报表 | | 人事 | hr | 组织、花名册、入转调离、合同、流程配置、报表、编制 |
| 部门经理 | manager | 数据范围内入转调离审批、团队统计、关怀提醒 | | 部门经理 | manager | 数据范围内入转调离审批、团队统计、关怀提醒 |
| 员工(自助) | employee | 个人档案、发起审批、待办、企业政策/公告 | | 员工(自助) | employee | 个人档案、发起审批、待办、企业政策/公告 |
脱敏基线身份证号全角色脱敏前3后3手机号前3后4薪资/职级敏感字段仅 admin/hr 可见(由 roster_field_def.sensitive 驱动)。 脱敏基线身份证号全角色脱敏前3后3手机号前3后4薪资/职级敏感字段仅 admin/hr 可见(由 roster_field_def.sensitive 驱动)。
## 1. 功能清单F01~F15共 81 条验收项) ## 1. 功能 → FEAT 映射与清单F01~F17共 90 条验收项)
| # | 功能 | 承载模块 | 表前缀 | 验收项数 | 关键交付 | 范围边界 | | # | 功能 | 对应 FEATSRS v3.1 | 承载模块 | 表前缀 | 验收项数 | 关键交付 | 范围边界 |
|---|---|---|---|---|---|---| |---|---|---|---|---|---|---|---|
| F01 | 组织架构 | hr-org | org_ | 6 | 组织树/架构图(含 as_of 历史)/新建变更停用移动/字段自定义/时间轴/Excel 导入 | 编制管理、项目式组织范围外 | | F01 | 组织架构 | FEAT-B1-02 | hr-org | org_ | 6 | 组织树/架构图(含 as_of 历史)/新建变更停用移动/字段自定义/时间轴/Excel 导入/合同公司 | 全量 |
| F02 | 职位职级体系 | hr-org | org_ | 5 | 职位/职务/职级/职等/序列 CRUD + 导入导出 + options | 全量 | | F02 | 职位职级体系 | FEAT-B1-03 | hr-org | org_ | 5 | 职位/职务/职级/职等/序列 CRUD + 导入导出 + options | 全量 |
| F03 | 花名册 | hr-roster | roster_ | 8 | 自定义字段(EAV)/分组/工号多规则/自助修改+审核/时间轴/类型规则/搜索/导入导出 | 附件预览依赖 files/ | | F03 | 花名册 | FEAT-B1-04 | hr-roster | roster_ | 8 | 自定义字段(EAV)/分组/工号多规则/自助修改+审核/时间轴/类型规则/搜索/导入导出 | 附件预览依赖 files/ |
| F04 | 入职管理 | hr-org | org_ | 7 | 审批入职/手动批量入职/登记表邀请/黑名单拦截/入职通知/复职 | 扫码入职、身份证读取为降级项 | | F04 | 入职管理 | FEAT-B1-05 | hr-org | org_ | 7 | 审批入职/手动批量入职/登记表邀请(扫码降级)/身份证手工录入(D1)/黑名单拦截/入职通知/复职 | 读卡二期、对外二维码二期 |
| F05 | 转正管理 | hr-org | org_ | 4 | 审批/手动转正、回写花名册、转正提醒 | 全量 | | F05 | 转正管理 | FEAT-B1-06 | hr-org | org_ | 4 | 审批/手动转正、回写花名册、转正提醒 | 全量 |
| F06 | 调动管理 | hr-org | org_ | 4 | 调动查询/审批(晋升/降级/调岗/组织调整)/批量调动 | 全量 | | F06 | 调动管理 | FEAT-B1-06 | hr-org | org_ | 4 | 调动查询/审批(晋升/降级/调岗/组织调整)/批量调动/编制联动提醒 | 全量 |
| F07 | 离职管理 | hr-org | org_ | 7 | 审批/手动离职、交接、离职证明、黑名单、信息存储 | 钉钉资源交接置后 | | F07 | 离职管理 | FEAT-B1-07 | hr-org | org_ | 7 | 审批/手动离职、交接(钉钉占位 D3)、离职证明、黑名单、信息存储 | 钉钉资源交接二期 |
| F08 | 兼岗管理 | hr-org | org_ | 3 | 一人多兼岗记录、兼岗审批、通过自动同步 | 全量 | | F08 | 兼岗管理 | FEAT-B1-04 | hr-org | org_ | 3 | 一人多兼岗记录、兼岗审批、通过自动同步 | 全量 |
| F09 | 合同台账 | hr-contract | contract_ | 6 | 台账/类型自定义/模板/审批(新签续签变更终止)/到期提醒 | 电子签置后(esign_stub 预留) | | F09 | 合同台账 | FEAT-B1-08 | hr-contract | contract_ | 6 | 台账/类型自定义/模板(生成文本 D4)/审批(新签续签变更终止)/到期提醒 | 电子签二期(esign_stub 预留) |
| F10 | 流程审批 | hr-flow | flow_ | 7 | 表单/流程/节点配置、审批角色、流转引擎、查询导出、打印 | 考勤/薪酬/组合审批置后 | | F10 | 流程审批 | FEAT-B1-01 | hr-flow | flow_ | 7 | 表单/流程/节点配置、审批角色、流转引擎、查询导出、打印;考勤流程桩位 | 薪酬/组合审批批次2 |
| F11 | 权限管理 | hr-system | sys_ | 4 | 管理角色、人员范围(组织维度+花名册字段维度)、管理员管理 | 全量 | | F11 | 权限管理 | FEAT-B1-01 | hr-system | sys_ | 4 | 管理角色,人员范围(组织维度+花名册字段维度),管理员管理 | 全量 |
| F12 | 操作日志 | hr-system | sys_ | 4 | 全量写操作留痕、前后对比、时间/类型查询 | 全量 | | F12 | 操作日志 | FEAT-B1-01 | hr-system | sys_ | 4 | 全量写操作留痕、前后对比、时间/类型查询 | 全量 |
| F13 | 人事报表 | hr-report | —(只读) | 6 | 花名册/入职/转正/调岗/离职五类分析,数据范围受控 | 全量 | | F13 | 人事报表 | FEAT-B1-12 | hr-report | —(只读) | 6 | 花名册/入职/转正/调岗/离职五类分析,数据范围受控,可导出 | 全量 |
| F14 | 工作台 | hr-system | sys_ | 5 | 员工/经理/管理员三工作台聚合 | 绩效/考勤统计预留占位 | | F14 | 工作台 | FEAT-B1-09 | hr-system | sys_ | 5 | 员工/经理/管理员三工作台聚合 | 工资条/绩效/考勤桩位 |
| F15 | 员工服务与提醒 | hr-system | sys_ | 5 | 生日周年关怀、政策、公告、多场景到期提醒 | 站内消息优先,短信/邮件预留 | | F15 | 员工服务与提醒 | FEAT-B1-09 | hr-system | sys_ | 5 | 生日周年关怀、政策、公告、多场景到期提醒(≥6类) | 站内消息优先,短信/邮件预留(D9) |
| F16 | 编制管理 | FEAT-B1-10 | hr-org | org_/headcount_ | 6 | 编制方案/占编范围/细分/超缺编状态/异动管控提醒/历史编制 | 全量(一期提醒不硬拦截) |
| F17 | 项目式组织 | FEAT-B1-11 | hr-org | org_ | 3 | 纵向部门×横向项目组组合、横向组织信息、横向职务体系 | 全量 |
合计:**81 条可验收项**(逐项输入/处理/输出见 `iteration1-function-detail.md`)。 合计:6+5+8+7+4+4+7+3+6+7+4+4+6+5+5+6+3 = **90 条可验收项**F01~F15 逐项输入/处理/输出见 `iteration1-function-detail.md`F16/F17 按 SRS v3.1 §3.1 FEAT-B1-10/11 验收标准执行)。
## 2. 功能 → 模块 → 数据表落点 ## 2. 功能 → 模块 → 数据表落点
| 模块 | 功能 | 主要数据表 | | 模块 | 功能 | 主要数据表 |
|---|---|---| |---|---|---|
| hr-org | F01/F02/F04/F05/F06/F07/F08 | org_unit, org_unit_change, org_field_def/value, org_job, org_position, org_sequence, org_grade_level, org_grade_rank, org_blacklist, org_contract_company, org_entry, org_regularization, org_transfer(+detail), org_leave(+handover), org_concurrent_post18 张) | | hr-org | F01/F02/F04/F05/F06/F07/F08/F16/F17 | org_unit(+change/field_def/field_value)、org_job/position/sequence/grade_level/grade_rank、org_blacklist、org_contract_company、org_entry、org_regularization、org_transfer(+detail)、org_leave(+handover)、org_concurrent_post、org_headcount_scheme/headcount_item/headcount_snapshot、org_project/org_project_post23 张) |
| hr-roster | F03 | roster_field_group, roster_field_def, roster_employee, roster_field_value, roster_empno_rule, roster_timeline, roster_type_rule7 张) | | hr-roster | F03 | roster_field_group, roster_field_def, roster_employee, roster_field_value, roster_empno_rule, roster_timeline, roster_type_rule7 张) |
| hr-flow | F10 | flow_form_def, flow_def, flow_node_def, flow_role, flow_instance, flow_task, flow_op_log7 张) | | hr-flow | F10 | flow_form_def, flow_def, flow_node_def, flow_role, flow_instance, flow_task, flow_op_log7 张) |
| hr-contract | F09 | contract_type, contract_template, contract_info, contract_remind_rule4 张) | | hr-contract | F09 | contract_type, contract_template, contract_info, contract_remind_rule4 张) |
| hr-report | F13 | 无自有表,只读聚合 org_/roster_/flow_ | | hr-report | F13 | 无自有表,只读聚合 org_/roster_/flow_ |
| hr-system | F11/F12/F14/F15 | sys_data_scope, sys_audit_log, sys_message, sys_remind_rule, sys_announcement, sys_policy, sys_care_config7 张 | | hr-system | F11/F12/F14/F15 | sys_data_scope, sys_audit_log, sys_message, sys_remind_rule, sys_announcement, sys_policy, sys_care_config, sys_openapp8 张,末张为 API 开放预留 |
43 张业务表,详见 `database-design.md` **49 张业务表**,详见 `database-design.md`
## 3. 设计文档索引 ## 3. 设计文档索引
| 文档 | 内容 | | 文档 | 内容 |
|---|---| |---|---|
| architecture.md | 系统架构、技术选型、模块划分与依赖、hr-system/staff-mgr 职责边界、部署、安全、非功能 | | architecture.md | 系统架构、技术选型、模块划分与依赖、部署9182/MariaDB hrs、安全、非功能、降级项设计专章、API 开放规范 |
| database-design.md | ER、43 表结构、索引、数据字典、models JSON、staff-mgr 迁移 | | database-design.md | ER、49 表结构、索引、数据字典、models JSON、staff-mgr 迁移 |
| api-design.md | dspy 端点清单、通用约定、鉴权、错误码、典型调用链、v1 接口替代 | | api-design.md | dspy 端点清单(约 120 个)、通用约定、鉴权、错误码、典型调用链、降级桩端点汇总 |
| ui-design.md | 布局、路由表、页面组件树、核心交互流程、设计规范、页面-接口追溯 | | ui-design.md | 布局、路由表、页面组件树、核心交互流程、设计规范、页面-接口追溯 |
| iteration1-task-breakdown.md | 技术可行性、风险、开发任务拆解T01~T24约 84 人日 | | iteration1-task-breakdown.md | 技术可行性、风险、开发任务拆解T01~T27约 92 人日,面向 develop 角色 |
## 4. 迭代1范围外(既定) ## 4. 批次1范围外/降级项(既定)
编制管理、项目式组织、钉钉同步、考勤流程、薪酬流程、组合审批、电子签、短信/邮件通道、浏览器插件——列为后续迭代/集成迭代,本期仅预留字段或桩接口。 - 范围外:钉钉同步(组织/人员/考勤/智能人事、薪酬流程与组合审批批次2、招聘全部批次3、电子签、税局在线申报、短信网关、浏览器插件。
- 一期降级SRS §9设计落点见 architecture.md §10D1 身份证手工录入、D3 离职交接钉钉占位、D4 合同模板文本+esign_stub、D9 站内消息兜底、扫码入职内网登记链接/二维码、考勤/绩效/工资条工作台桩位。
- 以上均在一期做字段/桩端点/流程位预留,二期对接不改表结构主干。

View File

@ -1,9 +1,9 @@
# 迭代1总体设计 —— 技术可行性与开发任务拆解hr-web # 一期批次1总体设计 —— 技术可行性与开发任务拆解hr-web
- 版本v1.0迭代1-总体设计配套文档 - 版本v2.0批次1设计定稿v2.0 变更:对齐 SRS v3.1 —— 范围扩入编制(F16)/项目式(F17)、新增降级项任务、部署任务与开放接口桩任务;任务编号 T01~T27可直接用于 develop 角色创建开发任务
- 状态:评审通过主agent评审基线冻结 - 状态:**设计定稿批次1评审修订版**
- 基线:`docs/01-design/architecture.md`(架构)+ `database-design.md`43 表)+ `api-design.md`(端点清单)+ `ui-design.md`(页面结构) - 基线:`docs/01-design/architecture.md`(架构)+ `database-design.md`49 表)+ `api-design.md`(端点清单)+ `ui-design.md`(页面结构)
- 需求基线:`docs/00-requirement/requirement-spec.md`SRS v2+ `iteration1-function-detail.md`F01~F1581 条验收项 - 需求基线:`docs/00-requirement/requirement-spec.md`SRS v3.1+ `iteration1-function-detail.md`F01~F1581 条)+ approved-features.mdFEAT-B1-01~12
## 1. 技术可行性说明 ## 1. 技术可行性说明
@ -11,89 +11,104 @@
| 能力诉求 | ocai 设施 | 成熟度结论 | | 能力诉求 | ocai 设施 | 成熟度结论 |
|---|---|---| |---|---|---|
| 声明式 CRUD 页面 | json/*.json + xls2ui 自动生成 DataViewer/Form/Tree | 成熟产线既有模式迭代1约 20 个 CRUD 页面零手写 | | 声明式 CRUD 页面 | json/*.json + xls2ui 自动生成 DataViewer/Form/Tree | 成熟产线既有模式批次1约 25 个 CRUD 页面零手写 |
| 组织树/架构图 | Tree widget + org_unit parent_id 自引用 + as_of 历史查询 | 可行;历史架构靠 org_unit_change 时间轴回放/有效期区间过滤 | | 组织树/架构图 | Tree widget + org_unit parent_id 自引用 + as_of 历史查询 | 可行;历史架构按 effective_date/expire_date + org_unit_change 回放 |
| 自定义字段(花名册/组织) | EAV 双表 + field_def 元数据驱动表单渲染 | 可行;列表页采用"主表分页+值表批量拼装"规避 EAV 性能问题 | | 自定义字段(花名册/组织) | EAV 双表 + field_def 元数据驱动表单渲染 | 可行;列表页"主表分页+值表批量拼装"规避 EAV 性能问题 |
| 审批引擎 | flow_def/node_def JSON 配置 + flow_instance/task 状态机 | 可行迭代1仅串行节点 + any/all 通过规则,不做并行分支(满足 F10 验收) | | 审批引擎 | flow_def/node_def JSON 配置 + flow_instance/task 状态机 | 可行;一期仅串行节点 + any/all 通过规则,不做并行分支(满足 F10 验收);四类人事流程模板 init/data.json 预置 |
| 审批通过自动回写 | biz_type+biz_id 关联 + ServerEnv 注册回调 hook | 可行;模块宿主无关原则下经 load_xxx() 注册函数互调 | | 审批通过自动回写 | biz_type+biz_id 关联 + ServerEnv 注册回调 hook | 可行roster_writeback 唯一入口,回写后联动 headcount_check 与 timeline |
| 批量导入导出 | ahserver 后台任务 + openpyxl + files/ 结果文件 | 可行100 人量级同步/准同步处理即可 | | 批量导入导出 | ahserver 后台任务 + openpyxl + files/ 结果文件 | 可行500 行 ≤30s 指标NFR-1在 100 人量级轻松满足 |
| 数据范围权限 | rbac 路径级 + sys_data_scope组织/字段双维度)查询叠加 | 可行;复用 rbac-permission-initialization-pattern | | 数据范围权限 | rbac 路径级 + sys_data_scope组织/字段双维度)查询叠加 | 可行;查询/报表/导出三处强制叠加 |
| 脱敏/审计 | roster_field_def.sensitive + sys_audit_log 前后 JSON | 可行;替代 staff-mgr 硬编码 MaskUtil | | 脱敏/审计 | roster_field_def.sensitive + sys_audit_log 前后 JSON | 可行 |
| 图表报表 | bricks Chart widgetsbricks-chart-widgets 技能) | 可行;聚合 SQL 只读查询 | | 图表报表 | bricks Chart widgets | 可行;聚合 SQL 只读查询≤3s 指标满足 |
| 提醒推送 | cron 扫描 remind_scan + sys_message 站内消息 | 可行;短信/邮件通道预留 send_channel 字段 | | 提醒推送 | cron 扫描 remind_scan + sys_message 站内消息 | 可行≥6 场景;短信/邮件 send_channel 预留 |
| 编制实时计数 | 异动事件触发重算 + headcount_snapshot 快照 | 可行100 人规模事件内同步重算满足"1 分钟内刷新" |
| 项目式组织 | org_project 自引用 + org_project_post 关联表 | 可行;横向职务复用 org_job(job_category=horizontal) |
| 入职登记链接/二维码 | token + tmpl 页面 + qrcode 图片生成files/ | 可行;内网 token 鉴权免登录 |
| 合同文本生成 | openpyxl/python-docx 模板占位符替换 | 可行;一期 docx/pdf 打印下载,电子签二期 |
### 1.2 规模与性能 ### 1.2 规模与性能
100 人账号、单实例部署nginx + ahserver + MySQL + Redis。最大表量级花名册 100 行、字段值 ≤100×100=1 万行、审计日志年级 ≤10 万行。全部查询在索引覆盖下远低于 500ms 指标;组织树/主数据全量加载无分页压力。导入导出 100 人 × 50 字段 openpyxl 秒级完成。 100 人账号、单实例部署(ahserver:9182 + MariaDB(hrs) + Redis。最大表量级花名册 2000 行(含离职)、字段值 ≤2000×100=20 万行、审计日志年级 ≤10 万行、编制快照 365×细分项数。全部查询在索引覆盖下远低于 500ms 指标。
### 1.3 主要风险与对策 ### 1.3 主要风险与对策
| 风险 | 等级 | 对策 | | 风险 | 等级 | 对策 |
|---|---|---| |---|---|---|
| EAV 自定义字段在列表页的筛选/排序复杂度 | 中 | 迭代1筛选支持"主表字段 + 至多 3 个自定义字段等值匹配",排序仅主表字段;超出部分作为已知限制写入 UAT 说明 | | EAV 自定义字段在列表页的筛选/排序复杂度 | 中 | 筛选支持"主表字段 + 至多 3 个自定义字段等值匹配",排序仅主表字段;已知限制写入 UAT 说明 |
| 审批引擎配置化过度导致返工 | 中 | 迭代1锁定"串行节点、any/all、字段权限、抄送"能力边界;并行/条件分支留 flow_node_def JSON 扩展位 | | 审批引擎配置化过度导致返工 | 中 | 锁定"串行节点、any/all、字段权限、抄送"能力边界;并行/条件分支留 flow_node_def JSON 扩展位 |
| staff-mgr 旧数据语义差异status/加密算法) | 中 | 迁移脚本内置映射表 + 核对报告 + UAT 双库比对(见 database-design.md §7 | | staff-mgr 旧数据语义差异status/加密算法) | 中 | 迁移脚本内置映射表 + 核对报告 + UAT 双库比对;迁移范围待 PM 确认SRS Q3脚本支持 --scope 参数 |
| 6 模块并行开发契约漂移 | 中 | 本文 T01 先行冻结表定义 models JSON 与 api-design 端点签名,变更走设计评审 | | 6 模块并行开发契约漂移 | 中 | T01 先行冻结表定义 models JSON 与 api-design 端点签名,变更走设计评审 |
| 提醒场景字段依赖(健康证/社保等花名册字段未建) | 低 | init/data.json 预置 REMIND_SCENE 对应字段定义remind_scan 按 field_def 取数 | | 提醒场景字段依赖(健康证/社保等花名册字段未建) | 低 | init/data.json 预置 REMIND_SCENE 对应字段定义remind_scan 按 field_def 取数 |
| 编制占编范围条件表达力 | 低 | scope_json 采用 {conds:[{field,op,value}]} 结构,支持等值/包含;复杂表达式二期扩展 |
### 1.4 已裁决口径(对 baseline-decision 遗留问题 ### 1.4 降级项任务落点SRS §9批次1相关
- Q1 双口径:统一 ocai本设计全套 | 降级项 | 一期落点任务 |
- Q6 删除语义迭代1员工/组织不做物理删除与逻辑删除标记,统一走停用/离职流程database-design.md §1.3、api-design.md §4 |---|---|
- 其余 Q2~Q5/Q7 以本设计为评审结论自定义字段排序限主表字段1.3、审批引擎能力边界1.3、迁移幂等策略db §7 | D1 身份证读卡→手工录入 | T06证件字段组/T13入职表单证件分组/T15档案证件展示脱敏 |
| 扫码入职→内网登记链接/二维码 | T13entry_register 页面+token+二维码) |
| D3 钉钉交接→占位项 | T17交接项 dingtalk_resource 类型手工登记) |
| D4 电子签→模板文本+桩 | T19contract_text_gen + esign_stub |
| D9 短信→站内兜底 | T16send_channel=sitesms/email 枚举预留) |
| 考勤/绩效/工资条桩位 | T10attendance_* 表单桩)/T21工作台桩位卡片 |
| API 开放接口预留 | T26sys_openapp 表 + /openapi/v1/ping 桩) |
## 2. 开发任务拆解T01~T24契约先行 ## 2. 开发任务拆解T01~T27,契约先行)
> 依赖关系T01~T02 为契约冻结阶段,全量先行;其后按模块并行。工作量单位:人日(估算,供 PM 排期)。 > 依赖关系T01~T02 为契约冻结阶段,全量先行;其后按模块并行。工作量单位:人日(估算,供 PM 排期)。每个任务含验收对照F#/FEAT 编号develop 角色可直接按任务建卡。
### 阶段0 契约与脚手架 ### 阶段0 契约与脚手架
| 编号 | 任务 | 内容/产出 | 依赖 | 估时 | | 编号 | 任务 | 内容/产出 | 验收对照 | 依赖 | 估时 |
|---|---|---|---|---| |---|---|---|---|---|---|
| T01 | 数据契约冻结 | 6 模块仓库建仓hr_org/hr_roster/hr_flow/hr_contract/hr_reporthr-system 复用既有空仓43 张 models/*.json 全量提交json2ddl 生成 DDL 验证 | — | 4 | | T01 | 数据契约冻结 | 6 模块仓库建仓hr_org/hr_roster/hr_flow/hr_contract/hr_reporthr-system 复用既有仓);**49 张** models/*.json 全量提交json2ddl 生成 DDL 导入 hrs 库验证init/data.json 字典(含 HEADCOUNT_CYCLE/PROJECT_STATUS/ID_SOURCE 等新增字典) | database-design §4 全表 | — | 5 |
| T02 | 应用脚手架 | hr-web 应用仓app/hr_web.py、conf/config.json 含 processors/indexes/session、build.sh、.envappbase/rbac 加载验证;登录走通 | T01 | 2 | | T02 | 应用脚手架 | hr-web 应用仓app/hr_web.py、conf/config.json 含 processors/indexes/session/databases.hrs、build.sh、systemd unitappbase/rbac 加载验证;登录走通;内置 admin+四角色初始化 | SRS §5.2-4 | T01 | 2 |
### 阶段1 主数据与底座(可并行) ### 阶段1 主数据与底座(可并行)
| 编号 | 任务 | 内容/产出 | 依赖 | 估时 | | 编号 | 任务 | 内容/产出 | 验收对照 | 依赖 | 估时 |
|---|---|---|---|---| |---|---|---|---|---|---|
| T03 | hr-org 组织管理 | org_unit CRUD/树/停用/移动、org_field_def 自定义字段、org_unit_change 时间轴、org_tree/org_import 端点、org_tree.ui/org_chart.uiF01 | T01,T02 | 5 | | T03 | hr-org 组织管理 | org_unit CRUD/树/停用/移动(子树+员工联动)、org_field_def 自定义字段、org_unit_change 时间轴、org_import≥200行、org_tree.ui/org_chart.uias_of+导出)、合同公司 company CRUD | F01 全 6 项 + FEAT-B1-02 | T01,T02 | 5 |
| T04 | hr-org 职位职级 | org_job/position/sequence/grade_level/grade_rank CRUD + 导入导出 + options 端点F02 | T03 | 3 | | T04 | hr-org 职位职级 | org_job(含 job_category 横向位)/position/sequence/grade_level/grade_rank CRUD + 停用启用联动 + 导入导出 + options 端点 | F02 全 5 项 + FEAT-B1-03 | T03 | 3 |
| T05 | hr-roster 字段体系 | roster_field_group/field_def/type_rule/empno_rule 配置页与端点、工号生成器F03 搭建类验收 1/2/3/6 | T01,T02 | 4 | | T05 | hr-roster 字段体系 | roster_field_group/field_def/type_rule/empno_rule 配置页与端点、工号生成器(多规则+冲突报错、field_config.ui 拖拽排序 | F03 验收 1/3/6 | T01,T02 | 4 |
| T06 | hr-roster 花名册主体 | roster_employee CRUD、EAV 值表读写、roster_list/employee_detail/timeline、脱敏与字段可见F03 验收 4/5/7 | T05,T03,T04 | 6 | | T06 | hr-roster 花名册主体 | roster_employee CRUD**含证件字段组手工录入 D1**、EAV 值表读写、roster_list/employee_detail/timeline、脱敏与字段可见、自助修改+审核、复职 prev_employee_id 关联 | F03 验收 2/4/5/7 + F04-4/5 + SRS §2.2-4 | T05,T03,T04 | 6 |
| T07 | hr-roster 导入导出 | roster_import新增/修改、模板生成、roster_export字段/顺序/as_ofF03 验收 8 | T06 | 3 | | T07 | hr-roster 导入导出 | roster_import新增/修改≥500 行含更新匹配)、模板生成(按字段定义+类型规则、roster_export字段/顺序/as_of强制数据范围 | F03 验收 8 | T06 | 3 |
| T08 | hr-system 权限底座 | 角色/管理员/数据范围sys_data_scope 双维度、get_data_scope 注册、各模块查询叠加F11 | T02 | 4 | | T08 | hr-system 权限底座 | 角色/管理员/数据范围sys_data_scope 双维度叠加、get_data_scope 注册、各模块查询/报表/导出叠加、role_admin.ui/data_scope.ui | F11 全 4 项 + SRS §2.2-1/2/3 | T02 | 4 |
| T09 | hr-system 审计底座 | write_audit_log + sys_audit_log 查询/详情对比页F12 | T02 | 2 | | T09 | hr-system 审计底座 | write_audit_log(全量写操作含导入导出/审批/登录,前后值+IP+ audit_log_list.ui 详情对比 | F12 全 4 项 + SRS §2.2-5 | T02 | 2 |
### 阶段2 审批引擎(关键路径) ### 阶段2 审批引擎(关键路径)
| 编号 | 任务 | 内容/产出 | 依赖 | 估时 | | 编号 | 任务 | 内容/产出 | 验收对照 | 依赖 | 估时 |
|---|---|---|---|---| |---|---|---|---|---|---|
| T10 | hr-flow 引擎核心 | flow_form_def/flow_def/flow_node_def/flow_role 配置、flow_start 状态机、task 生成与流转、flow_match、回调 hook 机制F10 验收 1/2/3 | T02,T08 | 6 | | T10 | hr-flow 引擎核心 | flow_form_def/flow_def/flow_node_def/flow_role 配置(含考勤桩位 attendance_*、flow_start 状态机、task 生成与流转、flow_match、回调 hook 机制、init 预置人事四类流程模板 | F10 验收 1/2/3 + FEAT-B1-01 ①②③ | T02,T08 | 6 |
| T11 | hr-flow 审批界面 | todo/done/mine/received 列表、inst_detail 动态表单渲染、approve/reject/forward/withdraw、打印F10 验收 5/6 | T10 | 4 | | T11 | hr-flow 审批界面 | todo/done/mine/received 列表、inst_detail 动态表单渲染节点字段权限、approve/reject/forward/withdraw、inst_print A4 | F10 验收 6/7 + F14-4 | T10 | 4 |
| T12 | hr-flow 查询导出 | inst_query/inst_export、审批角色数据范围生效验证F10 验收 3/5 | T10,T08 | 2 | | T12 | hr-flow 查询导出 | inst_query/inst_export、审批角色数据范围生效验证 | F10 验收 3/6 + FEAT-B1-01 ④ | T10,T08 | 2 |
### 阶段3 入转调离与合同(依赖 T10 回调,可部分并行) ### 阶段3 入转调离与合同(依赖 T10 回调,可部分并行)
| 编号 | 任务 | 内容/产出 | 依赖 | 估时 | | 编号 | 任务 | 内容/产出 | 验收对照 | 依赖 | 估时 |
|---|---|---|---|---| |---|---|---|---|---|---|
| T13 | 入职管理 | entry_approval/entry_manual批量/登记表邀请与提交/黑名单校验与高亮/入职通知/复职关联F04 全 7 项) | T10,T06 | 5 | | T13 | 入职管理 | entry_approval(含证件手工录入)/entry_manual批量/**登记表邀请token+二维码+entry_register.tmpl扫码入职降级**/entry_register_submit/黑名单校验与高亮/入职通知/复职匹配 | F04 全 7 项 + FEAT-B1-05 | T10,T06 | 6 |
| T14 | 转正管理 | regular_apply自助/代发)/regular_manual/回写花名册/转正提醒接入F05 全 4 项) | T10,T06,T16 | 3 | | T14 | 转正管理 | regular_apply自助/代发)/regular_manual/回写花名册(状态+转正日期)/转正提醒接入probation_end_date 提前 7 天可配) | F05 全 4 项 + FEAT-B1-06 转正 | T10,T06,T16 | 3 |
| T15 | 调动管理 | transfer_apply含批量明细)/transfer_cancel/回写档案与花名册/调动查询F06 全 4 项) | T10,T06 | 4 | | T15 | 调动管理 | transfer_apply批量 ≥20 人明细)/transfer_cancel/回写档案+时间轴/调动查询(状态/类型/日期)/编制联动提醒接入 | F06 全 4 项 + FEAT-B1-06 调动 | T10,T06 | 4 |
| T16 | 提醒引擎 | sys_remind_rule/care_config/remind_scan转正/合同/生日/周年等场景)+ sys_messageF15 提醒类验收) | T02 | 3 | | T16 | 提醒引擎 | sys_remind_rule≥6 场景)/care_config生日/周年文案)/remind_scan转正/合同/生日/周年/退休/离职生效扫描)+ sys_messagesend_channel=sitesms/email 预留 D9 | F15 提醒类验收 1/4/5 | T02 | 3 |
| T17 | 离职管理 | leave_apply/leave_manual/交接项/办理离职/离职证明生成下载/一键黑名单/信息存储F07 全 7 项,钉钉交接留扩展点) | T10,T06 | 5 | | T17 | 离职管理 | leave_apply/leave_manual/交接项**含 dingtalk_resource 占位手工登记 D3**/到期自动生效leave_effect/离职证明 PDF 生成下载/一键黑名单/离职员工信息存储可查可改 | F07 全 7 项 + FEAT-B1-07 | T10,T06,T16 | 5 |
| T18 | 兼岗管理 | concurrent_apply/兼岗记录维护/审批通过同步花名册F08 全 3 项) | T10,T06 | 2 | | T18 | 兼岗管理 | concurrent_apply/兼岗记录维护/审批通过自动同步(状态 active供薪酬引用 | F08 全 3 项 + FEAT-B1-04 兼岗 | T10,T06 | 2 |
| T19 | 合同台账 | contract_type/template/info CRUD + 批量导入 + 合同审批(新签/续签/变更/终止)+ 到期提醒规则 + esign_stub 预留F09 全 6 项) | T10,T06,T16 | 4 | | T19 | 合同台账 | contract_type/template/info CRUD + 批量导入 + 合同审批(新签/续签/变更/终止)+ **contract_text_gen 模板生成文本D4 打印下载)** + 到期提醒规则(误差 ≤1 天)+ esign_stub/esign_status 预留 | F09 全 6 项 + FEAT-B1-08 | T10,T06,T16 | 4 |
### 阶段4 报表、工作台、员工服务与收尾 ### 阶段4 编制/项目式/报表/工作台/服务与收尾
| 编号 | 任务 | 内容/产出 | 依赖 | 估时 | | 编号 | 任务 | 内容/产出 | 验收对照 | 依赖 | 估时 |
|---|---|---|---|---| |---|---|---|---|---|---|
| T20 | 人事报表 | roster/entry/regular/transfer/leave 五类分析端点 + report_board.ui 图表F13 全 6 项,数据范围受控) | T06,T13~T17 | 4 | | T20 | 编制管理 | headcount_scheme/item CRUD + scope_json 占编范围编辑器 + headcount_check 异动联动(提醒不硬拦截)+ snapshot 快照/历史回溯 + headcount_board/config.ui | F16 全 6 项 + FEAT-B1-10 | T06,T13~T18 | 4 |
| T21 | 工作台 | workbench_employee/manager/admin 聚合端点与三页面F14 全 5 项,绩效/考勤占位预留) | T10,T11,T16 | 3 | | T21 | 项目式组织 | org_project/org_project_post CRUD + project_tree.ui + 横向职务(job_category=horizontal)维护与 options + 到期自动标识 | F17 全 3 项 + FEAT-B1-11 | T04,T06 | 3 |
| T22 | 员工服务 | 公告/政策发布与查询(查阅范围/下载权限、关怀文案配置F15 服务类验收 1~3 | T16 | 2 | | T22 | 人事报表 | roster/entry/regular/transfer/leave 五类分析端点(维度可配置)+ report_board.ui 图表 + report_export与页面一致+ 全程数据范围 | F13 全 6 项 + FEAT-B1-12 | T06,T13~T18 | 4 |
| T23 | staff-mgr 迁移 | migrate_staff_mgr.py映射/解密重加密/幂等/核对报告、UAT 双库比对、切换演练 | T06,T09 | 3 | | T23 | 工作台 | workbench_employee/manager/admin 聚合端点与三页面(**工资条/绩效/考勤桩位卡片**+ 消息铃铛 | F14 全 5 项 + FEAT-B1-09 工作台 | T10,T11,T16 | 3 |
| T24 | 集成联调与验收 | F01~F15 共 81 条验收项端到端回归;性能验证(列表 ≤500msload_path 全路径注册核查部署脚本验证dev/test | 全部 | 4 | | T24 | 员工服务 | 公告/政策发布与查询(查阅范围/下载权限、关怀文案配置、message_list | F15 服务类验收 1~3 + FEAT-B1-09 服务 | T16 | 2 |
| T25 | staff-mgr 迁移 | migrate_staff_mgr.py映射/解密重加密/幂等/--scope 参数/核对报告总数+抽样、UAT 双库比对、切换演练 | NFR-8 + SRS §11-Q3 参数化 | T06,T09 | 3 |
| T26 | API 开放预留与部署 | sys_openapp 表 + /openapi/v1/ping 桩端点部署脚本systemd/备份 crontab/监控探活脚本9182 端口测试+生产HTTPS 升级路径文档 | FEAT-B1-01 ⑦ + SRS §8 + NFR-3/5 | T02 | 3 |
| T27 | 集成联调与验收 | F01~F17 共 **90 条**验收项端到端回归;性能抽测(列表 ≤500ms/报表 ≤3s/导入 500 行 ≤30s权限与脱敏抽测SRS §10-2load_path 全路径注册核查;降级项 D1/D3/D4/D9/扫码登记 专项验证 | SRS §10 验收总纲 | 全部 | 5 |
**合计估算:约 84 人日**(不含 PM 排期缓冲。关键路径T01→T02→T10→T11→T13/T15/T17→T20/T21→T24。 **合计估算:约 92 人日**(不含 PM 排期缓冲。关键路径T01→T02→T10→T11→T13/T15/T17→T20/T22→T27
## 3. 交付与验收定义 ## 3. 交付与验收定义
- 每个 T 任务交付模块仓代码models/json/wwwroot/init/scripts/skill/SKILL.md+ 对应功能验收项自测记录。 - 每个 T 任务交付模块仓代码models/json/wwwroot/init/scripts/skill/SKILL.md+ 对应功能验收项自测记录。
- 契约变更(表结构/端点签名)必须回改 docs/01-design 四份文档并评审。 - 契约变更(表结构/端点签名)必须回改 docs/01-design 四份文档并评审。
- T24 通过标准81 条验收项全部通过或经 PM 确认降级项(扫码入职、身份证读取、钉钉交接、电子签为既定范围外/降级项)。 - T27 通过标准90 条验收项全部通过P0FEAT-B1-01~05100% 通过;降级项按 SRS §9 验证桩位与降级方案生效D1 手工录入+脱敏、D3 交接占位、D4 模板文本+NOT_ENABLED 桩、D9 站内兜底、扫码登记内网闭环);性能/权限/脱敏抽测记录齐备SRS §10
- 批次1完成即满足批次2薪酬进入条件花名册/组织/流程/报表基线 + 权限日志基线 + 消息通道SRS §1.4)。

View File

@ -1,7 +1,7 @@
# 迭代1总体设计 —— UI/页面设计hr-webocai 口径) # 一期批次1总体设计 —— UI/页面设计hr-webocai 口径)
- 版本v2.0迭代1-总体设计,取代 v1 Vue3/Element Plus 口径v1 已归档至 `docs/_archive/01-design-v1-old/ui-design.md` - 版本v3.0批次1设计定稿v3.0 变更:对齐 SRS v3.1 —— 新增编制看板(F16)/项目式组织(F17)页面、工作台工资条/绩效桩位、入职登记链接与二维码交互扫码入职降级、证件手工录入交互D1、合同文本生成打印、离职交接钉钉占位项
- 状态:评审通过主agent评审基线冻结 - 状态:**设计定稿批次1评审修订版**
- 规范依据ocai 技能集 bricks-framework、bricks-layout-patterns、module-development-specindex.ui 强制、crud-definition-spec交互基线 `docs/01-design/architecture.md` - 规范依据ocai 技能集 bricks-framework、bricks-layout-patterns、module-development-specindex.ui 强制、crud-definition-spec交互基线 `docs/01-design/architecture.md`
## 1. 界面体系与总体布局 ## 1. 界面体系与总体布局
@ -9,7 +9,7 @@
1. **技术形态**:无 Vue/无手写 HTML。页面 = `wwwroot/*.ui`(纯 JSON bricks 组件树)+ `*.dspy`数据端点CRUD 列表/表单页由 json/*.json 经 xls2ui 自动生成 DataViewer/Form/Tree 页面。 1. **技术形态**:无 Vue/无手写 HTML。页面 = `wwwroot/*.ui`(纯 JSON bricks 组件树)+ `*.dspy`数据端点CRUD 列表/表单页由 json/*.json 经 xls2ui 自动生成 DataViewer/Form/Tree 页面。
2. **入口**`/index.ui`(应用门户,菜单聚合 6 模块入口);每模块强制 `/{module}/index.ui`ResponsableBox 功能卡片导航)。 2. **入口**`/index.ui`(应用门户,菜单聚合 6 模块入口);每模块强制 `/{module}/index.ui`ResponsableBox 功能卡片导航)。
3. **权限渲染**:菜单与按钮可见性由 rbac 角色控制Menu 只注册已授权路径;操作按钮 binds 前按角色渲染)。 3. **权限渲染**:菜单与按钮可见性由 rbac 角色控制Menu 只注册已授权路径;操作按钮 binds 前按角色渲染)。
4. **核心 widgets**VBox/HBox、ResponsableBox自适应员工自助移动端兼容、Menu、DataViewer列表data_filter 筛选/toolbar binds/子表 subtables、Tree组织树、Form、PopupWindow、Chart报表、Text、FileUpload/FilePreview、UrlWidget。 4. **核心 widgets**VBox/HBox、ResponsableBox自适应员工自助移动端兼容、Menu、DataViewer列表data_filter 筛选/toolbar binds/子表 subtables、Tree组织树/项目树、Form、PopupWindow、Chart报表/编制看板、Text、FileUpload/FilePreview、UrlWidget。
5. **binds actiontype 仅 5 种**urlwidget / script / url / datawidget / event禁止 script 内 fetch弹窗走 PopupWindow + urlwidget 5. **binds actiontype 仅 5 种**urlwidget / script / url / datawidget / event禁止 script 内 fetch弹窗走 PopupWindow + urlwidget
6. **URL 规则**.ui 内全部 url 使用 `{{entire_url('/module/xxx.ui')}}` 绝对路径json/ 内引用别名用 `{{entire_url('../alias')}}` 6. **URL 规则**.ui 内全部 url 使用 `{{entire_url('/module/xxx.ui')}}` 绝对路径json/ 内引用别名用 `{{entire_url('../alias')}}`
@ -17,7 +17,7 @@
``` ```
index.ui (VBox, height:100%) index.ui (VBox, height:100%)
├── Header(HBox): Text「Web版人事系统」+ 用户信息 + [消息铃铛(message_list 未读数)] ├── Header(HBox): Text「Web版人事系统」+ 用户信息 + [消息铃铛(message_unread_count.dspy 未读数)]
├── 内容区(HBox, flex:1) ├── 内容区(HBox, flex:1)
│ ├── Menu(id:app.menu, width:220px) │ ├── Menu(id:app.menu, width:220px)
│ │ ├── 工作台 → /hrsystem/workbench_*.ui按角色路由 │ │ ├── 工作台 → /hrsystem/workbench_*.ui按角色路由
@ -25,6 +25,8 @@ index.ui (VBox, height:100%)
│ │ ├── 花名册 → /hrroster/index.ui │ │ ├── 花名册 → /hrroster/index.ui
│ │ ├── 审批中心 → /hrflow/index.ui │ │ ├── 审批中心 → /hrflow/index.ui
│ │ ├── 合同管理 → /hrcontract/index.ui │ │ ├── 合同管理 → /hrcontract/index.ui
│ │ ├── 编制管理 → /hrorg/headcount_board.uiF16
│ │ ├── 项目组织 → /hrorg/project_tree.uiF17
│ │ ├── 人事报表 → /hrreport/index.ui │ │ ├── 人事报表 → /hrreport/index.ui
│ │ ├── 员工服务 → /hrsystem/service.ui公告/政策) │ │ ├── 员工服务 → /hrsystem/service.ui公告/政策)
│ │ └── 系统管理 → /hrsystem/index.ui角色/范围/管理员/日志) │ │ └── 系统管理 → /hrsystem/index.ui角色/范围/管理员/日志)
@ -37,31 +39,36 @@ index.ui (VBox, height:100%)
| URL | 页面 | 说明 | 角色 | | URL | 页面 | 说明 | 角色 |
|---|---|---|---| |---|---|---|---|
| /index.ui | 应用门户 | 全局导航 | L | | /index.ui | 应用门户 | 全局导航 | L |
| /hrorg/index.ui | 组织模块入口 | 卡片:组织树/架构图/时间轴/职位职级/入转调离工作台/黑名单 | L | | /hrorg/index.ui | 组织模块入口 | 卡片:组织树/架构图/时间轴/职位职级/入转调离工作台/编制/项目组织/黑名单 | L |
| /hrorg/org_tree.ui | 组织管理 | Tree + 详情表单 + 变更时间轴 | L | | /hrorg/org_tree.ui | 组织管理 | Tree + 详情表单 + 变更时间轴 | L |
| /hrorg/org_chart.ui | 组织架构图 | 层级展开/as_of 历史/导出 | A,H | | /hrorg/org_chart.ui | 组织架构图 | 层级展开/as_of 历史/导出 PNG/XMind | A,H |
| /hrorg/position_list.ui 等 | 职位/职务/职级/职等/序列 CRUD | xls2ui 生成 DataViewer | A,H | | /hrorg/position_list.ui 等 | 职位/职务/职级/职等/序列 CRUD | xls2ui 生成 DataViewer | A,H |
| /hrorg/entry_workbench.ui | 入职工作台 | 待入职/审批中/黑名单高亮 | A,H | | /hrorg/company_list.ui | 合同公司台账 | CRUDFEAT-B1-02 | A,H |
| /hrorg/entry_workbench.ui | 入职工作台 | 待入职/审批中/黑名单高亮/登记二维码 | A,H |
| /hrorg/entry_register.tmpl | 入职登记表(免登录) | 候选人扫码填表页(内网 token 鉴权,扫码入职降级) | 匿名(token) |
| /hrorg/transfer_list.ui | 调动查询 | 待确定/已确定/已取消筛选 | A,H,M | | /hrorg/transfer_list.ui | 调动查询 | 待确定/已确定/已取消筛选 | A,H,M |
| /hrorg/leave_workbench.ui | 离职工作台 | 待离职名单/交接/证明 | A,H,M | | /hrorg/leave_workbench.ui | 离职工作台 | 待离职名单/交接/证明/黑名单 | A,H,M |
| /hrorg/headcount_board.ui | 编制看板F16 | 方案/细分/超缺编状态/历史回溯 | A,H,M |
| /hrorg/headcount_config.ui | 编制配置F16 | 方案+细分项+占编范围条件编辑 | A,H |
| /hrorg/project_tree.ui | 项目式组织F17 | 项目树+属性+任职维护 | L |
| /hrroster/index.ui | 花名册入口 | 卡片:花名册/字段配置/工号规则/导入导出 | A,H | | /hrroster/index.ui | 花名册入口 | 卡片:花名册/字段配置/工号规则/导入导出 | A,H |
| /hrroster/roster_list.ui | 花名册列表 | DataViewer + data_filter + 自定义列 | A,H,M(团队) | | /hrroster/roster_list.ui | 花名册列表 | DataViewer + data_filter + 自定义列 | A,H,M(团队) |
| /hrroster/employee_detail.ui | 员工档案 | Tabs 分组 + 时间轴 | L(按范围) | | /hrroster/employee_detail.ui | 员工档案 | Tabs 分组 + 时间轴(含证件信息分组,脱敏展示) | L(按范围) |
| /hrroster/field_config.ui | 字段/分组/类型规则配置 | 拖拽排序 | A,H | | /hrroster/field_config.ui | 字段/分组/类型规则配置 | 拖拽排序 | A,H |
| /hrflow/index.ui | 审批中心入口 | 待办/已办/我发起/我收到/流程配置 | L | | /hrflow/index.ui | 审批中心入口 | 待办/已办/我发起/我收到/流程配置 | L |
| /hrflow/todo_list.ui | 待办列表 | DataViewer行内审批 | L | | /hrflow/todo_list.ui | 待办列表 | DataViewer行内审批 | L |
| /hrflow/inst_detail.ui | 审批单 | 表单渲染 + 流转记录 + 操作按钮 | 参与者 | | /hrflow/inst_detail.ui | 审批单 | 表单渲染 + 流转记录 + 操作按钮 | 参与者 |
| /hrflow/flow_design.ui | 流程/表单/节点/审批角色配置 | A,H/A | A,H | | /hrflow/flow_design.ui | 流程/表单/节点/审批角色配置 | 含考勤桩位表单、四类流程模板 | A,H |
| /hrcontract/index.ui | 合同入口 | 台账/类型/模板/提醒规则 | A,H | | /hrcontract/index.ui | 合同入口 | 台账/类型/模板/提醒规则 | A,H |
| /hrcontract/contract_list.ui | 合同台账 | DataViewer + 到期高亮 | A,H | | /hrcontract/contract_list.ui | 合同台账 | DataViewer + 到期高亮 + 文本生成 | A,H |
| /hrreport/index.ui | 报表看板 | 五类分析卡片 | A,H,M | | /hrreport/index.ui | 报表看板 | 五类分析卡片 | A,H,M |
| /hrreport/report_board.ui | 看板页 | Chart 组件 | A,H,M | | /hrreport/report_board.ui | 看板页 | Chart 组件 + 导出 | A,H,M |
| /hrsystem/index.ui | 系统管理入口 | 角色/管理员/数据范围/日志/提醒配置 | A | | /hrsystem/index.ui | 系统管理入口 | 角色/管理员/数据范围/日志/提醒配置 | A |
| /hrsystem/workbench_employee.ui | 员工工作台 | 个人档案/发起审批/待办 | E | | /hrsystem/workbench_employee.ui | 员工工作台 | 个人档案/发起审批/待办;工资条/绩效桩位 | E |
| /hrsystem/workbench_manager.ui | 经理工作台 | 团队统计/入转调离审批/关怀 | M | | /hrsystem/workbench_manager.ui | 经理工作台 | 团队统计/入转调离审批/关怀;考勤/团队绩效桩位 | M |
| /hrsystem/workbench_admin.ui | 管理员工作台 | 人事统计/合同/提醒 | A,H | | /hrsystem/workbench_admin.ui | 管理员工作台 | 人事统计/合同/提醒 | A,H |
| /hrsystem/audit_log_list.ui | 操作日志 | DataViewer + 详情对比弹窗 | A | | /hrsystem/audit_log_list.ui | 操作日志 | DataViewer + 详情对比弹窗 | A |
| /hrsystem/service.ui | 员工服务 | 公告/政策查询预览 | L | | /hrsystem/service.ui | 员工服务 | 公告/政策查询预览(下载按权限) | L |
| /hrsystem/message_list.ui | 站内消息 | 未读/已读 | L | | /hrsystem/message_list.ui | 站内消息 | 未读/已读 | L |
## 3. 关键页面结构与组件树 ## 3. 关键页面结构与组件树
@ -79,9 +86,9 @@ org_tree.ui (HBox)
│ 字段: org_code/org_name/org_type(codes:ORG_TYPE)/leader_id(dataurl:employee_options)/effective_date/自定义字段(动态渲染 org_field_def) │ 字段: org_code/org_name/org_type(codes:ORG_TYPE)/leader_id(dataurl:employee_options)/effective_date/自定义字段(动态渲染 org_field_def)
├── 操作按钮行: [编辑][移动(PopupWindow)][停用(二次确认)] ← A/H 角色可见 ├── 操作按钮行: [编辑][移动(PopupWindow)][停用(二次确认)] ← A/H 角色可见
└── 变更时间轴 VBox(id:org_timeline, dataurl=/hrorg/api/org_change_timeline.dspy) └── 变更时间轴 VBox(id:org_timeline, dataurl=/hrorg/api/org_change_timeline.dspy)
每条: Text(时间+操作人+类型) + before/after 对比展开 每条: Text(时间+操作人+类型 add/edit/disable/move/split/merge) + before/after 对比展开
``` ```
交互Tree 节点点击 → urlwidget 刷新 org_detail 与 org_timelineparams_mapping 传 id停用前弹确认 PopupWindow停用后该组织在入职/调动表单 options 中不可选(服务端过滤 status=active 交互Tree 节点点击 → urlwidget 刷新 org_detail 与 org_timelineparams_mapping 传 id停用前弹确认 PopupWindow停用后该组织在入职/调动表单 options 中不可选(服务端过滤 status=active;组织移动后员工任职部门随组织联动(服务端处理,页面提示影响人数)
### 3.2 组织架构图 /hrorg/org_chart.uiF01 ### 3.2 组织架构图 /hrorg/org_chart.uiF01
@ -90,16 +97,16 @@ org_chart.ui (VBox)
├── 工具行(HBox): DatePicker(as_of 历史日期) + TreeSelect(根节点) + 显示内容多选(姓名/职位/负责人) + Button[查看][导出PNG][导出XMind] ├── 工具行(HBox): DatePicker(as_of 历史日期) + TreeSelect(根节点) + 显示内容多选(姓名/职位/负责人) + Button[查看][导出PNG][导出XMind]
└── Chart/Tree 容器(id:chart_box, dataurl=/hrorg/api/org_tree.dspy?as_of=..&root_id=..) └── Chart/Tree 容器(id:chart_box, dataurl=/hrorg/api/org_tree.dspy?as_of=..&root_id=..)
``` ```
交互as_of 变更后重查;导出经 PopupWindow 提示后浏览器下载org_chart_export.dspy 返回文件)。 交互as_of 变更后重查(按生效时间重建当时结构);导出经 PopupWindow 提示后浏览器下载org_chart_export.dspy 返回文件)。
### 3.3 花名册列表 /hrroster/roster_list.uiF03CRUD 生成) ### 3.3 花名册列表 /hrroster/roster_list.uiF03CRUD 生成)
``` ```
roster_list.ui = DataViewer(json/roster_employee_list.json 生成) roster_list.ui = DataViewer(json/roster_employee_list.json 生成)
├── data_filter: keyword(姓名/工号 LIKE) + org_id(TreeSelect:org_options) + employee_status(codes) + employee_type(codes) + 自定义字段筛选(动态追加) ├── data_filter: keyword(姓名/工号 LIKE) + org_id(TreeSelect:org_options) + employee_status(codes) + employee_type(codes) + 自定义字段筛选(动态追加≤3 项)
├── toolbar binds: ├── toolbar binds:
│ ├── [新增员工] → PopupWindow → roster_employee_create.dspy │ ├── [新增员工] → PopupWindow → roster_employee_create.dspy(含证件信息分组:证件类型/号码/有效期起止/签发机关,手工录入 D1
│ ├── [导入] → PopupWindow: 模板下载链接 + FileUpload(roster_import.dspy) + 结果文件下载 │ ├── [导入] → PopupWindow: 模板下载链接 + FileUpload(roster_import.dspy, mode=new/update) + 结果文件下载
│ ├── [导出] → PopupWindow: 字段多选(拖拽排序) + as_of 日期 → roster_export.dspy │ ├── [导出] → PopupWindow: 字段多选(拖拽排序) + as_of 日期 → roster_export.dspy
│ └── [字段配置] → url 跳转 field_config.uiA/H │ └── [字段配置] → url 跳转 field_config.uiA/H
├── 列: 工号/姓名(点击→employee_detail.ui?id=)/组织/职位/员工类型/状态/入职日期 + 自定义显示列 ├── 列: 工号/姓名(点击→employee_detail.ui?id=)/组织/职位/员工类型/状态/入职日期 + 自定义显示列
@ -112,14 +119,15 @@ roster_list.ui = DataViewer(json/roster_employee_list.json 生成)
employee_detail.ui (VBox) employee_detail.ui (VBox)
├── 头部卡片(HBox): 头像 + 姓名/工号/状态标签 + 快捷操作[编辑][发起审批](PopupWindow 选择 biz_type) ├── 头部卡片(HBox): 头像 + 姓名/工号/状态标签 + 快捷操作[编辑][发起审批](PopupWindow 选择 biz_type)
├── Tabs(id:profile_tabs) ├── Tabs(id:profile_tabs)
│ ├── Tab 分组字段(按 roster_field_group 动态生成): Form 只读/可编辑(按 editable_self+角色) │ ├── Tab 分组字段(按 roster_field_group 动态生成证件信息组展示脱敏证件号前3后3+有效期+签发机关: Form 只读/可编辑(按 editable_self+角色)
│ ├── Tab 时间轴(id:timeline, dataurl=timeline.dspy, 垂直时间线) + [添加记录](A/H) │ ├── Tab 时间轴(id:timeline, dataurl=timeline.dspy, 垂直时间线) + [添加记录](A/H)
│ ├── Tab 兼岗记录(DataViewer subtables: org_concurrent_post by employee_id) │ ├── Tab 兼岗记录(DataViewer subtables: org_concurrent_post by employee_id)
│ ├── Tab 合同(DataViewer subtables: contract_info by employee_id) │ ├── Tab 合同(DataViewer subtables: contract_info by employee_id)
│ ├── Tab 项目任职F17org_project_post by employee_id横向项目+横向职务)
│ └── Tab 审批记录(dataurl=inst_mine.dspy?about=..) │ └── Tab 审批记录(dataurl=inst_mine.dspy?about=..)
└── 附件: 字段类型=file → FileUpload + FilePreview(file_preview_url.dspy) └── 附件: 字段类型=file → FileUpload + FilePreview(file_preview_url.dspy)
``` ```
交互自助修改——employee 角色仅看到 editable_self=1 字段可编辑;提交时若字段 need_audit=1服务端走 roster_self_edit 审批流,页面提示"已提交审核";否则直接生效。 交互自助修改——employee 角色仅看到 editable_self=1 字段可编辑;提交时若字段 need_audit=1服务端走 roster_self_edit 审批流,页面提示"已提交审核";否则直接生效。复职员工档案头部显示"复职"标签并链接原档案prev_employee_id
### 3.5 入转调离工作台F04~F07 ### 3.5 入转调离工作台F04~F07
@ -127,17 +135,20 @@ employee_detail.ui (VBox)
entry_workbench.ui (VBox) entry_workbench.ui (VBox)
├── 状态卡片行(ResponsableBox): 待入职数/审批中数/本月入职数dataurl=workbench_transfer.dspy ├── 状态卡片行(ResponsableBox): 待入职数/审批中数/本月入职数dataurl=workbench_transfer.dspy
├── 待入职列表 DataViewer(org_entry by entry_status=pending_entry) ├── 待入职列表 DataViewer(org_entry by entry_status=pending_entry)
│ ├── 黑名单命中行: 高亮样式(confidential_fields/行样式) + [拦截原因] │ ├── 黑名单命中行: 高亮样式 + [拦截原因]BLACKLIST_HIT
│ └── 行操作: [邀请填登记表][发送入职通知][直接入花名册] │ ├── 登记表状态列: none/invited/filled + [复制链接][二维码(PopupWindow 展示二维码图片+有效期)]
└── 工具行: [手动入职(批量 PopupWindow)][发起入职审批] │ └── 行操作: [邀请填登记表(entry_invite_register.dspy)][发送入职通知][直接入花名册][复职匹配提示(命中历史档案时高亮)]
└── 工具行: [手动入职(批量 PopupWindow)][发起入职审批(含证件信息手工录入分组)]
transfer_list.ui: DataViewer(org_transfer) + data_filter(status=pending/confirmed/cancelled, transfer_type, effective_date) transfer_list.ui: DataViewer(org_transfer) + data_filter(status=pending/confirmed/cancelled, transfer_type, effective_date)
行操作: [查看明细(org_transfer_detail subtable)][取消](pending 状态) 行操作: [查看明细(org_transfer_detail subtable批量逐人)][取消](pending 状态)
[发起调动] PopupWindow: 多人选择(批量) + 调动类型 + 生效日期 + 逐人目标组织/职位/职级
leave_workbench.ui (VBox) leave_workbench.ui (VBox)
├── 待离职名单 DataViewer(org_leave by status=pending_leave) ├── 待离职名单 DataViewer(org_leave by status=pending_leave)
│ 行操作: [交接管理(PopupWindow: org_leave_handover 编辑)][办理离职][开具证明][加入黑名单(确认弹窗)] │ 行操作: [交接管理(PopupWindow: org_leave_handover 编辑,交接项类型含"钉钉资源交接(占位,手工登记内容)")][办理离职][开具证明][加入黑名单(确认弹窗)]
└── 已离职列表 DataViewer(status=left) + [离职证明下载] ├── 交接完成率: 每个离职单展示交接项完成进度条done/total
└── 已离职列表 DataViewer(status=left) + [离职证明下载(PDF)] + [加入黑名单]
``` ```
### 3.6 审批中心F10 ### 3.6 审批中心F10
@ -149,16 +160,44 @@ todo_list.ui = DataViewer(dataurl=task_todo.dspy)
inst_detail.ui (VBox) inst_detail.ui (VBox)
├── 表单渲染区(id:form_box, dataurl=inst_detail.dspy) —— 按 flow_form_def 动态渲染,节点字段权限控制可编辑性 ├── 表单渲染区(id:form_box, dataurl=inst_detail.dspy) —— 按 flow_form_def 动态渲染,节点字段权限控制可编辑性
├── 流转记录 VBox: 节点链(提交→各审批人意见/时间) ├── 流转记录 VBox: 节点链(提交→各审批人意见/时间)
└── 操作行(binds urlwidget POST): [同意(task_approve.dspy)][驳回(task_reject.dspy)][转交(PopupWindow 选人)][撤回(发起人)][打印(inst_print.dspy)] └── 操作行(binds urlwidget POST): [同意(task_approve.dspy)][驳回(task_reject.dspy)][转交(PopupWindow 选人)][撤回(发起人)][打印(inst_print.dspyA4 版式)]
操作完成后 script 刷新页面 → 列表刷新 操作完成后 script 刷新页面 → 列表刷新
flow_design.ui (A/H): 三区块 flow_design.ui (A/H): 三区块
├── 表单定义 DataViewer(flow_form_def) + 字段引用器(勾选 roster_field_def) ├── 表单定义 DataViewer(flow_form_def) + 字段引用器(勾选 roster_field_defbiz_type 含考勤桩位 attendance_* 分组提示"桩位,不联动考勤系统")
├── 流程定义 DataViewer(flow_def) + 节点编辑 PopupWindow(审批人类型/通过规则/字段权限) ├── 流程定义 DataViewer(flow_def,含初始化预置的人事四类模板:入职/转正/异动/离职/离职交接) + 节点编辑 PopupWindow(审批人类型/通过规则 any-all/字段权限/抄送)
└── 审批角色 DataViewer(flow_role, 仅 admin) └── 审批角色 DataViewer(flow_role, 仅 admin;三维配置:流程范围/操作权限/数据查看)
``` ```
### 3.7 报表看板 /hrreport/report_board.uiF13 ### 3.7 编制管理F16新增
```
headcount_config.ui (A/H) (VBox)
├── 编制方案 DataViewer(org_headcount_scheme): 方案名/周期类型(年/季/月)/起止/状态 行操作:[编辑][停用]
└── [新增方案] PopupWindow + 方案展开行内编辑细分项:
细分项表格(headcount_item): 占编范围条件编辑器(scope_json: 员工类型/状态/职位/职级/自定义字段多条件) + 细分维度(seg_json) + 编制数量(head_limit)
headcount_board.ui (VBox)
├── 顶部: 方案选择器 + 快照日期 DatePicker(历史回溯)
├── 状态卡片区(ResponsableBox): 总编制/在编/超编/缺编
├── Chart(柱状: 各细分项 head_limit vs used_count超编红色标注) dataurl=headcount_status.dspy
└── 明细 DataViewer: 细分项/编制数/占编数/超编数/缺编数(超编行红色高亮 + 提醒消息入口)
交互:异动(入转调)生效后看板 ≤1 分钟刷新(事件触发重算);历史日期选择 → headcount_history.dspy 按快照取数。
```
### 3.8 项目式组织F17新增
```
project_tree.ui (HBox)
├── 左侧 VBox: Tree(org_project 多层级) + [新增项目][新增子项目]
└── 右侧 VBox
├── 项目详情 Form: 编码/名称/负责人/时间范围(到期自动标识 expired 状态)/属性(attrs_json)
└── 项目任职 DataViewer(org_project_post): 员工/横向职务(horizontal_job_options)/起止日期
行操作:[添加任职(PopupWindow 选人+选横向职务)][移除]
交互员工同时挂纵向部门roster_employee.org_id与横向项目横向职务数据可被花名册任职信息与薪酬模块引用options 端点)。
```
### 3.9 报表看板 /hrreport/report_board.uiF13
``` ```
report_board.ui (VBox) report_board.ui (VBox)
@ -167,71 +206,92 @@ report_board.ui (VBox)
├── 入职 Tab: 维度(部门/地区/岗位) + 周期选择 + Chart(趋势折线 + 分布柱) ├── 入职 Tab: 维度(部门/地区/岗位) + 周期选择 + Chart(趋势折线 + 分布柱)
├── 转正 Tab: Chart(趋势) + 近期待转正 DataViewer(regular_analysis.dspy) ├── 转正 Tab: Chart(趋势) + 近期待转正 DataViewer(regular_analysis.dspy)
├── 调岗 Tab: 日期范围 + Chart(按类型柱状) ├── 调岗 Tab: 日期范围 + Chart(按类型柱状)
└── 离职 Tab: 卡片(待离职人数/离职率/同比/环比) + Chart(离职原因饼图) ├── 离职 Tab: 卡片(待离职人数/离职率/同比/环比) + Chart(离职原因饼图)
└── 各 Tab 右上 [导出] → report_export.dspy与页面数据一致
``` ```
所有看板查询服务端叠加数据范围manager 仅见团队。 所有看板查询服务端叠加数据范围manager 仅见团队。
### 3.8 系统管理F11/F12/F15 ### 3.10 合同管理F09
```
contract_list.ui = DataViewer(contract_info)
├── data_filter: 员工/类型/合同公司/状态/到期日期前
├── toolbar: [新增合同][批量导入][类型管理][模板管理][提醒规则]
├── 行操作: [发起审批(新签/续签/变更/终止 PopupWindow 选类型)][生成合同文本(contract_text_gen.dspy按模板填充下载 docx/pdf 供打印——电子签二期)][到期高亮(end_date 临近橙色)]
└── 模板管理页: contract_template CRUD + 占位符映射编辑(field_marks_json)
```
### 3.11 系统管理F11/F12/F15
``` ```
index.ui(hrsystem): 卡片导航 → role_admin.ui / data_scope.ui / audit_log_list.ui / remind_config.ui / service.ui index.ui(hrsystem): 卡片导航 → role_admin.ui / data_scope.ui / audit_log_list.ui / remind_config.ui / service.ui
role_admin.ui: DataViewer(角色) + 权限树勾选 PopupWindow(rbac paths) role_admin.ui: DataViewer(角色) + 权限树勾选 PopupWindow(rbac paths)
data_scope.ui: 管理员列表 + 范围编辑 PopupWindow(scope_type 切换: 组织 TreeSelect 多选 / 花名册字段多选) data_scope.ui: 管理员列表 + 范围编辑 PopupWindow(scope_type 切换: 组织 TreeSelect 多选(含子树) / 花名册字段多选;两类可叠加)
audit_log_list.ui: DataViewer(module/operation/date_range 筛选) + 行[详情] → PopupWindow 前后 JSON 对比(左右双栏 Text) audit_log_list.ui: DataViewer(module/operation/date_range 筛选) + 行[详情] → PopupWindow 前后 JSON 对比(左右双栏 Text)
remind_config.ui: DataViewer(sys_remind_rule) + DataViewer(sys_care_config) remind_config.ui: DataViewer(sys_remind_rule场景≥6 类 entry/regular/leave/retire/contract_expire/health_cert/social_insurance/custom) + DataViewer(sys_care_config 生日/周年文案)
service.ui: Tabs[公告 DataViewer(sys_announcement)][政策 DataViewer(sys_policy, 行内预览/下载按权限)] service.ui: Tabs[公告 DataViewer(sys_announcement 在线预览)][政策 DataViewer(sys_policy, 行内预览/下载按 view_scope+downloadable 权限)]
message_list.ui: DataViewer(msg_type/is_read 筛选) 行点击标已读 message_list.ui: DataViewer(msg_type/is_read 筛选) 行点击标已读
``` ```
### 3.9 工作台F14 ### 3.12 工作台F14
``` ```
workbench_employee.ui (ResponsableBox) workbench_employee.ui (ResponsableBox 移动端自适应)
├── 卡片: 个人档案(→employee_detail.ui?id=self) | 发起审批(PopupWindow 选择流程类型→flow_start) ├── 卡片: 个人档案(→employee_detail.ui?id=self) | 工资条(桩位卡片:显示"薪酬模块上线后可用"FEAT-B1-09) | 个人绩效(桩位:同上) | 发起审批(PopupWindow 选择流程类型→flow_start)
├── 待办/已办/我发起/我收到 四 Tab DataViewer(task_todo/done/inst_mine/received) ├── 待办/已办/我发起/我收到 四 Tab DataViewer(task_todo/done/inst_mine/received)
└── 企业政策/公告入口(service.ui)
workbench_manager.ui (VBox) workbench_manager.ui (VBox)
├── 统计卡片行(dataurl=team_stats.dspy): 团队人数/本月入离职/待审批数 ├── 统计卡片行(dataurl=team_stats.dspy): 团队人数/本月入离职/待审批数(考勤统计/团队绩效为桩位卡片"未接入"
├── 待审批 DataViewer(task_todo 范围=团队) | 团队入转调离 DataViewer(workbench_transfer.dspy) ├── 待审批 DataViewer(task_todo 范围=团队) | 团队入转调离 DataViewer(workbench_transfer.dspy scope=team)
└── 关怀提醒 VBox(生日/周年/合同到期 近期列表) └── 关怀提醒 VBox(生日/周年/合同到期 近期列表)
workbench_admin.ui (VBox) workbench_admin.ui (VBox)
├── 人事统计卡片(team_stats scope=all) + 合同即将到期 DataViewer(contract_expire_soon.dspy) ├── 人事统计卡片(team_stats scope=all) + 合同即将到期 DataViewer(contract_expire_soon.dspy) + 编制超编提醒入口(headcount_board.ui)
└── 待审批 + 关怀提醒(同经理视图,范围=数据权限内全部) └── 待审批 + 关怀提醒(同经理视图,范围=数据权限内全部)
``` ```
## 4. 核心交互流程(页面级时序) ## 4. 核心交互流程(页面级时序)
1. **入职(审批)**entry_workbench [发起入职审批] → PopupWindow 表单 → entry_approval.dspy →BLACKLIST_HIT 则红色高亮提示)成功 → 待审批列表出现;审批人在 todo_list 处理 → inst_detail 同意 → 花名册新增记录 → message_list 收到入职通知。 1. **入职(审批)**entry_workbench [发起入职审批] → PopupWindow 表单(含证件信息手工录入分组)→ entry_approval.dspy →BLACKLIST_HIT 则红色高亮提示)成功 → 待审批列表出现;审批人在 todo_list 处理 → inst_detail 同意 → 花名册新增记录 → message_list 收到入职通知。
2. **员工自助修改**employee_detail → 编辑可改字段 → 保存 → 提示"直接生效"或"已提交审核"need_audit→ 审核通过后字段更新、时间轴留痕。 2. **入职登记表(扫码降级)**:待入职行 [邀请填登记表] → 生成链接+二维码PopupWindow 展示,内网访问)→ 候选人扫码打开 entry_register.tmpl → 填写提交 → 列表登记表状态 filled → 继续审批/入职。
3. **调动批量**transfer_list [发起调动] → PopupWindow 多人选择 + 目标组织/职位 → transfer_apply.dspy → 生成批量审批单 → 通过后逐人更新,明细可追溯。 3. **复职**:发起入职审批输入证件号 → entry_rehire_match 命中历史档案 → 表单提示"复职:原部门/职位"并自动带出关联 → 入职后档案显示复职标签。
4. **离职全流程**leave_workbench 发起/手动 → 待离职名单 → [交接管理]逐项勾选 → [办理离职] → 状态 left → [开具证明]下载 → 可选[加入黑名单]。 4. **员工自助修改**employee_detail → 编辑可改字段 → 保存 → 提示"直接生效"或"已提交审核"need_audit→ 审核通过后字段更新、时间轴留痕。
5. **合同到期提醒**remind_scan后台→ message_list 消息 → workbench_admin 到期卡片 → contract_list 行内到期高亮。 5. **调动批量**transfer_list [发起调动] → PopupWindow 多人选择 + 调动类型 + 逐人目标 → transfer_apply.dspy → 生成批量审批单 → 通过后逐人更新(明细可追溯)→ 编制联动校验提醒。
6. **历史架构图**org_chart 选择 as_of 日期 → 查看 → 导出 PNG/XMind。 6. **离职全流程**leave_workbench 发起/手动 → 待离职名单 → [交接管理]逐项勾选(含钉钉资源占位项手工登记)→ 到期自动生效remind_scan→leave_effect→ [开具证明]下载 PDF → 可选[加入黑名单]。
7. **合同到期提醒**remind_scan后台→ message_list 消息 → workbench_admin 到期卡片 → contract_list 行内到期高亮 → [生成合同文本]续签打印。
8. **历史架构图**org_chart 选择 as_of 日期 → 查看 → 导出 PNG/XMind。
9. **编制看板**headcount_config 配置方案与细分(占编范围条件)→ headcount_board 实时查看超/缺编 → 异动后自动刷新并推送超编提醒 → 选择历史日期回溯快照。
## 5. 设计规范 ## 5. 设计规范
1. **布局**:左侧 Menu 固定 220px内容区 VBox 滚动;卡片统一圆角 8px、间距 16px表单 label 右对齐;列表默认每页 50。 1. **布局**:左侧 Menu 固定 220px内容区 VBox 滚动;卡片统一圆角 8px、间距 16px表单 label 右对齐;列表默认每页 50。
2. **状态色**active/在职=绿、probation/审批中=橙、inactive/离职/驳回=灰、黑名单/超期=红。 2. **状态色**active/在职=绿、probation/审批中=橙、inactive/离职/驳回=灰、黑名单/超编/到期=红。
3. **反馈**:操作成功 message 提示并刷新当前视图;不可逆操作(停用/删除语义/加黑名单)一律 PopupWindow 二次确认;耗时操作(导入导出)返回 task_id 后轮询/消息通知结果。 3. **反馈**:操作成功 message 提示并刷新当前视图;不可逆操作(停用/加黑名单)一律 PopupWindow 二次确认;耗时操作(导入导出)返回 task_id 后轮询/消息通知结果。
4. **空态/加载**DataViewer 自带 loading 与空数据提示。 4. **空态/加载**DataViewer 自带 loading 与空数据提示;桩位卡片(工资条/绩效/考勤)统一"未接入"样式与文案
5. **权限感知**按钮与列按角色渲染load_path + CRUD confidential_fields敏感字段服务端脱敏后展示。 5. **权限感知**按钮与列按角色渲染load_path + CRUD confidential_fields敏感字段服务端脱敏后展示证件号前3后3、手机前3后4
6. **移动端兼容**:员工自助页面(工作台/档案/待办/服务/消息)使用 ResponsableBox 自适应,窄屏卡片化;管理类页面 PC 优先。 6. **移动端兼容**:员工自助页面(工作台/档案/待办/服务/消息/登记表)使用 ResponsableBox 自适应,窄屏卡片化;管理类页面 PC 优先NFR-6
7. **打印**:审批单 inst_print.dspy 输出 A4 打印样式页面。 7. **打印**:审批单 inst_print.dspy 输出 A4 打印样式页面;合同文本 docx/pdf 直接打印
## 6. 页面-接口追溯 ## 6. 页面-接口追溯
| 页面 | 主要接口(见 api-design.md | | 页面 | 主要接口(见 api-design.md |
|---|---| |---|---|
| org_tree.ui | org_tree / org_unit_create / org_unit_update / org_unit_move / org_unit_disable / org_change_timeline / org_import | | org_tree.ui | org_tree / org_unit_create / org_unit_update / org_unit_move / org_unit_disable / org_change_timeline / org_import / org_field_def_save |
| org_chart.ui | org_tree(as_of) / org_chart_export | | org_chart.ui | org_tree(as_of) / org_chart_export |
| roster_list.ui | roster_list / roster_employee_create / roster_import / roster_export / check_employee_no | | company_list.ui | company_saveCRUD |
| employee_detail.ui | employee_detail / roster_employee_update / timeline / file_preview_url | | position_list.ui 等 | position/job/grade/rank/sequence CRUD + *_import/_export + *_options |
| entry_workbench.ui | entry_approval / entry_manual / entry_invite_register / entry_blacklist_check / entry_notify | | roster_list.ui | roster_list / roster_employee_create / roster_import / roster_export / check_employee_no / roster_field_def_save |
| employee_detail.ui | employee_detail / roster_employee_update / timeline / timeline_add / file_preview_url |
| entry_workbench.ui | entry_approval / entry_manual / entry_invite_register / entry_qrcode / entry_blacklist_check / entry_notify / entry_rehire_match |
| entry_register.tmpl | entry_register_page / entry_register_submit |
| transfer_list.ui | transfer_apply / transfer_cancel | | transfer_list.ui | transfer_apply / transfer_cancel |
| leave_workbench.ui | leave_apply / leave_manual / leave_handover_save / leave_certificate / blacklist_add | | leave_workbench.ui | leave_apply / leave_manual / leave_handover_save / leave_certificate / blacklist_add |
| headcount_config.ui / headcount_board.ui | headcount_scheme_save / headcount_item_save / headcount_status / headcount_history |
| project_tree.ui | project_tree / project_save / project_post_save / horizontal_job_options |
| todo_list.ui / inst_detail.ui | task_todo / inst_detail / task_approve / task_reject / task_forward / inst_withdraw / inst_print | | todo_list.ui / inst_detail.ui | task_todo / inst_detail / task_approve / task_reject / task_forward / inst_withdraw / inst_print |
| flow_design.ui | form_def_save / flow_def_save / flow_node_save / flow_role_save | | flow_design.ui | form_def_save / flow_def_save / flow_node_save / flow_role_save / flow_match |
| contract_list.ui | contract_list / contract_create / contract_import / contract_apply / contract_remind_rule_save | | contract_list.ui | contract_list / contract_create / contract_import / contract_apply / contract_text_gen / contract_remind_rule_save / contract_template_save / esign_stub |
| report_board.ui | roster_analysis / entry_analysis / regular_analysis / transfer_analysis / leave_analysis | | report_board.ui | roster_analysis / entry_analysis / regular_analysis / transfer_analysis / leave_analysis / report_export |
| workbench_*.ui | workbench_employee / workbench_manager / workbench_admin / team_stats | | workbench_*.ui | workbench_employee / workbench_manager / workbench_admin / team_stats / contract_expire_soon |
| audit_log_list.ui | audit_log_list / audit_log_detail | | audit_log_list.ui | audit_log_list / audit_log_detail |
| remind_config.ui / service.ui | remind_rule_save / care_config_save / announcement_save / policy_save | | remind_config.ui / service.ui | remind_rule_save / care_config_save / announcement_save / policy_save / policy_download |
| message_list.ui | message_list / message_read / message_unread_count |