flowable 特殊多实例并行例子解决方案

场景描述:

由于公司需要在流程图中明确的显示不同部门的流程情况,而这些部门是并行的,最后要有系统自动判断这些节点的审核结果给出一个最终的结果,来确定流程的走向,如果是单个审核节点的话可以使用多实例(设置多实例结束条件即可),但是通常业务中包含着不止一个节点,这种情况我们可以使用子流程解决,也可以使用下边我要介绍的方案,这个方案我只画了每个并行节点的一个审核,但是实际通常会有多个,我只做例子讲解,就不画多个了。

注意:如果大家有更好的解决,请大家在下方留言,谢谢。(还有一种简单的解决方案是设置任务过期时间)

  • 流程图如下

  • 流程图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="audit-article" name="文章审核" isExecutable="true">
        <documentation>测试流程</documentation>
        <startEvent id="start" name="开始"></startEvent>
        <userTask id="group_leader_approve" name="组长审核" flowable:candidateGroups="role_group_leader"></userTask>
        <sequenceFlow id="sid-F0149E5B-E9A1-49C9-A243-638C4E21E378" sourceRef="start" targetRef="group_leader_approve"></sequenceFlow>
        <parallelGateway id="sid-6E2896F8-BF54-4F7B-BF14-DF9C850E7BDE"></parallelGateway>
        <userTask id="editor1_approval" name="主编1审核" flowable:assignee="${group_editor1}">
          <extensionElements>
            <modeler:initiator-can-complete xmlns:modeler="http://flowable.org/modeler"><![CDATA[false]]></modeler:initiator-can-complete>
          </extensionElements>
        </userTask>
        <userTask id="editor2_approval" name="主编2审核" flowable:assignee="${group_editor2}">
          <extensionElements>
            <modeler:initiator-can-complete xmlns:modeler="http://flowable.org/modeler"><![CDATA[false]]></modeler:initiator-can-complete>
          </extensionElements>
        </userTask>
        <parallelGateway id="sid-56FAADCB-CE8E-4F10-834C-EB29D9A30F72"></parallelGateway>
        <userTask id="system_judge" name="系统判断" flowable:assignee="system_judge">
          <extensionElements>
            <flowable:taskListener event="create" class="com.spark.platform.flowable.biz.listener.MyTaskListener"></flowable:taskListener>
            <modeler:initiator-can-complete xmlns:modeler="http://flowable.org/modeler"><![CDATA[false]]></modeler:initiator-can-complete>
          </extensionElements>
        </userTask>
        <exclusiveGateway id="sid-AC406909-E994-4CD0-9AEC-901ABB27688E"></exclusiveGateway>
        <userTask id="submit_approval" name="退回修改" flowable:assignee="${submitter}">
          <extensionElements>
            <modeler:initiator-can-complete xmlns:modeler="http://flowable.org/modeler"><![CDATA[false]]></modeler:initiator-can-complete>
          </extensionElements>
        </userTask>
        <endEvent id="pass" name="通过"></endEvent>
        <exclusiveGateway id="sid-E2A8AD68-FA23-4D9B-8CA4-863CA08E483A"></exclusiveGateway>
        <exclusiveGateway id="sid-A9213851-D3FA-450B-8A9D-FCD4C54F2440"></exclusiveGateway>
        <endEvent id="over" name="关闭流程"></endEvent>
        <sequenceFlow id="sid-89703E3C-E4C1-4DBF-9462-2DAE98EF4D55" sourceRef="editor1_approval" targetRef="sid-56FAADCB-CE8E-4F10-834C-EB29D9A30F72"></sequenceFlow>
        <sequenceFlow id="sid-C91352A8-84D9-474E-89A5-0AF0EFC5F58B" sourceRef="editor2_approval" targetRef="sid-56FAADCB-CE8E-4F10-834C-EB29D9A30F72"></sequenceFlow>
        <sequenceFlow id="sid-FF7E4059-6000-4335-8F8E-AC2295A8DB5B" sourceRef="sid-56FAADCB-CE8E-4F10-834C-EB29D9A30F72" targetRef="system_judge"></sequenceFlow>
        <sequenceFlow id="sid-71206A86-A1DC-42CE-92FF-179507B2AC04" sourceRef="submit_approval" targetRef="sid-A9213851-D3FA-450B-8A9D-FCD4C54F2440"></sequenceFlow>
        <sequenceFlow id="sid-606C543E-F974-42F7-8BBE-86E19E6A40FC" sourceRef="group_leader_approve" targetRef="sid-E2A8AD68-FA23-4D9B-8CA4-863CA08E483A"></sequenceFlow>
        <sequenceFlow id="sid-8882D268-789B-4A66-99A8-513C8F19E21C" sourceRef="sid-A9213851-D3FA-450B-8A9D-FCD4C54F2440" targetRef="group_leader_approve">
          <conditionExpression xsi:type="tFormalExpression"><![CDATA[${SUBMIT_APPROVAL_SUBMIT_VALUE == 'GROUP_LEADER_APPROVAL'}]]></conditionExpression>
        </sequenceFlow>
        <sequenceFlow id="sid-32CBC3C6-757D-41CC-AC34-3CC7E71C226A" sourceRef="sid-6E2896F8-BF54-4F7B-BF14-DF9C850E7BDE" targetRef="editor1_approval"></sequenceFlow>
        <sequenceFlow id="sid-9D742EBD-78A0-4CBE-884C-BBE85340FC5A" sourceRef="sid-6E2896F8-BF54-4F7B-BF14-DF9C850E7BDE" targetRef="editor2_approval"></sequenceFlow>
        <sequenceFlow id="sid-C39C6BE4-57FF-4153-8C1E-1D97D37146DE" sourceRef="sid-A9213851-D3FA-450B-8A9D-FCD4C54F2440" targetRef="over">
          <conditionExpression xsi:type="tFormalExpression"><![CDATA[${SUBMIT_APPROVAL_SUBMIT_VALUE == 'OVER'}]]></conditionExpression>
        </sequenceFlow>
        <sequenceFlow id="sid-E2AE9738-1E1E-4C66-853C-8E8E50E7D5BD" name="退回修改" sourceRef="sid-E2A8AD68-FA23-4D9B-8CA4-863CA08E483A" targetRef="submit_approval">
          <conditionExpression xsi:type="tFormalExpression"><![CDATA[${GROUP_LEADER_APPROVE_SUBMIT_VALUE=='SUBMIT_APPROVAL'}]]></conditionExpression>
        </sequenceFlow>
        <sequenceFlow id="sid-97861805-692B-48CA-BBC8-C3BCF604E7AB" name="通过" sourceRef="sid-E2A8AD68-FA23-4D9B-8CA4-863CA08E483A" targetRef="sid-6E2896F8-BF54-4F7B-BF14-DF9C850E7BDE">
          <conditionExpression xsi:type="tFormalExpression"><![CDATA[${GROUP_LEADER_APPROVE_SUBMIT_VALUE=='GROUP_EDITOR'}]]></conditionExpression>
        </sequenceFlow>
        <sequenceFlow id="sid-88320958-56A0-458B-A8DC-D6EB60D548BA" sourceRef="system_judge" targetRef="sid-AC406909-E994-4CD0-9AEC-901ABB27688E"></sequenceFlow>
        <sequenceFlow id="sid-7492310C-5318-4379-8DEB-53D6CA7E6AD9" name="退回修改" sourceRef="sid-AC406909-E994-4CD0-9AEC-901ABB27688E" targetRef="submit_approval">
          <conditionExpression xsi:type="tFormalExpression"><![CDATA[${SYSTEM_JUDGE_SUBMIT_VALUE == 'SUBMIT_APPROVAL'}]]></conditionExpression>
        </sequenceFlow>
        <sequenceFlow id="sid-38F4E395-FC66-4BA5-B5E5-FB4C217FF3DC" sourceRef="sid-AC406909-E994-4CD0-9AEC-901ABB27688E" targetRef="pass">
          <conditionExpression xsi:type="tFormalExpression"><![CDATA[${SYSTEM_JUDGE_SUBMIT_VALUE == 'PASS'}]]></conditionExpression>
        </sequenceFlow>
      </process>
      <bpmndi:BPMNDiagram id="BPMNDiagram_audit-article">
        <bpmndi:BPMNPlane bpmnElement="audit-article" id="BPMNPlane_audit-article">
          <bpmndi:BPMNShape bpmnElement="start" id="BPMNShape_start">
            <omgdc:Bounds height="30.0" width="30.0" x="10.0" y="150.0"></omgdc:Bounds>
          </bpmndi:BPMNShape>
          <bpmndi:BPMNShape bpmnElement="group_leader_approve" id="BPMNShape_group_leader_approve">
            <omgdc:Bounds height="80.0" width="100.0" x="105.0" y="125.0"></omgdc:Bounds>
          </bpmndi:BPMNShape>
          <bpmndi:BPMNShape bpmnElement="sid-6E2896F8-BF54-4F7B-BF14-DF9C850E7BDE" id="BPMNShape_sid-6E2896F8-BF54-4F7B-BF14-DF9C850E7BDE">
            <omgdc:Bounds height="40.0" width="40.0" x="370.0" y="145.0"></omgdc:Bounds>
          </bpmndi:BPMNShape>
          <bpmndi:BPMNShape bpmnElement="editor1_approval" id="BPMNShape_editor1_approval">
            <omgdc:Bounds height="80.0" width="100.0" x="460.0" y="45.0"></omgdc:Bounds>
          </bpmndi:BPMNShape>
          <bpmndi:BPMNShape bpmnElement="editor2_approval" id="BPMNShape_editor2_approval">
            <omgdc:Bounds height="80.0" width="100.0" x="460.0" y="180.0"></omgdc:Bounds>
          </bpmndi:BPMNShape>
          <bpmndi:BPMNShape bpmnElement="sid-56FAADCB-CE8E-4F10-834C-EB29D9A30F72" id="BPMNShape_sid-56FAADCB-CE8E-4F10-834C-EB29D9A30F72">
            <omgdc:Bounds height="40.0" width="40.0" x="593.5" y="145.0"></omgdc:Bounds>
          </bpmndi:BPMNShape>
          <bpmndi:BPMNShape bpmnElement="system_judge" id="BPMNShape_system_judge">
            <omgdc:Bounds height="80.0" width="100.0" x="678.5" y="125.0"></omgdc:Bounds>
          </bpmndi:BPMNShape>
          <bpmndi:BPMNShape bpmnElement="sid-AC406909-E994-4CD0-9AEC-901ABB27688E" id="BPMNShape_sid-AC406909-E994-4CD0-9AEC-901ABB27688E">
            <omgdc:Bounds height="40.0" width="40.0" x="823.5" y="145.0"></omgdc:Bounds>
          </bpmndi:BPMNShape>
          <bpmndi:BPMNShape bpmnElement="submit_approval" id="BPMNShape_submit_approval">
            <omgdc:Bounds height="80.0" width="100.0" x="222.5" y="270.0"></omgdc:Bounds>
          </bpmndi:BPMNShape>
          <bpmndi:BPMNShape bpmnElement="pass" id="BPMNShape_pass">
            <omgdc:Bounds height="28.0" width="28.0" x="908.5" y="151.0"></omgdc:Bounds>
          </bpmndi:BPMNShape>
          <bpmndi:BPMNShape bpmnElement="sid-E2A8AD68-FA23-4D9B-8CA4-863CA08E483A" id="BPMNShape_sid-E2A8AD68-FA23-4D9B-8CA4-863CA08E483A">
            <omgdc:Bounds height="40.0" width="40.0" x="255.0" y="145.0"></omgdc:Bounds>
          </bpmndi:BPMNShape>
          <bpmndi:BPMNShape bpmnElement="sid-A9213851-D3FA-450B-8A9D-FCD4C54F2440" id="BPMNShape_sid-A9213851-D3FA-450B-8A9D-FCD4C54F2440">
            <omgdc:Bounds height="40.0" width="40.0" x="135.0" y="290.0"></omgdc:Bounds>
          </bpmndi:BPMNShape>
          <bpmndi:BPMNShape bpmnElement="over" id="BPMNShape_over">
            <omgdc:Bounds height="28.0" width="28.0" x="141.0" y="390.0"></omgdc:Bounds>
          </bpmndi:BPMNShape>
          <bpmndi:BPMNEdge bpmnElement="sid-9D742EBD-78A0-4CBE-884C-BBE85340FC5A" id="BPMNEdge_sid-9D742EBD-78A0-4CBE-884C-BBE85340FC5A">
            <omgdi:waypoint x="390.5" y="184.43264652014656"></omgdi:waypoint>
            <omgdi:waypoint x="390.5" y="220.0"></omgdi:waypoint>
            <omgdi:waypoint x="460.0" y="220.0"></omgdi:waypoint>
          </bpmndi:BPMNEdge>
          <bpmndi:BPMNEdge bpmnElement="sid-E2AE9738-1E1E-4C66-853C-8E8E50E7D5BD" id="BPMNEdge_sid-E2AE9738-1E1E-4C66-853C-8E8E50E7D5BD">
            <omgdi:waypoint x="274.66101694915255" y="184.6118644067797"></omgdi:waypoint>
            <omgdi:waypoint x="273.1887931034483" y="270.0"></omgdi:waypoint>
          </bpmndi:BPMNEdge>
          <bpmndi:BPMNEdge bpmnElement="sid-32CBC3C6-757D-41CC-AC34-3CC7E71C226A" id="BPMNEdge_sid-32CBC3C6-757D-41CC-AC34-3CC7E71C226A">
            <omgdi:waypoint x="390.5" y="145.5"></omgdi:waypoint>
            <omgdi:waypoint x="390.5" y="85.0"></omgdi:waypoint>
            <omgdi:waypoint x="460.0" y="85.0"></omgdi:waypoint>
          </bpmndi:BPMNEdge>
          <bpmndi:BPMNEdge bpmnElement="sid-88320958-56A0-458B-A8DC-D6EB60D548BA" id="BPMNEdge_sid-88320958-56A0-458B-A8DC-D6EB60D548BA">
            <omgdi:waypoint x="778.4499999999999" y="165.0"></omgdi:waypoint>
            <omgdi:waypoint x="823.5" y="165.0"></omgdi:waypoint>
          </bpmndi:BPMNEdge>
          <bpmndi:BPMNEdge bpmnElement="sid-38F4E395-FC66-4BA5-B5E5-FB4C217FF3DC" id="BPMNEdge_sid-38F4E395-FC66-4BA5-B5E5-FB4C217FF3DC">
            <omgdi:waypoint x="863.4373893805309" y="165.0"></omgdi:waypoint>
            <omgdi:waypoint x="908.5" y="165.0"></omgdi:waypoint>
          </bpmndi:BPMNEdge>
          <bpmndi:BPMNEdge bpmnElement="sid-F0149E5B-E9A1-49C9-A243-638C4E21E378" id="BPMNEdge_sid-F0149E5B-E9A1-49C9-A243-638C4E21E378">
            <omgdi:waypoint x="39.94999891869115" y="165.0"></omgdi:waypoint>
            <omgdi:waypoint x="105.0" y="165.0"></omgdi:waypoint>
          </bpmndi:BPMNEdge>
          <bpmndi:BPMNEdge bpmnElement="sid-C91352A8-84D9-474E-89A5-0AF0EFC5F58B" id="BPMNEdge_sid-C91352A8-84D9-474E-89A5-0AF0EFC5F58B">
            <omgdi:waypoint x="559.9499999999681" y="220.0"></omgdi:waypoint>
            <omgdi:waypoint x="613.5" y="220.0"></omgdi:waypoint>
            <omgdi:waypoint x="613.5" y="184.9180783242259"></omgdi:waypoint>
          </bpmndi:BPMNEdge>
          <bpmndi:BPMNEdge bpmnElement="sid-7492310C-5318-4379-8DEB-53D6CA7E6AD9" id="BPMNEdge_sid-7492310C-5318-4379-8DEB-53D6CA7E6AD9">
            <omgdi:waypoint x="843.5" y="184.94312543073747"></omgdi:waypoint>
            <omgdi:waypoint x="843.5" y="310.0"></omgdi:waypoint>
            <omgdi:waypoint x="322.45000000000005" y="310.0"></omgdi:waypoint>
          </bpmndi:BPMNEdge>
          <bpmndi:BPMNEdge bpmnElement="sid-97861805-692B-48CA-BBC8-C3BCF604E7AB" id="BPMNEdge_sid-97861805-692B-48CA-BBC8-C3BCF604E7AB">
            <omgdi:waypoint x="294.94133362293655" y="165.0"></omgdi:waypoint>
            <omgdi:waypoint x="370.0" y="165.0"></omgdi:waypoint>
          </bpmndi:BPMNEdge>
          <bpmndi:BPMNEdge bpmnElement="sid-89703E3C-E4C1-4DBF-9462-2DAE98EF4D55" id="BPMNEdge_sid-89703E3C-E4C1-4DBF-9462-2DAE98EF4D55">
            <omgdi:waypoint x="559.9499999999823" y="85.0"></omgdi:waypoint>
            <omgdi:waypoint x="613.5" y="85.0"></omgdi:waypoint>
            <omgdi:waypoint x="613.5" y="145.0"></omgdi:waypoint>
          </bpmndi:BPMNEdge>
          <bpmndi:BPMNEdge bpmnElement="sid-C39C6BE4-57FF-4153-8C1E-1D97D37146DE" id="BPMNEdge_sid-C39C6BE4-57FF-4153-8C1E-1D97D37146DE">
            <omgdi:waypoint x="155.0" y="329.93939957492034"></omgdi:waypoint>
            <omgdi:waypoint x="155.0" y="390.0"></omgdi:waypoint>
          </bpmndi:BPMNEdge>
          <bpmndi:BPMNEdge bpmnElement="sid-FF7E4059-6000-4335-8F8E-AC2295A8DB5B" id="BPMNEdge_sid-FF7E4059-6000-4335-8F8E-AC2295A8DB5B">
            <omgdi:waypoint x="633.4413336229366" y="165.0"></omgdi:waypoint>
            <omgdi:waypoint x="678.5" y="165.0"></omgdi:waypoint>
          </bpmndi:BPMNEdge>
          <bpmndi:BPMNEdge bpmnElement="sid-71206A86-A1DC-42CE-92FF-179507B2AC04" id="BPMNEdge_sid-71206A86-A1DC-42CE-92FF-179507B2AC04">
            <omgdi:waypoint x="222.5" y="310.0"></omgdi:waypoint>
            <omgdi:waypoint x="174.9084540032961" y="310.0"></omgdi:waypoint>
          </bpmndi:BPMNEdge>
          <bpmndi:BPMNEdge bpmnElement="sid-606C543E-F974-42F7-8BBE-86E19E6A40FC" id="BPMNEdge_sid-606C543E-F974-42F7-8BBE-86E19E6A40FC">
            <omgdi:waypoint x="204.95" y="165.0"></omgdi:waypoint>
            <omgdi:waypoint x="255.0" y="165.0"></omgdi:waypoint>
          </bpmndi:BPMNEdge>
          <bpmndi:BPMNEdge bpmnElement="sid-8882D268-789B-4A66-99A8-513C8F19E21C" id="BPMNEdge_sid-8882D268-789B-4A66-99A8-513C8F19E21C">
            <omgdi:waypoint x="155.0" y="290.0"></omgdi:waypoint>
            <omgdi:waypoint x="155.0" y="204.95"></omgdi:waypoint>
          </bpmndi:BPMNEdge>
        </bpmndi:BPMNPlane>
      </bpmndi:BPMNDiagram>
    </definitions>

    此时我们可以看到主编1和主编2 是并行审核的,当他们审核完的时候要有有一个系统判断来判断最终的审核结果,决定流程的走向。

解决方案:

在系统判断这个节点的时候我们就要是使用任务监听器:TaskListener

/**
 * @ProjectName: spark-platform
 * @Package: com.spark.platform.flowable.biz.listener
 * @ClassName: TaskListener
 * @Author: wangdingfeng
 * @Description: 任务监听器
 * @Date: 2020/4/8 14:22
 * @Version: 1.0
 */
@Slf4j
@Component
public class MyTaskListener implements TaskListener {

    @Override
    public void notify(DelegateTask delegateTask) {
        String eventName = delegateTask.getEventName();
        switch (eventName) {
            case BaseTaskListener.EVENTNAME_CREATE:
                log.info("当前监听创建事件:create");
                //开启消息发送线程
                Thread thread = new Thread(
                        new MessageRunnableTask(delegateTask));
                thread.start();
                break;
            case BaseTaskListener.EVENTNAME_ASSIGNMENT:
                log.info("当前监听指派事件:assignment");
                break;
            case BaseTaskListener.EVENTNAME_COMPLETE:
                log.info("当前监听完成事件:complete");
                break;
            case BaseTaskListener.EVENTNAME_DELETE:
                log.info("当前监听销毁事件:delete");
                break;
            default:
                break;
        }
    }
}

TaskListener 虽然是可以做监听,但是由于此时任务数据还没有在数据库中落地,所以无法获取到当前节点的taskID,不能自动推动流程的走向,所以我加了一个线程用来刷此个节点的taskId,代码如下

/**
 * @ProjectName: spark-platform
 * @Package: com.spark.platform.flowable.biz.listener
 * @ClassName: RunnableTask
 * @Author: wangdingfeng
 * @Description: 线程
 * @Date: 2020/4/14 11:07
 * @Version: 1.0
 */
@Slf4j
public class MessageRunnableTask implements Runnable {

    private DelegateTask delegateTask;

    MessageRunnableTask(DelegateTask delegateTask) {
        this.delegateTask = delegateTask;
    }


    @Override
    public void run() {
        Task task = getTask(delegateTask);
        StringRedisTemplate redisTemplate = SpringContextHolder.getBean(StringRedisTemplate.class);
        TaskVO taskVO = new TaskVO();
        BeanUtil.copyProperties(task, taskVO, "variables");
        taskVO.setVariables(task.getProcessVariables());
        redisTemplate.convertAndSend(RedisTopicName.topicName, JSONObject.toJSONString(taskVO));

    }

    /**
     * 递归查询 直到查询到task任务已经落地为止,然后发布消息
     *
     * @param delegateTask
     * @return
     */
    private Task getTask(DelegateTask delegateTask) {
        ActTaskQueryService actTaskQueryService = SpringContextHolder.getBean(ActTaskQueryService.class);
        Task task = null;
        while (null == task){
            log.info("开是休眠40S");
            ThreadUtil.sleep(1000 * 40);
            task = actTaskQueryService.createTaskQuery().processInstanceId(delegateTask.getProcessInstanceId()).taskAssignee(delegateTask.getAssignee()).includeProcessVariables().singleResult();
        }
        log.info("代办任务数据库已经落地----");
        return task;
    }
}

由于通常我们的业务代码不会在工作流这个服务中判断,通常由业务发起服务器判断,所以我使用了消息订阅。此示例代码用的是redis消息发布订阅,实际开发中不要使用redis,由于redis的消息队列一旦消费者不存在,就会出现消息丢失的情况,请使用rabbitmq这些消息队列。

Redis 订阅处理消息

@Component
@Slf4j
public class RedisChannelListener implements MessageListener {

    @Override
    public void onMessage(Message message, byte[] pattern) {
        //接受消息
        byte[] channel = message.getChannel();
        byte[] body = message.getBody();
        try {
            String content = new String(body, "UTF-8");
            String address = new String(channel, "UTF-8");
            log.info("接收到频道{}发来的消息:{}", address, address);
            switch (address) {
                case RedisTopicName.topicName:
                    articleMessage(content);
                    break;
                default:
                    break;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 文章消息处理
     *
     * @param content
     */
    public void articleMessage(String content) {
        log.info("开始处理文章信息");
        TaskVO taskVO = JSONObject.parseObject(content,TaskVO.class);
        //推进任务
        boolean flag = true;
        Iterator<Map.Entry<String, Object>> it = taskVO.getVariables().entrySet().iterator();
        //判断两个主编的最终审核结果 只有当两个主编都审核通过才通过
        while (it.hasNext()) {
            Map.Entry<String, Object> entry = it.next();
            if (entry.getKey().startsWith("multiInstance_result")) {
                if (!(boolean) entry.getValue()) {
                    flag = false;
                    break;
                }
            }
        }
        ActTaskService actTaskService = SpringContextHolder.getBean(ActTaskService.class);
        Map<String, Object> map = ImmutableMap.of("SYSTEM_JUDGE_SUBMIT_VALUE", "SUBMIT_APPROVAL");
        if (flag) {
            map = ImmutableMap.of("SYSTEM_JUDGE_SUBMIT_VALUE", "PASS");
        }
        actTaskService.complete(taskVO.getId(), map);
    }

}

具体的例子,请参考我的开源项目:

spark: https://gitee.com/dreamfeng/spark-platform

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值