Activiti7会签实战从“全员通过”到“一票否决”四种表决规则配置详解在企业级流程审批场景中会签Countersign是实现集体决策的核心机制。当采购金额超过阈值、重大项目立项或关键人事变动时往往需要多个责任方共同参与决策。Activiti7作为业界领先的工作流引擎通过多实例任务Multi-Instance Task为会签场景提供了灵活的技术支撑。本文将深入解析四种典型表决规则的实现方案涵盖从XML配置到流程变量的完整实践路径。1. 会签基础架构与核心要素多实例任务通过multiInstanceLoopCharacteristics元素实现会签能力其核心由三个部分组成参与者集合通过activiti:collection指定审批人列表支持静态定义或动态变量注入实例控制变量multiInstanceLoopCharacteristics isSequentialfalse activiti:collection${approverList} activiti:elementVariableapprover完成条件completionCondition表达式决定会签何时终止系统自动维护的流程变量包括nrOfInstances总实例数等于审批人列表长度nrOfCompletedInstances已完成审批数nrOfActiveInstances当前活跃实例数并行模式下等于待处理数提示当isSequentialtrue时会签转为串行审批模式此时nrOfActiveInstances恒为12. 全员通过民主决策模式最严格的审批规则要求所有参与者必须全部同意常见于高风险操作如资金划转、核心系统变更等场景。BPMN配置示例userTask idgroupApproval name安全委员会评审 multiInstanceLoopCharacteristics activiti:collection${securityCommittee} activiti:elementVariablemember completionCondition ${nrOfCompletedInstances nrOfInstances} /completionCondition /multiInstanceLoopCharacteristics /userTask实现要点启动流程时注入审批人列表MapString, Object vars new HashMap(); vars.put(securityCommittee, Arrays.asList(cto,cfo,cio)); runtimeService.startProcessInstanceByKey(riskControl, vars);每个审批任务需显式传递同意标记taskService.complete(taskId, Variables.putValue(approved, true));建议配合网关进行结果判断sequenceFlow sourceRefgroupApproval targetRefexclusiveGateway conditionExpression${approvedCount nrOfInstances}/conditionExpression /sequenceFlow典型问题未处理弃权情况时默认视为拒绝并行模式下可能出现并发冲突建议添加乐观锁控制3. 多数决平衡效率与风险当参与人数较多时可采用比例通过机制。例如5人评审团中3人同意即通过适合项目立项等常规决策。动态阈值配置方案completionCondition ${nrOfCompletedInstances Math.ceil(nrOfInstances * 0.6)} /completionCondition增强型实现带否决权completionCondition ${(approvedCount requiredApproves) || (rejectedCount (nrOfInstances - requiredApproves))} /completionConditionJava服务任务预处理public class QuorumCalculator implements JavaDelegate { Override public void execute(DelegateExecution execution) { Integer memberCount ((List)execution.getVariable(committee)).size(); execution.setVariable(requiredApproves, (int) Math.ceil(memberCount * 0.6)); } }注意浮点数比较可能存在精度问题建议使用整数运算approvedCount*100 nrOfInstances*604. 一票否决安全优先策略关键领域如财务审计、合规审查等场景往往采用保守策略。任一反对票立即终止流程。极简实现方案completionCondition ${rejectedCount 0 || nrOfCompletedInstances nrOfInstances} /completionCondition带自动终止的增强版taskService.complete(taskId, Variables.createVariables() .putValue(vote, reject) .putValue(terminateAll, true)); // 触发事件终止其他实例终止逻辑事件监听器public class TerminateListener implements TaskListener { public void notify(DelegateTask task) { if (task.getVariable(terminateAll) ! null) { runtimeService.createChangeActivityStateBuilder() .processInstanceId(task.getProcessInstanceId()) .cancelActivityInstance(task.getExecutionId()) .changeState(); } } }5. 一票通过快速通道机制适用于紧急情况处理或高层特权审批首个同意的审批人即可推动流程前进。基础配置模式completionCondition ${approvedCount 0} /completionCondition混合决策场景实践completionCondition !-- 常规情况需过半同意CEO审批可直接通过 -- ${(approvedCount quorum) || (approver.level CEO approved)} /completionCondition性能优化建议对高频使用的审批人添加缓存复杂表达式建议前置到服务任务计算并行实例数超过20时考虑分批次执行6. 高级技巧与避坑指南动态调整审批人列表runtimeService.setVariable( processInstanceId, approverList, newApprovers // 支持运行时调整参与人 );历史数据追踪方案SELECT TASK_DEF_KEY_ as task_key, VAR_TYPE_ as var_type, TEXT_ as decision FROM ACT_HI_VARINST WHERE PROC_INST_ID_ #{processInstanceId} AND NAME_ like vote_%常见异常处理空参与者列表添加前置校验sequenceFlow sourceRefcheckApprovers targetRefgroupApproval conditionExpression${!empty(approverList)}/conditionExpression /sequenceFlow表达式性能问题避免在循环条件中使用复杂计算变量作用域混淆明确指定变量作用域流程/任务实例在实施医疗设备采购审批系统时我们发现当会签节点存在动态分支时必须显式设置activiti:skipExpression以避免实例丢失。例如当某位审批人无需参与特定品类审批时userTask idmedicalReview activiti:skipExpression${productType ! Medical || approver.role ! MD}