flowable驳回/退回上一步/退回到

一、驳回/退回上一步/退回到(历史某一个节点)

    我们经常需要工作流中退回上一步,或者退回历史某一个节点。但由于流程的场景是很复杂的,回退有以下一些场景:

1.串行路线上的退回:流程中没有任何网关(排他网关/并行网关)和会签多实例。

2.退回到并行网关分支中的某一个节点上:

3.并行网关中的某一个分支节点上发起退回,退回到并行网关前面的某一个节点上

4.子流程中退回到主干流程中某一个节点/主干流程退回到子流程中某一个节点。

如下图:
在这里插入图片描述

二、flowable实现:

1.普通串行路线上的退回(此流程中没有并行网关的退回时),此方法支持普通串行节点/会签多实例节点/排他网关节点:

runtimeService.createChangeActivityStateBuilder()
.processInstanceId(proInstanceId)
.moveActivityIdsToSingleActivityId(curTaskKeys, targetTaskKey)
.changeState();
或者

moveActivityIdTo(String currentActivityId,String newActivityId);
2.并行网关中发起退回(即撤销当前的网关),这个地方不能用moveActivityIdTo(String currentActivityId,String newActivityId);是因为当某一个分支完成,它的is_active为0,另一条分支没有完成时。这时候这个方法是取不到所的分支的key的,它只有is_active为1的key能取到,不然就会造成多一条垃圾数据,同时再走并行时,任何一个分支不会等另一个分支就完走到分支的合并节点上,这就是bug,所以要改为以下方法:

// 并行网关的退回
List currentExecutionIds = new ArrayList<>();
List executions = runtimeService.createExecutionQuery().parentId(proInstanceId).list();
for (Execution execution : executions) {
System.out.println(“并行网关节点数:”+execution.getActivityId());
currentExecutionIds.add(execution.getId());
}
runtimeService.createChangeActivityStateBuilder()
.moveExecutionsToSingleActivityId(currentExecutionIds, targetTaskKey)
.changeState();
3.退回到并行网关中的某一个节点:经试验退回时必须同时退回并行网关中的所有分支。

List targetTaskKeys = new ArrayList<>();
targetTaskKeys.add(“sid-CA74ADED-7E70-451D-951C-95988BFC3F07”);
targetTaskKeys.add(“sid-7922C598-74FD-4848-95AC-D9790AF68432”);

runtimeService.createChangeActivityStateBuilder()
.processInstanceId(proInstanceId)
.moveSingleActivityIdToActivityIds(“sid-CAD50E6F-7E0C-437D-816B-DDBA1A976A79”, targetTaskKeys)
.changeState();
4.主干流程和子流程的退回(没有试验过),官方提供了以下方法:

moveActivityIdToParentActivityId(String currentActivityId, String newActivityId)

moveActivityIdToSubProcessInstanceActivityId(String currentActivityId, String newActivityId, String callActivityId)

moveActivityIdToSubProcessInstanceActivityId(String currentActivityId, String newActivityId, String callActivityId,Integer subProcessDefinitionVersion)
————————————————
版权声明:本文为CSDN博主「热水钟」的原创文章,遵循CC 4.0 by-sa版权协议
原文链接:https://blog.csdn.net/zhongzk69/article/details/90740662

### 如何在Flowable工作流引擎中实现驳回操作 #### 创建自定义服务任务处理程序 为了实现在特定条件下能够驳回流程实例的功能,通常会创建一个自定义的服务任务处理器。该处理器负责判断当前节点是否允许被驳回到前一环节,并执行相应的逻辑。 ```java public class RejectionHandler implements JavaDelegate { @Override public void execute(DelegateExecution execution) throws Exception { String currentActivityId = ((ExecutionEntity)execution).getCurrentActivityId(); // 获取变量以决定是否需要驳回 Boolean shouldReject = (Boolean) execution.getVariable("shouldReject"); if (shouldReject != null && shouldReject){ // 找到上一步活动ID List<HistoricActivityInstance> historicInstances = historyService.createHistoricActivityInstanceQuery() .processInstanceId(execution.getProcessInstanceId()) .orderByHistoricActivityInstanceId().asc() .list(); HistoricActivityInstance previousTask = findPreviousUserTask(historicInstances, currentActivityId); runtimeService.addComment(execution.getId(), previousTask.getTaskId(), "退回至:" + previousTask.getActivityName()); // 设置跳转标志位并触发事件 execution.setVariableLocal("rejection", true); execution.setVariableLocal("targetActivityId", previousTask.getActivityId()); // 跳过现有任务返回至上一用户任务 runtimeService.trigger(execution.getId()); } } private HistoricActivityInstance findPreviousUserTask(List<HistoricActivityInstance> instances, String excludeId){ Collections.reverse(instances); // 反向遍历历史记录以便找到最近的任务 for(HistoricActivityInstance instance : instances){ if(!instance.getActivityType().equals("userTask") || !excludeId.equals(instance.getActivityId())){ return instance; } } throw new RuntimeException("无法定位之前的用户任务!"); } } ``` 此代码片段展示了如何编写Java委托类`RejectionHandler`来处理驳回事宜[^2]。 #### 配置BPMN文件支持驳回路径 在设计业务流程模型时,在每个可能需要驳回的地方添加额外的网关和连接线指向先前的人工干预点。这可以通过图形化编辑器完成,比如Flowable Designer插件提供的工具。 ```xml <bpmn:userTask id="taskA" name="审核材料"/> <sequenceFlow sourceRef="taskA" targetRef="exclusiveGatewayAfterTaskA"/> <!-- Exclusive Gateway to decide whether rejection happens --> <bpmn:exclusiveGateway id="exclusiveGatewayAfterTaskA" default="toNextStep"> <!-- Define conditions here --> </bpmn:exclusiveGateway> <sequenceFlow id="toPrevStep" sourceRef="exclusiveGatewayAfterTaskA" targetRef="previousTask"> <conditionExpression xsi:type="tFormalExpression">${rejection}</conditionExpression> </sequenceFlow> <sequenceFlow id="toNextStep" sourceRef="exclusiveGatewayAfterTaskA" targetRef="nextTask"/> ``` 上述XML配置说明了当条件`${rejection}`成立时,则转向名为`previousTask`的前置任务;否则继续前进到下一个步骤[^3]。 #### 测试与验证 确保所有设置都已正确无误之后,可以在开发环境中部署更新后的流程定义版本,并通过启动新实例来进行测试。利用单元测试框架模拟不同场景下的输入参数变化情况,观察实际效果是否符合预期目标。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值