驰骋BPM四大流程模式与Flowable-Camunda对比选型指南

线性到父子流程:驰骋 BPM 四大流程模式源码解读,及与 Flowable/Camunda 的选型指南

导读

在企业 OA、ERP 审批、项目管理等场景中,线性审批只是起点。真正考验工作流引擎的,是:

  • 一笔采购拆成多部门并行处理(分合流
  • 各部门填同一张表还是各自独立表单
  • 主流程等待子项目、子合同子流程结束再继续

驰骋 BPM(CCFlow / JFlow)将上述能力抽象为四大流程运行模式,并在 WorkNode.NodeSend()5×5 路由算法中落地。Flowable / Camunda 则用 BPMN 2.0 的 Parallel Gateway、Multi-Instance、Call Activity 等标准元素实现类似能力。

本文从源码出发,对照 Flowable/Camunda 架构,梳理前后端实现、优劣势,并给出倾向选择 CCFlow/JFlow 的选型结论。


一、概念澄清:驰骋的「四大流程模式」是什么?

驰骋在节点级别通过 RunModel(运行模式)和 NodeType(节点类型)描述流程拓扑,面向业务人员的四大模式如下:

业务名称引擎标识RunModel 值核心含义
线性流程Ordinary0串行审批,一步接一步
同表单分合流SubThreadSameWorkID4分流后多子线程共享主表数据(FID 关联)
异表单分合流SubThreadUnSameWorkID5分流后各子线程独立表单 / 独立 WorkID
父子流程SubFlowNodeNodeType=3主流程嵌入子流程,支持手动/自动/延续

说明:引擎内部还有 分流(FL)合流(HL)分合流(FHL) 三种路由节点形态(RunModel 1/2/3),它们是实现「分合流」的拓扑基础,与上述四大模式配合使用,而非并列的第四种业务形态。

枚举定义(后端):

    /// <summary>
    /// 运行模式
    /// </summary>
    public enum RunModel
    {
        Ordinary = 0,          // 普通/线性
        HL = 1,                // 合流
        FL = 2,                // 分流
        FHL = 3,               // 分合流
        SubThreadSameWorkID = 4, // 同表单子线程
        SubThreadUnSameWorkID = 5 // 异表单子线程
    }

    public enum NodeType
    {
        UserNode = 0,
        RouteNode = 1,
        CCNode = 2,
        SubFlowNode = 3,       // 子流程节点
    }

前端流程设计器(FlowDesignerV2)将上述模式映射为可拖拽图元:

设计器图元mode 值形状
线性0矩形
分流2下宽梯形
合流1上宽梯形
分合流3六角形
同表单4梯形变体
异表单5梯形变体
子流程NodeType=3独立图元

二、四大模式技术实现(驰骋源码)

2.1 总体执行架构

驰骋流程发送的核心入口是 WorkNode.NodeSend(),采用三阶段处理:

  1. 发送前检查:权限、表单、条件
  2. 5×5 路由算法:按源节点 RunModel × 目标节点 RunModel 分支
  3. 发送后业务:抄送、子流程、事件、数据汇总
        /// 1,方法体分为三大部分: 发送前检查\5*5算法\发送后的业务处理.

关键实例字段:

字段含义
WorkIDWF_GenerWorkFlow流程实例主键
FID同上父流程 WorkID(子线程挂接干流程)
PWorkID / PFlowNo / PNodeID同上父子流程关联
FK_Node同上当前停留节点
IsPassWF_GenerWorkerList待办完成状态

④ 父子流程

等待

主流程节点

子流程节点

子流程实例

③ 异表单分合流

分流点

异表单线程+独立WorkID

异表单线程+独立WorkID

合流点

② 同表单分合流

分流点 FL

同表单线程1

同表单线程2

合流点 HL

① 线性流程

节点A

节点B

节点C


2.2 模式一:线性流程(Ordinary)

业务特征

最常见的串行审批:发起 → 部门审批 → 领导审批 → 归档。

后端实现
  • 节点 HisRunModel = OrdinaryHisNodeWorkType = Work(或 StartWork
  • 发送时走 NodeSend_11():计算下一节点 → FindWorker 找人 → 写 GenerWorkerList 待办
            switch (this.HisNode.HisRunModel)
            {
                case RunModel.Ordinary:
                    Node toND = this.NodeSend_GenerNextStepNode();
                    ...
                    switch (toND.HisRunModel)
                    {
                        case RunModel.Ordinary:
                            this.NodeSend_11(toND);
                            break;
对比 Flowable / Camunda
驰骋Flowable/Camunda
NodeSend_11 串行推进Sequence Flow 顺序流
WF_Cond 方向条件Exclusive Gateway 或 Sequence Flow 条件表达式
GenerWorkerList 单人待办ACT_RU_TASK User Task

两者在线性场景能力相当;Flowable 以 BPMN 图表达,驰骋以 WF_Node + WF_Direction 关系表表达。


2.3 模式二:同表单分合流(SubThreadSameWorkID)

业务特征

一张主表(如采购申请单),按明细行或按部门拆成多条并行子线程,各线程处理人不同,但共享同一份主表数据,合流后继续主流程。

典型场景:采购明细按供应商分给不同采购员并行询价,合流后统一审批。

后端实现

拓扑要求:分流点(FL/FHL)→ 同表单子线程节点 → 合流点(HL/FHL)

FID 机制:子线程 Work.FID = 干流程 WorkID,多个子线程共享数据上下文。

        /// 处理分流点向下发送 to 同表单.
        private void NodeSend_24_SameSheet(Node toNode)
        {
            Work wk = toNode.HisWork;
            wk.Copy(this.rptGe);
            wk.Copy(this.HisWork);
            wk.FID = this.WorkID; // 把该工作FID设置成干流程上的工作ID
            town = new WorkNode(wk, toNode);
            current_gwls = this.Func_GenerWorkerLists(town);

找人策略DeliveryWay)支持:

  • ByDtlAsSubThreadEmps:按上一节点明细表字段确定子线程接收人
  • BySQLAsSubThreadEmpsAndData:按 SQL 确定接收人与子线程数据

前端配置入口:Vue3/src/WF/Admin/AttrNode/AccepterRole/GPE_AccepterRole.ts

对比 Flowable / Camunda
驰骋同表单分合流Flowable/Camunda 等价物
FID 共享主表Multi-Instance 同一变量作用域
NodeSend_24_SameSheetParallel Gateway + Multi-Instance User Task(sequential=false
明细表驱动子线程Multi-Instance collection 表达式(如 ${detailList}
合流等待全部完成Parallel Gateway Join(默认全部到达)

差异:驰骋将「同表单 + FID」作为一等公民,表单引擎 Sys_MapData 原生识别 FID 字段;Flowable 需自行设计流程变量与表单绑定,明细表驱动多实例需额外开发。


2.4 模式三:异表单分合流(SubThreadUnSameWorkID)

业务特征

分流后各子线程使用不同表单(甚至不同 WorkID),并行处理后合流。例如:项目立项后,技术、财务、法务各自填独立审批表

后端实现

核心方法 NodeSend_24_UnSameSheet(Nodes toNDs)

  • 为每个子线程节点创建独立 GenerWorkFlow 实例
  • USSWorkIDRole 控制 WorkID 生成规则:
    • 0:同一节点仅生成一个 WorkID(多人共享)
    • 1:按接收人各生成一个 WorkID
  • 子线程通过 FID 关联干流程
        /// 处理分流点向下发送 to 异表单.
        private void NodeSend_24_UnSameSheet(Nodes toNDs)
        {
            GenerWorkFlows gwfThreads = new GenerWorkFlows();
            gwfThreads.Retrieve(GenerWorkFlowAttr.FID, this.WorkID);
            ...
                if (nd.USSWorkIDRole == 0)
                {
                    ...
                    if (workIDSubThread == 0)
                        workIDSubThread = DBAccess.GenerOID("WorkID");

发送时 FID/WorkID 切换逻辑(子线程 ↔ 合流点):

            // 是否是分流到子线程
            if (this.HisNode.ItIsFLHL == true && town.HisNode.ItIsSubThread == true)
            {
                nextUsersWorkID = 0;
                nextUsersFID = this.WorkID;
            }
            // 子线程到合流点
            if (this.HisNode.ItIsSubThread == true && town.HisNode.ItIsFLHL == true)
            {
                nextUsersWorkID = this.HisWork.FID;
                nextUsersFID = 0;
            }
对比 Flowable / Camunda
驰骋异表单分合流Flowable/Camunda
每子线程独立 Sys_MapData 表单每分支独立 User Task + 独立 Form Key
USSWorkIDRole 控制实例粒度Multi-Instance 或多次 Call Activity
NodeSend_24_UnSameSheetParallel Gateway + 多个并行 User Task
合流后数据汇总 CheckFrmHuiZongToDtl需 ExecutionListener 手动聚合变量

差异:驰骋在合流点内置异表单向合流节点明细表的数据汇总CheckFrmHuiZongToDtl);Flowable/Camunda 无内置表单汇总,需自定义 Listener 或外部服务。


2.5 模式四:父子流程(SubFlowNode)

业务特征

主流程某一节点触发完整子流程,子流程结束后父流程才继续。支持:

子流程类型SubFlowType说明
手动子流程HandSubFlow用户选择启动
自动子流程AutoSubFlow到达节点自动触发
延续子流程YanXuFlow子流程结束后回到父流程指定节点
子流程层级SubFlowModel说明
下级子流程SubLevelPWorkID 指向父流程 WorkID
同级子流程SameLevel与父流程共享上级上下文
    public enum SubFlowModel
    {
        SubLevel,   // 下级
        SameLevel,  // 同级
    }
后端实现

子流程启动(WF_WorkOpt.SubFlowGuid_Send):

        public void SendSingleSubFlow(SubFlowHand subFlowH, Hashtable ht, GenerWorkFlow gwf)
        {
            if (subFlowH.SubFlowModel == SubFlowModel.SubLevel)
                workidSubFlow = BP.WF.Dev2Interface.Node_CreateBlankWork(..., this.WorkID, this.FID, ...);
            if (subFlowH.SubFlowModel == SubFlowModel.SameLevel)
                workidSubFlow = BP.WF.Dev2Interface.Node_CreateBlankWork(..., gwf.PWorkID, gwf.PFID, ...);
            BP.WF.Dev2Interface.SetParentInfo(subFlowH.SubFlowNo, workidSubFlow, ...);
            BP.WF.Dev2Interface.Node_SendWork(subFlowH.SubFlowNo, workidSubFlow);

父流程等待规则(SubFlowRunModel):子流程全部结束 / 到达指定节点后,父流程才发送。

子流程启动后,父流程当前待办可设为不可见(IsPass=80),用户从在途查看进度。

对比 Flowable / Camunda
驰骋父子流程Flowable/Camunda
SubFlowNode + SubFlowHand 配置Call ActivityEmbedded Sub-Process
PWorkID / PFlowNo / PNodeIDsuperProcessInstanceId(历史表)
手动/自动/延续三种类型Call Activity 的 async、触发器配置
子流程数据反填父流程 BackCopyRole需 Output Mapping / 变量传递
父流程待办隐藏需自行实现或 BPMN Event Sub-Process

差异:驰骋父子流程与表单数据反填规则BackCopyRole:自动字段匹配、按格式匹配、混合模式)深度集成;Flowable Call Activity 只做流程层面嵌套,业务数据回填需额外开发。


三、四大模式与 Flowable/Camunda 对照总表

维度驰骋 BPMFlowableCamunda
建模标准自研节点表 + 设计器BPMN 2.0 XMLBPMN 2.0 XML
线性流程Ordinary + NodeSend_11Sequence FlowSequence Flow
并行分合流FL/HL/FHL + 5×5 算法Parallel GatewayParallel Gateway
同表单多实例SubThreadSameWorkID + FIDMulti-Instance(共享作用域)Multi-Instance
异表单多实例SubThreadUnSameWorkID多 User Task 并行多 User Task 并行
子流程SubFlowNode(手动/自动/延续)Call ActivityCall Activity
明细表驱线程ByDtlAsSubThreadEmps 内置collection 表达式collection 表达式
合流数据汇总CheckFrmHuiZongToDtl 内置无,需 Listener无,需 Listener
子流程数据反填BackCopyRole 内置变量映射变量映射
流程轨迹WF_Track + ActionType 分流/合流/子线程ACT_HI_ACTINSTOperate 历史
表单引擎Sys_MapData 内置无(外部集成)无(外部集成)

四、前端代码结构梳理

4.1 技术栈

Vue 3 + Vite + TypeScript + Ant Design Vue + AntV X6(流程设计器)

4.2 与四大模式相关的前端模块

模块路径职责
流程设计器 V2Vue3/src/WF/Admin/FlowDesignerV2/拖拽创建线性/分流/合流/同表单/异表单/子流程节点
图元定义FlowDesignerV2/shapes/index.tsmode: 0~5 对应 RunModel
节点属性WF/Admin/AttrNode/找人策略、子线程规则、子流程配置
流程办理WF/MyFlow.vueMyFlowGener.vue传递 WorkIDFIDPWorkID
审核轨迹WF/WorkOpt/WorkCheckParseTrack.vue展示分流前进/合流前进/子线程前进
子流程操作WF/WorkOpt/子流程发起、删除草稿
嵌入 SDKToolkit/WorkOpt/第三方系统嵌入分合流审批
移动端CCMobile/MyFlow*.vue移动端办理

4.3 设计器如何落地 RunModel

设计器保存节点时写入 RunModel 字段,与后端 WF_Node.RunModel 一致:

// FlowDesignerV2/shapes/index.ts
{ label: '线性', attrs: { typeInfo: { mode: 0 } } }
{ label: '分流', attrs: { typeInfo: { mode: 2 } } }
{ label: '合流', attrs: { typeInfo: { mode: 1 } } }
{ label: '同表单', attrs: { typeInfo: { mode: 4 } } }
{ label: '异表单', attrs: { typeInfo: { mode: 5 } } }

4.4 办理页 FID 传递

分流场景下,前端需正确传递 FID(干流程)与 WorkID(子线程):

            if ((currND.HisRunModel == RunModel.FL || currND.HisRunModel == RunModel.FHL) && this.FID != 0)
                urlExt += "WorkID=" + this.FID + "&SubWorkID=" + this.WorkID;

审核轨迹前端区分动作类型:

  • ActionType.ForwardFL — 分流前进
  • ActionType.ForwardHL — 合流前进
  • ActionType.SubThreadForward — 子线程前进

4.5 前后端通信

统一通过 HttpHandler 调用后端 Handler:

const handler = new HttpHandler('BP.WF.HttpHandler.WF_MyFlow');
handler.AddPara('WorkID', workID);
handler.AddPara('FID', fid);
const data = await handler.DoMethod('MyFlow_Init');

五、后端代码结构梳理

5.1 项目分层

CCFlow/CCFlow/                          → Web 宿主、API Controller
CCFlow/Components/BP.WF/                → 流程引擎核心
  ├── WF/WorkNode.cs                    → 发送引擎(5×5 算法)
  ├── WF/GenerWorkFlow.cs               → 流程实例
  ├── WF/GenerWorkerList.cs             → 待办任务
  ├── WF/WorkUnSend.cs                  → 撤销/退回
  ├── Template/FindWorker.cs            → 找人(含子线程策略)
  ├── Template/SFlow/                   → 子流程配置
  ├── Dev2Interface.cs                  → 对外 SDK
  └── HttpHandler/WF_MyFlow.cs          → 办理页接口
CCFlow/Components/BP.En30/              → 实体框架、表单引擎

5.2 四大模式关键类与方法

模式核心类/方法数据表
线性WorkNode.NodeSend_11()WF_GenerWorkFlowWF_GenerWorkerList
同表单分合流WorkNode.NodeSend_24_SameSheet()同上 + FID 关联
异表单分合流WorkNode.NodeSend_24_UnSameSheet()WorkID + FID
父子流程WF_WorkOpt.SendSingleSubFlow()PWorkIDPFlowNoPNodeID
合流汇总WorkNode.CheckFrmHuiZongToDtl()合流节点明细表
子流程反填BackCopyRole父流程表单字段

5.3 对外集成 API

方式入口适用
SDKDev2Interface.Node_SendWork()代码集成
RESTAPIController跨语言调用
HttpHandlerWF_MyFlow.MyFlow_Init()Vue 前端

JFlow 侧与 CCFlow 同源设计(类名、方法名、表结构一致),Java 团队可无缝使用相同模式语义。


六、优势与不足

6.1 驰骋 BPM(CCFlow/JFlow)优势

维度说明
四大模式原生支持线性/同表单/异表单/父子流程均为引擎内置路径,非插件
表单 + 流程一体分合流、子流程与 Sys_MapData 表单引擎深度耦合,无需拼装
明细表驱动子线程ByDtlAsSubThreadEmps 一行配置即可按明细拆线程
合流数据自动汇总CheckFrmHuiZongToDtl 异表单向合流节点汇总
子流程数据反填BackCopyRole 自动/按规则/混合反填父流程
5×5 路由算法覆盖普通/分流/合流/子线程任意组合,规则明确
中国式审批特性会签、加签、退回、撤销与子线程/子流程协同
双栈交付CCFlow(.NET) + JFlow(Java),适配不同甲方技术栈
设计器可视化FlowDesignerV2 图元直接对应四大模式,业务人员可理解
BPMN 导入支持从 Flowable 等工具导入 BPMN(单向转换)

6.2 驰骋 BPM 不足

维度说明
非 BPMN 运行时四大模式存于 WF_Node.RunModel,与 BPMN 生态互操作弱
5×5 算法复杂度高WorkNode.cs 逾万行,二次开发需深入理解 FID/WorkID 切换
标准 APIHttpHandler 协议非 RESTful 标准,国际化集成成本高
超大并行度分合流基于 DB 轮询合流条件,极高并发不如事件驱动引擎
文档碎片化四大模式语义需结合源码理解,官方文档不如 Flowable 系统

6.3 Flowable/Camunda 优势

维度说明
BPMN 2.0 标准并行网关、多实例、调用活动均为标准元素,模型可交换
生态成熟Camunda Modeler、Flowable Modeler、大量社区案例
微服务友好引擎轻量,易嵌入 Spring Cloud / K8s
DMN 决策Camunda 支持决策表(驰骋无原生 DMN)
外部任务长耗时异步任务模式成熟

6.4 Flowable/Camunda 不足(相对驰骋四大模式场景)

维度说明
同/异表单分合流需组合 Gateway + Multi-Instance + 表单集成,配置复杂
明细表驱线程无开箱即用,需写 collection 表达式 + 业务表查询
合流数据汇总无内置,需 Listener 开发
子流程数据反填仅变量映射,无表单字段级自动匹配
交付周期从引擎到可上线 OA,需集成表单、组织、权限多个系统

七、如何选择工作流引擎?

7.1 决策矩阵(围绕四大模式)

业务需求推荐理由
简单串行审批三者均可线性模式无本质差异
同一张表按明细/部门并行CCFlow/JFlowSubThreadSameWorkID + 明细表驱线程开箱即用
多部门独立表单并行CCFlow/JFlowSubThreadUnSameWorkID + 合流汇总内置
主流程嵌套子项目流程CCFlow/JFlow手动/自动/延续子流程 + 数据反填
流程即代码、GitOpsFlowable/CamundaBPMN XML 版本管理
百万级实例 / 事件驱动Camunda 8Zeebe 分布式架构
已有 BPMN 资产迁移FlowableBPMN 原生运行时
政府/国企全栈 OACCFlow/JFlow四大模式 + 表单 + 组织一体交付

7.2 决策树

您的流程是否涉及「分流 + 多表单 + 合流汇总」或「父子流程数据反填」?
├── 是 → 强烈推荐 CCFlow / JFlow
│   ├── .NET 技术栈 → CCFlow
│   └── Java 技术栈  → JFlow
└── 否 → 是否以 BPMN 标准 / 微服务编排为核心?
    ├── 是 → Flowable 或 Camunda
    └── 否 → 是否需要完整 OA(表单+组织+权限)?
        ├── 是 → CCFlow / JFlow(BPM 模式)
        └── 否 → 按团队技术栈在 Flowable 与 CCFlow 间选择

7.3 倾向选择 CCFlow / JFlow 的结论

综合源码分析与四大模式对照,在中文企业审批、OA、项目协同场景下,应优先选择 CCFlow / JFlow,理由如下:

  1. 四大模式是引擎内核,不是扩展包
    线性、同表单分合流、异表单分合流、父子流程均有专属发送路径(NodeSend_11 / _24_SameSheet / _24_UnSameSheet / SendSingleSubFlow),落地成本远低于在 Flowable 中拼装 Gateway + Multi-Instance + Call Activity + 自定义 Listener。

  2. 表单是分合流的灵魂
    驰骋 Sys_MapDataFIDPWorkID 原生配合,明细表驱线程、合流汇总、子流程反填均为配置级能力;Flowable/Camunda 无表单引擎,四大模式落地周期通常延长 2~5 倍。

  3. JFlow 与 CCFlow 同源,投资可迁移
    类名、表结构、模式语义一致,.NET 与 Java 项目可共享流程设计经验与实施方法论。

  4. Flowable/Camunda 的适合边界清晰
    当核心诉求是纯 BPMN 编排、微服务 Choreography、超高吞吐、DMN 决策时,选择 Flowable/Camunda;当核心诉求是复杂审批 + 表单 + 中国特色分合流/子流程时,选择驰骋。

  5. 中间件模式降低嵌入门槛
    若只需四大模式中的线性 + 简单并行,可通过 Toolkit SDK 嵌入现有 ERP,无需全盘替换。

一句话结论
「分合流 + 多表单 + 子流程」是中国 OA 的刚需,这是 CCFlow/JFlow 的设计原点,也是 Flowable/Camunda 需要大量定制才能补齐的短板。


八、附录:关键代码索引

主题文件
RunModel 枚举CCFlow/Components/BP.WF/EnumLib.cs
5×5 发送算法CCFlow/Components/BP.WF/WF/WorkNode.cs
同表单分合流WorkNode.NodeSend_24_SameSheet()
异表单分合流WorkNode.NodeSend_24_UnSameSheet()
子流程模型CCFlow/Components/BP.WF/Template/SFlow/FrmSubFlow.cs
子流程发送CCFlow/Components/BP.WF/HttpHandler/WF_WorkOpt.cs
流程办理CCFlow/Components/BP.WF/HttpHandler/WF_MyFlow.cs
找人(子线程)CCFlow/Components/BP.WF/Template/FindWorker.cs
对外 SDKCCFlow/Components/BP.WF/Dev2Interface.cs
设计器图元Vue3/src/WF/Admin/FlowDesignerV2/shapes/index.ts
子线程找人配置Vue3/src/WF/Admin/AttrNode/AccepterRole/GPE_AccepterRole.ts
审核轨迹Vue3/src/WF/WorkOpt/WorkCheckParseTrack.vue
流程办理页Vue3/src/WF/MyFlow.vue

九、参考文献

  • 驰骋 BPM 官网:https://ccbpm.cn/
  • Flowable 用户手册:https://www.flowable.com/open-source/docs/
  • Camunda BPMN 参考:https://docs.camunda.io/
  • BPMN 2.0 规范(并行网关 / 多实例 / 调用活动):https://www.omg.org/spec/BPMN/

本文基于 CCFlowWorkSpace 仓库静态分析生成。JFlow 与 CCFlow 在四大流程模式上保持架构同源,具体 API 以各平台官方文档为准。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

驰骋低代码、工作流、表单引擎

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值