如何优雅的实现activiti的回退和驳回
1、应用场景
当前activiti已经成为十分主流的流程框架,但是毕竟是老美的东西,在中国难免会水土不服,当业务涉及到一些回退,或者驳回的操作时,该框架并不能很好的实现我们的业务,
此时我们要做的就是对其进行改造,让他认识到中国特色社会主义的好。
2、解决方案
一、关于回退,我们在进行流程的操作的时候难免会手残,开始了一段让人心惊胆战的错误操作,此时第一时间是想着如何挽回自己得出错误,撤回该流程,不多说直接上代码
1 /** 2 * @params taskId 你想tiao回到那一任务节点Id 3 * 4 */ 5 6 public void taskRollback(String taskId){ 7 8 //根据要跳转的任务ID获取其任务 9 HistoricTaskInstance hisTask = activitiEnginUtil.getHistoryService() 10 .createHistoricTaskInstanceQuery().taskId(taskId) 11 .singleResult(); 12 //进而获取流程实例 13 ProcessInstance instance = activitiEnginUtil.getRuntimeServic() 14 .createProcessInstanceQuery() 15 .processInstanceId(hisTask.getProcessInstanceId()) 16 .singleResult(); 17 //取得流程定义 18 ProcessDefinitionEntity definition = (ProcessDefinitionEntity) activitiEnginUtil.getRepositoryService().getProcessDefinition(hisTask.getProcessDefinitionId()); 19 //获取历史任务的Activity 20 ActivityImpl hisActivity = definition.findActivity(hisTask.getTaskDefinitionKey()); 21 //实现跳转 22 activitiEnginUtil.getTaskManagementService().executeCommand(new JumpCmd(instance.getId(), hisActivity.getId())); 23 }
1 /** 2 * 因为activiti的具体服务执行是运用可命令模式 3 4 * 所以我们在进行动态任务节点跳转的时候要实现该接口 5 */ 6 7 public class JumpCmd implements Command<ExecutionEntity>{ 8 9 private String processInstanceId; 10 private String activityId; 11 public static final String REASION_DELETE = "deleted"; 12 13 public JumpCmd(String processInstanceId, String activityId) { 14 this.processInstanceId = processInstanceId; 15 this.activityId = activityId; 16 } 17 18 @Override 19 public ExecutionEntity execute(CommandContext commandContext) { 20 ExecutionEntity executionEntity = commandContext.getExecutionEntityManager().findExecutionById(processInstanceId); 21 22 executionEntity.destroyScope(REASION_DELETE); //删除的原因 23 ProcessDefinitionImpl processDefinition = executionEntity.getProcessDefinition(); 24 ActivityImpl activity = processDefinition.findActivity(activityId); 25 executionEntity.executeActivity(activity); 26 27 return executionEntity; 28 } 29 30 }
二、关于流程的驳回,即拒绝某一个流程,此时有多种办法可以实现该功能, 不过目前最常用的一种方法就是运用上一个节点流向来代替当前节点的流向,进而达到一个驳回的目的
具体代码实现如下
1 /** 2 3 * @params curTask 即当前任务 4 */ 5 6 public void rejectFlow(Task curTask) { 7 //获取任务ID 然后查询到当前任务节点 8 curTask.getProcessDefinitionId(); 9 ProcessDefinitionEntity processDefinitionEntity = (org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity) activitiEnginUtil.getRepositoryService(). 10 createProcessDefinitionQuery().processDefinitionId(curTask.getProcessDefinitionId()).singleResult(); 11 // 取得上一步活动的节点流向 12 ActivityImpl curActivity = processDefinitionEntity.findActivity(curTask.getTaskDefinitionKey()); 13 List<PvmTransition> incomingTransitions = curActivity.getIncomingTransitions(); 14 15 //清空指定节点所有流向并暂时先将所有流向变量暂时存储在一个新的集合(主要是为后来恢复正常流程走向做准备) 16 List<PvmTransition> pvmTransitionList = new ArrayList<PvmTransition>(); 17 18 List<PvmTransition> outgoingTransitions = curActivity.getOutgoingTransitions(); 19 20 for (PvmTransition pvmTransition: outgoingTransitions) { 21 pvmTransitionList.add(pvmTransition); 22 } 23 outgoingTransitions.clear(); 24 25 //创建新的流向并且设置新的流向的目标节点 (将该节点的流程走向都设置为上一节点的流程走向,目的是相当于形成一个回路) 26 List<TransitionImpl> newTransitionList = new ArrayList<TransitionImpl>(); 27 for (PvmTransition pvmTransition : incomingTransitions) { 28 PvmActivity source = pvmTransition.getSource(); 29 ActivityImpl inActivity = processDefinitionEntity.findActivity(source.getId()); 30 TransitionImpl newOutgoingTransition = curActivity.createOutgoingTransition(); 31 newOutgoingTransition.setDestination(inActivity); 32 newTransitionList.add(newOutgoingTransition); 33 } 34 35 //完成任务(流程走向上一节点) 36 TaskService taskService = activitiEnginUtil.getTaskService(); 37 List<Task> taskList = activitiEnginUtil.getTaskService().createTaskQuery().processInstanceId(curTask.getProcessInstanceId()).list(); 38 for (Task task : taskList) { 39 taskService.complete(task.getId()); 40 activitiEnginUtil.getHistoryService().deleteHistoricTaskInstance(task.getId()); 41 42 } 43 44 // 恢复方向(实现驳回功能后恢复原来正常的方向) 45 for (TransitionImpl transitionImpl : newTransitionList) { 46 curActivity.getOutgoingTransitions().remove(transitionImpl); 47 } 48 49 for (PvmTransition pvmTransition : pvmTransitionList) { 50 outgoingTransitions.add(pvmTransition); 51 } 52 53 } 54 55