【Activiti工作流】9.連線

光仔December發表於2017-03-26
連線
之前我們做的流程圖都是一條線下去,沒有任何分支:

有時候一件任務可能要分情況,有些情況需要走一個複雜流程,
有些情況需要走簡單流程,就如同一條河的分支一樣。例如,
員工請一天以內的假是部門經理直接審批通過,如果要請一天
以上的假期,則需要再由總經理審批之後才能通過,此時就要
分情況。這種情況在流程系統中叫做“連線”。
例圖:


我們接下來用一個程式碼例項來學習“連線”。
首先在我們之前的測試工程的src/main/java下建立一個包:



然後在該包下建立一個流程圖:



我們在流程圖編輯區域繪製流程圖:


然後編輯各個Task節點的名稱:


制定兩個Task的辦理人:



點選空白處,編輯整個流程的資訊:


如何判斷一個任務完成之後,怎麼判斷該走哪一個線?
我們點選下面的一條線,填寫該線的資訊:

另外一個Name類似:


但是這還不是控制分流的地方,我們點選Properties選項
的Main Config來設定:



我們在Condition中防止一個判斷語句即可。流程圖通過
判斷語句來確認自己該走哪一個流程。

儲存該流程圖。可以看到也生產了png圖片:


為了防止我們的bpmn和png格式的檔案在src/main/java下編譯之後消失,
我們要指定該資料夾下編譯之後存在所有格式的檔案(原來是隻存在java檔案):



接下來我們建立一個測試類:


在測試類中編寫部署/啟動/檢視/完成流程任務的方法:
package cn.com.sequenceFlow;

import java.io.InputStream;
import java.util.List;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.DeploymentBuilder;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.Test;

public class SequenceFlowTest {
		//獲取流程引擎物件
		//getDefaultProcessEngine方法內部會自動讀取名為activiti.cfg.xml檔案的配置資訊
		ProcessEngine processEngine=ProcessEngines.getDefaultProcessEngine();

		
		/**部署流程定義*/
		@Test
		public void deploymentProcessDefinition_inputStream(){
			//獲得上傳檔案的輸入流
			InputStream inputStreamBpmn=this.getClass().getResourceAsStream("SequenceFlow.bpmn");
			InputStream inputStreamPng=this.getClass().getResourceAsStream("SequenceFlow.png");
			//獲取倉庫服務,從類路徑下完成部署
			RepositoryService repositoryService=processEngine.getRepositoryService();
			DeploymentBuilder deploymentBuilder=repositoryService.createDeployment();//建立一個部署物件
			deploymentBuilder.name("連線");//新增部署的名稱
			deploymentBuilder.addInputStream("SequenceFlow.bpmn", inputStreamBpmn);
			deploymentBuilder.addInputStream("SequenceFlow.png", inputStreamPng);
			Deployment deployment=deploymentBuilder.deploy();//完成部署
			
			//列印我們的流程資訊
			System.out.println("部署Id:"+deployment.getId());
			System.out.println("部署名稱Name:"+deployment.getName());
		}
		
		/**啟動流程引擎*/
		@Test
		public void startProcessInstance(){
			//獲取流程啟動Service
			RuntimeService runtimeService=processEngine.getRuntimeService();
			//使用流程定義的key,key對應bpmn檔案對應的id,
			//(也是act_re_procdef表中對應的KEY_欄位),預設是按照最新版本啟動
			String processDefinitionkey="sequenceFlow";//流程定義的key就是sequenceFlow
			//獲取流程例項物件
			ProcessInstance processInstance=runtimeService.startProcessInstanceByKey(processDefinitionkey);
			System.out.println("流程例項ID:"+processInstance.getId());//流程例項ID
			System.out.println("流程定義ID:"+processInstance.getProcessDefinitionId());//流程定義ID
		}
		
		/**查詢當前的個人任務(實際就是查詢act_ru_task表)*/
		@Test
		public void findMyPersonalTask(){
			String assignee="趙六";
			//獲取事務Service
			TaskService taskService=processEngine.getTaskService();
			List<Task> taskList=taskService.createTaskQuery()//建立任務查詢物件
					   .taskAssignee(assignee)//指定個人任務查詢,指定辦理人
					   .list();//獲取該辦理人下的事務列表
			
			if(taskList!=null&&taskList.size()>0){
				for(Task task:taskList){
					System.out.println("任務ID:"+task.getId());
					System.out.println("任務名稱:"+task.getName());
					System.out.println("任務的建立時間:"+task.getCreateTime());
					System.out.println("任務辦理人:"+task.getAssignee());
					System.out.println("流程例項ID:"+task.getProcessInstanceId());
					System.out.println("執行物件ID:"+task.getExecutionId());
					System.out.println("流程定義ID:"+task.getProcessDefinitionId());
					System.out.println("#############################################");
				}
			}
		}
		
		/**完成我的任務*/
		@Test
		public void completeMyPersonalTask(){
			String taskId="";//上一次我們查詢的任務ID
			TaskService taskService=processEngine.getTaskService();
			taskService.complete(taskId);//完成taskId對應的任務
			System.out.println("完成ID為"+taskId+"的任務");
			
		}
}

(1)執行部署deploymentProcessDefinition_inputStream方法對我們的流程進行部署:


部署之後,我們可以在部署物件表act_re_deployment中檢視到我們的流程資訊:


然後可以在流程定義表act_re_procdef中檢視我們流程的所有基礎資訊:


可以在資原始檔表act_ge_bytearray中看到我們的資源資訊:


看一下我們的bpmn檔案,以XML格式開啟,我們可以看到,當部門經理
審批完之後,有SequenceFlow進行分支選擇,每一個SequenceFlow中都
包裹了自己的流程定義資訊:


(2)接下來我們通過我們的Key來啟動我們的流程例項,執行startProcessInstance方法:


啟動之後,檢視正在執行的流程例項表act_ru_execution,可以看到我們的例項:


檢視流程例項的歷史表act_hi_procinst,也可以看到我們的例項剛剛啟動後的歷史資訊:


檢視正在執行的任務表act_ru_task,可以看到我們的待辦任務:

可以看到,該部門經理趙六審批了。

檢視歷史任務表act_hi_taskinst,只有我們剛剛的需要趙六執行的任務資訊:


檢視活動歷史表act_hi_actinst,有start節點和第一個task任務的資訊:


(3)檢視趙六的待辦任務,執行findMyPersonalTask方法:

所以待會我們就要完成id為1604的任務

(4)完成任務
我們完成任務後,可以指定連線資訊,這樣就可以指定接下來的流程是走“重要”還是“不重要”。
所以我們要修改我們的completeMyPersonalTask方法:
/**完成我的任務*/
@Test
public void completeMyPersonalTask(){
	String taskId="1604";//上一次我們查詢的任務ID
	//完成任務的同時,設定流程變數,使用流程變數用來制定完成任務後,下一個連線,
	//對應sequenceFlow.bpmn檔案中${message=='不重要'}
	Map<String,Object> variables=new HashMap<String,Object>();
	variables.put("message", "不重要");
	TaskService taskService=processEngine.getTaskService();
	taskService.complete(taskId,variables);//完成taskId對應的任務,並附帶流程變數
	System.out.println("完成ID為"+taskId+"的任務");
}
我們上面的程式碼是設定的走“不重要”的流程。執行completeMyPersonalTask方法:


按照我們上面的流程圖,我們走“不重要”的時候,是直接到結束節點的,也就是
說我們的流程現在結束了,檢視正在執行的流程例項表act_ru_execution發現沒有了:


檢視流程例項的歷史表act_hi_procinst發現End的時間已經有了,說明例項結束了:


檢視活動歷史表act_hi_actinst,發現剛好走了start節點、審批【部門經理】和End節點:


我們重新部署一個流程,版本未2,部署/啟動/完成第一個任務的提交之後,流程先到專案經理趙六這裡。

我們給趙六的完成方法中的流程變數message設定“重要”:

/**完成我的任務*/
@Test
public void completeMyPersonalTask(){
	String taskId="2002";//上一次我們查詢的任務ID
	//完成任務的同時,設定流程變數,使用流程變數用來制定完成任務後,下一個連線,
	//對應sequenceFlow.bpmn檔案中${message=='重要'}
	Map<String,Object> variables=new HashMap<String,Object>();
	variables.put("message", "重要");
	TaskService taskService=processEngine.getTaskService();
	taskService.complete(taskId,variables);//完成taskId對應的任務,並附帶流程變數
	System.out.println("完成ID為"+taskId+"的任務");
}
執行該方法。

此時任務流轉到總經理田七這裡,檢視田七的任務,是有的:


此時對於總經理,只需要審批完成任務即可:

/**完成我的任務*/
@Test
public void completeMyPersonalTask(){
	String taskId="2003";//任務ID
	TaskService taskService=processEngine.getTaskService();
	taskService.complete(taskId);//完成taskId對應的任務
	System.out.println("完成ID為"+taskId+"的任務");
	
}

完成後整個流程結束。

再去檢視一下活動歷史表act_hi_actinst,發現剛好走了start節點、審批【部門經理】、
審批【總經理】和End節點:


最後,我們想檢視正在執行的流程變數,可以去act_ru_variables表中檢視。
想看歷史的流程變數,可以去act_hi_varinst表中檢視:


至此,我們的“連線”知識點介紹完畢。

附錄:
Activiti流程系統常用表

轉載請註明出處:http://blog.csdn.net/acmman/article/details/66473148

相關文章