package com.mei.flow.service;
import com.google.common.collect.Lists;
import com.mei.common.utils.SpringContextUtils;
import com.mei.common.utils.StringUtils;
import com.mei.flow.api.FlowService;
import com.mei.flow.config.EnumProcessDefine;
import com.mei.flow.constants.FlowConstants;
import lombok.extern.slf4j.Slf4j;
import ma.glasnost.orika.MapperFacade;
import org.flowable.bpmn.constants.BpmnXMLConstants;
import org.flowable.common.engine.impl.interceptor.Command;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.*;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.impl.persistence.entity.*;
import org.flowable.engine.impl.util.CommandContextUtil;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.service.impl.persistence.entity.HistoricTaskInstanceEntityImpl;
import org.flowable.task.service.impl.persistence.entity.TaskEntityImpl;
import org.flowable.variable.api.history.HistoricVariableInstance;
import org.flowable.variable.service.impl.persistence.entity.HistoricVariableInstanceEntityImpl;
import org.flowable.variable.service.impl.persistence.entity.VariableInstanceEntity;
import org.flowable.variable.service.impl.persistence.entity.VariableInstanceEntityImpl;
import org.springframework.transaction.annotation.Transactional;
import java.io.Serializable;
import java.util.Iterator;
import java.util.List;
/**
* @Author MR.MEI
* @Description 办结取回
* @Date 2020/07/10
*/
@Slf4j
public class FinishedCallBackCmd implements Command<Boolean>, Serializable {
private static final long serialVersionUID = 1305995404093357323L;
private String processInstanceId;
public FinishedCallBackCmd(String processInstanceId) {
this.processInstanceId = processInstanceId;
}
@Override
@Transactional
public Boolean execute(CommandContext commandContext) {
if (StringUtils.isEmpty(processInstanceId)) {
log.error("流程实例id不能为空");
return false;
}
RuntimeService runtimeService = SpringContextUtils.getBean(RuntimeService.class);
HistoryService historyService = SpringContextUtils.getBean(HistoryService.class);
RepositoryService repositoryService = SpringContextUtils.getBean(RepositoryService.class);
ManagementService managementService = SpringContextUtils.getBean(ManagementService.class);
FlowService flowService = SpringContextUtils.getBean(FlowService.class);
MapperFacade mapperFacade = SpringContextUtils.getBean(MapperFacade.class);
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
if (null != processInstance) {
log.error("processInstanceId:{},流程还未结束,不能取回",processInstance);
return false;
}
HistoricProcessInstanceEntityImpl instance = (HistoricProcessInstanceEntityImpl) historyService.createHistoricProcessInstanceQuery()
.processInstanceId(processInstanceId).singleResult();
if (null == instance) {
log.error("流程实例未找到");
return false;
}
// 取得流程定义
ProcessDefinition definition = repositoryService.createProcessDefinitionQuery().processDefinitionId(instance.getProcessDefinitionId()).singleResult();
if (definition == null) {
log.error("流程定义未找到");
return false;
}
// 获取结束前那一步环节任务
HistoricTaskInstanceEntityImpl previousFinishedTask = (HistoricTaskInstanceEntityImpl) historyService.createHistoricTaskInstanceQuery()
.processInstanceId(processInstanceId).orderByHistoricTaskInstanceEndTime().desc().list().get(0);
if (null == previousFinishedTask) {
return false;
}
String hisActivityInstanceTableName = managementService.getTableName(HistoricActivityInstance.class);
//删除endEvent记录、删除sequenceFlow END_TIME_时间最大的记录
flowService.removeLastApproveHisActInstance(processInstanceId);
/*
1.更新act_hi_actinst表最后一个任务节点的END_TIME为null
2.重新组装act_ru_actinst表中的内容
*/
String sql = "select * from " + hisActivityInstanceTableName + " where PROC_INST_ID_ = #{processInstanceId} and ACT_TYPE_ = #{actType} order by END_TIME_ desc";
HistoricActivityInstanceEntityImpl historicActivityInstance = (HistoricActivityInstanceEntityImpl) historyService.createNativeHistoricActivityInstanceQuery().sql(sql)
.parameter("processInstanceId", processInstanceId)
.parameter("actType", BpmnXMLConstants.ELEMENT_TASK_USER).list().get(0);
historicActivityInstance.setEndTime(null);
historicActivityInstance.setDurationInMillis(null);
CommandContextUtil.getHistoricActivityInstanceEntityManager().update(historicActivityInstance);
String querySql = "select * from " + hisActivityInstanceTableName + " where PROC_INST_ID_ = #{processInstanceId} and ACT_TYPE_ != #{actType}";
List<HistoricActivityInstance> historicActivityInstanceList = historyService.createNativeHistoricActivityInstanceQuery().sql(querySql)
.parameter("processInstanceId", processInstanceId)
.parameter("actType", BpmnXMLConstants.ELEMENT_EVENT_END).list();
// 重新构造execution
for (int i = 0; i < 2; i++) {
ExecutionEntityImpl newExecution = new ExecutionEntityImpl();
newExecution.setProcessDefinitionId(instance.getProcessDefinitionId());
newExecution.setProcessInstanceId(instance.getId());
newExecution.setActive(true); // 设置为激活状态
newExecution.setSuspensionState(1);
newExecution.setTenantId(instance.getTenantId());
newExecution.setStartTime(instance.getStartTime());
newExecution.setCountEnabled(true);
newExecution.setDeploymentId(instance.getDeploymentId());
newExecution.setRootProcessInstanceId(processInstanceId);
if (i == 0) {
newExecution.setId(instance.getId());
newExecution.setBusinessKey(instance.getBusinessKey());
newExecution.setRevision(1);
newExecution.setScope(true);
newExecution.setStartActivityId("startEvent1");
newExecution.setTaskCount(0);
// newExecution.setVariables(processVariables);
} else {
newExecution.setId(previousFinishedTask.getExecutionId());
newExecution.setRevision(1);
newExecution.setScope(false);
newExecution.setParentId(instance.getId());
newExecution.setTaskCount(1);
newExecution.setActivityId(historicActivityInstance.getActivityId());
// newExecution.setVariables(taskVariables);
}
CommandContextUtil.getExecutionEntityManager().insert(newExecution);
}
//根据历史活动实例创建运行时活动实例
for (HistoricActivityInstance activityInstance : historicActivityInstanceList) {
ActivityInstanceEntity activityInstanceEntity = new ActivityInstanceEntityImpl();
mapperFacade.map(activityInstance, activityInstanceEntity);
CommandContextUtil.getActivityInstanceEntityManager().insert(activityInstanceEntity);
}
//处理候选人信息
/* List<HistoricIdentityLink> historicIdentityLinks = historyService.getHistoricIdentityLinksForProcessInstance(processInstanceId);
List<HistoricIdentityLink> historicIdentityLinksForTask = historyService.getHistoricIdentityLinksForTask(previousFinishedTask.getId());
historicIdentityLinks.addAll(historicIdentityLinksForTask);
for (HistoricIdentityLink historicIdentityLink : historicIdentityLinks) {
IdentityLinkEntityImpl identityLinkEntity = mapperFacade.map(historicIdentityLink, IdentityLinkEntityImpl.class);
CommandContextUtil.getIdentityLinkService().insertIdentityLink(identityLinkEntity);
}*/
//更新最后任务信息
previousFinishedTask.setEndTime(null);
previousFinishedTask.setDurationInMillis(null);
CommandContextUtil.getHistoricTaskService().updateHistoricTask(previousFinishedTask, false);
// 重新构造运行任务
TaskEntityImpl newTask = new TaskEntityImpl();
// TaskEntityImpl newTask = (TaskEntityImpl) taskService.newTask();
newTask.setId(previousFinishedTask.getId());
newTask.setRevision(1);
newTask.setExecutionId(previousFinishedTask.getExecutionId());
newTask.setProcessInstanceId(previousFinishedTask.getProcessInstanceId());
newTask.setProcessDefinitionId(previousFinishedTask.getProcessDefinitionId());
newTask.setName(previousFinishedTask.getName());
newTask.setTaskDefinitionKey(previousFinishedTask.getTaskDefinitionKey());
newTask.setClaimTime(previousFinishedTask.getClaimTime());
newTask.setAssignee(previousFinishedTask.getAssignee());
newTask.setPriority(previousFinishedTask.getPriority());
newTask.setCreateTime(previousFinishedTask.getCreateTime());
newTask.setSuspensionState(1);
newTask.setTenantId(instance.getTenantId());
newTask.setCountEnabled(true);
List<HistoricVariableInstance> historicVariableInstances = historyService.createHistoricVariableInstanceQuery()
.processInstanceId(processInstanceId)
.taskId(newTask.getId()).list();
newTask.setVariableCount(historicVariableInstances.size());
newTask.setIdentityLinkCount(0);
// newTask.setIdentityLinkCount(historyService.getHistoricIdentityLinksForTask(newTask.getId()).size());
CommandContextUtil.getTaskService().insertTask(newTask, true);
// 置空实例部分信息
instance.setEndTime(null);
instance.setEndActivityId(null);
instance.setDeleteReason(null);
instance.setDurationInMillis(null);
CommandContextUtil.getDbSqlSession().update(instance);
//获取流程相关变量
List<HistoricVariableInstance> processHistoricVariables = historyService.createHistoricVariableInstanceQuery()
.processInstanceId(instance.getProcessInstanceId()).list();
// 删除历史实例变量
if (processHistoricVariables != null && processHistoricVariables.size() > 0) {
for (Iterator<HistoricVariableInstance> iterator = processHistoricVariables.iterator(); iterator.hasNext(); ) {
HistoricVariableInstanceEntityImpl historicVariable = (HistoricVariableInstanceEntityImpl) iterator.next();
if(StringUtils.isEmpty(historicVariable.getTaskId())){
if (allowToAdd(historicVariable, definition)) {
VariableInstanceEntity variableInstanceEntity = new VariableInstanceEntityImpl();
variableInstanceEntity.setId(historicVariable.getId());
variableInstanceEntity.setType(historicVariable.getVariableType());
variableInstanceEntity.setName(historicVariable.getName());
variableInstanceEntity.setExecutionId(processInstanceId);
variableInstanceEntity.setProcessInstanceId(processInstanceId);
variableInstanceEntity.setValue(historicVariable.getValue());
org.flowable.task.service.impl.util.CommandContextUtil.getVariableInstanceEntityManager().insert(variableInstanceEntity);
}
}
// CommandContextUtil.getHistoricVariableService().deleteHistoricVariableInstance(historicVariable);
}
}
//获取任务相关变量
List<HistoricVariableInstance> taskHistoricVariables = historyService.createHistoricVariableInstanceQuery()
.processInstanceId(instance.getProcessInstanceId()).taskId(previousFinishedTask.getId()).list();
if (taskHistoricVariables != null && taskHistoricVariables.size() > 0) {
for (Iterator<HistoricVariableInstance> iterator = taskHistoricVariables.iterator(); iterator.hasNext(); ) {
HistoricVariableInstanceEntityImpl historicVariable = (HistoricVariableInstanceEntityImpl) iterator.next();
if (allowToAdd(historicVariable, definition)) {
VariableInstanceEntity variableInstanceEntity = new VariableInstanceEntityImpl();
variableInstanceEntity.setId(historicVariable.getId());
variableInstanceEntity.setType(historicVariable.getVariableType());
variableInstanceEntity.setName(historicVariable.getName());
variableInstanceEntity.setExecutionId(previousFinishedTask.getExecutionId());
variableInstanceEntity.setProcessInstanceId(processInstanceId);
variableInstanceEntity.setTaskId(previousFinishedTask.getId());
variableInstanceEntity.setValue(historicVariable.getValue());
org.flowable.task.service.impl.util.CommandContextUtil.getVariableInstanceEntityManager().insert(variableInstanceEntity);
}
// CommandContextUtil.getHistoricVariableService().deleteHistoricVariableInstance(historicVariable);
}
}
return true;
}
private boolean allowToAdd(HistoricVariableInstanceEntityImpl historicVariable, ProcessDefinition definition) {
if (null == historicVariable.getValue()) {
CommandContextUtil.getHistoricVariableService().deleteHistoricVariableInstance(historicVariable);
}
List<String> notAllowToAddList = Lists.newArrayList();
notAllowToAddList.add(FlowConstants.FLOW_FILTER_KEY_HANDLE_TIME);
notAllowToAddList.add(FlowConstants.TASK_AUDIT_STATUS);
if (EnumProcessDefine.PRO_TASK_FLOW_KEY.getCode().equals(definition.getKey())) {
notAllowToAddList.add("flowBizProcurementResultData");
notAllowToAddList.add("filterEntryProcurementResultTime");
}
if (null != historicVariable.getValue() && !notAllowToAddList.contains(historicVariable.getName())) {
return true;
} else {
CommandContextUtil.getHistoricVariableService().deleteHistoricVariableInstance(historicVariable);
return false;
}
}
}
贴出一些封装的方法 //删除endEvent记录、删除sequenceFlow END_TIME_时间最大的记录 flowService.removeLastApproveHisActInstance(processInstanceId);
public void removeLastApproveHisActInstance(String processInstanceId) {
flowMapper.deleteHistoricActivityInstanceByProcessInstanceIdAndActType(processInstanceId, BpmnXMLConstants.ELEMENT_EVENT_END);
String sql = "select * from act_hi_actinst where PROC_INST_ID_ = #{processInstanceId} and ACT_TYPE_ = #{actType} order by END_TIME_ desc";
HistoricActivityInstance historicActivityInstance = historyService.createNativeHistoricActivityInstanceQuery().sql(sql)
.parameter("processInstanceId", processInstanceId)
.parameter("actType", BpmnXMLConstants.ELEMENT_SEQUENCE_FLOW).list().get(0);
flowMapper.deleteHistoricActivityInstanceById(historicActivityInstance.getId());
}
单元测试代码:
@Test
public void finishCallBack(){
FinishedCallBackCmd callBack = new FinishedCallBackCmd("c9c2d598-c0f9-11ea-8147-00ff1bb9adc3");
processEngine.getProcessEngineConfiguration().getCommandExecutor().execute(callBack);
}