开源 HRM 人事系统选型避坑:6 模块 23 单据,员工全生命周期一张图打通
📦 RuoYi Office · 一个平台,管好整个企业
🌐 文档地址:ruoyioffice.com | 📦 源码1:gitcode.com/zhouzhongya… | 📦 源码2:gitcode.com/zhouzhongya… | 📦 源码3:github.com/yuqing2026/…
你一定在 GitHub、Gitee 搜过「开源 HRM」。搜出来的结果无非三类:单表 Demo(就一张员工表 + 增删改查)、教学项目(只有前端界面没有流程)、停更多年(Spring Boot 1.x、Vue 2、提交停留在 2020)。真正敢让你上生产的,一只手数得过来。
人力资源管理的难点,从来不在"把员工名单存下来",而在:员工从候选人到离职归档的每一次身份变化,都要有单据、要走审批、要落档案、要联动考勤和假期。任何一个环节断档,HR 就得在 Excel 和系统之间来回搬运数据。
本文以 RuoyiOffice 开源 HRM 为样本,拆解一个真正能跑起来的开源人事系统长什么样——从 6 大业务模块、23+ 单据、8 张审批表、3 个定时任务,到 BPM 驱动的全流程闭环设计。

▲ RuoyiOffice 开源 HRM 全景:招聘 → 入职 → 在职 → 调转 → 薪酬 → 离职,数据不落地、流程不断档
引言:开源 HRM 的 5 个真实坑
如果你正在为团队选型一个开源人事系统,这几个坑大概率绕不开:
| 坑 | 真实表现 | 后果 |
|---|---|---|
| 只做 CRUD | 员工、部门、岗位三张表,连入职单都没有 | 上线当天就要自己二开 |
| 没有审批流 | 请假/转正/调动全靠钉钉,数据对不上 | HR 做报表要跨系统抓数据 |
| 假期硬编码 | 年假=5天,写死在 if 里 | 老员工/高级别员工的差异化规则改不了 |
| 只有 PC 端 | 手机上请假看不到余额、批不了单 | 移动办公需求直接落空 |
| 技术栈老旧 | Spring Boot 1.x、Vue 2、Element UI 1 | 招不到愿意维护的程序员 |
HRM 不是"员工名单管理系统",它是以员工为主体、以单据为载体、以流程为纽带的生命周期档案平台。选开源 HRM,本质上是在选一套可二次开发的企业级人事底座。
本文要回答的问题是:一套可以直接投产的开源 HRM 应该具备哪些能力?架构上怎么设计?流程和数据如何打通?
一、员工全生命周期:6 阶段一张图
人事管理的核心是员工身份随时间的变化。一个员工进入企业到离开,会经历 6 个阶段,每个阶段都对应不同的单据和档案操作:
| # | 阶段 | 典型动作 | 涉及单据/档案 | 面向角色 |
|---|---|---|---|---|
| 1 | 招聘前置 | 招聘需求、职位发布、候选人入库、面试评估、Offer 发放 | 招聘需求单、面试反馈、Offer 单 | HR / 用人部门 |
| 2 | 入职管理 | 入职申请、BPM 多级审批、自动建档、生成系统账号、分配角色岗位 | 入职单、员工档案、系统用户 | HR / IT |
| 3 | 在职管理 | 考勤打卡(GPS/内网)、请假 / 销假、假期余额账户、补卡申请、加班调休 | 考勤记录、请假单、余额账本 | 全员 |
| 4 | 人事异动 | 转正、部门/岗位调动、薪资档案变更、计薪规则调整 | 转正单、调动单、薪资单 | HR / 部门负责人 |
| 5 | 薪资发放 | 薪资档案、计薪规则、工资条发放、个税、社保公积金 | 薪资单、工资发放台账 | HR / 财务 |
| 6 | 离职归档 | 离职申请、交接清单、BPM 审批、账号停用、档案归档 | 离职单、交接单、归档记录 | HR / 直属主管 |
这 6 个阶段看似独立,其实有两条隐藏主线贯穿始终:
- 主线 1 · 单据驱动档案:每一次身份变化都先有"单据"、再影响"档案"。没有单据的档案修改是不可追溯的,这是企业合规的基础。
- 主线 2 · 流程驱动联动:入职通过了,才能自动建档和开通系统账号;离职通过了,才能停用账号、计算期末假期余额。这需要 BPM 引擎作为"业务回调中心"。
📌 一句话总结:HRM = 员工生命周期单据化 × BPM 流程联动 × 档案自动沉淀。
二、系统架构:为什么是 6 模块 + BPM 内核
很多人做 HRM 喜欢按"功能清单"切模块——"员工管理、考勤管理、假期管理、薪资管理"。这种切法没错,但忽略了最关键的一层:所有单据都要走审批流,审批状态变更要触发业务动作。RuoyiOffice 把 HRM 设计成 6 大模块 + 1 个 BPM 内核的结构:
▲ 员工档案列表:支持按部门/岗位/状态筛选,字段可配置、导出导入
2.1 核心模块矩阵
| 模块 | 关键表 | 核心单据 | 定时任务 |
|---|---|---|---|
| 员工档案 | hrm_employee、hrm_employee_leave_setting | — | — |
| 入职管理 | hrm_entry_bill、hrm_entry_bill_item | 员工入职单 | — |
| 在职管理 | hrm_attendance、hrm_leave_cancel_bill | 考勤记录、请假/销假单 | 考勤异常检测、假期到期清理 |
| 人事异动 | hrm_transfer_bill、hrm_confirm_bill | 转正单、调动单 | — |
| 假期管理 | hrm_leave_type、hrm_leave_scheme、hrm_leave_account、hrm_leave_ledger | 假期类型、部门方案、员工账户、余额流水 | 年度发放、到期清零 |
| 离职归档 | hrm_resignation_bill | 离职单、交接清单 | 账号停用检查 |
2.2 核心设计决策
| 决策点 | 方案 | 理由 |
|---|---|---|
| 单据与审批的耦合方式 | FlowBillService 回写 | 单据不直接依赖 BPM API,由回调机制驱动,方便解耦测试 |
| 假期规则的配置粒度 | 部门方案 + 员工个性化 + JSON 规则继承 | 集团企业各部门年假规则差异化,员工入职工龄带入 |
| 考勤数据的存储 | 按日预生成 + 实时打卡回填 | 查询性能高,支持月/周/日多粒度统计 |
| 金额/天数精度 | BigDecimal + 统一 scale(1) | 假期半天、加班 0.5 天等场景,避免浮点误差 |
| 前端表单架构 | Vben Admin + form-create 动态表单 | 入职/转正等单据字段经常变,动态渲染降低二开成本 |
| 移动端策略 | UniApp 同构页面 | APP 只维护列表/详情/新建,PC 负责配置与报表,成本可控 |
| 审批流模型 | Flowable 7 + BPMN 2.0 | 国际标准,社区活跃,国内落地案例最多 |
2.3 技术底座
| 技术项 | 选型 | 说明 |
|---|---|---|
| 后端 | Spring Boot 3.5 + Java 17 | LTS 版本,支持单体/微服务双模式 |
| ORM | MyBatis-Plus + MyBatis-Plus-Join | 单表 CRUD 零 SQL,多表联查方便 |
| 工作流 | Flowable 7 | BPMN 2.0 企业级引擎 |
| 权限 | Spring Security + OAuth2 + 数据权限注解 | RBAC + 部门隔离 + 多租户 |
| 定时任务 | XXL-Job | 假期年度发放、到期清零、考勤异常检测 |
| PC 前端 | Vue 3 + Vben Admin 5 + Ant Design Vue | Monorepo + TypeScript + Vite |
| 移动端 | UniApp + Vue 3 + wot-design-uni | 一套代码 H5/小程序/APP 三端 |
| 数据库 | MySQL 8.0+(PostgreSQL 可切换) | 支持主流企业数据库 |
三、PC 端核心功能
3.1 员工档案:9 大信息域 + 动态扩展
员工档案是 HRM 的主数据表。RuoyiOffice 把员工档案切分为 9 个信息域:
- 基础信息:姓名、工号、性别、证件、手机号、邮箱
- 组织信息:所属公司/部门/岗位、直属上级、上级部门
- 雇佣信息:雇佣类型、入职日期、转正日期、试用期、合同起止
- 学历信息:最高学历、毕业院校、专业、毕业时间
- 银行信息:开户行、银行卡号(AES 加密)
- 社保公积金:参保地、缴费基数、个人/公司比例
- 假期设置:工龄起算日、总工龄、年假奖励天数
- 紧急联系人:关系、姓名、手机
- 附件档案:身份证、合同、毕业证、简历等扫描件
所有字段都支持表单配置化——企业可以按需调整字段顺序、必填、是否脱敏,不用改代码。
3.2 入职管理:从 Offer 到系统账号

▲ 员工入职单:填写一次信息,审批通过后自动建档、生成账号、分配角色
入职单是 HRM 里联动最多的单据。一个入职单通过后会触发:
- 在
hrm_employee表中自动建档,带上完整字段 - 在
system_users表中生成系统账号,默认密码策略 - 根据岗位自动分配 RBAC 角色(例如销售岗 → CRM 销售角色)
- 初始化假期账户(年假按工龄算、事假/病假按部门方案)
- 触发入职通知(发给部门负责人 + IT + 行政)
这里的核心是 FlowBillService 的回调机制——BPM 审批通过时,由 HRM 模块的 EntryBillFlowBillServiceImpl 统一处理下游动作:
@Service
public class EntryBillFlowBillServiceImpl implements FlowBillService {
@Override
@Transactional(rollbackFor = Exception.class)
public void updateFlowStatus(BpmProcessInstanceStatusEvent event) {
Long billId = Long.valueOf(event.getBusinessKey());
EntryBillDO bill = entryBillMapper.selectById(billId);
if (BpmProcessInstanceStatusEnum.APPROVE.getStatus().equals(event.getStatus())) {
EmployeeDO employee = employeeService.createByBill(bill);
Long userId = userService.createByEmployee(employee);
employeeService.bindUserId(employee.getId(), userId);
leaveBalanceService.initAccountsForEmployee(employee);
bill.setStatus(BillStatusEnum.APPROVED.getStatus());
} else if (BpmProcessInstanceStatusEnum.REJECT.getStatus().equals(event.getStatus())) {
bill.setStatus(BillStatusEnum.REJECTED.getStatus());
}
entryBillMapper.updateById(bill);
}
}
3.3 考勤打卡:PC + APP 双端
考勤是典型的双端差异化场景:

- PC 端:主要是配置(班次、排班、规则)和报表(部门考勤统计、异常列表)

- APP 端:主要是执行(打卡、补卡申请、查看本月考勤)
RuoyiOffice 的考勤打卡支持两种模式:
| 模式 | 场景 | 技术实现 |
|---|---|---|
| GPS 围栏 | 外勤、多地办公 | 前端获取 GPS → 后端判断是否在部门坐标的半径内 |
| 内网 IP | 总部统一打卡 | 后端校验请求 IP 是否在白名单 |
考勤异常(迟到/早退/缺卡)会自动生成补卡建议,员工在 APP 上一键提交补卡申请,走 BPM 审批。
3.4 人事异动:转正 / 调动
转正单和调动单是变更型单据,设计要点是"快照 + 差异":
- 快照:记录变更前的部门、岗位、薪资
- 差异:高亮展示变更后的字段
- 生效时间:支持立即生效或定时生效(例如 2026-05-01 部门调整)
- 级联影响:调动会触发假期方案重算(不同部门的假期方案不同)、薪资档案变更
3.5 离职归档:倒推检查清单
离职单是归档型单据,设计核心是"检查清单"——不能让员工走了之后还留着系统漏洞:
- 系统账号停用 / 账号退出登录
- 办公用品归还(联动 OA 办公用品模块)
- 借用资产归还(联动资产管理模块)
- 知识文档交接 / 云盘权限回收
- 客户 / 项目交接(联动 CRM)
- 假期账户期末结算
- 档案归入离职档案库(保留 N 年)
四、BPM 流程联动:HRM 的神经中枢

很多 HRM 系统做不大,本质上是流程引擎太弱。RuoyiOffice 把 Flowable 7 作为 HR 单据的统一审批底座,所有单据(入职/转正/调动/离职/请假/销假/补卡)都走同一套 BPM 机制:
4.1 FlowBillService 统一回调
public interface FlowBillService {
/** 单据类型标识 */
String getBillType();
/** 审批状态变更时的业务回调 */
@Transactional(rollbackFor = Exception.class)
void updateFlowStatus(BpmProcessInstanceStatusEvent event);
/** 供 BPM 表单渲染的单据详情 */
Map<String, Object> getBillDetail(String businessKey);
}
每个 HR 单据(入职/转正/离职/请假/销假)都实现这个接口。BPM 引擎审批完成后,发出 BpmProcessInstanceStatusEvent 事件,对应的 FlowBillService 实现类负责写档案、建账号、扣余额等业务动作。
这种设计的好处是:
- BPM 模块不感知 HRM 业务细节,解耦干净
- 新增单据类型只需实现一个接口,扩展简单
- 审批状态和业务状态分离,易于测试和补偿
4.2 定时任务驱动周期性动作
| 任务 | 调度 | 作用 |
|---|---|---|
LeaveAnnualGrantJob | 每年 1 月 1 日 00:00 | 按部门方案和工龄发放全员年假 |
LeaveExpireClearJob | 每日凌晨 | 清理过期未使用的假期余额 |
AttendanceAbnormalJob | 每日 10:00 | 检测前日考勤异常,推送补卡建议 |
五、数据结构(核心表)
5.1 员工档案 hrm_employee(字段节选)
| 字段 | 类型 | 说明 |
|---|---|---|
id | bigint | 主键 |
employee_no | varchar(32) | 工号(租户内唯一) |
name | varchar(64) | 姓名 |
dept_id | bigint | 所属部门 |
position_id | bigint | 岗位 |
entry_date | date | 入职日期 |
confirm_date | date | 转正日期 |
employee_status | tinyint | 雇佣状态:0 试用 / 1 正式 / 2 离职 |
user_id | bigint | 关联 system_users.id,部分字段空 = 未开账号 |
tenant_id | bigint | 多租户 ID |
5.2 入职单 hrm_entry_bill(字段节选)
| 字段 | 类型 | 说明 |
|---|---|---|
id | bigint | 主键 |
bill_code | varchar(64) | 单据编号(按规则生成) |
candidate_name | varchar(64) | 候选人姓名 |
dept_id | bigint | 拟入职部门 |
position_id | bigint | 拟入职岗位 |
expected_entry_date | date | 预计入职日 |
process_instance_id | varchar(64) | 关联 BPM 流程实例 |
status | tinyint | 单据状态:0 草稿 / 10 审批中 / 20 通过 / 30 拒绝 |
employee_id | bigint | 审批通过后生成的员工 ID |
5.3 离职单 hrm_resignation_bill(字段节选)
| 字段 | 类型 | 说明 |
|---|---|---|
id | bigint | 主键 |
employee_id | bigint | 离职员工 |
resignation_type | tinyint | 离职类型:主动 / 辞退 / 协商 |
resignation_date | date | 离职日期 |
handover_user_id | bigint | 交接人 |
handover_checklist | json | 交接清单(JSON 数组) |
process_instance_id | varchar(64) | 关联 BPM 流程实例 |
status | tinyint | 单据状态 |
六、RuoyiOffice HRM 的 5 个差异化设计
6.1 单据 + 档案双表设计
大多数开源 HRM 直接把"员工信息"写到一张表里——转正就 UPDATE 一下 confirm_date。RuoyiOffice 坚持"任何档案变更都要有单据":
- 转正 → 生成
hrm_confirm_bill→ 审批通过 → 更新hrm_employee.confirm_date - 调动 → 生成
hrm_transfer_bill→ 审批通过 → 更新hrm_employee.dept_id - 离职 → 生成
hrm_resignation_bill→ 审批通过 → 更新hrm_employee.employee_status
价值:所有档案变更都可审计、可回滚、可追溯——这是企业合规的底线。
6.2 假期规则的 3 层继承
很多系统的假期规则写死在代码里。RuoyiOffice 采用 3 层继承结构:
- 第 1 层 · 假期类型主数据:年假、事假、病假、婚假、产假、陪产假、丧假、调休(全局统一)
- 第 2 层 · 部门方案:每个部门可以有自己的方案,继承上级部门或租户默认方案
- 第 3 层 · 员工个性化:工龄起算日、年假奖励天数、特殊配额
三层叠加后,最终每个员工都有一套个性化的假期规则,且可以 JSON 配置、不用改代码。
6.3 三端同构的 UniApp 移动端
PC 端用 Vue 3 + Vben Admin,移动端用 UniApp + Vue 3,同一套类型定义和 API 层。这意味着:
- 后端 DTO 改了字段,前端双端同时得到 TypeScript 类型提示
- 小程序和 APP 共用一份代码,不用两套人维护
- HR 可以 PC 批量操作,员工在手机上审批/打卡
6.4 多租户 + 数据权限
- 多租户:一套系统同时服务多家子公司,数据严格隔离
- 数据权限:部门负责人只能看自己部门的员工和单据,HRBP 按条线授权
这两个能力基于 RuoYi-Vue-Pro 的底座,HRM 模块不需要重复实现。
6.5 AI 能力挂载点
HRM 是企业 AI 落地最容易出效果的场景之一:
- AI 写 Offer:把岗位说明书 + 薪酬档 → Offer 信
- AI 审简历:简历 → 结构化信息入候选人库
- AI 员工问答:员工手册 + 考勤规则 → AI 助手答疑
- AI 生成 OKR:岗位目标 → 季度 OKR 草稿
RuoyiOffice 已经内置 Spring AI,可以直接接入 DeepSeek / 通义千问 / 智谱等模型,不用从零搭 RAG 和 MCP。
七、技术亮点总结
| 设计要点 | 实现方式 | 价值 |
|---|---|---|
| 单据化档案 | 所有变更都先走 BPM 单据 | 可审计、可追溯、合规 |
| BPM 统一审批 | Flowable 7 + BPMN 2.0 + FlowBillService | 业务扩展零侵入 |
| 假期 3 层继承 | 主数据 → 部门方案 → 员工个性化 + JSON 规则 | 差异化配置不改代码 |
| 假期账本流水 | account + ledger 分离 + 5 种变动类型 | 数据一致、可追溯 |
| PC + APP 三端 | Vben Admin + UniApp + 同构 API 层 | 一次开发多端发布 |
| 定时任务 | XXL-Job 调度年度发放/到期清零/异常检测 | 无需人工干预 |
| 多租户 + 数据权限 | RuoYi-Vue-Pro 基座 | 集团多组织开箱即用 |
| AI 挂载点 | Spring AI 多模型适配 | Offer/简历/问答/OKR 即开即用 |
八、快速体验路径
| 路径 | 操作 | 预期结果 |
|---|---|---|
| 1 | 登录 → HRM · 组织管理 · 组织信息 | 看到公司/部门/岗位树 |
| 2 | HRM · 员工管理 · 员工档案 | 查看员工列表、筛选、导出 |
| 3 | HRM · 员工关系 · 入职管理 | 新建入职单,提交 BPM 审批 |
| 4 | BPM · 审批中心 · 我的待办 | 看到上一步的待审批单 |
| 5 | 审批通过后,回到员工列表 | 看到新员工自动建档 |
| 6 | HRM · 假期 · 余额查询 | 看到该员工的年假/事假余额 |
| 7 | HRM · 考勤 · 规则设置 | 查看部门打卡规则和班次 |
| 8 | 切到 APP 端登录 | 首页看到 |