构建可视化审批工作流引擎
每个 ERP 最终都需要审批:超限采购单、价格折扣、工单下达、红字发票。买一套完整 BPM 套件太重;为每个场景手写 if (amount > 50000) sendTo(manager) 又烂得很快。中间路线是一个带可视化设计器的小型工作流引擎。本文介绍我们搭建的模型——刻意务实。
砍需求
忍住打造通用 BPM 引擎的冲动。根据我们的经验,ERP 里的审批流恰好只需要四种节点:
- 开始 / 结束——定义图的起点和终点。
- 审批——分配给某人或某角色(部门经理、财务主管)的任务,带超时和升级路径。
- 条件——针对单据字段的布尔表达式(金额、部门、物料类别),决定走哪条分支。
- 会签组——多个审批人,与模式(全部通过)或或模式(第一人定夺)。
四种节点覆盖了我们见过的几乎所有真实审批。任何更花哨的东西——循环、子流程、消息事件——正是通用 BPM 工具把 80% 的复杂度预算花在 5% 的价值上的地方。
定义、版本与实例
流程定义是一张带版本的图:节点、边、每节点配置。实例是绑定到具体业务单据(采购单、折扣申请)的一次运行。保证安全的规则:
- 定义发布后不可变。修改已发布的流程产生新版本。
- 实例绑定启动时所处的定义版本并存快照。v3 启动的流程在 v4 发布后仍按 v3 跑完——在途单据的规则绝不静默变化。
- 只有一个版本是新实例的默认版本;旧版本随其实例自然完结而退役。
实例状态机
实例状态模型要简单到令人尴尬。每个实例有一个当前节点;每个节点任务有 pending / approved / rejected 状态。迁移规则:
- 启动 → 创建首个节点任务,按节点配置分配(角色解析在分配时刻发生——职位空缺不会无声卡死流程,会升级)。
- 审批人操作 → 任务完结,引擎评估该节点的完成规则(会签模式、投票阈值)。
- 按顺序求值出边条件,选出下一节点。
- 拒绝 → 实例进入终态
REJECTED,可选"重新提交"路径重启流程。 - 没有下一节点 →
APPROVED,引擎触发业务模块监听的事件。
每个动作——分配、通过、拒绝、升级——都是实例上一条 append-only 的日志记录。经理看到的审批轨迹就是这条日志的渲染;审计证据也是它。
与业务模块集成
引擎拥有编排,从不拥有业务数据。业务模块把流程挂到某类单据上,订阅 APPROVED / REJECTED 事件。这让引擎成为模块化单体中的纯组件:销售、采购、生产、财务共用同一个引擎,而引擎不需要知道"销售订单"是什么。超时和升级由一个定时清扫器驱动,扫描超过期限的待办任务。
可视化设计器
设计器是画布:顾问拖四种节点、连线、在侧栏配置每个节点。底层编辑的就是引擎执行的那份 JSON 图——没有模型到模型的翻译。发布前的校验检查无聊但致命的问题:不可达节点、没有 else 分支的条件、没有分配人的审批节点。画布保持简单(网格吸附、直线连边)就好——你画的是审批链,不是电路板。同样高密度的企业界面渲染技巧,见企业级 Web 界面模式。
结语
工作流引擎的价值恰恰在于它比人们预想的更小:四种节点、不可变的带版本定义、逐节点状态机、append-only 动作日志、基于事件的集成。把这些做好,ERP 里所有现在和未来的审批都从代码变成配置。