Activiti回退与跳转节点

Activiti6.0中审批不通过时回退到上一个节点/指定节点

在当前做的这个审批流中,需要增加一个审批不通过时回退节点的功能,因为当前系统需求还没有特别明确这部分,所以我就先写了以下两种回退情况:

1.回退到上一个节点

java 复制代码
 /**
     * 撤回到上一个节点
     * @param processInstanceId
     * @param nowUserId
     */
    @Override
    @Transactional
    public void revoke(String processInstanceId, String nowUserId) {
        //获取待执行的任务节点
        Task task = taskService.createTaskQuery().processInstanceId(processInstanceId).singleResult();
        if(task == null){
           // throw new Exception("sorry,the process is not started or has finished, cannot be withdrawn");
            System.out.println("sorry,the process is not started or has finished, cannot be withdrawn");
        }
        //通过processInstanceId查询历史节点
        List<HistoricTaskInstance> htiList = historyService.createHistoricTaskInstanceQuery()
                .processInstanceId(processInstanceId)
                .orderByTaskCreateTime()
                .asc()
                .list();
        String myTaskId = null;
        HistoricTaskInstance myTask = null;
        //找到当前运行的节点
        HistoricProcessInstance processInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
        ProcInstance procInstance = procInstanceMapper.selectById(processInstance.getBusinessKey()).get(0);
        SysUser startUser = sysUserService.selectUserById(procInstance.getUserId());
        List<SysUser> currUsers = findCurrUsers(task, startUser);
        System.out.println("----------- =-= -------currUser-----------------------"+currUsers.get(0).getUserId());
        System.out.println("------ =-= ------nowUserId--------------------------"+nowUserId);
        for (HistoricTaskInstance hti : htiList) {
            //判断一下当前的用户是否为当前任务的审批负责人 , 感觉后面通过权限赋予也可以不加这个判断
            //if (currUsers.get(0).getUserId().equals(nowUserId)&& hti.getId().equals(task.getId())) {
            if ( currUsers.get(0).getUserId().toString().equals(nowUserId)&&hti.getId().equals(task.getId())) {
                myTaskId = hti.getId();  //当前任务id
                myTask = hti;
                break;
            }
        }
        if (null == myTaskId) {
            //throw new Exception("该任务非当前用户提交,无法撤回");
            System.out.println("该任务非当前用户提交,无法撤回~~!!");
        }
        String processDefinitionId = myTask.getProcessDefinitionId();
        //获取流程模型
        BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
        String myActivityId = null;
        //查询已经完成的流程节点,查询到上一条已完成的节点,则跳出循环
        List<HistoricActivityInstance> haiList = historyService.createHistoricActivityInstanceQuery()
                .executionId(myTask.getExecutionId())
                .finished()
                .orderByHistoricActivityInstanceStartTime()
                .desc()
                .list();
        System.out.println("---------------the latest finished---------------"+haiList.get(0));
        myActivityId = haiList.get(0).getActivityId();
//        for (HistoricActivityInstance hai : haiList) {
//            if (myTaskId.equals(hai.getTaskId())) {
//                myActivityId = hai.getActivityId();
//                break;
//            }
//        }
        //最近一个已完成节点的 FlowNode
        FlowNode myFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(myActivityId);
        //原本的活动方向
        Execution execution = runtimeService.createExecutionQuery().executionId(task.getExecutionId()).singleResult();
        String activityId = execution.getActivityId();
        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"+" WITHDRAW: "+nowtime());
        //新方向的源头---当前节点
        newSequenceFlow.setSourceFlowElement(flowNode);
        //新方向的目标---上一个已完成节点
        newSequenceFlow.setTargetFlowElement(myFlowNode);
        newSequenceFlowList.add(newSequenceFlow);
        flowNode.setOutgoingFlows(newSequenceFlowList);

        Authentication.setAuthenticatedUserId(nowUserId);
        taskService.addComment(task.getId(), task.getProcessInstanceId(), "撤回");
        //完成任务
        taskService.complete(task.getId());
        //恢复原方向
        flowNode.setOutgoingFlows(oriSequenceFlows);
        System.out.println("------------------withdraw successfully!!----------------------------");
        logger.info("退回成功!");
    }

2.回退到当前审批用户指定的节点

先查询一下当前流程实例的历史Activity表:

java 复制代码
 /**
     * 展示历史Activity表
     * @param proInstanceId
     * @return
     */
    @Override
    @Transactional
    public List hisActInst(String proInstanceId){
        HistoricProcessInstance instance = historyService.createHistoricProcessInstanceQuery().processInstanceBusinessKey(proInstanceId).singleResult();
        String processInstanceId = instance.getId();
        //获取待执行的任务节点
        Task task = taskService.createTaskQuery().processInstanceId(processInstanceId).singleResult();
        if(task == null){
            // throw new Exception("sorry,the process is not started or has finished, cannot be withdrawn");
            System.out.println("sorry,the process is not started or has finished, cannot be withdrawn");
        }
        //通过processInstanceId查询历史节点
        List<HistoricTaskInstance> htiList = historyService.createHistoricTaskInstanceQuery()
                .processInstanceId(processInstanceId)
                .orderByTaskCreateTime()
                .asc()
                .list();
        String myTaskId = null;
        HistoricTaskInstance myTask = null;
        //找到当前运行的节点
        HistoricProcessInstance processInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
        ProcInstance procInstance = procInstanceMapper.selectById(processInstance.getBusinessKey()).get(0);
        SysUser startUser = sysUserService.selectUserById(procInstance.getUserId());
        List<SysUser> currUsers = findCurrUsers(task, startUser);
        for (HistoricTaskInstance hti : htiList) {
            //判断一下当前的用户是否为当前任务的审批负责人 , 感觉后面通过权限赋予也可以不加这个判断
            //if (currUsers.get(0).getUserId().equals(nowUserId)&& hti.getId().equals(task.getId())) {
            if ( hti.getId().equals(task.getId())) {
                myTaskId = hti.getId();  //当前任务id
                myTask = hti;
                break;
            }
        }
        if (null == myTaskId) {
            //throw new Exception("该任务非当前用户提交,无法撤回");
            System.out.println("该任务非当前用户提交,无法撤回~~!!");
        }
        List<HistoricActivityInstance> haiList = historyService.createHistoricActivityInstanceQuery()
                .executionId(myTask.getExecutionId())
                .finished()
                .orderByHistoricActivityInstanceStartTime()
                .desc()
                .list();
        return haiList;
    }

在根据获取到的目标回退节点的ActivityId进行回退操作:

java 复制代码
/**
     * 回退到指定节点处
     * @param processInstanceId
     * @param nowUserId
     * @param tarActivityId
     * @return
     */
    @Override
    @Transactional
    public void rollBackToSpec(String processInstanceId, String nowUserId, String tarActivityId) {
        //获取待执行的任务节点
        Task task = taskService.createTaskQuery().processInstanceId(processInstanceId).singleResult();
        if(task == null){
            // throw new Exception("sorry,the process is not started or has finished, cannot be withdrawn");
            System.out.println("sorry,the process is not started or has finished, cannot be withdrawn");
        }
        //通过processInstanceId查询历史节点
        List<HistoricTaskInstance> htiList = historyService.createHistoricTaskInstanceQuery()
                .processInstanceId(processInstanceId)
                .orderByTaskCreateTime()
                .asc()
                .list();
        String myTaskId = null;
        HistoricTaskInstance myTask = null;
        //找到当前运行的节点
        HistoricProcessInstance processInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
        ProcInstance procInstance = procInstanceMapper.selectById(processInstance.getBusinessKey()).get(0);
        SysUser startUser = sysUserService.selectUserById(procInstance.getUserId());
        List<SysUser> currUsers = findCurrUsers(task, startUser);
        System.out.println("----------- =-= -------currUser-----------------------"+currUsers.get(0).getUserId());
        System.out.println("------ =-= ------nowUserId--------------------------"+nowUserId);
        for (HistoricTaskInstance hti : htiList) {
            //判断一下当前的用户是否为当前任务的审批负责人 , 感觉后面通过权限赋予也可以不加这个判断
            //if (currUsers.get(0).getUserId().equals(nowUserId)&& hti.getId().equals(task.getId())) {
            if ( currUsers.get(0).getUserId().toString().equals(nowUserId)&&hti.getId().equals(task.getId())) {
                myTaskId = hti.getId();  //当前任务id
                myTask = hti;
                break;
            }
        }
        if (null == myTaskId) {
            //throw new Exception("该任务非当前用户提交,无法撤回");
            System.out.println("该任务非当前用户提交,无法撤回~~!!");
        }
        String processDefinitionId = myTask.getProcessDefinitionId();
        //获取流程模型
        BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
//        String myActivityId = null;
        //查询已经完成的流程节点,查询到上一条已完成的节点,则跳出循环
//        List<HistoricActivityInstance> haiList = historyService.createHistoricActivityInstanceQuery()
//                .executionId(myTask.getExecutionId())
//                .finished()
//                .orderByHistoricActivityInstanceStartTime()
//                .desc()
//                .list();
//        System.out.println("---------------the latest finished---------------"+haiList.get(0));
//        myActivityId = haiList.get(0).getActivityId();
        //想要回退到的节点位置
        System.out.println(tarActivityId);
        FlowNode myFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(tarActivityId);
        //原本的活动方向
        Execution execution = runtimeService.createExecutionQuery().executionId(task.getExecutionId()).singleResult();
        String activityId = execution.getActivityId();
        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"+" ROLLBACK: "+nowtime());
        //新方向的源头---当前节点
        newSequenceFlow.setSourceFlowElement(flowNode);
        System.out.println("--------------new flow-----------------"+flowNode);
        //新方向的目标---要回退的节点
        System.out.println("--------------target flow-----------------"+myFlowNode);
        newSequenceFlow.setTargetFlowElement(myFlowNode);
        newSequenceFlowList.add(newSequenceFlow);
        flowNode.setOutgoingFlows(newSequenceFlowList);

        Authentication.setAuthenticatedUserId(nowUserId);
        taskService.addComment(task.getId(), task.getProcessInstanceId(), "回退");
        //完成任务
        System.out.println("========================完成任务====================");
        taskService.complete(task.getId());

        //恢复原方向
        flowNode.setOutgoingFlows(oriSequenceFlows);
        System.out.println("------------------RollBack successfully!!----------------------------");
        logger.info("退回成功!");
        //将退回完成后的当前节点的task返回
//        HistoricActivityInstance historicActivityInstance = historyService.createHistoricActivityInstanceQuery().activityId(tarActivityId).singleResult();
//
//        return historicActivityInstance.getTaskId();
    }
相关推荐
装不满的克莱因瓶27 分钟前
【Redis经典面试题六】Redis的持久化机制是怎样的?
java·数据库·redis·持久化·aof·rdb
n北斗34 分钟前
常用类晨考day15
java
骇客野人38 分钟前
【JAVA】JAVA接口公共返回体ResponseData封装
java·开发语言
yuanbenshidiaos2 小时前
c++---------数据类型
java·jvm·c++
向宇it2 小时前
【从零开始入门unity游戏开发之——C#篇25】C#面向对象动态多态——virtual、override 和 base 关键字、抽象类和抽象方法
java·开发语言·unity·c#·游戏引擎
Lojarro2 小时前
【Spring】Spring框架之-AOP
java·mysql·spring
莫名其妙小饼干2 小时前
网上球鞋竞拍系统|Java|SSM|VUE| 前后端分离
java·开发语言·maven·mssql
isolusion2 小时前
Springboot的创建方式
java·spring boot·后端
zjw_rp3 小时前
Spring-AOP
java·后端·spring·spring-aop
Oneforlove_twoforjob3 小时前
【Java基础面试题033】Java泛型的作用是什么?
java·开发语言