排他網關(ExclusiveGateWay)


網關(ExclusiveGateWay)

作者:Jesai
2018年3月11日 00:13:25

情景:
某一家公司最近在給一個單位做一個財務審批的OA。具體需求是這樣的:當部門申請的金額小於一萬塊的時候,財務部可以直接決策。當部分申請的金額大於一萬塊並且小於三十萬的時候,財務部經理決策,當金額超出了或者等於三十萬的時候,需要財務主管來決策。那么我們的工作流應該如何設計呢?
也許有人會說,這不簡單,小於一萬直接發送到財務部,大於一萬小於三十,直接給財務經理。其他就發給財務主管。
你是否注意到,其實這樣字可以存在審批漏洞。打個比方,我跟部門一個哥們非常好,我又想申請大於一萬的經費。我是不是可以直接越過領導發送給我哥們,讓他給我放款。再或者,來了一個新人,新人並不知道這個申請的規則,申請幾塊錢,也發給了財務主管,財務主管非常生氣的說:我很忙的,沒空給你處理這些蒜皮小事。
分析:
工作流的作用無非就是自動化,規范化。形成一整套的流程。制定好一些列規則后,能夠嚴格遵守這些規則來處理任務。很多一些國產的工作流很靈活,但是審核機制或者工作機制很不嚴謹。我是不怎么理解這些工作流中國化的。當然,客戶是上帝,客戶說了算。我們這里以BPMN2.0的標准。就可以使用排他網關來實現我們的需求。
關於排他網關:
1. 排他網關exclusive gateway 經常使用流程變量決定流程下一步要選擇的路徑
2. 排他網關(也叫異或網關 XOR gateway,或者更專業的,基於數據的排他網關 exclusive data¬based gateway),用於為流程中的決策建模。
3. 當執行到達這個網關時,所有出口順序流會按照它們定義的順序進行計算。條件計算為true的順序流(當沒有設置條件時,認為順序流定義為true)會被選擇用於繼續流程。
4. 用排他網關時,只會選擇一條順序流。當多條順序 流的條件都計算為true時,其中在XML中定義的第一條(也只有這條)會被選擇,用於繼續流程。如果沒有可選的順序流,會拋出異常。
5. 排他網關,用內部帶有’X’圖標的標准網關(菱形)表示,'X’圖標代表異或(XOR)的含義。請注意內部沒有圖標的網關默認為排他網關。BPMN 2.0規范不允許在同一個流程中,混合使用帶有及沒有X的菱形標志
6. 一個排他網關對應一個以上的順序流


圖1 排他網關

說明:網關是一個菱形◇,排他網關就是菱形里面加個'X’,'X’圖標代表異或(XOR)的含義



圖2 默認順序流

說明:默認順序流,用起點帶有“斜線”標記的一般順序流表示。
活動的默認順序流,由該活動的default屬性定義。
當其他連線計算都為false的時候,才會走默認順序流。

排他網關的實現:

關於資金申請審批流程。
步驟一:設計流程圖
我們這里設置一個發起部門,就是資金發起申請部門
流程申請的流程:
1. 小於或者等於一萬的,直接走財務審批即可
2. 大於一萬小於三十萬的,需要財務經理審批。
3. 大於或者等於三十萬的,需要愛財務主管審批。



圖3 排他網關設計

步驟二:並設置表達式

Activiti里面設置表達式可以用EL(Expression Language)表達式。。表達式語言的靈感來自於 ECMAScript 和 XPath 表達式語言,它提供了在 JSP 中簡化表達式的方法,讓Jsp的代碼更加簡化。EL不在本章節的討論范圍內,需要了解的可以自行找資料。
1、語法結構
${expression}
2、[ ]與.運算符
EL 提供“.“和“[ ]“兩種運算符來存取數據。
當要存取的屬性名稱中包含一些特殊字符,如 . 或 - 等並非字母或數字的符號,就一定要使用“[ ]“。例如:
${ user. My-Name}應當改為${user["My-Name"]}
如果要動態取值時,就可以用“[ ]“來做,而“.“無法做到動態取值。例如:
${sessionScope.user[data]}中data 是一個變量

表達式一:${money>1&&money<30}


 


圖4 設置表達式

表達式二:${money>=30}


 


圖6 設置表達式

無表達式:默認
默認是指其他其他條件都不滿足的條件下,走默認路線。



 

圖7 設置表達式

流程圖代碼:

 1 <?xml version='1.0' encoding='UTF-8'?>
 2 <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:activiti="http://activiti.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.activiti.org/processdef">
 3 <process id="process" isExecutable="true">
 4 <startEvent id="sid-7FF420A9-E0A3-435A-8C64-17F4948E169F" />
 5 <userTask id="sid-77BDF7D7-590C-421B-AE15-8BA17A6C37BB" name="部門" activiti:assignee="admin" />
 6 <exclusiveGateway id="sid-8E4A81E5-2B71-4397-A8F1-242C7B0F4DC9" default="sid-21324A76-AD4C-4B76-989A-4870D2AACA3C" />
 7 <userTask id="sid-E53B2318-C85B-442F-9DA7-56E96341FB79" name="財務經理" activiti:assignee="admin" />
 8 <userTask id="sid-E974CD46-11DC-4860-B277-E452C97D4487" name="財務主管" activiti:assignee="admin" />
 9 <endEvent id="sid-6E6E0074-2729-4217-B273-938DE98CF5BE" />
10 <sequenceFlow id="sid-48D646A3-2C45-4F83-9BAF-0ABECFE842D0" sourceRef="sid-E53B2318-C85B-442F-9DA7-56E96341FB79" targetRef="sid-6E6E0074-2729-4217-B273-938DE98CF5BE" />
11 <sequenceFlow id="sid-B8EA0191-9F35-4D09-BEA6-EF41420A86ED" sourceRef="sid-7FF420A9-E0A3-435A-8C64-17F4948E169F" targetRef="sid-77BDF7D7-590C-421B-AE15-8BA17A6C37BB" />
12 <sequenceFlow id="sid-4298366E-F857-4818-8570-DDF1DA7F41AF" sourceRef="sid-77BDF7D7-590C-421B-AE15-8BA17A6C37BB" targetRef="sid-8E4A81E5-2B71-4397-A8F1-242C7B0F4DC9" />
13 <userTask id="sid-8DE1277A-5CAA-4576-A7CD-55E6272B0A6C" name="財務" activiti:assignee="admin" />
14 <sequenceFlow id="sid-4C05BAAF-2FBC-4220-B832-52FFEED2A855" sourceRef="sid-8DE1277A-5CAA-4576-A7CD-55E6272B0A6C" targetRef="sid-6E6E0074-2729-4217-B273-938DE98CF5BE" />
15 <sequenceFlow id="sid-21324A76-AD4C-4B76-989A-4870D2AACA3C" name="默認" sourceRef="sid-8E4A81E5-2B71-4397-A8F1-242C7B0F4DC9" targetRef="sid-8DE1277A-5CAA-4576-A7CD-55E6272B0A6C" />
16 <sequenceFlow id="sid-8D92C614-D1B7-4AF9-9489-F7AAA9732868" sourceRef="sid-E974CD46-11DC-4860-B277-E452C97D4487" targetRef="sid-6E6E0074-2729-4217-B273-938DE98CF5BE" />
17 <sequenceFlow id="sid-838AEA2C-C494-4830-B78F-20EBA96ECB43" name="金額&lt;30萬且大於1萬" sourceRef="sid-8E4A81E5-2B71-4397-A8F1-242C7B0F4DC9" targetRef="sid-E53B2318-C85B-442F-9DA7-56E96341FB79">
18 <conditionExpression xsi:type="tFormalExpression"><![CDATA[${money>1&&money<30}]]></conditionExpression>
19 </sequenceFlow>
20 <sequenceFlow id="sid-D916A9B9-DC9A-4FC1-BB6B-377520F5F7FC" name="金額>=30萬" sourceRef="sid-8E4A81E5-2B71-4397-A8F1-242C7B0F4DC9" targetRef="sid-E974CD46-11DC-4860-B277-E452C97D4487">
21 <conditionExpression xsi:type="tFormalExpression"><![CDATA[${money>=30}]]></conditionExpression>
22 </sequenceFlow>
23 </process>
24 <bpmndi:BPMNDiagram id="BPMNDiagram_process">
25 <bpmndi:BPMNPlane bpmnElement="process" id="BPMNPlane_process">
26 <bpmndi:BPMNShape bpmnElement="sid-7FF420A9-E0A3-435A-8C64-17F4948E169F" id="BPMNShape_sid-7FF420A9-E0A3-435A-8C64-17F4948E169F">
27 <omgdc:Bounds height="30.0" width="30.0" x="105.0" y="155.0" />
28 </bpmndi:BPMNShape>
29 <bpmndi:BPMNShape bpmnElement="sid-77BDF7D7-590C-421B-AE15-8BA17A6C37BB" id="BPMNShape_sid-77BDF7D7-590C-421B-AE15-8BA17A6C37BB">
30 <omgdc:Bounds height="80.0" width="100.0" x="202.0" y="130.0" />
31 </bpmndi:BPMNShape>
32 <bpmndi:BPMNShape bpmnElement="sid-8E4A81E5-2B71-4397-A8F1-242C7B0F4DC9" id="BPMNShape_sid-8E4A81E5-2B71-4397-A8F1-242C7B0F4DC9">
33 <omgdc:Bounds height="40.0" width="40.0" x="360.0" y="150.0" />
34 </bpmndi:BPMNShape>
35 <bpmndi:BPMNShape bpmnElement="sid-E53B2318-C85B-442F-9DA7-56E96341FB79" id="BPMNShape_sid-E53B2318-C85B-442F-9DA7-56E96341FB79">
36 <omgdc:Bounds height="80.0" width="100.0" x="525.0" y="0.0" />
37 </bpmndi:BPMNShape>
38 <bpmndi:BPMNShape bpmnElement="sid-E974CD46-11DC-4860-B277-E452C97D4487" id="BPMNShape_sid-E974CD46-11DC-4860-B277-E452C97D4487">
39 <omgdc:Bounds height="80.0" width="100.0" x="540.0" y="130.0" />
40 </bpmndi:BPMNShape>
41 <bpmndi:BPMNShape bpmnElement="sid-6E6E0074-2729-4217-B273-938DE98CF5BE" id="BPMNShape_sid-6E6E0074-2729-4217-B273-938DE98CF5BE">
42 <omgdc:Bounds height="28.0" width="28.0" x="735.0" y="156.0" />
43 </bpmndi:BPMNShape>
44 <bpmndi:BPMNShape bpmnElement="sid-8DE1277A-5CAA-4576-A7CD-55E6272B0A6C" id="BPMNShape_sid-8DE1277A-5CAA-4576-A7CD-55E6272B0A6C">
45 <omgdc:Bounds height="80.0" width="100.0" x="529.0" y="254.0" />
46 </bpmndi:BPMNShape>
47 <bpmndi:BPMNEdge bpmnElement="sid-4298366E-F857-4818-8570-DDF1DA7F41AF" id="BPMNEdge_sid-4298366E-F857-4818-8570-DDF1DA7F41AF">
48 <omgdi:waypoint x="302.0" y="170.0" />
49 <omgdi:waypoint x="360.0" y="170.0" />
50 </bpmndi:BPMNEdge>
51 <bpmndi:BPMNEdge bpmnElement="sid-D916A9B9-DC9A-4FC1-BB6B-377520F5F7FC" id="BPMNEdge_sid-D916A9B9-DC9A-4FC1-BB6B-377520F5F7FC">
52 <omgdi:waypoint x="399.54545454545456" y="170.45454545454547" />
53 <omgdi:waypoint x="540.0" y="170.11933174224345" />
54 </bpmndi:BPMNEdge>
55 <bpmndi:BPMNEdge bpmnElement="sid-21324A76-AD4C-4B76-989A-4870D2AACA3C" id="BPMNEdge_sid-21324A76-AD4C-4B76-989A-4870D2AACA3C">
56 <omgdi:waypoint x="392.2127329192547" y="177.78726708074535" />
57 <omgdi:waypoint x="529.0" y="262.89168765743074" />
58 </bpmndi:BPMNEdge>
59 <bpmndi:BPMNEdge bpmnElement="sid-8D92C614-D1B7-4AF9-9489-F7AAA9732868" id="BPMNEdge_sid-8D92C614-D1B7-4AF9-9489-F7AAA9732868">
60 <omgdi:waypoint x="640.0" y="170.0" />
61 <omgdi:waypoint x="735.0" y="170.0" />
62 </bpmndi:BPMNEdge>
63 <bpmndi:BPMNEdge bpmnElement="sid-838AEA2C-C494-4830-B78F-20EBA96ECB43" id="BPMNEdge_sid-838AEA2C-C494-4830-B78F-20EBA96ECB43">
64 <omgdi:waypoint x="392.46923076923076" y="162.46923076923076" />
65 <omgdi:waypoint x="525.0" y="73.54755784061696" />
66 </bpmndi:BPMNEdge>
67 <bpmndi:BPMNEdge bpmnElement="sid-4C05BAAF-2FBC-4220-B832-52FFEED2A855" id="BPMNEdge_sid-4C05BAAF-2FBC-4220-B832-52FFEED2A855">
68 <omgdi:waypoint x="629.0" y="257.52941176470586" />
69 <omgdi:waypoint x="737.6892144673815" y="178.25022003555705" />
70 </bpmndi:BPMNEdge>
71 <bpmndi:BPMNEdge bpmnElement="sid-48D646A3-2C45-4F83-9BAF-0ABECFE842D0" id="BPMNEdge_sid-48D646A3-2C45-4F83-9BAF-0ABECFE842D0">
72 <omgdi:waypoint x="625.0" y="77.35632183908046" />
73 <omgdi:waypoint x="737.7845494056976" y="161.6206403605787" />
74 </bpmndi:BPMNEdge>
75 <bpmndi:BPMNEdge bpmnElement="sid-B8EA0191-9F35-4D09-BEA6-EF41420A86ED" id="BPMNEdge_sid-B8EA0191-9F35-4D09-BEA6-EF41420A86ED">
76 <omgdi:waypoint x="135.0" y="170.0" />
77 <omgdi:waypoint x="202.0" y="170.0" />
78 </bpmndi:BPMNEdge>
79 </bpmndi:BPMNPlane>
80 </bpmndi:BPMNDiagram>
81 </definitions>

 

步驟三:測試

1).如果是大於1萬小於30萬
完成任務代碼

 1 /**完成我的任務*/
 2 @Test
 3 public void completeMyPersonalTask(){
 4 ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
 5 String taskId="377542";
 6 Map<String,Object> variables=new HashMap<String,Object>();
 7 variables.put("money", 20);
 8 processEngine.getTaskService()//與正在執行的案例管理相關的Service
 9 .complete(taskId,variables);
10 
11 System.out.println("完成任務,任務ID:"+taskId);
12 }

 


 


圖8 測試流程跟蹤

2).如果是大於或者等於30萬

 1 /**完成我的任務*/
 2 @Test
 3 public void completeMyPersonalTask(){
 4 ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
 5 String taskId="385053";
 6 Map<String,Object> variables=new HashMap<String,Object>();
 7 variables.put("money", 40);
 8 processEngine.getTaskService()//與正在執行的案例管理相關的Service
 9 .complete(taskId,variables);
10 
11 System.out.println("完成任務,任務ID:"+taskId);
12 }

 

 


圖9 測試流程跟蹤

3).如果是小於1萬(沒有滿足條件的,走默認路徑:財務):

 1 /**完成我的任務*/
 2 @Test
 3 public void completeMyPersonalTask(){
 4 ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
 5 String taskId="385048";
 6 Map<String,Object> variables=new HashMap<String,Object>();
 7 variables.put("money", 0.2);
 8 processEngine.getTaskService()//與正在執行的案例管理相關的Service
 9 .complete(taskId,variables);
10 
11 System.out.println("完成任務,任務ID:"+taskId);
12 }

 


 

圖10 測試流程跟蹤

4).如果沒有設置金額

 1 /**完成我的任務*/
 2 @Test
 3 public void completeMyPersonalTask(){
 4 ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
 5 String taskId="385048";
 6 //Map<String,Object> variables=new HashMap<String,Object>();
 7 //variables.put("money", 0.2);
 8 processEngine.getTaskService()//與正在執行的案例管理相關的Service
 9 .complete(taskId);
10 
11 System.out.println("完成任務,任務ID:"+taskId);

 

會拋一個異常:Unknown property used in expression: ${money>1&&money<30}

org.activiti.engine.ActivitiException: Unknown property used in expression: ${money>1&&money<30}

5).如果沒有默認順序流,又沒有滿足的條件(2000)

 



圖11 測試流程圖設計

 

 1 /**完成我的任務*/
 2 @Test
 3 public void completeMyPersonalTask(){
 4 ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
 5 String taskId="385022";
 6 Map<String,Object> variables=new HashMap<String,Object>();
 7 variables.put("money", 0.2);
 8 processEngine.getTaskService()//與正在執行的案例管理相關的Service
 9 .complete(taskId,variables);
10 
11 System.out.println("完成任務,任務ID:"+taskId);
12 }

 

會拋異常:No outgoing sequence flow of the exclusive gateway

org.activiti.engine.ActivitiException: No outgoing sequence flow of the exclusive gateway 'sid-8E4A81E5-2B71-4397-A8F1-242C7B0F4DC9' could be selected for continuing the process

擴展:

假如我部門是確定了,但是我的金額可能是隨時變動的,那么有兩種方案第一種,全部動態表達式:
財務經理:
${money>num2&&money<num3}
財務主管:
${money>=num1}
財務:
${money<num4}

 1 /**完成我的任務*/
 2 @Test
 3 public void completeMyPersonalTask(){
 4 ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
 5 String taskId="385063";
 6 Map<String,Object> variables=new HashMap<String,Object>();
 7 variables.put("money", 40);
 8 variables.put("num1", 30);
 9 variables.put("num2", 1);
10 variables.put("num3", 30);
11 variables.put("num3", 1);
12 processEngine.getTaskService()//與正在執行的案例管理相關的Service
13 .complete(taskId,variables);
14 
15 System.out.println("完成任務,任務ID:"+taskId);
16 }

 


 


圖12 測試流程跟蹤

第二種,后台判斷
設置表達式:
財務經理:
${flow==”1” }
財務主管:
${flow==”2” }
財務:
${flow==”3” }

 1 @Test
 2 public void completeMyPersonalTask(){
 3 ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
 4 String taskId="385072";
 5 Map<String,Object> variables=new HashMap<String,Object>();
 6 int money=40;
 7 if(money>=30){
 8 variables.put("flow", "1");
 9 }else if(money>1&&money<30){
10 variables.put("flow", "2");
11 }else{
12 variables.put("flow", "3");
13 }
14 processEngine.getTaskService()//與正在執行的案例管理相關的Service
15 .complete(taskId,variables);
16 
17 System.out.println("完成任務,任務ID:"+taskId);
18 }

 



圖13 測試流程跟蹤

  Activiti交流QQ群:634320089


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM