三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

业务系统接审批流别再到处写 if else:用开源 BPM 引擎跑通表单、待办和申请记录

业务系统接审批流别再到处写 if else:用开源 BPM 引擎跑通表单、待办和申请记录

业务系统里最容易变复杂的模块之一,就是审批。

最开始可能只是一个请假审批:

员工提交 -> 主管审批 -> 结束

后来加了采购审批:

申请人提交 -> 部门负责人审批 -> 财务审批 -> 总经理审批

再后来又有合同审批、报销审批、工单流转、用章审批、付款审批。每个流程都有不同的表单、审批人、按钮、退回逻辑、状态展示和消息提醒。

如果每个业务模块都自己写一套审批逻辑,代码很快会变成这样:

if 金额小于 5000,主管审批 if 金额大于 5000,经理审批 if 是合同,走法务 if 是采购,走采购负责人 if 是报销,走财务

短期能上线,长期很难维护。流程一改,业务代码就要改;审批人一变,系统就要发版;按钮权限一调整,前后端都要跟着动。

这也是为什么很多业务系统需要把审批能力抽成流程引擎。

1. 审批流不应该绑死在业务模块里

比较理想的拆分是:

职责
业务表单保存请假单、采购单、合同单等业务数据
BPM 流程引擎负责流程定义、节点流转、待办任务、流程状态
业务回调在流程前后校验和同步业务状态
前端运行入口提供发起流程、我的待办、我的申请等统一入口

这样做以后,业务模块不需要自己造一套待办中心,流程引擎也不需要理解每张业务表的所有字段。

Open BPM Flow Engine 这次整理开源时,重点就是把这条链路补齐。

项目地址:

https://gitee.com/luotianding/open-project

2. 一个业务审批的最小闭环

业务系统接审批流,至少需要下面 6 步:

步骤动作
1配置流程图
2配置流程关联业务表单
3用户填写业务单据
4调用流程发起接口
5审批人进入我的待办办理
6流程回调业务服务,同步业务状态

Open BPM Flow Engine 里提供的请假 Demo,就是为了演示这个闭环。

正文配图建议:

3. 业务表单怎么和流程关联

流程引擎不应该写死“请假表单”“采购表单”“合同表单”。更好的方式是通过配置把流程和表单关联。

示例配置:

配置项示例
流程 Key`demo_leave_process`
流程名称`演示请假审批流程`
发起表单地址`/demo/leave-form`
回调类`cn.icepanda.bpm.demo.service.DemoLeaveFlowService`

这样发起页只需要读取已发布流程,再根据流程读取对应表单地址。

前端逻辑可以理解为:

用户打开发起流程页 -> 查询可发起流程 -> 读取流程关联表单 -> 跳转到业务表单

如果业务系统要二次开发接入,可以照着这个清单走:

开发对象采购审批示例说明
业务表`purchase_apply`保存采购金额、供应商、原因、业务状态、流程实例 ID
后端实体`PurchaseApply`映射采购业务表
后端接口`PurchaseApplyController`提供草稿、发起前保存、详情、待办上下文、列表
业务服务`PurchaseApplyServiceImpl`保存业务单、查业务单、同步流程状态
流程回调`PurchaseFlowService``before` 校验金额,`after` 同步审批状态
前端表单`PurchaseForm.vue`支持发起、办理、查看三种模式
前端路由`/demo/purchase-form`要和流程关联业务里的表单地址一致
流程配置`purchase_approval`配流程图、节点处理人、按钮和回调类

普通开发者可以先不管复杂组织架构,先按“固定审批人或固定流程角色”跑通。等流程闭环跑通后,再逐步接部门负责人、岗位、角色、金额条件和消息通知。

4. 业务状态怎么同步

流程状态和业务状态不是一回事。

流程状态关注的是:

当前节点是谁 任务有没有办 流程有没有结束 流程有没有退回

业务状态关注的是:

请假单是草稿还是审批中 合同是待审还是已通过 采购单是否允许下单 报销单是否允许付款

所以项目里用业务回调类做状态同步。

请假 Demo 的回调类:

@Service public class DemoLeaveFlowService implements BpmBizInvoke<DemoLeaveApply> { public BpmResult before(FlowContext context, DemoLeaveApply apply) { if (apply == null) { return BpmResult.failure("请假申请数据不能为空"); } if (apply.getDays() == null || apply.getDays() <= 0) { return BpmResult.failure("请假天数必须大于 0"); } return BpmResult.success(); } public BpmResult after(FlowContext context, DemoLeaveApply apply) { return BpmResult.success(leaveApplyService.syncByFlowCallback(context, apply)); } }

业务系统只关心自己的业务校验和状态同步,流程推进由 BPM 引擎完成。

5. 我的待办和我的申请为什么重要

很多业务系统刚开始只做“提交审批”,但没有统一待办。审批人只能从消息里找链接,或者回到业务列表里筛选待处理数据。

这会带来几个问题:

1. 审批人不知道自己还有多少任务没处理。

2. 发起人不知道流程走到哪一步。

3. 管理员不知道流程卡在哪个节点。

4. 多个业务模块各自实现待办,体验不统一。

所以开源版提供:

/#/runtime/myTask 我的待办 /#/runtime/myApply 我的申请 /#/runtime/taskPool 任务池 /#/runtime/myDeliver 我的抄送

正文配图建议:

6. 适合接哪些业务

这类流程引擎适合:

业务示例流程
请假审批员工 -> 主管
采购审批申请人 -> 部门 -> 财务 -> 总经理
合同审批业务 -> 法务 -> 财务 -> 负责人
报销审批员工 -> 主管 -> 财务
工单流转客服 -> 技术 -> 复核
用章审批申请人 -> 部门 -> 行政

如果你的业务有“多人协作、状态流转、审批留痕、节点权限”,都可以考虑抽成流程。

7. 开源项目能提供什么

Open BPM Flow Engine 当前提供:

1. 流程设计器。

2. 流程定义管理。

3. 流程属性配置。

4. 发起流程入口。

5. 我的待办。

6. 我的申请。

7. 任务池。

8. 我的抄送。

9. 流程实例和任务监控。

10. 请假申请 Demo。

11. MySQL 初始化脚本。

12. 图文说明文档。

它适合作为学习、二次开发和项目选型参考,不建议不改造就直接用于复杂生产场景。

二次开发时建议按这个顺序落地:

先接一个最简单的业务单 -> 再加一个审批节点 -> 再加一个条件网关 -> 再加角色和人员规则 -> 再加审批意见和流程轨迹 -> 最后接消息通知和组织架构

不要一上来就把所有复杂规则都放进去。流程系统最怕“第一版就想做成万能平台”,这样很容易把业务表、流程表、权限表和消息表缠在一起。

完整二次开发指南:

bpm-project/docs/secondary-development-guide.md

接口清单和关键代码索引:

bpm-project/docs/api-and-code-map.md

如果企业准备基于这套开源项目做二次开发,可以按 4 个阶段落地:

阶段目标验收方式
第一阶段本地启动后端、前端和数据库能访问流程设计器、发起流程、我的待办
第二阶段跑通请假 Demo能完成“发起 -> 待办 -> 办理 -> 我的申请”
第三阶段新增一个真实业务,例如采购审批有采购表、采购表单、采购接口、采购回调
第四阶段接组织、角色、消息和流程监控审批人规则、提醒、追踪、异常处理符合企业规则

这个路线的好处是每一步都能验证,不会陷入“先搭一个大平台,最后发现闭环没跑通”的问题。

8. 总结

审批流的本质不是“某个页面上多一个同意按钮”,而是把业务状态和流程状态连接起来。

如果业务系统里审批越来越多,不要继续在各个模块里复制 if else。更合理的方式是抽出统一流程引擎,让业务模块只关心业务数据,让 BPM 引擎处理流程流转。

项目地址:

https://gitee.com/luotianding/open-project

关键词:BPM流程引擎、工作流引擎、Flowable、Spring Boot工作流、业务审批、OA审批、表单流转。

← 返回列表