BPM引擎Activiti6.0任务撤回实现方法

BPM引擎Activiti6.0任务撤回实现方法

当前使用的BPM引擎为Activiti6.0,客户需求是流程发起人能将整个流程撤销,对于某个流程节点,办理人可以撤回已经办理的任务,同时前提是该任务节点的下个节点未被办理。

1、流程撤销

首先说下发起人对整个流程的撤销,直接删除流程,传入流程实例ID,结束一个流程。执行此方法后,流程实例的当前任务act_ru_task会被删除,流程历史act_hi_taskinst不会被删除,并且流程历史的状态置为finished完成。

runtimeService.deleteProcessInstance(instanceId, deleteReason);

2、任务撤回

已执行任务的撤回操作相对来说复杂些,这里先分步骤说下总体思路:

1)选择一条已办理任务,根据该任务查询出任务ID =myTaskId和流程实例ID=processInstanceId;

2)根据processInstanceId判断当前流程是否已结束或已挂起,流程结束或挂起则无法执行撤回操作;

3)根据myTaskId查询选择任务的历史任务实例historicTaskInstance,进而查询出对应历史活动实例historicActivityInstance,最终得到活动标识myActivityId;

4)根据活动标识myActivityId获取该任务对应的FlowNode对象myFlowNode;

5)查询出该任务节点的所有下一任务节点flowElementList,此处是任务节点Task,排查其它类型活动节点;

6)判断flowElementList中是否有代办事项,如果有则可以执行撤回操作,否则表示该任务的所有下一任务都执行完毕,此时不允许再执行撤回操作;

7)对下一节点代办任务,同样查询出对应的FlowNode对象flowNode;

8)借助FlowNode对象myFlowNode和flowNode,反方向执行一次任务,即从代办任务节点反方向流转到当前任务节点,从而完成了任务撤回操作。

完整代码如下:

public Result cancelTask(ActivitiTask doneTask) { 	try { 		// doneTask为封装的Task对象     String processInstanceId = doneTask.getInstanceId(); 		String myTaskId = doneTask.getTaskId(); 		// 校验流程是否结束 		ProcessInstance processInstance = runtimeService.createProcessInstanceQuery() 				.processInstanceId(processInstanceId).active().singleResult(); 		if(processInstance == null) { 			return Result.error("流程已结束或已挂起,无法执行撤回操作"); 		} 		// 当前任务 		HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery() 				.taskId(myTaskId).processInstanceId(processInstanceId).singleResult(); 		if(historicTaskInstance==null) { 		    return Result.error("当前任务不存在,无法撤回"); 		} 		String myActivityId = null; 		List<HistoricActivityInstance> actInstList = 			historyService.createHistoricActivityInstanceQuery() 				.executionId(historicTaskInstance.getExecutionId()) 				.finished().list(); 		for(HistoricActivityInstance hai : actInstList) { 		    if(myTaskId.equals(hai.getTaskId())) { 			      myActivityId = hai.getActivityId(); 			      break; 		    } 		} 		 		BpmnModel bpmnModel = repositoryService.getBpmnModel(processInstance.getProcessDefinitionId()); 		FlowNode myFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(myActivityId); 		// 获取所有下一任务节点的标识ID 		Map<String, String> taskKeyMap = Maps.newHashMap(); 		// 获取所有下一任务节点对应的FlowElement 		List<FlowElement> flowElementList = getOutgoingTask(bpmnModel, myActivityId); 		for(FlowElement flowElement : flowElementList) { 			String eleId = flowElement.getId(); 			taskKeyMap.put(eleId, eleId); 		} 		// 获取当前流程代办事项,没有代办事项表明流程结束或已挂起 		List<Task> alltaskList = taskService.createTaskQuery().processInstanceId(processInstanceId).list(); 		if(alltaskList.size() <= 0) { 			return Result.error("流程已结束或已挂起,无法执行撤回操作"); 		} 		// 判断所有下一任务节点中是否有代办任务,没有则表示任务已办理或已撤回,此时无法再执行撤回操作 		List<Task> nextTaskList = Lists.newArrayList(); 		for(Task task : alltaskList) { 			if(taskKeyMap.containsKey(task.getTaskDefinitionKey())) { 				nextTaskList.add(task); 			} 		} 		if(nextTaskList.size() <= 0) { 			return Result.error("任务已办理或已撤回,无法执行撤回操作"); 		} 		 		// 执行撤回操作 		for(Task task : nextTaskList) { 			Execution execution = runtimeService.createExecutionQuery() 			    .executionId(task.getExecutionId()).singleResult(); 		    String activityId = execution.getActivityId(); 		    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.setId("sid-"+UUID.randomUUID().toString()); 		    newSequenceFlow.setSourceFlowElement(flowNode); 		    newSequenceFlow.setTargetFlowElement(myFlowNode); 		    newSequenceFlowList.add(newSequenceFlow); 		    flowNode.setOutgoingFlows(newSequenceFlowList); 		    // 反方向执行任务 		    taskService.addComment(task.getId(), task.getProcessInstanceId(), "主动撤回"); 		    taskService.resolveTask(task.getId()); 		    taskService.claim(task.getId(),doneTask.getTodoUserId()); 		    taskService.complete(task.getId()); 		    flowNode.setOutgoingFlows(oriSequenceFlows); 		} 		 		return Result.success(); 	} catch (Exception e) { 		return Result.error("任务撤回失败500"); 	} }

您可能还会对下面的文章感兴趣: