activiti流程回退实现思路

package com.yussion;

import java.text.ParseException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.activiti.engine.HistoryService;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
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.cfg.StandaloneProcessEngineConfiguration;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;

public class RollBackTaskTest {
    public static void main(String[] args) throws ParseException {
        excuteTask();
        rollBackTask2("9");  //taskId 刚完成的任务ID,即需要回退的任务对应任务ID
        rollBackTask("15"); //taskId 当前任务ID,即需要回退的任务ID的下一步任务ID
    }
    
    private static void excuteTask() throws ParseException {
        ProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration()
                //.setJdbcUrl("jdbc:h2:mem:activiti;DB_CLOSE_DELAY=1000").setJdbcUsername("sa").setJdbcPassword("")
                //.setJdbcDriver("org.h2.Driver")
                .setJdbcUrl("jdbc:mysql://localhost:3306/activiti?serverTimezone=UTC").setJdbcUsername("root").setJdbcPassword("123456")
                .setJdbcDriver("com.mysql.jdbc.Driver")
                .setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
        ProcessEngine processEngine = cfg.buildProcessEngine();

        RepositoryService repositoryService = processEngine.getRepositoryService();
        Deployment deployment = repositoryService.createDeployment().addClasspathResource("onboarding.bpmn20.xml")
                .deploy();
        repositoryService.createProcessDefinitionQuery().deploymentId(deployment.getId()).singleResult();

        RuntimeService runtimeService = processEngine.getRuntimeService();
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("onboarding");

        //startOnboarding - enterOnboardingData - personalizedIntro - endOnboarding
        //执行完成enterOnboardingData后,需要回退该已完成的任务,此处构造出enterOnboardingData任务完成的数据
        if (processInstance != null && !processInstance.isEnded()) {
            TaskService taskService = processEngine.getTaskService();
            List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup("managers").list();
            Task task = tasks.get(0);
            
            Map<String, Object> variables = new HashMap<String, Object>();
            variables.put("fullName", "张三");
            variables.put("yearsOfExperience", 11);
            taskService.complete(task.getId(), variables);
            
            //variables.clear();
            //variables.put("personalWelcomeTime", "1/1/2021");
            //task = tasks.get(1);
            //taskService.complete(task.getId(), variables);
        }
    }
    
    //lastHiTaskId: 刚完成的任务ID,即需要回退的任务对应任务ID
    private static void rollBackTask2(String lastHiTaskId) {
        ProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration()
                //.setJdbcUrl("jdbc:h2:mem:activiti;DB_CLOSE_DELAY=1000").setJdbcUsername("sa").setJdbcPassword("")
                //.setJdbcDriver("org.h2.Driver")
                .setJdbcUrl("jdbc:mysql://localhost:3306/activiti?serverTimezone=UTC").setJdbcUsername("root").setJdbcPassword("123456")
                .setJdbcDriver("com.mysql.jdbc.Driver")
                .setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
        ProcessEngine processEngine = cfg.buildProcessEngine();
        
        // https://www.itdaan.com/blog/2017/10/26/a24659ba5fa8e821ce9bc9267ca96107.html
        // 按照完成时间排序取第一个, 即需要回退到该节点
        HistoricTaskInstance hstTask = processEngine.getHistoryService().createHistoricTaskInstanceQuery()
                .taskId(lastHiTaskId).singleResult();
        List<HistoricTaskInstance> htiList = processEngine.getHistoryService().createHistoricTaskInstanceQuery()
                .processInstanceId(hstTask.getProcessInstanceId()).finished().orderByTaskCreateTime().desc().list();
        if (htiList == null || htiList.size() < 2) {
            //回退到开始节点,这种情况清空hi和RU表数据即可
            return;
        }
        String lastTaskId = htiList.get(0).getId(); // 从taskId对应节点回退到parentTaskId对应节点
        String execId = hstTask.getExecutionId();
        System.out.println(lastTaskId+"   "+execId);
    }
    
    // taskId 当前任务ID,即需要回退的任务ID的下一步任务ID, 以完成enterOnboardingData后需要回退enterOnboardingData为例   当前任务ID为15,上一步任务ID为9, execId为6
    private static void rollBackTask(String taskId) {
        ProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration()
                //.setJdbcUrl("jdbc:h2:mem:activiti;DB_CLOSE_DELAY=1000").setJdbcUsername("sa").setJdbcPassword("")
                //.setJdbcDriver("org.h2.Driver")
                .setJdbcUrl("jdbc:mysql://localhost:3306/activiti?serverTimezone=UTC").setJdbcUsername("root").setJdbcPassword("123456")
                .setJdbcDriver("com.mysql.jdbc.Driver")
                .setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
        ProcessEngine processEngine = cfg.buildProcessEngine();
        
        // https://www.itdaan.com/blog/2017/10/26/a24659ba5fa8e821ce9bc9267ca96107.html
        // 按照完成时间排序取第一个, 即需要回退到该节点
        HistoricTaskInstance hstTask = processEngine.getHistoryService().createHistoricTaskInstanceQuery()
                .taskId(taskId).singleResult();
        List<HistoricTaskInstance> htiList = processEngine.getHistoryService().createHistoricTaskInstanceQuery()
                .processInstanceId(hstTask.getProcessInstanceId()).finished().orderByTaskCreateTime().desc().list();
        if (htiList == null || htiList.size() < 2) {
            //回退到开始节点,这种情况清空hi和RU表数据即可
            return;
        }
        String lastTaskId = htiList.get(0).getId(); // 从taskId对应节点回退到parentTaskId对应节点
        String execId = hstTask.getExecutionId();
        System.out.println(lastTaskId+"   "+execId);

        // 删除待回退的历史任务
        // DELETE from ACT_HI_TASKINST where EXECUTION_ID_=#{execId} and ID_=#{taskId}  
        // DELETE from ACT_HI_TASKINST where EXECUTION_ID_='6' and ID_='15';

        // 更新跳转任务的完成时间 和状态
        // update ACT_HI_TASKINST set END_TIME_=NULL,DURATION_=NULL,DELETE_REASON_=NULL where EXECUTION_ID_=#{execId} and id_=#{lastTaskId}
        // update ACT_HI_TASKINST set END_TIME_=NULL,DURATION_=NULL,DELETE_REASON_=NULL where EXECUTION_ID_='6' and id_='9';

        // 更新taskId 解除关联 ACT_RU_IDENTITYLINK
        // String linkId: select ID_ from ACT_RU_IDENTITYLINK where TASK_ID_=#{taskId}  select ID_ from ACT_RU_IDENTITYLINK where TASK_ID_='15' -> 16
        // update ACT_RU_IDENTITYLINK set TASK_ID_=NULL where ID_=#{linkId}  update ACT_RU_IDENTITYLINK set TASK_ID_=NULL where ID_='16'

        // 更新当前任务 名称 fromKey id
        /*
          UPDATE ACT_RU_TASK a, ( SELECT TASK_DEF_KEY_, FORM_KEY_, NAME_, ID_ FROM
          ACT_HI_TASKINST WHERE EXECUTION_ID_ = #{execId} AND ID_ = #{lastTaskId} ) b
          SET a.ID_ = b.ID_, a.TASK_DEF_KEY_ = b.TASK_DEF_KEY_, a.NAME_ = b.NAME_,
          a.FORM_KEY_ = b.FORM_KEY_ WHERE a.EXECUTION_ID_ = #{execId} AND a.id_ =
          #{taskId}
          -----------------------------------
          UPDATE ACT_RU_TASK a, ( SELECT TASK_DEF_KEY_, FORM_KEY_, NAME_, ID_ FROM
          ACT_HI_TASKINST WHERE EXECUTION_ID_ = '6' AND ID_ = '9' ) b
          SET a.ID_ = b.ID_, a.TASK_DEF_KEY_ = b.TASK_DEF_KEY_, a.NAME_ = b.NAME_,
          a.FORM_KEY_ = b.FORM_KEY_ WHERE a.EXECUTION_ID_ = '6' AND a.id_ = '15'
         */

        // 更新ACT_RU_IDENTITYLINK 的taskid
        // update ACT_RU_IDENTITYLINK set TASK_ID_=#{lastTaskId} where ID_=#{linkId}  update ACT_RU_IDENTITYLINK set TASK_ID_='9' where ID_='16'

        // 更新execu的 act_id_
        // UPDATE ACT_RU_EXECUTION a, ( SELECT TASK_DEF_KEY_ FROM ACT_RU_TASK WHERE ID_ = #{lastTaskId} ) b SET a.ACT_ID_ = b.TASK_DEF_KEY_ WHERE ID_ = #{execId}
        // UPDATE ACT_RU_EXECUTION a, ( SELECT TASK_DEF_KEY_ FROM ACT_RU_TASK WHERE ID_ = '9' ) b SET a.ACT_ID_ = b.TASK_DEF_KEY_ WHERE ID_ = '6'
    }
}

-----------------流程各阶段数据库表数据变化----------------------

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值