根据提供参数获取流程实例:
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.impl.RuntimeServiceImpl;
import org.activiti.engine.impl.interceptor.CommandExecutor;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.runtime.Execution;
import org.activiti.engine.runtime.ProcessInstance;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.common.workflow.service.impl.base.WkflService;
import com.workflow.service.util.ActivityNodeJumpCommand;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.IJobHandler;
import com.xxl.job.core.handler.annotation.JobHandler;
/**
* 工作流任意节点跳转,输入:申请编号|当前节点标识|目标节点标识
* 类功能描述
*
* @author Administrator
* @version 1.0
* @type
* @date 2020年11月22日 下午9:12:32
*/
@JobHandler(value = "ActivityNodeJumpSchedule")
@Component
public class ActivityNodeJumpJobHandler extends IJobHandler {
private Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private WkflService wkflSerivce;
@Autowired
private ProcessEngine processEngine;
@Override
public ReturnT<String> execute(String param) throws Exception {
try {
return doExecute(param);
} catch (Exception e) {
logger.error("工作流节点任意跳转错误.......", e);
// 重新包装一下
throw new Exception(e);
}
}
private ReturnT<String> doExecute(String param) throws Exception {
if (StringUtils.isEmpty(param)) {
logger.info("请求参数不能为空,正确格式为:申请编号|当前节点标识|目标节点标识");
return FAIL;
}
String[] paramAttr = param.split("\\|");
if (paramAttr.length != 3 || StringUtils.isEmpty(paramAttr[0]) || StringUtils.isEmpty(paramAttr[1])
|| StringUtils.isEmpty(paramAttr[2])) {
logger.info("请求参数格式错误,正确格式为:申请编号|当前节点标识|目标节点标识");
return FAIL;
}
String appNo = paramAttr[0].trim();
String currNode = paramAttr[1].trim();
String jumpNode = paramAttr[2].trim();
logger.info("开始执行节点任意跳转,appNo:{}, currNode:{}, targetNode:{}", appNo, currNode, jumpNode);
HistoricProcessInstance historicProcessInstance =
processEngine.getHistoryService().createHistoricProcessInstanceQuery().processInstanceBusinessKey(appNo)
.singleResult();
ProcessDefinitionEntity processDefinitionEntity = (ProcessDefinitionEntity)processEngine.getRepositoryService()
.getProcessDefinition(historicProcessInstance.getProcessDefinitionId());
// 获取流程等待节点ID
Execution execution = wkflSerivce.getRuntimeService().createExecutionQuery().processInstanceBusinessKey(appNo)
.activityId(currNode).singleResult();
if (null == execution) {
logger.info("该申请当前所在节点不正确,appNo:{},currNode:{}", appNo, currNode);
return FAIL;
}
String executionId = execution.getId();
ActivityImpl destinationActivity = (ActivityImpl)processDefinitionEntity.findActivity(jumpNode);
if (null == destinationActivity) {
logger.info("找不到指定名称的目标节点,appNo:{}, jumpNode:{}", appNo, jumpNode);
return FAIL;
}
// 根据流程实例id获取流程实例
ProcessInstance currProcessInstance =
wkflSerivce.getRuntimeService().createProcessInstanceQuery().processInstanceBusinessKey(appNo).singleResult();
ActivityImpl currentTask = processDefinitionEntity.findActivity(currProcessInstance.getActivityId()); // 根据活动id获取活动实例
CommandExecutor commandExecutor = ((RuntimeServiceImpl)wkflSerivce.getRuntimeService()).getCommandExecutor();
commandExecutor.execute(new ActivityNodeJumpCommand(executionId, destinationActivity,
wkflSerivce.getRuntimeService().getVariables(executionId), currentTask));
logger.info("工作流任意节点跳转任务执行成功,appNo:{}, currNode:{}, targetNode:{}", appNo, currNode, jumpNode);
return SUCCESS;
}
}
编写跳转Command
import java.util.Iterator;
import java.util.Map;
import org.activiti.engine.impl.context.Context;
import org.activiti.engine.impl.interceptor.Command;
import org.activiti.engine.impl.interceptor.CommandContext;
import org.activiti.engine.impl.persistence.entity.ExecutionEntity;
import org.activiti.engine.impl.persistence.entity.ExecutionEntityManager;
import org.activiti.engine.impl.persistence.entity.TaskEntity;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
/**
* 支持Activity任意节点跳过
*
*
*/
public class ActivityNodeJumpCommand implements Command<Void> {
protected String executionId;
protected ActivityImpl desActivity;
protected Map<String, Object> paramvar;
protected ActivityImpl currentActivity;
/**
* 分享牛原创(尊重原创 转载对的时候第一行请注明,转载出处来自分享牛http://blog.csdn.net/qq_30739519)
*/
public Void execute(CommandContext commandContext) {
ExecutionEntityManager executionEntityManager = Context.getCommandContext().getExecutionEntityManager();
// 获取当前流程的executionId,因为在并发的情况下executionId是唯一的。
ExecutionEntity executionEntity = executionEntityManager.findExecutionById(executionId);
executionEntity.setVariables(paramvar);
executionEntity.setEventSource(this.currentActivity);
executionEntity.setActivity(this.currentActivity);
// 根据executionId 获取Task
Iterator<TaskEntity> localIterator = Context.getCommandContext().getTaskEntityManager()
.findTasksByExecutionId(this.executionId).iterator();
while(localIterator.hasNext()) {
TaskEntity taskEntity = (TaskEntity) localIterator.next();
// 触发任务监听
taskEntity.fireEvent("complete");
// 删除任务的原因
Context.getCommandContext().getTaskEntityManager().deleteTask(taskEntity, "completed", false);
}
executionEntity.executeActivity(this.desActivity);
return null;
}
/**
* 构造参数 可以根据自己的业务需要添加更多的字段 分享牛原创(尊重原创
* 转载对的时候第一行请注明,转载出处来自分享牛http://blog.csdn.net/qq_30739519)
*
* @param executionId
* @param desActivity
* @param paramvar
* @param currentActivity
*/
public ActivityNodeJumpCommand(String executionId, ActivityImpl desActivity, Map<String, Object> paramvar,
ActivityImpl currentActivity) {
this.executionId = executionId;
this.desActivity = desActivity;
this.paramvar = paramvar;
this.currentActivity = currentActivity;
}
}