SpringBoot+Vue3 企业员工转正管理全流程设计:1张申请单、BPM审批驱动档案状态流转——从“手动改状态“到“审批即转正“
深度拆解企业员工转正管理的完整设计方案。1张转正申请单承载从试用到正式的状态跃迁,BPM审批通过自动更新员工档案状态为正式员工并回写转正日期,员工选择器仅展示非正式状态人员防止重复转正,与入职单形成完整的入职→试用→转正数据链。从业务建模到审批驱动的档案联动,还原一套"审批即转正"的企业人力资源管理方案。
SpringBoot+Vue3 企业员工转正管理全流程设计:1张申请单、BPM审批驱动档案状态流转——从"手动改状态"到"审批即转正"
🌐 文档地址:http://ruoyioffice.com | 📦 源码1:https://gitcode.com/zhouzhongyan/ruoyi-office-vben.git |📦 源码2:https://gitcode.com/zhouzhongyan/ruoyi-office.git |📦 源码3:https://github.com/yuqing2026/ruoyi-office.git | 💬 微信:17156169080(备注「RuoYi Office」)
员工转正是试用期的终点、正式入职的起点——这一步看似简单,实际涉及档案状态变更、转正日期确认、审批链合规性校验。大量企业的转正管理还停留在"HR 在 Excel 里改个状态"的阶段:忘了改就一直是试用期,改早了审批还没走完,改完了转正日期对不上入职时的约定。RuoYi Office 用 1 张转正申请单 + BPM 审批流程 + 档案状态自动回写,实现了"审批通过的瞬间,员工就是正式工"的全自动化转正管理。

▲ 员工转正管理功能架构全景:1 张转正申请单承载转正全流程,BPM 审批驱动档案状态自动流转,与入职单形成"入职→试用→转正"的完整数据链
引言:转正管理到底难在哪?
“不就是把试用期改成正式吗?”——初次接到转正需求的开发者大多这么想。但真正深入后会发现,转正管理的难点在于状态变更的合规性和数据一致性:
手动改状态,谁都能改:没有审批流程的转正管理,HR 在后台直接修改员工状态——谁批准了?什么时候批准的?完全没有记录。一旦出现劳动纠纷,"什么时候转的正"无从考证。
转正日期对不上:入职时约定 3 个月试用期,预计 6 月 1 日转正。但实际转正可能提前(表现优秀)或延后(需要延长考察),最终的转正日期和入职单上的预计日期不一致,如果没有系统记录,事后扯不清。
忘了转正:员工试用期到了,HR 忙起来忘了发起转正流程——员工一直挂着"试用期"状态,影响薪资、福利、合同签订。
已经正式的员工被重复转正:没有校验机制的系统,可能对已经是正式员工的人再提交一次转正申请,数据混乱。
状态变更和审批脱节:有些系统"先改状态再走审批"或者"审批通过了但忘了改状态",审批和状态变更不是原子操作,导致数据不一致。
| 痛点 | 传统做法 | 后果 |
|---|---|---|
| 无审批记录 | HR 手动改 Excel/系统状态 | 劳动纠纷时无法举证转正时间和审批人 |
| 转正日期不一致 | 入职约定一个日期,实际转正另一个日期 | 薪资计算、合同签订日期混乱 |
| 遗忘转正 | 靠 HR 记忆或日历提醒 | 员工长期挂试用期,影响待遇和士气 |
| 重复转正 | 无状态校验 | 正式员工被再次提交转正申请,数据冗余 |
| 审批与状态脱节 | 审批和状态变更分两步操作 | 审批通过但忘了改状态,或先改了状态再补审批 |
本文以 RuoYi Office 的员工转正管理模块为例,完整拆解其业务建模、审批驱动的档案联动、入职-转正数据链的设计方案。
一句话总结:RuoYi Office 用 1 张转正申请单 + FlowBillService 回调 + 事务性档案更新,实现了"BPM 审批通过的瞬间,员工状态自动变为正式、转正日期自动写入档案"——彻底消除了审批与状态变更之间的时间差。
一、业务设计:从一次转正申请说起
1.1 业务全景
一次完整的员工转正业务涉及三个角色、四个阶段:
| 阶段 | 角色 | 操作 | 系统行为 |
|---|---|---|---|
| 入职 | HR | 通过入职单录入员工信息 | 创建员工档案,状态为「试用期」,记录预计转正日期 |
| 发起转正 | HR/直属上级 | 选择待转正员工,填写实际转正日期 → 提交审批 | 创建转正申请单,发起 BPM 流程 |
| 审批 | 直属上级 → HR → 最终审批 | 审核员工试用期表现 | 审批通过后自动更新员工档案 |
| 转正生效 | 系统自动 | — | 员工状态变为「正式员工」,转正日期写入档案 |
1.2 入职→试用→转正:完整数据链
这是本方案最核心的业务抽象——入职单和转正单共同构成员工从入职到正式的完整生命周期:
入职单(entry_bill) 转正单(regular_bill)
┌──────────────┐ ┌──────────────┐
│ 创建员工档案 │ │ 选择待转正员工 │
│ employeeStatus│ │ 自动带出档案信息│
│ = 试用期(2) │──── 试用期间 ────▶│ 填写实际转正日期│
│ expectedFormal│ │ 提交 BPM 审批 │
│ Date = 6月1日 │ │ │
└──────────────┘ └───────┬───────┘
│ 审批通过
▼
┌──────────────┐
│ 自动回写档案 │
│ employeeStatus│
│ = 正式(1) │
│ formalDate │
│ = 实际日期 │
└──────────────┘
入职单在创建员工档案时设定 expectedFormalDate(预计转正日期),转正单将这个日期作为参考,允许 HR 填写实际的 formalDate。如果实际日期未填,系统自动使用预计日期——这就是转正日期智能填充的设计。
1.3 员工选择器的过滤逻辑
转正申请单的员工选择器 EmployeeSelectModal 不是展示所有员工,而是仅展示非正式状态的员工:
| 可选状态 | 枚举值 | 场景 |
|---|---|---|
| 试用期 | 2 |
最常见的转正场景 |
| 实习生 | 3 |
实习转正 |
| 临时工 | 5 |
临时工转正式 |
已经是正式员工(1)、离职(6)、退休(7) 的人员不会出现在选择器中——从入口就杜绝了重复转正的可能。
二、系统设计:简洁的单表模型
2.1 模块定位
RuoYi Office 的员工转正管理位于 人力资源 → 员工管理 → 转正管理 目录下,是 HRM 模块中的一个独立子模块:
| 子模块 | 菜单名称 | 功能定位 | 面向角色 |
|---|---|---|---|
| 转正管理 | 转正管理 | 员工转正申请、BPM 审批、档案状态自动回写 | HR / 直属上级 |
与入职单、调动单、离职单并列,共同组成员工生命周期管理的四大流程单据。
2.2 核心设计决策
| 决策点 | 方案 | 理由 |
|---|---|---|
| 数据模型 | 单表 hrm_employee_regular_bill |
转正单只关联一个员工,无子表需求,比入职单更简洁 |
| 员工选择范围 | 过滤非正式状态 [2,3,5] | 从选择入口杜绝重复转正 |
| 档案更新时机 | 审批通过时自动更新 | 不在提交时更新,避免审批拒绝后数据不一致 |
| 转正日期优先级 | formalDate > expectedFormalDate |
允许提前/延后转正,实际日期优先于预计日期 |
| 员工信息冗余 | 申请单快照员工数据 | 提交后员工档案变更不影响申请单历史数据 |
| 员工校验 | validateEmployeeExists |
必须在档案中存在的员工才能发起转正 |
| 审批集成 | FlowBillService 标准接口 | 复用 BPM 框架回调,状态同步零耦合 |
| 单据编号 | HR202-YYYYMMDD00001 | HRM 模块统一编号体系,202 为转正单类型编码 |
三、PC 端功能实现
3.1 转正申请列表
列表页展示当前用户视角下的所有转正申请单,采用 VxeGrid 表格组件,支持多维度搜索筛选。

▲ 转正申请列表:支持按单据编号、流程状态、工号、姓名、部门、员工状态、创建时间等维度搜索筛选
列表设计要点:
- 多维度搜索:
billCode(单据编号)、processStatus(流程状态)、employeeNo(工号)、name(姓名)、empDeptId(部门)、employeeStatus(员工状态)、createTime(创建时间范围)——覆盖 HR 常用的查询场景 - 单据编号链接:点击编号列自动跳转到详情页,编号格式为
HR202-{YYYYMMDD}{5位流水} - 流程状态标签:通过
CellDict组件渲染为不同颜色标签(审批中/已通过/已拒绝) - 员工信息直观展示:列表直接展示工号、姓名、部门、公司等冗余字段,无需再查档案
- 删除约束:审批中的单据不可删除,已通过的单据因为已联动档案也不建议删除
3.2 转正申请详情
详情页是转正单的核心交互页面,使用 BasicForm 将信息分为两大区域,辅以附件管理。
▲ 转正申请详情页:上半部分为员工信息(选择员工后自动填充,不可编辑),下半部分为转正信息(HR 填写实际转正日期、备注)
「员工信息」区域(选择员工后自动填充,全部只读):
| 字段 | 组件 | 说明 |
|---|---|---|
| 员工姓名 | HelpInput + EmployeeSelectModal | 点击弹出员工选择弹窗,选中后自动回填所有员工信息 |
| 工号 | Input (disabled) | 自动回填 employeeNo |
| 性别 | Select (disabled) | 自动回填 sex |
| 所在部门 | Input (disabled) | 自动回填 empDeptName |
| 所属公司 | Input (disabled) | 自动回填 empCompanyName |
| 岗位 | Input (disabled) | 自动回填 jobPost |
| 职位 | Input (disabled) | 自动回填 jobPosition |
| 员工状态 | Select (disabled) | 自动回填 employeeStatus(试用期/实习/临时) |
| 入职日期 | DatePicker (disabled) | 自动回填 entryDate |
| 试用期(月) | InputNumber (disabled) | 自动回填 probationPeriod |
「转正信息」区域:
| 字段 | 组件 | 说明 |
|---|---|---|
| 预计转正日期 | DatePicker (disabled) | 从员工档案带入的 expectedFormalDate,只读参考 |
| 实际转正日期 | DatePicker | 必填,HR 填写实际转正日期,可早于/晚于预计日期 |
| 备注 | TextArea | 转正评语、考核说明等 |
「附件」区域:
AttachmentList组件,最多上传 10 个文件,单文件不超过 20MB- 用于上传试用期考核表、转正申请书、部门意见等材料
3.3 员工选择弹窗 EmployeeSelectModal
弹窗内部是独立的分页表格,核心过滤逻辑是只展示非正式状态的员工:
query: async ({ page }, formValues) => {
const queryParams = {
pageNo: page.currentPage,
pageSize: page.pageSize,
employeeStatus: [2, 3, 5], // 试用期、实习、临时——非正式状态
...formValues,
};
return await getEmployeePage(queryParams);
},
选择员工后,弹窗将完整的员工信息回传给表单,表单自动填充所有「员工信息」区域的字段。这种设计保证了两点:
- 只有非正式员工才能被选择——正式员工、离职、退休人员不出现在列表中
- 员工信息一次选择、全量填充——避免 HR 手动填写容易出错
3.4 表单状态与 BPM 联动
转正申请表单的可编辑性随流程状态自动切换:
| 流程阶段 | 表单行为 | 说明 |
|---|---|---|
| 新建/草稿 | 全部可编辑 | HR 可选择员工、填写转正日期 |
| 审批中 | 全部只读 | 提交后不可修改,保障审批内容一致性 |
| 审批通过 | 全部只读 | 档案已更新,申请单成为历史记录 |
| 审批拒绝 | 可重新编辑提交 | 修正后重新发起审批 |
转正申请的 BPM 集成方式与入职单完全一致——提交表单后自动发起 Flowable 审批流程,审批进度在详情页实时展示。流程定义 Key 为 hr_employee_regular_bill。
四、流程设计:BPM 审批驱动档案状态流转
4.1 流程编排
转正申请使用 Flowable 引擎编排,流程设计简洁直接:
- HR/直属上级填写转正信息(选择员工 + 填写实际转正日期) → 提交流程
- 直属上级审批(评价员工试用期表现)
- HR 复核(确认转正日期、薪资调整等)
- 最终审批(部门负责人或分管领导)
- 审批通过 → 系统自动更新员工档案
不同流程单据审批通过后的行为对比:
| 单据类型 | 审批通过后行为 | 原因 |
|---|---|---|
| 用印申请 | 设置用印状态为"待处理",等待管理员确认 | 用印是物理操作,需要人工执行 |
| 转正申请 | 直接自动更新员工档案 | 转正是状态变更,无需额外人工操作 |
| 入职申请 | 创建员工档案 | 入职是新增记录 |
| 离职申请 | 更新员工状态为离职 | 与转正类似,状态变更 |
转正管理审批通过后直接自动更新员工档案——因为转正是一个明确的状态变更,不需要额外的人工确认步骤。这种"审批即生效"的设计大幅减少了 HR 的操作步骤。
4.2 FlowBillService 回调:审批即转正
转正单服务实现了 FlowBillService 接口,BPM 引擎在流程状态变化时自动回调 updateProcessStatus——这是整个转正管理中最关键的方法:
@Override
@Transactional(rollbackFor = Exception.class)
public void updateProcessStatus(String businessKey, Integer status) {
Long id = Long.parseLong(businessKey);
validateEmployeeRegularBillExists(id);
EmployeeRegularBillDO updateObj = new EmployeeRegularBillDO();
updateObj.setId(id);
updateObj.setProcessStatus(status);
// 审批通过时,自动更新员工档案状态为正式
if (APPROVE.getStatus().equals(status)) {
updateEmployeeFromRegularBill(id);
}
employeeRegularBillMapper.updateById(updateObj);
}
关键设计:
- 审批通过时,先调用
updateEmployeeFromRegularBill更新员工档案,再更新申请单流程状态——两步操作在同一个事务中,要么都成功要么都回滚 - 审批拒绝/撤回时,只更新
processStatus,不触碰员工档案——申请单在业务层面"从未生效" @Transactional(rollbackFor = Exception.class)确保档案更新和状态更新的原子性
4.3 档案自动更新:审批通过的瞬间
updateEmployeeFromRegularBill 是审批通过后的核心联动逻辑——将员工状态改为正式、写入转正日期:
private void updateEmployeeFromRegularBill(Long regularBillId) {
EmployeeRegularBillRespVO regularBillRespVO = getEmployeeRegularBillInfo(regularBillId);
if (regularBillRespVO == null) return;
EmployeeDO employee = employeeMapper.selectById(regularBillRespVO.getEmployeeId());
if (employee == null) return;
EmployeeDO updateEmployee = new EmployeeDO();
updateEmployee.setId(employee.getId());
// 状态变更:试用期/实习/临时 → 正式员工
updateEmployee.setEmployeeStatus(EmployeeStatusEnum.FORMAL.getStatus());
// 转正日期智能填充:优先使用申请单上的实际日期
LocalDate formalDate = regularBillRespVO.getFormalDate();
if (formalDate == null) {
formalDate = regularBillRespVO.getExpectedFormalDate();
}
if (formalDate != null) {
updateEmployee.setFormalDate(formalDate);
}
employeeMapper.updateById(updateEmployee);
}
转正日期的优先级逻辑:
| 优先级 | 日期来源 | 场景 |
|---|---|---|
| 1(最高) | formalDate(转正单填写的实际日期) |
HR 填写了实际转正日期(可能提前或延后) |
| 2 | expectedFormalDate(入职时的预计日期) |
HR 未填写实际日期,使用入职时的约定 |
这种设计覆盖了三种常见场景:
- 按时转正:
formalDate = expectedFormalDate,两个日期一致 - 提前转正:
formalDate < expectedFormalDate,表现优秀提前转正 - 延后转正:
formalDate > expectedFormalDate,延长试用期后转正
五、后端核心实现
5.1 单表数据模型
与入职单的多子表设计不同,转正单采用简洁的单表模型——因为转正只关联一个员工,不涉及经历明细等一对多信息:
hrm_employee_regular_bill(转正申请单)
├── 单据信息:billCode, processInstanceId, processStatus
├── 员工信息(冗余):employeeId, employeeNo, name, sex, empDeptId/Name, empCompanyId/Name
├── 工作信息(冗余):jobPost, jobPosition, employeeStatus, entryDate
├── 转正信息:formalDate, expectedFormalDate, probationPeriod
└── 附件:通过 attachment 表关联
单表设计带来的好处:查询无需 JOIN、数据自包含、维护成本低。
5.2 单据编号生成
每张转正申请单都有唯一的单据编号,格式为 HR202-{YYYYMMDD}{5位流水}(如 HR202-2026041100001)。编号在首次保存或提交时自动生成:
if (StringUtils.isBlank(saveReqVO.getBillCode())) {
saveReqVO.setBillCode(BillCodeUtils.generateBillCode(
SystemEnum.HRM, HrmBillTypeEnum.HRM_EMPLOYEE_REGULAR_BILL));
}
202 是 HRM 模块中转正申请单的类型编码,由 HrmBillTypeEnum.HRM_EMPLOYEE_REGULAR_BILL 定义。流水号基于 Redis 自增,key 为 bill_code:HRM:202:{yyyyMMdd},过期时间 2 天,保证分布式环境下编号唯一且递增。
5.3 提交流程:校验 + 保存 + 发起BPM
提交转正申请是整个业务的核心入口——需要校验员工、生成编号、保存数据、发起BPM流程、保存附件:
@Override
public Long submitEmployeeRegularBill(EmployeeRegularBillSaveReqVO saveReqVO) {
// 1. 生成单据编号
if (StringUtils.isBlank(saveReqVO.getBillCode())) {
saveReqVO.setBillCode(BillCodeUtils.generateBillCode(
SystemEnum.HRM, HrmBillTypeEnum.HRM_EMPLOYEE_REGULAR_BILL));
}
// 2. 校验员工必须在档案中存在
validateEmployeeExists(saveReqVO.getEmployeeId());
// 3. 保存转正申请单(状态设为审批中)
EmployeeRegularBillDO regularBill = BeanUtils.toBean(saveReqVO, EmployeeRegularBillDO.class)
.setProcessStatus(BpmTaskStatusEnum.RUNNING.getStatus());
employeeRegularBillMapper.insertOrUpdate(regularBill);
// 4. 构建流程变量并发起 BPM 流程
Map<String, Object> processInstanceVariables =
BpmProcessVariableUtils.buildBillVariables(saveReqVO);
processInstanceVariables.put(BpmProcessVariableConstants.CAUSE,
regularBill.getName() + "转正申请");
String processInstanceId = processInstanceApi.submitProcessInstance(
Long.valueOf(saveReqVO.getCreator()),
new BpmProcessInstanceCreateReqDTO()
.setProcessDefinitionKey(HrmBillTypeEnum
.HRM_EMPLOYEE_REGULAR_BILL.getProcessDefinitionKey())
.setVariables(processInstanceVariables)
.setBusinessKey(String.valueOf(regularBill.getId()))
).getCheckedData();
// 5. 回写流程实例 ID
employeeRegularBillMapper.updateById(new EmployeeRegularBillDO()
.setId(regularBill.getId()).setProcessInstanceId(processInstanceId));
// 6. 保存附件
if (saveReqVO.getAttachments() != null) {
attachmentService.saveAttachmentList(
HrmBillTypeEnum.HRM_EMPLOYEE_REGULAR_BILL.getTypeCode(),
regularBill.getId(), saveReqVO.getAttachments());
}
return regularBill.getId();
}
与用印申请提交的对比:
| 对比项 | 用印申请 | 转正申请 |
|---|---|---|
| 冲突检测 | 外借时间冲突校验 | 无(一个员工可以多次提交,只有通过的才生效) |
| 特有校验 | validateTimeConflict |
validateEmployeeExists(员工必须存在) |
| 流程变量 | sealUseMode 驱动审批分支 |
CAUSE 记录申请原因 |
| 审批后行为 | 设置用印状态为"待处理" | 直接更新员工档案 |
5.4 删除时清理流程与附件
删除转正申请单时,同样需要清理 BPM 流程实例和附件,设计模式与其他单据一致:
@Override
public void deleteEmployeeRegularBill(Long id) {
EmployeeRegularBillDO bill = employeeRegularBillMapper.selectById(id);
if (bill == null) {
throw exception(EMPLOYEE_REGULAR_BILL_NOT_EXISTS);
}
// 清理 BPM 流程实例
if (StringUtils.isNotBlank(bill.getProcessInstanceId())) {
try {
processInstanceApi.deleteProcessInstance(
Long.valueOf(bill.getCreator()), bill.getProcessInstanceId());
} catch (Exception e) {
log.warn("[deleteEmployeeRegularBill] 清理流程实例失败: {}", e.getMessage());
}
}
// 清理附件和主表
attachmentService.deleteAttachmentByBusiness(
HrmBillTypeEnum.HRM_EMPLOYEE_REGULAR_BILL.getTypeCode(), id);
employeeRegularBillMapper.deleteById(id);
}
六、RuoYi Office 的创新设计
6.1 审批即转正:审批通过自动更新档案
这是转正管理最核心的设计理念。传统方案中"审批"和"改状态"是两个独立动作,容易脱节:
- 传统方案:审批通过 → HR 手动到档案页面修改状态 → 容易忘记或延迟
- RuoYi Office:审批通过 →
updateProcessStatus回调中自动调用updateEmployeeFromRegularBill→ 员工状态和转正日期一步到位
整个过程在一个事务内完成,不存在"审批通过了但档案还是试用期"的中间态。
6.2 转正日期智能填充
转正日期不是简单的"填什么就是什么",而是有优先级链:
实际转正日期(formalDate) > 预计转正日期(expectedFormalDate)
↑ 转正单填写 ↑ 入职单带入
这种设计兼容了三种场景:按时转正(两个日期一致)、提前转正(实际日期早于预计)、延后转正(实际日期晚于预计)。HR 只需要在转正单上填写实际日期,如果留空则自动使用入职时的约定——操作负担最小化。
6.3 员工选择器过滤:从入口杜绝错误
EmployeeSelectModal 固定过滤 employeeStatus: [2, 3, 5](试用期、实习、临时),三重防护效果:
| 防护层 | 机制 | 效果 |
|---|---|---|
| 第一层 | 前端弹窗只展示非正式员工 | 已转正的员工根本不会出现在选择列表中 |
| 第二层 | 后端 validateEmployeeExists |
确保选择的员工在档案中真实存在 |
| 第三层 | 审批通过时按 employeeId 精准更新 |
即使并发提交,最终档案状态也是一致的 |
6.4 入职-转正数据链
入职单和转正单不是两个孤立的模块,而是通过员工档案作为桥梁形成数据链:
| 数据流向 | 字段 | 说明 |
|---|---|---|
| 入职单 → 员工档案 | employeeStatus = 试用期、expectedFormalDate |
入职时确定试用期和预计转正日期 |
| 员工档案 → 转正单 | employeeNo、name、empDeptName、expectedFormalDate 等 |
转正时从档案带入员工信息和预计日期 |
| 转正单 → 员工档案 | employeeStatus = 正式、formalDate |
审批通过后回写正式状态和实际日期 |
三者形成闭环:入职建档 → 转正审批 → 档案更新,每一步都有系统记录,可追溯、可审计。
6.5 员工信息冗余:历史快照不可篡改
转正申请单冗余存储了 employeeNo(工号)、name(姓名)、empDeptName(部门)、empCompanyName(公司)、jobPost(岗位)、jobPosition(职位)、employeeStatus(员工状态)等员工信息。这些字段在提交时从档案快照,此后不再随档案变更而变化。
为什么需要冗余? 如果员工在试用期内调动了部门(通过调动单),然后才走转正流程——转正单上记录的应该是"发起转正时的部门"还是"最新的部门"?答案是前者。冗余保证了"2026 年 4 月提交转正时,这个人在技术部"这一历史事实不可篡改。
七、数据结构
7.1 表结构:hrm_employee_regular_bill(转正申请单)
| 字段 | 类型 | 说明 |
|---|---|---|
id |
bigint | 主键 |
bill_code |
varchar(50) | 单据编号(HR202-YYYYMMDD00001) |
process_instance_id |
varchar(64) | Flowable 流程实例 ID |
process_status |
int | 流程状态(BpmTaskStatusEnum) |
employee_id |
bigint | 关联员工 ID |
employee_no |
varchar(50) | 工号(冗余) |
name |
varchar(100) | 姓名(冗余) |
sex |
int | 性别(冗余) |
emp_dept_id / emp_dept_name |
bigint / varchar | 所在部门(冗余) |
emp_company_id / emp_company_name |
bigint / varchar | 所属公司(冗余) |
job_post |
varchar(100) | 岗位(冗余) |
job_position |
varchar(100) | 职位(冗余) |
employee_status |
int | 员工状态(冗余,提交时快照) |
entry_date |
date | 入职日期(冗余) |
formal_date |
date | 实际转正日期 |
expected_formal_date |
date | 预计转正日期(从档案带入) |
probation_period |
int | 试用期(月) |
dept_id / dept_name |
bigint / varchar | 申请人所属部门 |
company_id / company_name |
bigint / varchar | 申请人所属公司 |
creator_name |
varchar(100) | 申请人姓名 |
remark |
varchar(500) | 备注 |
attachments |
— | 通过附件表关联(HrmBillTypeEnum.HRM_EMPLOYEE_REGULAR_BILL) |
7.2 设计要点
- 冗余存储:申请单冗余了员工的工号、姓名、部门、公司、岗位、职位、状态等 10+ 个字段。列表查询无需 JOIN 员工表,历史数据不受后续档案修改影响
- 双日期字段:
expected_formal_date从入职时带入作为参考,formal_date由 HR 在转正时填写。审批通过时优先使用formal_date,为空则 fallback 到expected_formal_date - 状态快照:
employee_status记录的是"提交转正申请时员工的状态"(一定是非正式状态),审批通过后档案中的状态会变为正式,但申请单上的值不变——方便事后统计"有多少人是从试用期转正的、有多少是从实习转正的" - 单表无子表:与入职单(1主表+3子表)不同,转正单不涉及经历明细,单表即可承载所有信息,模型更简洁
八、技术亮点总结
| 设计要点 | 实现方式 | 价值 |
|---|---|---|
| 审批即转正 | updateProcessStatus 回调中自动更新档案 |
审批通过瞬间员工就是正式工,零延迟 |
| 转正日期智能填充 | formalDate > expectedFormalDate 优先级链 |
兼容按时/提前/延后三种转正场景 |
| 员工选择器过滤 | employeeStatus: [2,3,5] 过滤 |
从入口杜绝重复转正 |
| 入职-转正数据链 | 入职单→档案→转正单→档案 闭环 | 完整可追溯的员工生命周期 |
| 事务保障 | @Transactional 包裹档案更新+状态更新 |
不存在"审批过了但状态没改"的中间态 |
| 员工信息冗余 | 申请单快照 10+ 个员工字段 | 历史数据不受后续档案变更影响 |
| 单表简洁模型 | 无子表,单表自包含 | 查询、维护、备份成本低 |
| 单据编号唯一 | Redis 自增 + 日期分段 | 分布式环境下编号唯一递增 |
| FlowBillService 标准化 | 统一接口接收 BPM 回调 | 新增流程单据只需实现接口 |
| 删除级联清理 | 流程+附件+主表 | 数据一致性,无孤儿记录 |
| 员工存在性校验 | validateEmployeeExists |
防止关联不存在的员工 |
九、快速体验
操作路径:人力资源 → 员工管理 → 转正管理
推荐体验流程:
- 准备数据:确保系统中有处于「试用期」状态的员工(可通过入职单流程创建)
- 发起转正:进入「转正管理」,点击「新建」,在员工选择弹窗中选择一名试用期员工
- 观察自动填充:选择员工后,工号、姓名、部门、公司、岗位、职位、员工状态、入职日期、试用期、预计转正日期全部自动填充
- 填写转正日期:在「实际转正日期」字段填写日期(可以与预计日期不同)
- 上传附件:上传试用期考核表等材料(可选)
- 提交审批:点击「提交」,观察单据状态变为「审批中」
- 审批通过:到流程中心的待办任务中找到申请,逐级审批通过
- 验证档案更新:进入「员工档案」查看该员工,确认状态已变为「正式员工」,转正日期已写入
- 验证选择器过滤:再次新建转正单,在员工选择弹窗中确认刚转正的员工已不再出现
源码仓库:
| 平台 | 地址 |
|---|---|
| GitCode(后端) | https://gitcode.com/zhouzhongyan/ruoyi-office.git |
| GitCode(前端) | https://gitcode.com/zhouzhongyan/ruoyi-office-vben.git |
| GitHub(后端) | https://github.com/yuqing2026/ruoyi-office.git |
结语
转正管理看似是 HRM 中一个"小而精"的模块,但它承载的是员工从试用到正式的关键状态跃迁。1 张单表的简洁模型让数据职责清晰,BPM 审批驱动的档案自动回写让"审批即转正"成为现实,转正日期智能填充覆盖了提前/按时/延后三种场景,员工选择器的状态过滤从入口就杜绝了重复转正。
这套"审批驱动档案状态流转"的设计模式不仅适用于转正管理,还可以推广到其他员工生命周期场景——调岗单审批通过自动更新部门和职位,离职单审批通过自动更新状态为离职。核心思想是:用 BPM 审批保障合规性,用 FlowBillService 回调驱动数据联动,用事务保障数据一致性。
如果你正在设计类似的员工生命周期管理模块,或者对 BPM 审批驱动数据联动的设计感兴趣,欢迎参考源码实现。
你们公司的转正流程有多少个审批节点?转正日期是固定的还是可以提前/延后?欢迎在评论区分享你的实践经验。
📚 想要体验 RuoYi Office 的强大功能?
🌐 在线演示:http://ruoyioffice.com/web/(账号 admin / admin123)
📦 GitCode 开源:https://gitcode.com/zhouzhongyan/ruoyi-office.git
💬 技术咨询:添加微信 17156169080,备注「RuoYi Office」
⭐ 如果觉得不错,请给个 Star 支持一下!
更多推荐
所有评论(0)