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();
    }
相关推荐
Full Stack Developme1 小时前
Java LRU 与 LFU 算法及应用
java·开发语言·算法
程序员老油条4 小时前
WSL2 + Docker Desktop:Windows 下的完美 Java 开发环境
java·windows·docker·wsl2
shushangyun_5 小时前
2026智能采购商城系统选型指南:如何引领企业数字化采购升级
java·大数据·数据库·人工智能·机器学习
她说..5 小时前
Java 默认值设置方式
java·开发语言·后端·springboot
学渣超5 小时前
记一次分布式事务数据不一致的排查之旅:从超时到索引,层层剥茧
java·后端·架构
掉鱼的猫5 小时前
Agent Harness 实战指南:构建生产级 AI Agent 的"马具"框架
java·llm·aigc
带刺的坐椅5 小时前
Agent Harness 实战指南:构建生产级 AI Agent 的"马具"框架
java·ai·llm·agent·solon-ai
c238565 小时前
互斥锁高频面试题全解:从基础概念到底层实现,一文通关
java·c++·面试·职场和发展
error:(6 小时前
【系统与实战双精通】VS Code 调试 ROS2 Python 节点与 Launch 系统指南
android·java·python
Tian_Hang7 小时前
Eclipse Ditto 的权限策略
java·服务器·前端·网络·ide·ubuntu·eclipse