# 玻思韬 TMS · JNPF / PostgreSQL 数据表设计 依据《玻思韬TMS功能设计书 V1》和老飞企界面字段设计,给 JNPF 6.x + PostgreSQL 18 用。 风格对齐现有 `lims_*` / `dms_*`:主键 `f_id`,子表 `f_foreign_id`,流程 `f_flow_id`,业务字段英文蛇形、不加 `f_`。 交付物: - 建表脚本:`docs/tms/tms_schema_pg.sql`(48 张表 + 预置数据) - 字段清单:`docs/tms/玻思韬TMS-JNPF数据表字段清单.xlsx` --- ## 1. 怎么在 JNPF 建 推荐顺序: 1. 先配字典和单据规则(第 3、4 节) 2. 数据建模按第 2 节顺序建表(或先跑 SQL,再「同步数据表」) 3. 基础档案表单 → 题库试卷 → 计划 → 任务/记录 → 档案 4. 用户、组织、岗位、附件一律用平台控件,不要自建用户表 5. 培训对象、培训师多选存用户 ID;发布时再按人拆 `tms_person_task` 系统字段每张表都有,设计器会带出,不必在业务字段里重复: | 字段 | 用途 | |---|---| | `f_id` | 主键 | | `f_tenant_id` | 租户 | | `f_foreign_id` | 子表指向主表 | | `f_flow_id` / `f_flow_task_id` / `f_flow_state` | 流程表单 | | `f_creator_user_id` / `f_creator_time` | 创建 | | `f_last_modify_user_id` / `f_last_modify_time` | 修改 | | `f_delete_mark` | 逻辑删除 | --- ## 2. 表关系(主链路) ```mermaid flowchart LR subgraph base [基础] P[tms_place 地点] T[tms_trainer 培训师] M[tms_material 教材] C[tms_course 课程] A[tms_admin_auth 授权] end subgraph exameng [考试引擎] QB[tms_question_bank 题库] Q[tms_question 试题] PAP[tms_paper 试卷] end subgraph plan [计划] PC[tms_post_catalog 岗位目录] PP[tms_post_plan 岗位计划] PPP[tms_person_post 个人岗位培训] AP[tms_annual_plan 年度计划] end subgraph exec [执行] TK[tms_task 培训任务] PT[tms_person_task 个人任务] RC[tms_record 培训记录] EX[tms_exam 答卷] end subgraph file [档案] PF[tms_person_file 个人档案] CERT[tms_person_cert 资质证书] DIR[tms_person_train 培训目录] end QB --> Q --> PAP PC --> PP --> PPP PP --> TK AP --> TK M --> TK P --> TK T --> TK PAP --> TK C --> AP TK --> PT TK --> RC TK --> EX PT --> EX RC --> DIR PF --> CERT PF --> DIR ``` 主键怎么串: | 从 | 到 | 字段 | |---|---|---| | 年计划明细 / 岗计划明细 | 任务 | `source_id` + `source_item_id` | | 任务 | 个人任务 | `task_id` | | 任务 | 培训记录 | `task_id`(一对一) | | 任务 | 答卷 | `task_id` + `user_id` + `attempt_no` | | 记录签到子表 | 记录 | `f_foreign_id` | | 记录归档 | 个人培训目录 | `record_id` + `user_id` | 老界面里「培训任务」和「个人任务」字段码混用,JNPF 必须拆成两张表。 --- ## 3. 先配字典 | 字典 | 选项 | |---|---| | 任务发布状态 | draft 未发布 / published 已发布 / cancelled 已取消 / done 已完成 | | 培训分类 | 临时培训 / 岗位培训计划 / 年度培训计划 / 文件生效培训 / 外出培训 / 再维护 | | 任务类型 | new 新增 / continue 继续(再维护) | | 归档状态 | pending 待归档 / ready 可归档 / archived 已归档 / invalid 无效 | | 个人任务状态 | todo 未完成 / signed 已签到 / done 已完成 / expired 已过期 / cancelled 已取消 | | 是否合格 | pass 合格 / fail 不合格 / absent 未参加 / na 无需考核 | | 题型 | single 单选 / multi 多选 / judge 判断 / blank 填空 / essay 问答 | | 试题试卷状态 | open 开放 / closed 不开放 / invalid 废弃 | | 难度 | easy 简单 / normal 一般 / hard 困难 | | 阅卷状态 | auto 无需阅卷 / pending 待批改 / graded 已批改 | | 有效撤销 | valid 有效期内 / revoked 已撤销 | | 计划行状态 | pending 待执行 / tasked 已生成任务 / done 已完成 / delayed 已延期 | | 教材类型 | Word / PPT / Excel / PDF / 视频 / 音频 | 培训方式、签到方式、评估方式做成**业务表**(带规则),不要只做字典: - 集中授课:仅扫码、允许名单外签到、开始结束同一天、地点必填 - 操作授课:仅扫码、不允许名单外、同一天、地点必填 - 在线学习:扫码+在线、地点不必填、扫码必须匹配名单 --- ## 4. 单据规则(对齐老编号) | 对象 | 规则 | 老界面示例 | |---|---|---| | 地点编号 `place_no` | `A` + YYYYMM + 4 位 | A2026090001 | | 档案编号 `archive_no` | `AR` + YYYY + 4 位 | AR20260028 | | 教材编号 `material_no` | `TM` + YYYYMM + 4 位 | TM2026090001 | | 岗位计划 `plan_no` | `JP` + YYYYMM + 4 位 | JP2026090012 | | 年度计划 `plan_no` | 年份 4 位 + 4 位流水 | 20260001 | | 培训任务 `task_no` | `TT` + YYYYMM + 4 位 | TT2026090618 | 培训记录编号默认等于任务编号(老档案培训目录里就是 TT 号)。 --- ## 5. 表单与表(搭建顺序) ### 5.1 基础设置 | 顺序 | 表单 | 表 | 主从 | 流程 | |---|---|---|---|---| | 1 | 培训地点 | `tms_place` | 否 | 否 | | 2 | 培训师档案 | `tms_trainer` | 工作经历 / 培训经历 | 否 | | 3 | 培训管理员授权 | `tms_admin_auth` | 否 | 否 | | 4 | 培训方式 | `tms_train_mode` | 否 | 否 | | 5 | 签到方式 | `tms_sign_mode` | 否 | 否 | | 6 | 评估方式 | `tms_eval_mode` | 否 | 否 | | 7 | 培训课程 | `tms_course` | 否 | 否 | | 8 | 培训教材 | `tms_material` | 否 | 否 | 地点表比老界面多了 `place_group`(FDS 要求按组别划分)。占用不单独存表,发布/保存任务时用时间交叉校验。 培训师按 `user_id` 唯一,重复录入提示不报错;列表用 `biz_status` 筛「有效期内 / 已撤销」。 ### 5.2 题库试卷 | 顺序 | 表单 | 表 | 主从 | |---|---|---|---| | 9 | 题库 | `tms_question_bank` | 否 | | 10 | 试题 | `tms_question` | 选项 `tms_question_option` | | 11 | 试卷 | `tms_paper` | 章节 + 试卷试题 | 老界面字段已落入:题库名称/状态/备注;试题类型、所属题库、难度、状态(默认开放)、来源、题干、选项 A-D 可增删;试卷名称、状态、考试时长、成绩公布时间、合格分数、试题排序(自身顺序/随机)。 **关键约束(GMP)**:改试题、改试卷、改答案,都不能动已考记录。已考数据只存在 `tms_exam` + `tms_exam_item` 快照里。 ### 5.3 岗位 / 年度计划 | 顺序 | 表单 | 表 | 流程 | |---|---|---|---| | 12 | 岗位培训目录 | `tms_post_catalog` + item | 可 | | 13 | 岗位培训计划 | `tms_post_plan` + item | 可 | | 14 | 个人岗位培训 | `tms_person_post` + item | 可退回 | | 15 | 年度培训计划 | `tms_annual_plan` + item | 部门负责人 → QA | | 16 | 年度计划延期 | `tms_annual_delay` | 是 | 岗位计划主表对齐老界面:岗位编码/名称、所属部门、计划结束时间、岗位描述、培训对象;子表:培训计划时间、培训师、培训内容、培训方式、课时、考核方式。 年度计划对齐老界面:年份、计划编号、计划类型、制定日期/人/部门、版本;子表:培训月份、内容、方式、对象、课时、培训师、考核方式、状态;表尾备注、部门负责人、QA 部负责人。 转岗:`tms_person_post_item.already_trained=1` 时不生成对应培训任务。 ### 5.4 任务 / 记录 / 考试 | 顺序 | 表单 | 表 | 说明 | |---|---|---|---| | 17 | 培训任务 | `tms_task` + 教材 + 提问预设 | 核心;跨月/临时/在岗走流程 | | 18 | 个人培训任务 | `tms_person_task` | 发布时按人生成,学员入口 | | 19 | 培训记录 | `tms_record` + 签到明细 | 发布时生成;关闭时间到 → 待归档 | | 20 | 培训记录变更 | `tms_record_change` | 改结束时间 / 加人 | | 21 | 培训资料归档 | `tms_archive_file` | 电子/纸质/实操 | | 22 | 在线考试 | `tms_exam` + 快照 | 列表/阅卷/个人考试记录共用 | | 23 | 实操考核 | `tms_practice` + item | 回写记录 | | 24 | 现场提问考核 | `tms_quiz_score` | 回写记录 | 培训任务主表对齐老界面: 编号、培训分类、来源计划编号、培训主题、培训要点、教材编号/附件、地点编号/名称、开始/结束、试卷编号/名称、开考/结考、培训师、任务关闭时间、培训方式、评估方式、培训对象。 列表另有:是否已发布、任务类型(新增/继续)、上一次任务编号。这些都在 `tms_task`。 记录台账不必再建模,用 `tms_record.archive_status` 筛待归档 / 可归档 / 已归档。 ### 5.5 档案与其它流程 | 顺序 | 表单 | 表 | |---|---|---| | 25 | 个人培训档案 | `tms_person_file` + 履历 + 证书 + 培训目录 | | 26 | 资质文件管理 | 复用 `tms_person_file` 列表,证书子表 `tms_person_cert` | | 27 | 外出培训 | `tms_out_train` | | 28 | 转岗 / 新员工 / 复岗考评 | `tms_transfer_eval` / `tms_newcomer_eval` / `tms_return_eval` | | 29 | 套打模板版本 | `tms_print_template`(按培训开始时间匹配版本) | | 30 | 提醒规则 | `tms_remind_rule` | 个人档案对齐老界面:档案编号、建档时间、员工姓名、所属部门、入职时间、主要岗位、兼职岗位;子表工作履历;查看页还有外部培训/证书、培训目录(记录编号、类型、内容、方式、培训师、考核方式、是否合格、开始/结束)。 入职自动建档:人事用户新增时插 `tms_person_file`。一人一档,`user_id` 唯一。 --- ## 6. 必须写在事件/代码里的规则 这些不要靠表结构硬约束,放发布/保存/归档按钮: 1. **时间**:`start_time <= end_time <= close_time`;考试时间不得早于培训开始;集中/操作授课开始结束必须同一天。 2. **地点占用**:同一 `place_id`,未取消任务的 `[start,end)` 按小时不得交叉。 3. **培训师冲突**:集中/操作授课下,同一培训师同一时段不能在两个任务。 4. **有人签到不能取消**;误取消可恢复(`cancelled → draft/published`)。 5. **发布**:拆个人任务;生成培训记录;考核方式=在线考试则生成 `tms_exam` 待考行;同步教材到记录。 6. **关闭时间到达** → 记录 `archive_status=pending`。 7. **归档**:计算签到率/合格率(取整舍小数);未完成人员生成再维护任务(`task_kind=continue`,`prev_task_no` 指向原任务);写入 `tms_person_train`。 8. **无效任务**:无人完成时可打 `invalid`,并自动生成新任务。 9. **提问人数**:`ceil(签到人数 * quiz_ratio / 100)`,取整。 10. **授权/计划到期前 30 天** 按 `tms_remind_rule` 推送给部门培训管理员和培训师。 --- ## 7. 角色只配权限,不新建表 | 角色 | 数据范围 | |---|---| | 系统管理员 | 基础设置 | | 公司培训管理员 | 全公司计划/任务/档案 | | 部门培训管理员 | 本部门 + `tms_admin_auth` 授权部门(可含下级) | | 培训师 | 自己的任务授课、打分、实操、阅卷 | | 普通员工 | 仅个人任务、个人考试记录、个人档案 | 「个人培训档案」只能看自己;「个人培训档案管理」按授权看部门/公司。 --- ## 8. 建议一期范围 先建并能跑通主链路的表: 地点、培训师、教材、题库、试题、试卷、年度计划、岗位计划、培训任务、个人任务、培训记录、签到明细、答卷快照、个人档案。 二期再铺:岗位目录升版、提问预设、实操/现场提问、记录变更、资料归档、外出/转岗/新员工/复岗流程、套打版本、提醒规则。 题库试卷引擎一期就要快照表,否则以后改题会污染已归档记录。