第二节 SpringBoot集成Activiti7

亮子 2022-04-30 05:38:45 18869 0 0 0

1、添加依赖

        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-spring-boot-starter</artifactId>
            <version>7.0.0.Beta2</version>
        </dependency>

2、配置文件

# 应用名称
spring.application.name=server-demo-activity7

# 应用服务 WEB 访问端口
server.port=6060


#下面这些内容是为了让MyBatis映射
#指定Mybatis的Mapper文件
mybatis.mapper-locations=classpath:mappers/*xml
#指定Mybatis的实体目录
mybatis.type-aliases-package=com.shenmazong.pojo

# 数据库驱动:
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# 数据源名称
spring.datasource.name=defaultDataSource
# 数据库连接地址
spring.datasource.url=jdbc:mysql://localhost:3306/db_demo_activiti7?autoReconnect=true&useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
# 数据库用户名&密码:
spring.datasource.username=root
spring.datasource.password=123456

##
# 如果为true,表不存在自动创建,false则不创建,线上用false,开发用true
spring.activiti.database-schema-update=true
spring.activiti.db-history-used=true
spring.activiti.history-level=full

3、运行成功后数据库

一共25张表

图片alt

Activiti的后台是有数据库的支持,所有的表都以ACT_开头。 第二部分是表示表的用途的两个字母标识。 用途也和服务的API对应。

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

4、安装Activiti插件

1)、安装插件actiBPM

  • 点击菜单【File】–>【Settings…】打开【Settings】窗口。

  • 点击左侧【Plugins】按钮,在右侧输出"actiBPM",点击下面的【Search in repositories】链接会打开【Browse Repositories】窗口。

图片alt

  • 进入【Browse Repositories】窗口,选中左侧的【actiBPM】,点击右侧的【Install】按钮,开始安装。

图片alt

2)、Activiti BPMN visualizer

actiBPM插件如果没有找到,可能你的IDEA版本过高,可以试试下面插件

图片alt

5、创建流程文件

1)、创建目录

可以在resources目录下,创建processes目录,然后右键:

图片alt

也有说在resources目录下,创建activiti目录,这个我没有测试。

2)、创建流程

在创建好的bpmn20.xml文件中任意位置右键,选择 View BPMN Diagram,打开可视化界面(流程定义的界面)

图片alt

图片alt

6、运行项目

插件会自动识别bpmn20.xml结尾的文件,自动创建相关流程。

图片alt

7、编写实例

1)、开启请假流程

    // 开启请假流程
    @Test
    public void start() {
        String instanceKey = "holiday";
        log.info("开启请假流程...");
        Map<String, Object> map = new HashMap<String, Object>();
        //在holiday.bpmn中,填写请假单的任务办理人为动态传入的userId,此处模拟一个id
        map.put("userId", "10001");
        ProcessInstance instance = runtimeService.startProcessInstanceByKey(instanceKey, map);
        log.info("启动流程实例成功:{}", instance);
        log.info("流程实例ID:{}", instance.getId());
        log.info("流程定义ID:{}", instance.getProcessDefinitionId());

        // 9addf6cb-c866-11ec-aa93-34f39a56d33e
        // holiday:1:2e565f61-c864-11ec-8c10-34f39a56d33e
    }

2)、填写请假单

通过实例id可以查询到实例所对应的任务,模拟用户请假的内容存入map中添加为流程变量。

    // 填写请假单
    @Test
    public void employeeApply() {
        String instanceId = "9addf6cb-c866-11ec-aa93-34f39a56d33e"; // 任务ID
        String leaveDays = "10"; // 请假天数
        String leaveReason = "回老家结婚"; // 请假原因
        Task task = taskService.createTaskQuery().processInstanceId(instanceId).singleResult();
        if (task == null) {
            log.info("任务ID:{}查询到任务为空!", instanceId);
        }
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("days", leaveDays);
        map.put("date", new Date());
        map.put("reason", leaveReason);
        taskService.complete(task.getId(), map);
        log.info("执行【员工申请】环节,流程推动到【上级审核】环节");
    }

3)、流程变量查看

上级审核的时候需要查看到员工所提交的请假相关信息,可以通过taskService.getVariable的形式来获取。

    // 流程变量查看
    @Test
    public void showTaskVariable (){
        String instanceId = "9addf6cb-c866-11ec-aa93-34f39a56d33e"; // 任务ID

        Task task = taskService.createTaskQuery().processInstanceId(instanceId).singleResult();
        String days = (String) taskService.getVariable(task.getId(), "days");
        Date date = (Date) taskService.getVariable(task.getId(), "date");
        String reason = (String) taskService.getVariable(task.getId(), "reason");
        String userId = (String) taskService.getVariable(task.getId(), "userId");
        System.out.println("请假天数:  " + days);
        System.out.println("请假理由:  " + reason);
        System.out.println("请假人id:  " + userId);
        System.out.println("请假日期:  " + date.toString());
    }

4)、上级审批

上级审批并且添加意见

    // 上级审批并且添加意见
    @Test
    public void departmentAudit() {
        String instanceId = "9addf6cb-c866-11ec-aa93-34f39a56d33e"; // 任务ID
        String departmentalOpinion = "早去早回";
        Task task = taskService.createTaskQuery().processInstanceId(instanceId).singleResult();
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("departmentalOpinion", departmentalOpinion);
        taskService.complete(task.getId(), map);
        log.info("添加审批意见,请假流程结束");
    }

4)、查询个人待执行的任务

    /**
     * 查询个人待执行的任务
     */
    @Test
    public void findPersonalTaskList() {
        // 获取流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        // 获取TaskService
        TaskService taskService = processEngine.getTaskService();
        // 根据流程的key和任务的负责人去查询任务
        List<Task> taskList = taskService.createTaskQuery()
                .processDefinitionKey("myEvection")  // 流程的key
                .includeProcessVariables()
                .taskAssignee("zhangsan")           // 要查询的负责人
                .list();
        // 输出
        for (Task task : taskList) {
            System.out.println("流程实例的ID:" + task.getProcessInstanceId());
            System.out.println("任务的ID:" + task.getId());
            System.out.println("任务的负责人:" + task.getAssignee());
            System.out.println("任务的名称:" + task.getName());
        }
    }

5)、Activiti工作流的流转任务和结束任务

Acitiviti工作流流转和结束任务其实是调用同一个接口:

流转当前任务:

Map<String,Object> variable=new HashMap<>();
variable.put("CLR","aa");

taskService.complete(taskId,variable);(taskId:当前的任务id,variable:下一步处理人)

结束当前任务:

taskService.complete(taskId);

两者都是调用的complete接口,区别就在于流转当前任务需要传入下一步的处理人,而结束当前任务则不需要。

6)、activiti7查询当前用户任务列表

package com.zcc.acvitivi;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
import org.activiti.engine.TaskService;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;

import java.util.List;

/**
 * 查询当前用户任务列表
 */
public class ActivitiTaskQuery {
   /* public static void main(String[] args) {
        //创建流程引擎配置类
        ProcessEngineConfiguration processEngineConfiguration=
                ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml");
        //流程引擎对象
        ProcessEngine processEngine = processEngineConfiguration.buildProcessEngine();
        //获取taskService
        TaskService taskService = processEngine.getTaskService();
        //获取查询对象
        TaskQuery taskQuery = taskService.createTaskQuery();
        //
        TaskQuery myProcess = taskQuery.processDefinitionKey("myProcess");
        //获取当前之前任务代理人
        TaskQuery taskAssignee = myProcess.taskAssignee("zhansan");
        //查询当前代理人要执行的任务
        List<Task> list = taskAssignee.list();
        for (int i=0;i<list.size();i++){
            Task task = list.get(i);
            System.out.println("任务id:"+task.getId());
            System.out.println("任务名称:"+task.getName());
            System.out.println("任务执行人:"+task.getAssignee());
        }
    }*/
    /*public static void main(String[] args) {
        //创建流程引擎配置类
        ProcessEngineConfiguration processEngineConfiguration=
                ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml");
        //流程引擎对象
        ProcessEngine processEngine = processEngineConfiguration.buildProcessEngine();
        //获取taskService
        TaskService taskService = processEngine.getTaskService();
        //获取查询对象
        TaskQuery taskQuery = taskService.createTaskQuery();
        //
        TaskQuery myProcess = taskQuery.processDefinitionKey("myProcess");
        //获取当前之前任务代理人
        TaskQuery taskAssignee = myProcess.taskAssignee("lisi");
        //查询当前代理人要执行的任务
        List<Task> list = taskAssignee.list();
        for (int i=0;i<list.size();i++){
            Task task = list.get(i);
            System.out.println("任务id:"+task.getId());
            System.out.println("任务名称:"+task.getName());
            System.out.println("任务执行人:"+task.getAssignee());
        }
    }*/
    public static void main(String[] args) {
        //创建流程引擎配置类
        ProcessEngineConfiguration processEngineConfiguration=
                ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml");
        //流程引擎对象
        ProcessEngine processEngine = processEngineConfiguration.buildProcessEngine();
        //获取taskService
        TaskService taskService = processEngine.getTaskService();
        //获取查询对象
        TaskQuery taskQuery = taskService.createTaskQuery();
        //
        TaskQuery myProcess = taskQuery.processDefinitionKey("myProcess");
        //获取当前之前任务代理人
        TaskQuery taskAssignee = myProcess.taskAssignee("wangwu");
        //查询当前代理人要执行的任务
        List<Task> list = taskAssignee.list();
        for (int i=0;i<list.size();i++){
            Task task = list.get(i);
            System.out.println("任务id:"+task.getId());
            System.out.println("任务名称:"+task.getName());
            System.out.println("任务执行人:"+task.getAssignee());
        }
    }
}

7)、将hr的任务进行委派:

taskService.delegateTask(taskId, userId);// taskId 任务id; userId:被委派人id

8)、被委派人办理任务

taskService.resolveTask(taskId,variables);

9)、查询委派任务

正在运行的任务表中被委派人办理任务后hr的任务会回到委派人xxhr ,历史任务表中也一样,只是多了一个人进行审批

查询委派任务:

根据字段owner查询

    //正在运行的委派任务:
    public ListmytaskChangeOtherList1(String userId){
        List<Task>list = taskService.createTaskQuery().taskOwner(userId)
                .orderByTaskCreateTime().desc().list();
        returnlist;
    }

10)、转办

直接将办理人assignee 换成别人,这时任务的拥有者不再是转办人,而是为空,相当与将任务转出。

直接将assignee =” zhuanban”

taskService.setAssignee(taskId, userId);

参考文章