Warm-Flow工作流引擎入门:比Flowable轻量在哪

背景

去年用一个人+AI给公司搭内部管理平台的时候,技术选型卡在工作流引擎上。请假、报销、招待费这些审批流程是刚需,绕不开。

一开始看的是Flowable,毕竟是Activiti原班人马做的,社区活跃、功能齐全。但研究了几天后我放弃了------一个简单的请假审批要搞懂几十张表、BPMN 2.0规范、各种部署模式,学习成本太高了。我只有一个人,没人能分担,时间上耗不起。

后来在Gitee上找国产方案,发现了Warm-Flow。试了一下,半天跑通了第一个流程。这篇聊聊我的选型思路和实际使用经验。

先看对比:7张表 vs 几十张表

Flowable完整部署后会创建将近80张表,就算精简版也有40多张。这些表覆盖流程定义、运行时实例、历史数据、身份管理、任务分配等方方面面。功能确实强大,但对于大多数审批场景来说太臃肿了。

Warm-Flow只有 7张核心表:

表 用途
flow_definition 流程定义(名称、编码、版本、定义JSON)
flow_node 流程节点(开始、中间节点、网关、结束)
flow_skip 节点跳转关系(通过/驳回的流转路径)
flow_instance 流程实例(谁发起的、当前走到哪了)
flow_task 审批任务(当前待审人、审批结果)
flow_his_task 历史任务(审批轨迹回溯)
flow_user 用户(参与流转的人员,可选)

7张表,表名见名知意。相比之下Flowable的ACT_RU_EXECUTION、ACT_HI_IDENTITYLINK、ACT_GE_BYTEARRAY这些表名,没学过BPMN规范的话根本不知道是干嘛的。

表少的直接好处是维护成本低。 数据出了问题不用在几十张表里来回查,7张表的关系一两分钟就能理清。

其他维度的对比

学习曲线: Flowable需要理解BPMN 2.0标准(事件子流程、补偿边界事件、调用活动等概念),API层叠复杂。Warm-Flow只暴露5个Service(DefService、InsService、TaskService、NodeService、HisTaskService),命名方式跟Spring一贯风格一致,上手快很多。

集成方式: Flowable需要独立部署或者嵌入应用,配置一堆Environment和Engine。Warm-Flow一个Maven依赖加几行配置就启动了。

中国特色审批: 转办、委派、加签、减签、任意跳转------这些国产OA常见的操作,Warm-Flow直接封装好了。Flowable需要自己基于API二次开发。

信创适配: 如果甲方要求国产数据库(达梦、人大金仓、OceanBase),Warm-Flow原生支持,Flowable需要自己搞适配。

前端设计器: Flowable的官方UI还是AngularJS写的,前端得基于bpmn-js自己画。Warm-Flow自带Vue设计器,支持经典流程图和仿钉钉两种模式,Jar包直接引入就能用。

一句话总结:追求BPMN标准、复杂流程选Flowable;中小企业审批、快速交付选Warm-Flow。

快速上手三步

1. Maven依赖

xml 复制代码
<dependency>
    <groupId>org.dromara.warm</groupId>
    <artifactId>warm-flow-mybatis-plus-sb-starter</artifactId>
    <version>1.8.0</version>
</dependency>

我项目用的是MyBatis-Plus,如果你用JPA也有对应的starter,官方都提供了。

2. 配置

yaml 复制代码
warm-flow:
  enabled: true
  banner: true
  ui: true
  key_type: SnowId19
  logic_delete: true
  data_source_type: mysql

再写个权限处理器,告诉引擎当前用户是谁:

kotlin 复制代码
@Configuration
public class WarmFlowConfig {
    @Bean
    public PermissionHandler permissionHandler() {
        return () -> SecurityContextHolder.getCurrentUserId();
    }
}

3. 跑通第一个流程

Warm-Flow的流程定义用JSON,这点比Flowable的XML友好得多:

arduino 复制代码
// 导入流程定义
String json = """
{
    "flowName": "请假审批",
    "flowCode": "leaveFlow",
    "version": "1",
    "nodeList": [
        {"nodeType":0, "nodeCode":"start", "nodeName":"开始"},
        {"nodeType":1, "nodeCode":"deptLeader", "nodeName":"部门经理审批"},
        {"nodeType":2, "nodeCode":"end", "nodeName":"结束"}
    ],
    "skipList": [
        {"nowNodeCode":"start", "nextNodeCode":"deptLeader", "skipType":"PASS"},
        {"nowNodeCode":"deptLeader", "nextNodeCode":"end", "skipType":"PASS"}
    ]
}""";
​
Definition def = defService.importJson(json);
defService.publish(def.getId());
​
// 启动流程
Instance ins = insService.start("业务ID", FlowParams.builder()
    .flowCode("leaveFlow")
    .handler("currentUserId")
    .build());
​
// 审批通过
taskService.pass(ins.getCurrentTaskId(), "同意", null);

基本用法就这么点。从引入依赖到跑通,不踩坑的话两个小时够了。

实战:监听器改造做节点级追踪

说回我那个项目。Warm-Flow本身只管流转,但业务侧需要追踪"每个节点谁审的、什么结果、卡在哪了"。我在监听器上做了扩展。

设计思路

审批链路是:部门经理 → 总监 → 财务。每一步可能是单个人,也可能多人会签。需要一张辅助表记录每个节点的审批明细:

sql 复制代码
CREATE TABLE approval_task_relation (
    id BIGINT PRIMARY KEY,
    instance_id BIGINT NOT NULL COMMENT '流程实例ID',
    task_id BIGINT COMMENT '任务ID',
    node_name VARCHAR(64) COMMENT '节点名称',
    node_code VARCHAR(64) COMMENT '节点编码',
    approver VARCHAR(64) COMMENT '审批人',
    status VARCHAR(16) DEFAULT 'pending' COMMENT 'pending/pass/reject',
    is_latest TINYINT DEFAULT 1 COMMENT '是否最新节点',
    remark VARCHAR(500) COMMENT '审批意见',
    create_time DATETIME,
    update_time DATETIME
);

NodeCreate监听器

节点创建时触发,注入审批人信息:

  • 解析当前节点配置的审批人(部门负责人/指定人/角色)
  • 向approval_task_relation插入记录
  • 把上一步的is_latest翻转为0
less 复制代码
@Component("nodeCreateApprovalListener")
public class NodeCreateApprovalListener implements Listener {
    @Override
    public void notify(ListenerVariable var) {
        Instance ins = var.getInstance();
        Node node = var.getNode();
​
        // 解析审批人------可能是指定人、部门负责人、角色
        List<String> approvers = resolveApprovers(node);
​
        for (String approver : approvers) {
            // 插入审批记录
            approvalTaskRelationService.save(new ApprovalTaskRelation()
                .setInstanceId(ins.getId())
                .setNodeName(node.getNodeName())
                .setNodeCode(node.getNodeCode())
                .setApprover(approver)
                .setStatus("pending")
                .setIsLatest(1));
        }
​
        // 翻转上一步的is_latest
        approvalTaskRelationService.flipLatest(ins.getId());
    }
}

NodeFinish监听器

节点完成时触发,更新审批结果。驳回时触发生成流程通知:

java 复制代码
@Component("nodeFinishApprovalListener")
public class NodeFinishApprovalListener implements Listener {
    @Override
    public void notify(ListenerVariable var) {
        Task task = var.getTask();
        String result = task.getResult(); // "PASS" or "REJECT"
​
        approvalTaskRelationService.updateStatus(
            task.getInstanceId(), task.getNodeCode(),
            result.equals("PASS") ? "pass" : "reject",
            task.getRemark()
        );
​
        if ("REJECT".equals(result)) {
            // 推送驳回通知,通知发起人
            notificationService.sendRejectNotice(task);
        }
    }
}

在JSON里绑定:

json 复制代码
{"nodeCode":"deptLeader", "nodeName":"部门经理审批",
 "listenerType":"CREATE", "listener":"nodeCreateApprovalListener"},
{"nodeCode":"deptLeader", "listenerType":"FINISH",
 "listener":"nodeFinishApprovalListener"}

这样任何时刻查approval_task_relation表就能看到:谁在哪个节点做了什么操作、当前卡在哪里、历史轨迹全量保留。

踩过的一个坑

Warm-Flow的def_json字段默认长度可能不够。复杂流程(多节点多网关)生成的JSON会很长,如果数据库字段是VARCHAR(2000)级别,导入时会被截断,然后流程跑一半报错。

解决: 检查数据库flow_definition表的def_json字段,至少设成TEXT类型,复杂流程用MEDIUMTEXT。

另外从1.7.0版本开始,Warm-Flow废弃了XML流程定义,统一用JSON。如果你看到网上旧教程还在讲XML,直接跳过不用管。

总结

Warm-Flow适合的场景很明确:中小型项目的审批流程,团队人少,追求快速交付。 它不是Flowable的替代品(复杂BPMN场景还是Flowable),但在它的目标场景里,体验确实比Flowable好得多。

如果你也在做类似的项目------内部管理系统、OA审批、报销流程------不妨试试。半天能跑通,比纠结Flowable的几十张表划算。


我在GitHub/Gitee上开源了一套完整的SpringBoot企业级项目,包含Warm-Flow的实际应用代码。感兴趣可以访问:gitee.com/yao113088/j...

相关推荐
愚农搬码2 天前
Flowable 工作流中如何接入大模型 LLM 节点
llm·ai编程·工作流引擎
愚农搬码8 天前
Flowable工作流引擎如何适配国产数据库?以达梦数据库举例说明
工作流引擎
songgeb8 天前
mspec体验:基于SDD的轻量AI工作流
ai编程·工作流引擎
大龄码农有梦想8 天前
企业工作流系统如何设计用户、部门、角色、岗位、动态关系五类流程办理人?
工作流引擎·flowable·流程引擎·oa·工作流系统·选人规则·bpm平台
愚农搬码11 天前
工作流里的转办、委托和工作移交的业务语义与技术实现
工作流引擎
大龄码农有梦想11 天前
工作流中的子流程节点能否驳回到父流程?
工作流引擎·流程引擎·oa·bpm·子流程·驳回·退回
愚农搬码12 天前
工作流中的子流程节点能否驳回到父流程?
工作流引擎
愚农搬码12 天前
流程图上的回退线与运行时动态回退,应该选择哪一种?
工作流引擎
大龄码农有梦想12 天前
开源流程引擎 Camunda 如何实现任意节点跳转?
工作流引擎·流程引擎·camunda·oa·bpn·流程跳转·会签
愚农搬码15 天前
在开源流程引擎 Flowable 里如何实现任意节点跳转?
工作流引擎