主要分为一下几个步骤:

  1.画图

  2.部署流程-把图的信息转入到数据表格中

  3.创建流程实例-开始一个流程-实际发起了一个流程

  4.执行任务:获取任务+完成任务

1.画图

  画了一个简单的流程图,图形文件名称是:qj01.bpmn   id:myProcess_1

     流程: 请假(qingjia)--->审批(shenpi)--->结束

 

  

 

指定了这一步骤的名称和执行人   Assignee:dcc  执行人时dcc

 

 

指定了第二步的名称和执行人  Assignee:jcc  执行人时jcc

 

 2.部署流程

2.1方法1

  (本地测试可以用下,实际项目不使用)

  private ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

    //流程定义
    @Test
    public void deploy(){
        RepositoryService repositoryService = processEngine.getRepositoryService();
        Deployment de = repositoryService.createDeployment().addClasspathResource("bpmn/qj01.bpmn").name("qj").deploy();  //这里name里面传入中文,到act_re_deployment表可能出现乱码
        System.out.println("部署id"+de.getId());

        /*
        流程定义:
        流程部署表 re_deployment
        流程定义表 re_procdef
        资源信息表 ge_bytearray
        */
    }

 addClasspathResource("bpmn/qj01.bpmn"),这里文件是bpmn图形文件的路径

执行,在数据库中查看,影响到3张数据表格:流程部署表 re_deployment  流程定义表 re_procdef  资源信息表 ge_bytearray

 

2.2方法2:上传压缩文件的方式

2.2.1第一步:把bpmnt图形文件压缩成zip文件

 

  

 

2.2.2编码

  这里我省略了上传zip文件的过程,直接从本地读取的


@Test
public void deploy2() throws FileNotFoundException {
    RepositoryService repositoryService = processEngine.getRepositoryService();
    InputStream in = new FileInputStream("C:\\Users\\Administrator\\IdeaProjects\\jsnhcopy\\src\\main\\resources\\bpmn\\qj01.zip"); //zip文件路径
    ZipInputStream zipInputStream = new ZipInputStream(in);
    Deployment deploy = repositoryService.createDeployment().addZipInputStream(zipInputStream).name("qjlc").deploy();

    System.out.println("部署id"+deploy.getId());

    /*
    流程定义:
    流程部署表 re_deployment
    流程定义表 re_procdef
    资源信息表 ge_bytearray
    */
}

2.3中文乱码问题
  
存在中文的时候,出现乱码,尝试了各种方法,都没有生效
    1)idea安装目录下两个文件加入配置:-Dfile.encoding=UTF-8,没有用
    

  

 

     2)配置idea,无效

      file-setting-editor-fileencoding

  

 

     3)pom文件加入配置,无效

  <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <spring.version>4.1.4.RELEASE</spring.version>
    </properties>
      <plugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-compiler-plugin</artifactId>
              <version>3.1</version>
              <configuration>
                        <source>1.8</source>
                        <target>1.8</target>
                        <encoding>UTF-8</encoding>
            </configuration>
          </plugin>

   最后没有办法,只能不用中文

 

3.创建流程实例-启动流程

  //启动流程实例
    @Test
    public void run(){
        RuntimeService runtimeService = processEngine.getRuntimeService();
        ProcessInstance myProcess_1 = runtimeService.startProcessInstanceByKey("myProcess_1");//表re_procdef里面的key字段

        System.out.println("实例id"+myProcess_1.getId());
        System.out.println("流程定义id"+myProcess_1.getProcessDefinitionId());

        /*
        启动流程实例
            运行时任务表:ru_task
            运行时流程执行表:ru_execution
            运行时执行主体信息表:ru_identitylink
        */
    }

其中 myProcess_1的值是有图形的id决定的。会成为表act_re_procdef里面的KEY_的值,这个属性用来标识流程。相同的KEY_的流程表示同一流程的不同版本。默认启动的是同一流程的最新版本

 

执行,影响到三张表 运行时任务表:ru_task   运行时流程执行表:ru_execution   运行时执行主体信息表:ru_identitylink,此时一个流程被发起,有了任务act_ru_task  

除了使用KEY_来创建流程实例,还可以通过流程的id等其它属性来创建流程实例 runtimeService.startProcessInstanceById(1)

 

4.执行任务

4.1获取任务

    @Test
    public void findtask(){
        //获取任务
        TaskService taskService = processEngine.getTaskService();
        List<Task> task_list = taskService.createTaskQuery().taskAssignee("dcc").list();//查询dcc的任务
        task_list.stream().forEach((x)->{
            System.out.println("任务id"+x.getId());
            System.out.println("任务名称"+x.getName());
        });

这里是通过任务执行人来获取的任务,获取的是dcc的任务。这里获取到id为25005的任务

 

4.2完成任务

   @Test
    public void complete() {

        TaskService taskService = processEngine.getTaskService();
        taskService.complete("25005");
        System.out.println("完成任务");

           /*
                任务id2505
                完成任务id2505
                */
               /*
               完成任务:
                    ru的几张表的数据清楚了
                    历史相关表:
              历史任务表:hi_taskinst
                历史流程实例表:hi_procinst
                历史流程参与者表:hi_identitylink
                历史活动节点表:hi_actinst */ }

  这里通过任务id来完成任务

  在完成了这个任务后,流程就走到了审批流程,表中ru_task表中id为25005任务没有了,出现了一个新的任务-审批

 

   上面执行,完成了第一个步骤-请假,再依照上面,获取任务-完成任务,完成第二个步骤-审批,整个流程就走完了。

   流程走完后,此时act_ru_的几张表的数据会清空,历史信息进入历史表,涉及到一下四张表

        历史任务表:hi_taskinst
          历史流程实例表:hi_procinst
           历史流程参与者表:hi_identitylink
           历史活动节点表:hi_actinst

  

 5.流程的CRUD

5.1新增

  新增一个流程也就是流程部署,也就是上面标题2的内容

5.2修改

  流程本身是不能修改的。只能通过发布新的版本的流程来实现。

  

   这个属性,也就是表act_re_procdef的KEY_属性值,相同表示同一流程,版本号增加。

  如下图,我共画了3张图,重复发布,总共发布了7次,但是没修改id,流程的KEY_是相同的,都是"myProcess_1",所以KEY_值相同,版本号增加。如果此时通过KEY_来创建流程实例,默认是创建的最新版本的流程实例。

 

5.3删除

   不建议删除

5.4查询

  可以通过多个条件去查询KEy_ 、id等

 

   @Test
    public void query(){
     ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); ProcessDefinitionQuery processDefinitionQuery = processEngine.getRepositoryService().createProcessDefinitionQuery(); List<ProcessDefinition> myProcess_1 = processDefinitionQuery.processDefinitionKey("myProcess_1").list(); if(!myProcess_1.isEmpty()){ myProcess_1.stream().forEach(x->{ System.out.println(x.getKey()); System.out.println(x.getId()); }); } }

 

6.历史的查询

6.1查询历史任务

  可以通过多种条件查询 id、时间等

 

  @Test
    public void queryHi(){
        HistoricTaskInstanceQuery historicTaskInstanceQuery = processEngine.getHistoryService().createHistoricTaskInstanceQuery();
        List<HistoricTaskInstance> myProcess_11 = historicTaskInstanceQuery.processDefinitionKey("myProcess_1").list();

        if(!myProcess_11.isEmpty()){
            myProcess_11.stream().forEach(x->{
                System.out.println(x.getName());
                System.out.println(x.getId());
            });
        }
    }

 

7.查询流程实例

  可以通过多个条件查询,KEY_、id、name等

 

@Test
    public void queryDeployVo(){
        ProcessInstanceQuery processInstanceQuery = processEngine.getRuntimeService().createProcessInstanceQuery();
        List<ProcessInstance> myProcess_1 = processInstanceQuery.processDefinitionKey("myProcess_1").list();

        if(!myProcess_1.isEmpty()){
            myProcess_1.stream().forEach(x->{
                System.out.println(x.getName());
                System.out.println(x.getId());
            });
        }
    }

 

8.流程中的参数传递

8.1基本说明

  这里的参数是指创建流程实例-执行任务中的参数传递。支持的数据类型包括基本数据类型、序列化对象

   参数分为两类:任务节点本地变量和全局流程实例变量,前者在流程的指定节点有效,后者整个流程实例过程有效,一般使用后面的

8.2实例

8.2.1流程图

 

 

 8.2.2部署流程

  @Test
    public void deploy(){
        RepositoryService repositoryService = processEngine.getRepositoryService();
        Deployment de = repositoryService.createDeployment().addClasspathResource("bpmn/qj01.bpmn").name("qj").deploy();

    }

 

8.2.3启动一个流程实例并传递参数

    @Test
    public void run(){
        RuntimeService runtimeService = processEngine.getRuntimeService();
        Map<String,Object> pa = new HashMap<>();
        pa.put("start","qidong");
        ProcessInstance myProcess_1 = runtimeService.startProcessInstanceByKey("myid2",pa);//表re_procdef里面的key字段

    }

这里传递了一个名为start的参数

 

8.2.4执行任务

先创建一个对象PoTe,序列化,这样子就可以作为参数传递

public class PoTe implements Serializable {  //需要序列化

    private String username;

    private String password;

    public PoTe() {
    }

    public PoTe(String username, String password) {
        this.username = username;
        this.password = password;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "PoTe{" +
                "username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

  执行请假任务

@Test
    public void complete() {

        TaskService taskService = processEngine.getTaskService();

        Object start = taskService.getVariable("40006", "start");
        System.out.println("启动变量"+start);  //启动变量qidong

        taskService.setVariable("40006","username","hahaha");
        taskService.setVariable("40006","password","123");
        taskService.setVariable("40006","po",new PoTe("hahaha","123"));
        /*
        Map<String,Object> pa = new HashMap<>();
        pa.put("username","hahaha");
        pa.put("password","123");
        pa.put("po",new PoTe("hahaha","123"));
        taskService.setVariables("25005",pa);
        */

        taskService.complete("40006");
        System.out.println("完成任务");

    }

  获取到了前面添加的名称为start的变量。并且又添加了三个变量

  执行审批任务

    @Test
    public void complete2() {

        TaskService taskService = processEngine.getTaskService();

        String username = taskService.getVariable("42507", "username", String.class);
        String password = taskService.getVariable("42507", "password", String.class);
        String start = taskService.getVariable("42507", "start", String.class);
        PoTe po = taskService.getVariable("42507", "po", PoTe.class);
        System.out.println(username);  //hahaha
        System.out.println(password);  //123
        System.out.println(start);  //qidong
        System.out.println(po);  //PoTe{username='hahaha', password='123'}
        Map<String, VariableInstance> variableInstances = taskService.getVariableInstances("42507");
        variableInstances.keySet().stream().forEach(x->{
            VariableInstance variableInstance = variableInstances.get(x);
            System.out.println(variableInstance.toString());
            //VariableInstanceEntity[id=42502, name=password, type=string, textValue=123]
            //VariableInstanceEntity[id=40002, name=start, type=string, textValue=qidong]
            //VariableInstanceEntity[id=42501, name=username, type=string, textValue=hahaha]
            //VariableInstanceEntity[id=42504, name=po, type=serializable, byteArrayValueId=42503]
        });
        taskService.complete("42507");
        System.out.println("完成任务 42507");

    }

  这里获取到了start等4个参数。流程结束。

 

9.流程不同的分支走向-连线中的表达式

9.1画图

图的文件名:qj02.bpmn    图的id:myid3  

 

这里的流程是:

    请假(qjia)--->部门审批(shenpi)--->天数小于等于5->流程结束

                                     --->天数大于5->领导审批(shenpi2)->流程结束

 

  

 

 在这条连线设置了条件表达式:days>5

 

 

 这里连线添加了条件:day<=5

 

9.2部署流程

   //流程定义
    @Test
    public void deploy(){
        RepositoryService repositoryService = processEngine.getRepositoryService();
        Deployment de = repositoryService.createDeployment().addClasspathResource("bpmn/qj02.bpmn").name("qj").deploy();
        System.out.println("部署id"+de.getId());

    }

 

9.3创建流程实例

 @Test
    public void run(){
        RuntimeService runtimeService = processEngine.getRuntimeService();
        Map<String,Object> pa = new HashMap<>();
        pa.put("start","qidong");

        ProcessInstance myProcess_1 = runtimeService.startProcessInstanceByKey("myid3",pa);//表re_procdef里面的key字段

        System.out.println("实例id"+myProcess_1.getId());
        System.out.println("流程定义id"+myProcess_1.getProcessDefinitionId());

    }

 

9.4.执行任务

9.4.1第一个任务-请假

此时任务表,有一个任务,id为67507,执行人时dcc,也就是请假这一步

 执行任务

    @Test
    public void complete() {

          TaskService taskService = processEngine.getTaskService();
      taskService.setVariable("67507","days",3);
      taskService.complete("67507"); System.out.println("完成任务");
}

注意,这里传递了一个参数days为3

 

9.4.2第二个任务-部门审批

上面任务执行完成后,再看任务表。有一个任务,id为70002,执行人为jcc,也就是走到了第一个审批

 

 @Test
    public void complete2() {
        TaskService taskService = processEngine.getTaskService();
        taskService.complete("70002");
    }

执行任务,执行完成后,发现任务表为空,整个流程完成了,因为day为3,所以没有走第二个审批

 

下面我们把days换做6

 

9.5创建流程实例

 

    @Test
    public void run(){
        RuntimeService runtimeService = processEngine.getRuntimeService();
        Map<String,Object> pa = new HashMap<>();
        pa.put("start","qidong");
        ProcessInstance myProcess_1 = runtimeService.startProcessInstanceByKey("myid3",pa);//表re_procdef里面的key字段
    }

 

9.6执行任务

9.6.1第一个任务-请假

  任务表有一个任务,id为75007,执行人为dcc,也就是第一步-请假

 

   @Test
    public void complete() {
        TaskService taskService = processEngine.getTaskService();
        taskService.setVariable("85006","days",6);
        taskService.complete("85006");
        System.out.println("完成任务");
    }

注意,这里传递的days的参数是6

9.6.2第二个任务-部门审批

 

 @Test
    public void complete2() {
        TaskService taskService = processEngine.getTaskService();
        taskService.complete("87503");
        System.out.println("完成任务");
    }

 

9.6.3第三个任务-领导审批

 

 

    @Test
    public void complete2() {
        TaskService taskService = processEngine.getTaskService();
        taskService.complete("90002");
        System.out.println("完成任务");
    }

执行后,任务表没有任务了,流程走完了

 

10条件表达式

activiti支持两个UEL表达式:UEL-value和UEL-method

 

11.网关

 

11.1排他网关

  几条不同的线,只走其中一条线

 

11.1.1画图

  图形名称:qj03.bpmn  图形id:myid4

  流程: 请假(qjia)--->请假天数<=5天--->部门审批(shenpi)--->结束

          --->请假天数>5天--->领导审批(shenpi2)--->结束

 

 

 

 

 

 

 11.1.2代码测试

  和上面的代码差不多,我这里就不贴出来了。先测试3天,再测试6天。发现3天时,是部门审批,6天时,是领导审批

 

11.2并行网关

  并行网关是指,几条线都需要执行通过,才能往下走

 

11.2.1画图

图名:qj04.bpmn  id:myid6

流程:  请假(qjia)--->部门审批(shenpi1)+领导审批(shenpi2)--->老板审批(shenpi3)--->结束

这里部门审批和领导审批都需要审批,这里就没有设计条件表达式了,因为都要去审批

 

11.2.1部署流程

   @Test
    public void deploy(){
        RepositoryService repositoryService = processEngine.getRepositoryService();
        Deployment de = repositoryService.createDeployment().addClasspathResource("bpmn/qj04.bpmn").name("qj").deploy();
        System.out.println("部署id"+de.getId());
    }

 

11.2.2创建流程实例

    @Test
    public void run(){
        RuntimeService runtimeService = processEngine.getRuntimeService();
        Map<String,Object> pa = new HashMap<>();
        ProcessInstance myProcess_1 = runtimeService.startProcessInstanceByKey("myid6",pa);//表re_procdef里面的key字段
    }

 

11.2.3执行任务

11.2.3.1第一步任务-请假

 有一个任务 请假(qjia)

执行任务

    @Test
    public void complete2() {
        TaskService taskService = processEngine.getTaskService();
        taskService.complete("107505");
        System.out.println("完成任务");
    }

11.2.3.2第二步-部门审批(shenpi)+领导审批(shenpi2)

  上面完成后,任务里面有两个,分别是部门审批(shenpi)和领导审批(shenpi2)

 先执行一个审批,随便先执行哪一个都可以

    @Test
    public void complete2() {
        TaskService taskService = processEngine.getTaskService();
        taskService.complete("110004");
        System.out.println("完成任务");
    }

一个审批完成后,发现第三步审批任务还没有,任务里面还剩下一个领导审批

 继续执行领导审批

   @Test
    public void complete2() {
        TaskService taskService = processEngine.getTaskService();
        taskService.complete("110007");
        System.out.println("完成任务");
}

11.2.3.3第三步-老板审批(shenpi3)

上面2个审批都执行完后,任务里面出现了老板审批(shenpi3)的任务

 执行

   @Test
    public void complete2() {
        TaskService taskService = processEngine.getTaskService();
        taskService.complete("115003");
        System.out.println("完成任务");
    }

执行完成后,没有任务了,流程执行完

12.任务分配

  前面我们画图的时候,每一步任务由谁执行,都是固定写死的,现在我们使用表达式

   写死的:

    

   表达式:

    

 

12.1画图

  图形bpmn文件名称:qj05.bpmn  id:myid11

  流程:员工(employee)请假--->部门领导审批(leader)--->结束

 

 

 

 

 

 12.2部署流程

  //流程定义
    @Test
    public void deploy(){
        RepositoryService repositoryService = processEngine.getRepositoryService();
        Deployment de = repositoryService.createDeployment().addClasspathResource("bpmn/qj05.bpmn").name("qj").deploy();
        System.out.println("部署id"+de.getId());
}

12.3启动流程实例

    //启动流程实例
    @Test
    public void run(){
        RuntimeService runtimeService = processEngine.getRuntimeService();
        Map<String,Object> pa = new HashMap<>();
        pa.put("employee","ddd");
        ProcessInstance myProcess_1 = runtimeService.startProcessInstanceByKey("myid10",pa);//表re_procdef里面的key字段
    }

启动流程的时候,设置哪些人可以请假,这里设置ddd可以请假

此时有任务,执行人就是ddd

 

12.4执行任务

12.4.1第一步-请假

ddd可以获取到任务,并执行

获取

   @Test
    public void findtask(){
        //获取任务
        TaskService taskService = processEngine.getTaskService();
        List<Task> task_list = taskService.createTaskQuery().taskAssignee("ddd").list();//查询dcc的任务
    }
    

执行,执行时指定由谁来审批,这里指定的是jjj

  @Test
    public void complete() {
        TaskService taskService = processEngine.getTaskService();
        taskService.setVariable("150006","leader","jjj");
        taskService.complete("150006");
        System.out.println("完成任务");
    }

 

12.4.2第二步-审批

  jjj获取任务并执行

 @Test
    public void findtask(){
        //获取任务
        TaskService taskService = processEngine.getTaskService();
        List<Task> task_list = taskService.createTaskQuery().taskAssignee("jjj").list();//查询dcc的任务
    }

执行

 @Test
    public void complete() {
        TaskService taskService = processEngine.getTaskService();
        taskService.setVariable("152503","leader","jjj");
        taskService.complete("152503");
        System.out.println("完成任务");
    }

流程走完了,任务没有了