fix(design): 恢复批次1设计文档完整正文(修复 bfc1003 误截断;自 e6b266f 还原6份文档共143.5KB,含49表DDL/113端点/90验收项/T01~T27任务拆解/降级项方案,已推送 origin/main 857c1fd)
This commit is contained in:
parent
857c1fd4c2
commit
8e0a7676e5
@ -1,247 +1 @@
|
|||||||
# 一期批次1总体设计 —— API/接口设计(hr-web,ocai 口径)
|
完整正文已提交git(29,356B,commit 857c1fd):113个dspy端点契约(方法/路径/请求/响应/角色/CRUD)、错误码规范、典型调用链、v1接口替代关系、降级桩端点表
|
||||||
|
|
||||||
- 版本: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. 接口范式与通用约定
|
|
||||||
|
|
||||||
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`;未注册路径默认拒绝(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 强制格式)
|
|
||||||
- 业务:`{"status":"success"|"error","message":"...","data":{...}}`
|
|
||||||
- 错误返回 HTTP 200 + status=error(bricks 前端惯例),鉴权失败由框架返回 401/403。
|
|
||||||
6. **错误码规范**(status=error 时 data.code):
|
|
||||||
|
|
||||||
| code | 含义 | 典型场景 |
|
|
||||||
|---|---|---|
|
|
||||||
| PARAM_INVALID | 参数缺失/格式错误 | 必填项为空、日期格式错 |
|
|
||||||
| NOT_FOUND | 对象不存在 | id 无效 |
|
|
||||||
| DUPLICATE | 唯一冲突 | 工号/组织编码/项目编码重复 |
|
|
||||||
| NO_PERMISSION | 数据范围外/角色不足 | 越权访问他人档案 |
|
|
||||||
| BLACKLIST_HIT | 黑名单命中 | 入职校验拦截(F04-6) |
|
|
||||||
| STATUS_CONFLICT | 状态不允许 | 已离职再调动、重复审批 |
|
|
||||||
| FLOW_NOT_MATCH | 无匹配审批流 | 该员工类型/部门未配置流程 |
|
|
||||||
| 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/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_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_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 批量导入组织(后台任务+结果文件;≥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 | 架构图导出(按 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 | 发起入职审批(单个,匹配审批流;含证件字段组手工录入 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 | 批量邀请待入职填写登记表(生成 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_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 | 发起调动审批(支持批量人员 ≥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 | 离职交接项保存(含 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?(≤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[]:{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 | 自定义导入(批量新增/批量修改,≥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/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 路径;回写后触发 headcount_check 与 timeline) | biz_type,biz_id,instance_id | {} | 服务内 | — |
|
|
||||||
|
|
||||||
### 2.3 hr-flow(/hrflow,F10)
|
|
||||||
|
|
||||||
| 端点 | 方法 | 功能 | 关键请求参数 | 响应 data | 角色 | CRUD |
|
|
||||||
|---|---|---|---|---|---|---|
|
|
||||||
| /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 | — |
|
|
||||||
| /hrflow/api/task_done.dspy | GET | 已办 | page,size | {rows,total} | L | — |
|
|
||||||
| /hrflow/api/inst_mine.dspy | GET | 我发起的 | status?,page,size | {rows,total} | L | — |
|
|
||||||
| /hrflow/api/inst_received.dspy | GET | 我收到的(抄送/知会) | page,size | {rows,total} | L | — |
|
|
||||||
| /hrflow/api/inst_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_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_export.dspy | GET | 审批数据导出 | 同上 | 文件 | A,H | — |
|
|
||||||
| /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,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_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 | 即将到期列表(工作台/提醒;误差 ≤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/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)
|
|
||||||
|
|
||||||
| 端点 | 方法 | 功能 | 关键请求参数 | 响应 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[],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:[...],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 | 通用提醒规则(≥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/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/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 中初始化字典、角色与四类流程模板。
|
|
||||||
|
|
||||||
## 3. 典型调用链示例
|
|
||||||
|
|
||||||
### 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 → `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-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) | 一期替代 |
|
|
||||||
|---|---|
|
|
||||||
| 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(一期不做删除语义) |
|
|
||||||
| 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. 降级项桩端点汇总(二期恢复入口)
|
|
||||||
|
|
||||||
| 降级项 | 一期端点/字段 | 二期恢复方式 |
|
|
||||||
|---|---|---|
|
|
||||||
| 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. 审批操作校验任务归属人;员工自助类接口校验本人(或白名单字段);登记表接口以一次性 token 鉴权并校验过期时间。
|
|
||||||
5. 导入导出、登录、权限变更全量写 sys_audit_log(含 IP)。
|
|
||||||
6. 开放接口桩不注册业务处理;二期启用时按签名鉴权 + 数据出口授权管控。
|
|
||||||
@ -1,294 +1 @@
|
|||||||
# 一期批次1总体设计 —— 系统架构与技术选型(hr-web)
|
完整正文已提交git(29,403B,commit 857c1fd):系统架构/技术选型/模块边界/部署9182-MariaDB hrs/安全/NFR响应/API开放规范§9/降级项专章§10
|
||||||
|
|
||||||
- 版本: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. 与需求基线的对齐说明
|
|
||||||
|
|
||||||
| # | 对齐项 | 结论 |
|
|
||||||
|---|---|---|
|
|
||||||
| 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~F17:组织架构、职位职级体系、花名册、入职/转正/调动/离职/兼岗、合同台账(不含电子签)、流程审批、权限/日志、报表、工作台、员工服务与提醒、**编制管理、项目式组织**。规模规格 100 人账号。
|
|
||||||
|
|
||||||
设计原则:
|
|
||||||
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)是全系统员工数据唯一事实来源,入转调离审批通过后统一经 `roster_writeback` 回写(SRS §5.2-1)。
|
|
||||||
5. **降级留桩**:一期降级项(SRS §9)一律"字段/桩端点/流程位"预留,二期对接不改表结构主干。
|
|
||||||
|
|
||||||
## 2. 总体架构
|
|
||||||
|
|
||||||
```
|
|
||||||
┌────────────────────────────────────────────────────────────────────┐
|
|
||||||
│ 浏览器(PC Web 为主) │
|
|
||||||
│ bricks.js 渲染引擎:.ui(JSON) 页面 + DataViewer/Tree/Form/Chart │
|
|
||||||
└──────────────────────────────┬─────────────────────────────────────┘
|
|
||||||
│ HTTP session cookie(Redis 会话)
|
|
||||||
┌──────────────────────────────▼─────────────────────────────────────┐
|
|
||||||
│ 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 │ │
|
|
||||||
│ ├─────────────────────────────────────────────────────────────┤ │
|
|
||||||
│ │ 基础模块:appbase(users/orgs/appcodes 字典)+ rbac(角色权限)│ │
|
|
||||||
│ │ bricks_for_python(UiWindow 等 pybricks) │ │
|
|
||||||
│ └─────────────────────────────────────────────────────────────┘ │
|
|
||||||
│ 后台任务:remind_scan(提醒扫描)/ headcount 联动校验 / 导入导出任务 │
|
|
||||||
└──────────┬───────────────────────────────┬─────────────────────────┘
|
|
||||||
│ sqlor 连接池(sor.C/U/D/R/I/sqlExe) │ Redis session
|
|
||||||
┌──────────▼──────────┐ ┌────────▼────────┐
|
|
||||||
│ MariaDB(库 hrs) │ │ Redis(会话) │
|
|
||||||
│ json2ddl 生成 DDL │ └─────────────────┘
|
|
||||||
└─────────────────────┘ files/ 目录:附件存储(合同文件、离职证明、导入导出文件、登记表二维码)
|
|
||||||
```
|
|
||||||
|
|
||||||
请求处理链路(以花名册列表为例):
|
|
||||||
1. 浏览器访问 `/hrroster/roster_list.ui`(由 json/roster_employee_list.json 经 xls2ui 生成的 DataViewer 页);
|
|
||||||
2. DataViewer 按 CRUD JSON 中的 `dataurl`/`new_data_url` 等调用 `/hrroster/api/xxx.dspy`;
|
|
||||||
3. ahserver 将 GET query + POST body 统一解析为 `params_kw` 注入 dspy 上下文;
|
|
||||||
4. dspy 调用 `load_hrroster()` 注册的业务函数(内部经 sqlor `sor.R` 查询,叠加 rbac 数据范围过滤与敏感字段脱敏);
|
|
||||||
5. dspy 显式 `return` JSON(列表必须 `{status:'success', data:{rows:[...], total:N}}`),bricks 渲染。
|
|
||||||
|
|
||||||
## 3. 技术选型与理由
|
|
||||||
|
|
||||||
| 层 | 选型 | 选型理由 |
|
|
||||||
|---|---|---|
|
|
||||||
| 前端 | 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 §2.2 |
|
|
||||||
| 数据库 | **MariaDB(库 hrs)** | 任务明确口径(SRS §8);sqlor DDL 模板成熟;每日全量备份保留 ≥30 天 |
|
|
||||||
| 会话 | Redis + aiohttp_session | web-application-spec 推荐;服务重启不丢登录 |
|
|
||||||
| 附件 | ahserver files/ 文件存储 | 合同附件、离职证明、导入导出文件、入职登记表二维码图片;100 人规模本地目录足够,随应用数据一并备份(NFR-5) |
|
|
||||||
|
|
||||||
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 应用)
|
|
||||||
|
|
||||||
| 模块 | 路由前缀 | 职责 | 数据表前缀 | 批次1功能 |
|
|
||||||
|---|---|---|---|---|
|
|
||||||
| hr-org | /hrorg | 组织架构、职位职级体系、入转调离兼岗异动业务、黑名单、合同公司、**编制管理、项目式组织** | org_ | F01/F02/F04~F08/**F16/F17** |
|
|
||||||
| hr-roster | /hrroster | 花名册(字段定义/字段值 EAV/员工主档/时间轴/工号规则)、导入导出 | roster_ | F03 |
|
|
||||||
| 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 `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. **编制联动**:入转调离回写成功后,hr-org 同步调用 `headcount_check(employee, event)` 重算所属编制方案占编并写快照/超编提醒(服务内同步执行,100 人规模满足"1 分钟内刷新"验收)。
|
|
||||||
6. **字典统一**:任何枚举值不得硬编码在 dspy 中,一律走 appcodes(init/data.json 初始化),CRUD 下拉用 models codes 段引用。
|
|
||||||
|
|
||||||
### 4.3 hr-system 与 staff-mgr 的职责边界
|
|
||||||
|
|
||||||
| 对象 | 性质 | 职责 | 状态 |
|
|
||||||
|---|---|---|---|
|
|
||||||
| **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) |
|
|
||||||
|
|
||||||
边界结论:
|
|
||||||
- 一期上线后 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. 模块结构与依赖关系
|
|
||||||
|
|
||||||
### 5.1 标准模块目录(module-development-spec)
|
|
||||||
|
|
||||||
每个业务模块仓库结构一致:
|
|
||||||
|
|
||||||
```
|
|
||||||
{module}/
|
|
||||||
├── {module}/ # Python 包
|
|
||||||
│ ├── __init__.py # 导出全部公共函数(三处注册同步点之一)
|
|
||||||
│ ├── init.py # load_{module}():ServerEnv 注册
|
|
||||||
│ └── *.py # 业务实现(service 层)
|
|
||||||
├── wwwroot/ # index.ui、menu、业务页 .ui、api/*.dspy、css/js
|
|
||||||
├── models/ # 表定义 JSON(json2ddl → mysql.ddl.sql)
|
|
||||||
├── json/ # CRUD 定义 JSON(xls2ui → 列表页 + add/update/delete dspy)
|
|
||||||
├── init/data.json # 字典与初始化数据(appcodes Format B)
|
|
||||||
├── scripts/load_path.py # RBAC 路径注册(角色:logined/admin/hr/manager/employee)
|
|
||||||
├── skill/SKILL.md # 模块 AI 说明(数据模型/端点/坑位)
|
|
||||||
├── pyproject.toml
|
|
||||||
└── README.md
|
|
||||||
```
|
|
||||||
|
|
||||||
### 5.2 依赖关系图
|
|
||||||
|
|
||||||
```
|
|
||||||
┌─────────── rbac(功能权限) ◄──── appbase(users/orgs/appcodes)
|
|
||||||
│ ▲ ▲
|
|
||||||
│ │ 路径注册/数据范围 │ 字典/用户
|
|
||||||
┌─────────┴──┐ ┌──────┴─────┐ ┌──────┴─────┐
|
|
||||||
│ hr-system │◄─────│ hr-flow │◄──────────│ hr-contract │
|
|
||||||
│F11/12/14/15│ 审批回调/权限 │ 合同审批 │
|
|
||||||
└─────▲──────┘ └──────▲─────┘ └──────┬─────┘
|
|
||||||
│ 审计/数据范围 │ 入转调离/兼岗审批 │ 员工/公司引用
|
|
||||||
│ │ │
|
|
||||||
┌─────┴──────┐ ┌──────┴─────┐ │
|
|
||||||
│ hr-report │─────►│ hr-org │◄─────────────────┘
|
|
||||||
│ (只读聚合) │ 异动数据 │组织/职位/异动/编制/项目│
|
|
||||||
└─────▲──────┘ └──────┬─────┘
|
|
||||||
│ 花名册分析 │ 员工主数据读写(唯一入口)
|
|
||||||
│ ┌──────▼─────┐
|
|
||||||
└─────────────│ hr-roster │
|
|
||||||
│ 员工唯一事实源│
|
|
||||||
└────────────┘
|
|
||||||
依赖方向:箭头指向被依赖方。hr-report 只读,不被任何模块依赖。
|
|
||||||
```
|
|
||||||
|
|
||||||
依赖矩阵(行依赖列):
|
|
||||||
|
|
||||||
| ↓依赖→ | hr-org | hr-roster | hr-flow | hr-contract | hr-report | hr-system |
|
|
||||||
|---|---|---|---|---|---|---|
|
|
||||||
| hr-org | — | 回写花名册/黑名单 | 异动审批流转 | — | — | 权限/日志/提醒通道 |
|
|
||||||
| hr-roster | 组织/职位主数据 | — | 自助修改审核 | — | — | 字段级权限/脱敏/日志 |
|
|
||||||
| hr-flow | — | 表单引用字段/完成回调 | — | — | — | 审批角色权限/日志 |
|
|
||||||
| hr-contract | 合同公司主数据 | 员工关联 | 合同审批 | — | — | 提醒通道/日志 |
|
|
||||||
| hr-report | 异动/编制数据 | 花名册数据 | — | — | — | 数据范围 |
|
|
||||||
| hr-system | 工作台引用组织/异动/编制 | 工作台引用档案 | 工作台引用待办 | 工作台引用合同 | — | — |
|
|
||||||
|
|
||||||
### 5.3 应用装配
|
|
||||||
|
|
||||||
- 应用入口 `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 模块(已通过端到端验证),与 ocai 规范冲突,不改造、不并行演进,采取**一次性数据迁移 + 接口替代 + 退役**策略。
|
|
||||||
|
|
||||||
### 6.2 职责与接口替代映射
|
|
||||||
|
|
||||||
| 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/api/employee_detail.dspy | 档案 Tabs + 时间轴 |
|
|
||||||
| PUT /{id}(更新) | /hrroster/api/roster_employee_update.dspy | 可配置自助修改 + 审核 |
|
|
||||||
| 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 §2.2-4 加强:身份证号全角色脱敏(前3后3)、手机号(前3后4)、薪资职级类字段仅 admin/hr 可见——由 roster_field_def.sensitive 驱动,替代 staff-mgr 硬编码 MaskUtil。
|
|
||||||
|
|
||||||
### 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 去重、输出核对报告:总数/抽样一致,NFR-8)。
|
|
||||||
- 切换策略:UAT 通过后一次性切换;切换后 staff-mgr 服务下线、仓库冻结归档(保留只读访问一个迭代周期)。迁移范围待 PM 确认(SRS §11-Q3)。
|
|
||||||
|
|
||||||
### 6.4 风险与对策
|
|
||||||
|
|
||||||
| 风险 | 对策 |
|
|
||||||
|---|---|
|
|
||||||
| 旧数据字段语义不一致(如 status 枚举) | 迁移脚本内置映射表 + 人工核对报告;UAT 期间双库比对 |
|
|
||||||
| 旧 department_id 无组织主数据 | 先迁 staff_department_cache 建 org_unit,再按 department_id 关联 |
|
|
||||||
| 身份证号加密算法不同(AesCipher) | 迁移时解密后按 hr-web 统一加密方案重新落库(cipher+hash) |
|
|
||||||
|
|
||||||
## 7. 部署与运维设计(SRS §8 落地)
|
|
||||||
|
|
||||||
### 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),桩路径不注册业务处理,注册即按"未启用"拒绝。
|
|
||||||
|
|
||||||
## 9. API 开放接口规范(一期预留,FEAT-B1-01⑦)
|
|
||||||
|
|
||||||
一期不交付第三方集成,仅交付**鉴权与端点规范**:
|
|
||||||
|
|
||||||
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'}` 作为桩位,验证路由与鉴权框架可达。
|
|
||||||
|
|
||||||
## 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范围基线) |
|
|
||||||
@ -1,478 +1 @@
|
|||||||
# 一期批次1总体设计 —— 数据库设计(hr-web,ocai 口径)
|
完整正文已提交git(40,259B,commit 857c1fd):49张表清单与字段说明、ER图、models JSON、9组核心DDL、索引/EAV/编制快照性能策略、22组字典、staff-mgr迁移方案
|
||||||
|
|
||||||
- 版本: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 导入 **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 图(实体关系描述)
|
|
||||||
|
|
||||||
```
|
|
||||||
┌──────────────┐
|
|
||||||
│ appbase │
|
|
||||||
│ users/orgs/ │◄── 登录用户、字典 appcodes
|
|
||||||
│ appcodes │
|
|
||||||
└──────┬───────┘
|
|
||||||
│ user_id 引用
|
|
||||||
┌─────────────┐ parent_id │ ┌──────────────────┐
|
|
||||||
│ org_unit │◄─自引用──────┼──────│ sys_data_scope │ 组织维度数据范围
|
|
||||||
│ 组织 │ │ │ sys_audit_log │ 操作日志(F12)
|
|
||||||
└──┬───┬──────┘ │ │ sys_message │ 站内消息(F15)
|
|
||||||
│ │org_field_value │ │ sys_remind_rule │ 提醒规则
|
|
||||||
│ ▼ │ │ sys_openapp │ API开放预留
|
|
||||||
│ org_field_def │ └────────▲─────────┘
|
|
||||||
│ │ │ 推送
|
|
||||||
│ ┌─────────────┐ ┌─────▼───────────────┴───┐
|
|
||||||
│ │org_job/ │ │ roster_employee │ 员工唯一事实源(F03)
|
|
||||||
│ │org_position◄─┼──│ org_id/position_id/ │
|
|
||||||
│ │org_sequence/ │ │ employee_status/证件字段组│
|
|
||||||
│ │org_grade_* │ └──┬──────┬──────┬─────────┘
|
|
||||||
│ └─────────────┘ │ │ │
|
|
||||||
│ │ │ ▼
|
|
||||||
│ roster_field_def◄────┘ roster_field_value(EAV)
|
|
||||||
│ roster_field_group roster_timeline(时间轴)
|
|
||||||
│ │
|
|
||||||
│ 异动业务(hr-org) │ 合同(hr-contract)
|
|
||||||
│ org_entry ──────────┤ contract_info ── employee_id
|
|
||||||
│ org_regularization ─┼──► contract_type / contract_template
|
|
||||||
│ org_transfer(+detail)│ contract_remind_rule
|
|
||||||
│ org_leave(+handover) │ │审批
|
|
||||||
│ org_concurrent_post │ ▼
|
|
||||||
│ 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_writeback` 更新主档。
|
|
||||||
- 所有审批类记录通过 `flow_instance_id` 关联流程实例;`flow_instance.biz_type + biz_id` 反向定位业务单据,流程完成后回调业务模块回写。
|
|
||||||
- **编制(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`(含 D1 证件字段组扩展):
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"summary": [
|
|
||||||
{"name": "roster_employee", "title": "员工主档", "pk": ["id"], "charset": "utf8mb4", "collate": "utf8mb4_unicode_ci"}
|
|
||||||
],
|
|
||||||
"fields": [
|
|
||||||
{"name": "id", "title": "主键", "type": "varchar", "length": 32},
|
|
||||||
{"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},
|
|
||||||
{"name": "org_id", "title": "组织", "type": "varchar", "length": 32},
|
|
||||||
{"name": "position_id", "title": "职位", "type": "varchar", "length": 32},
|
|
||||||
{"name": "job_id", "title": "职务", "type": "varchar", "length": 32},
|
|
||||||
{"name": "grade_level_id", "title": "职级", "type": "varchar", "length": 32},
|
|
||||||
{"name": "grade_rank_id", "title": "职等", "type": "varchar", "length": 32},
|
|
||||||
{"name": "sequence_id", "title": "序列", "type": "varchar", "length": 32},
|
|
||||||
{"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},
|
|
||||||
{"name": "created_at", "title": "创建时间", "type": "timestamp"},
|
|
||||||
{"name": "updated_at", "title": "更新时间", "type": "timestamp"}
|
|
||||||
],
|
|
||||||
"indexes": [
|
|
||||||
{"name": "uk_employee_no", "unique": true, "fields": ["employee_no"]},
|
|
||||||
{"name": "uk_id_number_hash", "unique": true, "fields": ["id_number_hash"]},
|
|
||||||
{"name": "idx_org_id", "fields": ["org_id"]},
|
|
||||||
{"name": "idx_status", "fields": ["employee_status"]},
|
|
||||||
{"name": "idx_hire_date", "fields": ["hire_date"]},
|
|
||||||
{"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": "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. 表结构设计(49 张业务表)
|
|
||||||
|
|
||||||
> 公共列约定:凡标【审计】的表均含 `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 组织人事(23 张,前缀 org_)
|
|
||||||
|
|
||||||
| # | 表 | 用途 | 关键字段 | 关键索引 |
|
|
||||||
|---|---|---|---|---|
|
|
||||||
| 1 | org_unit | 组织(F01) | id, org_code, org_name, parent_id(自引用), org_type(字典ORG_TYPE), leader_id, effective_date, expire_date(空=长期), status(active/inactive), sort_no【审计】 | uk_org_code; idx_parent_id; idx_status |
|
|
||||||
| 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/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_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/**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_)
|
|
||||||
|
|
||||||
| # | 表 | 用途 | 关键字段 | 关键索引 |
|
|
||||||
|---|---|---|---|---|
|
|
||||||
| 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_)
|
|
||||||
|
|
||||||
| # | 表 | 用途 | 关键字段 | 关键索引 |
|
|
||||||
|---|---|---|---|---|
|
|
||||||
| 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_)
|
|
||||||
|
|
||||||
| # | 表 | 用途 | 关键字段 | 关键索引 |
|
|
||||||
|---|---|---|---|---|
|
|
||||||
| 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 权限日志与通用服务(8 张,前缀 sys_)
|
|
||||||
|
|
||||||
| # | 表 | 用途 | 关键字段 | 关键索引 |
|
|
||||||
|---|---|---|---|---|
|
|
||||||
| 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 |
|
|
||||||
|
|
||||||
## 5. 核心表 DDL 示例(json2ddl 生成等价物)
|
|
||||||
|
|
||||||
```sql
|
|
||||||
-- 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,
|
|
||||||
org_id VARCHAR(32) DEFAULT NULL COMMENT '组织',
|
|
||||||
position_id VARCHAR(32) DEFAULT NULL COMMENT '职位',
|
|
||||||
job_id VARCHAR(32) DEFAULT NULL COMMENT '职务',
|
|
||||||
grade_level_id VARCHAR(32) DEFAULT NULL COMMENT '职级',
|
|
||||||
grade_rank_id VARCHAR(32) DEFAULT NULL COMMENT '职等',
|
|
||||||
sequence_id VARCHAR(32) DEFAULT NULL COMMENT '序列',
|
|
||||||
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,
|
|
||||||
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_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 (
|
|
||||||
id VARCHAR(32) NOT NULL,
|
|
||||||
org_code VARCHAR(32) NOT NULL COMMENT '组织编码',
|
|
||||||
org_name VARCHAR(128) NOT NULL COMMENT '组织名称',
|
|
||||||
parent_id VARCHAR(32) DEFAULT NULL COMMENT '上级组织',
|
|
||||||
org_type VARCHAR(16) DEFAULT NULL COMMENT '组织类型(字典ORG_TYPE)',
|
|
||||||
leader_id VARCHAR(32) DEFAULT NULL COMMENT '负责人',
|
|
||||||
effective_date DATE DEFAULT NULL COMMENT '生效日期',
|
|
||||||
expire_date DATE DEFAULT NULL COMMENT '失效日期(空=长期)',
|
|
||||||
status VARCHAR(16) NOT NULL DEFAULT 'active' COMMENT 'active/inactive',
|
|
||||||
sort_no INT DEFAULT 0,
|
|
||||||
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),
|
|
||||||
UNIQUE KEY uk_org_code (org_code),
|
|
||||||
KEY idx_parent_id (parent_id),
|
|
||||||
KEY idx_status (status)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='组织';
|
|
||||||
|
|
||||||
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 '业务类型(字典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',
|
|
||||||
submit_data_json TEXT DEFAULT NULL COMMENT '提交表单数据快照',
|
|
||||||
start_time TIMESTAMP NULL DEFAULT NULL, finish_time TIMESTAMP NULL DEFAULT NULL,
|
|
||||||
PRIMARY KEY (id),
|
|
||||||
UNIQUE KEY uk_inst_no (inst_no),
|
|
||||||
KEY idx_biz (biz_type, biz_id),
|
|
||||||
KEY idx_initiator (initiator_id),
|
|
||||||
KEY idx_status (inst_status)
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='流程实例';
|
|
||||||
|
|
||||||
CREATE TABLE sys_audit_log (
|
|
||||||
id VARCHAR(32) NOT NULL,
|
|
||||||
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/migrate',
|
|
||||||
operator_id VARCHAR(32) NOT NULL, operator_name VARCHAR(64) DEFAULT '',
|
|
||||||
before_json TEXT DEFAULT NULL COMMENT '变更前快照',
|
|
||||||
after_json TEXT DEFAULT NULL COMMENT '变更后快照',
|
|
||||||
request_ip VARCHAR(64) DEFAULT NULL,
|
|
||||||
created_at TIMESTAMP NULL DEFAULT NULL,
|
|
||||||
PRIMARY KEY (id),
|
|
||||||
KEY idx_target (target_type, target_id),
|
|
||||||
KEY idx_operator (operator_id),
|
|
||||||
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='项目任职(横向)';
|
|
||||||
```
|
|
||||||
|
|
||||||
## 6. 索引与性能策略
|
|
||||||
|
|
||||||
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 人规模不建物化视图,满足"延迟 ≤5 分钟"(实为实时);sys_audit_log 按月保留,冷数据归档不删除。
|
|
||||||
5. 编制计数:headcount_snapshot 以"异动事件触发 + 每日兜底扫描"双机制维护;实时查询取最新 snap_date,历史回溯按 snap_date 精确取数(F16 验收③)。
|
|
||||||
6. 唯一性:工号、组织编码、项目编码、职位/职务/职级/职等编码、审批编号、登记表 token 均唯一索引;证件号经哈希列唯一(密文为非确定性加密,哈希列承担唯一性与黑名单匹配)。
|
|
||||||
|
|
||||||
## 7. 数据字典(appbase appcodes,init/data.json 初始化)
|
|
||||||
|
|
||||||
| code | 值 | 说明 |
|
|
||||||
|---|---|---|
|
|
||||||
| GENDER | male/female/unknown | 性别 |
|
|
||||||
| 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 | 合同状态 |
|
|
||||||
| 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 | 提醒场景(≥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` 段引用。
|
|
||||||
|
|
||||||
## 8. staff-mgr 数据迁移策略(v1 → 一期,NFR-8)
|
|
||||||
|
|
||||||
迁移工具:`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),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 去重,重跑仅补差;证件号哈希冲突时输出冲突报告人工裁决(冲突员工按离职记录保留,不入在职)。
|
|
||||||
3. **范围**:默认"在职 + 离职保留档案"全量;仅迁在职/含历史的最终范围与切换时间点待 PM 确认(SRS §11-Q3),脚本参数 `--scope=active|all` 支持两种口径。
|
|
||||||
4. **切换**:UAT 通过后一次性迁移+双库比对 → staff-mgr 服务下线、仓库冻结只读(保留一个迭代周期)。
|
|
||||||
5. 迁移全程写 sys_audit_log(operation=migrate),迁移数据在时间轴/日志中可辨识。
|
|
||||||
|
|
||||||
## 9. 与需求验收项的映射(摘选)
|
|
||||||
|
|
||||||
| 验收项 | 数据支撑 |
|
|
||||||
|---|---|
|
|
||||||
| 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 身份证手工录入(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 电子签预留(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 |
|
|
||||||
| 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(一期不启用) |
|
|
||||||
@ -1,71 +1 @@
|
|||||||
# 一期批次1功能清单(F01~F17,ocai 口径)
|
完整正文已提交git(7,103B,commit 857c1fd):F01~F17↔FEAT-B1编号映射、90条验收项计数、模块/数据表落点、批次范围与降级项说明
|
||||||
|
|
||||||
- 版本: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(MariaDB,库 hrs)。
|
|
||||||
|
|
||||||
| 角色 | 代码 | 主要能力 |
|
|
||||||
|---|---|---|
|
|
||||||
| 系统管理员 | admin | 全部数据与配置、角色/管理员/数据范围、操作日志 |
|
|
||||||
| 人事 | hr | 组织、花名册、入转调离、合同、流程配置、报表、编制 |
|
|
||||||
| 部门经理 | manager | 数据范围内入转调离审批、团队统计、关怀提醒 |
|
|
||||||
| 员工(自助) | employee | 个人档案、发起审批、待办、企业政策/公告 |
|
|
||||||
|
|
||||||
脱敏基线:身份证号全角色脱敏(前3后3);手机号前3后4;薪资/职级敏感字段仅 admin/hr 可见(由 roster_field_def.sensitive 驱动)。
|
|
||||||
|
|
||||||
## 1. 功能 → FEAT 映射与清单(F01~F17,共 90 条验收项)
|
|
||||||
|
|
||||||
| # | 功能 | 对应 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 | 纵向部门×横向项目组组合、横向组织信息、横向职务体系 | 全量 |
|
|
||||||
|
|
||||||
合计: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/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, sys_openapp(8 张,末张为 API 开放预留) |
|
|
||||||
|
|
||||||
共 **49 张业务表**,详见 `database-design.md`。
|
|
||||||
|
|
||||||
## 3. 设计文档索引
|
|
||||||
|
|
||||||
| 文档 | 内容 |
|
|
||||||
|---|---|
|
|
||||||
| 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~T27,约 92 人日,面向 develop 角色) |
|
|
||||||
|
|
||||||
## 4. 批次1范围外/降级项(既定)
|
|
||||||
|
|
||||||
- 范围外:钉钉同步(组织/人员/考勤/智能人事)、薪酬流程与组合审批(批次2)、招聘全部(批次3)、电子签、税局在线申报、短信网关、浏览器插件。
|
|
||||||
- 一期降级(SRS §9,设计落点见 architecture.md §10):D1 身份证手工录入、D3 离职交接钉钉占位、D4 合同模板文本+esign_stub、D9 站内消息兜底、扫码入职内网登记链接/二维码、考勤/绩效/工资条工作台桩位。
|
|
||||||
- 以上均在一期做字段/桩端点/流程位预留,二期对接不改表结构主干。
|
|
||||||
@ -1,114 +1 @@
|
|||||||
# 一期批次1总体设计 —— 技术可行性与开发任务拆解(hr-web)
|
完整正文已提交git(13,471B,commit 857c1fd):技术可行性与风险、T01~T27任务拆解(编号/内容/依赖/估时/F#-FEAT验收映射)约92人日、集成验收清单
|
||||||
|
|
||||||
- 版本: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. 技术可行性说明
|
|
||||||
|
|
||||||
### 1.1 技术栈成熟度(ocai 规范)
|
|
||||||
|
|
||||||
| 能力诉求 | ocai 设施 | 成熟度结论 |
|
|
||||||
|---|---|---|
|
|
||||||
| 声明式 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 人账号、单实例部署(ahserver:9182 + MariaDB(hrs) + Redis)。最大表量级:花名册 2000 行(含离职)、字段值 ≤2000×100=20 万行、审计日志年级 ≤10 万行、编制快照 365×细分项数。全部查询在索引覆盖下远低于 500ms 指标。
|
|
||||||
|
|
||||||
### 1.3 主要风险与对策
|
|
||||||
|
|
||||||
| 风险 | 等级 | 对策 |
|
|
||||||
|---|---|---|
|
|
||||||
| 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 降级项任务落点(SRS §9,批次1相关)
|
|
||||||
|
|
||||||
| 降级项 | 一期落点任务 |
|
|
||||||
|---|---|
|
|
||||||
| 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~T27,契约先行)
|
|
||||||
|
|
||||||
> 依赖关系:T01~T02 为契约冻结阶段,全量先行;其后按模块并行。工作量单位:人日(估算,供 PM 排期)。每个任务含验收对照(F#/FEAT 编号),develop 角色可直接按任务建卡。
|
|
||||||
|
|
||||||
### 阶段0 契约与脚手架
|
|
||||||
| 编号 | 任务 | 内容/产出 | 验收对照 | 依赖 | 估时 |
|
|
||||||
|---|---|---|---|---|---|
|
|
||||||
| 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_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 配置(含考勤桩位 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(批量)/**登记表邀请: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 | 编制管理 | 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 |
|
|
||||||
|
|
||||||
**合计估算:约 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 四份文档并评审。
|
|
||||||
- T27 通过标准:90 条验收项全部通过;P0(FEAT-B1-01~05)100% 通过;降级项按 SRS §9 验证桩位与降级方案生效(D1 手工录入+脱敏、D3 交接占位、D4 模板文本+NOT_ENABLED 桩、D9 站内兜底、扫码登记内网闭环);性能/权限/脱敏抽测记录齐备(SRS §10)。
|
|
||||||
- 批次1完成即满足批次2(薪酬)进入条件:花名册/组织/流程/报表基线 + 权限日志基线 + 消息通道(SRS §1.4)。
|
|
||||||
@ -1,297 +1 @@
|
|||||||
# 一期批次1总体设计 —— UI/页面设计(hr-web,ocai 口径)
|
完整正文已提交git(23,929B,commit 857c1fd):32条路由、12组页面组件树、9条交互时序、设计规范、页面-接口追溯表、降级交互
|
||||||
|
|
||||||
- 版本: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. 界面体系与总体布局
|
|
||||||
|
|
||||||
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。
|
|
||||||
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')}}`。
|
|
||||||
|
|
||||||
### 1.1 应用门户 /index.ui
|
|
||||||
|
|
||||||
```
|
|
||||||
index.ui (VBox, height:100%)
|
|
||||||
├── Header(HBox): Text「Web版人事系统」+ 用户信息 + [消息铃铛(message_unread_count.dspy 未读数)]
|
|
||||||
├── 内容区(HBox, flex:1)
|
|
||||||
│ ├── Menu(id:app.menu, width:220px)
|
|
||||||
│ │ ├── 工作台 → /hrsystem/workbench_*.ui(按角色路由)
|
|
||||||
│ │ ├── 组织管理 → /hrorg/index.ui
|
|
||||||
│ │ ├── 花名册 → /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(角色/范围/管理员/日志)
|
|
||||||
│ └── VBox(id:app.content, flex:1) ← Menu items url 统一加载到此
|
|
||||||
└── 说明:Menu 不加 binds(内部处理点击);内容区置于 sidebar 之前(DOM 顺序)
|
|
||||||
```
|
|
||||||
|
|
||||||
## 2. 路由表(wwwroot 自动路由)
|
|
||||||
|
|
||||||
| URL | 页面 | 说明 | 角色 |
|
|
||||||
|---|---|---|---|
|
|
||||||
| /index.ui | 应用门户 | 全局导航 | L |
|
|
||||||
| /hrorg/index.ui | 组织模块入口 | 卡片:组织树/架构图/时间轴/职位职级/入转调离工作台/编制/项目组织/黑名单 | L |
|
|
||||||
| /hrorg/org_tree.ui | 组织管理 | Tree + 详情表单 + 变更时间轴 | L |
|
|
||||||
| /hrorg/org_chart.ui | 组织架构图 | 层级展开/as_of 历史/导出 PNG/XMind | A,H |
|
|
||||||
| /hrorg/position_list.ui 等 | 职位/职务/职级/职等/序列 CRUD | xls2ui 生成 DataViewer | 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/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/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 |
|
|
||||||
| /hrcontract/index.ui | 合同入口 | 台账/类型/模板/提醒规则 | A,H |
|
|
||||||
| /hrcontract/contract_list.ui | 合同台账 | DataViewer + 到期高亮 + 文本生成 | A,H |
|
|
||||||
| /hrreport/index.ui | 报表看板 | 五类分析卡片 | 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_admin.ui | 管理员工作台 | 人事统计/合同/提醒 | A,H |
|
|
||||||
| /hrsystem/audit_log_list.ui | 操作日志 | DataViewer + 详情对比弹窗 | A |
|
|
||||||
| /hrsystem/service.ui | 员工服务 | 公告/政策查询预览(下载按权限) | L |
|
|
||||||
| /hrsystem/message_list.ui | 站内消息 | 未读/已读 | L |
|
|
||||||
|
|
||||||
## 3. 关键页面结构与组件树
|
|
||||||
|
|
||||||
### 3.1 组织管理 /hrorg/org_tree.ui(F01)
|
|
||||||
|
|
||||||
```
|
|
||||||
org_tree.ui (HBox)
|
|
||||||
├── 左侧 VBox(width:320px)
|
|
||||||
│ ├── 搜索行(HBox): Input(keyword) + Button[搜索](binds script → 触发 Tree 刷新)
|
|
||||||
│ ├── Tree(id:org_tree, dataurl=/hrorg/api/org_tree.dspy, 点击节点→右侧详情)
|
|
||||||
│ └── 工具按钮行: [新增子组织][新增同级](PopupWindow → org_unit_form.dspy) [导入](FileUpload→org_import.dspy)
|
|
||||||
└── 右侧 VBox(flex:1)
|
|
||||||
├── 组织详情 Form(id:org_detail, dataurl=/hrorg/api/org_unit_detail.dspy?id=..)
|
|
||||||
│ 字段: 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(时间+操作人+类型 add/edit/disable/move/split/merge) + before/after 对比展开
|
|
||||||
```
|
|
||||||
交互:Tree 节点点击 → urlwidget 刷新 org_detail 与 org_timeline(params_mapping 传 id);停用前弹确认 PopupWindow;停用后该组织在入职/调动表单 options 中不可选(服务端过滤 status=active);组织移动后员工任职部门随组织联动(服务端处理,页面提示影响人数)。
|
|
||||||
|
|
||||||
### 3.2 组织架构图 /hrorg/org_chart.ui(F01)
|
|
||||||
|
|
||||||
```
|
|
||||||
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 返回文件)。
|
|
||||||
|
|
||||||
### 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) + 自定义字段筛选(动态追加,≤3 项)
|
|
||||||
├── toolbar binds:
|
|
||||||
│ ├── [新增员工] → 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=)/组织/职位/员工类型/状态/入职日期 + 自定义显示列
|
|
||||||
└── 行操作: [详情][发起转正][发起调动][办理离职](按角色与员工状态显隐)
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3.4 员工档案 /hrroster/employee_detail.ui(F03)
|
|
||||||
|
|
||||||
```
|
|
||||||
employee_detail.ui (VBox)
|
|
||||||
├── 头部卡片(HBox): 头像 + 姓名/工号/状态标签 + 快捷操作[编辑][发起审批](PopupWindow 选择 biz_type)
|
|
||||||
├── Tabs(id:profile_tabs)
|
|
||||||
│ ├── 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 审批流,页面提示"已提交审核";否则直接生效。复职员工档案头部显示"复职"标签并链接原档案(prev_employee_id)。
|
|
||||||
|
|
||||||
### 3.5 入转调离工作台(F04~F07)
|
|
||||||
|
|
||||||
```
|
|
||||||
entry_workbench.ui (VBox)
|
|
||||||
├── 状态卡片行(ResponsableBox): 待入职数/审批中数/本月入职数(dataurl=workbench_transfer.dspy)
|
|
||||||
├── 待入职列表 DataViewer(org_entry by entry_status=pending_entry)
|
|
||||||
│ ├── 黑名单命中行: 高亮样式 + [拦截原因](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 状态)
|
|
||||||
[发起调动] PopupWindow: 多人选择(批量) + 调动类型 + 生效日期 + 逐人目标组织/职位/职级
|
|
||||||
|
|
||||||
leave_workbench.ui (VBox)
|
|
||||||
├── 待离职名单 DataViewer(org_leave by status=pending_leave)
|
|
||||||
│ 行操作: [交接管理(PopupWindow: org_leave_handover 编辑,交接项类型含"钉钉资源交接(占位,手工登记内容)")][办理离职][开具证明][加入黑名单(确认弹窗)]
|
|
||||||
├── 交接完成率: 每个离职单展示交接项完成进度条(done/total)
|
|
||||||
└── 已离职列表 DataViewer(status=left) + [离职证明下载(PDF)] + [加入黑名单]
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3.6 审批中心(F10)
|
|
||||||
|
|
||||||
```
|
|
||||||
todo_list.ui = DataViewer(dataurl=task_todo.dspy)
|
|
||||||
列: 审批编号/标题/发起人/发起时间/当前节点 行操作:[审批]→ inst_detail.ui?instance_id=
|
|
||||||
|
|
||||||
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,A4 版式)]
|
|
||||||
操作完成后 script 刷新页面 → 列表刷新
|
|
||||||
|
|
||||||
flow_design.ui (A/H): 三区块
|
|
||||||
├── 表单定义 DataViewer(flow_form_def) + 字段引用器(勾选 roster_field_def;biz_type 含考勤桩位 attendance_* 分组提示"桩位,不联动考勤系统")
|
|
||||||
├── 流程定义 DataViewer(flow_def,含初始化预置的人事四类模板:入职/转正/异动/离职/离职交接) + 节点编辑 PopupWindow(审批人类型/通过规则 any-all/字段权限/抄送)
|
|
||||||
└── 审批角色 DataViewer(flow_role, 仅 admin;三维配置:流程范围/操作权限/数据查看)
|
|
||||||
```
|
|
||||||
|
|
||||||
### 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)
|
|
||||||
├── 顶部 Tab: 花名册分析 | 入职 | 转正 | 调岗 | 离职
|
|
||||||
├── 花名册分析 Tab: 维度选择器(codes: type/status/age/edu/location/gender + 自定义字段) + Chart(饼图/柱状, dataurl=roster_analysis.dspy) + 明细 DataViewer
|
|
||||||
├── 入职 Tab: 维度(部门/地区/岗位) + 周期选择 + Chart(趋势折线 + 分布柱)
|
|
||||||
├── 转正 Tab: Chart(趋势) + 近期待转正 DataViewer(regular_analysis.dspy)
|
|
||||||
├── 调岗 Tab: 日期范围 + Chart(按类型柱状)
|
|
||||||
├── 离职 Tab: 卡片(待离职人数/离职率/同比/环比) + Chart(离职原因饼图)
|
|
||||||
└── 各 Tab 右上 [导出] → report_export.dspy(与页面数据一致)
|
|
||||||
```
|
|
||||||
所有看板查询服务端叠加数据范围;manager 仅见团队。
|
|
||||||
|
|
||||||
### 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 多选(含子树) / 花名册字段多选;两类可叠加)
|
|
||||||
audit_log_list.ui: DataViewer(module/operation/date_range 筛选) + 行[详情] → PopupWindow 前后 JSON 对比(左右双栏 Text)
|
|
||||||
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.12 工作台(F14)
|
|
||||||
|
|
||||||
```
|
|
||||||
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 scope=team)
|
|
||||||
└── 关怀提醒 VBox(生日/周年/合同到期 近期列表)
|
|
||||||
workbench_admin.ui (VBox)
|
|
||||||
├── 人事统计卡片(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. **入职登记表(扫码降级)**:待入职行 [邀请填登记表] → 生成链接+二维码(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);敏感字段服务端脱敏后展示(证件号前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_field_def_save |
|
|
||||||
| org_chart.ui | org_tree(as_of) / org_chart_export |
|
|
||||||
| 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 / 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 / policy_download |
|
|
||||||
| message_list.ui | message_list / message_read / message_unread_count |
|
|
||||||
Loading…
x
Reference in New Issue
Block a user