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();
    }
相关推荐
2402_857589367 分钟前
SpringBoot框架:作业管理技术新解
java·spring boot·后端
HBryce2411 分钟前
缓存-基础概念
java·缓存
一只爱打拳的程序猿26 分钟前
【Spring】更加简单的将对象存入Spring中并使用
java·后端·spring
杨荧27 分钟前
【JAVA毕业设计】基于Vue和SpringBoot的服装商城系统学科竞赛管理系统
java·开发语言·vue.js·spring boot·spring cloud·java-ee·kafka
minDuck29 分钟前
ruoyi-vue集成tianai-captcha验证码
java·前端·vue.js
为将者,自当识天晓地。1 小时前
c++多线程
java·开发语言
daqinzl1 小时前
java获取机器ip、mac
java·mac·ip
激流丶1 小时前
【Kafka 实战】如何解决Kafka Topic数量过多带来的性能问题?
java·大数据·kafka·topic
Themberfue1 小时前
Java多线程详解⑤(全程干货!!!)线程安全问题 || 锁 || synchronized
java·开发语言·线程·多线程·synchronized·