zoukankan      html  css  js  c++  java
  • JBPM工作流(五)——执行流程实例

    概念:

    ProcessInstance,流程实例:代表流程定义的一次执行.如:张三昨天按请假流程请了一次假.一个流程实例包括了所有运行阶段,其中最典型的属性就是跟踪当前节点的指针,如下图。

     

    Execution,执行:一般情况下,一个流程实例是一个执行树的根节点。 

    使用树状结构的原因在于, 这一概念只有一条执行路径, 使用起来更简单。业务API不需要了解流程实例和执行之间功能的区别。因此,API里只有一个执行类型来引用流程实例和执行。

    假设汇款和存档可以同时执行,那么主流程实例就包含了2个用来跟踪状态的子节点:

     

    总的来说:

    ProcessInstance(流程实例)就是Execution(执行对象),processInstanceId就是executionId。

     在源码中,ProcessInstance接口直接继承了Execution接口。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    package org.jbpm.api;
     
     
    /** a process instance is one execution of a process definition.
     * One process instance can have many concurrent executions. 
     * Executions are structured in a tree of which the ProcessInstance
     * is the root.
     *
     * @author Tom Baeyens
     */
    public interface ProcessInstance extends Execution {
    }

      

    注释大概意思为:

    一个流程实例是一个流程定义的执行。

    一个流程实例可以有多个同时进行的执行对象。

    执行对象构成了一棵树,而流程实例是这棵树的根结点。

    1.启动流程实例

    a) 普通方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    // 启动流程实例
        // jbpm4_execution,正在执行的信息表
        // jbpm4_hist_procinst,历史信息表
        @Test
        public void startProcessInstance() {
            // 使用指定key的最新版本的流程定义启动流程实例,返回一个实例流程对象
            ProcessInstance pi = processEngine.getExecutionService().startProcessInstanceByKey("test");
     
            System.out.println("id=" + pi.getId()//
                    + ", state=" + pi.getState()//
                    + ", processDefinitionId=" + pi.getProcessDefinitionId());
        }

      b) 启动流程实例,并设置一些流程变量

    1
    2
    3
    4
    5
    6
    Map<String, Object> variables = new HashMap<String, Object>();
        variables.put("申请人", "张三");
        variables.put("报销金额", 1000.00);
          
        // 启动流程实例,并设置一些流程变量
        ProcessInstance pi = processEngine.getExecutionService().startProcessInstanceByKey(processDefinitionKey, variables);

      

    2.向后执行一步(Signal)

    a) 向后执行一步,使用唯一的outcome离开活动

    1
    processEngine.getExecutionService().signalExecutionById(executionId);

      b) 向后执行一步,使用唯一的outcome离开活动,并设置一些流程变量

    1
    2
    3
    4
    // 准备流程变量
        Map<String, Object> variables = new HashMap<String, Object>();
        variables.put("审批结果", "同意");
        processEngine.getExecutionService().signalExecutionById(executionId, variables);

      c) 向后执行一步,使用指定的outcome离开活动

    1
    2
    String outcome= "to end1";
        processEngine.getExecutionService().signalExecutionById(executionId, outcome);

      d) 向后执行一步,使用指定的outcome离开活动,并设置一些流程变量

    1
    2
    3
    4
    String outcome= "to end1";
        Map<String, Object> variables = new HashMap<String, Object>();
        variables.put("审批结果", "同意");
        processEngine.getExecutionService().signalExecutionById(executionId, outcome, variables);

      

    3.查询任务

    a) 查询个人任务列表

    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
    27
    28
    // 查询我的未办理完的任务列表
        // jbpm4_task,正在执行的信息表
        // jbpm4_hist_task,历史信息表
        @Test
        public void findMyTaskList() {
            String userId = "员工";
            //String userId = "部门经理";
            //String userId = "总经理";
     
            // 方式1.查询我所有未办理的任务的列表
            // List<Task> list = processEngine.getTaskService().findPersonalTasks(userId);
            // 方式2.分页的查询
            List<Task> list = processEngine.getTaskService()//
                    .createTaskQuery()//
                    .assignee(userId)//
                    .page(0, 100)
                    .list();
     
            // 显示
            System.out.println("============== 【" + userId + "】的未办理的任务列表 =============");
            for (Task t : list) {
                System.out.println("id=" + t.getId()//
                        + ", name=" + t.getName()// 任务的名称
                        + ", assignee=" + t.getAssignee()// 任务的办理人
                        + ", createTime=" + t.getCreateTime()// 任务的创建时间
                        + ", executionId=" + t.getExecutionId()); // 所属的执行对象的id
            }
        }

      

    b) 查询组任务列表

    方式1:

    1
    taskService.findGroupTasks(userId);

      方式2: 

    1
    2
    3
    4
    List<Task> list = processEngine.getTaskService()// 
                 .createTaskQuery()// 
                 .candidate(userId)// 
                 .list(); 

      

    4.办理任务

    a) 正常完成任务

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    @Test
        public void completeTask() {
            String taskId = "180009";
            //普通的方法
            processEngine.getTaskService().completeTask(taskId);
            //指定下一步的方法
            processEngine.getTaskService().completeTask(taskId, outcome);
            //设置流程变量的方法
            processEngine.getTaskService().completeTask(taskId, outcome, variables);
        }

      b) 自行控制完成任务后是否向后流转(少用)

    1
    2
    3
    4
    5
    6
    String taskId = "120001";
        // 1,设置为false代表:办理完任务后不向后移动(默认为true)
        TaskImpl taskImpl = (TaskImpl) processEngine.getTaskService().getTask(taskId);
        taskImpl.setSignalling(false);
        // 2,办理完任务
        processEngine.getTaskService().completeTask(taskId);

      

    5.拾取任务(少用)

    a) TaskService.takeTask(taskId, userId),拾取组任务到个人任务列表中,如果任务有assignee,则会抛异常。

    b) processEngine.getTaskService().assignTask(taskId, userId),转交任务给其他人,(如果任务有assignee,则执行这个方法代表重新分配。也可以把assignee设为null表示组任务没有人办理了)

    6.设置与获取流程变量

    a) 方式1:根据 executionId 设置或获取流程变量

    1
    2
    ExecutionService.setVariable(executionId, name, value);
        Object obj = executionService.getVariable(executionId, "请假人");

      b) 方式2:根据 taskId 设置或获取流程变量

    1
    2
    TaskService.setVariables(taskId, variables); // 一次设置多个变量
        Object obj = executionService.getVariable(executionId, "请假人");

      7.直接结束流程实例(手工)

    1
    2
    String processInstanceId =  "test.10001";
        processEngine.getExecutionService().endProcessInstance(processInstanceId, ProcessInstance.STATE_ENDED);
  • 相关阅读:
    初试Shell脚本
    iOS分类Category探索
    cocoaPods安装爬坑总结
    关于FFmpeg工具的使用总结
    关于Boost在工程下的配置
    关于Phabricator Arcanist以及提交项目代码
    关于visual studio的一些日常总结
    关于Python在Linux、Mac和Windows上的安装方法总结
    TextSwitcher 文本切换器的功能与用法
    Android必知必会-App 常用图标尺寸规范汇总
  • 原文地址:https://www.cnblogs.com/HHR-SUN/p/7235820.html
Copyright © 2011-2022 走看看