flowable6.3教程-官方流程案例

案例

为了便于快速入门,这里定义一个非常简单的 请假流程。

流程图

官方图如下:

翻译成下图:

解释:

  • 左侧的 圆圈 是 启动事件(start event)。这是一个流程实例的 起点。

  • 第一个 矩形 是一个 用户任务(user task)。这是流程中人类用户操作的步骤。在这个例子中,经理需要批准或驳回申请。

  • 带叉的菱形 是 排他网关(exclusive gateway) ,会将流程实例路由至批准或驳回路径。

  • 如果同意,就调用某个外部系统api(如:在oa系统请假通过后,调用erp系统api,这样erp系统可以进行排班等)。并将经理的结果通知给申请人

  • 如果驳回,则给员工发送一封邮件

如何设置流程的第一步?

一般启动流程时,都需要提交信息,如:员工名字、请假时长以及说明。那么 提交信息,可以作为流程中的 第一步 吗?

如果 提交信息 作为第一步,输入信息并提交,就 创建流程实例,当用户改变主意时(如:由于是第一步,用户很有可能填写错误,要重新填写),此时就要 取消流程,在某些场景中,可能影响重要的指标,如:统计启动了多少申请,但还未完成

所以,为了灵活,提交信息 不算工作流程的第一步。

注意:是否作为第一步,完全具体情况具体分析

流程定义文件

提示:该流程定义文件是对 官网流程翻译的(下面是官方流程定义文件)

在 resources 文件夹下,创建 请假审批流程5.bpmn20.xml 文件,内容如下:

<?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">
  <process id="holidayRequest" name="请假审批流程5" isExecutable="true">
    <startEvent id="startEvent"></startEvent>
    <sequenceFlow id="sequenceFlow-d8a55f73-e820-42f1-8a92-6b7d5033caf5" sourceRef="startEvent" targetRef="approveTask"></sequenceFlow>
    <userTask id="approveTask" name="部门经理审批" flowable:candidateGroups="managers"></userTask>
    <sequenceFlow id="sequenceFlow-ed5282cc-ec2e-48b8-a47c-6015c8b36125" sourceRef="approveTask" targetRef="decision"></sequenceFlow>
    <exclusiveGateway id="decision"></exclusiveGateway>
    <serviceTask id="externalSystemCall" name="调用外部系统发送假期" flowable:class="org.flowable.CallExternalSystemDelegate"></serviceTask>
    <sequenceFlow id="sequenceFlow-6c7b7298-5703-4100-8573-c57d0d5d4462" sourceRef="externalSystemCall" targetRef="holidayApprovedTask"></sequenceFlow>
    <userTask id="holidayApprovedTask" name="通知申请人" flowable:assignee="${emp}">
      <extensionElements>
        <modeler:initiator-can-complete xmlns:modeler="http://flowable.org/modeler"><![CDATA[false]]></modeler:initiator-can-complete>
      </extensionElements>
    </userTask>
    <sequenceFlow id="sequenceFlow-87a050e4-1f38-4a0a-b4c2-ae70de12889e" sourceRef="holidayApprovedTask" targetRef="approveEnd"></sequenceFlow>
    <serviceTask id="sendRejectionMail" name="发送拒绝邮件" flowable:class="org.flowable.SendRejectionMail"></serviceTask>
    <sequenceFlow id="sequenceFlow-add4cbf3-6b44-4b42-8f3a-d223882105ec" sourceRef="sendRejectionMail" targetRef="rejectEnd"></sequenceFlow>
    <endEvent id="approveEnd"></endEvent>
    <endEvent id="rejectEnd"></endEvent>
    <sequenceFlow id="sequenceFlow-8fcee143-f1e5-4f3e-9eba-593840c30c6f" name="拒绝" sourceRef="decision" targetRef="sendRejectionMail">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${!approved}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="sequenceFlow-50ace6b5-ce3f-4398-8037-700d738937a5" name="同意" sourceRef="decision" targetRef="externalSystemCall">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${approved}]]></conditionExpression>
    </sequenceFlow>
  </process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_holidayRequest">
    <bpmndi:BPMNPlane bpmnElement="holidayRequest" id="BPMNPlane_holidayRequest">
      <bpmndi:BPMNShape bpmnElement="startEvent" id="BPMNShape_startEvent">
        <omgdc:Bounds height="30.0" width="30.0" x="100.0" y="155.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="approveTask" id="BPMNShape_approveTask">
        <omgdc:Bounds height="60.0" width="100.0" x="180.0" y="140.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="decision" id="BPMNShape_decision">
        <omgdc:Bounds height="40.0" width="40.0" x="330.0" y="150.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="externalSystemCall" id="BPMNShape_externalSystemCall">
        <omgdc:Bounds height="60.0" width="100.0" x="449.9999932944776" y="139.99999791383746"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="holidayApprovedTask" id="BPMNShape_holidayApprovedTask">
        <omgdc:Bounds height="60.00000000000003" width="100.0" x="629.9999906122686" y="139.99999791383746"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="sendRejectionMail" id="BPMNShape_sendRejectionMail">
        <omgdc:Bounds height="60.0" width="100.0" x="449.9999865889554" y="284.9999825358397"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="approveEnd" id="BPMNShape_approveEnd">
        <omgdc:Bounds height="28.0" width="28.0" x="794.9999881535771" y="155.99999767541888"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="rejectEnd" id="BPMNShape_rejectEnd">
        <omgdc:Bounds height="28.0" width="28.0" x="644.9999903887511" y="300.9999780505905"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="sequenceFlow-87a050e4-1f38-4a0a-b4c2-ae70de12889e" id="BPMNEdge_sequenceFlow-87a050e4-1f38-4a0a-b4c2-ae70de12889e">
        <omgdi:waypoint x="729.9499829189559" y="169.99999782142714"></omgdi:waypoint>
        <omgdi:waypoint x="794.9999834136223" y="169.99999770120135"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="sequenceFlow-6c7b7298-5703-4100-8573-c57d0d5d4462" id="BPMNEdge_sequenceFlow-6c7b7298-5703-4100-8573-c57d0d5d4462">
        <omgdi:waypoint x="549.949993294448" y="169.99999791383746"></omgdi:waypoint>
        <omgdi:waypoint x="629.9999906122686" y="169.9999979138375"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="sequenceFlow-8fcee143-f1e5-4f3e-9eba-593840c30c6f" id="BPMNEdge_sequenceFlow-8fcee143-f1e5-4f3e-9eba-593840c30c6f">
        <omgdi:waypoint x="350.0" y="189.94312542991003"></omgdi:waypoint>
        <omgdi:waypoint x="350.0" y="314.99998253583976"></omgdi:waypoint>
        <omgdi:waypoint x="449.9999865889554" y="314.99998253583976"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="sequenceFlow-d8a55f73-e820-42f1-8a92-6b7d5033caf5" id="BPMNEdge_sequenceFlow-d8a55f73-e820-42f1-8a92-6b7d5033caf5">
        <omgdi:waypoint x="129.9499986183554" y="170.0"></omgdi:waypoint>
        <omgdi:waypoint x="180.0" y="170.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="sequenceFlow-50ace6b5-ce3f-4398-8037-700d738937a5" id="BPMNEdge_sequenceFlow-50ace6b5-ce3f-4398-8037-700d738937a5">
        <omgdi:waypoint x="369.94335470726526" y="169.99999972184497"></omgdi:waypoint>
        <omgdi:waypoint x="449.9999932944776" y="169.9999986085296"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="sequenceFlow-add4cbf3-6b44-4b42-8f3a-d223882105ec" id="BPMNEdge_sequenceFlow-add4cbf3-6b44-4b42-8f3a-d223882105ec">
        <omgdi:waypoint x="549.9499865889554" y="314.99998112538395"></omgdi:waypoint>
        <omgdi:waypoint x="644.9999896993223" y="314.9999784441077"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="sequenceFlow-ed5282cc-ec2e-48b8-a47c-6015c8b36125" id="BPMNEdge_sequenceFlow-ed5282cc-ec2e-48b8-a47c-6015c8b36125">
        <omgdi:waypoint x="279.95000000000005" y="170.0"></omgdi:waypoint>
        <omgdi:waypoint x="330.0" y="170.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>

解释:

  • 每一个步骤(在BPMN 2.0术语中称作活动(activity))都有一个id属性,为其提供一个在XML文件中唯一的标识符。所有的活动都可以设置一个名字,以提高流程图的可读性。

  • 活动之间通过顺序流(sequence flow)连接,在流程图中是一个有向箭头。在执行流程实例时,执行(execution)会从启动事件沿着顺序流流向下一个活动。

  • 离开排他网关(带有X的菱形)的顺序流很特别:都以表达式(expression)的形式定义了条件(condition) (见第25至32行)。当流程实例的执行到达这个网关时,会计算条件,并使用第一个计算为true的顺序流。这就是排他的含义:只选择一个。当然如果需要不同的路由策略,可以使用其他类型的网关。

  • 这里用作条件的表达式为${approved},这是${approved == true}的简写。变量’approved’被称作流程变量(process variable)。流程变量是持久化的数据,与流程实例存储在一起,并可以在流程实例的生命周期中使用。在这个例子里,我们需要在特定的地方(当经理用户任务提交时,或者以Flowable的术语来说,完成(complete)时)设置这个流程变量,因为这不是流程实例启动时就能获取的数据。

官方流程定义文件

提示:下面是官方流程定义文件,一般情况用上面翻译的就行

在 resources 文件夹下,创建 holiday-request.bpmn20.xml 文件,内容如下:

<?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: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"
  xmlns:flowable="http://flowable.org/bpmn"
  typeLanguage="http://www.w3.org/2001/XMLSchema"
  expressionLanguage="http://www.w3.org/1999/XPath"
  targetNamespace="http://www.flowable.org/processdef">

  <process id="holidayRequest" name="Holiday Request" isExecutable="true">

    <startEvent id="startEvent"/>
    <sequenceFlow sourceRef="startEvent" targetRef="approveTask"/>

    <userTask id="approveTask" name="Approve or reject request"/>
    <sequenceFlow sourceRef="approveTask" targetRef="decision"/>

    <exclusiveGateway id="decision"/>
    <sequenceFlow sourceRef="decision" targetRef="externalSystemCall">
      <conditionExpression xsi:type="tFormalExpression">
        <![CDATA[
          ${approved}
        ]]>
      </conditionExpression>
    </sequenceFlow>
    <sequenceFlow  sourceRef="decision" targetRef="sendRejectionMail">
      <conditionExpression xsi:type="tFormalExpression">
        <![CDATA[
          ${!approved}
        ]]>
      </conditionExpression>
    </sequenceFlow>

    <serviceTask id="externalSystemCall" name="Enter holidays in external system"
        flowable:class="org.flowable.CallExternalSystemDelegate"/>
    <sequenceFlow sourceRef="externalSystemCall" targetRef="holidayApprovedTask"/>

    <userTask id="holidayApprovedTask" name="Holiday approved"/>
    <sequenceFlow sourceRef="holidayApprovedTask" targetRef="approveEnd"/>

    <serviceTask id="sendRejectionMail" name="Send out rejection email"
        flowable:class="org.flowable.SendRejectionMail"/>
    <sequenceFlow sourceRef="sendRejectionMail" targetRef="rejectEnd"/>

    <endEvent id="approveEnd"/>

    <endEvent id="rejectEnd"/>

  </process>

</definitions>

原文出处:/show_1IX5bGPghDn4.html