回退备份 2019.2.12

package com.pty.workflow.service.extend;

import java.util.List;

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.history.HistoricTaskInstance;
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.IdentityLinkEntity;
import org.activiti.engine.impl.persistence.entity.TaskEntity;

import com.pty.workflow.api.RollbackPosition;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class RollbackTaskCmd extends NeedsActiveTaskCmd<Void> {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1264547749014497759L;

	private RollbackPosition _position;

	private String _designatedNodeId;

	public RollbackTaskCmd(String taskId, RollbackPosition position, String... designatedNodeId) {
		super(taskId);
		_position = position;
		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);
			}
			// Context.getAgenda().planTriggerExecutionOperation(executionEntity);
		}
		return null;
	}

	// 退回到流程初始的任务节点
	private void rollback2Start(CommandContext commandContext, TaskEntity task, ExecutionEntity executionEntity) {
		// TODO(liubo): 设置creator
		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);
		Process process = Context.getProcessEngineConfiguration().getRepositoryService()
				.getBpmnModel(task.getProcessDefinitionId()).getMainProcess();
		FlowNode prevNode = getPrevousNode(task, process);
		if (prevNode == null) {
			throw new RuntimeException("前置任务节点未找到");
		}
		if (prevNode.getIncomingFlows().stream().anyMatch(ele -> {
			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);
		executionEntity.executeActivity(executionEntity.getProcessDefinition().findActivity(prevNode.getId()));
	}

	private void rollback2Designated(CommandContext commandContext, TaskEntity task, ExecutionEntity executionEntity) {
		throw new RuntimeException("暂不支持退回到任一指定节点");
	}

	private FlowNode getPrevousNode(TaskEntity task, Process process) {
		// Process process =
		// ProcessDefinitionUtil.getProcess(task.getProcessDefinitionId());
		// FlowNode currentNode = (FlowNode)
		// process.getFlowElement(task.getTaskDefinitionKey());
		// HistoryService historyService =
		// Context.getProcessEngineConfiguration().getHistoryService();
		// return getPrevTaskNode(task.getProcessInstanceId(), currentNode, process,
		// historyService);
		HistoricTaskInstance taskHis = Context.getProcessEngineConfiguration().getHistoryService()
				.createHistoricTaskInstanceQuery().executionId(task.getExecutionId()).finished()
				.orderByHistoricTaskInstanceEndTime().desc().list().get(0);
		return (FlowNode) process.getFlowElement(taskHis.getTaskDefinitionKey());
	}

	private String getProcessCreator(TaskEntity task, CommandContext commandContext) {
		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;
	}

}

package com.pty.workflow.service;

import com.pty.workflow.api.IPtyWfRuntimeService;
import com.pty.workflow.api.IWfEventCallback;
import com.pty.workflow.api.RollbackPosition;
import com.pty.workflow.dao.ActHiActInstDao;
import com.pty.workflow.dao.ActHiVarInstDao;
import com.pty.workflow.dao.ActRuTaskDao;
import com.pty.workflow.dao.WfTaskDao;
import com.pty.workflow.entity.ActRuExecution;
import com.pty.workflow.entity.ActRuTask;
import com.pty.workflow.entity.WfTask;
import com.pty.workflow.service.extend.RollbackTaskCmd;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.FlowNode;
import org.activiti.bpmn.model.SequenceFlow;
import org.activiti.engine.ActivitiException;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.delegate.event.ActivitiEventListener;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.impl.RuntimeServiceImpl;
import org.activiti.engine.impl.identity.Authentication;
import org.activiti.engine.runtime.Execution;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class PtyWfRuntimeService implements IPtyWfRuntimeService {
	@Autowired
	private ProcessEngine activitiEngine;

	@Autowired
	private PtyWfDeployService ptyWfDeployService;

	@Autowired
	private WfTaskDao taskDao;
	
	@Autowired
	private ActRuTaskDao actRuTaskDao;
	
	@Autowired
	private ActHiVarInstDao actHiVarInstDao;
	
	@Autowired
	private ActHiActInstDao actHiActInstDao;

	@Override
	public WfTask startProcess(String tenantId, String processKey, String businessId, String submitter, Map vars,
			IWfEventCallback eventCallback) {
		ActivitiEventListener eventListener = null;
		if (eventCallback != null) {
			eventListener = new PtyWfEventListener(eventCallback);
			activitiEngine.getRuntimeService().addEventListener(eventListener);
		}
		try {
			//vars.put("creator", submitter);
			// 设置流程发起人
			activitiEngine.getIdentityService().setAuthenticatedUserId(submitter);
			ProcessInstance pi = activitiEngine.getRuntimeService().startProcessInstanceByKeyAndTenantId(processKey,
					businessId, vars, tenantId);
			Task task = activitiEngine.getTaskService().createTaskQuery().processInstanceId(pi.getProcessInstanceId())
					/*.taskAssignee(submitter)*/.singleResult();
			task.setAssignee(submitter);
			activitiEngine.getTaskService().saveTask(task);
			WfTask wfTask = new WfTask();
			wfTask.setTaskId(task.getId());
			wfTask.setProcessInstanceId(task.getProcessInstanceId());
			wfTask.setTodo(1);

			return wfTask;
		} catch (ActivitiException ex) {
			throw new RuntimeException(ex.getMessage() + "->" + ex.getCause().getMessage());
		} catch (Exception ex) {
			throw new RuntimeException(ex);
		} finally {
			if (eventListener != null) {
				activitiEngine.getRuntimeService().removeEventListener(eventListener);
			}
		}
	}

	@Override
	// todo(李世超):同一个单据是否可以重复启动,以及重复启动的条件???
	public WfTask startProcess(String tenantId, String processKey, String businessId, String submitter, Map vars) {
		return startProcess(tenantId, processKey, businessId, submitter, vars, null);
	}

	@Override
	public void submitTask(String taskId, String submitter, String comment, Map vars, IWfEventCallback eventCallback) {
		ActivitiEventListener eventListener = null;
		if (eventCallback != null) {
			eventListener = new PtyWfEventListener(eventCallback);
			activitiEngine.getRuntimeService().addEventListener(eventListener);
		}
		try {
			TaskService taskService = activitiEngine.getTaskService();
			Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
			if (task == null) {
//				throw new RuntimeException("待办任务" + taskId + "不存在");
				throw new RuntimeException("单据号:" + vars.get("billNo") + "已提交");//billNo
			}
			if (comment != null && !comment.isEmpty()) {
				taskService.addComment(taskId, task.getProcessInstanceId(), comment);
			}
			String assignee = taskService.createTaskQuery().taskId(taskId).singleResult().getAssignee();
			if (assignee == null) {
				taskService.claim(taskId, submitter);
			}
			taskService.complete(taskId, vars, true);
		} catch (ActivitiException ex) {
			throw new RuntimeException(ex.getMessage() + "->" + ex.getCause().getMessage());
		} catch (Exception ex) {
			throw new RuntimeException(ex);
		} finally {
			if (eventListener != null) {
				activitiEngine.getRuntimeService().removeEventListener(eventListener);
			}
		}
	}

	@Override
	public void submitTask(String taskId, String submitter, String comment, Map vars) {
		submitTask(taskId, submitter, comment, vars, null);
	}

	@Deprecated
	public void rollBack(String taskId, String submitter, String comment) {
		try {
			Task task = activitiEngine.getTaskService().createTaskQuery().taskId(taskId).singleResult();
			Execution execution = activitiEngine.getRuntimeService().createExecutionQuery()
					.executionId(task.getExecutionId()).singleResult();
			String executionId = execution.getId();
			String processInstanceId = execution.getProcessInstanceId();
			List<Task> listTask = activitiEngine.getTaskService().createTaskQuery().processInstanceId(processInstanceId)
					.list();
			if (listTask.size() >= 2) {
				throw new RuntimeException("此任务不可进行回退");
			}
			List<HistoricTaskInstance> list = activitiEngine.getHistoryService().createHistoricTaskInstanceQuery()
					.executionId(executionId).orderByHistoricTaskInstanceEndTime().desc().list();
			HistoricTaskInstance currTask = list.get(0);
			String processDefinitionId = currTask.getProcessDefinitionId();
			BpmnModel bpmnModel = ptyWfDeployService.getBpmnModel(processDefinitionId);
			String myActivityId = null;
			List<HistoricActivityInstance> haiList = activitiEngine.getHistoryService()
					.createHistoricActivityInstanceQuery().executionId(currTask.getExecutionId()).finished().list();
			for (HistoricActivityInstance hai : haiList) {
				if (currTask.getId().equals(hai.getTaskId())) {
					myActivityId = hai.getActivityId();
					break;
				}
			}
			FlowNode myFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(myActivityId);

			String activityId = execution.getActivityId();
			// logger.warn("------->> activityId:" + activityId);
			FlowNode flowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(activityId);

			// 记录原活动方向
			List<SequenceFlow> oriSequenceFlows = new ArrayList<SequenceFlow>();
			oriSequenceFlows.addAll(flowNode.getOutgoingFlows());

			// 清理活动方向
			flowNode.getOutgoingFlows().clear();
			// 建立新方向
			List<SequenceFlow> newSequenceFlowList = new ArrayList<SequenceFlow>();
			SequenceFlow newSequenceFlow = new SequenceFlow();
			newSequenceFlow.setSourceRef(flowNode.getId());
			newSequenceFlow.setTargetRef(myFlowNode.getId());
			newSequenceFlowList.add(newSequenceFlow);
			flowNode.setOutgoingFlows(newSequenceFlowList);
			Authentication.setAuthenticatedUserId(submitter);
			activitiEngine.getTaskService().addComment(task.getId(), task.getProcessInstanceId(), comment);
			activitiEngine.getTaskService().claim(taskId, submitter);
			// 完成任务
			activitiEngine.getTaskService().complete(task.getId());
			// 恢复原方向
			flowNode.setOutgoingFlows(oriSequenceFlows);
		} catch (ActivitiException ex) {
			throw new RuntimeException(ex.getMessage() + "->" + ex.getCause().getMessage());
		} catch (Exception ex) {
			throw new RuntimeException(ex);
		}
	}

	@Override
	public void terminate(String busiKey, String submitter, String comment) {
		HistoricProcessInstance instance = activitiEngine.getHistoryService().createHistoricProcessInstanceQuery()
				.processInstanceBusinessKey(busiKey).singleResult();
		if (instance != null) {
			RuntimeService runtimeService = activitiEngine.getRuntimeService();
			runtimeService.deleteProcessInstance(instance.getId(), comment);
		}
	}
	
	@Override
	public void rollBack(String taskId, String submitter, String comment, RollbackPosition position,
			String designatedNodeId,IWfEventCallback eventCallback) {
		ActivitiEventListener eventListener = null;
		if (eventCallback != null) {
			eventListener = new PtyWfEventListener(eventCallback);
			activitiEngine.getRuntimeService().addEventListener(eventListener);
		}
		try {
			TaskService taskService = activitiEngine.getTaskService();
			Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
			if (comment != null && !comment.isEmpty()) {
				taskService.addComment(taskId, task.getProcessInstanceId(), comment);
			}
			String assignee = taskService.createTaskQuery().taskId(taskId).singleResult().getAssignee();
			if (assignee == null) {
				taskService.claim(taskId, submitter);
			}
			RuntimeServiceImpl runtimeService = (RuntimeServiceImpl) activitiEngine.getRuntimeService();
			runtimeService.getCommandExecutor().execute(new RollbackTaskCmd(taskId, position, designatedNodeId));
			
			Task newTask=activitiEngine.getTaskService().createTaskQuery().processInstanceId(task.getProcessInstanceId()).singleResult();
			ActRuTask actRuTask =new ActRuTask();
			actRuTask.setId(newTask.getId());
			actRuTask.setIsReturn("1");
			actRuTaskDao.updateById(actRuTask);
		} catch (ActivitiException ex) {
			throw new RuntimeException(ex.getMessage() + "->" + ex.getCause().getMessage());
		} catch (Exception ex) {
			throw new RuntimeException(ex);
		} finally {
			if (eventListener != null) {
				activitiEngine.getRuntimeService().removeEventListener(eventListener);
			}
		}
	}

	@Override
	public List<Map<String, Object>> findVariables(String processId) {
		List<Map<String, Object>> vars = taskDao.findVariables(processId);
		return vars;
	}

	@Override
	public Map<String, Object> getProcessVariables(String processInstanceId) {
		List<Map<String, Object>> vars = taskDao.findVariables(processInstanceId);
		 Map<String, Object> nameValueMap = new HashMap<String, Object>();
	      for (Map<String, Object> processMap : vars) {
	        String name = (String) processMap.get("name");
	        String value = (String) processMap.get("value");
	        nameValueMap.put(name, value);
	      }
		String taskDefinitionKey=activitiEngine.getHistoryService().createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult().getProcessDefinitionKey();
		nameValueMap.put("wfId", taskDefinitionKey);
		return nameValueMap;
	}
	
	@Override
	public Map<String, Object> getSubmitVariables(String processInstanceId) {
		List<HistoricTaskInstance> list=activitiEngine.getHistoryService().createHistoricTaskInstanceQuery().processInstanceId(processInstanceId)
		.orderByHistoricTaskInstanceEndTime().asc().list();
		String taskId=list.get(0).getId();
		List<Map<String, Object>> vars =taskDao.findLocalVariables(taskId);
		Map<String, Object> nameValueMap = new HashMap<String, Object>();
	      for (Map<String, Object> processMap : vars) {
	        String name = (String) processMap.get("name");
	        String value = (String) processMap.get("value");
	        nameValueMap.put(name, value);
	      }
		String taskDefinitionKey=activitiEngine.getHistoryService().createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult().getProcessDefinitionKey();
		nameValueMap.put("wfId", taskDefinitionKey);
		return nameValueMap;
	}

	@Override
	public void updateVriables(String executionId,Map vars) {
		activitiEngine.getRuntimeService().setVariables(executionId, vars);
	}

	@Override
	public String getExecutionIdBytaskId(String taskId) {
		return activitiEngine.getTaskService().createTaskQuery().taskId(taskId).list().get(0).getExecutionId();
	}
	
	@Override
	public void deleteVriables(String procInstId) {
		actHiVarInstDao.deleteVriables(procInstId);
	}
	
	@Override
	public void deleteProcinst(String procInstId) {
		actHiVarInstDao.deleteProcinst(procInstId);
	}

	@Override
	public void lastRollBack(String wfTaskId, String processInstanceId) {
		HistoricTaskInstance task=activitiEngine.getHistoryService().createHistoricTaskInstanceQuery().taskId(wfTaskId).singleResult();
		ActRuTask actRuTask =new ActRuTask();
		actRuTask.setId(task.getId());
		actRuTask.setRev(2);
		actRuTask.setExecutionId(task.getExecutionId());
		actRuTask.setProcInstId(task.getProcessInstanceId());
		actRuTask.setProcDefId(task.getProcessDefinitionId());
		actRuTask.setName(task.getName());
		actRuTask.setParentTaskId("");
		actRuTask.setDescription("");
		actRuTask.setTaskEefKey(task.getTaskDefinitionKey());
		actRuTask.setOwner(task.getOwner());
		actRuTask.setAssignee(task.getAssignee());
		actRuTask.setDelegation("");
		actRuTask.setPriority(50);
		actRuTask.setCreateTime(task.getCreateTime());
		//actRuTask.setDueDate(1);
		actRuTask.setCategory(task.getCategory());
		actRuTask.setSuspensionState(1);
		actRuTask.setTenantId(task.getTenantId());
		actRuTask.setFormKey(task.getFormKey());
		actRuTask.setClaimTime(task.getClaimTime());
		actRuTask.setIsReturn("1");
		HistoricProcessInstance pi=activitiEngine.getHistoryService().createHistoricProcessInstanceQuery().processInstanceId(processInstanceId)
		.singleResult();
		ActRuExecution actRuExecution=new ActRuExecution();
		actRuExecution.setActId(pi.getEndActivityId());
		actRuExecution.setBusinessKey(pi.getBusinessKey());
		actRuExecution.setCachedEntState(2);
		actRuExecution.setDeadletterJobCount(0);
		actRuExecution.setEvtSubscrCount(0);
		actRuExecution.setId(pi.getId());
		actRuExecution.setIdLinkCount("");
		actRuExecution.setIsActive(1);
		actRuExecution.setIsConcurrent(0);
		actRuExecution.setIsCountEnabled(0);
		actRuExecution.setIsEventScope(0);
		actRuExecution.setIsMiRoor(0);//
		actRuExecution.setIsScope(1);
		actRuExecution.setJobCount(0);//
		actRuExecution.setLockTime("");//
		actRuExecution.setName(pi.getName());
		actRuExecution.setParentId("");//
		actRuExecution.setProcDefId(pi.getProcessDefinitionId());
		actRuExecution.setProcInstId(pi.getSuperProcessInstanceId());
		actRuExecution.setRev(0);//
		actRuExecution.setRootProcInstId("");//
		actRuExecution.setStartTime(pi.getStartTime());
		actRuExecution.setStartUserId(pi.getStartUserId());
		actRuExecution.setSuperExec("");
		actRuExecution.setSuspensionState(0);//
		
		
		
		
		actRuTaskDao.insert(actRuTask);
		actHiActInstDao.delByTaskId(wfTaskId);
	}

	@Override
	public void suspendProcess(String processInstanceId) {
		activitiEngine.getRuntimeService().suspendProcessInstanceById(processInstanceId);
	}

	@Override
	public String getBussKey(String taskId) {
		Task  task=activitiEngine.getTaskService().createTaskQuery().taskId(taskId).singleResult();
		ProcessInstance pi = activitiEngine.getRuntimeService().createProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).singleResult();
        //3 通过流程实例获取“业务键”
        return pi.getBusinessKey();
	}

}

package com.pty.workflow.dao;

import com.pty.pub.common.anno.MyBatisDao;

@MyBatisDao
public interface ActHiActInstDao {

	void delById(String taskId);

	void del(String taskId);

	void delByTaskId(String taskId);

}

猜你喜欢

转载自blog.csdn.net/weixin_38441551/article/details/87075454