ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

可视化流程设计器选型:钉钉风格与BPMN的全面对比

可视化流程设计器选型:钉钉风格与BPMN的全面对比 前阵子我们团队在重做内部低代码平台的流程设计器老同事在群里甩了两个参考原型一个照着钉钉宜搭的审批流风格画一个直接用 bpmn-js 拉标准的 BPMN 2.0 图。两边吵了一下午最后我干脆把两种方案都落了一版 demo自己跑了快两周才把账算明白。这篇文章就是把当时对比过程中踩过的坑、看过的源码、实测的交互数据和最后的选型结论整理出来给正在做可视化流程设计器、又在“钉钉风格”和“BPMN”之间纠结的朋友一个相对完整的参考。这里说的“钉钉风格”指的是以钉钉审批、企业微信审批为代表的那类面向普通业务人员的流程配置界面左侧节点拖拽、中间画布连线、右侧属性面板节点类型主要是审批人、抄送、条件分支这类。而“BPMN”则是 OMG 发布的业务流程建模标准用 bpmn-js 这类开源库渲染事件、网关、任务、子流程等元素是流程引擎领域的事实标准。两条路线争论的本质不是“谁更好看”而是“你做的到底是一个审批配置工具还是一个流程建模工具”。下面我把这两种方案从元模型、交互渲染、引擎映射、扩展成本和最终选型几个维度拆开讲。1. 内容整体设计与思路拆解1.1 设计器到底在建模什么在动手对比之前得先把一个最基本的问题想清楚可视化流程设计器本质上是在做什么。无论界面长成什么样背后干的事都一样——把一份离散的流程定义节点、连线、网关、事件转成一份结构化的描述文件再交给流程引擎去解释执行。所以设计器真正的灵魂不是画布长什么样而是它的“元模型”。钉钉风格背后是一套审批专用的元模型通常叫“审批流模型”。这种模型里节点类型普遍有这些开始节点、审批节点可设置多人审批、或签/会签、抄送节点、条件分支节点多条条件线单选命中、定时器节点个别平台还扩展出填写节点、自定义操作节点。连线只有一种语义就是“上一步完成后走下一步”没有事件、没有消息流、没有补偿、没有子流程的调用语义。BPMN 2.0 的元模型就完全不是一个量级。它有完整的 event 体系开始事件、结束事件、中间事件、边界事件、补偿事件、信号事件等几十种有 gateway 体系排他、并行、包容、事件网关、复杂网关有 task 类型用户任务、服务任务、脚本任务、接收任务、手动任务、业务规则任务还有 Pool、Lane、子流程、事务子流程等容器概念。这个差异最直接的影响是如果你做的是审批场景钉钉风格的元模型几乎正好覆盖需求任何一条审批流都能在半小时内配出来。但如果你想做的是跨系统集成流程比如“订单创建后 10 分钟未支付则自动取消同时发消息给库存系统库存充足走 A 分支否则走 B 分支”那种复杂的排他、并行、超时、补偿语义用钉钉风格那种“串行审批简单条件分支”的模型去表达就非常吃力甚至只能靠外挂节点硬凑。1.2 两套方案的定位差异从产品定位上看钉钉风格设计器和 BPMN 设计器服务的是两类完全不同的用户。钉钉风格面对的是业务运营、行政、HR 这类没有技术背景的普通人员。这类用户的特点是你不能让他理解“网关”和“事件”你只能告诉他“这里是条件分支满足哪个条件走哪条线”。所以在交互上必须做到条件配置尽量模板化、白盒化同一个节点它是什么类型就只露出一堆看得懂的字段。而 BPMN 设计器面对的是流程分析师、集成开发人员、或者懂一点建模知识的实施顾问。BPMN 的圈、矩形、菱形、叉叉本质上是一套严谨的形式化语言。你用 bpmn-js 拖出一个并行网关用户得先明白什么叫“所有进入该网关的分支都汇聚后继续”才对得起这一张图。这也是为什么 BPMN 虽然强大但直接面向普通业务人员时学习曲线非常陡。我个人的判断是钉钉风格解决的问题是“配置审批”BPMN 解决的问题是“描述业务流程”。这两个问题在低代码平台里经常同时存在。所以你真正该问自己的不是“哪个技术更先进”而是“我的平台用户是谁、引擎支持哪一种流程定义格式、未来要做多复杂的流程”。这段话是整个选型对比的顶层逻辑后面的技术细节都围绕着它展开。2. 元模型与流程图语义的底层差异2.1 任务节点的“状态机”差距如果你把设计器保存下来的流程定义交给引擎去跑很快就会遇到第一个分水岭钉钉风格的审批节点和 BPMN 的 UserTask 在生命周期管理上差了整整一个维度。钉钉风格的审批节点在运行时只有几种状态待处理、通过、驳回、撤销。驳回之后流程回到上一节点或发起人重新提交后再次进入审批序列。这个设计非常适合“人—人—人”的串行审批链。它的状态机简单业务方容易理解引擎也好实现。问题在于一旦流程里出现并发分支——比如两个部门同时审批、分别驳回不同分支、各自回退各自的上游——这种简单状态机就炸了。我在调研中就看过有人在钉钉风格设计器里通过多个条件分支、多个“虚拟节点”硬凑并发结果发起人视角一片乱麻引擎端的状态恢复和回退逻辑糊成一团。BPMN 这边UserTask 属于 Process 里普通 Activity活动生命周期由 BPMN 规范定义得明明白白Ready、Active、Completing、Completed、Terminating、Terminated 等等。引擎可以准确告诉你当前流程实例停在哪一个活动、活动处于什么状态、哪些并行分支还开着。你甚至可以挂边界事件在任务上设定超时提醒、超时自动驳回或自动转交。这种语义表达的精确性是钉钉风格简单状态机远远覆盖不了的。2.2 分支逻辑条件线 vs 网关两支方案在分支表达上也是最容易让人混淆的地方。钉钉风格的条件分支节点一般长这样在某个审批节点后添加“条件分支”然后画两条线分别标“金额大于 1000”和“金额小于等于 1000”配置界面让你分别写每条线的表达式。它没有“网关”概念没有汇聚语义更没有并行分支——本质上它是“单选命中”的条件路由。BPMN 里处理分支要专业得多。分支写在 FlowNode 上通过连线上的 conditionExpression 表达条件但到底走哪条线、是否多条线同时走由网关类型决定排他网关 XOR多条分支互斥第一条满足条件的命中默认线兜底。这个语义最接近钉钉风格的条件分支。并行网关 AND进来的分支全部激活同时执行必须等所有分支都抵达汇聚网关后才继续。包容网关 OR满足条件的分支全部执行条件分支和并行分支混合。这种表达体系给你的设计器带来的直接价值是用户画出这些图形时引擎不需要任何额外的配置猜测就清楚知道流程是怎么跑的。条件写在连线上语义挂在网关上图上是什么样跑起来就是什么样。2.3 数据结构的保存与解析复杂度这里我建议做技术选型的人有一个直观的参考——对比一下两种流程定义保存时的“序列化复杂度”。钉钉风格的流程定义通常可以映射成一份 JSON结构大概是{ nodes: [ { id: start, type: start, name: 开始 }, { id: approve_manager, type: approve, name: 经理审批, assignee: manager, mode: AND }, { id: condition_gateway, type: condition, conditions: [] }, { id: end, type: end, name: 结束 } ], edges: [ { from: start, to: approve_manager, condition: }, { from: approve_manager, to: condition_gateway, condition: }, { from: condition_gateway, to: end, condition: ${amount 1000} } ] }这种结构解析成本很低一个递归遍历就能找出一条条执行路径。缺陷是它没有内建的标准协议不同平台各自画一套 schema做开放集成时对方得重新解析一遍。BPMN 的流程定义直接保存为标准的 XML 文件符合 BPMN 2.0 XML Schema。bpmn-js 所见即所得编辑的 XML流程引擎Flowable、Camunda、Activiti可以直接解析执行。这就意味着 BPMN 设计器天然自带“跨系统能力”你画完图导出一个 XML 文件对方引擎只要支持 BPMN 标准就能跑。很多做集成平台的同学选 BPMN 就是冲着这一点。3. 交互与渲染技术选型怎么选3.1 画布渲染方案对比说完了模型层再落到前端渲染和交互上。可视化设计器本质上是一个图形编辑器核心就是画布引擎。钉钉风格的“拖节点—连线—配属性”这类交互相对传统市面上的实现方式非常成熟一般是这几种自研 DOM 或 SVG 渲染节点是一个个可拖拽的 div 或 svg 元素连线基于节点坐标用 SVG path 画。优点是简单不需要额外依赖缺点是自研拖拽对齐、自动布局、缩放联动这些功能成本高。使用 antv X6蚂蚁的图编辑引擎内置连线、锚点、群组、小地图、框选、撤销重做。很多国内低代码平台的钉钉风格设计器都用它。API 设计比较适合国内团队中文文档全遇到问题能查到的东西多。使用 LogicFlow滴滴开源的流程编辑框架比 X6 更高一层自带节点和边的基础模型适合快速搭流程设计器。如果你走钉钉风格路线我个人推荐优先考虑 antv X6 或 LogicFlow。这两者都在底层帮你处理好了拖拽、连线、坐标变换、缩放平移你只需要把精力放到节点类型定义和属性面板上。X6 的 Shape 定义比较灵活LogicFlow 则自带基础的流程节点模型起步更快。BPMN 路线几乎唯一的选择就是 bpmn-js。它基于 mermaid 画不出来、但 bpmn-js 全依赖 SVG 渲染 BPMN 图内部实现了一个完整的 BPMN 2.0 规范解析器。bpmn-js 给你做的是完整建模工具而不是一个图形库。它有 pallete、contextPad、propertiesPanel默认交互基本符合 BPMN 工具习惯。二次开发需要改它的 JSON Schema 和属性描述文件自定义节点比较麻烦不像 X6 那样自由。bpmn-js 初始化代码非常简单import BpmnModeler from bpmn-js/lib/Modeler; import bpmn-js/dist/assets/diagram-js.css; import bpmn-js/dist/assets/bpmn-js.css; const modeler new BpmnModeler({ container: #canvas, keyboard: { bindTo: document } }); const diagramXML ?xml version1.0 encodingUTF-8? bpmn2:definitions xmlns:bpmn2http://www.omg.org/spec/BPMN/20100524/MODEL ... bpmn2:process idProcess_1 isExecutabletrue bpmn2:startEvent idStartEvent_1 / bpmn2:sequenceFlow idFlow_1 sourceRefStartEvent_1 targetRefActivity_1 / bpmn2:userTask idActivity_1 name审批 / bpmn2:sequenceFlow idFlow_2 sourceRefActivity_1 targetRefEndEvent_1 / bpmn2:endEvent idEndEvent_1 / /bpmn2:process /bpmn2:definitions; modeler.importXML(diagramXML).then(() { console.log(流程已加载); });3.2 交互体验的实战对比两种方案在交互体验上的差异也会直接影响你产品的“买家用起来爽不爽”。钉钉风格交互强调“引导感”。节点类型少属性面板每一项都映射成具体的业务字段比如审批人可以直接选角色、选人、选部门主管不需要写表达式。用户在配置条件分支时看到的是表单式条件行而不是表达式编辑框。这种交互的优点非常明显业务用户不需要培训就能把一条报销流程搭出来。BPMN 的交互强调“自由表达”和“规范性”。bpmn-js 画布上用户在 Palette 里拿一个新的 start event 拖进画布再拖任务、拖网关、拉线连接。属性面板里有流程定义、条件表达式、文档说明这些字段。这套交互对懂一点建模概念的人来说效率很高但普通业务人员会认为完全是“开发工具”。实测我让产品设计和运营各画同一个审批场景钉钉风格完成大约需要 3 分钟BPMN 风格 8 分钟起步并且还有人问“那个菱形是什么”。这里我想给你一个非常实际的提示**如果你的设计器主要用户是普通业务人员永远优先选钉钉风格如果你的用户是实施顾问、集成开发BPMN 带来了建模自由度和标准兼容的价值。**交互设计不要两头讨好否则做出来一个“看起来像钉钉、拖出来又依赖网关”的四不像学习成本反而更高。3.3 节点样式与扩展的取舍钉钉风格画布上节点样式高度统一工作流节点、审批节点、抄送节点配色明确目的是让用户快速识别节点类型。BPMN 图的节点样式则受规范约束事件是圆形、活动是圆角矩形、网关是菱形用户识别靠的是图形语义而非颜色。如果你要在 BPMN 上强行做成“圆角矩形可爱图标”的钉钉风会破坏 BPMN 的规范性别人拿到图也容易看不懂。扩展方面钉钉风格因为节点类型是自定义业务对象你想加什么节点就加什么节点非常灵活。BPMN 加自定义节点就得在 bpmn-js 上写 CustomElement得改 modeler 的事件监听、rendering 逻辑还要保持 XML 扩展属性不破坏标准复杂度高不少。所以如果要走 BPMN尽量在标准节点体系里解决问题少做扩展。4. BPMN 网关实操从画图到引擎执行的映射既然热搜里专门问到“bpmn流程图网关使用”这一节我专门把 BPMN 的网关在可视化设计器里怎么用、怎么配条件、引擎里怎么解析展开讲。4.1 排他网关的配置与执行规则排他网关在 BPMN 图上就是一个菱形里面画一个“X”它的语义是进入网关后只选择一条满足条件的流出分支执行如果没有分支满足条件则走默认分支如果没有默认分支则报错。在 bpmn-js 里你从 Palette 拉一个 Exclusive Gateway 放在画布上然后从网关拉两条 SequenceFlow 出去分别在连线上设置 Condition Expression。XML 里大概长这样bpmn:exclusiveGateway idGateway_26m9c4a name金额判断 / bpmn:sequenceFlow idFlow_1 sourceRefGateway_26m9c4a targetRefActivity_5j0k2b bpmn:conditionExpression xsi:typebpmn:tFormalExpression ${amount 1000} /bpmn:conditionExpression /bpmn:sequenceFlow bpmn:sequenceFlow idFlow_2 sourceRefGateway_26m9c4a targetRefActivity_03nf3a /这里第二条连线没写条件就是默认分支。引擎遇到排他网关时通常先按连线顺序依次判断条件表达式命中第一条满足条件的就执行后面的不再判断。如果你想让某条分支兜底务必把这条分支设置为默认分支在 propertiesPanel 里勾选 default flow。我实际工作中一个常见的坑是条件表达式写错格式。Camunda 系引擎默认用 EL 表达式${...}Flowable 也类似但是有些团队还装了自定义表达式解析器写的时候就要对照引擎支持的语言来。在设计器里一定要把“条件编辑器”做好不要留给用户一个“表达式输入框”就完事而是做一个表单让用户选变量、选运算符、填值最后拼接成表达式字符串。这样能省掉 80% 的配置错误。4.2 并行网关与包容网关的实战用法并行网关的菱形里面是“”号语义是进入后所有流出分支并行执行不评判条件汇聚时等待所有分支都到达后才继续。它特别适合表达“会签”“多人同时审批”“并发子任务”这些场景。比如一个报价审批流程财务审核和法务审核同时发起两个都完成后自动进入下一步这就是一个典型的并行网关。在可视化设计器里并行网关前后分别放一个 fork 网关和一个 join 网关两两配对开始 → 并行网关(fork) → 财务审核 →┐ → 法务审核 →┤ 并行网关(join) → 结束XML 里就是两个 gateway所有流出连线都不用写条件并行网关忽略条件等待 join 汇聚。包容网关的菱形里面是一个圆圈带叉语义最灵活入站时判断每个流出分支的条件满足条件的全都执行汇聚时等待所有“被触发过”的分支到达才汇合。它解决的是“并行执行若干分支但分支是否激活取决于条件”的需求。会用的团队并不多因为大多数流程用排他并行就能覆盖了。我建议设计器里可以支持包容网关但默认节点面板里不要放太多把排他网关和并行网关做成常用包容网关放进高级分类里避免普通用户混乱。4.3 网关与引擎的可执行性测试在 bpmn-js 里画图不是最终目的图必须能被流程引擎解释执行。我强烈建议你在设计器开发完成后立刻做一个“导出 XML → 导入引擎 → 跑通场景”的闭环测试。我们当时踩了一个特别典型的坑设计器画了一个边界事件挂在一个用户任务上导出 XML 也没报错但部署到 Flowable 引擎后任务完成时边界事件不触发排查半天发现是边界事件和任务之间缺少一条 event definition 关联。这类坑如果不做端到端测试用户配完流程根本跑不起来问题全堆到运维那。另外BPMN 网关在引擎里有个执行细节值得提醒排他网关判断分支的顺序工程上依赖流程定义里 SequenceFlow 在 XML 中的顺序。如果你的设计器允许用户随意拖动改变连线顺序保存时最好显式把连线的兄弟顺序排一下否则可能出现“条件明明满足 A但引擎先判断 B 走了默认分支”这种莫名其妙的 bug。这个细节我在市面上不少开源设计器里都见过属于上游设计器很少主动处理、下游引擎背锅的经典问题。5. 扩展能力与工程成本对比5.1 属性面板和节点扩展如果你在做一个低代码平台可视化流程设计器大概率只是整个平台的一部分你还要接表单、接权限、接外部 API、接通知。这时候扩展能力就变得特别关键。钉钉风格设计器的节点属性面板完全由你自定义什么样的属性都能塞进去审批人字段、表单字段读写权限、目标人群、消息文本、外部接口调用参数等等。每个业务节点是一个 Vue/React 组件配一个 JSON Schema 描述属性运行时引擎读 JSON 里的值执行。这种模式的优点就是“引擎只关心 JSON 字段字段语义由平台自己定义”自由度极高。缺点是流程定义没法标准化未来如果要接第三方审批平台或引擎只能做适配器转换。BPMN 设计器的属性面板由 bpmn-js 的 properties panel 扩展驱动。标准节点支持 name、documentation、conditionExpression 这些属性。如果你要加自定义属性得定义 custom extension并在 modeler 里注册、渲染时把这些 custom attributes 写进 XML 的 bpmn:extensionElements 区域。这块改动虽然能做但工程量明显比钉钉风格重不少。说白了钉钉风格适合往平台里深度集成业务组件BPMN 适合向外提供标准流程能力。我一直认为扩展成本是最容易被低估的选型因素。很多人一开始被 bpmn-js 的“成熟可靠”吸引选完才发现要做一套自己的节点属性体系结果光自定义扩展就花了两三周还不算引擎对扩展节点的兼容成本。而钉钉风格从零搭节点的成本低得多如果你们的流程引擎本来也是自研的几乎可以在节点扩展上随便折腾。5.2 团队技术栈匹配度选型这件事也必须考虑团队现有技术栈。如果团队有图形编辑、SVG 方面经验短时间上手 bpmn-js 相对快如果前端团队主要做表单和中后台对拖拽、连线、锚点这些交互不熟那用 antv X6 或者 LogicFlow 搭钉钉风格会更快更稳。另外 bpmn-js 的依赖树比较大对打包体积、兼容性有要求时也要额外考虑。bpmn-js 整套库下来压缩后可能 1MB 级别X6 的包体相对也要几百 KB。这都是设计器放进中后台项目时要算的账。5.3 数据迁移与开放集成如果你做的是平台型产品客户可能已有旧的流程定义数据或者你的平台需要对接其他系统的流程定义。这时 BPMN 的价值立刻显现它是行业标准客户迁移时只需要导 XML另一边能识别 BPMN 就基本无障碍。但钉钉风格的 JSON 格式没有标准迁移只能靠你写转换器、或者是客户重新画一遍。我们当时评估的一个客户场景是对方现有系统是 Flowable 引擎存量几百条流程。如果新平台要承接这些流程BPMN 设计器 XML 导入直接裸兼容如果选钉钉风格设计器就得写一个 Flowable XML → 平台 JSON 的转换器涉及网关、事件、条件表达式的映射工作量大到爆炸。所以在做开放性评估时我强烈建议你列一张“未来可能对接的引擎/系统”清单逐个勾选兼容性这才是最理性的决策方式。6. 常见问题与选型建议6.1 两种方案常踩的坑我在做方案对比时记录了一些高频坑分享出来供你参考钉钉风格的“并行”经常被用户误用。很多用户在条件分支节点后拉两条线就以为自己做了并行实际语义是条件单选。如果产品文档没写清楚很容易线上跑出错误流程。BPMN 的网关和连线条件配置界面如果设计得不好用户配置时根本不知道条件该写哪。必须做条件配置引导不要裸开放一个表达式编辑器。钉钉风格在表达“超时未处理自动提醒”“任务逾期自动驳回”这些时间事件时很弱。如果需要这类功能建议直接在节点属性里做成“高级设置”不要硬靠节点堆。BPMN 学习成本高直接面向小白用户会劝退。如果平台同时有专业版和轻量版可以考虑做两套视图底层共用一份 BPMN 模型上层轻量版封装成钉钉风格。保存流程定义前一定要做模型校验。至少检查元素是否完整、连线有没有断头sourceRef 或 targetRef 为空、排他网关是否有默认分支。用户拖到一半关页面丢数据这个场景也要配置自动保存。6.2 一份可以直接用的选型决策表我把当时的对比结果整理成下面这个表格你拿来做需求评审时的参考维度钉钉风格设计器BPMN 设计器目标用户普通业务人员实施顾问、集成开发建模复杂度低适合审批流、串行流高适合复杂编排、事件驱动流程定义格式自定义 JSON标准 BPMN 2.0 XML引擎兼容性需自研/对接开箱兼容 Camunda、Flowable并行/网关表达弱条件分支单选强排他/并行/包容/事件网关时间事件支持弱需扩展属性强边界事件、中间事件二次开发成本低节点类型自由定义高自定义扩展需遵循规范第三方依赖可选 X6/LogicFlow以 bpmn-js 为主团队技能要求常规前端能力需理解 BPMN 规范适合场景审批流、企业内部管理流跨系统集成、复杂业务流程6.3 我的最终选型心得我们最终的选择是双轨制底层核心用 BPMN 模型保证流程定义的标准性和引擎兼容性但同时设计了一套“简化模式”作为默认入口——普通用户打开看到的是一个钉钉风格界面点的节点只有审批、抄送、条件分支画图过程极简高级用户切到“专业模式”看到完整 bpmn-js 功能用全量 BPMN 节点建模。两个模式操作同一个模型文件的视图层保存后永远是同一份 XML。从实操角度看这个方案开发成本略高一些因为要做两套渲染和一套模型映射但长期收益非常明显业务用户不觉得产品难用开发用户不觉得产品受限。如果你也面临这个对比决策我的建议是先想清楚平台要做给谁用然后不要急着选边。能用一套标准模型兼容两种交互才是这个领域里比较理想的路子。
返回列表