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) {
		logger.error(e.getMessage(), e);
		return Result.error("任务撤回失败500");
	}
}

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值