会签、或签、依次审批
这篇解决什么
同一用户任务算出多个人之后,节点怎么才算过:一起批、一人即可、还是按顺序一个接一个。读完能改设计器上的「多人审批方式」、完成条件表达式,以及并行 / 顺序两套 Behavior。
候选人从哪来,见 选择审批人。画布和发布见 流程设计器(BPMN)。办待办见 审批通过、不通过、驳回。
默认端口 48080,管理端前缀 /admin-api。PC 开发页 http://127.0.0.1:5800。引擎是 Flowable 8。先把流程跑起来,见 流程功能设计。
示意图:设计器写出 approveMethod 和 completionCondition;运行时由自定义多实例 Behavior 算人数、分人。
从哪打开
菜单在流程中心 → 流程设置 → 流程模型。日常单据用 SIMPLE:第三步点审批节点,右侧抽屉里「审批人设置」下面就是「多人审批方式」。BPMN 选中用户任务后,属性面板同一组单选。
| 名称 | 说明 | 仓库路径 |
|---|---|---|
| SIMPLE 抽屉 | 审批节点的 approveMethod / approveRatio | ruoyi-office-vben/apps/web-antd/src/views/bpm/components/simple-process-design/components/nodes-config/user-task-node-config.vue |
| 选项文案 | 依次 / 会签比例 / 或签 / 随机一人 | .../simple-process-design/consts.ts 的 APPROVE_METHODS |
| SIMPLE 落 BPMN | 发布前转 MultiInstanceLoopCharacteristics | ruoyi-office/yudao-module-bpm/.../util/SimpleModelUtils.java |
| BPMN 面板 | 折叠项「多人审批方式」 | .../bpmn-process-designer/package/penal/multi-instance/ElementMultiInstance.vue |
| 节点 VO | approveMethod、approveRatio | .../vo/model/simple/BpmSimpleModelNodeVO.java |
| 方式枚举 | 1 随机 / 2 会签 / 3 或签 / 4 依次 | yudao-module-bpm-api/.../enums/definition/BpmUserTaskApproveMethodEnum.java |
扩展属性名是 approveMethod(BpmnModelConstants.USER_TASK_APPROVE_METHOD)。时间轴要解释「这个节点当初怎么配的」,读的就是它。

本系统截图:用车申请「部门负责人」。上面先选候选人,下面才是依次 / 会签 / 或签 / 随机。
先定人,再定怎么过
候选人策略解决「谁来审」。多人审批方式解决「这批人怎样算节点完成」。两套配置正交,不要互相代替。
四种方式
界面上的四种,对应枚举和 BPMN 多实例参数。随机一人不建多实例;其余三种都写 multiInstanceLoopCharacteristics。
| 名称 | 说明 | 仓库路径 |
|---|---|---|
依次审批 4 | isSequential=true,一次只出现一个人的待办,全部办完才过 | BpmUserTaskApproveMethodEnum.SEQUENTIAL |
会签 2 | 并行。通过比例 approveRatio(默认 100,即全过) | RATIO |
或签 3 | 并行。任意一个实例完成后,节点就可以往下走 | ANY |
随机一人 1 | 不写多实例,从候选人里抽一个 assignee | RANDOM |
完成条件写在 completionCondition 上。Flowable 内置两个计数:
| 名称 | 说明 | 仓库路径 |
|---|---|---|
nrOfInstances | 这个节点一共要建多少个任务实例 | Flowable 多实例变量 |
nrOfCompletedInstances | 已经结束的实例数 | 同上 |
| 依次 / 全过会签 | ${ nrOfCompletedInstances >= nrOfInstances } | SEQUENTIAL;RATIO 在比例为 100 时等价 |
| 按比例会签 | ${ nrOfCompletedInstances/nrOfInstances >= 0.60 } | RATIO,approveRatio / 100,保留两位小数 |
| 或签 | ${ nrOfCompletedInstances > 0 } | ANY |
SimpleModelUtils.processMultiInstanceLoopCharacteristics 还会给集合写占位 ${coll_userList},只为过引擎校验。真正的人名单不读这个表达式。
依次审批另外写 loopCardinality=1:每一轮只建一个任务。总人数仍由候选人集合决定,不是「整个节点只批一次」。
会签 100% 不是依次审批
比例 100 只要求「都得过」,待办是同时发给所有人的。依次审批是串行:前一个人不提交,后一个人看不到任务。耗时和待办刷屏差很多。
票签怎么配
同一节点多人,过半就走:会签,比例填 50。表达式变成 ${ nrOfCompletedInstances/nrOfInstances >= 0.50 }。不要另写一套 Behavior。
运行时怎么分人
BpmFlowableConfiguration 把 BpmActivityBehaviorFactory 交给引擎。工厂替换三处默认行为:单任务、并行多实例、顺序多实例。
| 名称 | 说明 | 仓库路径 |
|---|---|---|
| 工厂 | 创建下面三个 Behavior | .../behavior/BpmActivityBehaviorFactory.java |
| 并行 | 会签、或签。集合用 Hash 语义即可 | BpmParallelMultiInstanceBehavior |
| 顺序 | 依次审批。集合必须是 LinkedHashSet | BpmSequentialMultiInstanceBehavior |
| 单任务 | 从集合取出当前人,设成 assignee | BpmUserTaskActivityBehavior |
| 候选人 | 按节点策略算出用户编号 | BpmTaskCandidateInvoker |
| 集合变量 | {activityId}_assignees | FlowableUtils.formatExecutionCollectionVariable |
| 当前人变量 | {activityId}_assignee | formatExecutionCollectionElementVariable |
解析器想改 collection 表达式时,两个 MultiInstance Behavior 都会忽略,保住上面这套变量名。
示意图:先算整表人,再按并行或顺序拆成多个任务;每个任务只有一个办理人。
多实例时,BpmUserTaskActivityBehavior 不再自己算人,只读当前实例的 *_assignee。非多实例(随机一人)才调用 calculateUsersByTask,再随机取一个。项目约定任务责任到人:一个 Task 只有一个 assignee。
算不到人时,集合里会放一个 null,仍然创建一个任务。空审批人、自动通过、自动拒绝都靠这条,避免节点被引擎直接跳过。
或签取消与退回
或签(以及会签已达比例)满足完成条件后,引擎会拆掉还没办的并行任务,并抛 ACTIVITY_CANCELLED。
| 名称 | 说明 | 仓库路径 |
|---|---|---|
| 监听取消 | ACTIVITY_CANCELLED → 按 execution 找历史活动 | .../listener/BpmTaskEventListener.java |
| 补本地状态 | 未结束的任务写成取消 | BpmTaskServiceImpl#processTaskCanceled |
| 取消原因 | CANCEL_BY_SYSTEM | BpmReasonEnum |
不补这一步,时间轴会留下「审批中」。办理页和待办列表读的是任务本地变量 TASK_STATUS,见 审批通过、不通过、驳回。
依次审批退回后再进来时,顺序 Behavior 用 getVariableLocal 读集合。实例级变量退回后可能没清干净,再读会沿用旧名单,新的候选人算不进去。
退回多实例节点时,returnTask 用 moveActivityIdsToSingleActivityId。Flowable 8 已覆盖早年多实例退回的引擎缺陷;同节点上别人的任务会标取消,自己的标退回。
或签「完成」包含拒绝
条件是「完成数 > 0」,通过或拒绝都可能结束多实例。拒绝后整单停还是退回某节点,由「审批人拒绝时」决定,和会签 / 或签正交。改或签一定要用两个人测拒绝路径。
扩展时注意
加一种「必须全过、但待办并行」:会签比例填 100,不要手改隐藏的旧快捷按钮。BPMN 面板里「并行多重事件 / 完成条件」那一组 Form 已 hidden,以免和四个单选抢 XML。
子流程 CallActivity 也可以挂多实例。人数来源是 BpmChildProcessMultiInstanceSourceTypeEnum:固定数量、数字表单、多选表单。UserTask 那套 *_assignees 不算子流程次数。
运行中临时加人是加签,不是改 approveMethod。模型能静态表达的,优先配多人审批方式。加签见后续「审批加签、减签」篇。
跨租户导模型会清掉不能复用的审批人。导入后重新选候选人,并再确认会签比例,不要假设源租户的名单还在。
配置与操作
管理员在 SIMPLE 抽屉或 BPMN 面板选「多人审批方式」和会签比例,保存后发布。approveMethod 写成多实例,运行时才分出多条待办。
要部门里人人都能批,用或签;要按顺序批,用依次审批。单人任务不会把角色集合都派出去。运行中临时加人走加签,不要改已发布图去「补人」。
开启见 流程功能设计。截图见上文。
