【Activiti】activiti 手动回退一个结束的流程


【Activiti】activiti 手动回退一个结束的流程

1. 引言

最近有一个流程回退的任务,于是就上网搜,发现流程回退大都是针对没有结束的流程回退到上一步,而且给出的方法大都如吻末给出的相关链接中操作方式,试了试好像都不太好使。
于是就参照着网上的方法,顺带看接口看源码,试了试感觉总是不够灵活,还容易出错。
后来想了想,其实他流程所有的信息都存在了23张表中,每一步,无非就是改这些表信息,我抹清每一个审批动作他到底改变了那些表,我把这些表数据回滚不就好了。

2. 准备

  1. 首先我们需要先了解一下这23张表到底都是干什么的
  2. 我们要知道这些表是怎么变化的
    关于表变化,要把过程记录下来太麻烦了,我就不一一走了,给出一个参考链接https://blog.csdn.net/ccdust/article/details/52600804
ACT_EVT_LOG -- ACT_GE_* 通用数据, 用于不同场景下 ACT_GE_BYTEARRAY ACT_GE_PROPERTY -- ACT_HI_* history 历史数据,每一步操作,都会在这些相关表记录 ACT_HI_ACTINST ACT_HI_ATTACHMENT ACT_HI_COMMENT ACT_HI_DETAIL ACT_HI_IDENTITYLINK ACT_HI_PROCINST ACT_HI_TASKINST ACT_HI_VARINST --ACT_ID_* identity 身份信息 ACT_ID_GROUP ACT_ID_INFO ACT_ID_MEMBERSHIP ACT_ID_USER ACT_PROCDEF_INFO --ACT_RE_* repository 流程相关表(流程部署、流程模型、流程定义) ACT_RE_DEPLOYMENT ACT_RE_MODEL ACT_RE_PROCDEF --ACT_RU_* runtime 流程运行时表,流程结束,这些表数据清空 ACT_RU_EVENT_SUBSCR ACT_RU_EXECUTION ACT_RU_IDENTITYLINK ACT_RU_JOB ACT_RU_TASK ACT_RU_VARIABLE -- 可能我们业务结合,还会自定义一些表,保存重要信息 

    
    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

3. 回退

建议先找一个备份库,直接用sql操作回退流程,找到每一步都的变化,直到成功,然后再在代码中实现。

我这里记录的是一个结束的流程回退,所以运行时表中已经没有数据了,得从历史表走起

3.1 先用sql试验回退activiti表

-- 1. 查询ACT_HI_TASKINST,返回历史中task数据 select * from ACT_HI_TASKINST where ID_=#{taskId}; --2. 创建一个ACT_RU_EXECUTION记录,每一个流程都有一个记录,流程结束清除,但EXECUTION没有历史表,所以自己创建 # 参照插入 select * from ACT_RU_EXECUTION; insert into ACT_RU_EXECUTION (ID_, REV_, PROC_INST_ID_, BUSINESS_KEY_, PROC_DEF_ID_, ACT_ID_, IS_ACTIVE_, IS_CONCURRENT_, IS_SCOPE_,IS_EVENT_SCOPE_, PARENT_ID_, SUPER_EXEC_, SUSPENSION_STATE_, CACHED_ENT_STATE_, TENANT_ID_, NAME_) values (...); -- 3. 将历史数据task添加至ACT_RU_TASK # 参照插入 select * from ACT_RU_TASK; insert into ACT_RU_TASK (ID_, REV_, NAME_, PARENT_TASK_ID_, DESCRIPTION_, PRIORITY_, CREATE_TIME_, OWNER_, ASSIGNEE_, DELEGATION_, EXECUTION_ID_, PROC_INST_ID_, PROC_DEF_ID_, TASK_DEF_KEY_, DUE_DATE_, CATEGORY_, SUSPENSION_STATE_, TENANT_ID_, FORM_KEY_) values (); -- 4. 恢复当前任务相关处理人到ACT_RUN_IDENTITYLINK select * from ACT_HI_IDENTITYLINK WHERE PROC_INST_ID_={} OR TASK_ID_={}; # 这里会返回一个list # 参照插入 select * from ACT_RU_IDENTITYLINK; insert into ACT_RU_IDENTITYLINK (ID_, REV_, TYPE_, USER_ID_, GROUP_ID_, TASK_ID_, PROC_INST_ID_, PROC_DEF_ID_) values (); -- 5. 添加运行时变量 ACT_RUN_VARIABLE select * from ACT_HI_VARINST where EXECUTION_ID_={}; # 这里会返回一个list # 参照插入 select * from ACT_RUN_VARIABLE; insert into ACT_RU_VARIABLE (ID_, REV_, TYPE_, NAME_, PROC_INST_ID_, EXECUTION_ID_, TASK_ID_, BYTEARRAY_ID_, DOUBLE_, LONG_ , TEXT_, TEXT2_) values (); -- 至此数据已经恢复到待办中了,下一步还要回退已办中的数据哈 -- 6. 撤销已办 # 因为这是回退一个已经结束的流程,所以那个流程肯定会在已办列表里 # 看一下自己的已办是根据什么查询的对应修改相应数据 # 我这里是根据ACT_HI_TASKINST表endtime如果不为NULL,就到已办中去了 # 所以我只需要将这条记录中的endtime再改为NULL select * from ACT_HI_TASKINST where ID_={}; update ACT_HI_TASKINST set END_TIME_={} where ID_={}; 

    
    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

3.2 代码实现回退activiti流程

代码中实现,按上边sql顺序写逻辑就好了

@Transactional public void rollbackTask(String taskId){ ProcessEngine pe = ActivitiConfiguration.getProcessEngine(); logger.info("begin to rollback task: [{}]",taskId); //1. select task HistoricTaskInstance hstTask = pe.getHistoryService().createHistoricTaskInstanceQuery() .taskId(taskId).singleResult(); if(hstTask == null){ throw new RuntimeException("task is not exists: "+ taskId); } //2. create a execution,SubExecutionEntity只是添加了一个构造器 ExecutionEntity execution = new SubExecutionEntity( hstTask.getExecutionId(), hstTask.getProcessInstanceId(), hstTask.getProcessDefinitionId(), hstTask.getTaskDefinitionKey()); logger.info("create a new run execution"); taskRollBackMapper.insertExecution(execution); //3. insert task into ACT_RU_TASK TaskEntity runTask = new TaskEntity(); runTask.setId(hstTask.getId()); runTask.setName(hstTask.getName()); runTask.setPriority(hstTask.getPriority()); runTask.setCreateTime(hstTask.getCreateTime()); runTask.setAssignee(hstTask.getAssignee()); runTask.setExecutionId(hstTask.getExecutionId()); runTask.setProcessInstanceId(hstTask.getProcessInstanceId()); runTask.setProcessDefinitionId(hstTask.getProcessDefinitionId()); runTask.setTaskDefinitionKey(hstTask.getTaskDefinitionKey()); logger.info("insert task[{}] into ACT_RU_TASK",taskId); taskRollBackMapper.insertTask(runTask); //4. insert task identitylink into ACT_RUN_IDENTITYLINK List<HistoricIdentityLinkEntity> hstIdentityLinks= taskRollBackMapper .selectHistoricIdentityLinksByProcessInstanceAndTaskId(hstTask.getProcessInstanceId(), hstTask.getId()); List<IdentityLinkEntity> identityLinkEntities = new ArrayList<>(); for (HistoricIdentityLinkEntity hstIdentityLink:hstIdentityLinks){ IdentityLinkEntity identityLink = new IdentityLinkEntity(); identityLink.setId(hstIdentityLink.getId()); identityLink.setType(hstIdentityLink.getType()); identityLink.setUserId(hstIdentityLink.getUserId()); identityLink.setTaskId(hstIdentityLink.getTaskId()); identityLink.setProcessInstanceId(hstIdentityLink.getProcessInstanceId()); identityLinkEntities.add(identityLink); } logger.info("bulk insert task identitylinks into ACT_RUN_IDENTITYLINK"); taskRollBackMapper.bulkInsertIdentityLink(identityLinkEntities); // 5. insert variables into ACT_RU_VARIABLE final List<HistoricVariableInstance> hstVariables = pe.getHistoryService().createHistoricVariableInstanceQuery() .executionId(hstTask.getExecutionId()).list(); List<VariableInstanceEntity> variables = new ArrayList<>(); for (HistoricVariableInstance hstVariable:hstVariables){ VariableInstanceEntity variableInstance = VariableInstanceEntity .create(hstVariable.getVariableName(), new StringType(100), hstVariable.getValue()); variableInstance.setId(hstVariable.getId()); variableInstance.setExecutionId(hstVariable.getProcessInstanceId()); variableInstance.setProcessInstanceId(hstVariable.getProcessInstanceId()); variableInstance.setTaskId(hstVariable.getTaskId()); variableInstance.setTextValue((String) hstVariable.getValue()); variables.add(variableInstance); } logger.info("bulk insert task variables into ACT_RU_VARIABLE"); taskRollBackMapper.bulkInsertVariableInstance(variables); // 6. remove task from history record HistoricTaskInstanceEntity hstTaskUpdate = new HistoricTaskInstanceEntity(); hstTaskUpdate.setId(hstTask.getId()); hstTaskUpdate.setProcessDefinitionId(hstTask.getProcessDefinitionId()); hstTaskUpdate.setTaskDefinitionKey(hstTask.getTaskDefinitionKey()); hstTaskUpdate.setProcessInstanceId(hstTask.getProcessInstanceId()); hstTaskUpdate.setExecutionId(hstTask.getExecutionId()); hstTaskUpdate.setName(hstTask.getName()); hstTaskUpdate.setAssignee(hstTask.getAssignee()); hstTaskUpdate.setStartTime(hstTask.getStartTime()); hstTaskUpdate.setClaimTime(hstTask.getClaimTime()); hstTaskUpdate.setEndTime(null); hstTaskUpdate.setDueDate(hstTask.getDueDate()); hstTaskUpdate.setDeleteReason(hstTask.getDeleteReason()); hstTaskUpdate.setPriority(hstTask.getPriority()); logger.info("remove task from history record"); taskRollBackMapper.updateHistoricTaskInstance(hstTaskUpdate); logger.info("rollback task: [{}] end",taskId); } 

    
    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96

至于mapper.xml,可以参照源码中搬过来稍微改改就好了

相关链接:

  1. activiti执行过程,表变化
    https://blog.csdn.net/ccdust/article/details/52600804
  2. Activiti从当前任务任意回退至已审批任务
    https://www.bbsmax.com/A/obzb4o4B5E/
  3. Activiti6实现自由跳转
  4. https://segmentfault.com/a/1190000013952695
  5. Activiti6.0版本流程撤回、跳转、回退等操作
    https://blog.csdn.net/lianjie_c/article/details/79242009


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM