• Activiti——流程的挂起与激活


    前言

    在一般的金融业务系统中,通常会有一个类似的场景。

    在某个月的21号,财务需要针对公司或企业的金额进行一个做账的操作。
    在做账的时候,不允许进行业务的审批处理操作,这些流程必须要进行暂停。
    在做账完成后,需要恢复相应的业务操作,可以供操作者继续使用。

    前面博客中也说到了工作流的部署、扭转、删除等操作方式。工作流的删除的确可以实现上面的业务需求,但是有一点,删除后工作流会被删除,如果需要唤醒并继续使用则会不行。

    为了解决这些类似的问题,在activiti 中,提供有专门的流程暂停(挂起)激活操作。

    针对已部署的流程模板 RepositoryService

    流程挂起

    先写一个简单的例子,实现工作流的挂起。

    一经挂起操作,工作流将不允许继续执行审批扭转等操作。

    @Test
    public void suspend(){
        ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();
        RepositoryService repositoryService = defaultProcessEngine.getRepositoryService();
        // 查询流程定义
        ProcessDefinition singleResult = repositoryService.createProcessDefinitionQuery()
                .processDefinitionKey("demo01")
                .singleResult();
        // 判断是否被挂起  如果被挂起 则让其激活;激活 则进行挂起操作
        boolean suspended = singleResult.isSuspended();
        System.out.println("singleResult.getId()==== "+singleResult.getId());
        if(!suspended){
            /**
             * 激活  需要进行挂起操作
             * 参数一:流程定义id
             * 参数二:是否暂停
             * 参数三:暂停时间
             */
            repositoryService.suspendProcessDefinitionById(singleResult.getId(),
                    true,
                    null);
            System.out.println("流程已挂起");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    文件部署成功后,再进行启动操作,此时的流程实例必然是激活状态,所以上面的代码在执行后,会进入挂起操作流程中。测试运行并查看控制台打印信息。
    在这里插入图片描述
    挂起操作执行成功,表示当前该部署的流程的所有流程实例都将会不能执行。为了验证是否可以操作,再次执行以下流程的状态扭转方法。

    任务状态的推进与状态的扭转,需要知道对应的任务id信息。所以需要先查询任务信息,再进行提交扭转。

    /**
     * 查询当前个人待执行的任务
     */
    @Test
    public void viewReDoTask(){
        // 工作流从启动开始  就会流转至 第一个 UserTask 节点,
        // 此时可以通过配置的 Assignee 查询指定的人的  一些待处理 任务信息
        String assignee = "worker";
        // 数据库连接配置操作
        ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();
        // 根据对应的流程 查询当前指定人的待处理任务信息
        TaskService taskService = defaultProcessEngine.getTaskService();
        List<Task> list = taskService.createTaskQuery()
                .processDefinitionKey("demo01") // 指定哪个流程图模板
                .taskAssignee(assignee) // 指定是谁负责待处理的任务
                .list();
        if(!CollectionUtil.isEmpty(list)){
            list.forEach(x->{
                System.out.println("流程实例 id "+x.getProcessInstanceId());
                System.out.println("任务 id "+x.getId());
                System.out.println("任务负责人 "+x.getAssignee());
                System.out.println("任务名称 "+x.getName());
                System.out.println("===========================================");
            });
        }
    }
    
    • 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

    在这里插入图片描述
    再次执行扭转操作,如果扭转失败,则表示activiti能够很好地控制挂起操作。

    /**
     * 工作流的节点与状态的扭转
     */
    @Test
    public void doTask(){
        // 获取数据库的连接信息
        ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();
        TaskService taskService = defaultProcessEngine.getTaskService();
    
        // 完成当前节点的任务  并向下推进
        String taskId = "2505";
        taskService.complete(taskId);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    在这里插入图片描述

    流程激活

    上面的代码逻辑成功地将流程进行了挂起操作,后续某一天财务统计资金完成,需要开放给操作者继续使用。

    @Test
    public void actProcess(){
        ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();
        RepositoryService repositoryService = defaultProcessEngine.getRepositoryService();
        // 查询流程定义
        ProcessDefinition singleResult = repositoryService.createProcessDefinitionQuery()
                .processDefinitionKey("demo01")
                .singleResult();
        // 判断是否被挂起  如果被挂起 则让其激活;激活 则进行挂起操作
        boolean suspended = singleResult.isSuspended();
        System.out.println("singleResult.getId()==== "+singleResult.getId());
        if(suspended){
            /**
             * 挂起  进行激活操作
             * 参数一:流程定义id
             * 参数二:是否激活
             * 参数三:激活时间
             */
            repositoryService.activateProcessDefinitionById(singleResult.getId(),
                    true,
                    null);
            System.out.println("流程激活成功");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    执行上述的代码,查看控制台日期信息。
    在这里插入图片描述
    再次进行流程的审批扭转操作,查看任务是否能够再次进行推进操作。
    在这里插入图片描述

    未出现报错信息,表示当前的流程得到了激活,并能继续进行工作流的审批操作了!

    针对单个流程 RuntimeService

    上面的案例中,是依据已部署的流程模板,同时暂停全部的对应实例与激活操作。但如果业务中出现需要针对某一个申请做暂停,其他流程实例依据进行审批流程,那么上面的方式则不能很好的去实现。

    比如:张三的请假流程申请,需要做暂停;但其他李四、王五等人的请假流程不需要做管控等。

    比如针对当前的审批模板,开启了两个流程实例。

    select * from act_ru_execution;

    在这里插入图片描述
    当然,也可以用代码查询,如下:
    在这里插入图片描述
    2501流程已经被woeker做了扭转,此时在manager节点上;7501只是才开始流程,需要worker角色去处理。

    如何只对2501限制审批流程处理,但7501能够正常执行呢?下面看代码。

    /**
     * 指定流程实例的暂停与激活
     */
    @Test
    public void oneSuppendAndAct(){
        // 获取数据库的连接信息
        ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();
        RuntimeService runtimeService = defaultProcessEngine.getRuntimeService();
        ProcessInstance singleResult = runtimeService.createProcessInstanceQuery()
                .processInstanceId("2501")
                .singleResult();
        // 当前实例流程对象是都被暂停
        boolean suspended = singleResult.isSuspended();
        // 流程定义id
        String id = singleResult.getId();
        if(suspended){
            // 被暂停  则进行激活操作
            runtimeService.activateProcessInstanceById(id);
            System.out.println("流程定义:"+id+",已激活");
        }else{
            // 是激活状态  则进行暂停
            runtimeService.suspendProcessInstanceById(id);
            System.out.println("流程定义:"+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

    最开始2501是正常的,并且已经被worker进行了处理。执行上述的代码逻辑后,因为监测到是激活状态,所以执行了挂起。

    按道理来说,2501进行了挂起,但必须要求同部署模板下的其他流程实例能够正常执行。

    现在执行7501的流程推进,查看效果。
    在这里插入图片描述
    执行推进操作。
    在这里插入图片描述
    没有报错,查看当前流程信息。
    在这里插入图片描述
    推进是成功的,最新状态已经到了部门经理审批


    现在再来验证2501是否能够被推进。
    在这里插入图片描述
    得到2501流程实例此时部门经理审批的任务id为5002。进行流程的推进操作。
    在这里插入图片描述
    【结论】
    流程能够对指定的实例对象进行管控!!

    2501实例对应的当前任务5002进行恢复激活操作,再次进行推进。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    【结论】
    激活后的指定实例对象,能够进行审批操作和状态的扭转。

  • 相关阅读:
    c++ 静态库,动态库的制作和使用
    Go语言 | 01 WSL+VSCode环境搭建必坑必看
    Nacos版本升级
    关于过滤器Filter
    中国多元醇行业发展态势良好 重点关注海外市场
    【Java基础知识 46】GET和POST的区别,java模拟postman发post请求
    OpenHD改造实现廉价高清数字图传(树莓派zero + ubuntu PC )—(三)OpenVG和libshapes在PC上的移植
    微信小程序电影票订票小程序软件设计与实现
    2010年09月06日 Go生态洞察:Go语言荣获2010年度Bossie奖
    【Leetcode打卡冲冲冲】
  • 原文地址:https://blog.csdn.net/qq_38322527/article/details/138166381