一、工作流的初步認識
1.工作流就是將開發中由代碼控制的業務流程狀態抽取出來然后進行統一控制的機制!
2.比如有這樣一個小場景:
我們開發了一個小軟件,該軟件想要上線給所有人用,然后需經紀人審批、老總審批、大boss審批等。該小軟件其審核流程狀態有:暫存,待審核,通過或拒絕。
當我們在實現這幾個狀態的改變時,可以通過java編碼實現,但如果這時業務需求發生了改變,只需要老總審核,這時我們就得去更改代碼了,如果業務再復雜一點,一旦更改流程,代碼就需要大改了。
而這時就可以使用工作流,來處理業務復雜且需求經常性變更的流程。
3.該小場景的呈現效果流程:
開發一個小軟件,其狀態是暫存;
然后提交審核(狀態變成待審核),會自動到第一道審批中,則經紀人登錄就可看到這條申請,然后給同意;
接着會自動到第二道審批,如果給拒絕,則狀態變成拒絕流程結束,否則到第三道,如果大Boss也同意,則最后狀態自動變成通過。(哈哈,描述的有點亂,反正大概這個意思)
二、創建流程模型
第一次創建模型:http://localhost:8080/flow/model/create?name=xxname1&key=xxkey1&description=desc
該接口會保存模型數據到ac_re_*三張表,並跳轉到http://localhost:8080/flow/model.html?modelId=1模型頁面,之后查看或修改該模型,直接加載模型即可(modelId是模型的唯一標識)
設置流程的屬性:
1.流程發起人的流程變量
在開始節點的屬性中設置流程發起人的變量applicantId,然后可以在某個任務的屬性中,設置參與者為${applicantId},
這樣可以實現:誰發起誰執行
2.設置流程參與者 (重要)
可以給每道審批動態設置參與者,
根據業務功能指定每道審批哪些人可以看到和執行。
2.1在流程節點中,設置任務分配
這里第一道審批指定職務是agentJob;第二道misterJob;第三道bossJob
2.2 在流程節點中,設置表單屬性
根據業務需求,大概有指定用戶,指定角色,指定部門和指定職務這幾種情況,來指定任務的參與者。
比如這里指定職務,則設置isTargetJob值為true,其余幾個設置值為false。(到時代碼里會根據哪個是true,然后去調用對應的接口)
3.設置流程跳轉的條件
選定流轉線,在流條件中填寫EL表達式,返回true或false
4.設置服務任務Service task(重要)
ServiceTask任務節點是自動化的,不需要任何的人工干涉,比如大boss審批通過,則流程就會走到了服務任務這個節點,這里就會自動去修改該小軟件的狀態為審核通過。
${auditService.endAudit(procInstId,xxcode,xxtype)}(調用endAudit()接口)
三、數據庫表(超重要)
activiti工作流框架有一套自己的表。
activti有提供接口:RepositoryService、RuntimeService、TaskService 、HistoryService等,里面有對這些表的基本操作,若滿足不了有些開發需求,我們可以自寫sql玩轉這些表。
1. act_re_* 資源庫流程規則表(包含了流程定義和流程靜態資源)
re:repository
act_re_deployment 部署信息表
act_re_model 流程設計模型表
act_re_procdef 流程定義數據表
注意:當創建模型后,模型信息會保存到這三張表。保存模型時,會部署流程,修改和部署的信息會保留到這幾張表中:
act_ge_bytearray,act_re_deployment,act_re_procdef,act_re_model
1.1 act_re_model
ID_: modelId
NAME_:模型名稱
KEY_:模型標識
2. act_ge_* 通用數據表
act_ge_bytearray 二進制數據表
act_ge_property 屬性數據表,存儲整個流程引擎級別的數據;初始化表結構時,會默認插入三條記錄
3. act_ru_* 運行時數據庫表
ru:runtime
這些運行時的表,包含流程‘實例,任務,變量‘等運行中的數據。
Activiti只在流程實例執行過程中保存這些數據, 在流程結束時就會刪除這些記錄。
(1)act_ru_execution 運行時流程執行實例表,即存放實例的
(2)act_ru_identitylink 運行時流程人員表,主要存儲任務節點的參與者信息
(3)act_ru_task 運行時任務節點表
(4)act_ru_variable 運行時流程變量數據表,存放在map中的
模型流程、實例、任務的關系區別:(一個模型,一個流程定義ID,可以發起多個流程實例ID,每個流程實例ID,對應3個節點ID)
比如小紅發起軟件A審批,使用模型A(modleId=1),這時創建了一個實例(procInstId = 11),
這時就走到了該模型流程的第一個任務節點(taskId=111),該任務信息就保存到了ru_和hi_表中,
只有該任務的參與者才能看見這一個任務,審批通過然后進入下一個任務節點( taskId=112 )
然后又發起軟件B審批,還是使用模型A (modleId=1),這時也會創建了一個實例( procInstId = 12),
接下去也是走到了第一個任務節點( taskId=121 )
3.1 act_ru_execution 運行時流程執行實例表
ID_ = PROC_INST_ID_
3.2 act_ru_identitylink 運行時流程人員表
3.3 act_ru_task 運行時任務節點表
ID_:任務id
PROC_INST_ID_:實例id
EXECUTION_ID_:實例分支id,軟件審批流程就一條線,故這兩個值相同
3.4 act_ru_variable 運行時流程變量數據表(重要)
比如:
發起審批時,把業務功能需要的信息放到map中,保存到該表,則流程進入第一個節點,就可獲取到該map數據,
如果再給map添加新數據,進入到第二個節點,該表會更新map數據
4. act_hi_* 歷史數據庫表
hi:history
這些表包含歷史數據,比如歷史流程實例, 變量,任務等等
(1) act_hi_actinst 歷史節點表,存放所有用過的節點(startEvent,userTask,serviceTask,endEvent)
(2) act_hi_attachment 歷史附件表
(3) act_hi_comment 歷史意見表
(4) act_hi_identitylink 歷史流程人員表,存放任務節點的參與者信息
(5) act_hi_detail 歷史詳情表,提供歷史變量的查詢
(6) act_hi_procinst 歷史流程實例表
(7) act_hi_taskinst 歷史任務實例表
(8) act_hi_varinst 歷史變量表
注意:
ru 正在處理中的節點信息
hi 已完成和正在處理中的(開發中發現hi其實是都保存的,故主要會查詢hi的表)
4.1 act_hi_actinst :歷史節點表(startEvent,userTask,serviceTask,endEvent)
與act_hi_taskinst不同的是,taskinst只記錄usertask內容
4.2 act_hi_procinst:歷史流程實例表
4.3 act_hi_taskinst:歷史任務實例表(重要)
END_TIME_:結束時間值為空,則表示該節點是正在處理中的;這個相當於審批時間
DELETE_REASON_:completed(該節點被同意了)、refused(該節點被拒絕了)、空值(該節點正在處理中)
這里有個小技巧:
當經紀人登錄后,有個審批列表(全部、待審核、已審核),該列表還需展示軟件一些信息,並且還是分頁查詢。
然后開發時,我發現NAME_和DESCRIPTION_始終是空值,於是就在發起審批時,把該軟件信息存在這里。
4.4 act_hi_varinst 歷史變量表
5.biz_act_relation(自定義表)
這張表是自己根據業務需求建的,用來存放業務與任務的關系,用於業務功能的開發。
當一個任務節點被完成后,便會把該節點的信息保存到這張表。
(哈哈,其實開發審批功能時,我用了幾個小技巧在表中,才滿足所給需求,當然我開發的並不是軟件的審批,軟件只是一個舉例)
四、項目中使用activiti工作流
springboot集成activiti:可以把activiti框架單獨作為一個子服務,對應單獨一個數據庫,就只存放上面所有表。
其他服務引入activiti服務,調用開放接口即可。
1.activiti目錄結構
2.activiti工作流接口
2.1 關於模型的接口(自帶的,用於在線流程設計器)
在線流程設計器不需要登錄就可訪問,可以這樣設置跳過攔截:
|| this.matchers("/modeler.html", request) || this.matchers("/editor-app/**", request) || this.matchers("/model/**", request) || this.matchers("/editor/stencilset", request)
2.2 關於流程實例和任務的接口
3.審批功能效果