2023最新版本Activiti7系列-任务分配

303 阅读3分钟

任务分配

在这里插入图片描述

1.固定分配

  在指派用户任务的审批人时。我们是直接指派的固定账号。但是为了保证流程设计审批的灵活性。我们需要各种不同的分配方式,所以这节我们就详细的来介绍先在Activiti7中我们可以使用的相关的分配方式.

  固定分配就是我们前面介绍的,在绘制流程图或者直接在流程文件中通过Assignee来指定的方式.

在这里插入图片描述

2. 表达式

  Activiti使用UEL进行表达式解析。UEL代表Unified Expression Language,是EE6规范的一部分(查看EE6规范了解更多信息)。为了在所有环境上支持UEL标准的所有最新特性,我们使用JUEL的修改版本。

  表达式可以用于例如Java服务任务 Java Service tasks, 执行监听器 Execution Listeners, 任务监听器 Task Listeners条件流 Conditional sequence flows。尽管有值表达式与方法表达式两种表达式,通过Activiti的抽象,使它们都可以在需要expression(表达式)的地方使用。

myVar{myVar} {myBean.myProperty}

2.1 值表达式

  我们在处理的位置通过UEL表达式来占位。

在这里插入图片描述

然后做流程的部署和启动操作:

/**
 * 流程部署操作
 */
@Test
public void test1(){
    // 1.获取ProcessEngine对象
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    // 2.完成流程的部署操作 需要通过RepositoryService来完成
    RepositoryService repositoryService = processEngine.getRepositoryService();
    // 3.完成部署操作
    Deployment deploy = repositoryService.createDeployment()
            .addClasspathResource("flow/test2.bpmn20.xml")
            .name("请假流程-流程变量")
            .deploy(); // 是一个流程部署的行为 可以部署多个流程定义的
    System.out.println(deploy.getId());
    System.out.println(deploy.getName());
}

然后我们发起请假流程:

/**
 * 发起一个流程
 */
@Test
public void test3(){
    ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
    // 发起流程 需要通过 runtimeService来实现
    RuntimeService runtimeService = engine.getRuntimeService();
    // 通过流程定义ID来启动流程  返回的是流程实例对象
    ProcessInstance processInstance = runtimeService
            .startProcessInstanceById("test01:1:12503");
    System.out.println("processInstance.getId() = " + processInstance.getId());
    System.out.println("processInstance.getDeploymentId() = " + processInstance.getDeploymentId());
    System.out.println("processInstance.getDescription() = " + processInstance.getDescription());
}

我们发起流程后。根据流程的设计应该需要进入到人事审批。但是呢。审批的用户是${assign1}是一个流程变量。那么还没有赋值的情况下。那么系统是没有办法识别的。

在这里插入图片描述

我们需要在进入该节点前对流程变量赋值

/**
 * 发起一个流程
 */
@Test
public void test3(){
    ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
    // 发起流程 需要通过 runtimeService来实现
    RuntimeService runtimeService = engine.getRuntimeService();
    // 对流程变量做赋值操作
    Map<String,Object> map = new HashMap<>();
    map.put("assgin1","张三");
    map.put("assign2","李四");
    // 通过流程定义ID来启动流程  返回的是流程实例对象
    ProcessInstance processInstance = runtimeService
            .startProcessInstanceById("test01:1:12503",map);
    System.out.println("processInstance.getId() = " + processInstance.getId());
    System.out.println("processInstance.getDeploymentId() = " + processInstance.getDeploymentId());
    System.out.println("processInstance.getDescription() = " + processInstance.getDescription());
}

然后我们就可以看到对应的表结构中的待办记录

在这里插入图片描述

同时需要了解 : ACT_RU_VARIABLE

在这里插入图片描述

2.2 方法表达式

  方法表达式 Method expression: 调用一个方法,可以带或不带参数。**当调用不带参数的方法时,要确保在方法名后添加空括号(以避免与值表达式混淆)。**传递的参数可以是字面值(literal value),也可以是表达式,它们会被自动解析。例如:

${printer.print()}
${myBean.getAssignee()}
${myBean.addNewOrder('orderName')}
${myBean.doSomething(myVar, execution)}

  myBean是Spring容器中的个Bean对象,表示调用的是bean的addNewOrder方法.我们通过案例来演示下。我们先定义对应的Service

先定义Bean

public class MyBean {

    public String getAssignee(){
        System.out.println("本方法执行了....");
        return "波哥";
    }
}

然后在Spring的配置文件中注册

在这里插入图片描述

然后在绘制流程图的时候就可以对应的指派了。

在这里插入图片描述

然后我们先部署流程

/**
 * 流程部署操作
 */
@Test
public void test1(){
    // 1.获取ProcessEngine对象
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    // 2.完成流程的部署操作 需要通过RepositoryService来完成
    RepositoryService repositoryService = processEngine.getRepositoryService();
    // 3.完成部署操作
    Deployment deploy = repositoryService.createDeployment()
            .addClasspathResource("flow/test3.bpmn20.xml")
            .name("请假流程-方法表达式")
            .deploy(); // 是一个流程部署的行为 可以部署多个流程定义的
    System.out.println(deploy.getId());
    System.out.println(deploy.getName());
}

然后我们发起新的流程。注意在这块我们可以不用添加流程变量信息了。因为人事审批节点的审批人是通过流程方法来赋值的

/**
 * 发起一个流程
 */
@Test
public void test3(){
    ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
    // 发起流程 需要通过 runtimeService来实现
    RuntimeService runtimeService = engine.getRuntimeService();
    // 通过流程定义ID来启动流程  返回的是流程实例对象
    ProcessInstance processInstance = runtimeService
            .startProcessInstanceById("test01:2:27503");
    System.out.println("processInstance.getId() = " + processInstance.getId());
    System.out.println("processInstance.getDeploymentId() = " + processInstance.getDeploymentId());
    System.out.println("processInstance.getDescription() = " + processInstance.getDescription());
}

可以看到操作成功。方法表达式被执行了

在这里插入图片描述

同时待办中的审批人就是方法表达式返回的结果 在这里插入图片描述

3.监听器分配

  可以使用监听器来完成很多Activiti的流程业务。我们在此处使用监听器来完成负责人的指定,那么我们在流程设计的时候就不需要指定assignee。创建自定义监听器:

public class MyFirstListener implements TaskListener {
    /**
     * 监听器触发的回调方法
     * @param delegateTask
     */
    @Override
    public void notify(DelegateTask delegateTask) {
        System.out.println("---->自定义的监听器执行了");
        if(EVENTNAME_CREATE.equals(delegateTask.getEventName())){
            // 表示是Task的创建事件被触发了
            // 指定当前Task节点的处理人
            delegateTask.setAssignee("boge666");
        }

    }
}

在配置流程的时候关联监听器。注意对应的事件。CREATE

在这里插入图片描述

然后我们部署和启动流程后。可以看到自定义的监听器触发了

在这里插入图片描述

而且待办中的任务的处理人就是监听器中设置的信息

在这里插入图片描述