网关(ExclusiveGateWay)

作者:邓家海
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应当改为" role="presentation">user.My−Name应当改为user.My−Name应当改为{user["My-Name"]}
如果要动态取值时,就可以用“[ ]“来做,而“.“无法做到动态取值。例如:
${sessionScope.user[data]}中data 是一个变量

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

图4 设置表达式

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

图6 设置表达式

无表达式:默认
默认是指其他其他条件都不满足的条件下,走默认路线。

图7 设置表达式

流程图代码:

 <?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: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">
<process id="process" isExecutable="true">
<startEvent id="sid-7FF420A9-E0A3-435A-8C64-17F4948E169F" />
<userTask id="sid-77BDF7D7-590C-421B-AE15-8BA17A6C37BB" name="部门" activiti:assignee="admin" />
<exclusiveGateway id="sid-8E4A81E5-2B71-4397-A8F1-242C7B0F4DC9" default="sid-21324A76-AD4C-4B76-989A-4870D2AACA3C" />
<userTask id="sid-E53B2318-C85B-442F-9DA7-56E96341FB79" name="财务经理" activiti:assignee="admin" />
<userTask id="sid-E974CD46-11DC-4860-B277-E452C97D4487" name="财务主管" activiti:assignee="admin" />
<endEvent id="sid-6E6E0074-2729-4217-B273-938DE98CF5BE" />
<sequenceFlow id="sid-48D646A3-2C45-4F83-9BAF-0ABECFE842D0" sourceRef="sid-E53B2318-C85B-442F-9DA7-56E96341FB79" targetRef="sid-6E6E0074-2729-4217-B273-938DE98CF5BE" />
<sequenceFlow id="sid-B8EA0191-9F35-4D09-BEA6-EF41420A86ED" sourceRef="sid-7FF420A9-E0A3-435A-8C64-17F4948E169F" targetRef="sid-77BDF7D7-590C-421B-AE15-8BA17A6C37BB" />
<sequenceFlow id="sid-4298366E-F857-4818-8570-DDF1DA7F41AF" sourceRef="sid-77BDF7D7-590C-421B-AE15-8BA17A6C37BB" targetRef="sid-8E4A81E5-2B71-4397-A8F1-242C7B0F4DC9" />
<userTask id="sid-8DE1277A-5CAA-4576-A7CD-55E6272B0A6C" name="财务" activiti:assignee="admin" />
<sequenceFlow id="sid-4C05BAAF-2FBC-4220-B832-52FFEED2A855" sourceRef="sid-8DE1277A-5CAA-4576-A7CD-55E6272B0A6C" targetRef="sid-6E6E0074-2729-4217-B273-938DE98CF5BE" />
<sequenceFlow id="sid-21324A76-AD4C-4B76-989A-4870D2AACA3C" name="默认" sourceRef="sid-8E4A81E5-2B71-4397-A8F1-242C7B0F4DC9" targetRef="sid-8DE1277A-5CAA-4576-A7CD-55E6272B0A6C" />
<sequenceFlow id="sid-8D92C614-D1B7-4AF9-9489-F7AAA9732868" sourceRef="sid-E974CD46-11DC-4860-B277-E452C97D4487" targetRef="sid-6E6E0074-2729-4217-B273-938DE98CF5BE" />
<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">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${money>1&&money<30}]]></conditionExpression>
</sequenceFlow>
<sequenceFlow id="sid-D916A9B9-DC9A-4FC1-BB6B-377520F5F7FC" name="金额>=30万" sourceRef="sid-8E4A81E5-2B71-4397-A8F1-242C7B0F4DC9" targetRef="sid-E974CD46-11DC-4860-B277-E452C97D4487">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${money>=30}]]></conditionExpression>
</sequenceFlow>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_process">
<bpmndi:BPMNPlane bpmnElement="process" id="BPMNPlane_process">
<bpmndi:BPMNShape bpmnElement="sid-7FF420A9-E0A3-435A-8C64-17F4948E169F" id="BPMNShape_sid-7FF420A9-E0A3-435A-8C64-17F4948E169F">
<omgdc:Bounds height="30.0" width="30.0" x="105.0" y="155.0" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="sid-77BDF7D7-590C-421B-AE15-8BA17A6C37BB" id="BPMNShape_sid-77BDF7D7-590C-421B-AE15-8BA17A6C37BB">
<omgdc:Bounds height="80.0" width="100.0" x="202.0" y="130.0" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="sid-8E4A81E5-2B71-4397-A8F1-242C7B0F4DC9" id="BPMNShape_sid-8E4A81E5-2B71-4397-A8F1-242C7B0F4DC9">
<omgdc:Bounds height="40.0" width="40.0" x="360.0" y="150.0" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="sid-E53B2318-C85B-442F-9DA7-56E96341FB79" id="BPMNShape_sid-E53B2318-C85B-442F-9DA7-56E96341FB79">
<omgdc:Bounds height="80.0" width="100.0" x="525.0" y="0.0" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="sid-E974CD46-11DC-4860-B277-E452C97D4487" id="BPMNShape_sid-E974CD46-11DC-4860-B277-E452C97D4487">
<omgdc:Bounds height="80.0" width="100.0" x="540.0" y="130.0" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="sid-6E6E0074-2729-4217-B273-938DE98CF5BE" id="BPMNShape_sid-6E6E0074-2729-4217-B273-938DE98CF5BE">
<omgdc:Bounds height="28.0" width="28.0" x="735.0" y="156.0" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="sid-8DE1277A-5CAA-4576-A7CD-55E6272B0A6C" id="BPMNShape_sid-8DE1277A-5CAA-4576-A7CD-55E6272B0A6C">
<omgdc:Bounds height="80.0" width="100.0" x="529.0" y="254.0" />
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="sid-4298366E-F857-4818-8570-DDF1DA7F41AF" id="BPMNEdge_sid-4298366E-F857-4818-8570-DDF1DA7F41AF">
<omgdi:waypoint x="302.0" y="170.0" />
<omgdi:waypoint x="360.0" y="170.0" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sid-D916A9B9-DC9A-4FC1-BB6B-377520F5F7FC" id="BPMNEdge_sid-D916A9B9-DC9A-4FC1-BB6B-377520F5F7FC">
<omgdi:waypoint x="399.54545454545456" y="170.45454545454547" />
<omgdi:waypoint x="540.0" y="170.11933174224345" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sid-21324A76-AD4C-4B76-989A-4870D2AACA3C" id="BPMNEdge_sid-21324A76-AD4C-4B76-989A-4870D2AACA3C">
<omgdi:waypoint x="392.2127329192547" y="177.78726708074535" />
<omgdi:waypoint x="529.0" y="262.89168765743074" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sid-8D92C614-D1B7-4AF9-9489-F7AAA9732868" id="BPMNEdge_sid-8D92C614-D1B7-4AF9-9489-F7AAA9732868">
<omgdi:waypoint x="640.0" y="170.0" />
<omgdi:waypoint x="735.0" y="170.0" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sid-838AEA2C-C494-4830-B78F-20EBA96ECB43" id="BPMNEdge_sid-838AEA2C-C494-4830-B78F-20EBA96ECB43">
<omgdi:waypoint x="392.46923076923076" y="162.46923076923076" />
<omgdi:waypoint x="525.0" y="73.54755784061696" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sid-4C05BAAF-2FBC-4220-B832-52FFEED2A855" id="BPMNEdge_sid-4C05BAAF-2FBC-4220-B832-52FFEED2A855">
<omgdi:waypoint x="629.0" y="257.52941176470586" />
<omgdi:waypoint x="737.6892144673815" y="178.25022003555705" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sid-48D646A3-2C45-4F83-9BAF-0ABECFE842D0" id="BPMNEdge_sid-48D646A3-2C45-4F83-9BAF-0ABECFE842D0">
<omgdi:waypoint x="625.0" y="77.35632183908046" />
<omgdi:waypoint x="737.7845494056976" y="161.6206403605787" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sid-B8EA0191-9F35-4D09-BEA6-EF41420A86ED" id="BPMNEdge_sid-B8EA0191-9F35-4D09-BEA6-EF41420A86ED">
<omgdi:waypoint x="135.0" y="170.0" />
<omgdi:waypoint x="202.0" y="170.0" />
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>

步骤三:测试

1).如果是大于1万小于30万
完成任务代码

 /**完成我的任务*/
@Test
public void completeMyPersonalTask(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
String taskId="377542";
Map<String,Object> variables=new HashMap<String,Object>();
variables.put("money", 20);
processEngine.getTaskService()//与正在执行的案例管理相关的Service
.complete(taskId,variables); System.out.println("完成任务,任务ID:"+taskId);
}

图8 测试流程跟踪

2).如果是大于或者等于30万

 /**完成我的任务*/
@Test
public void completeMyPersonalTask(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
String taskId="385053";
Map<String,Object> variables=new HashMap<String,Object>();
variables.put("money", 40);
processEngine.getTaskService()//与正在执行的案例管理相关的Service
.complete(taskId,variables); System.out.println("完成任务,任务ID:"+taskId);
}

图9 测试流程跟踪

3).如果是小于1万(没有满足条件的,走默认路径:财务):

 /**完成我的任务*/
@Test
public void completeMyPersonalTask(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
String taskId="385048";
Map<String,Object> variables=new HashMap<String,Object>();
variables.put("money", 0.2);
processEngine.getTaskService()//与正在执行的案例管理相关的Service
.complete(taskId,variables); System.out.println("完成任务,任务ID:"+taskId);
}

图10 测试流程跟踪

4).如果没有设置金额

 /**完成我的任务*/
@Test
public void completeMyPersonalTask(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
String taskId="385048";
//Map<String,Object> variables=new HashMap<String,Object>();
//variables.put("money", 0.2);
processEngine.getTaskService()//与正在执行的案例管理相关的Service
.complete(taskId); 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 测试流程图设计

 /**完成我的任务*/
@Test
public void completeMyPersonalTask(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
String taskId="385022";
Map<String,Object> variables=new HashMap<String,Object>();
variables.put("money", 0.2);
processEngine.getTaskService()//与正在执行的案例管理相关的Service
.complete(taskId,variables); System.out.println("完成任务,任务ID:"+taskId);
}

会抛异常: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}

 /**完成我的任务*/
@Test
public void completeMyPersonalTask(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
String taskId="385063";
Map<String,Object> variables=new HashMap<String,Object>();
variables.put("money", 40);
variables.put("num1", 30);
variables.put("num2", 1);
variables.put("num3", 30);
variables.put("num3", 1);
processEngine.getTaskService()//与正在执行的案例管理相关的Service
.complete(taskId,variables); System.out.println("完成任务,任务ID:"+taskId);
}

图12 测试流程跟踪

第二种,后台判断
设置表达式:
财务经理:
${flow==”1” }
财务主管:
${flow==”2” }
财务:
${flow==”3” }

 @Test
public void completeMyPersonalTask(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
String taskId="385072";
Map<String,Object> variables=new HashMap<String,Object>();
int money=40;
if(money>=30){
variables.put("flow", "1");
}else if(money>1&&money<30){
variables.put("flow", "2");
}else{
variables.put("flow", "3");
}
processEngine.getTaskService()//与正在执行的案例管理相关的Service
.complete(taskId,variables); System.out.println("完成任务,任务ID:"+taskId);
}

图13 测试流程跟踪

Activiti交流QQ群:634320089

原文地址:https://www.cnblogs.com/dengjiahai/p/8542929.html

排他网关(ExclusiveGateWay)的更多相关文章

  1. activiti实战系列 排他网关(ExclusiveGateWay)

    流程图 12.2:部署流程定义+启动流程实例 12.3:查询我的个人任务 12.4:完成我的个人任务 说明: 1)     一个排他网关对应一个以上的顺序流 2)     由排他网关流出的顺序流都有个 ...

  2. activiti入门3排他网关,并行网管,包含网关,事件网关(转)

    网关用来控制流程的流向 网关可以消费也可以生成token. 网关显示成菱形图形,内部有有一个小图标. 图标表示网关的类型. 基本分支 首先 利用 流程变量  写个带有分支的一个基本流程 流程图: 部署 ...

  3. Activiti第三篇【连接、排他网关、指定任务处理人、组任务】

    连线 上面我们已将学过了流程变量了,可以在[任务服务.运行时服务.流程开始.完成某个任务时设置流程变量],而我们的连接就是流程变量的实际应用了-. 定义流程图 我们并不是所有的流程都是按一条的路径来走 ...

  4. activiti入门3排他网关,并行网管,包括网关,事件网关

    网关用来控制流程的流向 网关能够消费也能够生成token. 网关显示成菱形图形,内部有有一个小图标. 图标表示网关的类型. 基本分支 首先 利用 流程变量  写个带有分支的一个基本流程 流程图: wa ...

  5. Activity并行网关和排他网关

    说一说activiti中的排他网关和并行网关 activiti工作流中我们经常用到的网关有两种: 1. Exclusive Gateway 排他网关 排他网关.png 排他网关(也叫异或(XOR)网关 ...

  6. java中activiti框架中的排他网关使用方法,多条件判断

    当排他网关的判断条件中出现多个条件时,需要注意,设置判断条件时,可能遇到,流向相同的任务,而判断条件的变量个数不同 那么,必须在后面的运行任务时,将所有的涉及到的变量都设置进任务中,只不过,如果这个任 ...

  7. Activiti网关--排他网关

    排他网关 1.什么是排他网关 排他网关(也叫异或(XOR)网关,或叫基于数据的排他网关),用来在流程中实现决策. 当流程执行到这个网关,所有分支都会判断条件是否为true,如果为 true 则执行该分 ...

  8. Activiti7 网关(排他网关)

    什么是排他网关? 排他网关(也叫异或(XOR)网关,或叫基于数据的排他网关),用于在流程中实现决策,当流程执行到这个网关,所有分支都会判断条件是否为true,如果为true则执行该分支 注意:排他网关 ...

  9. activiti排他网关

    /*启动流程实例*可以在启动流程时把所有流程变量设置好*/@Test public void startProcessInstance(){ //流程定义key String processDefin ...

随机推荐

  1. Node.js调试技巧

    1. console.log 跟前端调试相同,通过一步步打印相关变量进行代码调试 2. 使用Node.js内置的调试器 通过node debug xxx.js来进行调试: [root@~/wade/n ...

  2. Laravel 安装mysql、表增加模拟数据、生成控制器

    参考中文网教程: 安装mysql.表增加模拟数据 http://www.golaravel.com/post/2016-ban-laravel-xi-lie-ru-men-jiao-cheng-yi/ ...

  3. Codeforces 375A

    这是一道数学题,真是很考验数学思维,之前也遇到过相似的问题,但是依然是想不到点子上,就这提而言,最重要的就是 能否发现由 1, 6, 8,9这四个数字组成的排列对7取模是可以得到0, 1, 2, 3, ...

  4. 移动端h5禁用浏览器左滑右滑的前进后退功能

    在项目运行过程中发现,用户在有左右滑动前进后退的功能的浏览器上签字时,偶然触发了前进后退会导致canvas像是重置了一样内容消失,所以需要在代码中处理这种情况. 基本原理就是在touchmove事件中 ...

  5. LintCode 合并二维数组

    合并两个排序的整数数组A和B变成一个新的数组. 样例 给出A=[1,2,3,4],B=[2,4,5,6],返回 [1,2,2,3,4,4,5,6] 之前想的是用剑指offer里替换空格那种方法 但是把 ...

  6. Ubuntu 安装 setuptools

    Setuptools的官方页面 Easily download, build, install, upgrade, and uninstall Python packages 它是一个对python的 ...

  7. 【JZOJ5094】【GDSOI2017第四轮模拟day3】鸽子 计算几何+floyd

    题面 养鸽人要监视他的鸽子,有n只鸽子站在平面上,他可以在m个给定的点上设置监视器,如果一只鸽子在某个监视器上或者在两个监视器所连直线上或者在三个监视器所连直线的三角形内则其就咕咕咕了,现在养鸽人要让 ...

  8. GitHub上的SliddingMenu滑动过程中卡顿问题的解决的方法

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/wenyiqingnianiii/article/details/25123995 找了非常久,仅仅需 ...

  9. Windows10 +Ubuntu 18.04双系统安装详细教程

    前言: 由于开发需要,很多用户需要安装Linux环境.如果用虚拟机操作会消耗大量内存,一般的电脑会显得卡顿,从而影响开发效率.这里分享一些安装经验,希望能够帮助大家. 教程: 步骤1:下载镜像文件 从 ...

  10. python判断输入日期是该年的第几天

    1.输入日期,判断日期是该年度的第几天 iyear = int(input("请输入年:\n")) imonth = int(input("请输入月:\n")) ...