From e6b266fee7723de4e759076ced47eea086d57250 Mon Sep 17 00:00:00 2001 From: Pipeline Agent Date: Wed, 19 Aug 2026 16:08:16 +0800 Subject: [PATCH] =?UTF-8?q?design:=20=E4=B8=80=E6=9C=9F=E6=89=B9=E6=AC=A11?= =?UTF-8?q?=E7=BB=84=E7=BB=87=E4=BA=BA=E4=BA=8B=E5=BA=95=E5=BA=A7(F01~F17)?= =?UTF-8?q?=E8=AE=BE=E8=AE=A1=E8=AF=84=E5=AE=A1=E5=AE=9A=E7=A8=BF=EF=BC=88?= =?UTF-8?q?=E5=AF=B9=E9=BD=90SRS=20v3.1=EF=BC=9A=E8=8C=83=E5=9B=B4?= =?UTF-8?q?=E6=89=A9=E5=85=A5=E7=BC=96=E5=88=B6F16/=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E5=BC=8FF17=E3=80=8149=E8=A1=A8DDL=E3=80=81=E7=BA=A6120?= =?UTF-8?q?=E7=AB=AF=E7=82=B9=E3=80=81UI=E9=A1=B5=E9=9D=A2=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E6=A0=91=E3=80=81=E9=99=8D=E7=BA=A7=E9=A1=B9D1/D3/D4/?= =?UTF-8?q?D9=E6=96=B9=E6=A1=88=E4=B8=8E=E4=BA=8C=E6=9C=9F=E9=A2=84?= =?UTF-8?q?=E7=95=99=E3=80=81=E9=9D=A2=E5=90=91develop=E4=BB=BB=E5=8A=A1?= =?UTF-8?q?=E6=8B=86=E8=A7=A3T01~T27=E3=80=81=E9=83=A8=E7=BD=B2=E5=8F=A3?= =?UTF-8?q?=E5=BE=849182/MariaDB=20hrs=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/00-requirement/requirement-spec.md | 398 +++++++++++++++++++- docs/01-design/api-design.md | 178 +++++---- docs/01-design/architecture.md | 237 +++++++----- docs/01-design/database-design.md | 299 ++++++++++----- docs/01-design/feature-list.md | 70 ++-- docs/01-design/iteration1-task-breakdown.md | 141 +++---- docs/01-design/ui-design.md | 194 ++++++---- 7 files changed, 1106 insertions(+), 411 deletions(-) diff --git a/docs/00-requirement/requirement-spec.md b/docs/00-requirement/requirement-spec.md index 8046230..e26328b 100644 --- a/docs/00-requirement/requirement-spec.md +++ b/docs/00-requirement/requirement-spec.md @@ -1 +1,397 @@ -见 git 仓库 git@git.opencomputing.cn:yumoqing/hr-system.git(main 分支,提交 7926505)路径 docs/00-requirement/requirement-spec.md —— 《人事系统一期需求规格说明书》SRS v3.1 全文(12 章,29 项 FEAT 规格)。配套文档同目录:approved-features.md(29 项 feature 基线)、requirement-traceability.md(xlsx→feature 100% 覆盖追溯矩阵)、iteration1-function-detail.md(F01~F15 共 81 条可验收项);应用/模块定义见 apps/hr-web.md 与 modules/hr-*.md(8 个模块)。 \ No newline at end of file +# 人事系统一期 需求规格说明书(SRS) + +- 文档编号:HR-SRS-2026-001 +- 版本:v3.1(2026-08-18,针对 QC 退回意见复核修订:修正批次条目计数、统一模块文档引用口径、补充中文标题命名;v3.0 补齐全部规格内容并落仓) +- 状态:提交评审(agent.requirement 正式交付件;本文档即《人事系统一期需求规格说明书》) +- 迭代:人事系统-初始迭代(ID:k1bIV7ab0-_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 声明式页面,后端 ahserver(Python),数据层 apppublic/sqlor(MariaDB) + +--- + +## 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 | 性能 | 列表页查询 ≤500ms(100 人规模、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 | +| 应用端口 | 9182(Web + 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/*.md(F01~F15) | diff --git a/docs/01-design/api-design.md b/docs/01-design/api-design.md index 7f80bd7..6203743 100644 --- a/docs/01-design/api-design.md +++ b/docs/01-design/api-design.md @@ -1,14 +1,14 @@ -# 迭代1总体设计 —— API/接口设计(hr-web,ocai 口径) +# 一期批次1总体设计 —— API/接口设计(hr-web,ocai 口径) -- 版本:v2.0(迭代1-总体设计,取代 v1 Spring Boot/JWT RESTful 口径,v1 已归档至 `docs/_archive/01-design-v1-old/api-design.md`) -- 状态:评审通过(主agent评审,基线冻结) +- 版本:v3.0(批次1设计定稿;v3.0 变更:对齐 SRS v3.1 —— 新增编制管理(F16)/项目式组织(F17)端点、入职登记链接与二维码端点(扫码入职降级)、合同文本生成端点(D4)、证件手工录入字段契约(D1)、开放接口桩端点、错误码扩充) +- 状态:**设计定稿(批次1评审修订版)** - 规范依据: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` 块内 return(NoneType 陷阱)。 -2. **鉴权**:session cookie(Redis 会话)+ rbac 路径级角色控制;每条路径经各模块 `scripts/load_path.py` 注册,角色:`admin / hr / manager / employee / logined`;未注册路径默认拒绝。不使用 JWT。 -3. **数据范围**:查询类接口强制叠加 `get_data_scope(user_id)`(hr-system 提供),范围外数据不可见。 +2. **鉴权**:session cookie(Redis 会话)+ rbac 路径级角色控制;每条路径经各模块 `scripts/load_path.py` 注册,角色:`admin / hr / manager / employee / logined`;未注册路径默认拒绝(SRS §2.2-1)。不使用 JWT。 +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 顶层。 5. **统一响应结构**: - 列表:`{"status":"success","data":{"rows":[...],"total":N}}`(DataViewer 强制格式) @@ -20,85 +20,102 @@ |---|---|---| | PARAM_INVALID | 参数缺失/格式错误 | 必填项为空、日期格式错 | | NOT_FOUND | 对象不存在 | id 无效 | -| DUPLICATE | 唯一冲突 | 工号/编码重复 | +| DUPLICATE | 唯一冲突 | 工号/组织编码/项目编码重复 | | NO_PERMISSION | 数据范围外/角色不足 | 越权访问他人档案 | -| BLACKLIST_HIT | 黑名单命中 | 入职校验拦截 | +| BLACKLIST_HIT | 黑名单命中 | 入职校验拦截(F04-6) | | STATUS_CONFLICT | 状态不允许 | 已离职再调动、重复审批 | | FLOW_NOT_MATCH | 无匹配审批流 | 该员工类型/部门未配置流程 | -| SCOPE_OVERDRAFT | 编制/范围超限 | 预留(编制管理范围外) | +| HEADCOUNT_OVER | 编制超编提醒(不硬拦截) | 入转调联动编制校验(F16,SRS 验收"提醒不硬拦截") | +| NOT_ENABLED | 功能未启用(桩位) | esign_stub / openapi ping(降级项) | +| REGISTER_EXPIRED | 登记表链接过期 | 入职登记二维码超时 | | INTERNAL_ERROR | 服务异常 | 兜底 | 7. **审计**:所有写接口成功后调用 `write_audit_log(module,target_type,target_id,op,before,after)`(hr-system)。 +8. **敏感字段**:响应中身份证一律脱敏(前3后3)、手机(前3后4)、sensitive=1 字段按角色矩阵过滤,服务端处理后返回。 ## 2. 端点清单(按模块) > 角色列:A=admin,H=hr,M=manager,E=employee,L=任意登录。数据范围=是 表示叠加数据范围过滤。 > CRUD 列:该表的标准增删改查由 json/*.json 自动生成,路径为 `/{module}/{tblname}_list`(页面) + `add_/update_/delete_{tblname}.dspy`。 -### 2.1 hr-org(/hrorg,F01/F02/F04~F08) +### 2.1 hr-org(/hrorg,F01/F02/F04~F08/F16/F17) | 端点 | 方法 | 功能 | 关键请求参数 | 响应 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_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_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_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_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/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/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/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/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 | 发起入职审批(单个,匹配审批流;含证件字段组手工录入 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_invite_register.dspy | POST | 邀请待入职填写登记表(站内消息) | entry_ids[] | {} | A,H | — | -| /hrorg/api/entry_register_submit.dspy | POST | 待入职员工提交登记表 | entry_id,字段kv | {} | E(本人) | — | +| /hrorg/api/entry_invite_register.dspy | POST | 批量邀请待入职填写登记表(生成 register_token/url/二维码图片,站内消息发送) | entry_ids[],expire_days? | {} | A,H | — | +| /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_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_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/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_handover_save.dspy | POST | 离职交接项保存 | leave_id,items[] | {} | A,H,M | org_leave_handover | -| /hrorg/api/leave_certificate.dspy | GET | 离职证明生成下载 | employee_id | 文件 | E(本人),A,H | — | +| /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_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/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 | — | ### 2.2 hr-roster(/hrroster,F03) | 端点 | 方法 | 功能 | 关键请求参数 | 响应 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_employee_create.dspy | POST | 新增员工(自动生成工号、写时间轴) | 主档字段+自定义字段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/employee_detail.dspy | GET | 员工档案详情(主档+分组字段+兼岗+合同摘要,按角色脱敏/字段可见) | id | {main,groups:[{group_name,fields:[...]}],concurrent,contracts} | L(按范围) | — | -| /hrroster/api/roster_field_def_save.dspy | POST | 字段定义维护(类型/必填/敏感/自助/审核/适用类型/排序) | fields[] | {} | A,H | roster_field_def | +| /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 | 新增员工(工号规则自动生成、写时间轴;含证件字段组手工录入 D1:id_type/id_number/id_valid_from/id_valid_to/id_authority,id_source='manual') | 主档字段+证件字段组+自定义字段kv | {id,employee_no} | A,H | 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,projects} | L(按范围) | — | +| /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_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/roster_type_rule_save.dspy | POST | 员工类型字段规则(正式/临时等必填差异) | employee_type,field_rules_json | {} | A,H | roster_type_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/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_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/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_add.dspy | POST | 时间轴记录编辑 | employee_id,event_type,event_date,title,content | {} | A,H | — | | /hrroster/api/file_preview_url.dspy | GET | 附件在线预览 URL(files/ 受控访问) | 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(/hrflow,F10) | 端点 | 方法 | 功能 | 关键请求参数 | 响应 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/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_role_save.dspy | POST | 审批角色(流程范围/操作权限/数据范围) | role_name,flow_scope_json,op_perm_json,data_scope_json | {id} | A | flow_role | +| /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_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_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/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_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/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_forward.dspy | POST | 转交 | task_id,to_user_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_print.dspy | GET | 审批单打印视图 | instance_id | 打印 HTML | L(参与者) | — | +| /hrflow/api/inst_print.dspy | GET | 审批单打印视图(A4 版式) | instance_id | 打印 HTML | L(参与者) | — | ### 2.4 hr-contract(/hrcontract,F09) | 端点 | 方法 | 功能 | 关键请求参数 | 响应 data | 角色 | CRUD | |---|---|---|---|---|---|---| | /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_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_apply.dspy | POST | 合同审批(新签/续签/变更/终止四类) | contract_id?,biz_type=contract_sign/renew/change/stop,form_data_json | {instance_id} | A,H | — | +| /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_expire_soon.dspy | GET | 即将到期列表(工作台/提醒) | days | {rows} | A,H | — | -| /hrcontract/api/esign_stub.dspy | POST | 电子签预留桩(返回未启用提示) | contract_id | {status:'error',code:'NOT_ENABLED'} | A,H | — | +| /hrcontract/api/contract_expire_soon.dspy | GET | 即将到期列表(工作台/提醒;误差 ≤1 天) | days | {rows} | A,H | — | +| /hrcontract/api/esign_stub.dspy | POST | 电子签预留桩(D4:返回未启用,验证路由可达) | contract_id | {status:'error',data:{code:'NOT_ENABLED'}} | A,H | — | ### 2.5 hr-report(/hrreport,F13,全部只读) | 端点 | 方法 | 功能 | 关键请求参数 | 响应 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/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/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/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/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 | ### 2.6 hr-system(/hrsystem,F11/F12/F14/F15) @@ -143,59 +162,86 @@ | 端点 | 方法 | 功能 | 关键请求参数 | 响应 data | 角色 | CRUD | |---|---|---|---|---|---|---| | /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/admin_save.dspy | POST | 管理员管理(创建/调整权限) | user_id,roles[] | {} | A | — | +| /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[],scope | {} | A | — | | /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_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_manager.dspy | GET | 经理工作台聚合(团队统计/待审批/关怀提醒) | — | {stats,todos:[],care:[...]} | M | — | +| /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:[...],salary_stub:null,perf_stub:null} | E | — | +| /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/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/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/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_download.dspy | GET | 政策文件下载(校验 downloadable 与查阅范围) | id | 文件 或 NO_PERMISSION | L(按范围) | — | | /hrsystem/api/message_list.dspy | GET | 我的站内消息 | is_read?,msg_type? | {rows,total} | 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 沿用(不自研) -登录/登出、用户管理、字典 appcodes 维护、rbac 角色路径绑定由 appbase/rbac 包自带页面与端点承载(`/appbase/*`、`/rbac/*`),迭代1仅在各模块 init/data.json 中初始化字典与角色。 +登录/登出、用户管理、字典 appcodes 维护、rbac 角色路径绑定由 appbase/rbac 包自带页面与端点承载(`/appbase/*`、`/rbac/*`),批次1仅在各模块 init/data.json 中初始化字典、角色与四类流程模板。 ## 3. 典型调用链示例 -### 3.1 转正审批(F05 流程2) +### 3.1 转正审批(F05) 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,发站内消息给审批人; 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; -5. 各步均写 sys_audit_log;转正提醒由 `remind_scan` 按预计日期提前推送管理员与直属主管。 +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` 按 probation_end_date 提前(默认 7 天可配)推送管理员与直属主管。 ### 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}}`。 -### 3.3 入职黑名单拦截(F04) +### 3.3 入职黑名单拦截(F04-6) `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) -| v1 端点(JWT RESTful) | 迭代1替代 | +| v1 端点(JWT RESTful) | 一期替代 | |---|---| | 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/{id} | /hrroster/api/employee_detail.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/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/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_save(item_type=dingtalk_resource 手工登记) | 钉钉开放平台对接后该类型项自动拉取资源清单 | +| D4 电子签 | esign_stub.dspy(NOT_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.dspy(NOT_ENABLED)+ sys_openapp 表 | 按 architecture.md §9 规范启用签名鉴权 | +| 考勤/绩效桩位 | flow_form_def biz_type=attendance_*;workbench_*_stub 字段 | 二期绩效/考勤系统接入后填充 | + +## 6. 安全设计要点 1. 所有路径 load_path.py 注册;未注册即拒绝(含 .css/.js 静态资源)。 2. 敏感字段(身份证全角色脱敏前3后3;手机前3后4;职级/薪资类字段仅 admin/hr)由 roster_field_def.sensitive + 角色矩阵驱动,服务端脱敏后返回。 3. 全部 SQL 经 sqlor 绑定参数(`${var}$` 占位),禁止拼接用户输入。 -4. 审批操作校验任务归属人;员工自助类接口校验本人(或白名单字段)。 +4. 审批操作校验任务归属人;员工自助类接口校验本人(或白名单字段);登记表接口以一次性 token 鉴权并校验过期时间。 5. 导入导出、登录、权限变更全量写 sys_audit_log(含 IP)。 +6. 开放接口桩不注册业务处理;二期启用时按签名鉴权 + 数据出口授权管控。 diff --git a/docs/01-design/architecture.md b/docs/01-design/architecture.md index c70b663..a2c26ec 100644 --- a/docs/01-design/architecture.md +++ b/docs/01-design/architecture.md @@ -1,33 +1,31 @@ -# 迭代1总体设计 —— 系统架构与技术选型(hr-web) +# 一期批次1总体设计 —— 系统架构与技术选型(hr-web) -- 版本:v1.1(迭代1-总体设计;v1.1 变更:database/api/ui 三份配套文档已按 ocai 口径重写为 v2.0,表数量与端点数量同步修正) -- 状态:评审通过(主agent评审,基线冻结) -- 需求基线:`docs/00-requirement/requirement-spec.md`(SRS v2)+ `docs/00-requirement/iteration1-function-detail.md`(F01~F15) +- 版本:v2.0(批次1设计定稿;v2.0 变更:对齐 SRS v3.1 —— 批次1范围扩入编制管理(F16)/项目式组织(F17)、数据库口径修正 MariaDB/库hrs、部署端口统一 9182、新增降级项设计专章 §10、新增 API 开放接口规范 §9、F01~F15↔FEAT-B1 编号映射) +- 状态:**设计定稿(批次1评审修订版,随本批次冻结;契约变更须走设计评审)** +- 需求基线:`docs/00-requirement/requirement-spec.md`(SRS v3.1,2026-08-18)+ `docs/00-requirement/iteration1-function-detail.md`(F01~F15,81 条)+ `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` - 开发规范: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 | -| 2 | 数据库设计(核心表、字段、索引、关系、迁移策略) | `database-design.md` 全文(§4 表结构、§5 索引策略、§7 迁移策略) | -| 3 | API 设计(路径、方法、请求/响应、鉴权、错误码) | `api-design.md` 全文(§1 通用约定、§2 端点清单、§3 示例) | -| 4 | UI 设计(页面结构、核心交互、组件/路由) | `ui-design.md` 全文(§2 路由、§3 组件树、§4 交互流程) | -| 5 | 与现有 staff-mgr 员工管理模块的衔接方案 | 本文 §6 + `database-design.md` §6 数据迁移 | -| 6 | 技术可行性说明与后续开发任务拆解 | `iteration1-task-breakdown.md` 全文 | +| 1 | 批次1范围 | SRS v3.1 §1.4 批次1 = 12 feature(FEAT-B1-01~12)。其中 FEAT-B1-10 编制管理、FEAT-B1-11 项目式组织在原 F01~F15(81 条验收项)基线之外,本设计新增 **F16 编制管理(6 条验收项)、F17 项目式组织(3 条验收项)**,批次1合计 **90 条可验收项** | +| 2 | 功能编号映射 | F01 组织↔FEAT-B1-02;F02 职位职级↔FEAT-B1-03;F03 花名册+F08 兼岗↔FEAT-B1-04;F04 入职↔FEAT-B1-05;F05 转正+F06 调动↔FEAT-B1-06;F07 离职↔FEAT-B1-07;F09 合同↔FEAT-B1-08;F14 工作台+F15 员工服务↔FEAT-B1-09;F10 流程审批+F11 权限+F12 日志↔FEAT-B1-01;F13 报表↔FEAT-B1-12;F16↔FEAT-B1-10;F17↔FEAT-B1-11 | +| 3 | 技术口径 | ocai 规范:前端 bricks + dspy;后端 ahserver(Python);数据层 apppublic/sqlor(MariaDB);应用 hr-web。与 SRS v3.1 头注一致 | +| 4 | 部署口径 | 测试/生产应用统一端口 **9182**、库名 **hrs**(SRS §8);v1.1 文档中 dev:9080/prod:443/库hr 口径作废 | +| 5 | 降级项 | 批次1涉及 D1 身份证读卡→手工录入、D3 钉钉交接→占位字段、D4 电子签→模板生成+桩、D9 短信→站内兜底、扫码入职→内网登记链接/二维码;专章见 §10,二期预留接口清单见 §10.4 | ## 1. 概述 -迭代1交付「Web 版人事系统(hr-web)」组织人事底座,功能范围 F01~F15:组织架构、职位职级体系、花名册、入职/转正/调动/离职/兼岗、合同台账(不含电子签)、流程审批、权限/日志、报表、工作台、员工服务与提醒。规模规格 100 人账号。 +批次1交付「Web 版人事系统(hr-web)」**组织人事底座 + 系统管理与权限基座**,功能范围 F01~F17:组织架构、职位职级体系、花名册、入职/转正/调动/离职/兼岗、合同台账(不含电子签)、流程审批、权限/日志、报表、工作台、员工服务与提醒、**编制管理、项目式组织**。规模规格 100 人账号。 设计原则: -1. **全栈遵循 ocai 规范**:前端 bricks 组件体系(.ui 纯 JSON 声明式页面 + dspy 驱动的 CRUD),后端 ahserver(Python/aiohttp),数据层 apppublic/sqlor,基础模块 appbase(字典/用户)+ rbac(角色权限)。 -2. **配置驱动**:表结构(models/*.json)、CRUD 界面(json/*.json)、字典(appcodes)全部声明式定义,减少硬编码,支撑 SRS 的"字段/流程/表单自定义"诉求。 +1. **全栈遵循 ocai 规范**:前端 bricks 组件体系(.ui 纯 JSON 声明式页面 + dspy 驱动的 CRUD),后端 ahserver(Python/aiohttp),数据层 apppublic/sqlor(MariaDB),基础模块 appbase(字典/用户)+ rbac(角色权限)。 +2. **配置驱动**:表结构(models/*.json)、CRUD 界面(json/*.json)、字典(appcodes)全部声明式定义,支撑 SRS 的"字段/流程/表单自定义"诉求(FEAT-B1-01 验收①不写代码配置 4 类审批流)。 3. **模块宿主无关**:每个模块仅依赖基础包与自己的数据表,通过 `load_{module}()` 注册 ServerEnv,可被任意宿主应用加载(module-development-spec)。 -4. **单一事实来源**:花名册(roster_employee)是全系统员工数据唯一事实来源,入转调离审批通过后统一回写花名册。 +4. **单一事实来源**:花名册(roster_employee)是全系统员工数据唯一事实来源,入转调离审批通过后统一经 `roster_writeback` 回写(SRS §5.2-1)。 +5. **降级留桩**:一期降级项(SRS §9)一律"字段/桩端点/流程位"预留,二期对接不改表结构主干。 ## 2. 总体架构 @@ -36,28 +34,27 @@ PM 退回意见要求交付件至少包含 6 项内容,落点如下: │ 浏览器(PC Web 为主) │ │ bricks.js 渲染引擎:.ui(JSON) 页面 + DataViewer/Tree/Form/Chart │ └──────────────────────────────┬─────────────────────────────────────┘ - │ HTTP(S) session cookie(Redis 会话) + │ HTTP session cookie(Redis 会话) ┌──────────────────────────────▼─────────────────────────────────────┐ -│ nginx 反向代理(prod: 443) │ -└──────────────────────────────┬─────────────────────────────────────┘ -┌──────────────────────────────▼─────────────────────────────────────┐ -│ ahserver 应用进程(hr-web,dev:9080) │ +│ ahserver 应用进程(hr-web,直接监听 9182,systemd 守护) │ +│ (二期补齐域名/证书后可选引入 nginx:9182 HTTPS 反代,见 §7.3) │ │ 路由:wwwroot 自动路由 /{module}/{file}.ui|.dspy|.css|.js │ │ processors: .tmpl→tmpl, .ui→bui, .dspy→dspy │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ 业务模块(load_xxx 注册 ServerEnv) │ │ │ │ hr-org | hr-roster | hr-flow | hr-contract | hr-report | │ │ -│ │ hr-system │ │ +│ │ hr-system │ │ │ ├─────────────────────────────────────────────────────────────┤ │ -│ │ 基础模块:appbase(users/appcodes 字典)+ rbac(角色/权限) │ │ -│ │ bricks_for_python(UiWindow 等 pybricks) │ │ +│ │ 基础模块:appbase(users/orgs/appcodes 字典)+ rbac(角色权限)│ │ +│ │ bricks_for_python(UiWindow 等 pybricks) │ │ │ └─────────────────────────────────────────────────────────────┘ │ +│ 后台任务:remind_scan(提醒扫描)/ headcount 联动校验 / 导入导出任务 │ └──────────┬───────────────────────────────┬─────────────────────────┘ │ sqlor 连接池(sor.C/U/D/R/I/sqlExe) │ Redis session ┌──────────▼──────────┐ ┌────────▼────────┐ -│ MySQL 8.0(库 hr) │ │ Redis(会话) │ -│ json2ddl 生成 DDL │ └─────────────────┘ -└─────────────────────┘ files/ 目录:附件存储(合同文件、头像、导入导出文件) +│ MariaDB(库 hrs) │ │ Redis(会话) │ +│ json2ddl 生成 DDL │ └─────────────────┘ +└─────────────────────┘ 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 与页面逻辑统一语言栈(Python);ahserver 自动解析参数、自动 JSON 序列化;禁止 import/print,天然受控 | | 后端框架 | ahserver(aiohttp 异步) | ocai 强制规范;内置会话/RBAC/文件上传/后台任务;wwwroot 自动路由免手写路由注册;100 人规模单实例足够 | | 数据访问 | apppublic/sqlor | 异步连接池 + 绑定参数防注入;`sor.C/U/D/R/I/sqlExe` 六元 API 覆盖全部数据操作;与 models JSON 配套 | | 表定义 | models/*.json + json2ddl | database-table-definition-spec 标准;数据库无关的抽象类型,DDL 自动生成,保证 collate utf8mb4_unicode_ci 一致 | | CRUD 生成 | json/*.json + xls2ui | crud-definition-spec 标准;自动产出列表页 .ui 与 add/update/delete dspy 包装 | -| 字典 | appbase appcodes/appcodes_kv | 性别/员工类型/异动类型/离职原因等枚举统一管理,CRUD 下拉直接引用(codes 段) | -| 权限 | rbac 模块 + 自研数据范围表 | rbac 管"功能权限(路径级)",hr-system 扩展"数据范围(组织维度/花名册字段维度)",满足 SRS §3.1.14 | -| 数据库 | MySQL 8.0 | 产线既有设施(staff-mgr 亦为 MySQL),sqlor DDL 模板成熟 | +| 字典 | appbase appcodes/appcodes_kv | 性别/员工类型/异动类型/离职原因/提醒场景/编制周期等枚举统一管理,CRUD 下拉直接引用(codes 段) | +| 权限 | rbac 模块 + 自研数据范围表 | rbac 管"功能权限(路径级)",hr-system 扩展"数据范围(组织维度/花名册字段维度)",满足 SRS §2.2 | +| 数据库 | **MariaDB(库 hrs)** | 任务明确口径(SRS §8);sqlor DDL 模板成熟;每日全量备份保留 ≥30 天 | | 会话 | Redis + aiohttp_session | web-application-spec 推荐;服务重启不丢登录 | -| 附件 | ahserver files/ 文件存储 | 合同附件、离职证明、导入导出文件;100 人规模本地目录足够 | +| 附件 | ahserver files/ 文件存储 | 合同附件、离职证明、导入导出文件、入职登记表二维码图片;100 人规模本地目录足够,随应用数据一并备份(NFR-5) | -与 v1(Java/Spring Boot/JPA/JWT)口径的差异已全部废弃归档(`docs/_archive/`),不再保留双栈:鉴权由"自研 JWT Filter"改为"ahserver session + rbac",ORM 由 JPA 改为 sqlor,前端由"无"改为 bricks/dspy。 +v1(Java/Spring Boot/JPA/JWT)口径已全部废弃归档(`docs/_archive/`),不保留双栈:鉴权由"自研 JWT Filter"改为"ahserver session + rbac",ORM 由 JPA 改为 sqlor,前端由"无"改为 bricks/dspy。 ## 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-flow | /hrflow | 表单定义、流程定义、流程实例、审批任务(待办/已办/我发起) | flow_ | F10 | -| hr-contract | /hrcontract | 合同台账、合同模板、到期提醒规则、合同审批 | contract_ | F09 | -| hr-report | /hrreport | 只读聚合报表(花名册分析/入职/转正/调岗/离职分析),无自有表 | — | F13 | -| hr-system | /hrsystem | 角色/管理员/数据范围、操作日志、工作台聚合、提醒规则、公告政策、站内消息 | sys_ | F11/F12/F14/F15 | +| hr-flow | /hrflow | 表单定义、流程定义、流程实例、审批任务(待办/已办/我发起/我收到) | flow_ | F10(FEAT-B1-01 流程引擎部分) | +| hr-contract | /hrcontract | 合同台账、合同类型/模板、到期提醒规则、合同审批、esign 桩 | contract_ | F09 | +| hr-report | /hrreport | 只读聚合报表(花名册/入职/转正/调岗/离职五类分析),无自有表 | — | F13 | +| hr-system | /hrsystem | 角色/管理员/数据范围、操作日志、工作台聚合、提醒规则、公告政策、站内消息 | sys_ | F11/F12/F14/F15(FEAT-B1-01 权限日志部分 + FEAT-B1-09) | ### 4.2 职责边界规则 -1. **员工主数据唯一入口**:所有模块读写员工信息必须经 hr-roster 的注册函数(ServerEnv 暴露),禁止跨模块直接 SQL 写 roster_ 表。入转调离审批通过后由 hr-flow 回调 hr-org 的业务函数,再调用 hr-roster 回写接口更新员工状态。 -2. **审批引擎与业务解耦**:hr-flow 只管"表单+流程+实例+任务"的流转,不含业务语义;业务回写通过 `biz_type + biz_id` 关联 + 流程完成回调(ServerEnv 注册的 hook 函数)实现。 -3. **权限横切**:功能权限(路径级 RBAC)由 rbac 模块统一拦截(各模块 scripts/load_path.py 注册路径与角色);数据范围由 hr-system 提供 `get_data_scope(user_id)` 公共函数,hr-org/hr-roster/hr-report 在查询时强制叠加。 +1. **员工主数据唯一入口**:所有模块读写员工信息必须经 hr-roster 的注册函数(ServerEnv 暴露),禁止跨模块直接 SQL 写 roster_ 表。入转调离审批通过后由 hr-flow 回调 hr-org 的业务函数,再调用 hr-roster `roster_writeback` 更新员工主档与时间轴。 +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 在查询、报表、**导出**时强制叠加(SRS §2.2-2)。 4. **操作日志横切**:所有写操作(sor.C/U/D)统一经 hr-system 的 `write_audit_log(...)` 记录前后值(before/after JSON),F12 查询页只读 sys_audit_log。 -5. **字典统一**:任何枚举值不得硬编码在 dspy 中,一律走 appcodes(init/data.json 初始化),CRUD 下拉用 models codes 段引用。 +5. **编制联动**:入转调离回写成功后,hr-org 同步调用 `headcount_check(employee, event)` 重算所属编制方案占编并写快照/超编提醒(服务内同步执行,100 人规模满足"1 分钟内刷新"验收)。 +6. **字典统一**:任何枚举值不得硬编码在 dspy 中,一律走 appcodes(init/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) | -| **staff-mgr**(repos/staff-mgr) | v1 遗留 Java 模块 | 旧员工 CRUD REST 服务(/api/v1/staff/*,Spring Boot + JPA + JWT) | **已归档,冻结不再开发**;仅作迭代1数据迁移来源与参考实现(见 §6) | +| **hr-system**(模块,repos/hr-system) | ocai 规范模块 | 系统支撑层:F11 权限管理、F12 操作日志、F14 工作台、F15 员工服务与提醒;并承载全应用横切能力(数据范围、审计、站内消息、提醒扫描) | 批次1新建(复用现有空仓 hr-system.git) | +| **staff-mgr**(遗留 Java 模块) | v1 遗留 | 旧员工 CRUD REST 服务(/api/v1/staff/*,Spring Boot + JPA + JWT) | **已归档,冻结不再开发**;仅作数据迁移来源与参考实现(见 §6) | 边界结论: -- 迭代1上线后 staff-mgr **不再承担任何线上职责**;其员工数据一次性迁移至 hr-roster(roster_employee + roster_field_value),部门缓存迁移至 hr-org(org_unit),日志迁移/归档至 hr-system(sys_audit_log)。 -- 旧模块的"员工 CRUD"职责由 **hr-roster** 承接(不是 hr-system);hr-system 只承接其"操作日志/权限"类横切职责。详见 §6 衔接方案。 -- v1 应用定义 `apps/hr-system.md`(Java 后端服务)已废弃,与模块 hr-system(ocai 支撑模块)仅重名,无继承关系。 +- 一期上线后 staff-mgr 不再承担任何线上职责;其员工数据一次性迁移至 hr-roster,部门缓存迁移至 hr-org,日志迁移至 hr-system(详见 database-design.md §8、任务 T23)。 +- 旧模块的"员工 CRUD"职责由 **hr-roster** 承接(不是 hr-system);hr-system 只承接"操作日志/权限"类横切职责。 +- v1 应用定义 `apps/hr-system.md`(Java 后端服务)已废弃,与模块 hr-system 仅重名,无继承关系。 +- 迁移范围(仅在职/含历史)与切换时间点待 PM 确认(SRS §11-Q3),脚本按"可配置范围"实现,默认在职+离职保留档案。 ## 5. 模块结构与依赖关系 @@ -147,14 +146,14 @@ PM 退回意见要求交付件至少包含 6 项内容,落点如下: │ ▲ ▲ │ │ 路径注册/数据范围 │ 字典/用户 ┌─────────┴──┐ ┌──────┴─────┐ ┌──────┴─────┐ - │ hr-system │◄─────│ hr-flow │◄──────────│ hr-contract│ - │ F11/12/14/15│ 审批回调/权限 │ 合同审批 │ + │ hr-system │◄─────│ hr-flow │◄──────────│ hr-contract │ + │F11/12/14/15│ 审批回调/权限 │ 合同审批 │ └─────▲──────┘ └──────▲─────┘ └──────┬─────┘ - │ 审计/数据范围 │ 入转调离审批 │ 员工/公司引用 + │ 审计/数据范围 │ 入转调离/兼岗审批 │ 员工/公司引用 │ │ │ ┌─────┴──────┐ ┌──────┴─────┐ │ │ 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-org | — | 回写花名册/黑名单 | 异动审批流转 | — | — | 权限/日志/提醒通道 | | hr-roster | 组织/职位主数据 | — | 自助修改审核 | — | — | 字段级权限/脱敏/日志 | | hr-flow | — | 表单引用字段/完成回调 | — | — | — | 审批角色权限/日志 | | hr-contract | 合同公司主数据 | 员工关联 | 合同审批 | — | — | 提醒通道/日志 | -| hr-report | 异动数据 | 花名册数据 | — | — | — | 数据范围 | -| hr-system | 工作台引用组织 | 工作台引用档案 | 工作台引用待办 | 工作台引用合同 | — | — | +| hr-report | 异动/编制数据 | 花名册数据 | — | — | — | 数据范围 | +| 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()`。 -- `conf/config.json`:processors 必含 `[".tmpl","tmpl"], [".ui","bui"], [".dspy","dspy"]`;indexes 含 `index.ui`;databases 配置 hr 库;Redis session(session_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 服务。 -- 环境:dev/test 单实例容器(nginx:8080 → ahserver:9080);prod nginx:443 反代,ahserver 不直接暴露,MySQL/Redis 仅内网;数据每日备份。100 人规模单实例即可满足"列表页 ≤500ms"指标(见 §8)。 +- 应用入口 `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 配置 **hrs** 库(测试环境 test/test123);Redis session(session_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` 并导入 hrs 库 → init/data.json 导入(含四类流程模板、基础字段集、内置 admin 与角色,SRS §5.2-4)→ json/ 执行 `xls2ui` 生成 CRUD → symlink 各模块 wwwroot 与 bricks dist → systemd 服务。 ## 6. 与现有 staff-mgr 员工管理模块的衔接方案 ### 6.1 衔接定位 -staff-mgr 是 v1 Java 口径下的员工 CRUD 模块(已通过端到端验证,见其 README),与 ocai 规范冲突,不改造、不并行演进,采取**一次性数据迁移 + 接口替代 + 退役**策略。 +staff-mgr 是 v1 Java 口径下的员工 CRUD 模块(已通过端到端验证),与 ocai 规范冲突,不改造、不并行演进,采取**一次性数据迁移 + 接口替代 + 退役**策略。 ### 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) | 新建一律走入职流程或花名册新增 | | GET /(分页列表) | /hrroster/roster_list(CRUD 列表 + 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 | 可配置自助修改 + 审核 | -| DELETE /{id}、POST /batch-delete | 离职流程 /hrorg/api/leave_manual.dspy | 迭代1不做物理/逻辑删除员工,统一走离职 | -| GET /{id}/change-logs | /hrroster/timeline.dspy | 时间轴(含迁移进来的旧变更记录) | -| GET /audit-logs | /hrsystem/audit_log_list(CRUD) | 历史日志迁入 sys_audit_log | +| DELETE /{id}、POST /batch-delete | 离职流程 /hrorg/api/leave_manual.dspy | 一期不做物理/逻辑删除员工,统一走离职 | +| GET /{id}/change-logs | /hrroster/api/timeline.dspy | 时间轴(含迁移进来的旧变更记录) | +| GET /audit-logs | /hrsystem/api/audit_log_list.dspy | 历史日志迁入 sys_audit_log | | GET /check/employee-no | /hrroster/api/check_employee_no.dspy | 工号查重保留 | | 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_employee;staff_employee_extra → roster_field_value(学历/专业等映射到预置字段定义)+ contract_info(合同起止);staff_department_cache → org_unit;staff_change_log → roster_timeline;staff_audit_log → sys_audit_log。 -- 迁移工具:hr-system 仓内 `scripts/migrate_staff_mgr.py`(Python + sqlor,幂等、按 employee_no 去重、输出核对报告)。 -- 切换策略:迭代1 UAT 通过后一次性切换;切换后 staff-mgr 服务下线、仓库冻结归档(保留只读访问一个迭代周期)。 +- 迁移对象:staff_employee → roster_employee;staff_employee_extra → roster_field_value + contract_info;staff_department_cache → org_unit;staff_change_log → roster_timeline;staff_audit_log → sys_audit_log。 +- 迁移工具:hr-system 仓内 `scripts/migrate_staff_mgr.py`(Python + sqlor,幂等、按 employee_no 去重、输出核对报告:总数/抽样一致,NFR-8)。 +- 切换策略:UAT 通过后一次性切换;切换后 staff-mgr 服务下线、仓库冻结归档(保留只读访问一个迭代周期)。迁移范围待 PM 确认(SRS §11-Q3)。 ### 6.4 风险与对策 @@ -216,28 +214,81 @@ staff-mgr 是 v1 Java 口径下的员工 CRUD 模块(已通过端到端验证 |---|---| | 旧数据字段语义不一致(如 status 枚举) | 迁移脚本内置映射表 + 人工核对报告;UAT 期间双库比对 | | 旧 department_id 无组织主数据 | 先迁 staff_department_cache 建 org_unit,再按 department_id 关联 | -| 身份证号加密算法不同(AesCipher) | 迁移时解密后按 hr-web 统一加密方案重新落库 | +| 身份证号加密算法不同(AesCipher) | 迁移时解密后按 hr-web 统一加密方案重新落库(cipher+hash) | -## 7. 安全设计 +## 7. 部署与运维设计(SRS §8 落地) -1. **鉴权**:ahserver session(Redis)+ rbac 角色。迭代1角色:`admin`(系统管理员)、`hr`(人事)、`manager`(部门经理)、`employee`(员工自助);所有路径经 scripts/load_path.py 注册,未注册路径默认拒绝。 -2. **数据范围**(F11):sys_role_data_scope 支持两类范围——组织维度(org_id 集合,含子树)、花名册字段维度(field_id 可见集合)。查询层强制拼接范围条件;报表同样受控。 -3. **脱敏**:敏感字段(身份证/手机/薪资级)在 roster_field_def 标记 sensitive,dspy 返回前按角色脱敏。 -4. **审计**(F12):全量写操作记录前后值 JSON、操作人、IP;审批、导入导出同样记录。 +### 7.1 环境矩阵 + +| 项 | 测试环境 | 生产环境 | +|---|---|---| +| 主机 | 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 直接监听 9182,systemd 守护(`Restart=always`),满足 NFR-3(月度可用率 ≥99% 工作时间、异常自动重启)。不强制引入 nginx。 + +### 7.3 HTTPS 升级路径(预留) + +生产域名与证书补齐后(SRS §11-Q1),引入 nginx 监听 9182(HTTPS)反代 ahserver 内部端口(如 127.0.0.1:9183),ahserver 改绑 loopback;配置变更仅涉及 conf/config.json 端口与 systemd unit,无代码改动。招聘官网对外(批次3 FEAT-B3-07)依赖此升级。 + +## 8. 安全设计 + +1. **鉴权**:ahserver session(Redis)+ rbac 角色。批次1角色:`admin`(系统管理员)、`hr`(人事)、`manager`(部门经理)、`employee`(员工自助);所有路径经 scripts/load_path.py 注册,**未注册路径默认拒绝**(SRS §2.2-1)。 +2. **数据范围**(F11):sys_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}$` 占位)。 +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_def(EAV)、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.0):ER、43 张表结构、索引、字典、models JSON 示例、staff-mgr 迁移策略 -- `api-design.md`(v2.0):dspy 端点清单(约 100 个)、请求/响应、鉴权角色、错误码 -- `ui-design.md`(v2.0):页面结构、组件树、路由表、核心交互流程 -- `iteration1-task-breakdown.md`(v1.0):可行性分析、风险、开发任务拆解(T01~T24) +## 10. 降级项设计(批次1相关,SRS §9) + +| # | 降级项 | 一期降级方案(设计落点) | 二期预留接口/字段 | +|---|---|---|---| +| 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.1:mysqldump 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范围基线) | diff --git a/docs/01-design/database-design.md b/docs/01-design/database-design.md index 167adad..e6220e0 100644 --- a/docs/01-design/database-design.md +++ b/docs/01-design/database-design.md @@ -1,19 +1,20 @@ -# 迭代1总体设计 —— 数据库设计(hr-web,ocai 口径) +# 一期批次1总体设计 —— 数据库设计(hr-web,ocai 口径) -- 版本:v2.0(迭代1-总体设计,取代 v1 Java/JPA 口径,v1 已归档至 `docs/_archive/01-design-v1-old/`) -- 状态:评审通过(主agent评审,基线冻结) -- 需求基线:`docs/00-requirement/requirement-spec.md`(SRS v2)+ `iteration1-function-detail.md`(F01~F15) +- 版本: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 钉钉交接占位、字典扩充) +- 状态:**设计定稿(批次1评审修订版)** +- 需求基线:`docs/00-requirement/requirement-spec.md`(SRS v3.1)+ `iteration1-function-detail.md`(F01~F15)+ approved-features.md(FEAT-B1-01~12) - 架构基线:`docs/01-design/architecture.md` - 规范依据:ocai 技能集 database-table-definition-spec(models/*.json + json2ddl)、crud-definition-spec、sqlor-database-module ## 1. 设计总则 -1. **表定义声明式管理**:所有表以 `models/{table}.json`(summary/fields/indexes/codes 四段)定义,build.sh 中 `json2ddl mysql . > mysql.ddl.sql` 生成 DDL 导入 `hr` 库。本文 DDL 为生成物等价示例,开发以 models JSON 为准。 -2. **统一约定**:InnoDB;utf8mb4 / utf8mb4_unicode_ci;主键 `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 的裁决落地)。 -4. **自定义字段(EAV)**:花名册字段(F03)与组织字段(F01)采用"字段定义表 + 字段值表"EAV 方案,支撑字段/分组/类型规则自定义;固定高频查询字段(组织、职位、状态、入离职日期)冗余在员工主表保证列表性能。 -5. **敏感字段**:身份证号密文列 + 哈希列(确定性,供唯一性与黑名单匹配),手机号明文存储、按角色脱敏展示;`roster_field_def.sensitive` 驱动字段级脱敏与可见性。 -6. **库划分**:单库 `hr`,表前缀区分模块:`org_`(hr-org)、`roster_`(hr-roster)、`flow_`(hr-flow)、`contract_`(hr-contract)、`sys_`(hr-system);appbase(users/orgs/appcodes)与 rbac 表沿用基础包自带结构,不在本文重复。 +1. **表定义声明式管理**:所有表以 `models/{table}.json`(summary/fields/indexes/codes 四段)定义,build.sh 中 `json2ddl mysql . > mysql.ddl.sql` 生成 DDL 导入 **hrs** 库。本文 DDL 为生成物等价示例,开发以 models JSON 为准。 +2. **统一约定**:InnoDB;utf8mb4 / utf8mb4_unicode_ci;数据库 MariaDB,库名 `hrs`;主键 `id VARCHAR(32)`(getID() 雪花串,sqlor 惯例);公共审计列 `created_by/updated_by/created_at/updated_at`;`sor.C` 不自动填时间戳,写入时显式 `created_at=curDateString()`。 +3. **逻辑删除策略**:员工与组织**不做物理删除**,统一走"停用(status=inactive)/离职流程";物理删除仅 admin 可执行且必须留审计(SRS §5.2-2)。 +4. **自定义字段(EAV)**:花名册字段(F03)与组织字段(F01)采用"字段定义表 + 字段值表"EAV 方案;固定高频查询字段(组织、职位、状态、入离职日期)冗余在员工主表保证列表性能。 +5. **敏感字段**:身份证号密文列 + 哈希列(确定性哈希,供唯一性与黑名单匹配),手机号明文存储、按角色脱敏展示;`roster_field_def.sensitive` 驱动字段级脱敏与可见性(SRS §2.2-4)。 +6. **库划分**:单库 `hrs`,表前缀区分模块:`org_`(hr-org)、`roster_`(hr-roster)、`flow_`(hr-flow)、`contract_`(hr-contract)、`sys_`(hr-system);appbase(users/orgs/appcodes)与 rbac 表沿用基础包自带结构,不在本文重复。 +7. **预留字段约定**:二期对接预留字段一律带明确默认值与字典枚举位(如 esign_status='not_enabled'、id_source='manual'、send_channel='site'),不参与一期业务分支。 ## 2. ER 图(实体关系描述) @@ -29,13 +30,13 @@ │ 组织 │ │ │ sys_audit_log │ 操作日志(F12) └──┬───┬──────┘ │ │ sys_message │ 站内消息(F15) │ │org_field_value │ │ sys_remind_rule │ 提醒规则 - │ ▼ │ └────────▲─────────┘ - │ org_field_def │ │ 推送 - │ │ │ + │ ▼ │ │ sys_openapp │ API开放预留 + │ org_field_def │ └────────▲─────────┘ + │ │ │ 推送 │ ┌─────────────┐ ┌─────▼───────────────┴───┐ │ │org_job/ │ │ roster_employee │ 员工唯一事实源(F03) │ │org_position◄─┼──│ org_id/position_id/ │ - │ │org_sequence/ │ │ employee_status/... │ + │ │org_sequence/ │ │ employee_status/证件字段组│ │ │org_grade_* │ └──┬──────┬──────┬─────────┘ │ └─────────────┘ │ │ │ │ │ │ ▼ @@ -48,26 +49,27 @@ │ org_transfer(+detail)│ contract_remind_rule │ org_leave(+handover) │ │审批 │ org_concurrent_post │ ▼ - │ │审批流转 │ ┌──────────────┐ - └────────┴──────────────┴────►│ flow_def │ 流程定义 - biz_type+biz_id │ flow_form_def│ 表单定义(引用花名册字段) - │ flow_node_def│ 节点(审批人/字段权限) - │ flow_role │ 审批角色 - │ flow_instance│ 实例 ──► flow_task(待办) - │ │ └► flow_op_log - └──────────────┘ + │ org_headcount_scheme │ ┌──────────────┐ + │ └ headcount_item │ │ flow_def │ 流程定义 + │ └ headcount_snapshot│ │ flow_form_def│ 表单定义(引用花名册字段) + │ org_project(F17) │ │ flow_node_def│ 节点(审批人/字段权限) + │ └ org_project_post │ │ flow_role │ 审批角色 + │ │审批流转 │ │ flow_instance│ 实例 ──► flow_task(待办) + └────────┴──────────────┴────►│ │ └► flow_op_log + biz_type+biz_id └──────────────┘ 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` 反向定位业务单据,流程完成后回调业务模块回写。 -- `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 惯例,跨模块解耦)。 ## 3. models JSON 示例(规范格式,json2ddl 输入) -`hr-roster/models/roster_employee.json`: +`hr-roster/models/roster_employee.json`(含 D1 证件字段组扩展): ```json { @@ -79,8 +81,13 @@ hr-report 无自有表:只读聚合 org_/roster_/flow_ 表,叠加 sys_data_s {"name": "employee_no", "title": "工号", "type": "varchar", "length": 32}, {"name": "name", "title": "姓名", "type": "varchar", "length": 64}, {"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_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": "phone", "title": "手机号", "type": "varchar", "length": 20}, {"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_status", "title": "员工状态", "type": "varchar", "length": 16}, {"name": "hire_date", "title": "入职日期", "type": "date"}, + {"name": "probation_end_date", "title": "试用期止(预计转正日)", "type": "date"}, {"name": "regular_date", "title": "转正日期", "type": "date"}, {"name": "leave_date", "title": "离职日期", "type": "date"}, {"name": "company_id", "title": "合同公司", "type": "varchar", "length": 32}, {"name": "work_location", "title": "办公地点", "type": "varchar", "length": 128}, {"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": "created_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_status", "fields": ["employee_status"]}, {"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": [ {"name": "gender", "source": "appcodes", "code": "GENDER"}, {"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 字典。 -## 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 | | 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) | -| 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/horizontal,F17 横向职务), 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 | | 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 | | 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 | -| 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 | +| 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_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 | | 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 | | 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 | +| 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_) | # | 表 | 用途 | 关键字段 | 关键索引 | |---|---|---|---|---| -| 19 | 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 | -| 21 | roster_employee | 员工主档(F03) | 见 §3 models 示例 | 见 §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 | -| 23 | 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) | -| 25 | roster_type_rule | 员工类型字段规则(F03 分类管理) | id, employee_type, field_rules_json(按类型必填/隐藏字段), status【审计】 | uk(employee_type) | +| 24 | roster_field_group | 字段分组(F03) | id, group_code, group_name(工作信息/个人信息/绩效结果/培训记录), sort_no, status【审计】 | uk_group_code | +| 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 | +| 26 | roster_employee | 员工主档(F03) | 见 §3 models 示例(含证件字段组/probation_end_date/prev_employee_id) | 见 §3 | +| 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 | +| 28 | roster_empno_rule | 工号规则(F03) | id, rule_name, prefix, match_field(如company_id), match_value, seq_length, current_seq(int), status【审计】 | — | +| 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) | +| 30 | roster_type_rule | 员工类型字段规则(F03 分类管理) | id, employee_type, field_rules_json(按类型必填/隐藏字段), status【审计】 | uk(employee_type) | ### 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 | -| 27 | 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 | -| 29 | 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 | -| 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 | -| 32 | flow_op_log | 流转日志 | id, instance_id, op_type(submit/approve/reject/forward/cancel/withdraw), operator_id, comment, created_at | idx_instance | +| 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 | +| 32 | flow_def | 流程定义(F10) | id, flow_code, flow_name, form_id, biz_type, match_cond_json(员工类型/部门匹配条件), version, status【审计】 | uk_flow_code; idx_biz_type | +| 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 | +| 34 | flow_role | 审批角色(F10) | id, role_name, flow_scope_json(可用流程), op_perm_json(操作权限), data_scope_json(数据查看范围), 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 | +| 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 | +| 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_) | # | 表 | 用途 | 关键字段 | 关键索引 | |---|---|---|---|---| -| 33 | 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【审计】 | — | -| 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 | -| 36 | contract_remind_rule | 到期提醒规则(F09) | id, rule_name, days_before(int), target_role(self/leader/hr), content_template, status【审计】 | — | +| 38 | contract_type | 合同类型(F09 自定义) | id, type_code, type_name(劳动合同/保密协议/竞业协议…), status【审计】 | uk_type_code | +| 39 | contract_template | 合同模板(F09) | id, template_name, type_id, file_path, field_marks_json(占位符映射), 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 | +| 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 | -| 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) | -| 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 | -| 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) | -| 41 | 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 | -| 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 | +| 42 | sys_data_scope | 数据范围(F11) | id, admin_user_id(管理员), scope_type(org/field), org_ids_json(组织维度,含子树), field_ids_json(花名册字段维度), remark【审计】 | idx_admin_user | +| 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) | +| 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 | +| 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) | +| 46 | sys_announcement | 企业公告(F15) | id, title, content, publish_scope_json, publish_time, status(draft/published/offline), 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 | +| 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 --- roster_employee(完整 DDL 见 §3 models JSON) +-- roster_employee(完整字段见 §3 models JSON;此处为等价 DDL 含证件字段组) CREATE TABLE roster_employee ( id VARCHAR(32) NOT NULL COMMENT '主键', employee_no VARCHAR(32) NOT NULL COMMENT '工号', name VARCHAR(64) NOT NULL COMMENT '姓名', 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_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, phone VARCHAR(20) 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_status VARCHAR(16) DEFAULT NULL COMMENT '状态(字典EMP_STATUS)', hire_date DATE DEFAULT NULL, + probation_end_date DATE DEFAULT NULL COMMENT '试用期止(预计转正日,转正提醒依据)', regular_date DATE DEFAULT NULL, leave_date DATE DEFAULT NULL, company_id VARCHAR(32) DEFAULT NULL COMMENT '合同公司', work_location VARCHAR(128) DEFAULT NULL, direct_leader_id VARCHAR(32) DEFAULT NULL COMMENT '直属主管', + prev_employee_id VARCHAR(32) DEFAULT NULL COMMENT '复职关联原档案ID(F04-5)', 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, + 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_employee_no (employee_no), UNIQUE KEY uk_id_number_hash (id_number_hash), KEY idx_org_id (org_id), KEY idx_status (employee_status), 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='员工主档'; CREATE TABLE org_unit ( @@ -260,7 +286,8 @@ CREATE TABLE flow_instance ( id VARCHAR(32) NOT NULL, inst_no VARCHAR(32) NOT NULL COMMENT '审批编号', 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, initiator_id VARCHAR(32) NOT NULL, 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/...', target_type VARCHAR(32) NOT NULL COMMENT 'roster_employee/org_unit/...', 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 '', before_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_module_op (module, operation) ) 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 行),前端缓存,无需分页。 3. EAV 查询模式:花名册列表先按主表条件分页取员工,再批量 `IN` 查值表拼装(每页 ≤50 人 × 显示字段数),避免 EAV 行转列大 JOIN。 -4. 报表(hr-report)直接 SQL 聚合(sor.sqlExe 只读),100 人规模不建物化视图;sys_audit_log 按月保留,冷数据归档不删除。 -5. 唯一性:工号、组织编码、职位/职务/职级/职等编码、审批编号均唯一索引;证件号经哈希列唯一(加密为非确定性,哈希列承担唯一与黑名单匹配)。 +4. 报表(hr-report)直接 SQL 聚合(sor.sqlExe 只读),100 人规模不建物化视图,满足"延迟 ≤5 分钟"(实为实时);sys_audit_log 按月保留,冷数据归档不删除。 +5. 编制计数:headcount_snapshot 以"异动事件触发 + 每日兜底扫描"双机制维护;实时查询取最新 snap_date,历史回溯按 snap_date 精确取数(F16 验收③)。 +6. 唯一性:工号、组织编码、项目编码、职位/职务/职级/职等编码、审批编号、登记表 token 均唯一索引;证件号经哈希列唯一(密文为非确定性加密,哈希列承担唯一性与黑名单匹配)。 -## 6. 数据字典(appbase appcodes,init/data.json 初始化) +## 7. 数据字典(appbase appcodes,init/data.json 初始化) | code | 值 | 说明 | |---|---|---| @@ -308,48 +410,69 @@ CREATE TABLE sys_audit_log ( | ORG_TYPE | group/subsidiary/dept/team | 组织类型 | | EMP_TYPE | formal/temp/dispatch/intern | 员工类型(正式/临时/派遣/实习) | | 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 | 职位类别 | +| JOB_CATEGORY | vertical/horizontal | 职务类别(F17 横向职务) | | TRANSFER_TYPE | promotion/demotion/position_change/org_adjust | 调动类型 | | LEAVE_REASON | personal/company/contract_expire/retire/other | 离职原因 | +| HANDOVER_TYPE | approval/file/subordinate/permission/dingtalk_resource(占位)/other | 离职交接项类型(D3) | | 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 | 实例状态 | -| REMIND_SCENE | entry/regular/leave/retire/contract_expire/health_cert/social_insurance/custom | 提醒场景 | -| AUDIT_OP | create/update/delete/import/export/approve/login | 操作类型 | +| REMIND_SCENE | entry/regular/leave/retire/contract_expire/health_cert/social_insurance/custom | 提醒场景(≥6 类,F15 验收④) | +| 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 | 登记表状态 | 枚举一律不硬编码于 dspy;CRUD 下拉经 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) | 目标表 | 映射规则 | |---|---|---| | staff_department_cache | org_unit | 按树形重建 parent_id;org_code=DEPT{id};status 映射 active/inactive | -| staff_employee | roster_employee | employee_no/name/gender/phone/email 直映;id_number AES 解密后按新方案重加密(cipher+hash);department_id→org_id;position 文本→预置 org_position(无匹配则建"未定职");status: active→regular、probation→probation、inactive→left;hire_date 直映 | +| staff_employee | roster_employee | employee_no/name/gender/phone/email 直映;id_number AES 解密后按新方案重加密(cipher+hash),id_source='manual',证件有效期/签发机关置空待补;department_id→org_id;position 文本→预置 org_position(无匹配则建"未定职");status: active→regular、probation→probation、inactive→left;hire_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_info(type_id 映射正式/外包/实习协议) | | staff_change_log | roster_timeline | change_type→event_type(transfer/field_change),old/new 值入 content_json,event_type 前缀 `migrate:` 标识迁移来源 | | 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。 -2. **幂等**:按 employee_no/org_code 去重,重跑仅补差;证件号哈希冲突时输出冲突报告人工裁决(对 baseline-decision Q6:冲突员工按离职记录保留,不入在职)。 -3. **切换**:迭代1 UAT 通过后一次性迁移+双库比对 → staff-mgr 服务下线、仓库冻结只读(保留一个迭代周期)。 -4. 迁移全程写 sys_audit_log(operation=migrate),迁移数据在时间轴/日志中可辨识。 +2. **幂等**:按 employee_no/org_code 去重,重跑仅补差;证件号哈希冲突时输出冲突报告人工裁决(冲突员工按离职记录保留,不入在职)。 +3. **范围**:默认"在职 + 离职保留档案"全量;仅迁在职/含历史的最终范围与切换时间点待 PM 确认(SRS §11-Q3),脚本参数 `--scope=active|all` 支持两种口径。 +4. **切换**:UAT 通过后一次性迁移+双库比对 → staff-mgr 服务下线、仓库冻结只读(保留一个迭代周期)。 +5. 迁移全程写 sys_audit_log(operation=migrate),迁移数据在时间轴/日志中可辨识。 -## 8. 与需求验收项的映射(摘选) +## 9. 与需求验收项的映射(摘选) -| 验收项(function-detail) | 数据支撑 | +| 验收项 | 数据支撑 | |---|---| | 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-3 多规则工号 | roster_empno_rule | | F03-4 自助修改审核 | roster_field_def.editable_self/need_audit + flow biz_type=roster_self_edit | | F03-6 类型差异规则 | roster_type_rule + apply_types | -| F04-4 黑名单拦截 | org_blacklist(id_number_hash 匹配) | +| F04-4 身份证手工录入(D1) | roster_employee/org_entry 证件字段组 + id_source='manual' | +| F04-5 复职 | roster_employee.prev_employee_id | +| F04-6 黑名单拦截 | org_blacklist(id_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_file(files/ 存储) | -| 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 | | F11-2 双维度数据范围 | sys_data_scope(scope_type=org/field) | | 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(一期不启用) | diff --git a/docs/01-design/feature-list.md b/docs/01-design/feature-list.md index b51f58f..9b9859d 100644 --- a/docs/01-design/feature-list.md +++ b/docs/01-design/feature-list.md @@ -1,67 +1,71 @@ -# 迭代1功能清单(F01~F15,ocai 口径) +# 一期批次1功能清单(F01~F17,ocai 口径) -- 版本:v2.0(替换原 299B 占位文件;占位文件内容为 v1 Java 口径描述,已废弃) -- 需求基线:`docs/00-requirement/requirement-spec.md`(SRS v2)+ `docs/00-requirement/iteration1-function-detail.md` +- 版本: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 v3.1)+ `docs/00-requirement/iteration1-function-detail.md` - 应用:hr-web(`apps/hr-web.md`);模块定义:`modules/hr-*.md` ## 0. 范围与角色 -迭代1 = 组织人事底座,规模 100 人账号。技术口径统一 ocai:前端 bricks + dspy 声明式页面,后端 ahserver(Python),数据层 apppublic/sqlor。 +一期批次1 = 组织人事底座 + 系统管理与权限基座,规模 100 人账号。技术口径统一 ocai:前端 bricks + dspy 声明式页面,后端 ahserver(Python),数据层 apppublic/sqlor(MariaDB,库 hrs)。 | 角色 | 代码 | 主要能力 | |---|---|---| | 系统管理员 | admin | 全部数据与配置、角色/管理员/数据范围、操作日志 | -| 人事 | hr | 组织、花名册、入转调离、合同、流程配置、报表 | +| 人事 | hr | 组织、花名册、入转调离、合同、流程配置、报表、编制 | | 部门经理 | manager | 数据范围内入转调离审批、团队统计、关怀提醒 | | 员工(自助) | employee | 个人档案、发起审批、待办、企业政策/公告 | 脱敏基线:身份证号全角色脱敏(前3后3);手机号前3后4;薪资/职级敏感字段仅 admin/hr 可见(由 roster_field_def.sensitive 驱动)。 -## 1. 功能清单(F01~F15,共 81 条验收项) +## 1. 功能 → FEAT 映射与清单(F01~F17,共 90 条验收项) -| # | 功能 | 承载模块 | 表前缀 | 验收项数 | 关键交付 | 范围边界 | -|---|---|---|---|---|---|---| -| F01 | 组织架构 | hr-org | org_ | 6 | 组织树/架构图(含 as_of 历史)/新建变更停用移动/字段自定义/时间轴/Excel 导入 | 编制管理、项目式组织范围外 | -| F02 | 职位职级体系 | hr-org | org_ | 5 | 职位/职务/职级/职等/序列 CRUD + 导入导出 + options | 全量 | -| F03 | 花名册 | hr-roster | roster_ | 8 | 自定义字段(EAV)/分组/工号多规则/自助修改+审核/时间轴/类型规则/搜索/导入导出 | 附件预览依赖 files/ | -| F04 | 入职管理 | hr-org | org_ | 7 | 审批入职/手动批量入职/登记表邀请/黑名单拦截/入职通知/复职 | 扫码入职、身份证读取为降级项 | -| F05 | 转正管理 | hr-org | org_ | 4 | 审批/手动转正、回写花名册、转正提醒 | 全量 | -| F06 | 调动管理 | hr-org | org_ | 4 | 调动查询/审批(晋升/降级/调岗/组织调整)/批量调动 | 全量 | -| F07 | 离职管理 | hr-org | org_ | 7 | 审批/手动离职、交接、离职证明、黑名单、信息存储 | 钉钉资源交接置后 | -| F08 | 兼岗管理 | hr-org | org_ | 3 | 一人多兼岗记录、兼岗审批、通过自动同步 | 全量 | -| F09 | 合同台账 | hr-contract | contract_ | 6 | 台账/类型自定义/模板/审批(新签续签变更终止)/到期提醒 | 电子签置后(esign_stub 预留) | -| F10 | 流程审批 | hr-flow | flow_ | 7 | 表单/流程/节点配置、审批角色、流转引擎、查询导出、打印 | 考勤/薪酬/组合审批置后 | -| F11 | 权限管理 | hr-system | sys_ | 4 | 管理角色、人员范围(组织维度+花名册字段维度)、管理员管理 | 全量 | -| F12 | 操作日志 | hr-system | sys_ | 4 | 全量写操作留痕、前后对比、时间/类型查询 | 全量 | -| F13 | 人事报表 | hr-report | —(只读) | 6 | 花名册/入职/转正/调岗/离职五类分析,数据范围受控 | 全量 | -| F14 | 工作台 | hr-system | sys_ | 5 | 员工/经理/管理员三工作台聚合 | 绩效/考勤统计预留占位 | -| F15 | 员工服务与提醒 | hr-system | sys_ | 5 | 生日周年关怀、政策、公告、多场景到期提醒 | 站内消息优先,短信/邮件预留 | +| # | 功能 | 对应 FEAT(SRS v3.1) | 承载模块 | 表前缀 | 验收项数 | 关键交付 | 范围边界 | +|---|---|---|---|---|---|---|---| +| F01 | 组织架构 | FEAT-B1-02 | hr-org | org_ | 6 | 组织树/架构图(含 as_of 历史)/新建变更停用移动/字段自定义/时间轴/Excel 导入/合同公司 | 全量 | +| F02 | 职位职级体系 | FEAT-B1-03 | hr-org | org_ | 5 | 职位/职务/职级/职等/序列 CRUD + 导入导出 + options | 全量 | +| F03 | 花名册 | FEAT-B1-04 | hr-roster | roster_ | 8 | 自定义字段(EAV)/分组/工号多规则/自助修改+审核/时间轴/类型规则/搜索/导入导出 | 附件预览依赖 files/ | +| F04 | 入职管理 | FEAT-B1-05 | hr-org | org_ | 7 | 审批入职/手动批量入职/登记表邀请(扫码降级)/身份证手工录入(D1)/黑名单拦截/入职通知/复职 | 读卡二期、对外二维码二期 | +| F05 | 转正管理 | FEAT-B1-06 | hr-org | org_ | 4 | 审批/手动转正、回写花名册、转正提醒 | 全量 | +| F06 | 调动管理 | FEAT-B1-06 | hr-org | org_ | 4 | 调动查询/审批(晋升/降级/调岗/组织调整)/批量调动/编制联动提醒 | 全量 | +| F07 | 离职管理 | FEAT-B1-07 | hr-org | org_ | 7 | 审批/手动离职、交接(钉钉占位 D3)、离职证明、黑名单、信息存储 | 钉钉资源交接二期 | +| F08 | 兼岗管理 | FEAT-B1-04 | hr-org | org_ | 3 | 一人多兼岗记录、兼岗审批、通过自动同步 | 全量 | +| F09 | 合同台账 | FEAT-B1-08 | hr-contract | contract_ | 6 | 台账/类型自定义/模板(生成文本 D4)/审批(新签续签变更终止)/到期提醒 | 电子签二期(esign_stub 预留) | +| F10 | 流程审批 | FEAT-B1-01 | hr-flow | flow_ | 7 | 表单/流程/节点配置、审批角色、流转引擎、查询导出、打印;考勤流程桩位 | 薪酬/组合审批批次2 | +| F11 | 权限管理 | FEAT-B1-01 | hr-system | sys_ | 4 | 管理角色,人员范围(组织维度+花名册字段维度),管理员管理 | 全量 | +| F12 | 操作日志 | FEAT-B1-01 | hr-system | sys_ | 4 | 全量写操作留痕、前后对比、时间/类型查询 | 全量 | +| F13 | 人事报表 | FEAT-B1-12 | hr-report | —(只读) | 6 | 花名册/入职/转正/调岗/离职五类分析,数据范围受控,可导出 | 全量 | +| F14 | 工作台 | FEAT-B1-09 | 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. 功能 → 模块 → 数据表落点 | 模块 | 功能 | 主要数据表 | |---|---|---| -| 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_post(18 张) | +| 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_post(23 张) | | hr-roster | F03 | roster_field_group, roster_field_def, roster_employee, roster_field_value, roster_empno_rule, roster_timeline, roster_type_rule(7 张) | | hr-flow | F10 | flow_form_def, flow_def, flow_node_def, flow_role, flow_instance, flow_task, flow_op_log(7 张) | | hr-contract | F09 | contract_type, contract_template, contract_info, contract_remind_rule(4 张) | | 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_config(7 张) | +| 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_openapp(8 张,末张为 API 开放预留) | -共 43 张业务表,详见 `database-design.md`。 +共 **49 张业务表**,详见 `database-design.md`。 ## 3. 设计文档索引 | 文档 | 内容 | |---|---| -| architecture.md | 系统架构、技术选型、模块划分与依赖、hr-system/staff-mgr 职责边界、部署、安全、非功能 | -| database-design.md | ER、43 表结构、索引、数据字典、models JSON、staff-mgr 迁移 | -| api-design.md | dspy 端点清单、通用约定、鉴权、错误码、典型调用链、v1 接口替代 | +| architecture.md | 系统架构、技术选型、模块划分与依赖、部署(9182/MariaDB hrs)、安全、非功能、降级项设计专章、API 开放规范 | +| database-design.md | ER、49 表结构、索引、数据字典、models JSON、staff-mgr 迁移 | +| api-design.md | dspy 端点清单(约 120 个)、通用约定、鉴权、错误码、典型调用链、降级桩端点汇总 | | 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 §10):D1 身份证手工录入、D3 离职交接钉钉占位、D4 合同模板文本+esign_stub、D9 站内消息兜底、扫码入职内网登记链接/二维码、考勤/绩效/工资条工作台桩位。 +- 以上均在一期做字段/桩端点/流程位预留,二期对接不改表结构主干。 diff --git a/docs/01-design/iteration1-task-breakdown.md b/docs/01-design/iteration1-task-breakdown.md index 67d21f2..f352c23 100644 --- a/docs/01-design/iteration1-task-breakdown.md +++ b/docs/01-design/iteration1-task-breakdown.md @@ -1,9 +1,9 @@ -# 迭代1总体设计 —— 技术可行性与开发任务拆解(hr-web) +# 一期批次1总体设计 —— 技术可行性与开发任务拆解(hr-web) -- 版本:v1.0(迭代1-总体设计配套文档) -- 状态:评审通过(主agent评审,基线冻结) -- 基线:`docs/01-design/architecture.md`(架构)+ `database-design.md`(43 表)+ `api-design.md`(端点清单)+ `ui-design.md`(页面结构) -- 需求基线:`docs/00-requirement/requirement-spec.md`(SRS v2)+ `iteration1-function-detail.md`(F01~F15,81 条验收项) +- 版本:v2.0(批次1设计定稿;v2.0 变更:对齐 SRS v3.1 —— 范围扩入编制(F16)/项目式(F17)、新增降级项任务、部署任务与开放接口桩任务;任务编号 T01~T27,可直接用于 develop 角色创建开发任务) +- 状态:**设计定稿(批次1评审修订版)** +- 基线:`docs/01-design/architecture.md`(架构)+ `database-design.md`(49 表)+ `api-design.md`(端点清单)+ `ui-design.md`(页面结构) +- 需求基线:`docs/00-requirement/requirement-spec.md`(SRS v3.1)+ `iteration1-function-detail.md`(F01~F15,81 条)+ approved-features.md(FEAT-B1-01~12) ## 1. 技术可行性说明 @@ -11,89 +11,104 @@ | 能力诉求 | ocai 设施 | 成熟度结论 | |---|---|---| -| 声明式 CRUD 页面 | json/*.json + xls2ui 自动生成 DataViewer/Form/Tree | 成熟(产线既有模式);迭代1约 20 个 CRUD 页面零手写 | -| 组织树/架构图 | Tree widget + org_unit parent_id 自引用 + as_of 历史查询 | 可行;历史架构靠 org_unit_change 时间轴回放/有效期区间过滤 | -| 自定义字段(花名册/组织) | EAV 双表 + field_def 元数据驱动表单渲染 | 可行;列表页采用"主表分页+值表批量拼装"规避 EAV 性能问题 | -| 审批引擎 | flow_def/node_def JSON 配置 + flow_instance/task 状态机 | 可行;迭代1仅串行节点 + any/all 通过规则,不做并行分支(满足 F10 验收) | -| 审批通过自动回写 | biz_type+biz_id 关联 + ServerEnv 注册回调 hook | 可行;模块宿主无关原则下经 load_xxx() 注册函数互调 | -| 批量导入导出 | ahserver 后台任务 + openpyxl + files/ 结果文件 | 可行;100 人量级同步/准同步处理即可 | -| 数据范围权限 | rbac 路径级 + sys_data_scope(组织/字段双维度)查询叠加 | 可行;复用 rbac-permission-initialization-pattern | -| 脱敏/审计 | roster_field_def.sensitive + sys_audit_log 前后 JSON | 可行;替代 staff-mgr 硬编码 MaskUtil | -| 图表报表 | bricks Chart widgets(bricks-chart-widgets 技能) | 可行;聚合 SQL 只读查询 | -| 提醒推送 | cron 扫描 remind_scan + sys_message 站内消息 | 可行;短信/邮件通道预留 send_channel 字段 | +| 声明式 CRUD 页面 | json/*.json + xls2ui 自动生成 DataViewer/Form/Tree | 成熟(产线既有模式);批次1约 25 个 CRUD 页面零手写 | +| 组织树/架构图 | Tree widget + org_unit parent_id 自引用 + as_of 历史查询 | 可行;历史架构按 effective_date/expire_date + org_unit_change 回放 | +| 自定义字段(花名册/组织) | EAV 双表 + field_def 元数据驱动表单渲染 | 可行;列表页"主表分页+值表批量拼装"规避 EAV 性能问题 | +| 审批引擎 | flow_def/node_def JSON 配置 + flow_instance/task 状态机 | 可行;一期仅串行节点 + any/all 通过规则,不做并行分支(满足 F10 验收);四类人事流程模板 init/data.json 预置 | +| 审批通过自动回写 | biz_type+biz_id 关联 + ServerEnv 注册回调 hook | 可行;roster_writeback 唯一入口,回写后联动 headcount_check 与 timeline | +| 批量导入导出 | ahserver 后台任务 + openpyxl + files/ 结果文件 | 可行;500 行 ≤30s 指标(NFR-1)在 100 人量级轻松满足 | +| 数据范围权限 | rbac 路径级 + sys_data_scope(组织/字段双维度)查询叠加 | 可行;查询/报表/导出三处强制叠加 | +| 脱敏/审计 | roster_field_def.sensitive + sys_audit_log 前后 JSON | 可行 | +| 图表报表 | bricks Chart widgets | 可行;聚合 SQL 只读查询,≤3s 指标满足 | +| 提醒推送 | 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 规模与性能 -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 主要风险与对策 | 风险 | 等级 | 对策 | |---|---|---| -| EAV 自定义字段在列表页的筛选/排序复杂度 | 中 | 迭代1筛选支持"主表字段 + 至多 3 个自定义字段等值匹配",排序仅主表字段;超出部分作为已知限制写入 UAT 说明 | -| 审批引擎配置化过度导致返工 | 中 | 迭代1锁定"串行节点、any/all、字段权限、抄送"能力边界;并行/条件分支留 flow_node_def JSON 扩展位 | -| staff-mgr 旧数据语义差异(status/加密算法) | 中 | 迁移脚本内置映射表 + 核对报告 + UAT 双库比对(见 database-design.md §7) | -| 6 模块并行开发契约漂移 | 中 | 本文 T01 先行冻结表定义 models JSON 与 api-design 端点签名,变更走设计评审 | +| EAV 自定义字段在列表页的筛选/排序复杂度 | 中 | 筛选支持"主表字段 + 至多 3 个自定义字段等值匹配",排序仅主表字段;已知限制写入 UAT 说明 | +| 审批引擎配置化过度导致返工 | 中 | 锁定"串行节点、any/all、字段权限、抄送"能力边界;并行/条件分支留 flow_node_def JSON 扩展位 | +| staff-mgr 旧数据语义差异(status/加密算法) | 中 | 迁移脚本内置映射表 + 核对报告 + UAT 双库比对;迁移范围待 PM 确认(SRS Q3),脚本支持 --scope 参数 | +| 6 模块并行开发契约漂移 | 中 | T01 先行冻结表定义 models JSON 与 api-design 端点签名,变更走设计评审 | | 提醒场景字段依赖(健康证/社保等花名册字段未建) | 低 | 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(档案证件展示脱敏) | +| 扫码入职→内网登记链接/二维码 | T13(entry_register 页面+token+二维码) | +| D3 钉钉交接→占位项 | T17(交接项 dingtalk_resource 类型手工登记) | +| D4 电子签→模板文本+桩 | T19(contract_text_gen + esign_stub) | +| D9 短信→站内兜底 | T16(send_channel=site;sms/email 枚举预留) | +| 考勤/绩效/工资条桩位 | T10(attendance_* 表单桩)/T21(工作台桩位卡片) | +| API 开放接口预留 | T26(sys_openapp 表 + /openapi/v1/ping 桩) | -## 2. 开发任务拆解(T01~T24,契约先行) +## 2. 开发任务拆解(T01~T27,契约先行) -> 依赖关系:T01~T02 为契约冻结阶段,全量先行;其后按模块并行。工作量单位:人日(估算,供 PM 排期)。 +> 依赖关系:T01~T02 为契约冻结阶段,全量先行;其后按模块并行。工作量单位:人日(估算,供 PM 排期)。每个任务含验收对照(F#/FEAT 编号),develop 角色可直接按任务建卡。 ### 阶段0 契约与脚手架 -| 编号 | 任务 | 内容/产出 | 依赖 | 估时 | -|---|---|---|---|---| -| T01 | 数据契约冻结 | 6 模块仓库建仓(hr_org/hr_roster/hr_flow/hr_contract/hr_report,hr-system 复用既有空仓);43 张 models/*.json 全量提交;json2ddl 生成 DDL 验证 | — | 4 | -| T02 | 应用脚手架 | hr-web 应用仓(app/hr_web.py、conf/config.json 含 processors/indexes/session、build.sh、.env);appbase/rbac 加载验证;登录走通 | T01 | 2 | +| 编号 | 任务 | 内容/产出 | 验收对照 | 依赖 | 估时 | +|---|---|---|---|---|---| +| T01 | 数据契约冻结 | 6 模块仓库建仓(hr_org/hr_roster/hr_flow/hr_contract/hr_report,hr-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/databases.hrs、build.sh、systemd unit);appbase/rbac 加载验证;登录走通;内置 admin+四角色初始化 | SRS §5.2-4 | T01 | 2 | ### 阶段1 主数据与底座(可并行) -| 编号 | 任务 | 内容/产出 | 依赖 | 估时 | -|---|---|---|---|---| -| T03 | hr-org 组织管理 | org_unit CRUD/树/停用/移动、org_field_def 自定义字段、org_unit_change 时间轴、org_tree/org_import 端点、org_tree.ui/org_chart.ui(F01) | T01,T02 | 5 | -| T04 | hr-org 职位职级 | org_job/position/sequence/grade_level/grade_rank CRUD + 导入导出 + options 端点(F02) | T03 | 3 | -| T05 | hr-roster 字段体系 | roster_field_group/field_def/type_rule/empno_rule 配置页与端点、工号生成器(F03 搭建类验收 1/2/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 | -| T07 | hr-roster 导入导出 | roster_import(新增/修改)、模板生成、roster_export(字段/顺序/as_of)(F03 验收 8) | T06 | 3 | -| T08 | hr-system 权限底座 | 角色/管理员/数据范围(sys_data_scope 双维度)、get_data_scope 注册、各模块查询叠加(F11) | T02 | 4 | -| T09 | hr-system 审计底座 | write_audit_log + sys_audit_log 查询/详情对比页(F12) | T02 | 2 | +| 编号 | 任务 | 内容/产出 | 验收对照 | 依赖 | 估时 | +|---|---|---|---|---|---| +| T03 | hr-org 组织管理 | org_unit CRUD/树/停用/移动(子树+员工联动)、org_field_def 自定义字段、org_unit_change 时间轴、org_import(≥200行)、org_tree.ui/org_chart.ui(as_of+导出)、合同公司 company CRUD | F01 全 6 项 + FEAT-B1-02 | T01,T02 | 5 | +| 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 配置页与端点、工号生成器(多规则+冲突报错)、field_config.ui 拖拽排序 | F03 验收 1/3/6 | T01,T02 | 4 | +| 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(新增/修改,≥500 行含更新匹配)、模板生成(按字段定义+类型规则)、roster_export(字段/顺序/as_of,强制数据范围) | F03 验收 8 | T06 | 3 | +| 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(全量写操作含导入导出/审批/登录,前后值+IP)+ audit_log_list.ui 详情对比 | F12 全 4 项 + SRS §2.2-5 | T02 | 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 | -| T11 | hr-flow 审批界面 | todo/done/mine/received 列表、inst_detail 动态表单渲染、approve/reject/forward/withdraw、打印(F10 验收 5/6) | T10 | 4 | -| T12 | hr-flow 查询导出 | inst_query/inst_export、审批角色数据范围生效验证(F10 验收 3/5) | T10,T08 | 2 | +| 编号 | 任务 | 内容/产出 | 验收对照 | 依赖 | 估时 | +|---|---|---|---|---|---| +| 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、inst_print A4 | F10 验收 6/7 + F14-4 | T10 | 4 | +| T12 | hr-flow 查询导出 | inst_query/inst_export、审批角色数据范围生效验证 | F10 验收 3/6 + FEAT-B1-01 ④ | T10,T08 | 2 | ### 阶段3 入转调离与合同(依赖 T10 回调,可部分并行) -| 编号 | 任务 | 内容/产出 | 依赖 | 估时 | -|---|---|---|---|---| -| T13 | 入职管理 | entry_approval/entry_manual(批量)/登记表邀请与提交/黑名单校验与高亮/入职通知/复职关联(F04 全 7 项) | T10,T06 | 5 | -| T14 | 转正管理 | regular_apply(自助/代发)/regular_manual/回写花名册/转正提醒接入(F05 全 4 项) | T10,T06,T16 | 3 | -| T15 | 调动管理 | transfer_apply(含批量明细)/transfer_cancel/回写档案与花名册/调动查询(F06 全 4 项) | T10,T06 | 4 | -| T16 | 提醒引擎 | sys_remind_rule/care_config/remind_scan(转正/合同/生日/周年等场景)+ sys_message(F15 提醒类验收) | T02 | 3 | -| T17 | 离职管理 | leave_apply/leave_manual/交接项/办理离职/离职证明生成下载/一键黑名单/信息存储(F07 全 7 项,钉钉交接留扩展点) | T10,T06 | 5 | -| T18 | 兼岗管理 | concurrent_apply/兼岗记录维护/审批通过同步花名册(F08 全 3 项) | T10,T06 | 2 | -| T19 | 合同台账 | contract_type/template/info CRUD + 批量导入 + 合同审批(新签/续签/变更/终止)+ 到期提醒规则 + esign_stub 预留(F09 全 6 项) | T10,T06,T16 | 4 | +| 编号 | 任务 | 内容/产出 | 验收对照 | 依赖 | 估时 | +|---|---|---|---|---|---| +| 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/回写花名册(状态+转正日期)/转正提醒接入(probation_end_date 提前 7 天可配) | F05 全 4 项 + FEAT-B1-06 转正 | T10,T06,T16 | 3 | +| T15 | 调动管理 | transfer_apply(批量 ≥20 人明细)/transfer_cancel/回写档案+时间轴/调动查询(状态/类型/日期)/编制联动提醒接入 | F06 全 4 项 + FEAT-B1-06 调动 | T10,T06 | 4 | +| T16 | 提醒引擎 | sys_remind_rule(≥6 场景)/care_config(生日/周年文案)/remind_scan(转正/合同/生日/周年/退休/离职生效扫描)+ sys_message(send_channel=site,sms/email 预留 D9) | F15 提醒类验收 1/4/5 | T02 | 3 | +| T17 | 离职管理 | leave_apply/leave_manual/交接项(**含 dingtalk_resource 占位手工登记 D3**)/到期自动生效(leave_effect)/离职证明 PDF 生成下载/一键黑名单/离职员工信息存储可查可改 | F07 全 7 项 + FEAT-B1-07 | T10,T06,T16 | 5 | +| T18 | 兼岗管理 | concurrent_apply/兼岗记录维护/审批通过自动同步(状态 active,供薪酬引用) | F08 全 3 项 + FEAT-B1-04 兼岗 | T10,T06 | 2 | +| 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 报表、工作台、员工服务与收尾 -| 编号 | 任务 | 内容/产出 | 依赖 | 估时 | -|---|---|---|---|---| -| T20 | 人事报表 | roster/entry/regular/transfer/leave 五类分析端点 + report_board.ui 图表(F13 全 6 项,数据范围受控) | T06,T13~T17 | 4 | -| T21 | 工作台 | workbench_employee/manager/admin 聚合端点与三页面(F14 全 5 项,绩效/考勤占位预留) | T10,T11,T16 | 3 | -| T22 | 员工服务 | 公告/政策发布与查询(查阅范围/下载权限)、关怀文案配置(F15 服务类验收 1~3) | T16 | 2 | -| T23 | staff-mgr 迁移 | migrate_staff_mgr.py(映射/解密重加密/幂等/核对报告)、UAT 双库比对、切换演练 | T06,T09 | 3 | -| T24 | 集成联调与验收 | F01~F15 共 81 条验收项端到端回归;性能验证(列表 ≤500ms);load_path 全路径注册核查;部署脚本验证(dev/test) | 全部 | 4 | +### 阶段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 | 项目式组织 | org_project/org_project_post CRUD + project_tree.ui + 横向职务(job_category=horizontal)维护与 options + 到期自动标识 | F17 全 3 项 + FEAT-B1-11 | T04,T06 | 3 | +| T22 | 人事报表 | roster/entry/regular/transfer/leave 五类分析端点(维度可配置)+ report_board.ui 图表 + report_export(与页面一致)+ 全程数据范围 | F13 全 6 项 + FEAT-B1-12 | T06,T13~T18 | 4 | +| T23 | 工作台 | workbench_employee/manager/admin 聚合端点与三页面(**工资条/绩效/考勤桩位卡片**)+ 消息铃铛 | F14 全 5 项 + FEAT-B1-09 工作台 | T10,T11,T16 | 3 | +| 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-2);load_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. 交付与验收定义 - 每个 T 任务交付:模块仓代码(models/json/wwwroot/init/scripts/skill/SKILL.md)+ 对应功能验收项自测记录。 - 契约变更(表结构/端点签名)必须回改 docs/01-design 四份文档并评审。 -- T24 通过标准:81 条验收项全部通过或经 PM 确认降级项(扫码入职、身份证读取、钉钉交接、电子签为既定范围外/降级项)。 +- T27 通过标准:90 条验收项全部通过;P0(FEAT-B1-01~05)100% 通过;降级项按 SRS §9 验证桩位与降级方案生效(D1 手工录入+脱敏、D3 交接占位、D4 模板文本+NOT_ENABLED 桩、D9 站内兜底、扫码登记内网闭环);性能/权限/脱敏抽测记录齐备(SRS §10)。 +- 批次1完成即满足批次2(薪酬)进入条件:花名册/组织/流程/报表基线 + 权限日志基线 + 消息通道(SRS §1.4)。 diff --git a/docs/01-design/ui-design.md b/docs/01-design/ui-design.md index d8aed85..295f290 100644 --- a/docs/01-design/ui-design.md +++ b/docs/01-design/ui-design.md @@ -1,7 +1,7 @@ -# 迭代1总体设计 —— UI/页面设计(hr-web,ocai 口径) +# 一期批次1总体设计 —— UI/页面设计(hr-web,ocai 口径) -- 版本:v2.0(迭代1-总体设计,取代 v1 Vue3/Element Plus 口径,v1 已归档至 `docs/_archive/01-design-v1-old/ui-design.md`) -- 状态:评审通过(主agent评审,基线冻结) +- 版本:v3.0(批次1设计定稿;v3.0 变更:对齐 SRS v3.1 —— 新增编制看板(F16)/项目式组织(F17)页面、工作台工资条/绩效桩位、入职登记链接与二维码交互(扫码入职降级)、证件手工录入交互(D1)、合同文本生成打印、离职交接钉钉占位项) +- 状态:**设计定稿(批次1评审修订版)** - 规范依据:ocai 技能集 bricks-framework、bricks-layout-patterns、module-development-spec(index.ui 强制)、crud-definition-spec;交互基线 `docs/01-design/architecture.md` ## 1. 界面体系与总体布局 @@ -9,7 +9,7 @@ 1. **技术形态**:无 Vue/无手写 HTML。页面 = `wwwroot/*.ui`(纯 JSON bricks 组件树)+ `*.dspy`(数据端点);CRUD 列表/表单页由 json/*.json 经 xls2ui 自动生成 DataViewer/Form/Tree 页面。 2. **入口**:`/index.ui`(应用门户,菜单聚合 6 模块入口);每模块强制 `/{module}/index.ui`(ResponsableBox 功能卡片导航)。 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)。 6. **URL 规则**:.ui 内全部 url 使用 `{{entire_url('/module/xxx.ui')}}` 绝对路径;json/ 内引用别名用 `{{entire_url('../alias')}}`。 @@ -17,7 +17,7 @@ ``` index.ui (VBox, height:100%) -├── Header(HBox): Text「Web版人事系统」+ 用户信息 + [消息铃铛(message_list 未读数)] +├── Header(HBox): Text「Web版人事系统」+ 用户信息 + [消息铃铛(message_unread_count.dspy 未读数)] ├── 内容区(HBox, flex:1) │ ├── Menu(id:app.menu, width:220px) │ │ ├── 工作台 → /hrsystem/workbench_*.ui(按角色路由) @@ -25,6 +25,8 @@ index.ui (VBox, height:100%) │ │ ├── 花名册 → /hrroster/index.ui │ │ ├── 审批中心 → /hrflow/index.ui │ │ ├── 合同管理 → /hrcontract/index.ui +│ │ ├── 编制管理 → /hrorg/headcount_board.ui(F16) +│ │ ├── 项目组织 → /hrorg/project_tree.ui(F17) │ │ ├── 人事报表 → /hrreport/index.ui │ │ ├── 员工服务 → /hrsystem/service.ui(公告/政策) │ │ └── 系统管理 → /hrsystem/index.ui(角色/范围/管理员/日志) @@ -37,31 +39,36 @@ index.ui (VBox, height:100%) | URL | 页面 | 说明 | 角色 | |---|---|---|---| | /index.ui | 应用门户 | 全局导航 | L | -| /hrorg/index.ui | 组织模块入口 | 卡片:组织树/架构图/时间轴/职位职级/入转调离工作台/黑名单 | L | +| /hrorg/index.ui | 组织模块入口 | 卡片:组织树/架构图/时间轴/职位职级/入转调离工作台/编制/项目组织/黑名单 | 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/entry_workbench.ui | 入职工作台 | 待入职/审批中/黑名单高亮 | A,H | +| /hrorg/company_list.ui | 合同公司台账 | CRUD(FEAT-B1-02) | A,H | +| /hrorg/entry_workbench.ui | 入职工作台 | 待入职/审批中/黑名单高亮/登记二维码 | A,H | +| /hrorg/entry_register.tmpl | 入职登记表(免登录) | 候选人扫码填表页(内网 token 鉴权,扫码入职降级) | 匿名(token) | | /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/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 | | /hrflow/index.ui | 审批中心入口 | 待办/已办/我发起/我收到/流程配置 | L | | /hrflow/todo_list.ui | 待办列表 | DataViewer,行内审批 | L | | /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/contract_list.ui | 合同台账 | DataViewer + 到期高亮 | A,H | +| /hrcontract/contract_list.ui | 合同台账 | DataViewer + 到期高亮 + 文本生成 | A,H | | /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/workbench_employee.ui | 员工工作台 | 个人档案/发起审批/待办 | E | -| /hrsystem/workbench_manager.ui | 经理工作台 | 团队统计/入转调离审批/关怀 | M | +| /hrsystem/workbench_employee.ui | 员工工作台 | 个人档案/发起审批/待办;工资条/绩效桩位 | E | +| /hrsystem/workbench_manager.ui | 经理工作台 | 团队统计/入转调离审批/关怀;考勤/团队绩效桩位 | M | | /hrsystem/workbench_admin.ui | 管理员工作台 | 人事统计/合同/提醒 | A,H | | /hrsystem/audit_log_list.ui | 操作日志 | DataViewer + 详情对比弹窗 | A | -| /hrsystem/service.ui | 员工服务 | 公告/政策查询预览 | L | +| /hrsystem/service.ui | 员工服务 | 公告/政策查询预览(下载按权限) | L | | /hrsystem/message_list.ui | 站内消息 | 未读/已读 | L | ## 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) ├── 操作按钮行: [编辑][移动(PopupWindow)][停用(二次确认)] ← A/H 角色可见 └── 变更时间轴 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_timeline(params_mapping 传 id);停用前弹确认 PopupWindow;停用后该组织在入职/调动表单 options 中不可选(服务端过滤 status=active)。 +交互:Tree 节点点击 → urlwidget 刷新 org_detail 与 org_timeline(params_mapping 传 id);停用前弹确认 PopupWindow;停用后该组织在入职/调动表单 options 中不可选(服务端过滤 status=active);组织移动后员工任职部门随组织联动(服务端处理,页面提示影响人数)。 ### 3.2 组织架构图 /hrorg/org_chart.ui(F01) @@ -90,16 +97,16 @@ org_chart.ui (VBox) ├── 工具行(HBox): DatePicker(as_of 历史日期) + TreeSelect(根节点) + 显示内容多选(姓名/职位/负责人) + Button[查看][导出PNG][导出XMind] └── 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.ui(F03,CRUD 生成) ``` 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: -│ ├── [新增员工] → PopupWindow → roster_employee_create.dspy -│ ├── [导入] → PopupWindow: 模板下载链接 + FileUpload(roster_import.dspy) + 结果文件下载 +│ ├── [新增员工] → PopupWindow → roster_employee_create.dspy(含证件信息分组:证件类型/号码/有效期起止/签发机关,手工录入 D1) +│ ├── [导入] → PopupWindow: 模板下载链接 + FileUpload(roster_import.dspy, mode=new/update) + 结果文件下载 │ ├── [导出] → PopupWindow: 字段多选(拖拽排序) + as_of 日期 → roster_export.dspy │ └── [字段配置] → url 跳转 field_config.ui(A/H) ├── 列: 工号/姓名(点击→employee_detail.ui?id=)/组织/职位/员工类型/状态/入职日期 + 自定义显示列 @@ -112,14 +119,15 @@ roster_list.ui = DataViewer(json/roster_employee_list.json 生成) employee_detail.ui (VBox) ├── 头部卡片(HBox): 头像 + 姓名/工号/状态标签 + 快捷操作[编辑][发起审批](PopupWindow 选择 biz_type) ├── 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 兼岗记录(DataViewer subtables: org_concurrent_post by employee_id) │ ├── Tab 合同(DataViewer subtables: contract_info by employee_id) +│ ├── Tab 项目任职(F17:org_project_post by employee_id,横向项目+横向职务) │ └── Tab 审批记录(dataurl=inst_mine.dspy?about=..) └── 附件: 字段类型=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) @@ -127,17 +135,20 @@ employee_detail.ui (VBox) entry_workbench.ui (VBox) ├── 状态卡片行(ResponsableBox): 待入职数/审批中数/本月入职数(dataurl=workbench_transfer.dspy) ├── 待入职列表 DataViewer(org_entry by entry_status=pending_entry) -│ ├── 黑名单命中行: 高亮样式(confidential_fields/行样式) + [拦截原因] -│ └── 行操作: [邀请填登记表][发送入职通知][直接入花名册] -└── 工具行: [手动入职(批量 PopupWindow)][发起入职审批] +│ ├── 黑名单命中行: 高亮样式 + [拦截原因](BLACKLIST_HIT) +│ ├── 登记表状态列: none/invited/filled + [复制链接][二维码(PopupWindow 展示二维码图片+有效期)] +│ └── 行操作: [邀请填登记表(entry_invite_register.dspy)][发送入职通知][直接入花名册][复职匹配提示(命中历史档案时高亮)] +└── 工具行: [手动入职(批量 PopupWindow)][发起入职审批(含证件信息手工录入分组)] 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) ├── 待离职名单 DataViewer(org_leave by status=pending_leave) -│ 行操作: [交接管理(PopupWindow: org_leave_handover 编辑)][办理离职][开具证明][加入黑名单(确认弹窗)] -└── 已离职列表 DataViewer(status=left) + [离职证明下载] +│ 行操作: [交接管理(PopupWindow: org_leave_handover 编辑,交接项类型含"钉钉资源交接(占位,手工登记内容)")][办理离职][开具证明][加入黑名单(确认弹窗)] +├── 交接完成率: 每个离职单展示交接项完成进度条(done/total) +└── 已离职列表 DataViewer(status=left) + [离职证明下载(PDF)] + [加入黑名单] ``` ### 3.6 审批中心(F10) @@ -149,16 +160,44 @@ todo_list.ui = DataViewer(dataurl=task_todo.dspy) inst_detail.ui (VBox) ├── 表单渲染区(id:form_box, dataurl=inst_detail.dspy) —— 按 flow_form_def 动态渲染,节点字段权限控制可编辑性 ├── 流转记录 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.dspy,A4 版式)] 操作完成后 script 刷新页面 → 列表刷新 flow_design.ui (A/H): 三区块 -├── 表单定义 DataViewer(flow_form_def) + 字段引用器(勾选 roster_field_def) -├── 流程定义 DataViewer(flow_def) + 节点编辑 PopupWindow(审批人类型/通过规则/字段权限) -└── 审批角色 DataViewer(flow_role, 仅 admin) +├── 表单定义 DataViewer(flow_form_def) + 字段引用器(勾选 roster_field_def;biz_type 含考勤桩位 attendance_* 分组提示"桩位,不联动考勤系统") +├── 流程定义 DataViewer(flow_def,含初始化预置的人事四类模板:入职/转正/异动/离职/离职交接) + 节点编辑 PopupWindow(审批人类型/通过规则 any-all/字段权限/抄送) +└── 审批角色 DataViewer(flow_role, 仅 admin;三维配置:流程范围/操作权限/数据查看) ``` -### 3.7 报表看板 /hrreport/report_board.ui(F13) +### 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.ui(F13) ``` report_board.ui (VBox) @@ -167,71 +206,92 @@ report_board.ui (VBox) ├── 入职 Tab: 维度(部门/地区/岗位) + 周期选择 + Chart(趋势折线 + 分布柱) ├── 转正 Tab: Chart(趋势) + 近期待转正 DataViewer(regular_analysis.dspy) ├── 调岗 Tab: 日期范围 + Chart(按类型柱状) -└── 离职 Tab: 卡片(待离职人数/离职率/同比/环比) + Chart(离职原因饼图) +├── 离职 Tab: 卡片(待离职人数/离职率/同比/环比) + Chart(离职原因饼图) +└── 各 Tab 右上 [导出] → report_export.dspy(与页面数据一致) ``` 所有看板查询服务端叠加数据范围;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 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) -remind_config.ui: DataViewer(sys_remind_rule) + DataViewer(sys_care_config) -service.ui: Tabs[公告 DataViewer(sys_announcement)][政策 DataViewer(sys_policy, 行内预览/下载按权限)] +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, 行内预览/下载按 view_scope+downloadable 权限)] message_list.ui: DataViewer(msg_type/is_read 筛选) 行点击标已读 ``` -### 3.9 工作台(F14) +### 3.12 工作台(F14) ``` -workbench_employee.ui (ResponsableBox) -├── 卡片: 个人档案(→employee_detail.ui?id=self) | 发起审批(PopupWindow 选择流程类型→flow_start) +workbench_employee.ui (ResponsableBox 移动端自适应) +├── 卡片: 个人档案(→employee_detail.ui?id=self) | 工资条(桩位卡片:显示"薪酬模块上线后可用",FEAT-B1-09) | 个人绩效(桩位:同上) | 发起审批(PopupWindow 选择流程类型→flow_start) ├── 待办/已办/我发起/我收到 四 Tab DataViewer(task_todo/done/inst_mine/received) +└── 企业政策/公告入口(service.ui) workbench_manager.ui (VBox) -├── 统计卡片行(dataurl=team_stats.dspy): 团队人数/本月入离职/待审批数 -├── 待审批 DataViewer(task_todo 范围=团队) | 团队入转调离 DataViewer(workbench_transfer.dspy) +├── 统计卡片行(dataurl=team_stats.dspy): 团队人数/本月入离职/待审批数(考勤统计/团队绩效为桩位卡片"未接入") +├── 待审批 DataViewer(task_todo 范围=团队) | 团队入转调离 DataViewer(workbench_transfer.dspy scope=team) └── 关怀提醒 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. 核心交互流程(页面级时序) -1. **入职(审批)**:entry_workbench [发起入职审批] → PopupWindow 表单 → entry_approval.dspy →(BLACKLIST_HIT 则红色高亮提示)成功 → 待审批列表出现;审批人在 todo_list 处理 → inst_detail 同意 → 花名册新增记录 → message_list 收到入职通知。 -2. **员工自助修改**:employee_detail → 编辑可改字段 → 保存 → 提示"直接生效"或"已提交审核"(need_audit)→ 审核通过后字段更新、时间轴留痕。 -3. **调动批量**:transfer_list [发起调动] → PopupWindow 多人选择 + 目标组织/职位 → transfer_apply.dspy → 生成批量审批单 → 通过后逐人更新,明细可追溯。 -4. **离职全流程**:leave_workbench 发起/手动 → 待离职名单 → [交接管理]逐项勾选 → [办理离职] → 状态 left → [开具证明]下载 → 可选[加入黑名单]。 -5. **合同到期提醒**:remind_scan(后台)→ message_list 消息 → workbench_admin 到期卡片 → contract_list 行内到期高亮。 -6. **历史架构图**:org_chart 选择 as_of 日期 → 查看 → 导出 PNG/XMind。 +1. **入职(审批)**:entry_workbench [发起入职审批] → PopupWindow 表单(含证件信息手工录入分组)→ entry_approval.dspy →(BLACKLIST_HIT 则红色高亮提示)成功 → 待审批列表出现;审批人在 todo_list 处理 → inst_detail 同意 → 花名册新增记录 → message_list 收到入职通知。 +2. **入职登记表(扫码降级)**:待入职行 [邀请填登记表] → 生成链接+二维码(PopupWindow 展示,内网访问)→ 候选人扫码打开 entry_register.tmpl → 填写提交 → 列表登记表状态 filled → 继续审批/入职。 +3. **复职**:发起入职审批输入证件号 → entry_rehire_match 命中历史档案 → 表单提示"复职:原部门/职位"并自动带出关联 → 入职后档案显示复职标签。 +4. **员工自助修改**:employee_detail → 编辑可改字段 → 保存 → 提示"直接生效"或"已提交审核"(need_audit)→ 审核通过后字段更新、时间轴留痕。 +5. **调动批量**:transfer_list [发起调动] → PopupWindow 多人选择 + 调动类型 + 逐人目标 → transfer_apply.dspy → 生成批量审批单 → 通过后逐人更新(明细可追溯)→ 编制联动校验提醒。 +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. 设计规范 1. **布局**:左侧 Menu 固定 220px;内容区 VBox 滚动;卡片统一圆角 8px、间距 16px;表单 label 右对齐;列表默认每页 50。 -2. **状态色**:active/在职=绿、probation/审批中=橙、inactive/离职/驳回=灰、黑名单/超期=红。 -3. **反馈**:操作成功 message 提示并刷新当前视图;不可逆操作(停用/删除语义/加黑名单)一律 PopupWindow 二次确认;耗时操作(导入导出)返回 task_id 后轮询/消息通知结果。 -4. **空态/加载**:DataViewer 自带 loading 与空数据提示。 -5. **权限感知**:按钮与列按角色渲染(load_path + CRUD confidential_fields);敏感字段服务端脱敏后展示。 -6. **移动端兼容**:员工自助页面(工作台/档案/待办/服务/消息)使用 ResponsableBox 自适应,窄屏卡片化;管理类页面 PC 优先。 -7. **打印**:审批单 inst_print.dspy 输出 A4 打印样式页面。 +2. **状态色**:active/在职=绿、probation/审批中=橙、inactive/离职/驳回=灰、黑名单/超编/到期=红。 +3. **反馈**:操作成功 message 提示并刷新当前视图;不可逆操作(停用/加黑名单)一律 PopupWindow 二次确认;耗时操作(导入导出)返回 task_id 后轮询/消息通知结果。 +4. **空态/加载**:DataViewer 自带 loading 与空数据提示;桩位卡片(工资条/绩效/考勤)统一"未接入"样式与文案。 +5. **权限感知**:按钮与列按角色渲染(load_path + CRUD confidential_fields);敏感字段服务端脱敏后展示(证件号前3后3、手机前3后4)。 +6. **移动端兼容**:员工自助页面(工作台/档案/待办/服务/消息/登记表)使用 ResponsableBox 自适应,窄屏卡片化;管理类页面 PC 优先(NFR-6)。 +7. **打印**:审批单 inst_print.dspy 输出 A4 打印样式页面;合同文本 docx/pdf 直接打印。 ## 6. 页面-接口追溯 | 页面 | 主要接口(见 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 | -| roster_list.ui | roster_list / roster_employee_create / roster_import / roster_export / check_employee_no | -| employee_detail.ui | employee_detail / roster_employee_update / timeline / file_preview_url | -| entry_workbench.ui | entry_approval / entry_manual / entry_invite_register / entry_blacklist_check / entry_notify | +| company_list.ui | company_save(CRUD) | +| position_list.ui 等 | position/job/grade/rank/sequence CRUD + *_import/_export + *_options | +| 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 | | 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 | -| flow_design.ui | form_def_save / flow_def_save / flow_node_save / flow_role_save | -| contract_list.ui | contract_list / contract_create / contract_import / contract_apply / contract_remind_rule_save | -| report_board.ui | roster_analysis / entry_analysis / regular_analysis / transfer_analysis / leave_analysis | -| workbench_*.ui | workbench_employee / workbench_manager / workbench_admin / team_stats | +| 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_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_export | +| workbench_*.ui | workbench_employee / workbench_manager / workbench_admin / team_stats / contract_expire_soon | | 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 |