SpringBoot+Vue3 企业员工入职管理全流程设计:1主表+3子表、BPM审批驱动自动建档——从"纸质入职登记"到"审批即建档"
🌐 文档地址:ruoyioffice.com | 📦 源码1:gitcode.com/zhouzhongya… |📦 源码2:gitcode.com/zhouzhongya… |📦 源码3:github.com/yuqing2026/… | 💬 微信:17156169080(备注「RuoYi Office」)
入职管理是企业人力资源数字化的"第一道门"——候选人通过面试后,HR 需要采集基本信息、工作经历、教育背景、家属信息,然后提交审批,审批通过后还要到员工档案系统手动再录一遍。信息二次录入不仅浪费时间,还容易出错遗漏。RuoYi Office 用 1 张主表 + 3 张子表构建入职登记的完整数据模型,BPM 审批通过后自动创建员工档案——从"纸质入职登记表"到"审批即建档",让入职流程真正闭环。
▲ 员工入职管理功能架构全景:1 张主表(入职登记单)+ 3 张子表(工作经历/教育经历/家属信息),BPM 审批驱动状态流转,审批通过后自动创建员工档案并关联入职单
引言:入职管理到底难在哪?
"不就是填个入职表吗?"——初次接到 HRM 需求的开发者大多这么想。但真正深入后会发现,入职管理的复杂度远超一张表单:
信息采集量大,字段维度多:入职登记不只是姓名电话——基本信息(姓名/性别/生日/民族/政治面貌/婚姻/身份证/学历/籍贯/地址/紧急联系人)15+ 字段,工作信息(入职部门/岗位/职务/薪资/银行卡/试用期/预计转正日期)10+ 字段,再加上工作经历、教育经历、家属信息三类"一对多"子表,一个人的入职登记需要覆盖 30+ 个字段维度。
信息二次录入:传统流程是"入职登记 → 审批 → HR 手动在员工档案系统再录一遍"。两套数据各自维护,容易出现入职单写的是市场部、档案却录成了销售部的低级错误。
唯一性冲突难检测:同一个人不能重复入职——但怎么判断"同一个人"?靠姓名?同名同姓太常见。必须用手机号 + 身份证号双重校验,而且要同时检查入职单和员工档案两张表。
审批与建档脱节:审批通过只是改了一个流程状态字段,HR 还得记着"审批通过了要去建档案"。如果忙忘了,新员工第二天来上班发现系统里没有自己的账号。
试用期管理缺乏自动化:入职时填了试用期 3 个月、入职日期 2026-04-01,转正日期应该是 2026-07-01——但大多数系统需要 HR 手动计算填写。
| 痛点 | 传统做法 | 后果 |
|---|---|---|
| 信息二次录入 | 入职登记填一遍,档案系统再录一遍 | 数据不一致,人工成本高 |
| 审批与建档脱节 | 审批通过后人工记着去建档 | 遗忘导致新员工无系统账号 |
| 唯一性无校验 | 纯靠HR人工核对 | 同一人重复入职无人发现 |
| 试用期手动计算 | HR人工推算转正日期 | 算错导致提前/延迟转正 |
| 多租户不安全 | 建档时忘记切租户上下文 | 员工档案建错租户 |
RuoYi Office 的解法:入职登记单走 BPM 审批,审批通过的那一刻自动调用 createEmployeeFromEntryBill——把入职单的全部数据(基本信息 + 工作信息 + 工作经历 + 教育经历 + 家属信息)一键迁移到员工档案,试用期自动推算转正日期,多租户安全隔离,审批即建档,零人工干预。
一、业务设计:入职登记的完整生命周期
1.1 业务流程概览
一次完整的入职登记业务涉及三个角色、五个阶段:
| 阶段 | 角色 | 操作 | 系统行为 |
|---|---|---|---|
| 填写 | HR 专员 | 填写候选人基本信息、工作信息、经历信息 | 创建入职登记单(草稿) |
| 提交 | HR 专员 | 确认信息无误后提交审批 | 生成 HR201 编号,发起 BPM 流程 |
| 审批 | 部门主管/HR 经理 | 审核入职信息是否准确完整 | 流程流转,支持加签/退回/抄送 |
| 建档 | 系统自动 | 审批通过后自动执行 | 创建员工档案 + 迁移全部数据 |
| 归档 | HR 专员 | 查看入职单详情,关联已创建的档案 | 入职单记录员工档案 ID |
1.2 数据模型:1 主表 + 3 子表
入职登记单的数据结构与员工档案高度对齐,这是"审批即建档"的数据基础:
hrm_employee_entry_bill(入职登记主表 · 30+字段)
├── 1:N ──▶ hrm_employee_entry_bill_work_experience(工作经历)
│ 通过 entry_bill_id 关联
├── 1:N ──▶ hrm_employee_entry_bill_education(教育经历)
│ 通过 entry_bill_id 关联
└── 1:N ──▶ hrm_employee_entry_bill_family(家属信息)
通过 entry_bill_id 关联
──── 审批通过 ──▶ hrm_employee(员工档案主表)
+ hrm_employee_work_experience
+ hrm_employee_education
+ hrm_employee_family
为什么入职单要独立建表,而不是直接写员工档案? 因为入职单是"待审批的数据",审批可能被拒绝、退回、修改后重新提交。只有审批通过的入职单才应该进入正式的员工档案体系。入职单和档案是"申请"与"确认"的关系,职责不同,必须分表。
1.3 流程关键字与编号规则
| 项目 | 值 | 说明 |
|---|---|---|
| 流程定义 Key | hr_employee_entry_bill | BPM 流程的唯一标识 |
| 单据编号 | HR201-YYYYMMDD00001 | SystemEnum.HRM(code="HR") + typeCode="201" |
| 编号示例 | HR201-2026040700001 | 2026年4月7日第1张入职单 |
二、系统设计:模块组成与设计决策
2.1 模块定位
员工入职管理位于 HRM 人力资源 → 员工管理 → 员工入职 目录下,是员工档案的"前置流程":
| 子模块 | 功能定位 | 面向角色 |
|---|---|---|
| 入职登记单 | 新员工信息采集 + BPM 审批 + 自动建档 | HR 专员 |
| 员工档案(下游) | 正式员工数据管理(由入职单自动创建) | HR 管理员 |
2.2 核心设计决策
| 决策点 | 方案 | 理由 |
|---|---|---|
| 数据模型 | 1 主表 + 3 子表(独立于档案表) | 入职单是待审批数据,与正式档案分离 |
| 子表更新策略 | 先删后插(全量替换) | 子表数据量小(3-5条),全量替换比差异对比简单可靠 |
| 编号生成 | BillCodeUtils.generateBillCode | 统一编号框架,HR201前缀+日期+流水号 |
| 唯一性校验 | 手机号 + 身份证号双重校验(查档案表) | 防止同一人重复入职,姓名可能重复 |
| 审批回调 | FlowBillService.updateProcessStatus | 标准 BPM 回调接口,状态同步零耦合 |
| 审批即建档 | createEmployeeFromEntryBill | 审批通过时自动创建员工档案,零人工 |
| 转正日期 | entryDate + probationPeriod 自动计算 | 消除 HR 手动计算的错误风险 |
| 多租户建档 | TenantUtils.execute 包裹建档操作 | 确保档案创建在正确的租户上下文中 |
| 删除级联 | 清理 BPM 流程 + 附件 + 3 子表 + 主表 | 数据一致性,无孤儿记录 |
三、PC 端功能实现
3.1 入职登记列表
列表页采用 VxeGrid 表格 的标准布局,支持按单据编号、流程状态、姓名、手机号、所属部门、人员状态、入职日期、创建时间等多维度搜索。
▲ 入职登记列表:单据编号列可点击跳转详情页,流程状态按字典渲染彩色标签(草稿/审批中/已通过/已拒绝),支持新建、删除、撤回操作
列表设计要点:
- 单据编号链接:通过
createRouterLinkColumn渲染为可点击链接,跳转到/hrm/employee/employee-entry-bill-info?id=xxx详情页 - 流程状态标签:
processStatus通过CellDict渲染为不同颜色标签——草稿(灰色)、审批中(蓝色)、已通过(绿色)、已拒绝(红色) - 撤回操作:审批中的单据支持撤回,调用 BPM 撤回接口将流程退回草稿状态
- 删除约束:审批中的单据不可删除,删除时同步清理 BPM 流程实例
3.2 入职登记详情
详情页是入职管理的核心交互页面,使用 BasicForm 分为 基本信息 + 工作信息 + 三张子表 + 附件 的分区布局。

▲ 入职登记详情页:上方基本信息表单(姓名/性别/手机/生日/身份证/学历/民族等),中间工作信息表单(入职部门/岗位/薪资/试用期等),下方三张子表(工作经历/教育经历/家属信息),底部附件区域
基本信息表单:
| 字段 | 组件 | 说明 |
|---|---|---|
| 姓名 | Input | 必填 |
| 性别 | Select | 字典 system_user_sex |
| 手机号 | Input | 必填,11位手机号校验 |
| 出生日期 | DatePicker | 选择生日 |
| 身份证号 | Input | 18位身份证正则校验 |
| 邮箱 | Input | 邮箱格式校验 |
| 民族 | Select | 字典 |
| 政治面貌 | Select | 字典 |
| 婚姻状况 | Select | 字典 |
| 学历 | Select | 字典 |
| 籍贯 | Input | 省市级别 |
| 现住址 | Input | 详细地址 |
| 户籍地址 | Input | 户口所在地 |
| 紧急联系人 | Input | 紧急联络人姓名 |
| 紧急联系电话 | Input | 紧急联络人手机号 |
| 照片 | ImageUpload | maxNumber: 1,支持裁剪 |
工作信息表单:
| 字段 | 组件 | 说明 |
|---|---|---|
| 入职部门 | DeptSelectModal | 弹窗选择部门,自动回填部门名称和公司信息 |
| 所属公司 | 自动回填 | 沿部门树向上查找 orgType === '1' 的公司节点 |
| 岗位 | Input | 具体岗位名称 |
| 职务 | Input | 管理职务 |
| 职称 | Input | 专业技术职称 |
| 人员状态 | Select | 默认"试用期",可选正式/实习/临时 |
| 试用期(月) | InputNumber | 填写后自动推算预计转正日期 |
| 入职日期 | DatePicker | 必填 |
| 预计转正日期 | DatePicker | 由 entryDate + probationPeriod 自动计算,也可手动修改 |
| 薪资 | InputNumber | 税前月薪 |
| 工资开户行 | Input | 银行名称 |
| 工资卡号 | Input | 银行账号 |
| 备注 | Textarea | 补充说明 |
三张可编辑子表:
| 子表 | 可编辑列 | 操作 |
|---|---|---|
| 工作经历 | 开始时间(DatePicker)、结束时间(DatePicker)、单位名称(Input)、职务(Input) | 新增行 / 删除行 |
| 教育经历 | 开始时间(DatePicker)、结束时间(DatePicker)、学校名称(Input)、专业(Input) | 新增行 / 删除行 |
| 家属信息 | 姓名(Input)、关系(Input)、手机(Input)、工作单位(Input) | 新增行 / 删除行 |
子表使用 Ant Design Table 组件配合 h(DatePicker) / h(Input) 渲染行内可编辑单元格。流程审批通过后页面进入只读模式,隐藏操作列和新增按钮。
附件区域:AttachmentList 组件,最多上传 10 个文件,单文件不超过 20MB,支持常见文档和图片格式。
3.3 部门选择与公司回填
入职部门使用 DeptSelectModal 弹窗选择,选中部门后触发两个联动操作:
- 部门名称回填:将选中部门的
id和name填入empDeptId/empDeptName - 公司自动推算:沿部门树
parentId向上遍历,找到orgType === '1'(公司类型)的节点,回填empCompanyId/empCompanyName
这个设计消除了"员工入职到市场部,结果手动选了总部公司"的人工失误,公司信息由组织架构树形结构自动推导。
3.4 BPM 流程集成
入职单详情页根据 processStatus 动态控制交互模式:
| processStatus | 页面状态 | 可用操作 |
|---|---|---|
| 无/草稿 | 可编辑 | 保存、提交审批 |
| 审批中(RUNNING) | 只读 | 撤回 |
| 已通过(APPROVE) | 只读 | 查看关联的员工档案 |
| 已拒绝(REJECT) | 可编辑 | 修改后重新提交 |
审批组件嵌入在详情页底部,审批人可以直接在入职单详情页内完成审批操作(通过/拒绝/退回/加签),无需跳转到独立的审批页面。
四、流程设计:BPM 驱动的审批与自动建档
4.1 流程编排
入职登记使用流程定义 Key hr_employee_entry_bill,在 Flowable 中配置审批流程:

发起(HR专员)→ 部门主管审批 → HR经理审批 → 通过 ↓ 拒绝 ↓ 拒绝 退回修改 退回修改
流程变量中携带入职单的关键信息,支持根据入职部门、薪资等级等条件走不同审批分支。提交时额外传入 `BpmProcessVariableConstants.CAUSE` = `"{姓名}入职申请"`,审批人在待办列表即可看到申请摘要。
### 4.2 FlowBillService 回调机制
入职单的 Service 实现 `FlowBillService` 接口,BPM 引擎在流程状态变更时自动回调 `updateProcessStatus` 方法:
```java
@Override
@Transactional(rollbackFor = Exception.class)
public void updateProcessStatus(String businessKey, Integer status) {
Long id = Long.parseLong(businessKey);
validateEmployeeEntryBillExists(id);
EmployeeEntryBillDO updateObj = new EmployeeEntryBillDO();
updateObj.setId(id);
updateObj.setProcessStatus(status);
// 审批通过时自动创建员工档案
if (APPROVE.getStatus().equals(status)) {
createEmployeeFromEntryBill(id);
}
employeeEntryBillMapper.updateById(updateObj);
}
核心设计:updateProcessStatus 是 BPM 框架与业务模块之间的标准契约——BPM 引擎只需要传入 businessKey(入职单 ID)和 status(流程状态),具体的业务逻辑(如自动建档)由业务模块自行实现。这种回调机制让 BPM 引擎与业务完全解耦。
4.3 审批即建档:createEmployeeFromEntryBill
这是入职管理最核心的创新——审批通过的瞬间,系统自动将入职单的全部数据迁移到员工档案体系:
createEmployeeFromEntryBill 的执行流程:
- 根据入职单 ID 查询入职单主表 + 3 张子表的完整数据
- 构建
EmployeeSaveReqVO,映射基本信息、工作信息、经历信息 - 根据
entryDate+probationPeriod自动推算formalDate(转正日期) - 使用
TenantUtils.execute确保多租户安全隔离 - 调用
employeeService.createEmployeeArchive()创建正式员工档案 - 将返回的
employeeId回写到入职单,建立入职单与档案的关联
转正日期自动推算:如果入职日期是 2026-04-01、试用期 3 个月,系统自动计算 formalDate = 2026-07-01。HR 不再需要手动计算,消除人为错误。
多租户安全:建档操作通过 TenantUtils.execute 包裹,确保在正确的租户上下文中创建员工档案——这对 SaaS 多租户部署至关重要,防止 A 公司的入职单在 B 公司创建了员工档案。
五、后端核心实现
5.1 单据编号生成
入职单的编号遵循 RuoYi Office 统一的单据编号框架:
HR201-YYYYMMDD00001
│ │ │
│ │ └── 5位每日流水号(自动递增)
│ └── 日期
└── SystemEnum.HRM(code="HR") + HrmBillTypeEnum.HRM_EMPLOYEE_ENTRY_BILL(typeCode="201")
编号在保存和提交时按需生成——如果 billCode 为空,调用 BillCodeUtils.generateBillCode 自动分配:
if (StringUtils.isBlank(saveReqVO.getBillCode())) {
saveReqVO.setBillCode(BillCodeUtils.generateBillCode(
SystemEnum.HRM, HrmBillTypeEnum.HRM_EMPLOYEE_ENTRY_BILL));
}
5.2 唯一性校验
validateMobileAndIdCardUnique 在保存和提交时都会执行,通过手机号 + 身份证号双重校验防止重复入职。校验范围覆盖员工档案表——因为已入职的员工信息在档案中,而非入职单中:
private void validateMobileAndIdCardUnique(EmployeeEntryBillSaveReqVO saveReqVO) {
// 检查手机号在员工档案中是否已存在
// 检查身份证号在员工档案中是否已存在
// 排除自身记录(编辑场景)
}
为什么不检查入职单表?因为入职单审批通过后就会创建员工档案,真正的"在职人员"数据在档案表中。只查档案表就能覆盖所有已入职的员工。
5.3 保存逻辑
保存操作不触发审批流程,仅持久化入职单数据(草稿状态),支持反复修改:
public Long saveEmployeeEntryBill(EmployeeEntryBillSaveReqVO saveReqVO) {
if (StringUtils.isBlank(saveReqVO.getBillCode())) {
saveReqVO.setBillCode(BillCodeUtils.generateBillCode(
SystemEnum.HRM, HrmBillTypeEnum.HRM_EMPLOYEE_ENTRY_BILL));
}
validateMobileAndIdCardUnique(saveReqVO);
EmployeeEntryBillDO entryBill = BeanUtils.toBean(
saveReqVO, EmployeeEntryBillDO.class);
employeeEntryBillMapper.insertOrUpdate(entryBill);
saveDetailLists(entryBill.getId(), saveReqVO);
if (saveReqVO.getAttachments() != null) {
attachmentService.saveAttachmentList(
HrmBillTypeEnum.HRM_EMPLOYEE_ENTRY_BILL.getTypeCode(),
entryBill.getId(), saveReqVO.getAttachments());
}
return entryBill.getId();
}
insertOrUpdate 实现了新建和编辑的统一处理——有 id 则更新,无 id 则插入。saveDetailLists 内部对工作经历、教育经历、家属信息三张子表执行"先删后插"的全量替换策略。
5.4 提交逻辑
提交在保存的基础上额外执行两件事:将流程状态设为 RUNNING,发起 BPM 审批流程:
public Long submitEmployeeEntryBill(EmployeeEntryBillSaveReqVO saveReqVO) {
if (StringUtils.isBlank(saveReqVO.getBillCode())) {
saveReqVO.setBillCode(BillCodeUtils.generateBillCode(
SystemEnum.HRM, HrmBillTypeEnum.HRM_EMPLOYEE_ENTRY_BILL));
}
validateMobileAndIdCardUnique(saveReqVO);
EmployeeEntryBillDO entryBill = BeanUtils.toBean(
saveReqVO, EmployeeEntryBillDO.class)
.setProcessStatus(BpmTaskStatusEnum.RUNNING.getStatus());
employeeEntryBillMapper.insertOrUpdate(entryBill);
saveDetailLists(entryBill.getId(), saveReqVO);
// 构建流程变量并发起审批
Map<String, Object> processInstanceVariables =
BpmProcessVariableUtils.buildBillVariables(saveReqVO);
processInstanceVariables.put(
BpmProcessVariableConstants.CAUSE,
entryBill.getName() + "入职申请");
String processInstanceId = processInstanceApi.submitProcessInstance(
Long.valueOf(saveReqVO.getCreator()),
new BpmProcessInstanceCreateReqDTO()
.setProcessDefinitionKey(HrmBillTypeEnum
.HRM_EMPLOYEE_ENTRY_BILL.getProcessDefinitionKey())
.setVariables(processInstanceVariables)
.setBusinessKey(String.valueOf(entryBill.getId()))
).getCheckedData();
employeeEntryBillMapper.updateById(new EmployeeEntryBillDO()
.setId(entryBill.getId())
.setProcessInstanceId(processInstanceId));
if (saveReqVO.getAttachments() != null) {
attachmentService.saveAttachmentList(
HrmBillTypeEnum.HRM_EMPLOYEE_ENTRY_BILL.getTypeCode(),
entryBill.getId(), saveReqVO.getAttachments());
}
return entryBill.getId();
}
设计要点:
- 流程变量传递:通过
buildBillVariables将入职单字段打包为流程变量,审批流程中可基于部门、薪资等级等变量走不同分支 - CAUSE 摘要:
"{姓名}入职申请"作为流程摘要,审批人在待办列表一眼就能看到是谁的入职申请 - processInstanceId 回写:BPM 流程创建成功后将流程实例 ID 写回入职单,建立单据与流程的双向关联
5.5 删除级联清理
删除入职单时需要同步清理 BPM 流程实例、附件和三张子表,保持数据一致性:
@Transactional(rollbackFor = Exception.class)
public void deleteEmployeeEntryBill(Long id) {
EmployeeEntryBillDO entryBill = validateEmployeeEntryBillExists(id);
// 1. 清理 BPM 流程实例
if (entryBill.getProcessInstanceId() != null) {
processInstanceApi.cancelProcessInstance(
entryBill.getProcessInstanceId(), "删除入职单");
}
// 2. 清理附件
attachmentService.deleteAttachmentList(
HrmBillTypeEnum.HRM_EMPLOYEE_ENTRY_BILL.getTypeCode(), id);
// 3. 清理三张子表
workExperienceMapper.deleteByEntryBillId(id);
educationMapper.deleteByEntryBillId(id);
familyMapper.deleteByEntryBillId(id);
// 4. 删除主表
employeeEntryBillMapper.deleteById(id);
}
六、RuoYi Office 创新设计
6.1 审批即建档——零人工干预的数据迁移
传统入职流程:填入职表 → 提交审批 → 审批通过 → HR 手动到档案系统再录一遍 → 遗忘/出错。
RuoYi Office 方案:填入职表 → 提交审批 → 审批通过 → 系统自动创建员工档案。
createEmployeeFromEntryBill 在 updateProcessStatus 回调中自动执行,将入职单的全部数据(主表 30+ 字段 + 3 张子表)一键迁移到员工档案体系。HR 不需要做任何额外操作——审批的那一刻,新员工的档案就已经建好了。
6.2 1 主表 + 3 子表——完整的人员信息采集
入职登记不只是基本信息——工作经历反映候选人的职业路径,教育经历反映学术背景,家属信息用于紧急联络和福利管理。这些"一对多"信息用 3 张子表独立存储,与主表通过 entry_bill_id 关联,审批通过后完整迁移到员工档案的对应子表中。
6.3 手机号 + 身份证号双重唯一性校验
判断"同一个人"不能靠姓名(同名概率高),必须用不可变的唯一标识。RuoYi Office 在保存和提交时都执行双重校验:手机号查一遍员工档案表、身份证号再查一遍。校验对象是档案表而非入职单表——因为已入职人员的最终数据在档案中。
6.4 多租户安全建档
SaaS 多租户场景下,BPM 回调可能发生在系统级上下文中(非用户请求线程),此时租户信息可能丢失。createEmployeeFromEntryBill 使用 TenantUtils.execute 显式指定租户 ID,确保档案创建在正确的租户数据库中——这个细节容易被忽略,一旦出错会导致 A 公司的入职单在 B 公司创建了员工。
6.5 转正日期自动推算
入职日期 + 试用期月数 = 预计转正日期。createEmployeeFromEntryBill 在建档时自动计算:
if (entryBill.getEntryDate() != null && entryBill.getProbationPeriod() != null) {
LocalDate formalDate = entryBill.getEntryDate()
.plusMonths(entryBill.getProbationPeriod());
employeeSaveReqVO.setFormalDate(formalDate);
}
HR 填写入职日期 2026-04-01 和试用期 3 个月,系统自动推算转正日期 2026-07-01,消除人工计算的出错风险。
七、数据结构
7.1 表结构:hrm_employee_entry_bill(入职登记主表)
| 字段 | 类型 | 说明 |
|---|---|---|
id | bigint | 主键 |
bill_code | varchar(50) | 单据编号(HR201-YYYYMMDD00001) |
process_instance_id | varchar(64) | BPM 流程实例ID |
process_status | tinyint | 流程状态(草稿/审批中/已通过/已拒绝) |
name | varchar(100) | 姓名 |
sex | tinyint | 性别(1男 2女) |
birthday | date | 出生日期 |
id_card | varchar(18) | 身份证号 |
mobile | varchar(20) | 手机号 |
email | varchar(100) | 邮箱 |
nation | varchar(50) | 民族 |
native_place | varchar(200) | 籍贯 |
political_status | varchar(50) | 政治面貌 |
marital_status | varchar(50) | 婚姻状况 |
household_address | varchar(500) | 户籍地址 |
current_address | varchar(500) | 现住址 |
emergency_contact | varchar(100) | 紧急联系人 |
emergency_phone | varchar(20) | 紧急联系电话 |
avatar | varchar(500) | 照片 |
entry_date | date | 入职日期 |
probation_period | int | 试用期(月) |
expected_formal_date | date | 预计转正日期 |
emp_dept_id | bigint | 入职部门ID |
emp_dept_name | varchar(200) | 入职部门名称(冗余) |
emp_company_id | bigint | 入职公司ID |
emp_company_name | varchar(200) | 入职公司名称(冗余) |
job_post | varchar(100) | 岗位 |
job_position | varchar(100) | 职务 |
job_title | varchar(100) | 职称 |
employee_status | tinyint | 人员状态(1正式 2试用 3实习 5临时) |
education | varchar(50) | 学历 |
salary | decimal(10,2) | 薪资 |
bank_name | varchar(200) | 工资开户行 |
bank_account | varchar(50) | 工资卡号 |
employee_id | bigint | 关联员工档案ID(审批通过后回写) |
dept_id | bigint | 创建人部门ID |
dept_name | varchar(200) | 创建人部门名称 |
company_id | bigint | 创建人公司ID |
company_name | varchar(200) | 创建人公司名称 |
creator_name | varchar(100) | 创建人姓名 |
remark | varchar(500) | 备注 |
7.2 表结构:hrm_employee_entry_bill_work_experience(工作经历)
| 字段 | 类型 | 说明 |
|---|---|---|
id | bigint | 主键 |
entry_bill_id | bigint | 入职登记单ID(外键) |
start_time | date | 开始时间 |
end_time | date | 结束时间 |
company_name | varchar(200) | 单位名称 |
job_position | varchar(100) | 职务 |
7.3 表结构:hrm_employee_entry_bill_education(教育经历)
| 字段 | 类型 | 说明 |
|---|---|---|
id | bigint | 主键 |
entry_bill_id | bigint | 入职登记单ID(外键) |
start_time | date | 开始时间 |
end_time | date | 结束时间 |
school_name | varchar(200) | 学校名称 |
major | varchar(200) | 专业 |
7.4 表结构:hrm_employee_entry_bill_family(家属信息)
| 字段 | 类型 | 说明 |
|---|---|---|
id | bigint | 主键 |
entry_bill_id | bigint | 入职登记单ID(外键) |
name | varchar(100) | 姓名 |
relationship | varchar(50) | 与本人关系 |
mobile | varchar(20) | 联系电话 |
work_unit | varchar(200) | 工作单位 |
7.5 设计要点
- 冗余存储:主表冗余了
empDeptName、empCompanyName、creatorName等字段,列表展示不需要 JOIN 其他表,历史数据不受部门改名影响 - 入职单 vs 档案分表:入职单是"待审批数据",档案是"已确认数据"。分表后入职单可以自由修改、退回、重提交,不会污染正式的员工档案
- employeeId 回写:审批通过自动建档后,将档案 ID 回写到入职单的
employee_id字段,建立入职单与档案的双向追溯关系 - 子表结构对齐:入职单的 3 张子表字段与员工档案的 3 张子表完全对齐,建档时直接字段映射,无需额外转换
八、技术亮点总结
| 设计要点 | 实现方式 | 价值 |
|---|---|---|
| 审批即建档 | FlowBillService.updateProcessStatus 中调用 createEmployeeFromEntryBill | 审批通过自动创建员工档案,零人工干预 |
| 1主表+3子表 | 入职单独立建表,子表结构与档案子表对齐 | 完整人员信息一次采集,建档时直接迁移 |
| HR201编号 | BillCodeUtils.generateBillCode 统一框架 | 系统级 + 类型级 + 日期 + 流水号,编号可追溯 |
| 双重唯一性校验 | 手机号 + 身份证号查询员工档案表 | 防止同一人重复入职,比姓名判重更可靠 |
| 转正日期自动推算 | entryDate.plusMonths(probationPeriod) | 消除 HR 手动计算的出错风险 |
| 多租户安全建档 | TenantUtils.execute 包裹建档逻辑 | SaaS 场景下确保档案建在正确的租户中 |
| 先删后插子表 | deleteByEntryBillId + 循环 insert | 子表数据量小,全量替换比差异对比更简单可靠 |
| 流程变量传递 | buildBillVariables + CAUSE 摘要 | 审批流程可基于变量走分支,待办列表显示摘要 |
| 部门树公司回填 | 沿 parentId 向上查找 orgType=1 节点 | 自动推导所属公司,消除人工选择失误 |
| 删除级联清理 | BPM流程 + 附件 + 3子表 + 主表一起清理 | 数据一致性,无孤儿记录 |
| processStatus驱动 | 页面根据流程状态自动切换编辑/只读模式 | 审批中不可改、拒绝后可改,状态驱动交互 |
| 入职单与档案追溯 | employeeId 回写到入职单 | 从入职单可追溯到档案,从档案可回查入职记录 |
九、快速体验
在线演示(无需安装,即刻体验全部功能):
- 🌐 地址:ruoyioffice.com/web/
- 👤 账号:admin
- 🔑 密码:admin123
操作路径:HRM 人力资源 → 员工管理 → 员工入职
推荐体验流程:
- 新建入职单:进入入职登记列表,点击「新建」,进入入职登记详情页
- 填写基本信息:输入姓名、性别、手机号、身份证号、民族、学历等基本信息,上传照片
- 选择入职部门:点击入职部门的弹窗按钮,选择一个部门,观察公司名称自动回填
- 填写工作信息:输入岗位、试用期月数、入职日期,观察预计转正日期自动计算
- 录入经历信息:展开工作经历、教育经历、家属信息三个区域,逐行录入
- 保存草稿:点击「保存」,观察系统自动生成 HR201 开头的单据编号
- 提交审批:点击「提交」,入职单进入审批流程,页面变为只读模式
- 审批通过:切换到审批人账号,在待办列表中找到入职申请并通过
- 验证建档:回到入职单详情,确认已关联员工档案ID;到员工档案列表中查看自动创建的档案
源码仓库:
| 平台 | 地址 |
|---|---|
| GitCode(后端) | gitcode.com/zhouzhongya… |
| GitCode(前端) | [gitcode.com/zhouzhongya…https://gitcode |
