Camunda工作流的退回操作
话不多说,直接上代码
代码块 1:
/**
* 退回到起点
*/
@Test
public void deny(){
String processInstanceId = "37f9f9f4-9f72-11ec-8d1f-5254000c17ac";
Task activeTask = taskService.createTaskQuery()
.processInstanceId(processInstanceId)
.active()
.singleResult();
HistoricTaskInstance taskInstance = historyService.createHistoricTaskInstanceQuery()
.taskId(activeTask.getId())
.singleResult();
// 获取流程定义
ProcessDefinitionEntity processDefinitionEntity = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService).getDeployedProcessDefinition(taskInstance.getProcessDefinitionId());
// 获取当前活动
ActivityImpl currentActivity = processDefinitionEntity.findActivity(taskInstance.getTaskDefinitionKey());
// 获取起始活动
List<HistoricActivityInstance> historicActivityInstances = historyService.createHistoricActivityInstanceQuery()
.activityType("userTask")
.processInstanceId(processInstanceId)
.finished()
.orderByHistoricActivityInstanceEndTime()
.asc()
.list();
if(historicActivityInstances.size() == 0){
return ;
}
ActivityImpl lastActivity = processDefinitionEntity.findActivity(historicActivityInstances.get(0).getActivityId());
// 退回至起点
runtimeService.createProcessInstanceModification(processInstanceId)
.cancelAllForActivity(currentActivity.getActivityId())
.startBeforeActivity(lastActivity.getActivityId())
.setVariable("denyReason","就是搞你,就给你退回去")
.execute();
}
这段代码是参考Camunda官网来写来的,具体地址: https://docs.camunda.org/manual/7.15/user-guide/process-engine/process-instance-modification/#process-instance-modification-in-junit-tests
还有一段代码是参照activiti的退回写的,代码如下:
代码块 2:
/**
* 任务回退到开始
*/
@Test
public void rollBackToShangYiJi(){
//String processInstanceId = "49b521ac-9f50-11ec-8d1f-5254000c17ac";
String processInstanceId = "37f9f9f4-9f72-11ec-8d1f-5254000c17ac";
// 根据流程实例 id 获取当前任务
Task activeTask = taskService.createTaskQuery()
.processInstanceId(processInstanceId)
.active()
.singleResult();
HistoricTaskInstance taskInstance = historyService.createHistoricTaskInstanceQuery()
.taskId(activeTask.getId())
.singleResult();
// 获取流程定义
ProcessDefinitionEntity processDefinitionEntity = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService).getDeployedProcessDefinition(taskInstance.getProcessDefinitionId());
// 获取当前活动
ActivityImpl currentActivity = processDefinitionEntity.findActivity(taskInstance.getTaskDefinitionKey());
//清除当前活动出口
List<PvmTransition> originPvmTransitions = new ArrayList<>();
List<PvmTransition> pvmTransitionList = currentActivity.getOutgoingTransitions();
for (PvmTransition pvmTransition : pvmTransitionList) {
originPvmTransitions.add(pvmTransition);
}
pvmTransitionList.clear();
//查找最开始的user task节点
List<HistoricActivityInstance> historicActivityInstances = historyService.createHistoricActivityInstanceQuery()
.activityType("userTask")
.processInstanceId(processInstanceId)
.finished()
.orderByHistoricActivityInstanceEndTime()
.asc()
.list();
TransitionImpl transition = null;
if(historicActivityInstances.size() > 0){
ActivityImpl lastActivity = processDefinitionEntity.findActivity(historicActivityInstances.get(0).getActivityId());
//把当前任务的新出口设置为最开始的userTask节点
transition = currentActivity.createOutgoingTransition(lastActivity.getId());
transition.setDestination(lastActivity);
}
// 完成任务
List<Task> tasks = taskService.createTaskQuery()
.processInstanceId(processInstanceId)
.taskDefinitionKey(taskInstance.getTaskDefinitionKey())
.list();
for(Task task : tasks){
taskService.complete(task.getId());
historyService.deleteHistoricTaskInstance(task.getId());
}
//恢复活动方向
currentActivity.getOutgoingTransitions().remove(transition);
for (PvmTransition pvmTransition : originPvmTransitions) {
pvmTransitionList.add(pvmTransition);
}
}
参考网址:https://blog.csdn.net/qq_41136963/article/details/108184871
目前存在的问题
代码块1:
无法添加退回意见
代码块2:
测试时可以反复退回
但在实际环境下,二次退回时,节点的namedOutgoingTransitions无法清空,导致无法使当前节点的出口设置为起始节点
博主在找不到解决方案的情况下选择了代码块1
关于退回到上一级
假如存在 o -> 1 -> 2 ->3 -> O 的流程
如果用户在2节点和3节点之间反复横跳,来回的同意和退回,就会导致出现一大堆的historicActivityInstances数据
如果还使用上面的两个代码块中的代码,仅仅通过调整数字下标是无法准确定位到当前节点的上一级节点的
如何准确的获取需要用到一个有序不重复的集合LinkedHashSet
// 新建一个有序不重复集合
LinkedHashSet linkedHashSet = new LinkedHashSet();
// 获取当前的任务节点
String activeTask = "Activity_0lj34xv";
String backTask = "";
historyService.createHistoricTaskInstanceQuery().processInstanceId(processInstanceId).orderByHistoricTaskInstanceEndTime().asc().list().stream().forEach(historicTaskInstance -> {
linkedHashSet.add(historicTaskInstance.getTaskDefinitionKey());
});
if(linkedHashSet.size() == 0){
return ;
}
// 遍历到当前的任务节点后,取上一次遍历的值
Iterator<String> iterator = linkedHashSet.iterator();
while(iterator.hasNext()){
String nowTask = iterator.next();
if(StrUtil.equals(nowTask,activeTask)){
return backTask;
}
backTask = nowTask;
}
backTask.toString();
关于添加退回意见
在退回起点之前,直接选中当前任务节点添加comment即可
关于任务状态的分辨
源码里对任务状态的标识
可以根据自己需要做简单转换
int state = ((HistoricActivityInstanceEntity) historicActivityInstance).getActivityInstanceState();
if (state == ActivityInstanceState.ENDING.getStateCode()){
activityInfoVo.setResult("同意");
}else if(state == ActivityInstanceState.CANCELED.getStateCode()){
activityInfoVo.setResult("退回");
}else if(state == ActivityInstanceState.DEFAULT.getStateCode()){
activityInfoVo.setResult("进行中");
}