SpringBoot整合Flowable【05】- 使用流程变量传递业务数据

简介: 本文介绍了如何使用Flowable的流程变量来管理绩效流程中的自定义数据。首先回顾了之前的简单绩效流程,指出现有流程缺乏分数输入和保存步骤。接着详细解释了流程变量的定义、分类(运行时变量和历史变量)及类型。通过具体代码示例展示了如何在绩效流程中插入全局和局部流程变量,实现各节点打分并维护分数的功能。最后总结了流程变量的使用场景及其在实际业务中的灵活性,并承诺将持续更新Flowable系列文章,帮助读者更好地理解和应用Flowable。简要来说,本文通过实例讲解了如何利用Flowable的流程变量功能优化绩效评估流程,确保每个环节都能记录和更新分数,同时提供了全局和局部变量的对比和使用方法。

一、前情回顾

在04篇中,我们用代码的形式控制了一个简单的绩效流程的运转,并且基本熟悉了流程运行过程中涉及到的相关表。让我们继续回到这个简单的绩效流程,它依然是有所欠缺的,比如在实际业务场景中,我们在绩效的每个环节都应该有个分数,但目前我们只是指派个人去完成各个节点,并没有输入分数和保存分数的步骤。因此,在今天的文章中,我们将使用Flowable包含的流程变量来管理流程中的自定义数据。

二、认识流程变量

1.定义

首先,我们来看下流程变量的官方定义:在Flowable中,流程变量是在流程实例按步骤执行时需要保存并使用的数据,这些数据被称为变量(variable)。流程实例可以持有变量,这些变量被称为流程变量。

我们目前只需要知道变量可以在Java服务任务中用于调用外部服务(例如为服务调用提供输入或结果存储),参考上面绩效分数的例子。我们在实际业务中执行任何流程都可能涉及到有数据流转,流程变量负责的就是在流程流转的过程中传递业务参数。

2.分类

为了提高使用效率,Flowable将变量分为两种:运行时变量和历史变量:

  • 运行时变量:这是流程实例运行时的变量,存入act_ru_variable表中。在流程实例运行结束时,此实例的变量在表中删除。在流程实例创建及启动时,可以设置流程变量,也可以在流程执行中加入变量。由于流程实例结束时,对应在运行时表的数据跟着被删除,所以,查询一个已经完结流程实例的变量,只能在历史变量表中查找。

  • 历史变量:历史变量存入act_hi_varinst表中。在流程启动时,流程变量会同时存入历史变量表中。这样即使在流程结束时,历史表中的变量仍然存在。这里可以想想前文中的历史流程也是这样,在Flowable的设计中,我们一个流程启动到结束过程中涉及到的所有东西都可以在相应的历史表上查到。

    3.类型

    一般来说,一个变量由一个名称和值组成,就是个经典的KV结构。K是字符串类型的,V可以是基本数据类型,也可以是个Java对象(Ps:实现了Serializable接口)。如果流程变量名称相同的时候,后一次的值替换前一次的值。

三、使用流程变量

说了这么多,接下来让我们在我们前面定义的绩效流程中加入流程变量的使用,在自评阶段就需要打分,然后上级评和隔级评都需要打分,并且最后隔级评给出的分数权重最大,也就是本次绩效的最终的分数。

1.接口优化

部署流程模型就不赘述了,详情请翻阅04篇,这里主要为了更贴近实际,部署流程后返回流程定义id,这样前端拿到流程定义id也就可以发起请求来启动流程了,这里大家具体看下代码,和原本相比,多了第2步:

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

2.插入全局流程变量

完成了流程的部署后就可以启动流程了,因为我们在部署成功之后返回了流程定义id,那么这里就可以传参调用了。我们也需要在这时创建这个分数变量,大家可以在这里结合具体场景想想,作为执行层是不是得在完成自评前写好自评分数然后提交。于是我们对原有的启动流程接口进行改造:

/**
 * 启动流程.
 *
 * @return 流程key
 */
@PostMapping("/start/{processId}")
public ResponseEntity<Object> startProcessDef(@PathVariable String processId) {
   
    //1.启动流程
    ProcessInstance processInstance = runtimeService.startProcessInstanceById(processId);
    //2.维护该流程的分数变量
    runtimeService.setVariable(processInstance.getId(), "score", 0);
    //3.返回流程实例对象id
    return new ResponseEntity<>(new BaseResponse<>(processInstance.getId()), HttpStatus.OK);
}

在原有代码的基础上我们通过runtimeService设置了一个流程变量,这个流程变量是全局的,也就是这个流程没结束的情况下都可以查到并且进行维护,相同key的value会被最新的覆盖,我们执行这个接口后看下act_ru_variable表的变化:
1.png

2.png
在这张流程变量表上我们可以看到多了一条数据,注意看我圈起来的3个字段:NAMETEXT很明了,就对应着前面的key和value,这个EXECUTION_ID则是我们设置的流程实例ID,如果我们不设置,引擎也会自动生成,我这里只是方便演示这么做的(Ps:不建议自己改,因为当你的流程有分支时,这个执行ID它就是动态的),我们要通过这个执行ID进行对应变量的查询与维护(Ps:再次强调,这张表只负责运行时变量)。

3.维护流程变量

既然在启动流程的时候设置了变量,那么在接下来的每个节点都可以对变量进行更新,从而实现我们提到的需求,通过前面设置的执行ID查询关联的变量,并根据key对value进行维护,代码如下:

@PostMapping("/complete/agentUser/{agentUser}/score/{score}/processInstanceId/{processInstanceId}")
public ResponseEntity<Object> completeTask(@PathVariable String agentUser,
                                           @PathVariable String score,
                                           @PathVariable String processInstanceId) {
   
    //1.查询指定用户的待办任务
    String agentTaskId = findUserAgentTask(agentUser);
    //2.更新绩效流程变量
    runtimeService.setVariable(processInstanceId, "score", score);
    //3.完成指定任务的审批
    taskService.complete(agentTaskId);
    //4.返回响应
    return new ResponseEntity<>(new BaseResponse<>(null), HttpStatus.OK);
}

然后使用Apifox进行接口测试,对比04篇这个接口多了两个参数,分别是分数和流程实例ID。我说明下分数在实际场景中肯定是用户填写后由前端传来的;而流程实例ID在前面的启动流程中我们也有返回,所以前端同学也能拿到:
3.png
执行成功后,我们再去观察下act_ru_variable表中的那条流程变量,会发现它也同步更新了:
4.png
那么我们这里结合实际场景思考下,在我们现在设计的这套流程里,是不是每个节点都能通过流程ID查询并维护这个分数变量从而实现前面提到的业务需求。需要注意的是:我这里只是假设的业务场景,所以各位读者在自己实操的时候要根据自己业务需求来做,这个系列的文章主要目的是尽可能帮各位读者理清各种表的作用和各种API的用法。

4.查询历史变量

当我们这个流程执行结束的时候,act_ru_variable表中的这条数据就消失了:
5.png
这时候我们想再查到它就需要到act_hi_varinst表里,也就是流程变量历史表,通过流程ID就可以查到它,那么大家想想如果业务需要查询历史绩效包括分数,是不是就很简单了:
6.png

5.插入局部流程变量

02小标题进行对比,我们发现区别在于一个是全局,另一个是局部。大家观察下前面的部分里的流程变量在这个流程没结束前,任何节点都可以查询和维护,可以理解成它的生命周期伴随着那个流程。但局部流程变量是我们在某个节点声明,一旦这个节点执行过之后,它就和节点的任务一样都只能去历史表里查询了,所以全局和局部最大的区别就是生命周期的不同。

知道了它们的区别,接下来我们看看怎么使用,首先runtimeServicetaskService都可以设置流程变量,这里主要是API的变化,代码如下:

@PostMapping("/complete/agentUser/{agentUser}/score/{score}/processInstanceId/{processInstanceId}")
public ResponseEntity<Object> completeTask(@PathVariable String agentUser,
                                           @PathVariable String score,
                                           @PathVariable String processInstanceId) {
   
    //1.查询指定用户的待办任务
    String agentTaskId = findUserAgentTask(agentUser);
    //2.更新绩效流程变量
    runtimeService.setVariable(processInstanceId, "score", score);
    //3.设置任务节点流程变量
    taskService.setVariableLocal(agentTaskId, "score2", score);
    //4.完成指定任务的审批
    taskService.complete(agentTaskId);
    //5.返回响应
    return new ResponseEntity<>(new BaseResponse<>(null), HttpStatus.OK);
}

03处就是在设置局部流程变量,我在完成任务接口上设置了一个任务节点变量,也就是当我执行这个接口后,只能在历史表里看到这条score2的数据,调用接口测试下:
7.png
执行成功后,我们再去act_hi_varinst表查看有没有key为score2的数据:
8.png
可以看到此时key为score2的流程变量直接在历史表里,大家需要明白的是,无论是全局流程变量和局部流程变量都需要结合实际业务需求与场景进行使用,我这里只是告诉大家有这么个东西,在项目中怎么用是需要思考的,假设我们当前的这个绩效流程需要查询绩效历史的时候同时展示各个历史节点的分数,大家想想这个局部流程变量是不是就可以派上用场了。但是这也只是一种实现思路,其实用全局流程变量也可以实现,在每个节点设置变量的时候多设置一下,这个新变量在原key的基础上加上任务id,后续它就不会被覆盖了。所以API是很丰富的,主要看大家想怎么用。

6.补充

在这里补充一下,runtimeService也有设置局部流程变量,但传的ID是会影响结果的。如果你传的是流程ID,它就是全局,即使你用这个API;如果你传的是任务ID,它则是关联对应任务的局部流程变量。

runtimeService.setVariableLocal(XXId, "score", score);

四、小结

首先对一直支持该系列的读者表示感谢,同时也对大家表示抱歉,由于近期工作较忙,导致文章更新速度较慢。其实一开始写这个系列只是想让自己回顾下,但是随着慢慢的更新,开始有读者在评论区“催更”,让我看到了这个系列是有价值的,确实可以帮到别人,所以我也会持续更新下去的,给大家打个包票该系列至少更新10篇,尽可能地为大家详细介绍Flowable的用法以及引导大家结合实际业务进行思考。另外,个人水平毕竟有限,如果文章中有错误的地方,也欢迎大家批评指正!

目录
相关文章
|
3天前
|
前端开发 Java API
SpringBoot整合Flowable【06】- 查询历史数据
本文介绍了Flowable工作流引擎中历史数据的查询与管理。首先回顾了流程变量的应用场景及其局限性,引出表单在灵活定制流程中的重要性。接着详细讲解了如何通过Flowable的历史服务API查询用户的历史绩效数据,包括启动流程、执行任务和查询历史记录的具体步骤,并展示了如何将查询结果封装为更易理解的对象返回。最后总结了Flowable提供的丰富API及其灵活性,为后续学习驳回功能做了铺垫。
11 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代码控制流程的方法。
23 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完成节点回退,并清理相关脏数据(如历史任务和变量)。最后通过测试验证了驳回功能的正确性,确保流程能够成功回退到指定节点并清除中间产生的冗余数据。此功能在实际业务中非常有用,能够满足上级驳回自评等需求。
18 0
|
3天前
|
XML 前端开发 Java
SpringBoot整合Flowable【04】- 通过代码控制流程流转
本文介绍了如何使用Flowable的Java API控制流程流转,基于前文构建的绩效流程模型。首先,通过Flowable-UI导出模型文件并部署到Spring Boot项目中。接着,详细讲解了如何通过代码部署、启动和审批流程,涉及`RepositoryService`、`RuntimeService`和`TaskService`等核心服务类的使用。最后,通过实际操作演示了流程从部署到完成的全过程,并简要说明了相关数据库表的变化。本文帮助读者初步掌握Flowable在实际业务中的应用,后续将深入探讨更多高级功能。
19 0
|
2月前
|
SQL 前端开发 关系型数据库
SpringBoot使用mysql查询昨天、今天、过去一周、过去半年、过去一年数据
SpringBoot使用mysql查询昨天、今天、过去一周、过去半年、过去一年数据
81 9
|
2月前
|
XML Java 数据库连接
SpringBoot集成Flowable:打造强大的工作流管理系统
在企业级应用开发中,工作流管理是一个核心组件,它能够帮助我们定义、执行和管理业务流程。Flowable是一个开源的工作流和业务流程管理(BPM)平台,它提供了强大的工作流引擎和建模工具。结合SpringBoot,我们可以快速构建一个高效、灵活的工作流管理系统。本文将探讨如何将Flowable集成到SpringBoot应用中,并展示其强大的功能。
483 1
|
2月前
|
存储 easyexcel Java
SpringBoot+EasyExcel轻松实现300万数据快速导出!
本文介绍了在项目开发中使用Apache POI进行数据导入导出的常见问题及解决方案。首先比较了HSSFWorkbook、XSSFWorkbook和SXSSFWorkbook三种传统POI版本的优缺点,然后根据数据量大小推荐了合适的使用场景。接着重点介绍了如何使用EasyExcel处理超百万数据的导入导出,包括分批查询、分批写入Excel、分批插入数据库等技术细节。通过测试,300万数据的导出用时约2分15秒,导入用时约91秒,展示了高效的数据处理能力。最后总结了公司现有做法的不足,并提出了改进方向。
|
2月前
|
XML 存储 Java
SpringBoot集成Flowable:构建强大的工作流引擎
在企业级应用开发中,工作流管理是核心功能之一。Flowable是一个开源的工作流引擎,它提供了BPMN 2.0规范的实现,并且与SpringBoot框架完美集成。本文将探讨如何使用SpringBoot和Flowable构建一个强大的工作流引擎,并分享一些实践技巧。
281 0