圖 3 所示。
流程圖對(duì)應(yīng)的文件 audit.xml 部分如下:
上述為一個(gè)流程文件部分內(nèi)容。該文件中的 process 元素用于描述流程信息,而 bpmndi;BPMNDiagram 元素則用于描述流程節(jié)點(diǎn)的位置信息。在 process 元素中定義了開(kāi)始事件 srartEvent、兩個(gè) usertask 和結(jié)束事件 endEvent 以及連接這些元素的順序流(sequenceFlow)。
3.2.2 部署工作流
把工作流部署到工作流引擎中:
@Test
public void deploy(){ // 獲取倉(cāng)庫(kù)服務(wù) : 管理流程定義
RepositoryService repositoryService = processEngine.getRepositoryService():
Deployment deploy = repositoryService.createDeployment()// 創(chuàng)建一個(gè)部署的構(gòu)建器
.addClasspathResource("LeaveActiviti.bpmn")// 添加資源 , 一次只能添加一個(gè)
.name(" 請(qǐng)求單流程 ")// 設(shè)置部署的名稱
.category(" 辦公類別 ")// 設(shè)置部署的類別
.deploy():
System.out.println(" 部署的 id"+deploy.getId()):
System.out.println(" 部署的名稱 "+deploy.getName()):}
3.2.3 執(zhí)行工作流
指定執(zhí)行剛才部署的工作流就是我們定義時(shí)設(shè)置的工作流程圖中的當(dāng)前任務(wù) id:
@Test
public void startProcess(){ // 指定執(zhí)行我們剛才部署的工作流程
String processDefiKey="leaveBill": // 取運(yùn)行時(shí)服務(wù)
RuntimeService runtimeService = processEngine.getRuntimeService():// 取得流程實(shí)例
ProcessInstance pi = runtimeService.startProcessInstanceByKey(processDefiKey):
System.out.println(" 流程實(shí)例 id;"+pi.getId()):// 流程實(shí)例 id
System.out.println(" 流程定義 id;"+pi.getProcessDefinitionId()):// 輸出流程定義的 id}
3.2.4 查看任務(wù)信息
根據(jù)任務(wù)辦理人,查看當(dāng)前任務(wù)信息:
@Test
public void queryTask(){// 任務(wù)的辦理人
String assignee=" 辦理人 ": // 取得任務(wù)服務(wù)
TaskService taskService = processEngine.getTaskService(): // 創(chuàng)建一個(gè)任務(wù)查詢對(duì)象
TaskQuery taskQuery = taskService.createTaskQuery():// 辦理人的任務(wù)列表
List list = taskQuery.taskAssignee(assignee)//指定辦理人
.list(): // 遍歷任務(wù)列表
if(list!=null&&list.size()>0){
for(Task task;list){
System.out.println(" 任務(wù)的辦理人 : "+task.getAssignee()):
System.out.println(" 任務(wù)的 id: "+task.getId()):
System.out.println(" 任務(wù)的名稱 : "+task.getName()):
}}}
3.2.5 處理當(dāng)前任務(wù)
當(dāng)前任務(wù)的 id 已經(jīng)查詢出來(lái)了,處理 id 為 304 的這個(gè)任務(wù):
@Test
public void compileTask(){
String taskId="304": //taskId: 任務(wù) id
processEngine.getTaskService().complete(taskId):
System.out.println(" 當(dāng)前任務(wù)執(zhí)行完畢 "):}
3.2.6 刪除流程
刪除部署 id=101 這個(gè)流程定義的數(shù)據(jù):
@Test
public void deleteProcessDefi(){
// 通過(guò)部署 id 來(lái)刪除流程定義
String deploymentId="101":
processEngine.getRepositoryService().deleteDeployment(deploymentId):
}
4 Activiti 問(wèn)題總結(jié)
在實(shí)際的項(xiàng)目開(kāi)發(fā)過(guò)程中,筆者不斷遇到了一些問(wèn)題與挑戰(zhàn),同時(shí)也積累了一些經(jīng)驗(yàn)。從 Activiti 數(shù)據(jù)庫(kù)的連接;到排他網(wǎng)關(guān)與并行網(wǎng)關(guān)的不同設(shè)置;再到執(zhí)行監(jiān)聽(tīng)器的配置與使用,任務(wù)監(jiān)聽(tīng)器的配置與使用等等的入坑事件。下面總結(jié)幾個(gè)遇到的比較典型的問(wèn)題。
4.1 會(huì)簽功能
實(shí)際項(xiàng)目中會(huì)碰到某個(gè)任務(wù)節(jié)點(diǎn)需要實(shí)現(xiàn)會(huì)簽功能的要求,就是指一個(gè)任務(wù)需要多人進(jìn)行審批,多人都審批通過(guò)后,流程才能繼續(xù)往下走。目前的實(shí)現(xiàn)方式為:
(1)啟動(dòng)這個(gè)流程圖時(shí),遍歷所有任務(wù),獲取當(dāng)前任務(wù)的辦理人;
(2)將任務(wù)辦理人做成一個(gè)集合,每個(gè)辦理人元素用逗號(hào)分隔;
(3)將這個(gè)集合的鍵以 Publicitylist_ 加上當(dāng)前的元素ID,值以前面獲取到的集合放入 Activiti 上下文。將這個(gè)參數(shù)作為 Activiti 啟動(dòng)參數(shù)放入即可。
4.2 回退功能
實(shí)際項(xiàng)目中還會(huì)碰到某個(gè)任務(wù)節(jié)點(diǎn)需要實(shí)現(xiàn)回退功能的要求。就是指能夠回退到流程圖上的任意節(jié)點(diǎn),Activiti 無(wú)法滿足這樣的項(xiàng)目需求,就需要進(jìn)行二次開(kāi)發(fā)封裝。目前的實(shí)現(xiàn)方式為:
(1)獲取當(dāng)前任務(wù)所在的節(jié)點(diǎn);
(2)獲取當(dāng)前節(jié)點(diǎn)的流出方向;
(3)記住當(dāng)前節(jié)點(diǎn)的流出信息,并將當(dāng)前節(jié)點(diǎn)的流出信息清空;
(4)獲取目標(biāo)節(jié)點(diǎn);
(5)創(chuàng)建新的方向;
(6)將新的方向設(shè)置為當(dāng)前節(jié)點(diǎn)的流出方向;
(7)完成當(dāng)前任務(wù);
(8)還原當(dāng)前節(jié)點(diǎn)的流出方向。
5 結(jié) 論
在實(shí)際的項(xiàng)目開(kāi)發(fā)過(guò)程中,工作流管理的好處是能實(shí)實(shí)在在感受到的,工作流管理在項(xiàng)目管理軟件中是有很大的發(fā)展空間的。筆者簡(jiǎn)要總結(jié)了以下幾點(diǎn):軟件的過(guò)程控制可見(jiàn),清晰明了,客戶滿意度提高;工作流的可配置性提高,直接減少了軟件開(kāi)發(fā)、后期維護(hù)成本;增強(qiáng)了系統(tǒng)的適應(yīng)性,能夠快速適應(yīng)客戶提出的流程變化。
參考文獻(xiàn):
[1] 程序人生丶 .activiti 入坑總結(jié) [EB/OL].(2019-02-20).https://www.jianshu.com/p/5c0e43701d51.html.
[2] Java3y.Activiti 就是這么簡(jiǎn)單 [EB/OL].(2018-03-21).https://www.jianshu.com/p/aa09fe0594ef.html.
[3] jgroup. 俯瞰開(kāi)源工作流引擎 Activiti [EB/OL].(2018-08-27).https://blog.csdn.net/jgroup/article/details/82116523.html.