最适合入门的Activiti工作流零基础教程

1.Activiti数据库表

1.1 数据表介绍

Activiti的数据表都以ACT_开头。

ACT_RE_: 'RE’表示repository。 这个前缀的表包含了流程定义和流程静态资源 (图片,规则,等等)。
ACT_RU_
:'RU’表示runtime。 这些运行时的表,包含流程实例,任务,变量,异步任务,等运行中的数据。
Activiti只在流程实例执行过程中保存这些数据, 在流程结束时就会删除这些记录。 这样运行时表可以一直很小速度很快
ACT_ID_: 'ID’表示identity。 这些表包含身份信息,比如用户,组等等。
ACT_HI_
: 'HI’表示history。这些表包含历史数据,比如历史流程实例, 变量,任务等等。 ACT_GE_*: 通用数据, 用于不同场景下,如存放资源文件。

1.2 创建数据库表+获得核心引擎

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
import org.activiti.engine.ProcessEngines;
import org.junit.Test;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class JunitTest {
    /**
     * 使用代码创建工作流需要的23张表
     * 硬编码数据库连接
     */
    @Test
    public void createTableOne() {
        ProcessEngineConfiguration processEngineConfiguration =
                ProcessEngineConfiguration.createStandaloneProcessEngineConfiguration()
                        .setJdbcDriver("com.mysql.jdbc.Driver")
                        .setJdbcUrl("jdbc:mysql://localhost:3306/activiti?useUnicode=true&characterEncoding=utf8")
                        .setJdbcUsername("root")
                        .setJdbcPassword("123456");
        /*
         * public static final
         * StringDB_SCHEMA_UPDATE_FALSE = "false"; * 不能自动创建表,需要表存在 public static final
         * StringDB_SCHEMA_UPDATE_CREATE_DROP * = "create-drop";先删除表再创建表 public static
         * final String * DB_SCHEMA_UPDATE_TRUE ="true";如果表不存在,自动创建表
         */
        processEngineConfiguration.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
        //工作流的核心对象,ProcessEngine对象
        ProcessEngine processEngine = processEngineConfiguration.buildProcessEngine();
        System.out.println("processEngine_1:" + processEngine);
    }

    /**
     * 使用activiti-cfg.xml或activiti-contect.xml配置文件创建数据库
     */
    @Test
    public void createTablesTwo() {
        String resource = "activiti.cfg.xml";// 配置文件名称
        String beanName = "processEngineConfiguration";// 配置id值
        ProcessEngineConfiguration configuration = ProcessEngineConfiguration
                .createProcessEngineConfigurationFromResource(resource, beanName);
        ProcessEngine processEngine = configuration.buildProcessEngine();
          System.out.println("processEngine_2:" + processEngine);
    }


    /**
     * 默认使用activiti-cfg.xml配置文件创建数据库
     */
    @Test
    public void createTablesThree() {
        ProcessEngineConfiguration configuration = ProcessEngineConfiguration
                .createProcessEngineConfigurationFromResourceDefault();
        ProcessEngine processEngine = configuration.buildProcessEngine();
        System.out.println("processEngine_3:" + processEngine);
    }


    /**
     * 默认使用activiti-cfg.xml配置文件创建数据库
     * <p>
     * This will look for an "activiti.cfg.xml" file on the classpath and construct an engine based on the configuration in that file. The following snippet shows an example configuration.
     * The following sections will give a detailed overview of the configuration properties.
     */
    @Test
    public void createTablesFour() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        System.out.println("processEngine_4:" + processEngine);
    }

    @Test
    public void updateTable(){
        ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createStandaloneProcessEngineConfiguration();
        configuration.setJdbcDriver("com.mysql.jdbc.Driver")
                .setJdbcUrl("jdbc:mysql://localhost:3306/activiti?useUnicode=true&characterEncoding=utf8")
                .setJdbcUsername("root")
                .setJdbcPassword("123456")
                .setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_CREATE_DROP);
        //创建引擎
        ProcessEngine processEngine = configuration.buildProcessEngine();
        System.out.println(processEngine);
    }

使用配置文件方式下配套的activiti.cfg.xml,以下仅为部分与数据库有关的代码

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
 	<!-- 配置 ProcessEngineConfiguration  -->
	 <bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
		   <!-- 配置数据库连接 -->
		 <property name="jdbcDriver" value="com.mysql.jdbc.Driver"></property>
		 <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/activiti?createDatabaseIfNotExist=true&amp;useUnicode=true&amp;characterEncoding=utf8"></property>
		 <property name="jdbcUsername" value="root"></property>
		 <property name="jdbcPassword" value="123456"></property>
		 
		  <!-- 配置创建表策略 :没有表时,自动创建 -->
		  <property name="databaseSchemaUpdate" value="true"></property>
	 </bean>
</beans>

2.流程的管理

类似于我们的关系型数据库中DML,用来定义数据库表的结构。

2.1数据库表

主要涉及到以下的4张表:

-- 流程部署相关的表
SELECT * FROM act_ge_bytearray # 通用字节资源表

SELECT * FROM act_ge_property # 通用属性表,可以生成部署id

SELECT * FROM act_re_deployment  #部署表

SELECT * FROM act_re_procdef    # 流程定义表

2.2定义工作流

定义工作流就需要我们刚才下载的插件了,我们是使用图形的方式来定义工作流的…

这里写图片描述

在每个流程中,我们都可以指定对应的处理人是谁,交由谁处理.

2.3部署工作流

    @Test
    public void deploy() {
        RepositoryService repositoryService = processEngine.getRepositoryService();
        repositoryService.createDeployment()
                .addClasspathResource("processes/TestProcess.bpmn")//加载bpmn文件
                .addClasspathResource("processes/TestProcess.png")//加载图片文件
                .name("请求单流程")//设置部署的名称
                .category("办公类别")//设置部署的类别
                .deploy();
    }

我们还可以加载的是ZIP类型的资源数据,就是将bpmn和png图片打包成zip文件,不能是rar格式。

//部署流程定义,资源来自zip格式
@Test
public void deployProcessDefiByZip(){
	//文件输入流读取资源文件
    InputStream in=getClass().getClassLoader().getResourceAsStream("BuyBill.zip");
    Deployment deploy = processEngine.getRepositoryService()
            .createDeployment()
            .name("采购流程")
            .addZipInputStream(new ZipInputStream(in))//封装到zip输入流并加载
            .deploy();
    
    System.out.println("部署名称:"+deploy.getName());
    System.out.println("部署id:"+deploy.getId());
}

相对应的数据库表就会插入数据、涉及到的数据库表后面会详细说明。现在我们只要了解到,我们工作流引擎执行操作会有数据库表记录。
在这里插入图片描述

2.4查看流程定义

查询流程定义的方式很多。

    //查看流程定义
    @Test
    public void queryProcessDefination(){
        String processDefiKey="buyBill";//流程定义key
        //获取流程定义列表
        List<ProcessDefinition> list = processEngine.getRepositoryService().createProcessDefinitionQuery()
        //查询 ,好比where
//        .processDefinitionId(proDefiId) //流程定义id
         // 流程定义id  : buyBill:2:704   组成 : proDefikey(流程定义key)+version(版本)+自动生成id
        .processDefinitionKey(processDefiKey)//流程定义key 由bpmn 的 process 的  id属性决定
//        .processDefinitionName(name)//流程定义名称  由bpmn 的 process 的  name属性决定
//        .processDefinitionVersion(version)//流程定义的版本
        .latestVersion()//最新版本
        //排序
        .orderByProcessDefinitionVersion().desc()//按版本的降序排序
        //结果
//        .count()//统计结果
//        .listPage(arg0, arg1)//分页查询
        .list();
        
        
        //遍历结果
        if(list!=null&&list.size()>0){
            for(ProcessDefinition temp:list){
                System.out.print("流程定义的id: "+temp.getId());
                System.out.print("流程定义的key: "+temp.getKey());
                System.out.print("流程定义的版本: "+temp.getVersion());
                System.out.print("流程定义部署的id: "+temp.getDeploymentId());
                System.out.println("流程定义的名称: "+temp.getName());
            }
        }
    }

3.流程实例与任务执行细讲

3.1数据库表

流程实例与任务执行的常用表有以下几个:

-- 流程实例与任务
SELECT * FROM act_ru_execution  # 流程执行对象信息
SELECT * FROM act_ru_task   # 正在运行的任务表
SELECT * FROM act_hi_procinst # 历史流程实例表
SELECT * FROM act_hi_taskinst  # 历史流程任务表

流程实例与流程对象的区别

(1)如果是单例流程,执行对象ID就是流程实例ID
(2)如果一个流程有分支和聚合,那么执行对象ID和流程实例ID就不相同
(3)一个流程中,流程实例只有1个,执行对象可以存在多个。

3.2.执行工作流

    @Test
    public void startProcess(){

        //指定执行我们刚才部署的工作流程
        String processDefiKey="leaveBill";
        ProcessInstance pi = processEngine.getRuntimeService()
                .startProcessInstanceByKey(processDefiKey);//通过流程定义的key 来执行流程
        
        System.out.println("流程执行对象的id:"+pi.getId());//Execution 对象
        System.out.println("流程实例的id:"+pi.getProcessInstanceId());//ProcessInstance 对象
        System.out.println("流程定义的id:"+pi.getProcessDefinitionId());//默认执行的是最新版本的流程定义
    }

startProcessInstanceByKey():key就是工作流就是我们定义时工作流程表的id

这里写图片描述

3.3设置发起人

在实际业务中设置发起人非常有必要,可以全局查看流程的运行状态。

通常的做法是,获取当前登陆用户的userName并设置

identityService.setAuthenticatedUserId( user.getUsername());

然后再执行启动流程实例的操作:

//流程发起前设置发起人,记录在流程历史中
identityService.setAuthenticatedUserId(user.getUsername())//开始流程
runtimeService.startProcessInstanceByKey("leavebill");

设置发起人后,数据存在ACT_HI_PROCINST表中。
在这里插入图片描述
我们调用API 获取到发起人:

historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstance.getId()).singleResult().getStartUserId();//获取发起人

两种方法:

identityService.setAuthenticatedUserId();//调用官方的开放API;

Authentication.setAuthenticatedUserId();//直接调用底层实现;

3.4业务关联流程(重点)

工作流的核心就是要让流程与业务关联在一起。activiti本身关注的是流程的流转,而业务需要我们自己去创建。比如说请假流程,所谓的业务就是:请假单据的内容+单据在不同工作流节点中的数据和状态变化。因此我们必须在启动流程实例的同时将流程与业务绑定,并且在每个工作流节点修改单据的状态和数据。

3.4.1流程关联业务

在流程启动的时候关联业务。
如下图,使用了流程定义的id+业务单据的id拼接的字符串作为activiti流程中的business_key,并在启动流程实例时传入了该值,从而实现了业务与流程的关联。这里面体现了两个开发时的经验和技巧:

  1. 绘制流程图并设置流程的id时,使用业务单据Bean的名称作为id。当启动流程实例时,我们需要根据流程定义的key来启动流程实例,那么,流程实例的key等于业务单据bean的简单类名。在代码中使用leaveBill.getClass().getSimpleName()即可以拿到流程实例的key。
  2. 使用流程定义的id+业务单据的id拼接的字符串作为activiti流程中的business_key。如此一来,只要能拿到这个key,工作流数据和业务数据也就都可以获取到。

在这里插入图片描述

4.根据办理人查询当前任务的信息

刚才我们已经开始了工作流了,随后工作流应该去到了申请请假的流程,申请请假的处理人是Jack,我们可以查询出对应的信息:

 	//查询任务
    @Test
    public void queryTask(){
        //任务的办理人
        String assignee="Jack";
        //取得任务服务
        TaskService taskService = processEngine.getTaskService();
        //根据办理人查询其任务列表
        List<Task> list =  = taskService.createTaskQuery()//创建一个任务查询对象
						       			.taskQuery.taskAssignee(assignee)//指定办理人
						                .list();
        //遍历任务列表
        if(list!=null&&list.size()>0){
            for(Task task:list){
                System.out.println("任务的办理人:"+task.getAssignee());
                System.out.println("任务的id:"+task.getId());
                System.out.println("任务的名称:"+task.getName());
            }
        }
    }

执行的是查询SELECT * FROM act_ru_task表的操作:
在这里插入图片描述

3.4获取流程实例的状态

有的时候,我们需要判断它是在该流程,还是该流程已经结束了。

一般情况下,我们可以通过获取流程实例对象、判断是否为空来进行判断。

//获取流程实例的状态
@Test
public void getProcessInstanceState(){
    String processInstanceId="605";
    ProcessInstance pi = processEngine.getRuntimeService()
            .createProcessInstanceQuery()
            .processInstanceId(processInstanceId)
            .singleResult();//返回的数据要么是单行,要么是空 ,其他情况报错
    //判断流程实例的状态
    if(pi!=null){
        System.out.println("该流程实例"+processInstanceId+"正在运行...  "+"当前活动的任务:"+pi.getActivityId());
    }else{
        System.out.println("当前的流程实例"+processInstanceId+" 已经结束!");
    }
}

3.5查看历史流程实例的信息

//查看历史执行流程实例信息
@Test
public void queryHistoryProcInst(){
    List<HistoricProcessInstance> list = processEngine.getHistoryService()
												    .createHistoricProcessInstanceQuery()
												    .list();
    if(list!=null&&list.size()>0){
        for(HistoricProcessInstance temp:list){
            System.out.println("历史流程实例id:"+temp.getId());
            System.out.println("历史流程定义的id:"+temp.getProcessDefinitionId());
            System.out.println("历史流程实例开始时间--结束时间:"+temp.getStartTime()+"-->"+temp.getEndTime());
        }
    }
}

3.6查看历史实例执行任务信息

根据对应的实例id就可以查询出执行到哪个任务了…

@Test
public void queryHistoryTask(){
    String processInstanceId="605";
    List<HistoricTaskInstance> list = processEngine.getHistoryService()
										            .createHistoricTaskInstanceQuery()
										            .processInstanceId(processInstanceId)
										            .list();
    if(list!=null&&list.size()>0){
        for(HistoricTaskInstance temp:list){
            System.out.print("历史流程实例任务id:"+temp.getId());
            System.out.print("历史流程定义的id:"+temp.getProcessDefinitionId());
            System.out.print("历史流程实例任务名称:"+temp.getName());
            System.out.println("历史流程实例任务处理人:"+temp.getAssignee());
        }
    }
}

3.7完成当前节点任务

根据任务的id,就可以把该任务执行了。

    @Test
    public void compileTask(){
        String taskId="608";
        Map<String, Object> variable = new HashMap<>();
        //taskId:任务id
        processEngine.getTaskService()
//                .complete(taskId);//完成任务
                .complete(taskId,variable);//完成任务并设置下一节点的流程变量
        System.out.println("当前任务执行完毕");
    }
}

完成当前任务时我们可以设置下一节点任务的流程变量,如:办理人、判断条件等等。
需要说明的是,流程变量的key必须是String类型。
key的值要对应之前绘制流程图时,下一节点中所设置的变量表达式的变量名,如: u s e r I d , {userId}, userId{money > 1000 || money == 1000};value就是要设置的值。

4.流程变量细讲

4.1数据库表

-- 流程变量涉及到的数据库表:

act_ru_variable:正在执行的流程变量表
act_hi_varinst:流程变量历史表

流程变量在工作流中扮演着一个非常重要的角色。例如:请假流程中有请假天数、请假原因等一些参数都为流程变量的范围。流程变量的作用域范围是只对应一个流程实例。也就是说各个流程实例的流程变量是不相互影响的。流程实例结束完成以后流程变量还保存在数据库中(存放到流程变量的历史表中)。
在这里插入图片描述

4.1设置流程变量

我们有两种服务可以设置流程变量,TaskService【任务服务】和RuntimeService【运行时服务】

场景

  • 在流程开始的时候设置流程变量
  • 在完成某个任务的时候设置流程变量
  • 使用TaskService设置服务
  • 使用RuntimeService设置服务

作用

  • 传递业务参数
  • 动态指定代理人【我们快速入门的例子是固定在流程定义图上写上代理人的】
  • 指定连接【决定流程往哪边走】

4.2流程变量支持类型

  • 基本数据类型都是可以的。很简单不再过多讲解。
  • 如果我们使用JavaBean来作为流程的变量,那么我们需要实现两点要求:
  1. JavaBean必须要实现Serializable接口
  2. 为了防止流程变量对象的属性发生变化,JavaBean需要设置序列化ID
private static final long serialVersionUID = 1L;

4.3setVariable和setVariableLocal的区别

在这里插入图片描述

4.4示例


public class AppayBillBean  implements Serializable{
    private Integer id;
    private Integer cost;//金额
    private String appayPerson;//申请人
    private Date date;//申请日期
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public Integer getCost() {
        return cost;
    }
    public void setCost(Integer cost) {
        this.cost = cost;
    }
    public String getAppayPerson() {
        return appayPerson;
    }
    public void setAppayPerson(String appayPerson) {
        this.appayPerson = appayPerson;
    }
    public Date getDate() {
        return date;
    }
    public void setDate(Date date) {
        this.date = date;
    }
}
	//模拟流程变量设置
    @Test
    public void  getAndSetProcessVariable(){
        //有两种服务可以设置流程变量
        TaskService taskService = processEngine.getTaskService();
        RuntimeService runtimeService = processEngine.getRuntimeService();
        
        /**1.通过 runtimeService 来设置流程变量
         * executionId: 执行对象
         * variableName:变量名
         * values:变量值
         */
        runtimeService.setVariable(executionId, variableName, values);
        runtimeService.setVariableLocal(executionId, variableName, values);
        //设置本执行对象的变量 ,该变量的作用域只在当前的execution对象
        runtimeService.setVariables(executionId, variables); 
        //可以设置多个变量  放在 Map<key,value>  Map<String,Object>
        
        /**2. 通过TaskService来设置流程变量
         * taskId:任务id
         */
        taskService.setVariable(taskId, variableName, values);
        taskService.setVariableLocal(taskId, variableName, values);
        //设置本执行对象的变量 ,该变量的作用域只在当前的execution对象
        taskService.setVariables(taskId, variables); //设置的是Map<key,values>
        
        /**3. 当流程开始执行的时候,设置变量参数
         * processDefiKey: 流程定义的key
         * variables: 设置多个变量  Map<key,values>
         */
        processEngine.getRuntimeService()
        .startProcessInstanceByKey(processDefiKey, variables)
        
        /**4. 当任务完成时候,可以设置流程变量
         * taskId:任务id
         * variables: 设置多个变量  Map<key,values>
         */
        processEngine.getTaskService().complete(taskId, variables);
        
        
        /** 5. 通过RuntimeService取变量值
         * exxcutionId: 执行对象
         * 
         */
        runtimeService.getVariable(executionId, variableName);//取变量
        runtimeService.getVariableLocal(executionId, variableName);//取本执行对象的某个变量
        runtimeService.getVariables(variablesName);//取当前执行对象的所有变量
        /** 6. 通过TaskService取变量值
         * TaskId: 执行对象
         * 
         */
        taskService.getVariable(taskId, variableName);//取变量
        taskService.getVariableLocal(taskId, variableName);//取本执行对象的某个变量
        taskService.getVariables(taskId);//取当前执行对象的所有变量
    }
//设置流程变量值
    @Test
    public void setVariable(){
        String taskId="1804";//任务id
        //采用TaskService来设置流程变量
        //1. 第一次设置流程变量
        TaskService taskService = processEngine.getTaskService();
        taskService.setVariable(taskId, "cost", 1000);//设置单一的变量,作用域在整个流程实例
        taskService.setVariable(taskId, "申请时间", new Date());
        taskService.setVariableLocal(taskId, "申请人", "何某某");//该变量只有在本任务中是有效的
        
        
        //2. 在不同的任务中设置变量
        TaskService taskService = processEngine.getTaskService();
        taskService.setVariable(taskId, "cost", 5000);//设置单一的变量,作用域在整个流程实例
        taskService.setVariable(taskId, "申请时间", new Date());
        taskService.setVariableLocal(taskId, "申请人", "李某某");//该变量只有在本任务中是有效的
        
        /**
         * 3. 变量支持的类型
         * - 简单的类型 :String 、boolean、Integer、double、date 
         * - 自定义对象bean  
         */
        TaskService taskService = processEngine.getTaskService();
        //传递的一个自定义bean对象
        AppayBillBean appayBillBean=new AppayBillBean();
        appayBillBean.setId(1);
        appayBillBean.setCost(300);
        appayBillBean.setDate(new Date());
        appayBillBean.setAppayPerson("何某某");
        taskService.setVariable(taskId, "appayBillBean", appayBillBean);
        System.out.println("设置成功!");
    }
    //查询流程变量
    @Test
    public void getVariable(){
        String taskId="1804";//任务id
        TaskService taskService = processEngine.getTaskService();
        Integer cost=(Integer) taskService.getVariable(taskId, "cost");//取变量
        Date date=(Date) taskService.getVariable(taskId, "申请时间");//取本任务中的变量
        Date date=(Date) taskService.getVariableLocal(taskId, "申请时间");//取本任务中的变量
        String appayPerson=(String) taskService.getVariableLocal(taskId, "申请人");//取本任务中的变量
        String appayPerson=(String) taskService.getVariable(taskId, "申请人");//取本任务中的变量
        
        System.out.println("金额:"+cost);
        System.out.println("申请时间:"+date);
        System.out.println("申请人:"+appayPerson);
        
        //读取实现序列化的对象变量数据
        TaskService taskService = processEngine.getTaskService();
        AppayBillBean appayBillBean=(AppayBillBean) taskService.getVariable(taskId, "appayBillBean");
        System.out.println(appayBillBean.getCost());
        System.out.println(appayBillBean.getAppayPerson());
        
    }

5.连线

有了流程变量,我们可以在**【任务服务、运行时服务、流程开始、完成某个任务时设置流程变量】**,而我们的连线就是流程变量的实际应用。

5.1定义流程图

我们并不是所有的流程都是按一条的路径来走的,我们有的时候会根据条件来走不同的路。当然了,最终该流程是会一步步走完…

例子:重要的信息交由老板来处理,不重要的信息交由经理来处理
在这里插入图片描述

表达式的结果必须是布尔型

#{variable=='value'}
${variable==value}

6.排他网关

上面我们使用连线的时候用了两个条件 : 要么条件是“重要”,要么条件是“不重要”…如果有另一种情况呢???就是用户把条件输入错了,写成“不知道重不重要”,那么我们的流程怎么走???岂不是奔溃了???

因此,我们要有一条默认的路来走,就是当该变量不符合任何的条件时,有一条默认的出口让流程继续执行

这里写图片描述

注意:如果是在Eclipse中使用插件的BPMN流程图,如果使用了排他网关,那么在Idea下是解析不了的…
解决方案:我们只要重新定义BPMN流程图的排他网关就行了,idea中的Activiti插件是不用制定默认流程的,只要我们不设置条件,那就是默认的连接线

6.2示例

public class ExclusiveGetWay {
    private ProcessEngine processEngine = ProcessEngines
            .getDefaultProcessEngine();

    // 部署流程定义,资源来在bpmn格式
    @Test
    public void deployProcessDefi() {
        Deployment deploy = processEngine.getRepositoryService()
                .createDeployment().name("排他网关流程")
                .addClasspathResource("ExclusiveGateway.bpmn")
                .deploy();

        System.out.println("部署名称:" + deploy.getName());
        System.out.println("部署id:" + deploy.getId());
    }

    // 执行流程,开始跑流程
    @Test
    public void startProcess() {
        String processDefiKey = "bankBill";// bpmn 的 process id属性
        ProcessInstance pi = processEngine.getRuntimeService()
                .startProcessInstanceByKey(processDefiKey);

        System.out.println("流程执行对象的id:" + pi.getId());// Execution 对象
        System.out.println("流程实例的id:" + pi.getProcessInstanceId());// ProcessInstance
                                                                    // 对象
        System.out.println("流程定义的id:" + pi.getProcessDefinitionId());// 默认执行的是最新版本的流程定义
    }

    // 查询正在运行任务
    @Test
    public void queryTask() {
        // 取得任务服务
        TaskService taskService = processEngine.getTaskService();
        // 创建一个任务查询对象
        TaskQuery taskQuery = taskService.createTaskQuery();
        // 办理人的任务列表
        List<Task> list = taskQuery.list();
        // 遍历任务列表
        if (list != null && list.size() > 0) {
            for (Task task : list) {
                System.out.println("任务的办理人:" + task.getAssignee());
                System.out.println("任务的id:" + task.getId());
                System.out.println("任务的名称:" + task.getName());
            }
        }

    }

    // 完成任务
    @Test
    public void compileTask() {
        String taskId = "2404";
        Map<String,Object> params=new HashMap<String, Object>();
        params.put("visitor", 6);
        // taskId:任务id
        processEngine.getTaskService().complete(taskId, params);
//        processEngine.getTaskService().complete(taskId);
        System.out.println("当前任务执行完毕");
    }
}

7.个人任务指定办理人的三种方式

7.1流程图中指定办理人

在绘制流程图中硬性指定某个节点的办理人,但这种方法在实际开发中不灵活,基本不使用。

7.2使用流程变量指定办理人

在绘制流程图时,使用变量指定办理人。Assignee属性使用**${} 或者#{}**。
这里写图片描述
在业务代码中设置具体的流程变量的值。

@Test
public void deployProcessDefi() {
    Deployment deploy = processEngine.getRepositoryService()
            .createDeployment().name("用户任务指定流程")
            .addClasspathResource("AppayBill.bpmn")
            .deploy();

    System.out.println("部署名称:" + deploy.getName());
    System.out.println("部署id:" + deploy.getId());
}

// 执行流程,开始跑流程
@Test
public void startProcess() {
    String processDefiKey = "appayBill";// bpmn 的 process id属性
    //封装流程变量
    Map<String,Object> params=new HashMap<String, Object>();
    params.put("userID", "王某某");
    ProcessInstance pi = processEngine.getRuntimeService()
            .startProcessInstanceByKey(processDefiKey, params);

    System.out.println("流程执行对象的id:" + pi.getId());// Execution 对象
    System.out.println("流程实例的id:" + pi.getProcessInstanceId());// ProcessInstance
    // 对象
    System.out.println("流程定义的id:" + pi.getProcessDefinitionId());// 默认执行的是最新版本的流程定义
}

// 查询正在运行任务
@Test
public void queryTask() {
    String assignee="王某某";//指定任务处理人
    // 取得任务服务
    TaskService taskService = processEngine.getTaskService();
    // 创建一个任务查询对象
    TaskQuery taskQuery = taskService.createTaskQuery();
    // 办理人的任务列表
    List<Task> list = taskQuery.taskAssignee(assignee).list();
    // 遍历任务列表
    if (list != null && list.size() > 0) {
        for (Task task : list) {
            System.out.println("任务的办理人:" + task.getAssignee());
            System.out.println("任务的id:" + task.getId());
            System.out.println("任务的名称:" + task.getName());
        }
    }
}

7.3使用类指定办理人

7.3.1:流程图中任务节点的配置

在这里插入图片描述
在这里插入图片描述
此时流程图的XML文件,如图:
在这里插入图片描述

7.3.2:TaskListenerImpl类,用来设置任务的办理人

public class TaskListenerImpl implements TaskListener {

	/**指定个人任务和组任务的办理人*/
	@Override
	public void notify(DelegateTask delegateTask) {
		String assignee = "张无忌";
		//指定个人任务
		delegateTask.setAssignee(assignee);
	}
}

7.2.3:测试代码

ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//部署流程定义,启动流程实例
	@Test
	public void testTask() throws Exception {
		
		// 1 发布流程
		InputStream inputStreamBpmn = this.getClass().getResourceAsStream("taskProcess.bpmn");
		InputStream inputStreamPng = this.getClass().getResourceAsStream("taskProcess.png");
		processEngine.getRepositoryService()//
						.createDeployment()//
						.addInputStream("userTask.bpmn", inputStreamBpmn)//
						.addInputStream("userTask.png", inputStreamPng)//
						.deploy();
		
		// 2 启动流程
		ProcessInstance pi = processEngine.getRuntimeService()//
							.startProcessInstanceByKey("taskProcess");
		System.out.println("pid:" + pi.getId());
	}
	
	//查询我的个人任务列表
	@Test
	public void findMyTaskList(){
		String userId = "张无忌";
		List<Task> list = processEngine.getTaskService()//
		                .createTaskQuery()//
		                .taskAssignee(userId)//指定个人任务查询
		                .list();
		for(Task task:list ){
			System.out.println("id="+task.getId());
			System.out.println("name="+task.getName());
			System.out.println("assinee="+task.getAssignee());
			System.out.println("createTime="+task.getCreateTime());
			System.out.println("executionId="+task.getExecutionId());
		}
	}
	
	//完成任务
	@Test
	public void completeTask(){
		String taskId = "3408";
		processEngine.getTaskService()//
					.complete(taskId);//
		System.out.println("完成任务");
	}

	//可以分配个人任务从一个人到另一个人(认领任务)
	@Test
	public void setAssigneeTask(){
		//任务ID
		String taskId = "3408";
		//指定认领的办理者
		String userId = "周芷若";
		processEngine.getTaskService()//
					.setAssignee(taskId, userId);
	}

说明

  1. 在类中使用delegateTask.setAssignee(assignee);的方式分配个人任务的办理人,此时张无忌是下一个任务的办理人。。
  2. 通过processEngine.getTaskService().setAssignee(taskId, userId);将个人任务从一个人分配给另一个人,此时张无忌不再是下一个任务的办理人,而换成了周芷若
  3. 在开发中,可以将每一个任务的办理人规定好,例如张三的领导是李四,李四的领导是王五,这样张三提交任务,就可以查询出张三的领导是李四,通过类的方式设置下一个任务的办理人。

7.4 小结

个人任务及三种分配方式:

1:在taskProcess.bpmn中直接写 assignee=“张三丰"
2:在taskProcess.bpmn中写 assignee=“#{userID}”;变量的值要是String的。
使用流程变量指定办理人
3,使用监听类方式,要实现TaskListener接口,在类中定义:
delegateTask.setAssignee(assignee);// 指定个人任务的办理人

使用任务ID和办理人重新指定办理人:

 processEngine.getTaskService()
 				.setAssignee(taskId, userId);

8.组任务

8.1数据库表

act_ru_identitylink表存放任务的办理人,包括个人任务和组任务,表示正在执行的任务
act_hi_identitylink表存放任务的办理人,包括个人任务和组任务,表示历史任务

8.2流程图

在这里插入图片描述

8.3分配组任务方式一(直接指定办理人)

8.3.1流程图中任务节点的配置

在这里插入图片描述

8.3.2示例代码

ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
	
	//部署流程定义,启动流程实例
	@Test
	public void testTask() throws Exception {
		// 1 发布流程
		InputStream inputStreamBpmn = this.getClass().getResourceAsStream("taskProcess.bpmn");
		InputStream inputStreamPng = this.getClass().getResourceAsStream("taskProcess.png");
		processEngine.getRepositoryService()//
						.createDeployment()//
						.addInputStream("userTask.bpmn", inputStreamBpmn)//
						.addInputStream("userTask.png", inputStreamPng)//
						.deploy();
		// 2 启动流程
		ProcessInstance pi = processEngine.getRuntimeService()//
							.startProcessInstanceByKey("taskProcess");
		System.out.println("pid:" + pi.getId());
	}
	
	//3 查询我的个人任务列表
	@Test
	public void findMyTaskList(){
		String userId = "小A";
		List<Task> list = processEngine.getTaskService()//
		                .createTaskQuery()//
		                .taskAssignee(userId)//指定个人任务查询
		                .list();
		for(Task task:list ){
			System.out.println("id="+task.getId());
			System.out.println("name="+task.getName());
			System.out.println("assinee="+task.getAssignee());
			System.out.println("createTime="+task.getCreateTime());
			System.out.println("executionId="+task.getExecutionId());
			
		}
	}
	
	//4 查询组任务列表
	@Test
	public void findGroupList(){
		String userId = "小A";
		List<Task> list = processEngine.getTaskService()//
		                .createTaskQuery()//
		                .taskCandidateUser(userId)//指定组任务查询
		                .list();
		for(Task task:list ){
			System.out.println("id="+task.getId());
			System.out.println("name="+task.getName());
			System.out.println("assinee="+task.getAssignee());
			System.out.println("createTime ="+task.getCreateTime());
			System.out.println("executionId="+task.getExecutionId());
			System.out.println("##################################");
		}
	}
	
	//5 查询组任务成员列表
	@Test
	public void findGroupUser(){
		String taskId = "3709";
		List<IdentityLink> list = processEngine.getTaskService()//
		                .getIdentityLinksForTask(taskId);
         //List<IdentityLink> list = processEngine.getRuntimeService()//
		//				.getIdentityLinksForProcessInstance(instanceId);
		for(IdentityLink identityLink:list ){
			System.out.println("userId="+identityLink.getUserId());
			System.out.println("taskId="+identityLink.getTaskId());
			System.out.println("piId="+identityLink.getProcessInstanceId());
			System.out.println("######################");
		}
	}
	
	//6 查询组任务成员历史列表
	@Test
	public void findGroupHisUser(){
		String taskId = "3709";
		List<HistoricIdentityLink> list = processEngine.getHistoryService()//
						.getHistoricIdentityLinksForTask(taskId);
        // List<HistoricIdentityLink> list = processEngine.getHistoryService()//
          // .getHistoricIdentityLinksForProcessInstance(processInstanceId);
		for(HistoricIdentityLink identityLink:list ){
			System.out.println("userId="+identityLink.getUserId());
			System.out.println("taskId="+identityLink.getTaskId());
			System.out.println("piId="+identityLink.getProcessInstanceId());
			System.out.println("######################");
		}
	}
	
	//完成任务
	@Test
	public void completeTask(){
		String taskId = "3709";
		processEngine.getTaskService()//
					.complete(taskId);//
		System.out.println("完成任务");
	}

     /**将组任务分配给个人任务,拾取任务*/
	//由1个人去完成任务
	@Test
	public void claim(){
		//任务ID
		String taskId = "5908";
		//分配的办理人
		String userId = "小B";
		processEngine.getTaskService()//
					.claim(taskId, userId);
	}

说明:
1)小A,小B,小C,小D是组任务的办理人 。
2)但是上述分配组任务的办理人的方式不够灵活,因为项目开发中任务的办理人不要放置XML文件中。

个人任务和组任务的参与者类型的区别:

如果是个人任务TYPE的类型表示participant(参与者)
如果是组任务TYPE的类型表示candidate(候选者)和participant(参与者)

8.4 分配个人任务方式二(使用流程变量)

8.4.1 流程图中任务节点的配置

在这里插入图片描述

8.4.2 测试代码

ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
	
	//部署流程定义,启动流程实例
	@Test
	public void testTask() throws Exception {
		// 1 发布流程
		InputStream inputStreamBpmn = this.getClass().getResourceAsStream("taskProcess.bpmn");
		InputStream inputStreamPng = this.getClass().getResourceAsStream("taskProcess.png");
		processEngine.getRepositoryService()//
						.createDeployment()//
						.addInputStream("userTask.bpmn", inputStreamBpmn)//
						.addInputStream("userTask.png", inputStreamPng)//
						.deploy();
		// 2 启动流程
		//启动流程实例,同时设置流程变量,用来指定组任务的办理人
		Map<String, Object> variables = new HashMap<String, Object>();
		variables.put("userIDs", "大大,小小,中中");
		ProcessInstance pi = processEngine.getRuntimeService()//
						.startProcessInstanceByKey("taskProcess",variables);
		System.out.println("pid:" + pi.getId());
	}
	
	//查询我的个人任务列表
	@Test
	public void findMyTaskList(){
		String userId = "大大";
		List<Task> list = processEngine.getTaskService()//
		                .createTaskQuery()//
		                .taskAssignee(userId)//指定个人任务查询
		                .list();
		for(Task task:list ){
			System.out.println("id="+task.getId());
			System.out.println("name="+task.getName());
			System.out.println("assinee="+task.getAssignee());
			System.out.println("assinee="+task.getCreateTime());
			System.out.println("executionId="+task.getExecutionId());
			
		}
	}
	
	//查询组任务列表
	@Test
	public void findGroupList(){
		String userId = "大大";
		List<Task> list = processEngine.getTaskService()//
		                .createTaskQuery()//
		                .taskCandidateUser(userId)//指定组任务查询
		                .list();
		for(Task task:list ){
			System.out.println("id="+task.getId());
			System.out.println("name="+task.getName());
			System.out.println("assinee="+task.getAssignee());
			System.out.println("assinee="+task.getCreateTime());
			System.out.println("executionId="+task.getExecutionId());
			System.out.println("##################################");
			
		}
	}
	
	//查询组任务成员列表
	@Test
	public void findGroupUser(){
		String taskId = "3709";
		List<IdentityLink> list = processEngine.getTaskService()//
		                .getIdentityLinksForTask(taskId);
		for(IdentityLink identityLink:list ){
			System.out.println("userId="+identityLink.getUserId());
			System.out.println("taskId="+identityLink.getTaskId());
			System.out.println("piId="+identityLink.getProcessInstanceId());
			System.out.println("######################");
		}
	}
	
	//查询组任务成员历史列表
	@Test
	public void findGroupHisUser(){
		String taskId = "3709";
		List<HistoricIdentityLink> list = processEngine.getHistoryService()//
						.getHistoricIdentityLinksForTask(taskId);
		for(HistoricIdentityLink identityLink:list ){
			System.out.println("userId="+identityLink.getUserId());
			System.out.println("taskId="+identityLink.getTaskId());
			System.out.println("piId="+identityLink.getProcessInstanceId());
			System.out.println("######################");
		}
	}
	
	//完成任务
	@Test
	public void completeTask(){
		String taskId = "3709";
		processEngine.getTaskService()//
					.complete(taskId);//
		System.out.println("完成任务");
	}

     /**将组任务分配给个人任务,拾取任务*/
	//由1个人去完成任务
	@Test
	public void claim(){
		//任务ID
		String taskId = "5908";
		//分配的办理人
		String userId = "小B";
		processEngine.getTaskService()
					.claim(taskId, userId);
	}

说明:
1)大大,中中,小小是组任务的办理人
2)在开发中,可以在页面中指定下一个组任务的办理人,通过流程变量设置下一个任务的办理人
3) 个人任务和组任务的查询方式差别就在一行代码上:

List<Task> list = processEngine.getTaskService()//
                .createTaskQuery()//
                //.taskAssignee(userId)//指定个人任务查询
                .taskCandidateUser(userId)//指定组任务查询
                .list();

8.5 分配个人任务方式三(使用类)

8.5.1 流程图中任务节点的配置

在这里插入图片描述
在这里插入图片描述
此时流程图的XML文件,如图:
在这里插入图片描述

8.5.2 TaskListenerImpl类,用来设置任务的办理人

public class TaskListenerImpl implements TaskListener {

	/**指定个人任务和组任务的办理人*/
	@Override
	public void notify(DelegateTask delegateTask) {
		String userId1 = "孙悟空";
		String userId2 = "猪八戒";
		//指定组任务
		delegateTask.addCandidateUser(userId1);
		delegateTask.addCandidateUser(userId2);
	}
}

8.5.3 测试代码

ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
	
	//部署流程定义,启动流程实例
	@Test
	public void testTask() throws Exception {
		// 1 发布流程
		InputStream inputStreamBpmn = this.getClass().getResourceAsStream("taskProcess.bpmn");
		InputStream inputStreamPng = this.getClass().getResourceAsStream("taskProcess.png");
		processEngine.getRepositoryService()//
						.createDeployment()//
						.addInputStream("userTask.bpmn", inputStreamBpmn)//
						.addInputStream("userTask.png", inputStreamPng)//
						.deploy();
		// 2 启动流程
		ProcessInstance pi = processEngine.getRuntimeService()//
							.startProcessInstanceByKey("taskProcess");
		System.out.println("pid:" + pi.getId());
	}
	
	//查询我的个人任务列表
	@Test
	public void findMyTaskList(){
		String userId = "孙悟空";
		List<Task> list = processEngine.getTaskService()//
		                .createTaskQuery()//
		                .taskAssignee(userId)//指定个人任务查询
		                .list();
		for(Task task:list ){
			System.out.println("id="+task.getId());
			System.out.println("name="+task.getName());
			System.out.println("assinee="+task.getAssignee());
			System.out.println("assinee="+task.getCreateTime());
			System.out.println("executionId="+task.getExecutionId());
			
		}
	}
	
	//查询组任务列表
	@Test
	public void findGroupList(){
		String userId = "孙悟空";
		List<Task> list = processEngine.getTaskService()//
		                .createTaskQuery()//
		                .taskCandidateUser(userId)//指定组任务查询
		                .list();
		for(Task task:list ){
			System.out.println("id="+task.getId());
			System.out.println("name="+task.getName());
			System.out.println("assinee="+task.getAssignee());
			System.out.println("assinee="+task.getCreateTime());
			System.out.println("executionId="+task.getExecutionId());
			System.out.println("##################################");
			
		}
	}
	
	//查询组任务成员列表
	@Test
	public void findGroupUser(){
		String taskId = "4008";
		List<IdentityLink> list = processEngine.getTaskService()//
		                .getIdentityLinksForTask(taskId);
		for(IdentityLink identityLink:list ){
			System.out.println("userId="+identityLink.getUserId());
			System.out.println("taskId="+identityLink.getTaskId());
			System.out.println("piId="+identityLink.getProcessInstanceId());
			System.out.println("######################");
		}
	}
	
	//查询组任务成员历史列表
	@Test
	public void findGroupHisUser(){
		String taskId = "4008";
		List<HistoricIdentityLink> list = processEngine.getHistoryService()//
						.getHistoricIdentityLinksForTask(taskId);
		for(HistoricIdentityLink identityLink:list ){
			System.out.println("userId="+identityLink.getUserId());
			System.out.println("taskId="+identityLink.getTaskId());
			System.out.println("piId="+identityLink.getProcessInstanceId());
			System.out.println("######################");
		}
	}
	
	//完成任务
	@Test
	public void completeTask(){
		String taskId = "4008";
		processEngine.getTaskService()//
					.complete(taskId);//
		System.out.println("完成任务");
	}

将组任务分配给个人任务(认领任务)

	//将组任务分配给个人任务(认领任务)
	@Test
	public void claimTask(){
		String taskId = "4008";
		//个人任务的办理人
		String userId = "如来";
		processEngine.getTaskService().claim(taskId, userId);
	}

可以分配个人任务回退到组任务,(前提之前是个组任务)

	@Test
	public void setAssigneeTask(){
		//任务ID
		String taskId = "4008";
		processEngine.getTaskService()//
					.setAssignee(taskId, null);
	}
	```
```java
	//向组任务中添加成员
	@Test
	public void addUser(){
		String taskId = "4008";
		String userId = "沙和尚";
		processEngine.getTaskService().addCandidateUser(taskId, userId);
	}

	//向组任务中删除成员
	@Test
	public void removeUser(){
		String taskId = "4008";
		String userId = "沙和尚";
		processEngine.getTaskService().deleteCandidateUser(taskId, userId);
	}

说明:
1)在类中使用delegateTask.addCandidateUser (userId);的方式分配组任务的办理人,此时孙悟空和猪八戒是下一个任务的办理人。
2)通过processEngine.getTaskService().claim (taskId, userId);将组任务分配给个人任务,也叫认领任务,即指定某个人去办理这个任务,此时由如来去办理任务。
注意:认领任务的时候,可以是组任务成员中的人,也可以不是组任务成员的人,此时通过Type的类型为participant来指定任务的办理人
3)addCandidateUser()即向组任务添加成员,deleteCandidateUser()即删除组任务的成员。
4)在开发中,可以将每一个任务的办理人规定好,例如张三的领导是李四和王五,这样张三提交任务,由李四或者王五去查询组任务,可以看到对应张三的申请,李四或王五再通过认领任务(claim)的方式,由某个人去完成这个任务。

8.6 总结

组任务及三种分配方式:
1:在taskProcess.bpmn中直接写 candidate-users=“小A,小B,小C,小D";
2:在taskProcess.bpmn中写 candidate-users =“#{userIDs}”,变量的值要是String的。

//使用流程变量指定办理人
  Map<String, Object> variables = new HashMap<String, Object>();
  variables.put("userIDs", "大大,小小,中中");
3,使用TaskListener接口,使用类实现该接口,在类中定义:
//添加组任务的用户
	delegateTask.addCandidateUser(userId1);
	delegateTask.addCandidateUser(userId2);
//组任务分配给个人任务(认领任务):
     processEngine.getTaskService().claim(taskId, userId);
//个人任务分配给组任务:
     processEngine.getTaskService(). setAssignee(taskId, null);
//向组任务添加人员:
     processEngine.getTaskService().addCandidateUser(taskId, userId);
//向组任务删除人员:
     processEngine.getTaskService().deleteCandidateUser(taskId, userId);

个人任务和组任务存放办理人对应的表:
act_ru_identitylink表存放任务的办理人,包括个人任务和组任务,表示正在执行的任务
act_hi_identitylink表存放任务的办理人,包括个人任务和组任务,表示历史任务
区别在于:如果是个人任务TYPE的类型表示participant(参与者)
如果是组任务TYPE的类型表示candidate(候选者)和participant(参与者)

9 工作流定义的角色组(了解)

9.1数据库表

act_id_group:角色组表
act_id_user:用户表
act_id_membership:用户角色表

9.2 流程图

在这里插入图片描述
流程图中任务节点的配置:
在这里插入图片描述

分配任务负责的组:使用 candidate groups 属性指定 任务负责组。
代码:

<userTask id=“usertask1” name=“审批” activiti:candidateGroups=“部门经理”>
</userTask>   

其中部门经理表示一个用户组的角色.

9.3 测试代码

ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
	
	//部署流程定义,启动流程实例
	@Test
	public void testTask() throws Exception {
		// 1 发布流程
		InputStream inputStreamBpmn = this.getClass().getResourceAsStream("taskProcess.bpmn");
		InputStream inputStreamPng = this.getClass().getResourceAsStream("taskProcess.png");
		processEngine.getRepositoryService()//
						.createDeployment()//
						.addInputStream("userTask.bpmn", inputStreamBpmn)//
						.addInputStream("userTask.png", inputStreamPng)//
						.deploy();

		/**在部署流程定义和启动流程实例的中间,设置组任务的办理人,向Activity表中存放组和用户的信息*/
		IdentityService identityService = processEngine.getIdentityService();//认证:保存组和用户信息
		identityService.saveGroup(new GroupEntity("部门经理"));//建立组
		identityService.saveGroup(new GroupEntity("总经理"));//建立组
		identityService.saveUser(new UserEntity(“小张”));//建立用户
		identityService.saveUser(new UserEntity("小李")); //建立用户
		identityService.saveUser(new UserEntity("小王")); //建立用户
		identityService.createMembership("小张", "部门经理");//建立组和用户关系
		identityService.createMembership("小李", "部门经理");//建立组和用户关系
		identityService.createMembership(“小王”, “总经理”);//建立组和用户关系

		// 2 启动流程
		ProcessInstance pi = processEngine.getRuntimeService()//
							.startProcessInstanceByKey("taskProcess");
		System.out.println("pid:" + pi.getId());
	}
	
	//3 查询我的个人任务列表
	@Test
	public void findMyTaskList(){
		String userId = "唐僧";
		List<Task> list = processEngine.getTaskService()
			                .createTaskQuery()
			                .taskAssignee(userId)//指定个人任务查询
			                .list();
		for(Task task:list ){
			System.out.println("id="+task.getId());
			System.out.println("name="+task.getName());
			System.out.println("assinee="+task.getAssignee());
			System.out.println("assinee="+task.getCreateTime());
			System.out.println("executionId="+task.getExecutionId());
		}
	}
	
	//4 查询组任务列表
	@Test
	public void findGroupList(){
		String userId = "小李";//小张,小李可以查询结果,小王不可以,因为他不是部门经理
		List<Task> list = processEngine.getTaskService()//
		                .createTaskQuery()//
		                .taskCandidateUser(userId)//指定组任务查询
		                .list();
		for(Task task:list ){
			System.out.println("id="+task.getId());
			System.out.println("name="+task.getName());
			System.out.println("assinee="+task.getAssignee());
			System.out.println("assinee="+task.getCreateTime());
			System.out.println("executionId="+task.getExecutionId());
			System.out.println("##################################");
		}
	}
	
	//5 查询组任务成员列表
	@Test
	public void findGroupUser(){
		String taskId = "4408";
		List<IdentityLink> list = processEngine.getTaskService()//
		                .getIdentityLinksForTask(taskId);
		for(IdentityLink identityLink:list ){
			System.out.println("userId="+identityLink.getUserId());
			System.out.println("taskId="+identityLink.getTaskId());
			System.out.println("piId="+identityLink.getProcessInstanceId());
			System.out.println("######################");
		}
	}
	
	//完成任务
	@Test
	public void completeTask(){
		String taskId = "5108";
		processEngine.getTaskService()//
					.complete(taskId);//
		System.out.println("完成任务");
	}
}

9.4 核心操作

在部署流程定义和启动流程实例的中间,设置组任务的办理人,向Activiti表中存放组和用户的信息

/**在部署流程定义和启动流程实例的中间,设置组任务的办理人,向Activiti表中存放组和用户的信息*/
IdentityService identityService = processEngine.getIdentityService();//认证:保存组和用户信息
identityService.saveGroup(new GroupEntity("部门经理"));//建立组
identityService.saveGroup(new GroupEntity("总经理"));//建立组
identityService.saveUser(new UserEntity(“小张”));//建立用户
identityService.saveUser(new UserEntity("小李")); //建立用户
identityService.saveUser(new UserEntity("小王")); //建立用户
identityService.createMembership("小张", "部门经理");//建立组和用户关系
identityService.createMembership("小李", "部门经理");//建立组和用户关系
identityService.createMembership(“小王”, “总经理”);//建立组和用户关系

指定组任务的办理人,查询组任务

String userId = “小张”;//小张,小李可以查询结果,小王不可以,因为他不是部门经理角色
List<Task> list = processEngine.getTaskService()//
                .createTaskQuery()//
                .taskCandidateUser(userId)//指定组任务查询
                .list();

Activiti总结

在这里插入图片描述

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值