# Activiti终止流程

对于一个设计好的流程,在很多节点上,是无法直接将流程结束的,例如下面的流程实例,走到军师审批,如果审批人想直接撤销流程,把流程实例关掉,该怎么做呢?

foo

这时就可以使用动态流程来完成撤销操作,先看下面的撤销接口

class UserTaskService {

     @ApiOperation("撤销:强制结束一个流程")    
     @GetMapping(value = "/forceEnd/{taskId}")   
     @ResponseBody    
     public AjaxResult forceEnd(@PathVariable String taskId) 
     {        
         Task t = taskService.createTaskQuery().taskId(taskId).singleResult();        
         String processDefinitionId = runtimeService.createProcessInstanceQuery()
         .processInstanceId(t.getProcessInstanceId()).singleResult().getProcessDefinitionId();        
         BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);        
         // 寻找流程实例当前任务的activeId        
         Execution execution = runtimeService.createExecutionQuery().executionId(t.getExecutionId()).singleResult();        
         String activityId = execution.getActivityId();        
         FlowNode currentNode = (FlowNode)bpmnModel.getMainProcess().getFlowElement(activityId);        
         // 创建结束节点和连接线        
         EndEvent end = new EndEvent();        
         end.setName("强制结束");        
         end.setId("forceEnd");        
         List<SequenceFlow> newSequenceFlowList = new ArrayList<SequenceFlow>();        
         SequenceFlow newSequenceFlow = new SequenceFlow();        
         newSequenceFlow.setId("newFlow");        
         newSequenceFlow.setSourceFlowElement(currentNode);        
         newSequenceFlow.setTargetFlowElement(end);        
         newSequenceFlowList.add(newSequenceFlow);        
         // 备份原有方向        
         List<SequenceFlow> dataflows = currentNode.getOutgoingFlows();        
         List<SequenceFlow> oriSequenceFlows = new ArrayList<SequenceFlow>();        
         oriSequenceFlows.addAll(dataflows);        
         // 清空原有方向        
         currentNode.getOutgoingFlows().clear();        
         // 设置新方向        
         currentNode.setOutgoingFlows(newSequenceFlowList);        
         // 完成当前任务        
         taskService.addComment(taskId, t.getProcessInstanceId(), "comment", "撤销流程");       
         taskService.complete(taskId);        
          // 恢复原有方向       
        currentNode.setOutgoingFlows(oriSequenceFlows);        
        return AjaxResult.success();    
    }

}

执行以后,可以将参数指定的流程实例直接强制结束,这个过程分为以下按几个步骤:
1. 在BpmnModel对象查询出当前流程实例执行到的节点currentNode;
2. 创建一条结束节点end和一条执行线newSequenceFlow;
3. 将该执行线的起点设置为currentNode,终点设置为结束节点end;
4. 取出当前节点的输出流线进行备份,清空当前节点的输出;
5. 把执行线newSequenceFlow挂接到当前节点的输出线上;
6. 完成当前任务,流程会走到结束节点,流程实例自动关闭;
7. 将备份的流程线路恢复给当前节点,保证流程图跟修改前一致。撤销后,可以去表act_hi_actinst查看流程实例的执行历史,会发现确实该流程走到了结束节点:

foo

更多详情,请在线体验JeecgFlow (opens new window)