首先我这里有两张bpmn的图和其对应的xml文件:
上图对应的xml:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:tns="http://www.activiti.org/testm1539766523202" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" expressionLanguage="http://www.w3.org/1999/XPath" id="m1539766523202" name="" targetNamespace="http://www.activiti.org/testm1539766523202" typeLanguage="http://www.w3.org/2001/XMLSchema"> <process id="leave1" name="leave1" isClosed="false" isExecutable="true" processType="None"> <startEvent id="_2" name="start"/> <userTask activiti:assignee="${leave.userId}" activiti:exclusive="true" id="_3" name="submit"/> <exclusiveGateway gatewayDirection="Unspecified" id="_4" name="result"/> <userTask activiti:assignee="${leave.approver1}" activiti:exclusive="true" id="_5" name="approve1"/> <exclusiveGateway gatewayDirection="Unspecified" id="_6" name="result"/> <userTask activiti:assignee="${leave.approver2}" activiti:exclusive="true" id="_7" name="approve2"/> <exclusiveGateway gatewayDirection="Unspecified" id="_8" name="result"/> <endEvent id="_9" name="end"/> <sequenceFlow id="_10" sourceRef="_2" targetRef="_3"/> <sequenceFlow id="_11" sourceRef="_3" targetRef="_4"/> <sequenceFlow id="_12" name="y" sourceRef="_4" targetRef="_5"> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${leave.submit==true}]]></conditionExpression> </sequenceFlow> <sequenceFlow id="_13" name="n" sourceRef="_4" targetRef="_9"> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${leave.submit==false}]]></conditionExpression> </sequenceFlow> <sequenceFlow id="_14" sourceRef="_5" targetRef="_6"/> <sequenceFlow id="_15" name="n" sourceRef="_6" targetRef="_7"> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${leave.agree1==true}]]></conditionExpression> </sequenceFlow> <sequenceFlow id="_16" sourceRef="_7" targetRef="_8"/> <sequenceFlow id="_17" name="y" sourceRef="_6" targetRef="_3"> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${leave.agree1==false}]]></conditionExpression> </sequenceFlow> <sequenceFlow id="_18" name="n" sourceRef="_8" targetRef="_3"> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${leave.agree2==false}]]></conditionExpression> </sequenceFlow> <sequenceFlow id="_19" name="y" sourceRef="_8" targetRef="_9"> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${leave.agree2==true}]]></conditionExpression> </sequenceFlow> </process> </definitions>
上图对应的Xml:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:tns="http://www.activiti.org/testm1539766523202" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" expressionLanguage="http://www.w3.org/1999/XPath" id="m1539766523202" name="" targetNamespace="http://www.activiti.org/testm1539766523202" typeLanguage="http://www.w3.org/2001/XMLSchema"> <process id="bingxingleveal" isClosed="false" isExecutable="true" processType="None"> <startEvent id="_2" name="StartEvent"/> <userTask activiti:exclusive="true" id="shenqing" name="提交申请"/> <parallelGateway gatewayDirection="Unspecified" id="_4" name="ParallelGateway"/> <userTask activiti:exclusive="true" id="shenpiA" name="审批A"/> <userTask activiti:exclusive="true" id="shenpiB" name="审批B"/> <userTask activiti:exclusive="true" id="shenpiC" name="审批C"/> <exclusiveGateway gatewayDirection="Unspecified" id="_8" name="ExclusiveGateway"/> <parallelGateway gatewayDirection="Unspecified" id="_9" name="ParallelGateway"/> <userTask activiti:exclusive="true" id="_10" name="最终审批"/> <endEvent id="_11" name="EndEvent"/> <sequenceFlow id="_12" sourceRef="_2" targetRef="shenqing"/> <sequenceFlow id="_13" sourceRef="shenqing" targetRef="_4"/> <sequenceFlow id="_14" sourceRef="_4" targetRef="shenpiB"> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${leave.submit==true}]]></conditionExpression> </sequenceFlow> <sequenceFlow id="_15" sourceRef="_4" targetRef="shenpiA"> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${leave.submit==true}]]></conditionExpression> </sequenceFlow> <sequenceFlow id="_16" sourceRef="shenpiB" targetRef="_9"/> <sequenceFlow id="_18" sourceRef="shenpiC" targetRef="_8"/> <sequenceFlow id="_19" name="驳回" sourceRef="_8" targetRef="shenpiA"> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${leave.agree3==false}]]></conditionExpression> </sequenceFlow> <sequenceFlow id="_20" name="同意" sourceRef="_8" targetRef="_9"> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${leave.agree3==true}]]></conditionExpression> </sequenceFlow> <sequenceFlow id="_21" sourceRef="_9" targetRef="_10"/> <sequenceFlow id="_22" sourceRef="_10" targetRef="_11"/> <sequenceFlow id="_3" sourceRef="shenpiA" targetRef="shenpiC"> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${leave.agree1==true}]]></conditionExpression> </sequenceFlow> </process> <bpmndi:BPMNDiagram documentation="background=#3C3F41;count=1;horizontalcount=1;orientation=0;width=842.4;height=1195.2;imageableWidth=832.4;imageableHeight=1185.2;imageableX=5.0;imageableY=5.0" id="Diagram-_1" name="New Diagram"> <bpmndi:BPMNPlane bpmnElement="bingxingleveal"> <bpmndi:BPMNShape bpmnElement="_2" id="Shape-_2"> <dc:Bounds height="32.0" width="32.0" x="10.0" y="190.0"/> <bpmndi:BPMNLabel> <dc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/> </bpmndi:BPMNLabel> </bpmndi:BPMNShape> <bpmndi:BPMNShape bpmnElement="shenqing" id="Shape-shenqing"> <dc:Bounds height="55.0" width="85.0" x="125.0" y="180.0"/> <bpmndi:BPMNLabel> <dc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/> </bpmndi:BPMNLabel> </bpmndi:BPMNShape> <bpmndi:BPMNShape bpmnElement="_4" id="Shape-_4"> <dc:Bounds height="32.0" width="32.0" x="275.0" y="190.0"/> <bpmndi:BPMNLabel> <dc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/> </bpmndi:BPMNLabel> </bpmndi:BPMNShape> <bpmndi:BPMNShape bpmnElement="shenpiA" id="Shape-shenpiA"> <dc:Bounds height="55.0" width="85.0" x="400.0" y="80.0"/> <bpmndi:BPMNLabel> <dc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/> </bpmndi:BPMNLabel> </bpmndi:BPMNShape> <bpmndi:BPMNShape bpmnElement="shenpiB" id="Shape-shenpiB"> <dc:Bounds height="55.0" width="85.0" x="385.0" y="310.0"/> <bpmndi:BPMNLabel> <dc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/> </bpmndi:BPMNLabel> </bpmndi:BPMNShape> <bpmndi:BPMNShape bpmnElement="shenpiC" id="Shape-shenpiC"> <dc:Bounds height="55.0" width="85.0" x="550.0" y="85.0"/> <bpmndi:BPMNLabel> <dc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/> </bpmndi:BPMNLabel> </bpmndi:BPMNShape> <bpmndi:BPMNShape bpmnElement="_8" id="Shape-_8" isMarkerVisible="false"> <dc:Bounds height="32.0" width="32.0" x="735.0" y="110.0"/> <bpmndi:BPMNLabel> <dc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/> </bpmndi:BPMNLabel> </bpmndi:BPMNShape> <bpmndi:BPMNShape bpmnElement="_9" id="Shape-_9"> <dc:Bounds height="32.0" width="32.0" x="745.0" y="205.0"/> <bpmndi:BPMNLabel> <dc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/> </bpmndi:BPMNLabel> </bpmndi:BPMNShape> <bpmndi:BPMNShape bpmnElement="_10" id="Shape-_10"> <dc:Bounds height="55.0" width="85.0" x="900.0" y="210.0"/> <bpmndi:BPMNLabel> <dc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/> </bpmndi:BPMNLabel> </bpmndi:BPMNShape> <bpmndi:BPMNShape bpmnElement="_11" id="Shape-_11"> <dc:Bounds height="32.0" width="32.0" x="1105.0" y="230.0"/> <bpmndi:BPMNLabel> <dc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/> </bpmndi:BPMNLabel> </bpmndi:BPMNShape> <bpmndi:BPMNEdge bpmnElement="_13" id="BPMNEdge__13" sourceElement="shenqing" targetElement="_4"> <di:waypoint x="210.0" y="207.5"/> <di:waypoint x="275.0" y="206.0"/> <bpmndi:BPMNLabel> <dc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/> </bpmndi:BPMNLabel> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge bpmnElement="_12" id="BPMNEdge__12" sourceElement="_2" targetElement="shenqing"> <di:waypoint x="42.0" y="206.0"/> <di:waypoint x="125.0" y="207.5"/> <bpmndi:BPMNLabel> <dc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/> </bpmndi:BPMNLabel> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge bpmnElement="_15" id="BPMNEdge__15" sourceElement="_4" targetElement="_5"> <di:waypoint x="290.0" y="191.0"/> <di:waypoint x="290.0" y="110.0"/> <di:waypoint x="400.0" y="110.0"/> <bpmndi:BPMNLabel> <dc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/> </bpmndi:BPMNLabel> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge bpmnElement="_14" id="BPMNEdge__14" sourceElement="_4" targetElement="_6"> <di:waypoint x="290.0" y="221.0"/> <di:waypoint x="290.0" y="305.0"/> <di:waypoint x="385.0" y="337.5"/> <bpmndi:BPMNLabel> <dc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/> </bpmndi:BPMNLabel> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge bpmnElement="_16" id="BPMNEdge__16" sourceElement="_6" targetElement="_9"> <di:waypoint x="470.0" y="335.0"/> <di:waypoint x="760.0" y="335.0"/> <di:waypoint x="760.0" y="236.0"/> <bpmndi:BPMNLabel> <dc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/> </bpmndi:BPMNLabel> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge bpmnElement="_19" id="BPMNEdge__19" sourceElement="_8" targetElement="_5"> <di:waypoint x="751.0" y="110.0"/> <di:waypoint x="630.0" y="40.0"/> <di:waypoint x="442.5" y="80.0"/> <bpmndi:BPMNLabel> <dc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/> </bpmndi:BPMNLabel> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge bpmnElement="_18" id="BPMNEdge__18" sourceElement="_7" targetElement="_8"> <di:waypoint x="635.0" y="112.5"/> <di:waypoint x="735.0" y="126.0"/> <bpmndi:BPMNLabel> <dc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/> </bpmndi:BPMNLabel> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge bpmnElement="_3" id="BPMNEdge__3" sourceElement="_5" targetElement="_7"> <di:waypoint x="500.0" y="107.5"/> <di:waypoint x="550.0" y="112.5"/> <bpmndi:BPMNLabel> <dc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/> </bpmndi:BPMNLabel> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge bpmnElement="_20" id="BPMNEdge__20" sourceElement="_8" targetElement="_9"> <di:waypoint x="756.0" y="137.0"/> <di:waypoint x="756.0" y="210.0"/> <bpmndi:BPMNLabel> <dc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/> </bpmndi:BPMNLabel> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge bpmnElement="_22" id="BPMNEdge__22" sourceElement="_10" targetElement="_11"> <di:waypoint x="985.0" y="237.5"/> <di:waypoint x="1105.0" y="246.0"/> <bpmndi:BPMNLabel> <dc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/> </bpmndi:BPMNLabel> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge bpmnElement="_21" id="BPMNEdge__21" sourceElement="_9" targetElement="_10"> <di:waypoint x="777.0" y="221.0"/> <di:waypoint x="900.0" y="237.5"/> <bpmndi:BPMNLabel> <dc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/> </bpmndi:BPMNLabel> </bpmndi:BPMNEdge> </bpmndi:BPMNPlane> </bpmndi:BPMNDiagram> </definitions>
图一为排他网关,图二为并行网关。
排他网关部署、启动正常,观察act_ru_task表中数据的assignee有值,通过下面的代码是可以获取到taskid的:
/** * @Method 根据流程实例ID和用户ID查询任务ID * @Author MC 用户ID必须设置为Assignee * @Return * @Date 2019/9/19 0019 19:01 */ public String getTaskId( String processInstanceId, String userId){ TaskService taskService = processEngine.getTaskService();//获取任务的Service,设置和获取流程变量 //查询当前办理人的任务ID Task task = taskService.createTaskQuery() .processInstanceId(processInstanceId)//使用流程实例ID .taskAssignee(userId)//任务办理人 .singleResult(); return task.getId(); }
processInstanceId在启动后是可以获取的,具体可参考我之前的demo博客,而userid就是代码设置的。
好了,接下来操作并行网关。
并行网关部署、启动,正常。但是观察task表的时候神奇的发现assignee没有值,而task_def_key有值,一开始我以为是并行网关的特殊性导致的,修改获取task对象代码为:
Task task = taskService.createTaskQuery() .processInstanceId(processInstanceId)//使用流程实例ID .taskDefinitionKey("shenqing") .singleResult();
上下两个代码块可以发现原来的调用的是taskAssignee,而下面调用的是taskDefinitionKey。虽然下面的并行网关这样也能获取到值但是觉得有问题。
经过xml文件反复对比,发现排他网关比并行网关多了一点东西:
<userTask activiti:assignee="${leave.userId}" activiti:exclusive="true" id="_3" name="submit"/>
可以看出来userTask的属性添加了activiti:assignee,取的是全局变量的值userId。而并行网关没有设置该属性。所以才导致数据库数据与预期不符。
找到了问题就好办了,添加上就好了。
这里注意一下,在使用IDEA插件actBPM的时候,bpmn视图模式下竟然不展示assignee内容,这个是个大坑。后续一定要注意。
继续补充(19-09-24):
全局变量操作,在启动已部署的流程实例时, 可以设置流程变量代码如下:
@RequestMapping(value = "/start") public String start (){ activitiUtil.deploy("processes/bingxing.bpmn"); Map<String,Object> map = new HashMap<>();//流程变量对象 Leave leave = new Leave(); leave.setUserId("shenqing"); map.put("bingxing",leave);//其所存act_ru_variable表name属性值对应其map的Key Map<String, Object> startMap = activitiUtil.start(map, "bingxingleveal"); String processInstanceId = startMap.get("processInstanceId").toString(); return processInstanceId; } activitiUtil:/** * @Method 启动流程 * @Author MC * @Return * @Date 2019/9/19 0019 18:35 */ public Map<String,Object> start(Map<String,Object> map ,String processId){ ProcessInstance leave1 = runtimeService.startProcessInstanceByKey(processId, map); String processDefinitionId = leave1.getProcessDefinitionId(); System.out.print("============processDefinitionId:" + processDefinitionId);//流程定义的ID System.out.print("============processInstanceId:" + leave1.getId());//流程实例的ID Map<String, Object> resultMap = new HashMap<>(); resultMap.put("result",leave1); resultMap.put("processDefinitionId",processDefinitionId); resultMap.put("processInstanceId",leave1.getId()); return resultMap; }
后续需要注意的一点是,获取流程变量必须要跟map中key的值一样,否则获取将异常,例如在bpmn文件中连线的限制条件获取的就是全局变量中的值,如图:
请务必小心。