Activiti6 --- Retirada del proceso

1. Descripción

Escenario: Agregar un requisito al estilo chino sobre la base de mi caso 4. Por ejemplo, después de que el solicitante envía el formulario de licencia, descubre que ha escrito un error y necesita retirar la operación de presentación y completar la presentación nuevamente. Entonces qué debería ser hecho. Este es el retiro del proceso, la siguiente es la operación del retiro del proceso de prueba.

2. La idea de realizar el proceso de retirada

1、获取当前任务所在的节点
2、获取所在节点的流出方向
3、记录所在节点的流出方向,并将所在节点的流出方向清空
4、获取目标节点
5、创建新的方向
6、将新的方向set到所在节点的流出方向
7、完成当前任务
8、还原所在节点的流出方向

3. Prueba

Diagrama de flujo de diseño:
Inserte la descripción de la imagen aquí
archivo Bpmn:

<?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:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" xmlns:tns="http://www.activiti.org/test" 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="m1597282397003" name="" targetNamespace="http://www.activiti.org/test" typeLanguage="http://www.w3.org/2001/XMLSchema">
  <process id="withdraw" isClosed="false" isExecutable="true" processType="None">
    <startEvent id="_2" name="开始"/>
    <userTask activiti:assignee="zhangsan" activiti:exclusive="true" id="_3" name="原始任务A"/>
    <userTask activiti:assignee="lisi" activiti:exclusive="true" id="_4" name="原始任务B"/>
    <endEvent id="_5" name="结束"/>
    <sequenceFlow id="_6" sourceRef="_2" targetRef="_3"/>
    <sequenceFlow id="_7" sourceRef="_3" targetRef="_4"/>
    <sequenceFlow id="_8" sourceRef="_4" targetRef="_5"/>
  </process>
  <bpmndi:BPMNDiagram documentation="background=#000000;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="withdraw">
      <bpmndi:BPMNShape bpmnElement="_2" id="Shape-_2">
        <omgdc:Bounds height="32.0" width="32.0" x="-5.0" y="325.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_3" id="Shape-_3">
        <omgdc:Bounds height="55.0" width="85.0" x="140.0" y="310.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_4" id="Shape-_4">
        <omgdc:Bounds height="55.0" width="85.0" x="350.0" y="310.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_5" id="Shape-_5">
        <omgdc:Bounds height="32.0" width="32.0" x="545.0" y="320.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="_6" id="BPMNEdge__6" sourceElement="_2" targetElement="_3">
        <omgdi:waypoint x="27.0" y="341.0"/>
        <omgdi:waypoint x="140.0" y="337.5"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_7" id="BPMNEdge__7" sourceElement="_3" targetElement="_4">
        <omgdi:waypoint x="225.0" y="337.5"/>
        <omgdi:waypoint x="350.0" y="337.5"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_8" id="BPMNEdge__8" sourceElement="_4" targetElement="_5">
        <omgdi:waypoint x="435.0" y="337.5"/>
        <omgdi:waypoint x="545.0" y="336.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>

Categoría de prueba:

package com.yb;

import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.FlowNode;
import org.activiti.bpmn.model.SequenceFlow;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.impl.identity.Authentication;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.Execution;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.hibernate.service.spi.ServiceException;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;

/**
 * @author [email protected]
 * @version 1.0
 * @date 2020/8/5
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class ActivitiJpaTest08 {
    
    

    @Resource
    private RepositoryService repositoryService;
    @Resource
    private RuntimeService runtimeService;
    @Resource
    private TaskService taskService;
    @Resource
    private HistoryService historyService;

    @Resource
    private HttpServletRequest request;
    /**
     * 部署流程,测试撤回
     */
    @Test
    public void repositoryDeploy(){
    
    
        Deployment deploy = repositoryService.createDeployment()
                .addClasspathResource("processes/BackOff.bpmn")
                .addClasspathResource("processes/BackOff.png")
                .name("测试撤回-1")
                .deploy();
        System.out.println("部署ID:"+deploy.getId());
        System.out.println("部署名称"+deploy.getName());
    }

    /**
     * 发布流程
     */
    @Test
    public void runtimeRelease(){
    
    

        ProcessInstance pi = runtimeService.startProcessInstanceByKey("withdraw");
        System.out.println("流程实例ID:"+pi.getId());
        System.out.println("流程定义ID:"+pi.getProcessDefinitionId());
    }

    /**
     * 查询及完成任务
     */
    @Test
    public void taskQueryComplete(){
    
    
        List<Task> list = taskService.createTaskQuery()
                .taskAssignee("zhangsan")
                .list();
        for (Task task : list) {
    
    
            System.out.println("--------------------------------------------");
            System.out.println("任务ID:" + task.getId());
            System.out.println("任务名称:" + task.getName());
            System.out.println("任务创建时间:" + task.getCreateTime());
            System.out.println("任务委派人:" + task.getAssignee());
            System.out.println("流程实例ID:" + task.getProcessInstanceId());
            System.out.println("--------------------------------------------");
            taskService.complete(task.getId());
        }
    }





    /**
     *撤回上一个节点
     */
    @Test
    public void taskQueryComplete2() throws Exception{
    
    
        //当前任务
        Task task = taskService.createTaskQuery()
                .taskAssignee("lisi")
                .singleResult();
        if(task==null) {
    
    
            throw new ServiceException("流程未启动或已执行完成,无法撤回");
        }
        List<HistoricTaskInstance> htlist = historyService.createHistoricTaskInstanceQuery()
                .processDefinitionId(task.getProcessDefinitionId())
                .list();

        String myTaskId = null;
        HistoricTaskInstance myTask = null;

        for (HistoricTaskInstance hti : htlist) {
    
    
            //回退到zhangsan也就是任务A,业务中这里就是当前登录的用户名
            if(hti.getAssignee().equals("zhangsan")){
    
    
                myTaskId=hti.getId();

                myTask=hti;
                break;
            }
        }

        if(myTask==null){
    
    
            throw new ServiceException("该任务非当前用户提交,无法撤回");
        }

        String processDefinitionId = myTask.getProcessDefinitionId();
        

        BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);


        String myActivityId = null;

        List<HistoricActivityInstance> haiList =
                historyService
                        .createHistoricActivityInstanceQuery()
                        .executionId(myTask.getExecutionId())
                        .finished()
                        .list();

        for (HistoricActivityInstance hai : haiList) {
    
    
            if(myTaskId.equals(hai.getTaskId())) {
    
    
                myActivityId = hai.getActivityId();
                break;
            }
        }

        FlowNode myFlowNode =
                (FlowNode) bpmnModel.getMainProcess().getFlowElement(myActivityId);

        Execution execution = runtimeService.createExecutionQuery()
                .executionId(task.getExecutionId()).singleResult();

        String activityId = execution.getActivityId();

        System.out.println(activityId);

        FlowNode flowNode = (FlowNode) bpmnModel.getMainProcess()
                .getFlowElement(activityId);

        //记录原活动方向
        List<SequenceFlow> oriSequenceFlows = new ArrayList<SequenceFlow>();
        oriSequenceFlows.addAll(flowNode.getOutgoingFlows());

        //清理活动方向
        flowNode.getOutgoingFlows().clear();

        //建立新方向
        List<SequenceFlow> newSequenceFlowList = new ArrayList<SequenceFlow>();
        SequenceFlow newSequenceFlow = new SequenceFlow();
        newSequenceFlow.setId("newSequenceFlowId");
        newSequenceFlow.setSourceFlowElement(flowNode);
        newSequenceFlow.setTargetFlowElement(myFlowNode);
        newSequenceFlowList.add(newSequenceFlow);
        flowNode.setOutgoingFlows(newSequenceFlowList);

        Authentication.setAuthenticatedUserId("zhangsan");
        taskService.addComment(task.getId(), task.getProcessInstanceId(), "撤回");

        //完成任务
        taskService.complete(task.getId());
        //恢复原方向
        flowNode.setOutgoingFlows(oriSequenceFlows);
    }
}

base de datos:
Inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/Lv_vI/article/details/107997446
Recomendado
Clasificación