当前位置: 首页 > news >正文

Activiti7 会签多实例任务实战:动态审批人、一票否决与网关路由详解

1. 会签多实例任务的核心概念

会签是工作流中常见的审批场景,多个审批人需要同时对同一事项进行审批。在Activiti7中,这种需求可以通过多实例任务来实现。简单来说,就是把一个任务复制成多份,分发给不同的审批人。

想象一下公司采购申请的审批流程:财务、法务、技术三个部门需要同时审核。传统串行审批需要等前一个部门完成才能到下一个,而会签模式下三个部门可以同时处理,效率提升明显。

Activiti7的多实例任务实现依赖于三个关键属性:

  • collection:审批人集合,比如["财务","法务","技术"]
  • elementVariable:当前处理的审批人变量名
  • completionCondition:任务完成条件

实际项目中我遇到过这样的坑:忘记设置elementVariable导致任务无法分配。正确的做法应该像这样配置:

<multiInstanceLoopCharacteristics activiti:collection="approvers" activiti:elementVariable="approver"> <completionCondition>${nrOfCompletedInstances/nrOfInstances >= 0.6}</completionCondition> </multiInstanceLoopCharacteristics>

2. 动态设置审批人实战

静态配置审批人的方式在实际开发中基本不可行,因为审批人可能来自组织架构、角色配置或特定业务规则。通过RuntimeService传递动态审批人集合才是正确姿势。

最近给客户做OA系统时,我们是这样实现的:先通过组织架构接口获取部门经理列表,再结合业务规则过滤出最终审批人。核心代码如下:

// 获取动态审批人列表 List<String> approvers = orgService.getDepartmentManagers(deptId); // 添加业务规则筛选 approvers = approvers.stream() .filter(u -> !conflictCheckService.hasConflict(u, businessId)) .collect(Collectors.toList()); // 启动流程时传入变量 Map<String, Object> vars = new HashMap<>(); vars.put("approvers", approvers); vars.put("approverCount", approvers.size()); runtimeService.startProcessInstanceByKey("multiApprove", vars);

特别注意:当审批人列表为空时需要特殊处理。我们的做法是添加默认审批人并记录告警日志,避免流程卡死。

3. 一票否决机制的实现

一票否决是会签流程的关键特性。在Activiti中可以通过两种方式实现:

  1. 完成条件表达式
<completionCondition> ${rejected || nrOfCompletedInstances == nrOfInstances} </completionCondition>
  1. 执行监听器动态干预
public class RejectListener implements ExecutionListener { @Override public void notify(DelegateExecution execution) { String comment = (String)execution.getVariable("comment"); if("reject".equals(comment)){ execution.setVariable("rejected", true); // 强制终止其他实例 runtimeService.deleteMultiInstanceExecution( execution.getId(), false); } } }

实测发现第一种方式更简洁,但第二种更灵活。比如我们有个项目需要在否决时自动发送加急通知,就只能用监听器实现。

4. 网关路由的智能判断

会签完成后通常需要根据结果路由到不同分支。排他网关(Exclusive Gateway)配合条件表达式是最佳选择。这里分享几个实用技巧:

条件表达式优化

<conditionExpression xsi:type="tFormalExpression"> <!-- 更健壮的判断逻辑 --> ${!rejected && approvedCount > 0} </conditionExpression>

常见问题排查

  1. 表达式返回null会导致流程挂起
  2. 变量作用域问题(建议使用execution.setVariable)
  3. 类型转换异常(字符串和布尔值比较要特别注意)

在最近的项目中,我们封装了安全的条件表达式工具类:

public class ExpressionUtil { public static boolean safeEval(DelegateExecution exec, String expr) { try { Object result = runtimeService .createConditionEvaluation(exec) .evaluate(expr); return Boolean.TRUE.equals(result); } catch (Exception e) { log.warn("表达式执行失败", e); return false; } } }

5. 完整实现案例解析

结合上述知识点,我们来看一个生产级实现。这个案例包含以下特性:

  • 动态审批人设置
  • 一票否决机制
  • 智能路由判断
  • 审批意见收集

流程定义关键部分

<userTask id="multiApprove" name="会签审批"> <multiInstanceLoopCharacteristics activiti:collection="${approvers}" activiti:elementVariable="currentApprover"> <completionCondition> ${rejected || nrOfCompletedInstances == nrOfInstances} </completionCondition> </multiInstanceLoopCharacteristics> <extensionElements> <activiti:formProperty id="comment" /> <activiti:executionListener event="end" class="com.example.RejectListener"/> </extensionElements> </userTask> <exclusiveGateway id="decisionGateway" /> <sequenceFlow sourceRef="decisionGateway" targetRef="rejectTask"> <conditionExpression>${rejected}</conditionExpression> </sequenceFlow> <sequenceFlow sourceRef="decisionGateway" targetRef="nextStep"> <conditionExpression>${!rejected}</conditionExpression> </sequenceFlow>

监听器实现要点

public class RejectListener implements ExecutionListener { @Override public void notify(DelegateExecution exec) { String comment = (String)exec.getVariable("comment"); if(comment != null && comment.contains("拒绝")){ // 设置否决标志 exec.setVariable("rejected", true); // 记录否决人 String rejecter = (String)exec.getVariable("currentApprover"); exec.setVariable("rejecter", rejecter); // 发送实时通知 notifyService.sendRejectAlert(rejecter); } } }

这个方案在某大型企业的合同审批流程中稳定运行了2年多,日均处理3000+流程实例。关键优化点在于:

  1. 使用异步监听器处理通知逻辑
  2. 添加了完备的日志记录
  3. 对边界条件做了充分处理

6. 性能优化与常见问题

在大规模使用会签任务时,我们踩过不少性能坑。这里分享几个关键优化点:

审批人集合优化

  • 控制审批人数量(建议不超过20人)
  • 使用缓存减少组织架构查询
  • 分批处理超大规模审批

数据库优化

-- 添加必要的索引 CREATE INDEX idx_act_ru_exec_mi ON act_ru_execution(proc_inst_id_, is_mi_root_); -- 定期清理历史数据

常见问题解决方案

  1. 任务卡住:检查nrOfInstances和nrOfActiveInstances是否一致
  2. 网关不触发:确认条件表达式变量已正确设置
  3. 监听器不执行:检查event类型是否匹配(start/end)

在最近一次性能调优中,我们通过以下改动将处理速度提升了5倍:

  • 将同步监听器改为异步
  • 优化变量存储(大对象存MongoDB)
  • 添加流程实例缓存

7. 扩展应用场景

会签模式不仅适用于审批流程,还可以灵活应用于这些场景:

技术评审

  • 代码审查多人并行评审
  • 测试用例多人验证
  • 架构设计多方确认

业务场景

  • 采购多方比价
  • 合同多方签署
  • 项目多方验收

最近我们实现了一个创新的应用:在DevOps流程中使用会签任务控制发布流程。当多个系统需要同时发布时,各系统负责人并行确认准备状态,全部就绪后自动触发发布。关键实现点在于动态设置审批人为各系统负责人,并设置超时自动通过机制。

// 动态设置超时自动通过 timerService.schedule(new Runnable(){ public void run(){ if(!taskService.createTaskQuery() .processInstanceId(procId) .unfinished().list().isEmpty()){ // 自动完成所有任务 tasks.forEach(t -> taskService.complete(t.getId(), autoApproveVars)); } } }, 2, TimeUnit.HOURS);
http://www.jsqmd.com/news/821966/

相关文章:

  • 郑州墙面翻新修补:巩义墙面粉刷公司有哪些 - LYL仔仔
  • 学院教学工作量统计|基于java+ vue学院教学工作量统计管理系统(源码+数据库+文档)
  • GP8891CAS_SOP7原边反馈电源芯片 三绕组应用电路、双绕组应用电路分析
  • 开源监控系统clawatch:轻量级云原生监控与告警实践指南
  • Taotoken的Token Plan套餐为我们的小型项目带来了哪些成本优势
  • 2026胶州市黄金回收白银回收铂金回收店铺实力排行榜TOP5; K金+金条+银条+首饰回收靠谱门店及联系方式推荐_转自TXT - 盛世金银回收
  • 拷贝到linux的路径
  • 如何通过浏览器脚本实现网盘文件直链下载:LinkSwift 完全指南
  • 2026兰州市黄金回收白银回收铂金回收店铺实力排行榜TOP5; K金+金条+银条+首饰回收靠谱门店及联系方式推荐_转自TXT - 盛世金银回收
  • 小型房屋租赁|基于Java + vue小型房屋租赁系统(源码+数据库+文档)
  • 抚州冷轧钢筋加工定制怎么选?关键考量与供应渠道梳理 - 品牌推荐大师
  • ClickHouse运维实战:如何用一条SQL快速定位HTTP接口报错原因(附常见错误代码速查表)
  • 武哥带你谈谈-RHEL 网络配置十年变迁:从 ifcfg 到 Keyfile,/etc/sysconfig/network-scripts/ 是如何退出历史舞台的?
  • 永辉超市卡回收价目查询全解析 - 购物卡回收找京尔回收
  • 你的高速信号被TVS管拖慢了吗?RS485/CAN总线防护的结电容避坑指南
  • 2026阆中市黄金回收白银回收铂金回收店铺实力排行榜TOP5; K金+金条+银条+首饰回收靠谱门店及联系方式推荐_转自TXT - 盛世金银回收
  • 2026揭阳市黄金回收白银回收铂金回收店铺实力排行榜TOP5; K金+金条+银条+首饰回收靠谱门店及联系方式推荐_转自TXT - 盛世金银回收
  • 2026廊坊市黄金回收白银回收铂金回收店铺实力排行榜TOP5; K金+金条+银条+首饰回收靠谱门店及联系方式推荐_转自TXT - 盛世金银回收
  • 还在为论文 AI 痕迹和重复率头秃?okbiye 这套组合拳,直接帮你把问题打穿
  • 终极MTK设备BootROM保护绕过工具:快速解锁联发科设备的安全屏障
  • 2026界首市黄金回收白银回收铂金回收店铺实力排行榜TOP5; K金+金条+银条+首饰回收靠谱门店及联系方式推荐_转自TXT - 盛世金银回收
  • 2026 土工布厂家推荐:恒全土工布实力雄厚 - 19120507004
  • 别再只用中继了!OpenWrt无线桥接模式下,如何让打印服务器和Samba跨网段被访问?
  • 使用taotoken后我们的月度ai账单变得清晰可预测了
  • 从TUM到KITTI:手把手教你用EVO搞定多格式SLAM轨迹分析与精美绘图
  • 保姆级教程:在HCL模拟器上给H3C路由器配置DHCP服务器(双网段实战)
  • 终极免费NCM音乐解锁工具:3分钟掌握ncmppGui的完整使用指南
  • 星链引擎矩阵系统:内容资产全生命周期管理与智能标签体系技术实践
  • 2026乐昌市黄金回收白银回收铂金回收店铺实力排行榜TOP5; K金+金条+银条+首饰回收靠谱门店及联系方式推荐_转自TXT - 盛世金银回收
  • 终极指南:如何使用efinance快速获取免费金融数据