美文网首页
ServiceTask自定义属性

ServiceTask自定义属性

作者: 西城丶 | 来源:发表于2021-05-11 14:33 被阅读0次

背景

现在需要有一个节点,需要在流程到达这个节点的时候,需要将当前流程表单的一些参数作为参数调用外部的http地址,如果这个地址返回了成功,那么这个节点就继续往下走。

分析

按照上面的需求,我们需要做的主要是以下功能

  • 入参,勾选表单的参数
  • 调用地址
  • 调用方式(GET\POST)
  • 返回值判断(外部接口按照我们的定义统一返回就行)
  • 异常处理
    • 邮件
    • 企业微信告警

实现

前端部分

用的是bpmn.js的插件,需要自定义属性,最终展示效果为:


流程编辑页

设置完右侧的属性之后,我们这个节点的属性就设置完毕了。

最终提交的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:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
    xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC"
    xmlns:di="http://www.omg.org/spec/DD/20100524/DI"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:activiti="http://activiti.org/bpmn" id="m1577635100724" name="" targetNamespace="http://www.activiti.org/testm1577635100724">
    <process id="process1620637878536" processType="None" isClosed="false" isExecutable="true">
        <extensionElements>
            <activiti:properties>
                <activiti:property name="a" value="1" />
            </activiti:properties>
        </extensionElements>
        <startEvent id="_2" name="开始">
            <outgoing>Flow_0ca559g</outgoing>
        </startEvent>
        <sequenceFlow id="Flow_0ca559g" sourceRef="_2" targetRef="submitTask" />
        <userTask id="submitTask" name="提交节点" activiti:assignType="variable" activiti:assignValue="submitUser">
            <incoming>Flow_0ca559g</incoming>
            <outgoing>Flow_0a6iosp</outgoing>
        </userTask>
        <sequenceFlow id="Flow_0a6iosp" sourceRef="submitTask" targetRef="Activity_03v64y1" />
        <serviceTask id="Activity_03v64y1" name="自动化呀" activiti:class="com.*.interceptor.listener.ServiceTaskAuto" activiti:action="POST" activiti:url="http://test.com" activiti:forms="input_1619676303000_42933,input_1619676304000_57954,date_1619676335000_46739" activiti:abnormalWarning="email" activiti:email="chenquanwei@keytop.com.cn" activiti:wxwork="">
            <incoming>Flow_0a6iosp</incoming>
            <outgoing>Flow_01wlhjl</outgoing>
        </serviceTask>
        <exclusiveGateway id="Gateway_19nsa55">
            <incoming>Flow_01wlhjl</incoming>
            <outgoing>Flow_021bick</outgoing>
            <outgoing>Flow_1rt8i2h</outgoing>
        </exclusiveGateway>
        <sequenceFlow id="Flow_01wlhjl" sourceRef="Activity_03v64y1" targetRef="Gateway_19nsa55" />
        <sequenceFlow id="Flow_021bick" name="成功" sourceRef="Gateway_19nsa55" targetRef="Activity_1c2dbe5" activiti:condition="${approvalAuto==true}" />
        <sequenceFlow id="Flow_1rt8i2h" name="失败" sourceRef="Gateway_19nsa55" targetRef="Activity_1qq721y" activiti:condition="${approvalAuto==false}" />
        <userTask id="Activity_1c2dbe5" name="自动化成" activiti:assignType="role" activiti:assignValue="1">
            <incoming>Flow_021bick</incoming>
            <outgoing>Flow_1xurbpo</outgoing>
        </userTask>
        <userTask id="Activity_1qq721y" name="自动化败" activiti:assignType="person" activiti:assignValue="2,1">
            <incoming>Flow_1rt8i2h</incoming>
            <outgoing>Flow_162pjte</outgoing>
        </userTask>
        <sequenceFlow id="Flow_162pjte" sourceRef="Activity_1qq721y" targetRef="Event_151mw34" />
        <sequenceFlow id="Flow_1xurbpo" sourceRef="Activity_1c2dbe5" targetRef="Event_151mw34" />
        <endEvent id="Event_151mw34">
            <incoming>Flow_162pjte</incoming>
            <incoming>Flow_1xurbpo</incoming>
        </endEvent>
    </process>
    <bpmndi:BPMNDiagram id="BPMNDiagram_leave">
        <bpmndi:BPMNPlane id="BPMNPlane_leave" bpmnElement="process1620637878536">
            <bpmndi:BPMNEdge id="Flow_0ca559g_di" bpmnElement="Flow_0ca559g">
                <di:waypoint x="176" y="384" />
                <di:waypoint x="230" y="384" />
            </bpmndi:BPMNEdge>
            <bpmndi:BPMNEdge id="Flow_0a6iosp_di" bpmnElement="Flow_0a6iosp">
                <di:waypoint x="330" y="384" />
                <di:waypoint x="390" y="384" />
            </bpmndi:BPMNEdge>
            <bpmndi:BPMNEdge id="Flow_01wlhjl_di" bpmnElement="Flow_01wlhjl">
                <di:waypoint x="490" y="384" />
                <di:waypoint x="555" y="384" />
            </bpmndi:BPMNEdge>
            <bpmndi:BPMNEdge id="Flow_021bick_di" bpmnElement="Flow_021bick">
                <di:waypoint x="580" y="359" />
                <di:waypoint x="580" y="290" />
                <di:waypoint x="670" y="290" />
                <bpmndi:BPMNLabel>
                    <omgdc:Bounds x="585" y="322" width="21" height="14" />
                </bpmndi:BPMNLabel>
            </bpmndi:BPMNEdge>
            <bpmndi:BPMNEdge id="Flow_1rt8i2h_di" bpmnElement="Flow_1rt8i2h">
                <di:waypoint x="580" y="409" />
                <di:waypoint x="580" y="500" />
                <di:waypoint x="670" y="500" />
                <bpmndi:BPMNLabel>
                    <omgdc:Bounds x="584" y="452" width="22" height="14" />
                </bpmndi:BPMNLabel>
            </bpmndi:BPMNEdge>
            <bpmndi:BPMNEdge id="Flow_162pjte_di" bpmnElement="Flow_162pjte">
                <di:waypoint x="770" y="500" />
                <di:waypoint x="816" y="500" />
                <di:waypoint x="816" y="400" />
                <di:waypoint x="862" y="400" />
            </bpmndi:BPMNEdge>
            <bpmndi:BPMNEdge id="Flow_1xurbpo_di" bpmnElement="Flow_1xurbpo">
                <di:waypoint x="770" y="290" />
                <di:waypoint x="816" y="290" />
                <di:waypoint x="816" y="400" />
                <di:waypoint x="862" y="400" />
            </bpmndi:BPMNEdge>
            <bpmndi:BPMNShape id="BPMNShape__2" bpmnElement="_2">
                <omgdc:Bounds x="144" y="368" width="32" height="32" />
                <bpmndi:BPMNLabel>
                    <omgdc:Bounds x="149" y="400" width="23" height="14" />
                </bpmndi:BPMNLabel>
            </bpmndi:BPMNShape>
            <bpmndi:BPMNShape id="Activity_1pxs7ok_di" bpmnElement="submitTask">
                <omgdc:Bounds x="230" y="344" width="100" height="80" />
            </bpmndi:BPMNShape>
            <bpmndi:BPMNShape id="Activity_1ipcnqz_di" bpmnElement="Activity_03v64y1">
                <omgdc:Bounds x="390" y="344" width="100" height="80" />
            </bpmndi:BPMNShape>
            <bpmndi:BPMNShape id="Gateway_19nsa55_di" bpmnElement="Gateway_19nsa55" isMarkerVisible="true">
                <omgdc:Bounds x="555" y="359" width="50" height="50" />
            </bpmndi:BPMNShape>
            <bpmndi:BPMNShape id="Activity_12asdev_di" bpmnElement="Activity_1c2dbe5">
                <omgdc:Bounds x="670" y="250" width="100" height="80" />
            </bpmndi:BPMNShape>
            <bpmndi:BPMNShape id="Activity_0tlrnwu_di" bpmnElement="Activity_1qq721y">
                <omgdc:Bounds x="670" y="460" width="100" height="80" />
            </bpmndi:BPMNShape>
            <bpmndi:BPMNShape id="Event_0oq8k35_di" bpmnElement="Event_151mw34">
                <omgdc:Bounds x="862" y="382" width="36" height="36" />
            </bpmndi:BPMNShape>
        </bpmndi:BPMNPlane>
    </bpmndi:BPMNDiagram>
</definitions>

后端部分

因为都是自定义属性,所以我们需要写一个转化类的代码

部署转化类代码:

public class CustomServiceTaskXMLConverter extends ServiceTaskXMLConverter {

   @Override
   protected BaseElement convertXMLToElement(XMLStreamReader xtr, BpmnModel model) throws Exception {
      ServiceTask serviceTask = new ServiceTask();
      // 省略一些代码
      // 设置自定义属性到customProperties
      List<CustomProperty> customProperties = new ArrayList<>();
      ActivitiConstants.SERVICE_TASK_ATTRS[] values = ActivitiConstants.SERVICE_TASK_ATTRS.values();
      for ( ActivitiConstants.SERVICE_TASK_ATTRS serviceTaskAttrs : values ) {
        String attributeValue = xtr.getAttributeValue(null, serviceTaskAttrs.getAttrName());
        if (StringUtils.isNotEmpty(attributeValue)) {
            CustomProperty customProperty = new CustomProperty();
            customProperty.setId(serviceTaskAttrs.getAttrName());
            customProperty.setName(serviceTaskAttrs.getAttrName());
            customProperty.setSimpleValue(attributeValue);
            customProperties.add(customProperty);
        }
      }
      serviceTask.setCustomProperties(customProperties);
      // 省略一些代码
      return serviceTask;
   }

}

部署转化bpmn的时候需要添加自定义的转化类BpmnXMLConverter.addConverter(new CustomServiceTaskXMLConverter());

监听类:

public class ServiceTaskAuto implements JavaDelegate {
   /**
   * 这里是每个自定义属性的字段名
   */
   private FixedValue action;

   @Override
   public void execute(DelegateExecution execution) {
     // 根据业务完成自己的校验动作
     // 如果成功,设置流程属性,失败的话,设置失败的属性,让流程走向失败的节点
   }
}

提交流程到了这个节点可以看到获取到的参数为:


流程执行参数

问题

  • com...interceptor.listener.ServiceTaskAuto org.activiti.engine.ActivitiIllegalArgumentException: Field definition uses unexisting field 'action' on class com...interceptor.listener.ServiceTaskAuto

    这个是因为在监听器里接收的方式不对,我们的自定义属性都需要通过FixedValue来接收,并且我们设置的所有属性值,都必须在这边有接收的属性,一开始是采用下面的方式接收的,就会报这个错。

    private Expression attrs;
    
    @Override
    public void execute(DelegateExecution execution) {
        
    }
    

未竟之事

  • http当成一个策略,不止http调用外部,可以是mq发送
  • 节点的校验,做的比较粗糙,还没有对一些属性进行校验
  • 重试?接口调用在实现类重试还是serviceTask的重试

相关文章

网友评论

      本文标题:ServiceTask自定义属性

      本文链接:https://www.haomeiwen.com/subject/dpngdltx.html