新聞中心
1. 繪制流程圖
首先我們還是使用之前舊的流程圖,但是在為 UserTask 設(shè)置分配用戶的時候,我們設(shè)置多個用戶,如下圖:

創(chuàng)新互聯(lián)堅持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:網(wǎng)站設(shè)計、成都網(wǎng)站設(shè)計、企業(yè)官網(wǎng)、英文網(wǎng)站、手機端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時代的奉賢網(wǎng)站設(shè)計、移動媒體設(shè)計的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!
設(shè)置完成后,我們下載這個流程文件,來看下對應(yīng)的 XML 文件,內(nèi)容如下:
demo01
小伙伴們看到,UserTask 中的 flowable:candidateUsers="javaboy,zhangsan,lisi" 就表示這個 UserTask 由 javaboy、zhangsan 和 lisi 三個用戶處理,用戶名之間用 , 隔開。
2. 查詢?nèi)蝿?wù)處理人
接下來我們部署并啟動上面這個流程,具體如何部署如何啟動,這個在之前的文章中松哥已經(jīng)和大家聊過了,這里不再贅述。
當(dāng)流程啟動成功之后,現(xiàn)在我們很容易想到像之前文章那樣,去查詢 javaboy 需要處理的 UserTask,如下:
Listlist = taskService.createTaskQuery().taskAssignee("javaboy").list();
for (Task task : list) {
logger.info("id:{};name:{};taskDefinitionKey:{}", task.getId(), task.getName(), task.getTaskDefinitionKey());
}
但是我們卻發(fā)現(xiàn)這個 SQL 執(zhí)行完成后,查詢不到任何數(shù)據(jù)!為什么呢?我們來分析下。
經(jīng)過前面幾篇文章的介紹,現(xiàn)在小伙伴們都知道了,上面這個方法最終查詢的是數(shù)據(jù)庫中的 ACT_RU_TASK 表,查詢的 SQL 如下:
那我們就去檢查 ACT_RU_TASK 表以及它的 ASSIGNEE_ 字段,結(jié)果如下:
我們發(fā)現(xiàn) ACT_RU_TASK 表中記錄的 ASSIGNEE_ 字段值為 null!
為 null 這個其實也好理解,畢竟這個 UserTask 有多個人可以處理,但是只有一個字段,沒法儲存,肯定有其他存儲方式。
好啦,不和大家賣關(guān)子了,這種有多個候選人的任務(wù),我們應(yīng)該按照如下方式來查詢:
@Test
void test12() {
Listlist = taskService.createTaskQuery().taskCandidateUser("javaboy").list();
for (Task task : list) {
logger.info("id:{};name:{};taskDefinitionKey:{}", task.getId(), task.getName(), task.getTaskDefinitionKey());
}
}
小伙伴們看到,這里應(yīng)該調(diào)用 taskCandidateUser 方法進(jìn)行處理。那么這個方法查詢的是哪張表呢?我們來看下上面方法最終執(zhí)行的 SQL,如下:
: ==> Preparing: SELECT RES.* from ACT_RU_TASK RES WHERE RES.ASSIGNEE_ is null and exists(select LINK.ID_ from ACT_RU_IDENTITYLINK LINK where LINK.TYPE_ = 'candidate' and LINK.TASK_ID_ = RES.ID_ and ( LINK.USER_ID_ = ? ) ) order by RES.ID_ asc
: ==> Parameters: javaboy(String)
: <== Total: 1
小伙伴們看到,這里的查詢涉及到兩張表,分別是 ACT_RU_TASK 和 ACT_RU_IDENTITYLINK,兩張表聯(lián)合查詢查出來的,那我們來看看 ACT_RU_IDENTITYLINK 表的內(nèi)容:
小伙伴們看到,TYPE_ 為 candidate 的就表示這個 Task 的候選人,id 為 c5693038-3f42-11ed-b9e2-acde48001122 的 Task 一共有三個候選人,兩張表聯(lián)合查詢,才可以查到這個 UserTask 該由誰來處理。
另外一種常見的需求就是,已經(jīng)知道了要處理的流程實例了,但是不知道應(yīng)該由誰來處理,此時通過查詢 ACT_RU_IDENTITYLINK 表就可以確定一個流程實例都有哪些參與者,如下:
@Test
void test13() {
Listlist = runtimeService.createProcessInstanceQuery().list();
for (ProcessInstance pi : list) {
ListidentityLinksForProcessInstance = runtimeService.getIdentityLinksForProcessInstance(pi.getId());
for (IdentityLink identityLink : identityLinksForProcessInstance) {
logger.info("ProcessInstanceId:{},UserId:{}",identityLink.getProcessInstanceId(),identityLink.getUserId());
}
}
}
我們來看看上面這個執(zhí)行的 SQL,如下:
可以看到,其實就是通過查詢 ACT_RU_IDENTITYLINK 表獲取我們想要的數(shù)據(jù)。
3. 認(rèn)領(lǐng)任務(wù)
對于這種有候選人的任務(wù),我們需要先認(rèn)領(lǐng),再處理。認(rèn)領(lǐng)的本質(zhì),其實就是給 ACT_RU_TASK 表中,這個 UserTask 記錄的 ASSIGNEE_ 字段設(shè)置上值。
認(rèn)領(lǐng)任務(wù)的方式如下:
@Test
void test12() {
Listlist = taskService.createTaskQuery().taskCandidateUser("javaboy").list();
for (Task task : list) {
taskService.claim(task.getId(),"javaboy");
}
}
認(rèn)領(lǐng)之后,我們再來看 ACT_RU_TASK 表中的數(shù)據(jù),如下:
可以看到,此時 ASSIGNEE_ 字段就有值了,同時 CLAIM_TIME 字段也記錄了任務(wù)的認(rèn)領(lǐng)時間。
再來看看任務(wù)認(rèn)領(lǐng)執(zhí)行的 SQL,基本上和我們所想的一致。
4. 處理任務(wù)
認(rèn)領(lǐng)后的任務(wù)該如何處理,這個就和我們上篇文章中介紹的方式一致了,如下:
@Test
void test11() {
Listlist = taskService.createTaskQuery().taskAssignee("javaboy").list();
for (Task task : list) {
taskService.complete(task.getId());
}
}
具體原理上篇文章中已經(jīng)介紹過了,這里就不再贅述了。
任務(wù)執(zhí)行完成后,ACT_RU_IDENTITYLINK 表中的記錄也會隨之刪除。
5. 變量與監(jiān)聽器
前面這種方式設(shè)置的任務(wù)候選人我們是在繪制流程圖的時候直接硬編碼的,這顯然不是一個好辦法。如果能通過變量來傳遞任務(wù)的候選人,就會方便很多。
5.1 候選人變量
我們可以在繪制流程圖的時候,用變量代替直接指定候選人,方式如下:
此時,生成的流程 XML 文件中,UserTask 節(jié)點的處理人也就變成了下面這個樣子:
demo01
UserTask 節(jié)點中的 flowable:candidateUsers="${userIds}" 就表示流程的處理人由 userIds 變量控制。
好了,接下來我們來啟動流程,注意,此時啟動流程需要傳遞 userIds 變量,如下:
demo01
多個用戶之間,用英文 , 隔開。
好了,流程啟動成功后,接下來的操作參考 3、4 小節(jié),這里我就不再贅述了。
5.2 監(jiān)聽器
當(dāng)然,我們也可以通過監(jiān)聽器來為 UserTask 設(shè)置多個候選處理人用戶,首先我們創(chuàng)建一個監(jiān)聽器如下:
@Test
void test01() {
MapuserIds = new HashMap<>();
userIds.put("userIds", "javaboy,zhangsan,lisi");
ProcessInstance pi = runtimeService.startProcessInstanceByKey("demo01",userIds);
logger.info("id:{},activityId:{}", pi.getId(), pi.getActivityId());
}
然后在繪制流程圖的時候,刪除掉 UserTask 分配的用戶,然后重新為 UserTask 設(shè)置一個監(jiān)聽器:
然后設(shè)置一個在創(chuàng)建 UserTask 的時候觸發(fā)的監(jiān)聽器:
然后我們下載這個流程圖對應(yīng)的 XML 文件,如下:
demo01
可以看到,在 userTask 節(jié)點中,通過 extensionElements 指定了額外的監(jiān)聽器。
好啦,這個流程現(xiàn)在就可以直接啟動了,啟動時也不需要額外的變量。
流程啟動成功后,接下來的操作參考 3、4 小節(jié),這里我就不再贅述了。
6. 任務(wù)回退
當(dāng)一個任務(wù)認(rèn)領(lǐng)(Claim)之后,但是又不想處理,此時我們可以將任務(wù)退回。方式如下:
@Test
void test16() {
Listlist = taskService.createTaskQuery().taskAssignee("javaboy").list();
for (Task task : list) {
taskService.setAssignee(task.getId(), null);
}
}
其實思路很簡答,就是重新為任務(wù)設(shè)置處理人,且處理人為 null,這就是將任務(wù)回退了,接下來其他人可以重新認(rèn)領(lǐng)該任務(wù)了。
7. 修改任務(wù)候選人
7.1 增加
任務(wù)候選人也不是一成不變的,也可以動態(tài)修改,當(dāng)一個流程啟動之后,流程已經(jīng)走到某一個 Task 了,此時我們想要修改該 Task 的候選人,也是可以的,方式如下:
@Test
void test17() {
Listlist = taskService.createTaskQuery().taskCandidateUser("javaboy").list();
for (Task task : list) {
taskService.addCandidateUser(task.getId(),"wangwu");
}
}
添加完成后,查看 ACT_RU_IDENTITYLINK 表,我們發(fā)現(xiàn) wangwu 已經(jīng)添加進(jìn)來了:
7.2 刪除
如果想要刪除一個候選人,方式如下:
@Test
void test18() {
Listlist = taskService.createTaskQuery().taskCandidateUser("javaboy").list();
for (Task task : list) {
taskService.deleteCandidateUser(task.getId(), "wangwu");
}
}
刪除成功之后,ACT_RU_IDENTITYLINK 表中對應(yīng)的數(shù)據(jù)也就被清除掉了。
8. 查詢歷史數(shù)據(jù)
如果一個流程執(zhí)行結(jié)束了,我們還想查詢這個流程曾經(jīng)涉及到的參與者,可以通過如下方式查詢:
@Test
void test14() {
Listlist = historyService.createHistoricProcessInstanceQuery().list();
for (HistoricProcessInstance historicProcessInstance : list) {
Listlinks = historyService.getHistoricIdentityLinksForProcessInstance(historicProcessInstance.getId());
for (HistoricIdentityLink link : links) {
logger.info("userId:{},taskId:{},type:{},processInstanceId:{}",link.getUserId(),link.getTaskId(),link.getType(),link.getProcessInstanceId());
}
}
}
這里最終其實就是去 ACT_HI_IDENTITYLINK 表中查詢,對應(yīng)的 SQL 如下:
上面這是查詢一個流程的參與人,當(dāng)然我們也可以查詢一個 Task 的候選人與處理人,如下:
@Test
void test15() {
Listlist = historyService.createHistoricTaskInstanceQuery().list();
for (HistoricTaskInstance historicTaskInstance : list) {
Listlinks = historyService.getHistoricIdentityLinksForTask(historicTaskInstance.getId());
for (HistoricIdentityLink link : links) {
logger.info("userId:{},taskId:{},type:{},processInstanceId:{}", link.getUserId(), link.getTaskId(), link.getType(), link.getProcessInstanceId());
}
}
}
查詢對應(yīng)的 SQL 如下:
和我們所想的基本一致。
本文名稱:Flowable任務(wù)如何認(rèn)領(lǐng),回退?
鏈接地址:http://m.5511xx.com/article/djhssho.html


咨詢
建站咨詢
