package com.pty.workflow.service.extend;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import org.activiti.bpmn.model.ExclusiveGateway;
import org.activiti.bpmn.model.FlowElement;
import org.activiti.bpmn.model.FlowNode;
import org.activiti.bpmn.model.Process;
import org.activiti.bpmn.model.SequenceFlow;
import org.activiti.bpmn.model.StartEvent;
import org.activiti.bpmn.model.UserTask;
import org.activiti.engine.HistoryService;
import org.activiti.engine.delegate.event.ActivitiEventDispatcher;
import org.activiti.engine.delegate.event.ActivitiEventType;
import org.activiti.engine.delegate.event.impl.ActivitiEventBuilder;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.impl.cmd.NeedsActiveTaskCmd;
import org.activiti.engine.impl.context.Context;
import org.activiti.engine.impl.interceptor.CommandContext;
import org.activiti.engine.impl.persistence.entity.ExecutionEntity;
import org.activiti.engine.impl.persistence.entity.HistoricIdentityLinkEntity;
import org.activiti.engine.impl.persistence.entity.TaskEntity;
import org.activiti.engine.task.Task;
import com.pty.workflow.api.RollbackPosition;
import lombok.extern.slf4j.Slf4j;
@Slf4j
/* @Service */
public class RollbackTaskCmd extends NeedsActiveTaskCmd<Void> {
/**
*
*/
private static final long serialVersionUID = 1264547749014497759L;
private RollbackPosition _position;
private String _designatedNodeId;
private String _exeNodeId;
public RollbackTaskCmd(String taskId, RollbackPosition position, String exeNodeId,String... designatedNodeId) {
super(taskId);
_position = position;
_exeNodeId = exeNodeId;
if (designatedNodeId.length > 0) {
_designatedNodeId = designatedNodeId[0];
}
}
@Override
protected Void execute(CommandContext commandContext, TaskEntity task) {
ActivitiEventDispatcher eventDispatcher = Context.getProcessEngineConfiguration().getEventDispatcher();
// TODO(liubo): 增加退回的enum
if (eventDispatcher.isEnabled()) {
eventDispatcher
.dispatchEvent(ActivitiEventBuilder.createEntityEvent(ActivitiEventType.TASK_COMPLETED, task));
}
if (task.getExecutionId() != null) {
ExecutionEntity executionEntity = commandContext.getExecutionEntityManager()
.findExecutionById(task.getExecutionId());
if (_position.equals(RollbackPosition.START)) {
rollback2Start(commandContext, task, executionEntity);
} else if (_position.equals(RollbackPosition.PREVIOUS)) {
rollback2Previous(commandContext, task, executionEntity);
} else if (_position.equals(RollbackPosition.DESIGNATED)) {
rollback2Designated(commandContext, task, executionEntity,_exeNodeId);
}
// Context.getAgenda().planTriggerExecutionOperation(executionEntity);
}
return null;
}
// 退回到流程初始的任务节点
private void rollback2Start(CommandContext commandContext, TaskEntity task, ExecutionEntity executionEntity) {
// TODO(liubo): 设置creator
String creator=this.getProcessCreator(task, commandContext);
task.setVariable("creator", this.getProcessCreator(task, commandContext));
List<TaskEntity> tasks = commandContext.getTaskEntityManager().findTasksByExecutionId(task.getExecutionId());
tasks.forEach(taskEntity -> {
// commandContext.getTaskEntityManager().delete(taskEntity);
commandContext.getTaskEntityManager().deleteTask(taskEntity, null, false);
});
Process process = Context.getProcessEngineConfiguration().getRepositoryService()
.getBpmnModel(task.getProcessDefinitionId()).getMainProcess();
String firstUserTaskNode = process.findFlowElementsOfType(StartEvent.class).get(0).getOutgoingFlows().get(0)
.getTargetRef();
task.fireEvent("rollback");
executionEntity.removeTask(task);
executionEntity.executeActivity(executionEntity.getProcessDefinition().findActivity(firstUserTaskNode));
}
// 退回到上一个任务节点
private void rollback2Previous(CommandContext commandContext, TaskEntity task, ExecutionEntity executionEntity) {
commandContext.getTaskEntityManager().deleteTask(task, null, false);
// HistoryManager historyManager = commandContext.getHistoryManager();
// historyManager.recordTaskEnd(taskId, "shareniu-jump");
Process process = Context.getProcessEngineConfiguration().getRepositoryService()
.getBpmnModel(task.getProcessDefinitionId()).getMainProcess();
List<FlowElement> prevNode = getPrevousNode(task, process);
List<Task> list = Context.getProcessEngineConfiguration().getTaskService().createTaskQuery()
.processInstanceId(task.getProcessInstanceId()).list();
if (list.size() >= 2) {
for (Task task2 : list) {
if (!task2.getId().equals(task.getId())) {
commandContext.getTaskEntityManager().deleteTask((TaskEntity) task2, null, false);
}
}
}
prevNode.stream().forEach(node -> {
if (node == null) {
throw new RuntimeException("前置任务节点未找到");
}
if (((FlowNode) node).getIncomingFlows().stream().anyMatch(ele -> {
String s=ele.getSourceRef();
return StartEvent.class.isAssignableFrom(process.getFlowElement(ele.getSourceRef()).getClass());
})) {
task.setVariable("creator", this.getProcessCreator(task, commandContext));
}
// TODO(liubo):如果退回的是第一个任务节点,将creator注入
task.fireEvent("rollback");
executionEntity.removeTask(task);
/*String processDefinitionId = task.getProcessDefinitionId();
ProcessDefinitionEntity processDefinitionEntity = new GetDeploymentProcessDefinitionCmd(processDefinitionId).execute(commandContext);
ActivityImpl activityImpl = processDefinitionEntity.findActivity(task.getTaskDefinitionKey());
Map<String, Object> currMap = activityImpl.getProperties();
if (currMap.containsKey("multiInstance")) { // 删除当前多实例任务
// executionEntity= task.getExecution().getParent().getParent(); //taskEntity.getExecution();
this.deleteExecution(task);
}
executionEntity.setProcessInstance(executionEntity);
executionEntity.setProcessDefinitionId(historicActivityInstanceEntity.getProcessDefinitionId());
executionEntity.setActivity(targetActivity);
executionEntity.setActive(false);
executionEntity.setConcurrent(false);
executionEntity.setCachedEntityState(0);*/
executionEntity.executeActivity(executionEntity.getProcessDefinition().findActivity(node.getId()));
});
}
/*public void deleteExecution(TaskEntity taskEntity) {
// 删除未处理任务信息
List<TaskEntity> taskEntities = Context.getCommandContext().getTaskEntityManager().findTasksByProcessInstanceId(taskEntity.getProcessInstanceId());
for (TaskEntity taskEntity2 : taskEntities) {
List<VariableInstanceEntity> varLis = Context.getCommandContext().getVariableInstanceEntityManager().findVariableInstancesByExecutionId(taskEntity2.getExecutionId());
for (VariableInstanceEntity variableInstanceEntity : varLis) {
Context.getCommandContext().getVariableInstanceEntityManager().delete(variableInstanceEntity);
}
Context.getCommandContext().getExecutionEntityManager().delete(taskEntity2.getExecution());
}
// 获取多实例同节点处理任务
HistoricTaskInstanceQueryImpl historicTaskInstanceQueryImpl = new HistoricTaskInstanceQueryImpl();
historicTaskInstanceQueryImpl.taskDefinitionKey(taskEntity.getTaskDefinitionKey());
historicTaskInstanceQueryImpl.processInstanceId(taskEntity.getProcessInstanceId());
historicTaskInstanceQueryImpl.setFirstResult(0);
historicTaskInstanceQueryImpl.setMaxResults(999);
historicTaskInstanceQueryImpl.orderByTaskCreateTime().asc();
List<HistoricTaskInstance> historicTaskInstanceList = (List<HistoricTaskInstance>) Context.getCommandContext()
.getHistoricTaskInstanceEntityManager().findHistoricTaskInstancesByQueryCriteria(historicTaskInstanceQueryImpl);
if (historicTaskInstanceList != null && historicTaskInstanceList.size() > 0) {
for (HistoricTaskInstance historicTaskInstance : historicTaskInstanceList) {
ExecutionEntity executionEntity = Context.getCommandContext().getExecutionEntityManager().findExecutionById(historicTaskInstance.getExecutionId());
if(executionEntity != null) {
List<VariableInstanceEntity> hisVarLis = Context.getCommandContext().getVariableInstanceEntityManager().findVariableInstancesByExecutionId(executionEntity.getId());
for (VariableInstanceEntity variableInstanceEntity : hisVarLis) {
Context.getCommandContext().getVariableInstanceEntityManager().delete(variableInstanceEntity);
}
Context.getCommandContext().getExecutionEntityManager().delete(executionEntity);
}
}
}
// 删除多实例父节点信息
ExecutionEntity parent = Context.getCommandContext().getExecutionEntityManager().findExecutionById(taskEntity.getExecution().getParentId());
List<VariableInstanceEntity> varLis = Context.getCommandContext().getVariableInstanceEntityManager().findVariableInstancesByExecutionId(parent.getId());
for (VariableInstanceEntity variableInstanceEntity : varLis) {
Context.getCommandContext().getVariableInstanceEntityManager().delete(variableInstanceEntity);
}
Context.getCommandContext().getExecutionEntityManager().delete(parent);
}
public void deleteExecution(ExecutionEntity executionEntity) {
Context.getCommandContext().getExecutionEntityManager().delete(executionEntity);
}
*/
private void rollback2Designated(CommandContext commandContext, TaskEntity task, ExecutionEntity executionEntity, String _exeNodeId) {
commandContext.getTaskEntityManager().deleteTask(task, null, false);
// HistoryManager historyManager = commandContext.getHistoryManager();
// historyManager.recordTaskEnd(taskId, "shareniu-jump");
Process process = Context.getProcessEngineConfiguration().getRepositoryService()
.getBpmnModel(task.getProcessDefinitionId()).getMainProcess();
//List<FlowElement> prevNode = getPrevousNode(task, process);
FlowNode sss = (FlowNode)process.getFlowElement(_exeNodeId);
List<FlowNode> prevNode =new ArrayList<FlowNode>();
prevNode.add(sss);
prevNode.stream().forEach(node -> {
if (node == null) {
throw new RuntimeException("前置任务节点未找到");
}
if (((FlowNode) node).getIncomingFlows().stream().anyMatch(ele -> {
String s=ele.getSourceRef();
return StartEvent.class.isAssignableFrom(process.getFlowElement(ele.getSourceRef()).getClass());
})) {
task.setVariable("creator", this.getProcessCreator(task, commandContext));
}
// TODO(liubo):如果退回的是第一个任务节点,将creator注入
task.fireEvent("rollback");
executionEntity.removeTask(task);
/*String processDefinitionId = task.getProcessDefinitionId();
ProcessDefinitionEntity processDefinitionEntity = new GetDeploymentProcessDefinitionCmd(processDefinitionId).execute(commandContext);
ActivityImpl activityImpl = processDefinitionEntity.findActivity(task.getTaskDefinitionKey());
Map<String, Object> currMap = activityImpl.getProperties();
if (currMap.containsKey("multiInstance")) { // 删除当前多实例任务
// executionEntity= task.getExecution().getParent().getParent(); //taskEntity.getExecution();
this.deleteExecution(task);
}
executionEntity.setProcessInstance(executionEntity);
executionEntity.setProcessDefinitionId(historicActivityInstanceEntity.getProcessDefinitionId());
executionEntity.setActivity(targetActivity);
executionEntity.setActive(false);
executionEntity.setConcurrent(false);
executionEntity.setCachedEntityState(0);*/
executionEntity.executeActivity(executionEntity.getProcessDefinition().findActivity(node.getId()));
});
//throw new RuntimeException("暂不支持退回到任一指定节点");
}
/*private List<FlowNode> getPrevousNode(TaskEntity task, Process process) {
ProcessDefinitionEntity processDefinitionEntity = null;
String id = null;
TaskDefinition taskDef = null;
String type = null;
Map<String, Object> map = new HashMap<String, Object>();
// 获取流程实例Id信息
TaskService taskService = Context.getProcessEngineConfiguration().getTaskService();
Task Task = Context.getProcessEngineConfiguration().getTaskService().createTaskQuery().taskId(taskId)
.singleResult();
String processInstanceId = Context.getProcessEngineConfiguration().getTaskService().createTaskQuery()
.taskId(taskId).singleResult().getProcessInstanceId();
String executionId = Context.getProcessEngineConfiguration().getTaskService().createTaskQuery().taskId(taskId)
.singleResult().getExecutionId();
// 获取流程发布Id信息
String definitionId = Context.getProcessEngineConfiguration().getRuntimeService().createProcessInstanceQuery()
.processInstanceId(processInstanceId).singleResult().getProcessDefinitionId();
processDefinitionEntity = (ProcessDefinitionEntity) ((RepositoryServiceImpl) Context
.getProcessEngineConfiguration().getRepositoryService()).getDeployedProcessDefinition(definitionId);
List<Execution> execution = Context.getProcessEngineConfiguration().getRuntimeService().createExecutionQuery()
.executionId(executionId).list();
if (execution.size() == 1) {
// execution.getActivityId();
// 当前流程节点Id信息
String activitiId = execution.get(0).getActivityId();
// 获取流程所有节点信息
List<ActivityImpl> activitiList = processDefinitionEntity.getActivities();
// 遍历所有节点信息
for (ActivityImpl activityImpl : activitiList) {
id = activityImpl.getId();
// 找到当前节点信息
if (activitiId.equals(id)) {
// 判断上一个节点信息是 什么类型
map = lastNodeType(activityImpl, activityImpl.getId(), processInstanceId);
break;
}
}
} else {
}
if (map.get("type") != null && map.get("type").equals("parallelGateway")) {
List<FlowNode> flowNodes = new ArrayList<FlowNode>();
String activityId = (String) map.get("activityId");
FlowNode node = (FlowNode) process.getFlowElement(activityId);
List<SequenceFlow> list = node.getIncomingFlows();
for (SequenceFlow sequenceFlow : list) {
FlowElement flowElement = process.getFlowElement(sequenceFlow.getSourceRef());
FlowNode flowNode = (FlowNode) flowElement;
flowNodes.add(flowNode);
}
return flowNodes;
} else if (map.get("type").equals("userTask")) {
List<FlowNode> flowNodes = new ArrayList<FlowNode>();
List<HistoricActivityInstance> taskHis = Context.getProcessEngineConfiguration().getHistoryService()
.createHistoricActivityInstanceQuery().executionId(task.getExecutionId()).finished()
.orderByHistoricActivityInstanceEndTime().desc().list();
FlowNode flowNode = (FlowNode) process.getFlowElement(taskHis.get(0).getActivityId());
flowNodes.add(flowNode);
return flowNodes;
} else{
List<FlowNode> flowNodes = new ArrayList<FlowNode>();
List<HistoricActivityInstance> taskHis3 = Context.getProcessEngineConfiguration().getHistoryService()
.createHistoricActivityInstanceQuery().executionId(task.getExecutionId()).finished()
.orderByHistoricActivityInstanceEndTime().desc().list();
FlowNode flowNode = (FlowNode) process.getFlowElement(taskHis3.get(0).getActivityId());
flowNodes.add(flowNode);
return flowNodes;
}
}*/
private List<FlowElement> getPrevousNode(TaskEntity task, Process process) {
/*List<HistoricActivityInstance> historyActivitys = Context.getProcessEngineConfiguration().getHistoryService()
.createNativeHistoricActivityInstanceQuery("").list();*/
List<HistoricActivityInstance> taskHis = Context.getProcessEngineConfiguration().getHistoryService()
.createHistoricActivityInstanceQuery().processInstanceId(task.getProcessInstanceId()).finished()
.orderByHistoricActivityInstanceEndTime().desc().list();
List<HistoricActivityInstance> taskHis1 = Context.getProcessEngineConfiguration().getHistoryService()
.createHistoricActivityInstanceQuery().processInstanceId(task.getProcessInstanceId()).finished()
.orderByHistoricActivityInstanceEndTime().desc().list();
HistoricActivityInstance maxExecuteElement = taskHis.stream().filter(activity->{
FlowElement ele = process.getFlowElement(activity.getActivityId());
if (ele == null) {
return false;
}
if (!(ele instanceof FlowNode)) {
return false;
}
if (activity.getActivityType().equals("exclusiveGateway")) {
return false;
}
return true;
}).max((a, b)->{
return a.getEndTime().compareTo(b.getEndTime());
}).get();
List<SequenceFlow> list2=new ArrayList<>();
List<FlowElement> listFlowElement=new ArrayList<FlowElement>();
if (maxExecuteElement.getActivityType().equals("userTask")) {
FlowNode node = (FlowNode)process.getFlowElement(maxExecuteElement.getActivityId());
List<SequenceFlow> list=node.getOutgoingFlows();
for (SequenceFlow sequenceFlow : list) {
String targetRef=sequenceFlow.getTargetRef();
FlowNode node2 = (FlowNode) process.getFlowElement(targetRef);
String name=node2.getName();
/*if(name==null){
list2=node2.getIncomingFlows();
for (SequenceFlow sequenceFlow2 : list2) {
FlowElement flowElement=process.getFlowElement(sequenceFlow2.getSourceRef());
listFlowElement.add(flowElement);
}
}else{
FlowElement flowElement =process.getFlowElement(maxExecuteElement.getActivityId());
listFlowElement.add(flowElement);
}*/
FlowElement flowElement =process.getFlowElement(maxExecuteElement.getActivityId());
listFlowElement.add(flowElement);
}
return listFlowElement;
//return Arrays.asList(process.getFlowElement(maxExecuteElement.getActivityId()));
} else if (maxExecuteElement.getActivityType().equals("parallelGateway")) {
FlowNode node = (FlowNode)process.getFlowElement(maxExecuteElement.getActivityId());
return node.getIncomingFlows().stream().map(sequence->{
return process.getFlowElement(sequence.getSourceRef());
}).collect(Collectors.toList());
} else {
return new ArrayList<FlowElement>();
}
}
/*private List<FlowElement> getPrevousNode(TaskEntity task, Process process) {
List<HistoricActivityInstance> historyActivitys = Context.getProcessEngineConfiguration().getHistoryService()
.createNativeHistoricActivityInstanceQuery().list();
HistoricActivityInstance maxExecuteElement = historyActivitys.stream().filter(activity->{
FlowElement ele = process.getFlowElement(activity.getActivityId());
if (ele == null) {
return false;
}
if (!(ele instanceof FlowNode)) {
return false;
}
if (activity.getActivityType().equals("exclusiveGateway")) {
return false;
}
return true;
}).max((a, b)->{
return a.getEndTime().compareTo(b.getEndTime());
}).get();
if (maxExecuteElement.getActivityType().equals("userTask")) {
return Arrays.asList(process.getFlowElement(maxExecuteElement.getActivityId()));
} else if (maxExecuteElement.getActivityType().equals("parallelGateway")) {
FlowNode node = (FlowNode)process.getFlowElement(maxExecuteElement.getActivityId());
return node.getIncomingFlows().stream().map(sequence->{
return process.getFlowElement(sequence.getSourceRef());
}).collect(Collectors.toList());
} else {
return new ArrayList<FlowElement>();
}
}*/
/*private Map<String, Object> lastNodeType(ActivityImpl activityImpl, String id, String processInstanceId) {
PvmActivity ac = null;
Object s = null;
// 如果遍历节点为用户任务并且节点不是当前节点信息
if ("userTask".equals(activityImpl.getProperty("type")) && !id.equals(activityImpl.getId())) {
} else {
// 获取节点所有流向线路信息
List<PvmTransition> outTransitions = activityImpl.getOutgoingTransitions();
List<PvmTransition> outTransitionsTemp = null;
List<PvmTransition> incomings = activityImpl.getIncomingTransitions();
List<PvmTransition> incomingsTemp = null;
for (PvmTransition pvmTransition : incomings) {
ac = pvmTransition.getDestination();
PvmActivity source = pvmTransition.getSource();
String a = (String) source.getProperty("type");
if ("exclusiveGateway".equals(source.getProperty("type"))) {
incomingsTemp = source.getIncomingTransitions();
if (incomingsTemp.size() == 1) {
String actId = source.getId();
Map<String, Object> map = new HashMap<String, Object>();
map.put("activityId", source.getId());
map.put("type", "exclusiveGateway");
return map;
}
} else if ("userTask".equals(source.getProperty("type"))) {
String actId = source.getId();
Map<String, Object> map = new HashMap<String, Object>();
map.put("activityId", source.getId());
map.put("type", "userTask");
return map;
} else if ("parallelGateway".equals(source.getProperty("type"))) {
String actId = source.getId();
Map<String, Object> map = new HashMap<String, Object>();
map.put("activityId", source.getId());
map.put("type", "parallelGateway");
return map;
}
}
}
return null;
}*/
private String getProcessCreator(TaskEntity task, CommandContext commandContext) {
List<HistoricIdentityLinkEntity> links = commandContext.getHistoricIdentityLinkEntityManager().findHistoricIdentityLinksByProcessInstanceId(task.getProcessInstanceId());
/*List<IdentityLinkEntity> links = commandContext.getIdentityLinkEntityManager()
.findIdentityLinksByProcessInstanceId(task.getProcessInstanceId());*/
return links.stream().filter(link -> {
return "starter".equals(link.getType());
}).findFirst().get().getUserId();
}
@Deprecated
private FlowNode getPrevTaskNode(String processId, FlowElement curNode, Process process,
HistoryService historyService) {
if (curNode == null) {
return null;
}
if (!FlowNode.class.isAssignableFrom(curNode.getClass())) {
return null;
}
List<SequenceFlow> sequences = ((FlowNode) curNode).getIncomingFlows();
for (SequenceFlow seq : sequences) {
FlowElement ele = process.getFlowElement(seq.getSourceRef());
if (UserTask.class.isAssignableFrom(ele.getClass())) {
try {
HistoricActivityInstance his = historyService.createHistoricActivityInstanceQuery()
.processDefinitionId(processId).activityId(ele.getId())
.orderByHistoricActivityInstanceEndTime().desc().singleResult();
return (FlowNode) ele;
} catch (Exception ex) {
log.error("error", ex);
}
} else if (ExclusiveGateway.class.isAssignableFrom(ele.getClass())) {
return getPrevTaskNode(processId, ele, process, historyService);
}
}
return null;
}
}
RollbackTaskCmd
最新推荐文章于 2023-09-06 14:52:10 发布