Activiti作為工作流的首選,希望本系列文章能給大家帶來幫助
全網最詳細Activiti系列文章,強烈建議收藏加關注哦!
Activiti基本操作講解
1 流程的部署
將上面在設計器中定義的流程部署到activiti數據庫中,就是我們講的流程部署。
通過調用Activiti的api將流程定義的bpmn和png兩個文件一個一個添加部署到activiti中,還可以將兩個文件打車zip包部署。
1.1 單個文件部署
分別將bpmn文件和png圖片分別部署
/**
* 實現文件的單個部署
*/
@Test
public void test03(){
// 1.獲取ProcessEngine對象
ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
// 2.獲取RepositoryService進行部署操作
RepositoryService service = engine.getRepositoryService();
// 3.使用RepositoryService進行部署操作
Deployment deploy = service.createDeployment()
.addClasspathResource("bpmn/evection.bpmn") // 添加bpmn資源
.addClasspathResource("bpmn/evection.png") // 添加png資源
.name("出差申請流程")
.deploy();// 部署流程
// 4.輸出流程部署的信息
System.out.println("流程部署的id:" + deploy.getId());
System.out.println("流程部署的名稱:" + deploy.getName());
}
日志中查看到相關的輸出信息
1.2 部署zip文件
將bpmn文件和png文件兩個打包為一個zip文件,統一上傳
/**
* 通過一個zip文件來部署操作
*/
@Test
public void test04(){
// 定義zip文件的輸入流
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("bpmn/evection.zip");
// 對 inputStream 做裝飾
ZipInputStream zipInputStream = new ZipInputStream(inputStream);
ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
RepositoryService repositoryService = engine.getRepositoryService();
Deployment deploy = repositoryService.createDeployment()
.addZipInputStream(zipInputStream)
.name("出差申請流程")
.deploy();
// 4.輸出流程部署的信息
System.out.println("流程部署的id:" + deploy.getId());
System.out.println("流程部署的名稱:" + deploy.getName());
}
上傳后的數據庫中的數據和單個文件上傳其實是一樣的。
1.3 操作數據表
流程定義部署后操作activiti中的三張表
act_re_deployment: 流程定義部署表,每部署一次就增加一條記錄
act_re_procdef :流程定義表,部署每個新的流程定義都會在這張表中增加一條記錄
act_ge_bytearray :流程資源表,流程部署的 bpmn文件和png圖片會保存在該表中
2 啟動流程實例
流程定義部署在Activiti后就可以通過工作流管理業務流程,也就是說上邊部署的出差申請流程可以使用了。
針對該流程,啟動一個流程表示發起一個新的出差申請單,這就相當於Java類和Java對象的關系,類定義好了后需要new創建一個對象使用,當然可以new出多個對象來,對於出差申請流程,張三可以發起一個出差申請單需要啟動一個流程實例。
/**
* 啟動一個流程實例
*/
@Test
public void test05(){
// 1.創建ProcessEngine對象
ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
// 2.獲取RuntimeService對象
RuntimeService runtimeService = engine.getRuntimeService();
// 3.根據流程定義的id啟動流程
String id= "evection";
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(id);
// 4.輸出相關的流程實例信息
System.out.println("流程定義的ID:" + processInstance.getProcessDefinitionId());
System.out.println("流程實例的ID:" + processInstance.getId());
System.out.println("當前活動的ID:" + processInstance.getActivityId());
}
輸出內容:
啟動流程實例涉及到的表結構
act_hi_actinst 流程實例執行歷史
act_hi_identitylink 流程的參與用戶的歷史信息
act_hi_procinst 流程實例歷史信息
act_hi_taskinst 流程任務歷史信息
act_ru_execution 流程執行信息
act_ru_identitylink 流程的參與用戶信息
act_ru_task 任務信息
3 任務查找
流程啟動后,任務的負責人就可以查詢自己當前能夠處理的任務了,查詢出來的任務都是當前用戶的待辦任務
/**
* 任務查詢
*/
@Test
public void test06(){
String assignee ="zhansan";
ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
// 任務查詢 需要獲取一個 TaskService 對象
TaskService taskService = engine.getTaskService();
// 根據流程的key和任務負責人 查詢任務
List<Task> list = taskService.createTaskQuery()
.processDefinitionKey("evection")
.taskAssignee(assignee)
.list();
// 輸出當前用戶具有的任務
for (Task task : list) {
System.out.println("流程實例id:" + task.getProcessInstanceId());
System.out.println("任務id:" + task.getId());
System.out.println("任務負責人:" + task.getAssignee());
System.out.println("任務名稱:" + task.getName());
}
}
輸出結果
4 流程任務處理
任務負責人查詢出來了待辦的人,選擇任務進行處理,完成任務
/**
* 流程任務的處理
*/
@Test
public void test07(){
ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
TaskService taskService = engine.getTaskService();
Task task = taskService.createTaskQuery()
.processDefinitionKey("evection")
.taskAssignee("zhansan")
.singleResult();
// 完成任務
taskService.complete(task.getId());
}
zhangsan處理了這個操作后,流程就流轉到了 lisi處
然后就是不同的用戶登錄,然后查詢任務處理任務,直到任務流程走完。
5 流程定義的查詢
查詢流程相關的信息,包括流程的定義,流程的部署,流程定義的版本
/**
* 查詢流程的定義
*/
@Test
public void test08(){
ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
RepositoryService repositoryService = engine.getRepositoryService();
// 獲取一個 ProcessDefinitionQuery對象 用來查詢操作
ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
List<ProcessDefinition> list = processDefinitionQuery.processDefinitionKey("evection")
.orderByProcessDefinitionVersion() // 安裝版本排序
.desc() // 倒序
.list();
// 輸出流程定義的信息
for (ProcessDefinition processDefinition : list) {
System.out.println("流程定義的ID:" + processDefinition.getId());
System.out.println("流程定義的name:" + processDefinition.getName());
System.out.println("流程定義的key:" + processDefinition.getKey());
System.out.println("流程定義的version:" + processDefinition.getVersion());
System.out.println("流程部署的id:" + processDefinition.getDeploymentId());
}
}
輸出結果
流程定義的ID:evection:1:12504
流程定義的name:出差申請單
流程定義的key:evection
流程定義的version:1
流程部署的id:12501
6 流程的刪除
/**
* 刪除流程
*/
@Test
public void test09(){
ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
RepositoryService repositoryService = engine.getRepositoryService();
// 刪除流程定義,如果該流程定義已經有了流程實例啟動則刪除時報錯
repositoryService.deleteDeployment("12501");
// 設置為TRUE 級聯刪除流程定義,及時流程有實例啟動,也可以刪除,設置為false 非級聯刪除操作。
//repositoryService.deleteDeployment("12501",true);
}
注意:項目開發中級聯刪除操作的權限一般只開發給超級管理員使用。
7 流程資源的下載
現在我們的流程資源文件已經上傳到了數據庫中,如果其他用戶想要查看這些資源,可以從數據庫中把這些資源下載到本地。
解決方案:
- jdbc對blob類型處理clob類型數據讀取出來就可以了。
- 使用activiti的api來實現操作。
使用activiti的api來操作我們需要添加commons-io的依賴
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
實現代碼
/**
* 讀取數據庫中的資源文件
*/
@Test
public void test10() throws Exception{
// 1.得到ProcessEngine對象
ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
// 2.獲取RepositoryService對象
RepositoryService repositoryService = engine.getRepositoryService();
// 3.得到查詢器
ProcessDefinition definition = repositoryService.createProcessDefinitionQuery()
.processDefinitionKey("evection")
.singleResult();
// 4.獲取流程部署的id
String deploymentId = definition.getDeploymentId();
// 5.通過repositoryService對象的相關方法 來獲取圖片信息和bpmn信息
// png圖片
InputStream pngInput = repositoryService
.getResourceAsStream(deploymentId, definition.getDiagramResourceName());
// bpmn 文件的流
InputStream bpmnInput = repositoryService
.getResourceAsStream(deploymentId, definition.getResourceName());
// 6.文件的保存
File filePng = new File("d:/evection.png");
File fileBpmn = new File("d:/evection.bpmn");
OutputStream pngOut = new FileOutputStream(filePng);
OutputStream bpmnOut = new FileOutputStream(fileBpmn);
IOUtils.copy(pngInput,pngOut);
IOUtils.copy(bpmnInput,bpmnOut);
pngInput.close();
pngOut.close();
bpmnInput.close();
bpmnOut.close();
}
8 流程歷史信息查看
即使流程定義已經被刪除了,流程執行的實例信息通過前面的分析,依然保存在Activiti的act_hi_* 的相關表結構中,所以我們還是可以查詢流程的執行的歷史信息,可以通過HistoryService來查看
/**
* 流程歷史信息查看
*/
@Test
public void test11(){
ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
// 查看歷史信息我們需要通過 HistoryService來實現
HistoryService historyService = engine.getHistoryService();
// 獲取 actinst 表的查詢對象
HistoricActivityInstanceQuery instanceQuery = historyService.createHistoricActivityInstanceQuery();
instanceQuery.processDefinitionId("evection:1:12504");
instanceQuery.orderByHistoricActivityInstanceStartTime().desc();
List<HistoricActivityInstance> list = instanceQuery.list();
// 輸出查詢的結果
for (HistoricActivityInstance hi : list) {
System.out.println(hi.getActivityId());
System.out.println(hi.getActivityName());
System.out.println(hi.getActivityType());
System.out.println(hi.getAssignee());
System.out.println(hi.getProcessDefinitionId());
System.out.println(hi.getProcessInstanceId());
System.out.println("-----------------------");
}
}
輸出結果
usertask3
總經理審批
userTask
wangwu
evection:1:12504
15001
-----------------------
usertask2
經理審批
userTask
lisi
evection:1:12504
15001
-----------------------
usertask1
創建請假單
userTask
zhansan
evection:1:12504
15001
-----------------------
startevent1
Start
startEvent
null
evection:1:12504
15001
-----------------------
Activiti的基本操作就介紹到這兒,下篇開始給大家講解如何具體的來使用。歡迎關注點贊加收藏哦 V_V