SpringBoot整合Flowable【04】- 通过代码控制流程流转

简介: 本文介绍了如何使用Flowable的Java API控制流程流转,基于前文构建的绩效流程模型。首先,通过Flowable-UI导出模型文件并部署到Spring Boot项目中。接着,详细讲解了如何通过代码部署、启动和审批流程,涉及`RepositoryService`、`RuntimeService`和`TaskService`等核心服务类的使用。最后,通过实际操作演示了流程从部署到完成的全过程,并简要说明了相关数据库表的变化。本文帮助读者初步掌握Flowable在实际业务中的应用,后续将深入探讨更多高级功能。

一、前情回顾

在03篇中,我用Flowable-UI绘制了一个简单的绩效流程并在官方的demo中跑完了整个流程,加深了各位读者对于一个流程中包含的一些基础概念加深了认识,并且在这个过程里也渗透了一些可以应用的知识点。但我们也能想到,在实际业务中我们是要靠后端的接口去控制流程的流转,而不能靠Flowable-UI去控制。因此,本篇文章就是带领读者使用Flowable的Java Api去控制流程流转,从而熟悉对相关API的使用。

二、导入流程

本次我们演示使用的模型就是上篇中在Flowable-UI中建立的绩效模型,因此我们需要把模型文件导出。在模型管理界面,我们绘制的模型在详情页都有导出选项。
1.png
将导出的模型文件放到项目里,位置没有硬性要求,但建议放在resource目录下。
2.png

三、代码控制

虽然Flowable也可以在非Spring环境下使用,但我相信应该没人会拒绝SpringBoot,毕竟精力扑到业务和开发上,比折腾配置可有趣多了。

1.相关配置

我们需要在02篇配置的基础上添加Flowable相关的配置。

flowable:
  async-executor-activate: true # 关闭定时任务job
  database-schema-update: true # flowable自动更新表结构

2.部署流程

完成了相关的配置后,我们来定义一个流程控制器并注入一个RepositoryService对象,它提供了管理和控住部署和流程定义相关操作的API。

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/process/v1")
public class ProcessControllerV1 {
   

    private final RepositoryService repositoryService;

}

接着声明一个部署流程的接口方法,当然,这里也可以编写一个测试类进行测试,只是我个人更喜欢直接用接口测:

/**
 * 部署流程模型.
 *
 * @return 流程key
 */
@PostMapping("/deploy")
public ResponseEntity<Object> createProcessDef() {
   
    //1,创建部署对象
    Deployment deployment = repositoryService.createDeployment()
            //2.添加流程定义文件
            .addClasspathResource("process/performance.bpmn20.xml")
            //3.设置流程名称
            .name("绩效流程")
            //4.部署
            .deploy();
    //5.返回部署的流程id
    return new ResponseEntity<>(new BaseResponse<>(deployment.getId()), HttpStatus.OK);
}

完成编码通过调试工具调这个接口,当方法正常执行后,会返回流程部署的id。
3.png
此时我们可以在三张表中看到此次部署的相关信息,首先是act_ge_bytearray表,它记录了流程定义的资源信息,包含了xml和流程图的图片信息;
4.png
其次是act_re_deployment表,它记载了这次的部署行为;
5.png
最后是act_re_procdef表,他记录了此次部署对应的流程定义信息;
6.png

3.启动流程

流程部署成功后,就可以启动流程了,我们需要注入一个新的服务类-RuntimeService来启动流程。

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/process/v1")
public class ProcessControllerV1 {
   

    private final RepositoryService repositoryService;

    private final RuntimeService runtimeService;

在这里需要说明下启动流程有两个方法,分别是通过id和key。它们的区别就是id是由引擎维护的,而key是由我们自己维护的(Ps:这里迷惑的同学回到03篇看下,我们在创建流程和节点的时候都有输入Key)。因此,在实际业务开发中我建议还是通过id启动流程。

runtimeService.startProcessInstanceById(processId);

runtimeService.startProcessInstanceByKey(processKey);

于是我们通过流程id来启动这个绩效流程,这个方法会返回一个流程实例对象。需要注意的是,在下面的示例中,我是直接声明的,聪明的同学一定已经想到了,在实际业务开发中,这个是在部署流程之后,由前端调这个接口并传入流程id来启动流程。

/**
 * 启动流程.
 *
 * @return 流程key
 */
@PostMapping("/start")
public ResponseEntity<Object> startProcessDef() {
   
    //1.声明流程id
    String processId = "performance-001:1:a9d432fd-ec57-11ee-980b-c85ea9014af0";
    //2.启动流程
    ProcessInstance processInstance = runtimeService.startProcessInstanceById(processId);
    //3.返回流程实例对象id
    return new ResponseEntity<>(new BaseResponse<>(processInstance.getId()), HttpStatus.OK);
}

通过调试工具调这个接口,当方法正常执行后,会返回流程实例的id。
7.png
启动流程也需要我们关注三张表,此时我们可以在act_ru_task表中看到当前流程走到了自评节点以及节点的承办人,即当前待办的记录信息。
8.png
而在act_ru_execution表中则记录了每个启动了的流程分支。
9.png
另外,可以在act_hi_actinst表中查询到这个流程的运行记录,需要注意的是:只要你启动一个流程,记录都会维护在这张表中
10.png
这里可以看到我们在部署流程启动流程这两个方法里涉及到了两个概念-1.流程定义2.流程实例,它们二者的关系可以类比为Java中的类与对象,即定义一个流程后,我们可以根据这个流程定义启动N个流程实例

4.流程审批

流程启动成功后,为了流程的跑通,我们就需要对各个节点进行审批。因此,我们需要注入新的服务类-
TaskService,它负责处理所有的节点任务。

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/process/v1")
public class ProcessControllerV1 {
   

    private final RepositoryService repositoryService;

    private final RuntimeService runtimeService;

    private final TaskService taskService;

还记得前面提过的每个节点都有个承办人,完成节点的审批就需要各个节点的承办人来做。因此我们先写个方法来查找某个承接人待处理的待办:

/**
 * 查询指定用户的待办任务.
 *
 * @param user 待办用户
 * @return 待办任务id
 */
private String findUserAgentTask(String user) {
   
    //1.查找指定用户的一个待办任务
    Task agentTask = taskService.createTaskQuery()
            .taskAssignee(user)
            .singleResult();
    //2.返回待办任务的id
    return agentTask.getId();
}

因为我这里演示只启动了一个流程,所以也只有一个待办,因此查询单个任务就可以了。读者们在实际开发者需要结合实际业务,如果业务场景会出现一个用户有多个待办,一定要查询任务集合,否则会报错。

//待办任务集合
List<Task> list = taskService.createTaskQuery()
        .taskAssignee(user)
        .list();
//待办任务集合(带分页)
List<Task> tasks = taskService.createTaskQuery()
        .taskAssignee(user)
        .listPage(1, 10);

查询到某个用户的待办后,返回待办任务的id,直接调用API完成节点审批即可。这里再复习一下:因为我们不使用引擎自带的用户关系,所以这里的审批操作其实引擎不会校验的,所以需要我们根据实际业务自行编写鉴权代码。 我这里演示也没什么要鉴权的,直接完成审批:

    /**
     * 完成节点任务.
     *
     * @return 流程key
     */
    @PostMapping("/complete/{agentUser}")
    public ResponseEntity<Object> completeTask(@PathVariable String agentUser) {
   
        //1.查询指定用户的待办任务
        String agentTaskId = findUserAgentTask(agentUser);
        //2.完成指定任务的审批
        taskService.complete(agentTaskId);
        //3.返回响应
        return new ResponseEntity<>(new BaseResponse<>(null), HttpStatus.OK);
    }

通过调试工具调这个接口并在调用时传入承接人数据,运行后提示执行成功。
11.png
各位读者不要被这个传承接人数据限制了,我只是为了演示API的使用,既然强调了引擎不会校验我们自定义的用户关系,在我们自己不加入逻辑判断的情况下,直接给完成方法穿待办任务id也是可以通过的:

/**
 * 完成节点任务.
 *
 * @return 流程key
 */
@PostMapping("/complete/{agentUser}")
public ResponseEntity<Object> completeTask(@PathVariable String agentUser) {
   
    //1.查询指定用户的待办任务
    //String agentTaskId = findUserAgentTask(agentUser);
    //2.完成指定任务的审批
    taskService.complete("d30f9ffd-eeb2-11ee-9654-c85ea9014af0");
    //3.返回响应
    return new ResponseEntity<>(new BaseResponse<>(null), HttpStatus.OK);
}

这时候我们回到act_ru_task表,就可以看到节点走到了上级评节点:
12.png
再次调用接口,就可以看到节点走到了隔级评节点:
14.png
最后调用一次,会发现act_ru_task表中已经没有数据了,因为我们这个流程已经完成了,后续我们想查这个流程节点的信息就只能去历史相关表里了。
15.png

四、小结

本篇主要是让各位读者了解了如何通过代码控制流程流转,介绍了几个主要的服务类和相关API地使用,至此,各位读者应该已经对Flowable可以进行初步的应用了,在以后的篇章中,会开始一些进阶的内容,比如节点引用表单、驳回功能、网关的使用等等。

目录
相关文章
|
3天前
|
前端开发 Java API
SpringBoot整合Flowable【06】- 查询历史数据
本文介绍了Flowable工作流引擎中历史数据的查询与管理。首先回顾了流程变量的应用场景及其局限性,引出表单在灵活定制流程中的重要性。接着详细讲解了如何通过Flowable的历史服务API查询用户的历史绩效数据,包括启动流程、执行任务和查询历史记录的具体步骤,并展示了如何将查询结果封装为更易理解的对象返回。最后总结了Flowable提供的丰富API及其灵活性,为后续学习驳回功能做了铺垫。
10 0
SpringBoot整合Flowable【06】- 查询历史数据
|
3天前
|
Java 开发者
SpringBoot整合Flowable【01】- 初识工作流引擎
本文介绍了工作流的基本概念,重点讲解了BPM(业务流程管理)和BPMN 2.0(业务流程建模符号)的关系,以及工作流引擎的发展。BPM是一种管理思想,BPMN是实现该思想的工具。文中还介绍了Flowable、Activiti等主流工作流引擎,并详细说明了流程设计的五种方式,包括FlowableUI、BPMN.js自定义、第三方设计器和代码实现等。最后通过一个请假流程图解释了流程图的组成元素,如事件、连线、任务和网关,帮助读者更好地理解工作流的设计与实现。
22 3
|
3天前
|
存储 Java 数据安全/隐私保护
SpringBoot整合Flowable【03】- 通过Flowable-UI体验一个简单流程
本文介绍了如何使用Flowable 7.0以下版本的flowable-ui进行流程建模、发布和执行。首先,通过解压并启动flowable-ui war包,访问http://localhost:8080/flowable-ui/idm/#/login登录系统。接着,创建并绘制一个简单的绩效流程模型,包含开始节点、任务节点(自评、上级评、隔级评)和结束节点,并为各节点分配处理人。然后,创建应用并发布绩效流程。最后,通过创建a、b、c三个用户分别完成各节点任务,演示了整个流程的执行过程。本文旨在帮助读者理解Flowable的基本操作和流程元素,后续将介绍通过Java代码控制流程的方法。
22 0
SpringBoot整合Flowable【03】- 通过Flowable-UI体验一个简单流程
|
3天前
|
存储 Java API
SpringBoot整合Flowable【02】- 整合初体验
本文介绍了如何基于Flowable 6.8.1版本搭建工作流项目。首先,根据JDK和Spring Boot版本选择合适的Flowable版本(7.0以下)。接着,通过创建Spring Boot项目并配置依赖,包括Flowable核心依赖、数据库连接等。然后,建立数据库并配置数据源,确保Flowable能自动生成所需的表结构。最后,启动项目测试,确认Flowable成功创建了79张表。文中还简要介绍了这些表的分类和常用表的作用,帮助初学者理解Flowable的工作原理。
40 0
SpringBoot整合Flowable【02】- 整合初体验
|
3天前
|
前端开发 Java API
SpringBoot整合Flowable【07】- 驳回节点任务
本文通过绩效流程的业务场景,详细介绍了如何在Flowable工作流引擎中实现任务驳回功能。具体步骤包括:获取目标任务节点和当前任务节点信息,进行必要的判空和逻辑校验,调用API完成节点回退,并清理相关脏数据(如历史任务和变量)。最后通过测试验证了驳回功能的正确性,确保流程能够成功回退到指定节点并清除中间产生的冗余数据。此功能在实际业务中非常有用,能够满足上级驳回自评等需求。
17 0
|
3天前
|
存储 前端开发 Java
SpringBoot整合Flowable【05】- 使用流程变量传递业务数据
本文介绍了如何使用Flowable的流程变量来管理绩效流程中的自定义数据。首先回顾了之前的简单绩效流程,指出现有流程缺乏分数输入和保存步骤。接着详细解释了流程变量的定义、分类(运行时变量和历史变量)及类型。通过具体代码示例展示了如何在绩效流程中插入全局和局部流程变量,实现各节点打分并维护分数的功能。最后总结了流程变量的使用场景及其在实际业务中的灵活性,并承诺将持续更新Flowable系列文章,帮助读者更好地理解和应用Flowable。 简要来说,本文通过实例讲解了如何利用Flowable的流程变量功能优化绩效评估流程,确保每个环节都能记录和更新分数,同时提供了全局和局部变量的对比和使用方法。
24 0
|
2月前
|
XML Java 数据库连接
SpringBoot集成Flowable:打造强大的工作流管理系统
在企业级应用开发中,工作流管理是一个核心组件,它能够帮助我们定义、执行和管理业务流程。Flowable是一个开源的工作流和业务流程管理(BPM)平台,它提供了强大的工作流引擎和建模工具。结合SpringBoot,我们可以快速构建一个高效、灵活的工作流管理系统。本文将探讨如何将Flowable集成到SpringBoot应用中,并展示其强大的功能。
483 1
|
2月前
|
缓存 监控 Java
|
2月前
|
缓存 监控 Java
|
2月前
|
XML 存储 Java
SpringBoot集成Flowable:构建强大的工作流引擎
在企业级应用开发中,工作流管理是核心功能之一。Flowable是一个开源的工作流引擎,它提供了BPMN 2.0规范的实现,并且与SpringBoot框架完美集成。本文将探讨如何使用SpringBoot和Flowable构建一个强大的工作流引擎,并分享一些实践技巧。
281 0