1. 程式人生 > >activiti工作流退回問題研究

activiti工作流退回問題研究

近期由於業務需求,需要一個開源的工作流。研究了一下activiti工作流版本5.13 .在研究過程中發現,activiti工作流現有的功能中不能滿足中國式的駁回。如果工作流不能駁回,那對於咱們來說基本上是用不了。後來在網上找了一個退回到上一節點的例子。現在改了一下,可以從當前節點退回的以前走過的人工節點。廢話少說直接上例子。

<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:activiti="http://activiti.org/bpmn

" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test">
  <process id="helloworld" name="helloworldProcess" isExecutable="true">
    <startEvent id="startevent1" name="Start"></startEvent>
    <endEvent id="endevent1" name="End"></endEvent>
    <userTask id="usertask1" name="提交申請" activiti:assignee="張三"></userTask>
    <userTask id="usertask2" name="審批【部門經理】" activiti:assignee="李四"></userTask>
    <userTask id="usertask3" name="審批【總經理】" activiti:assignee="王五"></userTask>
    <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="usertask1"></sequenceFlow>
    <sequenceFlow id="flow2" sourceRef="usertask1" targetRef="usertask2"></sequenceFlow>
    <sequenceFlow id="flow3" sourceRef="usertask2" targetRef="usertask3"></sequenceFlow>
    <sequenceFlow id="flow4" sourceRef="usertask3" targetRef="endevent1"></sequenceFlow>
  </process>

以上是最簡單的審批流程

退回到上一級提交人的程式碼如下:

public class ModelRollBack {
     private Logger log = LogManager.getLogger(ModelRollBack.class);//日誌檔案
     private RuntimeService runtimeService;//
     private TaskService taskService;
     private RepositoryService repositoryService;
     private HistoryService historyService;
   
  private ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
 
  
      //退回上一個節點
     public String rollBackWorkFlow(String taskId) {
 
       this.taskService=processEngine.getTaskService();
       this.historyService = processEngine.getHistoryService();
       this.repositoryService = processEngine.getRepositoryService();
       this.runtimeService = processEngine.getRuntimeService();
         try {
             Map<String, Object> variables;
             // 取得當前任務.當前任務節點
             HistoricTaskInstance currTask = historyService
                     .createHistoricTaskInstanceQuery().taskId(taskId)
                     .singleResult();
             // 取得流程例項,流程例項
             ProcessInstance instance = runtimeService
                     .createProcessInstanceQuery()
                     .processInstanceId(currTask.getProcessInstanceId())
                     .singleResult();
             if (instance == null) {
              log.info("流程結束");
                 log.error("出錯啦!流程已經結束");
                 return "ERROR";
             }
             variables = instance.getProcessVariables();
             // 取得流程定義
             ProcessDefinitionEntity definition = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)
                     .getDeployedProcessDefinition(currTask
                             .getProcessDefinitionId());
             if (definition == null) {
              log.info("流程定義未找到");
                 log.error("出錯啦!流程定義未找到");
                 return "ERROR";
             }
             // 取得上一步活動
             ActivityImpl currActivity = ((ProcessDefinitionImpl) definition)
                     .findActivity(currTask.getTaskDefinitionKey());
            
             //也就是節點間的連線
             List<PvmTransition> nextTransitionList = currActivity
                     .getIncomingTransitions();
             // 清除當前活動的出口
             List<PvmTransition> oriPvmTransitionList = new ArrayList<PvmTransition>();
             //新建一個節點連線關係集合
            
             List<PvmTransition> pvmTransitionList = currActivity
                     .getOutgoingTransitions();
             //
             for (PvmTransition pvmTransition : pvmTransitionList) {
                 oriPvmTransitionList.add(pvmTransition);
             }
             pvmTransitionList.clear();
 
             // 建立新出口
             List<TransitionImpl> newTransitions = new ArrayList<TransitionImpl>();
             for (PvmTransition nextTransition : nextTransitionList) {
                 PvmActivity nextActivity = nextTransition.getSource();
                 ActivityImpl nextActivityImpl = ((ProcessDefinitionImpl) definition)
                         .findActivity(nextActivity.getId());
                 TransitionImpl newTransition = currActivity
                         .createOutgoingTransition();
                 newTransition.setDestination(nextActivityImpl);
                 newTransitions.add(newTransition);
             }
             // 完成任務
             List<Task> tasks = taskService.createTaskQuery()
                     .processInstanceId(instance.getId())
                     .taskDefinitionKey(currTask.getTaskDefinitionKey()).list();
             for (Task task : tasks) {
                 taskService.complete(task.getId(), variables);
                 historyService.deleteHistoricTaskInstance(task.getId());
             }
             // 恢復方向
             for (TransitionImpl transitionImpl : newTransitions) {
                 currActivity.getOutgoingTransitions().remove(transitionImpl);
             }
             for (PvmTransition pvmTransition : oriPvmTransitionList) {
                 pvmTransitionList.add(pvmTransition);
             }
             log.info("OK");
             log.info("流程結束");
         
             return "SUCCESS";
         } catch (Exception e) {
          log.error("失敗");
             log.error(e.getMessage());
             return "ERROR";
         }
     }
 
    
    
 
     //回退到指定節點
     public String rollBackToAssignWorkFlow(String taskId,String destTaskkey) {
       this.taskService=processEngine.getTaskService();
       this.historyService = processEngine.getHistoryService();
       this.repositoryService = processEngine.getRepositoryService();
       this.runtimeService = processEngine.getRuntimeService();
         try {
             Map<String, Object> variables;
             // 取得當前任務.當前任務節點
             HistoricTaskInstance currTask = historyService
                     .createHistoricTaskInstanceQuery().taskId(taskId)
                     .singleResult();
             // 取得流程例項,流程例項
             ProcessInstance instance = runtimeService
                     .createProcessInstanceQuery()
                     .processInstanceId(currTask.getProcessInstanceId())
                     .singleResult();
             if (instance == null) {
              log.info("流程結束");
                 log.error("出錯啦!流程已經結束");
                 return "ERROR";
             }
             variables = instance.getProcessVariables();
             // 取得流程定義
             ProcessDefinitionEntity definition = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)
                     .getDeployedProcessDefinition(currTask
                             .getProcessDefinitionId());
             if (definition == null) {
              log.info("流程定義未找到");
                 log.error("出錯啦!流程定義未找到");
                 return "ERROR";
             }
            //取得當前活動節點
             ActivityImpl currActivity = ((ProcessDefinitionImpl) definition)
                     .findActivity(currTask.getTaskDefinitionKey());
            
              log.info("currActivity"+currActivity);
              // 取得上一步活動
             //也就是節點間的連線
             //獲取來源節點的關係
             List<PvmTransition> nextTransitionList = currActivity.getIncomingTransitions();

             // 清除當前活動的出口
             List<PvmTransition> oriPvmTransitionList = new ArrayList<PvmTransition>();
             //新建一個節點連線關係集合
             //獲取出口節點的關係
             List<PvmTransition> pvmTransitionList = currActivity
                     .getOutgoingTransitions();
             //
             for (PvmTransition pvmTransition : pvmTransitionList) {
                 oriPvmTransitionList.add(pvmTransition);
             }
             pvmTransitionList.clear();
 
             // 建立新出口
             List<TransitionImpl> newTransitions = new ArrayList<TransitionImpl>();
             for (PvmTransition nextTransition : nextTransitionList) {
                 PvmActivity nextActivity = nextTransition.getSource();
                
                             log.info("nextActivity"+nextActivity);
                            
                             log.info("nextActivity.getId()"+nextActivity.getId());
                            
                             //destTaskkey
                 ActivityImpl nextActivityImpl = ((ProcessDefinitionImpl) definition)
                        // .findActivity(nextActivity.getId());
                   .findActivity(destTaskkey);
                 TransitionImpl newTransition = currActivity
                         .createOutgoingTransition();
                 newTransition.setDestination(nextActivityImpl);
                 newTransitions.add(newTransition);
             }
             // 完成任務
             List<Task> tasks = taskService.createTaskQuery()
                     .processInstanceId(instance.getId())
                     .taskDefinitionKey(currTask.getTaskDefinitionKey()).list();
             for (Task task : tasks) {
                 taskService.complete(task.getId(), variables);
                 historyService.deleteHistoricTaskInstance(task.getId());
             }
             // 恢復方向
             for (TransitionImpl transitionImpl : newTransitions) {
                 currActivity.getOutgoingTransitions().remove(transitionImpl);
             }
             for (PvmTransition pvmTransition : oriPvmTransitionList) {

              pvmTransitionList.add(pvmTransition);
             }
             log.info("OK");
             log.info("流程結束");
         
             return "SUCCESS";
         } catch (Exception e) {
          log.error("失敗");
             log.error(e.getMessage());
             return "ERROR";
         }
     }  
    
    
  

    
public static void main(String []args){
 
 ModelRollBack back = new ModelRollBack();
 //back.rollBackWorkFlow("1102");
 
  back.rollBackToAssignWorkFlow("2402", "usertask1");

}
         
}

以上程式碼是退回到上一節點,和退回到提交人節點的程式碼

   程式碼解析 : 例如 流程開始 走到張三 ,張三提交 ,走到李四 ,李四提交走到王五 。現在王五發現有問題,需要直接退回到 張三,讓張三修改之後再次提交 。

  這個過程中當前節點在王五   也就是usertask3  在此過程中我們要理清 節點之間的關係

usertask1----->usertask2

usertask2------>usertask3

usertask3------->endevent

目前對於uesrtask3來說來源 是usertask2------>usertask3

出口usertask3------>enendevent

所以我們只需要根據流程引擎中的定義將出口替換成usertask1就可以。

在此過程中 PvmTransition 只工作流引擎中 的節點關係維護

ActivityImpl是具體的節點。

ProcessDefinitionEntity是當前流程的定義

目前只研究到這個階段如果需要交流,可以給我留言哦