四大菜单与三大处理器:驰骋 BPM 与 Flowable / Camunda / Activiti 的任务交互层对比
分享定位:一次面向研发与架构同学的技术分享稿,聚焦「用户怎么进入流程、怎么办理、怎么查看」。
原文依据:JFlow Wiki《菜单与功能页面》
代码依据:本仓库CCFlow/Components/BP.WF(.NET)、JFlow/jflow-core(Java)、Vue3/src/WF(前端)
对比对象:Activiti、Flowable、Camunda(三者同属 BPMN 2.0 执行语义一脉,下文合称「Activiti 系」时会单独指出差异)
评价原则:场景匹配优先,不做「谁全面更好」的笼统结论。
0. 先说结论(分享开场 30 秒版)
BPM 产品对用户暴露的第一层界面,通常就是:
| 用户意图 | 驰骋 BPM 产品化命名 | Activiti 系常见落地 |
|---|---|---|
| 我能发起什么 | 发起菜单 | Startable Process Definitions |
| 我要办什么 | 待办菜单 | Task Query / Tasklist |
| 我参与过、还在跑的 | 在途菜单 | Involved / Started Process Instances |
| 让我知晓、不参与决策 | 抄送菜单 | 无标准一等公民,需扩展或外挂 |
驰骋把上述能力沉淀为 四大菜单 + 三大处理器,并给出稳定 API 与页面入口;Activiti / Flowable / Camunda 把能力沉在 引擎任务/执行/历史查询 API,交互页多由业务方或 Tasklist / Cockpit / Operate 等运维/任务产品补齐。
差异本质不是「有没有待办」,而是:
- 驰骋:任务交互层是产品内核,表单、工具栏、抄送、在途撤销/催办与流程引擎一体交付。
- Activiti 系:流程执行层是产品内核,任务交互层通常需要二次组装(尤其是中国式审批语义)。
1. Wiki 原文在讲什么
原文把 BPM 前端交互抽象成两层:
1.1 四大流程菜单
- 发起 —— 当前人可启动的流程列表
- 待办 —— 别人(或设备)发给我、需要我处理的工作
- 在途 —— 我参与过、流程未结束、且当前待办不在我身上
- 抄送 —— 让我知晓,但我不干涉流转决策
每个菜单背后是一份列表数据;列表可由 API 获取,前端可自绘风格。
1.2 三大处理器
| 处理器 | 上游菜单 | 职责 |
|---|---|---|
| 工作处理器 | 发起 / 待办 | 办理:工具栏 + 表单区 + 审核组件 |
| 工作查看器 | 在途(及已完成查看) | 查看进展:催办、撤销发送、打印、轨迹 |
| 抄送处理器 | 抄送 | 知晓:打印、轨迹等只读类操作 |
菜单决定「进哪张列表」,处理器决定「打开后能干什么」。
1.3 菜单与处理器的对应关系
发起/待办 ──► 工作处理器(MyFlow)──► 发送 / 退回 / 移交 / 加签 …
在途/完成 ──► 工作查看器(MyView)──► 催办 / 撤销 / 打印 / 轨迹
抄送 ──► 抄送处理器(MyCC) ──► 打印 / 轨迹(默认不改流转)
2. 驰骋 BPM 在代码里如何落地
CCFlow(.NET)与 JFlow(Java)功能等价;以下以本仓库 CCFlow 路径举例,JFlow 有同名 API。
2.1 四大菜单 ↔ 列表 API
Wiki 给出的映射如下:
| 菜单 | API | 代码位置 |
|---|---|---|
| 发起 | BP.WF.Dev2Interface.DB_GenerCanStartFlowsOfDataTable / DB_StarFlows | CCFlow/Components/BP.WF/Dev2Interface.cs |
| 待办 | BP.WF.Dev2Interface.DB_GenerEmpWorksOfDataTable | 同上 |
| 在途 | BP.WF.Dev2Interface.DB_GenerRuning | 同上 |
| 抄送 | BP.WF.Dev2Interface.DB_CCList | 同上 |
待办实现直接查询 WF_EmpWorks(由 WF_GenerWorkFlow、WF_GenerWorkerList、抄送等组装的待办视图),并支持授权待办 UNION:
public static DataTable DB_GenerEmpWorksOfDataTable(string userNo,
int nodeID = 0, string wfstate = null, string domain = null, string flowNo = null, string isRead = null, string orderBy = "ADT")
{
// ...
if (BP.WF.Glo.IsEnableTaskPool == true)
sql = "SELECT A.*, null as Auther, null as AutherName FROM WF_EmpWorks A WHERE A.WFState >1 AND TaskSta=0 AND A.FK_Emp='" + userNo + "' " + whereSQL + readSQL;
else
sql = "SELECT A.*, null as Auther, null as AutherName FROM WF_EmpWorks A WHERE A.WFState >1 AND A.FK_Emp='" + userNo + "' " + whereSQL + readSQL;
抄送则读写 WF_CCList,与流程实例 WF_GenerWorkFlow 关联:
public static DataTable DB_CCList(string domain = null, string fk_flow = null)
{
// ...
ps.SQL = "SELECT a.MyPK,A.Title,A.FlowNo as FK_Flow,A.FlowName,A.WorkID,'' as Doc,A.RecEmpNo as Rec,A.RecEmpName as RecName,A.RDT,A.FID,A.NodeIDCC AS FK_Node,A.NodeIDCCName AS NodeName,B.WFSta,A.Sta,A.NodeIDCC,A.NodeIDCCName,B.AtPara FROM WF_CCList A, WF_GenerWorkFlow B WHERE A.CCTo=" + BP.Difference.SystemConfig.AppCenterDBVarStr + "CCTo AND B.WorkID=A.WorkID AND A.Sta >=0 ORDER BY RDT DESC ";
发起侧通过开始节点访问规则视图(如 V_FlowStarterBPM)决定「谁能启动哪条流程」,不是简单的「部署即人人可启」。
2.2 三大处理器 ↔ 页面入口
| 处理器 | H5 入口(Wiki) | Vue3 路由(本仓库) | 后端入口 |
|---|---|---|---|
| 工作处理器 | /WF/MyFlow.htm?FK_Flow=…&WorkID=…&FK_Node=… | Vue3/src/WF/MyFlow.vue + wf.ts | HttpHandler/WF_MyFlow.cs(MyFlow_Init / InitToolBar) |
| 工作查看器 | /WF/MyView.htm?… | Vue3/src/WF/MyView.vue | 对应 MyView Handler |
| 抄送处理器 | /WF/MyCC.htm?… | Vue3/src/WF/MyCC.vue | 对应 MyCC Handler |
前端菜单列表页也已产品化,例如:
{
path: 'GL/Start',
name: 'GLStart',
component: () => import('/@/WF/views/GenerList.vue'),
meta: { title: '发起', EnName: 'GL_Start' },
},
{
path: 'GL/TodoList',
name: 'GLTodoList',
component: () => import('/@/WF/views/GenerList.vue'),
meta: { title: '待办', EnName: 'GL_Todolist' },
},
// ...
{
path: 'GL/Running',
name: 'GLRunning',
component: () => import('/@/WF/views/GenerList.vue'),
meta: { title: '在途', EnName: 'GL_Runing' },
},
工作处理器内部三块结构(与 Wiki 一致):
- 工具栏:发送、退回、移交、加签等运行控制(
WF_MyFlow.InitToolBar) - 表单区:CCForm / 嵌入式表单 / 树表单等
- 审核组件:意见与审核信息展示
待办打开处理器时,Wiki 强调四个关键参数:Title / WorkID / FK_Flow / FK_Node(另有 FID 用于分合流/子线程)。这与 Activiti 系的 taskId + processInstanceId 定位方式不同——驰骋更偏「节点 + 工作 ID」导航。
2.3 在途的业务语义(值得单独强调)
Wiki 对「在途」给出三个条件:
- 我经手过(含我发起、我审批)
- 流程未完成
- 当前待办不在我身上
在途页常见操作:
- 撤销发送:把已发出工作按规则取回
- 催办:通知当前待办人(
Flow_DoPress) - 打印 / 轨迹图
这套语义在中国审批系统里出现频率很高;在纯 BPMN 引擎里通常要组合「历史活动查询 + 自定义权限 + 自定义操作服务」。
2.4 扩展菜单(Wiki 后半段)
除四大菜单外,原文还列出:我的关注、授权待办、批处理、任务池、取回审批、草稿、挂起等。它们同样挂在 Dev2Interface 的列表/操作 API 上,属于同一交互层产品包,而不是零散脚本。
3. Activiti / Flowable / Camunda:同一问题怎么解
Activiti、Flowable、Camunda 同源(Activiti 拆分后形成 Flowable;Camunda 早期 fork Activiti,Camunda 8 转向 Zeebe)。对「菜单 + 处理器」这一层,它们的共同点多于差异。
3.1 能力映射(概念对照)
| 驰骋概念 | Activiti | Flowable | Camunda 7 / 8 |
|---|---|---|---|
| 发起列表 | RepositoryService + startable 权限 | 类似 + IdentityLink | C7:StartProcessInstance;C8:Operate/Tasklist + Zeebe client |
| 待办列表 | TaskService.createTaskQuery().taskAssignee / taskCandidate… | 同左,API 更完整 | C7:TaskService;C8:Tasklist / user tasks |
| 在途(我参与未结束) | HistoryService + Runtime 组合过滤 | 同左 | C7:历史/运行查询;C8:Operate 查询 |
| 抄送 | 无标准模型 | 无标准模型(可用 identity link / 自定义表) | 无标准模型(常见自建抄送表或消息) |
| 工作处理器 | 自研 Task Form UI | Flowable Task App / 自研 | Camunda Forms / Tasklist / 自研 |
| 工作查看器 | 自研 + Cockpit(偏运维) | Admin App / 自研 | Cockpit / Operate(偏运维与排障) |
| 表单一体 | 弱(外挂为主) | Flowable Forms(能力有限) | Camunda Forms / 外挂 |
3.2 三者之间的细微差别(公平说明)
| 维度 | Activiti | Flowable | Camunda |
|---|---|---|---|
| 产品定位 | 开源引擎内核 | 开源 BPM 套件(引擎+部分应用) | 流程编排与运维产品线更完整(C7→C8) |
| 任务应用成熟度 | 低,多为自研 | 中,有 Task/Admin 应用 | 高,Tasklist / Cockpit / Operate |
| 表单 | 外挂为主 | 有 Forms,复杂审批仍常外挂 | Forms + 外部 UI 常见 |
| 中国审批语义(退回重走、会签、加签、抄送) | 均需扩展 | 均需扩展 | 均需扩展 |
| 标准合规 / 云原生编排 | BPMN 执行 | BPMN 执行 | C7 BPMN;C8 Zeebe 更偏高吞吐编排 |
| 嵌入业务系统成本 | 需自建菜单与页面 | 可部分复用官方 App,定制仍重 | 官方组件更全,但仍是「任务/运维视角」 |
要点:在「四大菜单」这一产品抽象上,Activiti / Flowable / Camunda 并没有与驰骋一一对应的开箱菜单包;它们提供的是可查询的任务与实例模型。
3.3 典型 API 形态对比(伪代码级)
驰骋:一个菜单 ≈ 一个列表 API
发起 = DB_GenerCanStartFlowsOfDataTable(user)
待办 = DB_GenerEmpWorksOfDataTable(user)
在途 = DB_GenerRuning(user)
抄送 = DB_CCList()
打开办理 = MyFlow?FK_Flow&WorkID&FK_Node
Activiti 系:一个菜单 ≈ 多次查询 + 业务拼装
发起 = repositoryService.createProcessDefinitionQuery()
.startableByUser(user).latestVersion().list()
待办 = taskService.createTaskQuery()
.taskAssignee(user) // 还要并 candidateUser / candidateGroup
.list()
在途 = historyService.createHistoricProcessInstanceQuery()
.involvedUser(user).unfinished().list()
// 再排除「当前 assignee 是我」的实例 —— 需业务过滤
抄送 = 自定义表 / 自定义 identity link / 消息中心
打开办理 = 自研 Task Page(taskId) + 外挂表单
因此:引擎能力并不缺「查任务」,缺的是 「在途三条件」「抄送一等公民」「处理器三件套」这类产品约定。
4. 实现差异拆解(分享正文重点)
4.1 交互层是产品还是框架
| 维度 | 驰骋 CCFlow/JFlow | Activiti / Flowable / Camunda |
|---|---|---|
| 菜单模型 | 产品级固定抽象(四大菜单) | 无统一「四大菜单」规范 |
| 页面模型 | MyFlow / MyView / MyCC 固定角色 | Task UI / 运维台 / 自研页 |
| 集成方式 | 列表 API + 页面 URL/路由嵌入 | REST/Java API + 自建前端 |
| 表单 | 与处理器同屏,一等公民 | 多数项目外挂业务表单 |
| 工具栏动作 | 节点按钮配置驱动(发送/退回/…) | 完成任务 + Listener/Delegate 扩展 |
4.2 数据模型差异如何影响菜单实现
- 驰骋:待办围绕
WF_GenerWorkerList/WF_EmpWorks,字段已冗余标题、节点名、人员名,列表 SQL 可直出。 - Activiti 系:待办围绕
ACT_RU_TASK(或 C8 user task),标题/业务字段常在变量或外部业务表,列表往往要二次拼装。
这导致:
- 驰骋更适合「领导要看列表、顾问能写 SQL、实施要快上线」的交付模式。
- Activiti 系更适合「引擎标准执行、业务数据严格外置、微服务拆分」的架构模式。
4.3 「在途」与「抄送」:最容易被低估的差异
| 能力 | 驰骋 | Activiti 系 |
|---|---|---|
| 在途三条件 | 产品定义清晰,API 直接返回 | 需 History + Runtime + 业务过滤 |
| 在途撤销 / 催办 | 查看器内置操作 | 需自定义命令与权限模型 |
| 抄送 | WF_CCList + MyCC 处理器 | 非 BPMN 标准概念,各自实现 |
若选型评审只对比「能不能 complete task」,会低估这一层工作量。
4.4 处理器内部:办理页到底交付了什么
驰骋工作处理器默认交付:
- 流程运行控制(工具栏)
- 表单呈现与字段权限
- 审核意见组件
Activiti 系默认交付:
- 任务认领 / 完成 / 委派等引擎动作
- 表单与审核 UI 多数自建
- 运维观察更多在 Cockpit / Operate,不等于业务「工作查看器」
二者都正确,但交付边界不同。
5. 优缺点对照(尽量去掉感情色彩)
5.1 驰骋 BPM(四大菜单 + 三大处理器路线)
优势
- 交互层抽象稳定,嵌入门户成本低(API + 现成页面)。
- 表单、抄送、在途操作与办理页一体,中国审批场景交付路径短。
- 列表字段面向业务可读,实施与报表友好。
代价 / 约束
- 自研流程模型,BPMN 标准互操作、模型交换不是强项。
- 执行语义与 Activiti 系 Token/Gateway 体系不同,跨引擎人才经验不能直接复用。
- 超高并发、云原生编排、复杂服务编排场景,需要额外架构评估。
5.2 Activiti / Flowable / Camunda
优势
- BPMN(及 Camunda 8 编排)标准清晰,全球生态与资料多。
- 任务、执行、历史、作业、事件模型完整,适合深度定制引擎行为。
- Camunda 在运维可观测、Flowable 在开源套件完整度上各有积累。
代价 / 约束
- 「发起/待办/在途/抄送 + 办理/查看/抄送页」通常要项目组自己产品化。
- 中国特色审批(退回策略、加签、会签权重、抄送处理器)普遍要扩展。
- 表单与组织模型往往另建系统,总体集成面更大。
5.3 Activiti、Flowable、Camunda 三者怎么选(仅就交互层)
| 若你的重点是… | 更常见选择 |
|---|---|
| 只要轻量引擎内核,UI 全自研 | Activiti 或 Flowable Engine |
| 开源套件 + 可接受部分官方 App | Flowable |
| 强运维台、流程平台化、后续云原生编排 | Camunda |
| 中国政企审批门户快速嵌入、表单一体 | 驰骋 CCFlow/JFlow |
6. 选型建议(分享收尾用)
可以用三个问题做快速判断:
-
你要买的是「办理体验产品」还是「流程执行引擎」?
- 前者更贴近驰骋的四大菜单 / 三大处理器。
- 后者更贴近 Activiti / Flowable / Camunda。
-
抄送、在途撤销/催办、节点工具栏、表单字段权限,是不是刚需?
- 是:优先评估驰骋开箱能力。
- 否、且以服务编排/标准 BPMN 为主:优先评估 Activiti 系。
-
团队现有技能在哪?
- 熟悉 .NET/Java + 国内实施交付:驰骋上手路径短。
- 熟悉 BPMN、Listener、外部 Task、云原生:Activiti 系更顺。
混合架构也常见:人审门户用驰骋交互层,或业务审批用驰骋;长流程服务编排用 Camunda/Flowable。关键是不要在同一条审批链上混用两套待办语义。
7. 附录
7.1 Wiki 原文 API / URL 速查
发起: Dev2Interface.DB_GenerCanStartFlowsOfDataTable()
待办: Dev2Interface.DB_GenerEmpWorksOfDataTable()
在途: Dev2Interface.DB_GenerRuning()
抄送: Dev2Interface.DB_CCList()
H5:
发起/待办办理: /WF/MyFlow.htm?FK_Flow=001[&WorkID=&FK_Node=]
查看器: /WF/MyView.htm?FK_Flow=001&WorkID=…
抄送处理器: /WF/MyCC.htm?FK_Flow=001&WorkID=…
现成列表页: /WF/Start.htm, /WF/Todolist.htm, /WF/Runing.htm, /WF/CC.htm
7.2 本仓库关键文件索引
| 主题 | 路径 |
|---|---|
| 列表与操作 API | CCFlow/Components/BP.WF/Dev2Interface.cs |
| 工作处理器后端 | CCFlow/Components/BP.WF/HttpHandler/WF_MyFlow.cs |
| 工作者/待办模型 | CCFlow/Components/BP.WF/WF/GenerWorkerList.cs |
| Vue 办理/查看/抄送 | Vue3/src/WF/MyFlow.vue、MyView.vue、MyCC.vue |
| 四大菜单路由 | Vue3/src/router/routes/modules/wf.ts |
| Java 等价实现 | JFlow/jflow-core/.../Dev2Interface.java |
7.3 参考链接
- JFlow Wiki:菜单与功能页面
- Flowable Task / History API 文档(官方)
- Camunda Tasklist / Operate 文档(官方)
- Activiti TaskService 文档(官方)
8. 一句话收束
驰骋把「发起、待办、在途、抄送」做成了可嵌入的产品契约;Activiti / Flowable / Camunda 把「任务、执行、历史」做成了可组合的引擎契约。
选谁,取决于你缺的是交互产品,还是标准执行引擎——两者解决的是相邻但不同的问题。

被折叠的 条评论
为什么被折叠?



