“加签”既可能是动态增加审批人,也可能是动态增加审批步骤,但两者不是同一种实现。当前节点加人,通常是在同一个 BPMN 活动、同一个审批轮次中增加执行实例和用户任务;前加签、后加签则需要建立有先后顺序的审批子轮次。即使后者在运行时形成了新的活动实例,也通常不应该修改并重新部署正在运行流程的 BPMN XML。
真正需要先问的不是“引擎有没有加签 API”,而是:新增人员与原审批人是同轮平级,还是必须先于、后于原审批人完成?前者是参与者扩容,后者是审批结构变化。把两者混成一个按钮,最容易造成计票分母漂移、原任务提前完成、历史轨迹无法解释以及流程版本失控。
一、核心结论与问题边界
一句话回答:两者都是,但要先判断审批语义
可以用三条规则快速判断:
- 新人和原审批人共同参与同一轮会签,使用“动态增加审批人”;
- 新人必须在原审批人之前或之后单独形成结论,使用“动态增加审批子轮次”;
- 新审批步骤以后对所有新流程实例永久生效,才修改 BPMN 模型并发布新版本。
因此,“增加流程节点”必须说清楚是增加模型定义节点、运行时活动实例,还是业务审批轮次。三者看起来都像流程图上多了一个框,生命周期和治理方式却完全不同。
先分清 BPMN 节点、活动实例、任务和审批轮次
工作流项目中,至少有四类对象经常被叫成“节点”。
| 对象 | 一句话定义 | 典型标识 | 是否运行时产生 |
|---|---|---|---|
| BPMN 节点 | 流程定义中的静态活动模板 | processDefinitionId、activityId | 否,部署时确定 |
| 活动实例或 Execution | 某个流程实例运行到该活动后的执行状态 | activityInstanceId、executionId | 是 |
| 用户任务 | 分配给具体人员的工作项 | taskId、assignee | 是 |
| 审批轮次 | 业务系统对参与人、顺序和完成规则的聚合 | roundId、roundNo | 是,属于领域对象 |
Flowable 官方 API 文档把 Execution 描述为 BPMN “令牌”位置的表示;一个流程实例本身可以拥有一棵执行树。多实例活动则像 for each:一个静态 User Task 节点可以在运行时产生多个执行和多个用户任务。因此,任务数量增加并不等于 BPMN 节点数量增加。

图 1:一个 BPMN 节点可以产生多个运行时执行与用户任务;业务审批轮次用于解释这些对象为什么被创建以及怎样共同完成。
二、关键概念与能力差异
动态增加审批人到底改变了什么
动态增加审批人,改变的是某个活动实例下的参与者集合与执行树。例如采购会签节点原有 A、B 两个审批人,运行中加入 C:BPMN 模型仍然只有一个“采购会签”User Task,activityId 不变,但多实例父执行下新增一个子 Execution,并为 C 创建新的 taskId。
这类操作通常具备四个特征:
- A、B、C 属于同一审批轮次,原则上共享一套完成条件;
- 新人的意见与原审批人的意见处于同一层级;
- 流程图上的静态节点不增加,部署版本不改变;
- 需要重新明确 C 是否进入总人数、通过比例和一票否决计算。
如果新增人员只是咨询人,不参与最终计票,就不应伪装成同轮会签人。更合适的建模是“征询意见”子轮次、传阅任务或独立业务记录。
动态增加流程节点其实有三种含义
工程讨论中,“增加节点”可能指三件完全不同的事。
| 说法 | 实际动作 | 对运行中实例的建议 |
|---|---|---|
| 修改模型节点 | 修改 BPMN XML,部署新的流程定义版本 | 只影响未来实例;存量实例需要显式迁移 |
| 增加活动实例 | 在已有模型范围内启动一个活动、子流程或调用活动 | 可用于个例修复或受控扩展 |
| 增加审批子轮次 | 业务层创建前置、后置审批步骤,并映射到引擎执行 | 最适合中国式前加签、后加签 |
第一种是流程设计变更,第二种是引擎运行状态变更,第三种是审批领域结构变更。前加签和后加签通常属于第三种;它们可以由预先建模的子流程、可复用调用活动或审批容器承载,而不是在线改写模型 XML。
三、模型架构与运行机制
当前节点加人:增加的是执行实例,不是定义节点
Flowable 的 RuntimeService.addMultiInstanceExecution(activityId, parentExecutionId, executionVariables) 明确用于向运行中的多实例父执行增加一个 Execution。它可以携带 assignee、participantId、roundId 等局部变量,再由任务监听器或业务服务建立人员、Execution 与 Task 的映射。
这项 API 解决的是执行树扩容,不自动解决审批语义。系统仍需判断:新增人是否计入 nrOfInstances 对应的业务分母,已满足的完成条件是否允许重新打开,重复人员怎样处理,以及撤销新增实例时是否计为已完成。
Flowable 多实例文档还说明,实例总数在进入活动时计算一次。仅修改最初的 collection 变量并不会自动创建新的多实例任务;运行时加人必须走显式 API 或平台封装的领域命令。
前加签和后加签:增加的是有顺序的审批子轮次
前加签表示“新人先处理,原办理人随后继续”。原任务不能被删除,也不能提前完成,而应进入 WAIT_PRE_SIGN 状态;子轮次通过后,原任务恢复。后加签表示“原办理人先形成待确认意见,新人随后处理”,当前节点只有在后置轮次结束后才能整体离开。
这两种场景都不是给原多实例集合简单追加一个人,因为新增人员与原办理人的顺序不同、责任不同、拒绝后的路径也不同。推荐为每次加签创建独立 roundId,记录 parentRoundId、signType、顺序号、参与者快照和完成策略。

图 2:同轮加人扩充原活动的参与者;前后加签建立子轮次,但两者都不等于在线修改 BPMN 定义。
四、核心场景与处理策略
为什么不应在运行中直接修改 BPMN XML
流程定义是版本化、可审计的静态契约。运行实例通常绑定启动时使用的 processDefinitionId。在线修改模型再部署,会得到一个新版本,并不会自动把旧实例切换过去;若再强行迁移,还要处理活动映射、变量、边界事件、作业、监听器和历史一致性。
直接改 XML 还有三个治理问题:第一,同一业务单据的历史节点与当前模型可能不一致;第二,某次临时加签会污染以后所有流程;第三,审计人员无法判断节点来自原始制度还是某次运行时操作。
因此,个别实例的临时加签应保存为运行时命令和审批领域事件;组织制度永久增加审批环节,才进入模型变更、评审、发布和存量实例迁移流程。
什么情况下才应该真正增加 BPMN 节点
以下情况适合修改流程定义并部署新版本:
- 新的审批角色以后对所有同类业务都生效;
- 新步骤具有独立 SLA、边界事件、表单权限或异常路径;
- 新步骤不依赖某个办理人临时决定,而属于制度要求;
- 需要在设计器中被持续分析、模拟、审计和复用。
例如,金额超过 100 万元必须固定经过法务复核,这应通过网关与法务 User Task 建模。某次采购因合同特殊临时请法务复核,则更适合运行时创建后加签子轮次。判断标准不是“有没有新人”,而是变更是否应成为稳定的流程契约。
五、数据、规则与状态设计
Flowable 中怎样划清两类加签的实现边界
对于当前节点加人,优先从设计阶段就把可加人的节点建成多实例 User Task,即使初始只有一个人,也保持统一执行结构。运行时由加签命令服务校验多实例父执行,再调用 addMultiInstanceExecution;撤销未完成新增实例时可使用 deleteMultiInstanceExecution,但要谨慎处理 executionIsCompleted 参数对父多实例计数的影响。
对于前加签、后加签,更稳妥的方案是预建审批容器或启动可复用子流程。Flowable 还提供 ChangeActivityState 和 Ad-hoc Sub-Process 相关能力,可改变运行位置或执行容器内活动,但这些 API 只负责引擎状态,不能代替审批轮次、权限、计票和审计模型。
平台层应封装 ADD_PARTICIPANT、PRE_SIGN、POST_SIGN 三种领域命令,禁止界面直接提交 executionId 或拼装引擎调用。
Camunda 7 的实例修改为什么也不等于加签
Camunda 7 Process Instance Modification 支持 startBeforeActivity、startAfterActivity、启动指定 Sequence Flow,以及取消活动实例。官方把典型用途列为修复错误实例、迁移与测试,并提醒活动在同一实例内修改自身可能产生未定义行为。
这套 API 能在已有模型中创建新的活动实例,却不是面向 OA 的完整加签接口。调用方必须选择正确的 ancestorActivityInstanceId,并验证多实例 Activity Body、完成条件、监听器、历史与授权是否符合预期。前后加签仍应由外部命令服务或显式子流程管理责任链,不应把一次 startBeforeActivity 当成完整产品能力。
六、工程实现与系统集成
完成条件和计票分母为什么决定实现方式
假设会签原有 3 人,2 人同意即通过,在已有 2 人同意后再加入第 4 人,流程是否已经结束?如果引擎完成条件已经满足,节点可能已离开,新增任务没有合法父执行。即使尚未离开,也必须选择以下策略之一:
| 策略 | 新人是否进入分母 | 适用场景 |
|---|---|---|
| 动态分母 | 是,重新计算人数与阈值 | 同权会签 |
| 快照分母 | 否,只提供意见 | 咨询、复核 |
| 新子轮次 | 使用独立规则 | 前加签、后加签或临界时追加复核 |
不要直接用 nrOfCompletedInstances 当赞成票数。它表示完成的实例数,可能包含拒绝、弃权或管理员取消。业务决定应单独保存在 approval_decision 中,由领域规则计算赞成、反对、弃权和有效票。
加签与任务完成并发时怎样避免孤儿任务
最危险的竞态是一个请求完成最后一项审批,另一个请求同时增加参与者。推荐所有改变当前轮次的操作经过统一命令入口,并按 processInstanceId + activityId + roundId 串行化。
命令处理至少包含:校验 operationId 幂等;锁定审批轮次;重新读取引擎活动与任务状态;比较 roundVersion;校验完成条件;在同一事务边界内保存业务记录和执行引擎变更;提交后通过 Outbox 发布待办与通知。若节点已结束,应明确返回“加签窗口已关闭”,不能创建没有父轮次的任务。
七、安全、性能与治理要求
数据库里应该保存哪些映射和审计证据
建议把引擎对象与业务审批对象分开保存,通过稳定标识关联。
| 业务表 | 关键内容 |
|---|---|
| sign_request | 发起人、类型、原因、operationId、状态 |
| approval_round | roundId、parentRoundId、activityId、策略版本 |
| sign_participant | 人员快照、角色、顺序、executionId、taskId |
| approval_decision | 结构化决定、意见、附件、签章与时间 |
| engine_binding | processDefinitionId、activityInstanceId、executionId、taskId |
审计日志必须能回答:当时使用哪个模型版本、在哪个静态 activityId 上创建了哪个运行时活动、谁因哪次加签请求获得任务、意见是否进入最终计票、任务后来被完成还是取消。只保存流程引擎历史表,通常解释不了“为什么加这个人”;只保存业务意见表,又证明不了执行状态怎样变化。
企业应该怎样选择加人、子轮次还是模型变更

图 3:先判断同轮关系和永久性,再选择增加参与者、创建子轮次、运行时实例修改或发布新模型。
一个实用的选型顺序是:先问新增人与原审批人是否平级;再问是否存在明确的先后顺序;最后问该变化是只针对本次实例,还是以后所有实例都要执行。这样可以避免由某个引擎 API 反向定义产品语义。
对于单个异常实例,如果已有模型中存在可启动的活动或子流程,可使用引擎实例修改能力,但必须留下原因、操作者和前后状态快照。对于长期规则,则走模型版本管理;不要用大量运行时跳转弥补设计阶段缺失的制度流程。
八、平台落地、测试与选型
低代码流程设计器应该怎样暴露这项能力
低代码平台不应只提供一个笼统的“允许加签”开关。更可用的属性面板至少包括:允许同轮加人、允许前加签、允许后加签、允许嵌套层数、目标人员范围、新人是否进入计票、拒绝后的路径、撤销条件、原任务等待方式和数据权限重算规则。

发布校验要检查:允许同轮加人的节点是否具有多实例或等价审批容器;前后加签是否有可等待的父状态;所有结束和回退路径是否能关闭子轮次;完成条件是否引用结构化业务票数。云程低代码开发平台可在 BPMN.js 属性面板中把这些技术约束封装成业务选项,并由引擎适配层分别映射到 Flowable 或其他工作流引擎。
1万+

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



