Java的Flowable工作流之加簽轉(zhuǎn)簽詳解
1. 加簽
顧名思義就是增加一道審批簽名,這道審批往往是臨時(shí)增加的,標(biāo)準(zhǔn)流程沒(méi)有規(guī)定要走的
在現(xiàn)實(shí)工作流程中,加簽功能使用率頗高;有時(shí),審批人對(duì)內(nèi)容不太確定,不太敢做主,就會(huì)找更高層的領(lǐng)導(dǎo)進(jìn)行加簽;這樣就可以規(guī)避個(gè)人風(fēng)險(xiǎn);出問(wèn)題大家一起擔(dān)。有時(shí)為了表示對(duì)領(lǐng)導(dǎo)尊重,或者讓領(lǐng)導(dǎo)知道這回事,也需要使用加簽功能
1.1. 向前加簽
任務(wù)在 A 這里,A 這個(gè)時(shí)候需要 B 核對(duì)一下,等 B 核對(duì)之后又回到 A 這里,這時(shí) A 才能繼續(xù)自己的任務(wù)
1.2. 向后加簽
任務(wù)在 A 這里,A 這個(gè)時(shí)候需要 B 處理這個(gè)事情,處理完畢之后就不用管了,繼續(xù)后面的審批環(huán)節(jié)
2. 或簽
或簽:指同一個(gè)任務(wù)審批節(jié)點(diǎn)設(shè)置多個(gè)人,如 A、B、C 三人,三人會(huì)同時(shí)收到審批,只要其中任意一人審批即可流轉(zhuǎn)到下一審批節(jié)點(diǎn)
3. 委派和轉(zhuǎn)辦的區(qū)別
3.1. 委派
委派:是將任務(wù)節(jié)點(diǎn)分給其他人處理,等其他人處理好之后,委派任務(wù)還會(huì) 自動(dòng)回到委派人的任務(wù)中
3.2. 轉(zhuǎn)辦
直接將辦理人assignee 換成別人,這時(shí)任務(wù)的擁有著不再是轉(zhuǎn)辦人,而是為空,相當(dāng)與將任務(wù)轉(zhuǎn)出
直接將 assignee =” zhuanban” taskService.setAssignee(taskId, userId);
4. 向前加簽
4.1. 流程圖
完成后的流程圖如下
XML 文件內(nèi)容
<?xml version="1.0" encoding="UTF-8"?> <definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:flowable="http://flowable.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.flowable.org/processdef" exporter="Flowable Open Source Modeler" exporterVersion="6.7.2"> <process id="Countersign" name="Countersign" isExecutable="true"> <documentation>flowable的加簽</documentation> <startEvent id="sid-D7D95537-998F-4DC4-B951-78708D6DBB98" flowable:formFieldValidation="true"></startEvent> <userTask id="qjsqId" name="請(qǐng)假申請(qǐng)單" flowable:assignee="${user}" flowable:formFieldValidation="true"> <extensionElements> <modeler:initiator-can-complete xmlns:modeler="http://flowable.org/modeler"> <![CDATA[false]]></modeler:initiator-can-complete> </extensionElements> </userTask> <sequenceFlow id="sid-6B6AF669-F0E8-4D59-892A-162228D0510D" sourceRef="sid-D7D95537-998F-4DC4-B951-78708D6DBB98" targetRef="qjsqId"></sequenceFlow> <userTask id="zjlId" name="總經(jīng)理審批" flowable:assignee="${Boss}" flowable:formFieldValidation="true"> <extensionElements> <modeler:initiator-can-complete xmlns:modeler="http://flowable.org/modeler"> <![CDATA[false]]></modeler:initiator-can-complete> </extensionElements> </userTask> <sequenceFlow id="sid-A5F5DC0C-5E0B-4A14-B748-CBCFFB98696D" sourceRef="qjsqId" targetRef="zjlId"></sequenceFlow> <endEvent id="sid-2C1AB747-3343-41FC-954C-70B992D32D14"></endEvent> <sequenceFlow id="sid-8B64D6FD-A229-4E53-B4EB-C86449387AE6" sourceRef="zjlId" targetRef="sid-2C1AB747-3343-41FC-954C-70B992D32D14"></sequenceFlow> </process> <bpmndi:BPMNDiagram id="BPMNDiagram_Countersign"> <bpmndi:BPMNPlane bpmnElement="Countersign" id="BPMNPlane_Countersign"> <bpmndi:BPMNShape bpmnElement="sid-D7D95537-998F-4DC4-B951-78708D6DBB98" id="BPMNShape_sid-D7D95537-998F-4DC4-B951-78708D6DBB98"> <omgdc:Bounds height="30.0" width="30.0" x="74.0" y="117.0"></omgdc:Bounds> </bpmndi:BPMNShape> <bpmndi:BPMNShape bpmnElement="qjsqId" id="BPMNShape_qjsqId"> <omgdc:Bounds height="80.0" width="100.0" x="225.0" y="92.0"></omgdc:Bounds> </bpmndi:BPMNShape> <bpmndi:BPMNShape bpmnElement="zjlId" id="BPMNShape_zjlId"> <omgdc:Bounds height="80.0" width="100.0" x="450.0" y="92.0"></omgdc:Bounds> </bpmndi:BPMNShape> <bpmndi:BPMNShape bpmnElement="sid-2C1AB747-3343-41FC-954C-70B992D32D14" id="BPMNShape_sid-2C1AB747-3343-41FC-954C-70B992D32D14"> <omgdc:Bounds height="28.0" width="28.0" x="660.0" y="118.0"></omgdc:Bounds> </bpmndi:BPMNShape> <bpmndi:BPMNEdge bpmnElement="sid-6B6AF669-F0E8-4D59-892A-162228D0510D" id="BPMNEdge_sid-6B6AF669-F0E8-4D59-892A-162228D0510D" flowable:sourceDockerX="15.0" flowable:sourceDockerY="15.0" flowable:targetDockerX="50.0" flowable:targetDockerY="40.0"> <omgdi:waypoint x="103.94999947166039" y="132.0"></omgdi:waypoint> <omgdi:waypoint x="225.0" y="132.0"></omgdi:waypoint> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge bpmnElement="sid-A5F5DC0C-5E0B-4A14-B748-CBCFFB98696D" id="BPMNEdge_sid-A5F5DC0C-5E0B-4A14-B748-CBCFFB98696D" flowable:sourceDockerX="50.0" flowable:sourceDockerY="40.0" flowable:targetDockerX="50.0" flowable:targetDockerY="40.0"> <omgdi:waypoint x="324.94999999996566" y="132.0"></omgdi:waypoint> <omgdi:waypoint x="449.9999999998968" y="132.0"></omgdi:waypoint> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge bpmnElement="sid-8B64D6FD-A229-4E53-B4EB-C86449387AE6" id="BPMNEdge_sid-8B64D6FD-A229-4E53-B4EB-C86449387AE6" flowable:sourceDockerX="50.0" flowable:sourceDockerY="40.0" flowable:targetDockerX="14.0" flowable:targetDockerY="14.0"> <omgdi:waypoint x="549.95" y="132.0"></omgdi:waypoint> <omgdi:waypoint x="660.0" y="132.0"></omgdi:waypoint> </bpmndi:BPMNEdge> </bpmndi:BPMNPlane> </bpmndi:BPMNDiagram> </definitions>
4.2. 部署并啟動(dòng)
// 部署流程 @Test public void test1() { ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); RepositoryService repositoryService = processEngine.getRepositoryService(); Deployment deploy = repositoryService.createDeployment() .addClasspathResource("processes/Countersign.bpmn20.xml") .name("加簽流程") .deploy(); System.out.println("deploy.getId() = " + deploy.getId()); System.out.println("deploy.getName() = " + deploy.getName()); } // 啟動(dòng)流程 @Test public void test2() { ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); RuntimeService runtimeService = processEngine.getRuntimeService(); // 給請(qǐng)假申請(qǐng)單分配用戶 Map<String, Object> variables = new HashMap<>(); variables.put("user", "張三"); ProcessInstance processInstance = runtimeService.startProcessInstanceById("Countersign:2:bf2eeed9-58f1-11ed-8017-005056c00001", variables); System.out.println("流程定義的ID:" + processInstance.getProcessDefinitionId()); System.out.println("流程實(shí)例的ID:" + processInstance.getId()); }
4.3. 完成任務(wù)
張三 完成請(qǐng)假申請(qǐng)單任務(wù)
// 張三完成請(qǐng)假申請(qǐng)單 @Test public void test3() { ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); TaskService taskService = processEngine.getTaskService(); Task task = taskService.createTaskQuery() .processInstanceId("57c743b9-58f2-11ed-9a6d-005056c00001") .taskAssignee("張三") .singleResult(); // 給總經(jīng)理審批分配用戶 Map<String, Object> variables = new HashMap<>(); variables.put("Boss", "周經(jīng)理"); if (task != null) { taskService.complete(task.getId(), variables); } }
查看 ACT_RU_TASK 表數(shù)據(jù)如下,任務(wù)節(jié)點(diǎn)發(fā)生了流轉(zhuǎn);到了總經(jīng)理審批節(jié)點(diǎn)了
4.4. 向前加簽實(shí)現(xiàn)
在實(shí)際中會(huì)出現(xiàn)特殊情況,如還需要 董事長(zhǎng) 審批,但在流程設(shè)計(jì)中并沒(méi)有 董事長(zhǎng) 這個(gè)流程節(jié)點(diǎn),所以需要用到加簽的功能
4.4.1. 添加加簽(委派)功能任務(wù)
將任務(wù)委托給另一個(gè)人,修改 ACT_RU_TASK 表記錄,硬編碼不推薦
- 如果任務(wù)所有者字段 OWNER_ 為 null,則將該字段置為任務(wù)的當(dāng)前受理人(如 周經(jīng)理)
- 委托狀態(tài)字段 DELEGATION_ 變更為 PENDING;DelegationState 是一個(gè)枚舉
- 當(dāng)前審批人字段 ASSIGNEE_ 變更為被委托人(如 孫董事長(zhǎng))
/** * 假如流程中出現(xiàn)特殊情況,需要特定的人員進(jìn)行審批后才可以正常的把流程走下去,而這個(gè)特定的人員一開(kāi)始 * 并沒(méi)有在流程設(shè)計(jì)中體現(xiàn)出來(lái),所以這時(shí)候就需要加簽這個(gè)功能,在某一節(jié)點(diǎn)處添加一個(gè)新的人員來(lái)處理這個(gè)流程 */ @Test public void test4() { ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); TaskService taskService = processEngine.getTaskService(); Task task = taskService.createTaskQuery() .processInstanceId("57c743b9-58f2-11ed-9a6d-005056c00001") .taskAssignee("周經(jīng)理") .singleResult(); if (task != null) { taskService.delegateTask(task.getId(), "孫董事長(zhǎng)"); } }
4.4.1. 加簽(委派)任務(wù)的完成
@Test public void test5() { ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); TaskService taskService = processEngine.getTaskService(); Task task = taskService.createTaskQuery() .processInstanceId("57c743b9-58f2-11ed-9a6d-005056c00001") .taskAssignee("孫董事長(zhǎng)") .singleResult(); if (task != null) { taskService.resolveTask(task.getId()); } }
加簽任務(wù)不能用 completeTask() 方法來(lái)完成,因?yàn)檫@個(gè)加簽的任務(wù)并不屬于正常流程中的一個(gè)節(jié)點(diǎn)任務(wù),加簽任務(wù)完后,任務(wù)還會(huì)回到加簽前的人員手里
查看 ACT_RU_TASK 表數(shù)據(jù)如下,任務(wù)節(jié)點(diǎn)發(fā)生了流轉(zhuǎn);又回到了 總經(jīng)理審批 節(jié)點(diǎn)了
- 任務(wù)所有者字段 OWNER_ 為 周經(jīng)理
- 當(dāng)前審批人字段 ASSIGNEE_ 為 周經(jīng)理
- 委托狀態(tài)字段 DELEGATION_ 變更為 RESOLVED
5. 轉(zhuǎn)簽(轉(zhuǎn)辦)
// 轉(zhuǎn)簽:就是把任務(wù)轉(zhuǎn)辦給他人 @Test public void transferTask() { ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); TaskService taskService = processEngine.getTaskService(); // 直接setAssignee即可 taskService.setAssignee("90002", "總監(jiān)"); }
到此這篇關(guān)于Java的Flowable工作流之加簽轉(zhuǎn)簽詳解的文章就介紹到這了,更多相關(guān)Flowable工作流加簽轉(zhuǎn)簽內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
hibernate-validator如何使用校驗(yàn)框架
高效、合理的使用hibernate-validator校驗(yàn)框架可以提高程序的可讀性,以及減少不必要的代碼邏輯,本文主要介紹了hibernate-validator如何使用校驗(yàn)框架,感興趣的可以了解一下2022-04-04Javaweb-HttpServletResponse的sendRedirectch重定向方式
這篇文章主要介紹了Javaweb-HttpServletResponse的sendRedirectch重定向方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-09-09Java Lambda List轉(zhuǎn)Map代碼實(shí)例
這篇文章主要介紹了Java Lambda List轉(zhuǎn)Map代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03Java實(shí)現(xiàn)將word轉(zhuǎn)換為html的方法示例【doc與docx格式】
這篇文章主要介紹了Java實(shí)現(xiàn)將word轉(zhuǎn)換為html的方法,結(jié)合實(shí)例形式分析了java針對(duì)doc與docx格式文件的相關(guān)轉(zhuǎn)換操作技巧,需要的朋友可以參考下2019-03-03Java實(shí)現(xiàn)的各種排序算法(插入排序、選擇排序算法、冒泡排序算法)
本文是小編給大家?guī)?lái)的java各種排序算法知識(shí),包括插入排序、選擇排序算法、冒泡排序算法,代碼簡(jiǎn)單易懂,需要的朋友可以參考下2016-08-08MyBatis Generator的簡(jiǎn)單使用方法示例
這篇文章主要給大家介紹了關(guān)于MyBatis Generator的簡(jiǎn)單使用方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-02-02通過(guò)java記錄數(shù)據(jù)持續(xù)變化時(shí)間代碼解析
這篇文章主要介紹了通過(guò)java記錄數(shù)據(jù)持續(xù)變化時(shí)間代碼解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-01-01