# HRM 培训管理 + 证书/合同到期提醒 - 前端联调方案 ## 涉及页面 | 页面 | 变更类型 | 说明 | |------|----------|------| | 人力资源 - 证书资质 | 改造 | 列表筛选新增"到期类型",列表页打开触发证书到期提醒 | | 人力资源 - 员工合同 | 改造 | 列表页打开触发合同到期提醒(无页面结构改动) | | 人力资源 - 培训管理(新增菜单) | 新增 | 培训活动 + 参训人员 + 完成发证 | | 系统消息(站内信) | 展示 | 到期提醒站内信由后端主动发送,前端无需调用接口 | ## 到期提醒行为说明 - 证书资质、劳动合同到期前 N 天(默认 30,可在「系统配置」中改 `hrm.certificate.remind-days` / `hrm.contract.remind-days`),向该员工绑定的系统账号发送站内信。 - 触发时机双保险: 1. 每日定时任务(handlerName=`hrmExpiryRemindJob`,每日 08:00,可在定时任务管理中调整/启停); 2. 懒触发:打开"证书资质"或"员工合同"列表时后端顺带补扫一次(best-effort,失败不影响列表)。 - 去重规则:同一证书/合同在到期日前后 60 天内只提醒一次;同一员工离职后不提醒(仅向在岗/试用且有系统账号的员工发送)。 站内信文案(变量由后端带入,前端仅展示): | 模板 | 内容示例 | |------|----------| | 证书到期提醒 | {employeeName},您的证书资质【{certTypeName}】{certName} 将于 {expireDate} 到期,请及时办理复审/换证。 | | 劳动合同到期提醒 | {employeeName},您的劳动合同(编号:{contractNo})将于 {endDate} 到期,请及时联系人事办理续签或离职手续。 | ## API ### 一、证书资质(改造) | 方法 | 路径 | 说明 | |------|------|------| | GET | /hrm/certificate/page | 分页查询,新增 `expiryType` 过滤参数 | **请求参数(新增):** | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | expiryType | Integer | 否 | 1=即将到期(30 天内),2=已过期;不传则不过滤 | ### 二、培训活动(新增,菜单权限 hrm:training:*) | 方法 | 路径 | 说明 | |------|------|------| | POST | /hrm/training/create | 创建培训(初始状态=草稿) | | PUT | /hrm/training/update | 更新培训(仅草稿/待开展可改,编号不可改) | | DELETE | /hrm/training/delete | 批量删除培训(ids 数组,已完成/已取消不可删,级联删参训人) | | GET | /hrm/training/get?id= | 培训详情(含参训人员列表) | | GET | /hrm/training/page | 培训分页(含参训人数、状态/类型名称) | | POST | /hrm/training/start?id= | 开始培训(草稿 → 待开展) | | POST | /hrm/training/complete?id= | 完成培训(→ 已完成,触发联动发证) | | POST | /hrm/training/cancel?id= | 取消培训(草稿/待开展 → 已取消) | **创建/更新请求参数(HrmTrainingSaveReqVO):** | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | id | Long | 更新必填 | 培训活动编号 | | name | String | 是 | 培训名称 | | trainingType | Integer | 是 | 培训类型:1=安全培训,2=技能培训,3=管理培训,4=其他 | | trainer | String | 否 | 讲师 | | location | String | 否 | 培训地点 | | hours | BigDecimal | 否 | 培训学时 | | startDate | LocalDate | 否 | 开始日期 | | endDate | LocalDate | 否 | 结束日期 | | issueCertificate | Boolean | 否 | 是否自动发证(0=否,1=是;仅安全/技能培训可置 1) | | certValidityMonths | Integer | issue=1 时必填 | 证书有效期(月) | | remark | String | 否 | 备注 | **分页查询参数(HrmTrainingPageReqVO):** | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | trainingNo | String | 否 | 培训编号(精确) | | name | String | 否 | 培训名称(模糊) | | trainingType | Integer | 否 | 培训类型 | | status | Integer | 否 | 状态:0=草稿,10=待开展,20=已完成,30=已取消 | **详情/列表响应(HrmTrainingRespVO):** | 字段 | 类型 | 说明 | |------|------|------| | id / trainingNo / name | | 主键、编号(PX 前缀自动生成,只读)、名称 | | trainingType / trainingTypeName | | 类型 + 展示名(安全培训/技能培训/管理培训/其他) | | trainer / location / hours | | 讲师/地点/学时 | | startDate / endDate | | 起止日期 | | issueCertificate / certValidityMonths | | 是否自动发证 / 证书有效期月 | | status / statusName | | 状态 + 展示名(草稿/待开展/已完成/已取消) | | participantCount | Integer | 参训人数(分页列表返回) | | participants | Array | 参训人员列表(详情接口返回,结构见下) | | remark / createTime | | 备注 / 创建时间 | ### 三、培训参训人员(新增,挂培训管理权限) | 方法 | 路径 | 说明 | |------|------|------| | POST | /hrm/training-participant/add | 批量添加参训员工(自动跳过已在名单中的员工) | | PUT | /hrm/training-participant/update | 更新单条参训记录(参加/成绩/是否合格) | | DELETE | /hrm/training-participant/delete | 批量删除参训记录(ids 数组) | | GET | /hrm/training-participant/list?trainingId= | 某次培训的参训人员列表(含员工工号/姓名) | **add 请求参数:** | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | trainingId | Long | 是 | 培训活动编号 | | employeeIds | Array | 是 | 参训员工编号集合 | **update 请求参数:** | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | id | Long | 是 | 参训记录编号 | | attended | Boolean | 否 | 是否实际参加 | | score | BigDecimal | 否 | 考核成绩 | | isPass | Boolean | 否 | 是否合格 | | remark | String | 否 | 备注 | **list 响应字段(HrmTrainingParticipantRespVO):** | 字段 | 类型 | 说明 | |------|------|------| | id / trainingId / employeeId | | 主键 / 培训编号 / 员工编号 | | employeeNo / employeeName | | 员工工号 / 姓名(后端按 employeeId 回填) | | attended | Boolean | 是否实际参加 | | score | BigDecimal | 考核成绩 | | isPass | Boolean | 是否合格 | | certificateId | Long | 联动生成的证书编号(空=尚未发证,只读) | | remark / createTime | | 备注 / 创建时间 | ## 前端修改点(页面行为说明,不含代码) ### 1. 培训管理列表页(新增) - 顶部筛选:培训编号、培训名称、培训类型(下拉)、状态(下拉),调用培训分页接口。 - 列表列:培训编号、名称、类型、讲师、起止日期、参训人数、状态、操作。 - 新增/编辑弹窗:表单字段同创建请求参数;"是否自动发证"勾选且培训类型为安全/技能时展示"证书有效期(月)"必填输入。 - 操作按钮(按当前状态显隐): - 草稿:开始、编辑、删除; - 待开展:完成、取消、编辑、删除; - 已完成/已取消:仅查看,不允许编辑/删除/操作参与人。 - "参训人员"弹窗从详情接口获得 participants,按培训完成与否决定是否允许增删改参与人记录。 ### 2. 参训人员操作 - "添加参训员工"使用现有员工选择器,选中后取员工 id 列表,调用 add 接口;接口返回实际新增数(已存在的自动跳过)。 - 参训记录行可录"是否参加 / 考核成绩 / 是否合格",提交走 update;delete 传 ids。 - 员工工号/姓名由后端回填,前端不要在本地拼装。 ### 3. 证书资质列表(改造) - 列表筛选区新增"到期类型"下拉(全部/即将到期/已过期),值映射 expiryType 1/2。 - 列表打开即会触发到期提醒发送,无需额外 UI。 ## 业务规则说明 | 场景 | 规则 | |------|------| | 状态流转 | create→草稿(0);start→待开展(10);complete→已完成(20);cancel→已取消(30) | | 完成培训 | 状态为草稿/待开展才可完成,否则报错 | | 联动发证 | issueCertificate=1 时,培训完成自动对"合格(isPass=1)且未发证(certificateId 为空)"的参训人生成证书 | | 证书类型映射 | 安全培训(1)→证书类型4 安全培训合格证;技能培训(2)→证书类型3 技能等级证书;管理/其他不支持自动发证 | | 证书有效期 | 发证日期=完成当天;到期日期=完成当天 + certValidityMonths 个月 | | 幂等 | 重复点"完成"不会重复发证(参训人回写 certificateId 防重) | | 不可编辑边界 | 已完成/已取消的培训:不可编辑、删除,不可添加/更新/删除参训人 | | 参训人唯一 | 同一培训下同一员工只允许一条记录,重复添加自动跳过 | | 编号生成 | trainingNo 以 PX 开头 + 日期 + 自增,由后端生成,前端只读展示 | | 到期提醒发送对象 | 仅该员工绑定系统账号且在职/试用;离职不提醒 | ## 注意事项 - 培训相关 4 个按钮权限(query/create/update/delete)与证书资质一致已授权给租户管理员等角色;如某些账号看不到"培训管理"菜单,需在"系统管理→角色管理"里勾选该菜单权限。 - 站内信在登录用户的"系统消息"内查看;收件人是培训外的员工本人(证书/合同归属员工),不是 HR 操作人。 - `certificateId` 为只读回显,前端不可提交。 - 若修改了到期提醒天数配置,请在"系统配置"保存,下次提醒扫描即按新值生效。