Springboot +Flowable,流程表单应用之外置表单(HTML形式)(一)

news/2024/10/30 9:32:34/

一.简介

整体上来说,我们可以将Flowable 的表单分为三种不同的类型:

  1. 动态表单
    这种表单定义方式我们可以配置表单中每一个字段的可读性、可写性、是否必填等信息,不过不能定义完整的表单页面。
  2. 外置表单
    外置表单我们只需要定义一下表单的 key,至于这个 key 对应的表单是什么样子,则由开发者自己去维护。
  3. 内置表单
    这是内置的表单定义以及渲染引擎,

另外需要注意的,Flowable 中有很多不同类型的节点,但是只有开始节点和任务节点是支持表单定义的,其他节点均不支持表单定义

二.外置表单

所谓的外置表单,其实说白了,类似平时在 HTML 中写的 form 表单。

现在的 flowable 中,我们既可以利用 JSON 的形式来定义 form 表单,也可以直接就使用 HTML 来定义。

现在假设有一个请假流程,截图如下:
在这里插入图片描述
在开始节点中,需要一个表单来输入用户提交的请假信息,在组长审批和经理审批这两个节点中希望能够看到用户提交的请假信息,那么准备两个表单文件,第一个是提交请假信息的表单文件 askleave.html,代码如下:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<form action=""><table><tr><td>请假天数:</td><td><input type="text" name="days"></td></tr><tr><td>请假理由:</td><td><input type="text" name="reason"></td></tr><tr><td>起始时间:</td><td><input type="date" name="startTime"></td></tr><tr><td>结束时间:</td><td><input type="date" name="endTime"></td></tr><tr><td><input type="submit" value="提交"></td></tr></table>
</form>
</body>
</html>

这其实就是一个普通的 HTML 页面,这里为了省事,就没写 form 的 action 了。

还有一个是查看用户提交的请假信息的表单 leader_approval.html,代码如下:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<form action=""><table><tr><td>请假天数:</td><td><input type="text" name="days" value="${days}"></td></tr><tr><td>请假理由:</td><td><input type="text" name="reason" value="${reason}"></td></tr><tr><td>起始时间:</td><td><input type="date" name="startTime" value="${startTime}"></td></tr><tr><td>结束时间:</td><td><input type="date" name="endTime" value="${endTime}"></td></tr><tr><td><input type="submit" value="提交"></td></tr></table>
</form>
</body>
</html>

和前面的 askleave.html 文件相比,leader_approval.html 文件中,各个表单属性只是多了 value 属性而已,value 给了一个预填的变量,其他都是一样的。

两个表单文件定义完成之后,接下来为流程来配置这两个表单文件,如下图,为开始节点设置表单 key 为 askforleave.html,为组长审批和经理审批节点设置表单 key 为 leader_approval.html:
在这里插入图片描述
在这里插入图片描述
注意:在Spring Boot 项目中,外置表单默认放在 resources/forms 目录下,也就是说,凡是放在这个目录下的表单文件,会被自动部署(要求文件后缀为 .form)。

这样流程图就准备完成了。

三.流程部署

外置表单的部署需要和流程图一起部署,只有一起部署,他们才会有相同的 DEPLOYMENT_ID,否则两者的 DEPLOYMENT_ID 不同,在后续的查找中就找不到对应的表单。

因此,来修改一下流程部署的接口:代码如下:

@RestController
public class ProcessDeployController {@AutowiredRepositoryService repositoryService;@PostMapping("/deploy")public RespBean deploy(MultipartFile[] files) throws IOException {System.out.println(new Date());DeploymentBuilder deploymentBuilder = repositoryService.createDeployment().category("javaboy的工作流分类").name("javaboy的工作流名称").key("javaboy的工作流key666");for (int i = 0; i < files.length; i++) {MultipartFile file = files[i];deploymentBuilder.addInputStream(file.getOriginalFilename(), file.getInputStream());}Deployment deployment = deploymentBuilder.deploy();return RespBean.ok("部署成功", deployment.getId());}
}

这里将上传文件改为了数组,也就是流程图、form 表单等统统都以文件的形式上传,然后在部署的时候,统一都调用 addInputStream 方法进行添加。

来看下使用postman 部署的方式,截图如下:
在这里插入图片描述
部署成功之后,来看下 ACT_GE_BYTEARRAY 表中的记录,截图如下:

在这里插入图片描述
四条记录具有相同的 DEPLOYMENT_ID,这一点尤为重要。

四.流程开启与执行

在流程开启之前,首先可以通过如下方式查询启动节点上的表单内容,代码如下:

@Test
void test05() {ProcessDefinition pd = repositoryService.createProcessDefinitionQuery().latestVersion().processDefinitionKey("FormDemo02").singleResult();String startFormKey = formService.getStartFormKey(pd.getId());String renderedStartForm = (String) formService.getRenderedStartForm(pd.getId());System.out.println("startFormKey = " + startFormKey);System.out.println("renderedStartForm = " + renderedStartForm);
}

控制台输出的内容截图如下:
在这里插入图片描述
可以看到,表单的内容就被输出来了。
如果这里是一个 Web 工程,那么可以通过 Ajax 来请求到这个表单数据,并动态渲染到前端,然后在前端输入对应的值,点击提交按钮,就可以在服务端开启一个流程了。

服务端开启流程方式,代码如下:

@Test
void test02() {ProcessDefinition pd = repositoryService.createProcessDefinitionQuery().processDefinitionKey("FormDemo02").latestVersion().singleResult();Map<String, String> vars = new HashMap<>();vars.put("startTime", "2022-10-10 10:10");vars.put("endTime", "2022-10-12 10:10");vars.put("reason", "玩两天");vars.put("days", "3");ProcessInstance pi = formService.submitStartFormData(pd.getId(), vars);
}

调用 submitStartFormData 方法来开启一个流程,这里参数直接硬编码了。

流程开启之后,接下来组长 zhangsan 要来审批这个流程,审批之前他需要先查看一下用户提交的表单信息,代码如下:

@Test
void test06() {Task task = taskService.createTaskQuery().taskAssignee("zhangsan").singleResult();String renderedTaskForm = (String) formService.getRenderedTaskForm(task.getId());System.out.println("renderedTaskForm = " + renderedTaskForm);
}

这个 getRenderedTaskForm 方法只有外置表单才有,动态表单调用这个方法是没有东西的,因为动态表单单纯的就只是变量的传递,不涉及到渲染问题,来看下这里打印出来的结果如下图所示:
在这里插入图片描述
和前面的表单相比,这里的表单都渲染出来了对应的值。如果这是一个 Web 项目,那么就可以使用 Ajax 请求这个渲染后的表单,并展示在前端页面。当然实际审批中,这里可以有更多的字段,组长填完之后,进入到下一个环节。

zhangsan 进行流程审批,代码如下:

@Test
void test08() {Task task = taskService.createTaskQuery().taskAssignee("zhangsan").singleResult();Map<String, String> vars = new HashMap<>();vars.put("startTime", "2022-10-30 10:10");vars.put("endTime", "2022-12-30 10:10");vars.put("reason", "玩十天");vars.put("days", "10");formService.submitTaskFormData(task.getId(),vars);
}

可以使用 formService#submitTaskFormData 方法进行审批,也可以使用 taskService.complete 方法进行审批。


http://www.ppmy.cn/news/70255.html

相关文章

ruby打开文件的不同模式

在 Ruby 中&#xff0c;打开文件时可以使用不同的模式来指定文件的读写方式。以下是 Ruby 中打开文件的不同模式&#xff1a; r 只读模式&#xff0c;打开文件后只能读取文件内容&#xff0c;不能修改文件内容。r读写模式&#xff0c;打开文件后既可以读取文件内容&#xff0…

前端换肤,聊一聊主题切换那些事

一些网站通常会提供白天、夜间模式&#xff0c;以及自定义主题等等&#xff0c;这种主题切换也就是本文说的前端换肤。 这次案例用的是白天和夜间模式的切换&#xff0c;在做换肤之前&#xff0c;得先知道一件事情&#xff1a;css的变量定义&#xff0c;对变量定义不熟悉的同学…

Android MVVN 使用入门

MVVM&#xff08;Model-View-ViewModel&#xff09;是一种基于数据绑定的设计模式&#xff0c;它与传统的 MVC 和 MVP 模式相比&#xff0c;更加适合处理复杂的 UI 逻辑和数据展示。在 Android 开发中&#xff0c;MVVM 通常使用 Data Binding 和 ViewModel 实现。 下面是一个简…

小黑子—Java从入门到入土过程:第九章-IO流

Java零基础入门9.0 Java系列第九章- IO流1. 初识IO流2. IO流的体系2.1 字节流2.1.1 FileOutputStream 字符串输出流2.1.1 - I 字符串输出流的细节2.1.1 - II FileOutputStream写数据的3种方式2.1.1 -III FileOutputStream写数据的两个小问题 2.1.2 FileInputStream 字符串输入流…

Vue3 实现模态框组件

基于 Vue 3 实现模态框&#xff0c;并且单击遮罩层可关闭模态框 下面是一个基于 Vue 3 实现的模态框&#xff0c;并且点击遮罩层可关闭模态框的示例代码&#xff1a; <template><div class"modal-wrapper" v-show"visible" click.self"clos…

Mysql中select语句的执行流程?

Mysql中select语句的执行流程&#xff1f; 答&#xff1a; SELECT 语句的执行过程为&#xff1a;连接、查询缓存、a词法分析&#xff0c;语法分析&#xff0c;语义分析&#xff0c;构造执行树&#xff0c;生成执行计划、执行器执行计划&#xff0c;下面开始梳理一次完整的查询…

对SRC并发漏洞挖掘的思考

对SRC并发漏洞挖掘的思考 1.burpsuite Turbo插件使用2.并发点赞测试3.并发验证码测试4.某代金券逻辑测试5.有限制的并发验证码绕过6.对于并发漏洞的思考 1.burpsuite Turbo插件使用 Turbo Intruder是一个用于发送大量HTTP请求并会分析其结果的Burp Suite扩展。它旨在补充Burp …

JWT 入门

1.介绍 JSON Web Token&#xff08;JWT&#xff09;是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准。这个规范允许我们使用JWT在用户和服务器之间传递安全可靠的信息。该token被设计为紧凑且安全的&#xff0c;特别适用于分布式站点的单点登录&#xff08;SSO…