Activiti6驳回上一节点
主要是通过获取,通过遍历节点集合,通过上级节点对象的信息来判断上级节点是什么节点(网关、用户、开始、结束),来对不同的节点做不同的操作,目前只做一个互斥网关,用户,开始,和结束,其他的网关还没做,目前没用到。
我目前是SpringBoot整合的activiti6+Activiti Modeler在线流程编辑
注意:在进行驳回的时候要注意节点的上级活下级是不是起点或终点,如果是的话,是无法驳回的。
主要代码:
/**
* 节点驳回操作
*/
@Override
public Result nodeReject(String taskId, String processInstanceId) {
//获取仓库服务
RepositoryService repositoryService = processEngine.getRepositoryService();
//获取任务服务
TaskService taskService = processEngine.getTaskService();
ManagementService managementService = processEngine.getManagementService();
//获取当前任务对象
Task currentTask = taskService.createTaskQuery().taskId(taskId).singleResult();
if (currentTask == null) {
throw new ActivitiException("当前任务不存在或已被办理完成,回退失败!");
}
//获取流程定义id
String processDefinitionId = currentTask.getProcessDefinitionId();
//获取bpmn模板
BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
//获取当前任务信息
Task task = taskService.createTaskQuery().processInstanceId(processInstanceId).singleResult();
//获取目标节点定义
FlowNode flowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(task.getTaskDefinitionKey());
//获取输入节点集合
List<SequenceFlow> incomingFlows = flowNode.getIncomingFlows();
//遍历输入节点集合
for (SequenceFlow incomingFlow : incomingFlows) {
//上级节点的sourceRef-(sid)
String sourceRef = incomingFlow.getSourceRef();
//通过上级节点对象的信息来判断上级节点是什么节点(网关、用户、开始、结束)
FlowNode flowElement = (FlowNode) bpmnModel.getMainProcess().getFlowElement(sourceRef);
//上级节点判断,用户节点
if (flowElement instanceof UserTask) {
//返回上一个节点信息(可以删除)
Result result = lastNodeMessage(processInstanceId);
//删除当前运行任务
String executionEntityId = managementService.executeCommand(new ActivitiNodeUtil.DeleteTaskCmd(currentTask.getId()));
//流程执行到目标节点
managementService.executeCommand(new ActivitiNodeUtil.setFLowNodeAndGoCmd(flowElement, executionEntityId));
return result; //(可以删除)
//上级节点判断,互斥网关节点
} else if (flowElement instanceof ExclusiveGateway) {
//获取输入节点集合
List<SequenceFlow> incomingFlows1 = flowElement.getIncomingFlows();
//遍历输入节点集合,找到输入的上级节点id
for (SequenceFlow sequenceFlow : incomingFlows1) {
//上级节点的sourceRef-(sid)
String flowSourceRef = sequenceFlow.getSourceRef();
//通过上级节点的sid获取节点对象信息
FlowNode flowNodeUser = (FlowNode) bpmnModel.getFlowElement(flowSourceRef);
//通过上级节点对象的信息来判断上级节点是什么节点(网关、用户、开始、结束)
if (flowNodeUser instanceof UserTask) {
Result result = lastNodeMessage(processInstanceId);
//删除当前运行任务
String executionEntityId = managementService.executeCommand(new ActivitiNodeUtil.DeleteTaskCmd(currentTask.getId()));
//流程执行到目标节点
managementService.executeCommand(new ActivitiNodeUtil.setFLowNodeAndGoCmd(flowNodeUser, executionEntityId));
//返回上一个节点信息
return result;
//上级节点判断,流程起点节点
} else if (flowElement instanceof StartEvent) {
throw new ActivitiException("上级节点是流程开始节点无法驳回,驳回失败!");
}
}
//上级节点判断,流程起点节点
} else if (flowElement instanceof StartEvent) {
throw new ActivitiException("上级节点是流程开始节点无法驳回,驳回失败!");
}
}
return null;
}
/**
* 删除当前运行时任务命令,并返回当前任务的执行对象id
* 这里继承了NeedsActiveTaskCmd,主要时很多跳转业务场景下,要求不能是挂起任务。可以直接继承Command即可
*/
public static class DeleteTaskCmd extends NeedsActiveTaskCmd<String> {
public DeleteTaskCmd(String taskId) {
super(taskId);
}
@Override
public String execute(CommandContext commandContext, TaskEntity currentTask) {
//获取所需服务
TaskEntityManagerImpl taskEntityManager = (TaskEntityManagerImpl) commandContext.getTaskEntityManager();
//获取当前任务的来源任务及来源节点信息
ExecutionEntity executionEntity = currentTask.getExecution();
//删除当前任务,来源任务
taskEntityManager.deleteTask(currentTask, "jumpReason", false, false);
return executionEntity.getId();
}
@Override
public String getSuspendedTaskException() {
return "挂起的任务不能跳转";
}
}
/**
* 根据提供节点和执行对象id,进行跳转命令
*/
public static class setFLowNodeAndGoCmd implements Command<Void> {
private FlowNode flowElement;
private String executionId;
public setFLowNodeAndGoCmd(FlowNode flowElement, String executionId) {
this.flowElement = flowElement;
this.executionId = executionId;
}
@Override
public Void execute(CommandContext commandContext) {
//获取目标节点的来源连线
List<SequenceFlow> flows = flowElement.getIncomingFlows();
if (flows == null || flows.size() < 1) {
throw new ActivitiException("回退错误,目标节点没有来源连线");
}
//随便选一条连线来执行,当前执行计划为,从连线流转到目标节点,实现跳转
ExecutionEntity executionEntity = commandContext.getExecutionEntityManager().findById(executionId);
executionEntity.setCurrentFlowElement(flows.get(0));
commandContext.getAgenda().planTakeOutgoingSequenceFlowsOperation(executionEntity, true);
return null;
}
}
主要需要两个参数一个任务Id一个流程Id,