当前位置:   article > 正文

springboot 集成flowable_springboot集成flowable

springboot集成flowable

 本文集成分两部分,代码集成和界面集成,代码集成在IDE里面,界面集成直接使用官方下载的war包使用tomcat部署的。     

目录

一、代码集成 

1、Pom文件

2、配置文件

 3、代码文件

 4、流程文件

5、测试过程

5.1新增流程

5.2 第一步审批

5.3 第二部审批

5.4查看流程图

二、界面集成

2.1官网下载

 2.2 访问地址


一、代码集成 

1、Pom文件

  1. <dependencies>
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-web</artifactId>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.flowable</groupId>
  8. <artifactId>flowable-spring-boot-starter</artifactId>
  9. <version>6.3.0</version>
  10. </dependency>
  11. <dependency>
  12. <groupId>mysql</groupId>
  13. <artifactId>mysql-connector-java</artifactId>
  14. <version>8.0.20</version>
  15. </dependency>
  16. <dependency>
  17. <groupId>org.springframework.boot</groupId>
  18. <artifactId>spring-boot-starter-jdbc</artifactId>
  19. </dependency>
  20. </dependencies>

2、配置文件

  1. server:
  2. port: 8080
  3. spring:
  4. main:
  5. allow-bean-definition-overriding: true
  6. datasource:
  7. driver-class-name: com.mysql.cj.jdbc.Driver
  8. url: jdbc:mysql://localhost:3306/flowable?zeroDateTimeBehavior=convertToNull&serverTimezone=GMT%2B8&useSSL=false&useUnicode=yes&characterEncoding=utf8&autoReconnect=true&nullCatalogMeansCurrent=true
  9. username: root
  10. password: root
  11. flowable:
  12. async-executor-activate: false

 3、代码文件

代码结构如下图:

控制层:ExpenseController文件

  1. package com.example.flowable.controller;
  2. import org.flowable.bpmn.model.BpmnModel;
  3. import org.flowable.engine.*;
  4. import org.flowable.engine.runtime.Execution;
  5. import org.flowable.engine.runtime.ProcessInstance;
  6. import org.flowable.image.ProcessDiagramGenerator;
  7. import org.flowable.task.api.Task;
  8. import org.springframework.beans.factory.annotation.Autowired;
  9. import org.springframework.stereotype.Controller;
  10. import org.springframework.web.bind.annotation.RequestMapping;
  11. import org.springframework.web.bind.annotation.ResponseBody;
  12. import javax.servlet.http.HttpServletResponse;
  13. import java.io.InputStream;
  14. import java.io.OutputStream;
  15. import java.util.ArrayList;
  16. import java.util.HashMap;
  17. import java.util.List;
  18. /**
  19. * 报销demoController
  20. *
  21. */
  22. @Controller
  23. @RequestMapping(value = "expense")
  24. public class ExpenseController {
  25. @Autowired
  26. private RuntimeService runtimeService;
  27. @Autowired
  28. private TaskService taskService;
  29. @Autowired
  30. private RepositoryService repositoryService;
  31. @Autowired
  32. private ProcessEngine processEngine;
  33. /***************此处为业务代码******************/
  34. /**
  35. * 添加报销
  36. * @param userId 用户Id
  37. * @param money 报销金额
  38. * @param descption 描述
  39. */
  40. @RequestMapping(value = "add")
  41. @ResponseBody
  42. public String addExpense(String userId, Integer money, String descption) {
  43. //启动流程
  44. HashMap<String, Object> map = new HashMap<>();
  45. map.put("taskUser", userId);
  46. map.put("money", money);
  47. ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("Expense", map);
  48. return "提交成功.流程Id为:" + processInstance.getId();
  49. }
  50. /**
  51. * 获取审批管理列表
  52. */
  53. @RequestMapping(value = "/list")
  54. @ResponseBody
  55. public Object list(String userId) {
  56. List<Task> tasks = taskService.createTaskQuery().taskAssignee(userId).orderByTaskCreateTime().desc().list();
  57. for (Task task : tasks) {
  58. System.out.println(task.toString());
  59. }
  60. return tasks.toString();
  61. }
  62. /**
  63. * 批准
  64. *
  65. * @param taskId 任务ID
  66. */
  67. @RequestMapping(value = "apply")
  68. @ResponseBody
  69. public String apply(String taskId) {
  70. Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
  71. if (task == null) {
  72. throw new RuntimeException("流程不存在");
  73. }
  74. //通过审核
  75. HashMap<String, Object> map = new HashMap<>();
  76. map.put("outcome", "通过");
  77. taskService.complete(taskId, map);
  78. return "processed ok!";
  79. }
  80. /**
  81. * 拒绝
  82. */
  83. @ResponseBody
  84. @RequestMapping(value = "reject")
  85. public String reject(String taskId) {
  86. HashMap<String, Object> map = new HashMap<>();
  87. map.put("outcome", "驳回");
  88. taskService.complete(taskId, map);
  89. return "reject";
  90. }
  91. /**
  92. * 生成流程图
  93. *
  94. * @param processId 任务ID
  95. */
  96. @RequestMapping(value = "processDiagram")
  97. public void genProcessDiagram(HttpServletResponse httpServletResponse, String processId) throws Exception {
  98. ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(processId).singleResult();
  99. //流程走完的不显示图
  100. if (pi == null) {
  101. return;
  102. }
  103. Task task = taskService.createTaskQuery().processInstanceId(pi.getId()).singleResult();
  104. //使用流程实例ID,查询正在执行的执行对象表,返回流程实例对象
  105. String InstanceId = task.getProcessInstanceId();
  106. List<Execution> executions = runtimeService
  107. .createExecutionQuery()
  108. .processInstanceId(InstanceId)
  109. .list();
  110. //得到正在执行的Activity的Id
  111. List<String> activityIds = new ArrayList<>();
  112. List<String> flows = new ArrayList<>();
  113. for (Execution exe : executions) {
  114. List<String> ids = runtimeService.getActiveActivityIds(exe.getId());
  115. activityIds.addAll(ids);
  116. }
  117. //获取流程图
  118. BpmnModel bpmnModel = repositoryService.getBpmnModel(pi.getProcessDefinitionId());
  119. ProcessEngineConfiguration engconf = processEngine.getProcessEngineConfiguration();
  120. ProcessDiagramGenerator diagramGenerator = engconf.getProcessDiagramGenerator();
  121. InputStream in = diagramGenerator.generateDiagram(bpmnModel, "png", activityIds, flows, engconf.getActivityFontName(), engconf.getLabelFontName(), engconf.getAnnotationFontName(), engconf.getClassLoader(), 1.0);
  122. OutputStream out = null;
  123. byte[] buf = new byte[1024];
  124. int legth = 0;
  125. try {
  126. out = httpServletResponse.getOutputStream();
  127. while ((legth = in.read(buf)) != -1) {
  128. out.write(buf, 0, legth);
  129. }
  130. } finally {
  131. if (in != null) {
  132. in.close();
  133. }
  134. if (out != null) {
  135. out.close();
  136. }
  137. }
  138. }
  139. }

 业务文件:

  1. package com.example.flowable.handler;
  2. import org.flowable.engine.delegate.TaskListener;
  3. import org.flowable.task.service.delegate.DelegateTask;
  4. public class BossTaskHandler implements TaskListener {
  5. @Override
  6. public void notify(DelegateTask delegateTask) {
  7. delegateTask.setAssignee("老板");
  8. }
  9. }
  1. package com.example.flowable.handler;
  2. import org.flowable.engine.delegate.TaskListener;
  3. import org.flowable.task.service.delegate.DelegateTask;
  4. public class ManagerTaskHandler implements TaskListener {
  5. @Override
  6. public void notify(DelegateTask delegateTask) {
  7. delegateTask.setAssignee("经理");
  8. }
  9. }

 配置文件

  1. package com.example.flowable.config;
  2. import org.flowable.spring.SpringProcessEngineConfiguration;
  3. import org.flowable.spring.boot.EngineConfigurationConfigurer;
  4. import org.springframework.context.annotation.Configuration;
  5. /**
  6. * 为解决flowable图片中的中文乱码
  7. *
  8. */
  9. @Configuration
  10. public class FlowableConfig implements EngineConfigurationConfigurer<SpringProcessEngineConfiguration> {
  11. @Override
  12. public void configure(SpringProcessEngineConfiguration engineConfiguration) {
  13. engineConfiguration.setActivityFontName("宋体");
  14. engineConfiguration.setLabelFontName("宋体");
  15. engineConfiguration.setAnnotationFontName("宋体");
  16. }
  17. }

 4、流程文件

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xmlns:flowable="http://flowable.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
  4. xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI"
  5. typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath"
  6. targetNamespace="http://www.flowable.org/processdef">
  7. <process id="Expense" name="ExpenseProcess" isExecutable="true">
  8. <documentation>报销流程</documentation>
  9. <startEvent id="start" name="开始"></startEvent>
  10. <userTask id="fillTask" name="出差报销" flowable:assignee="${taskUser}">
  11. <extensionElements>
  12. <modeler:initiator-can-complete xmlns:modeler="http://flowable.org/modeler">
  13. <![CDATA[false]]></modeler:initiator-can-complete>
  14. </extensionElements>
  15. </userTask>
  16. <exclusiveGateway id="judgeTask"></exclusiveGateway>
  17. <userTask id="directorTak" name="经理审批">
  18. <extensionElements>
  19. <flowable:taskListener event="create"
  20. class="com.example.flowable.handler.ManagerTaskHandler"></flowable:taskListener>
  21. </extensionElements>
  22. </userTask>
  23. <userTask id="bossTask" name="老板审批">
  24. <extensionElements>
  25. <flowable:taskListener event="create"
  26. class="com.example.flowable.handler.BossTaskHandler"></flowable:taskListener>
  27. </extensionElements>
  28. </userTask>
  29. <endEvent id="end" name="结束"></endEvent>
  30. <sequenceFlow id="directorNotPassFlow" name="驳回" sourceRef="directorTak" targetRef="fillTask">
  31. <conditionExpression xsi:type="tFormalExpression"><![CDATA[${outcome=='驳回'}]]></conditionExpression>
  32. </sequenceFlow>
  33. <sequenceFlow id="bossNotPassFlow" name="驳回" sourceRef="bossTask" targetRef="fillTask">
  34. <conditionExpression xsi:type="tFormalExpression"><![CDATA[${outcome=='驳回'}]]></conditionExpression>
  35. </sequenceFlow>
  36. <sequenceFlow id="flow1" sourceRef="start" targetRef="fillTask"></sequenceFlow>
  37. <sequenceFlow id="flow2" sourceRef="fillTask" targetRef="judgeTask"></sequenceFlow>
  38. <sequenceFlow id="judgeMore" name="大于500元" sourceRef="judgeTask" targetRef="bossTask">
  39. <conditionExpression xsi:type="tFormalExpression"><![CDATA[${money > 500}]]></conditionExpression>
  40. </sequenceFlow>
  41. <sequenceFlow id="bossPassFlow" name="通过" sourceRef="bossTask" targetRef="end">
  42. <conditionExpression xsi:type="tFormalExpression"><![CDATA[${outcome=='通过'}]]></conditionExpression>
  43. </sequenceFlow>
  44. <sequenceFlow id="directorPassFlow" name="通过" sourceRef="directorTak" targetRef="end">
  45. <conditionExpression xsi:type="tFormalExpression"><![CDATA[${outcome=='通过'}]]></conditionExpression>
  46. </sequenceFlow>
  47. <sequenceFlow id="judgeLess" name="小于500元" sourceRef="judgeTask" targetRef="directorTak">
  48. <conditionExpression xsi:type="tFormalExpression"><![CDATA[${money <= 500}]]></conditionExpression>
  49. </sequenceFlow>
  50. </process>
  51. <bpmndi:BPMNDiagram id="BPMNDiagram_Expense">
  52. <bpmndi:BPMNPlane bpmnElement="Expense" id="BPMNPlane_Expense">
  53. <bpmndi:BPMNShape bpmnElement="start" id="BPMNShape_start">
  54. <omgdc:Bounds height="30.0" width="30.0" x="285.0" y="135.0"></omgdc:Bounds>
  55. </bpmndi:BPMNShape>
  56. <bpmndi:BPMNShape bpmnElement="fillTask" id="BPMNShape_fillTask">
  57. <omgdc:Bounds height="80.0" width="100.0" x="405.0" y="110.0"></omgdc:Bounds>
  58. </bpmndi:BPMNShape>
  59. <bpmndi:BPMNShape bpmnElement="judgeTask" id="BPMNShape_judgeTask">
  60. <omgdc:Bounds height="40.0" width="40.0" x="585.0" y="130.0"></omgdc:Bounds>
  61. </bpmndi:BPMNShape>
  62. <bpmndi:BPMNShape bpmnElement="directorTak" id="BPMNShape_directorTak">
  63. <omgdc:Bounds height="80.0" width="100.0" x="735.0" y="110.0"></omgdc:Bounds>
  64. </bpmndi:BPMNShape>
  65. <bpmndi:BPMNShape bpmnElement="bossTask" id="BPMNShape_bossTask">
  66. <omgdc:Bounds height="80.0" width="100.0" x="555.0" y="255.0"></omgdc:Bounds>
  67. </bpmndi:BPMNShape>
  68. <bpmndi:BPMNShape bpmnElement="end" id="BPMNShape_end">
  69. <omgdc:Bounds height="28.0" width="28.0" x="771.0" y="281.0"></omgdc:Bounds>
  70. </bpmndi:BPMNShape>
  71. <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
  72. <omgdi:waypoint x="315.0" y="150.0"></omgdi:waypoint>
  73. <omgdi:waypoint x="405.0" y="150.0"></omgdi:waypoint>
  74. </bpmndi:BPMNEdge>
  75. <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
  76. <omgdi:waypoint x="505.0" y="150.16611295681062"></omgdi:waypoint>
  77. <omgdi:waypoint x="585.4333333333333" y="150.43333333333334"></omgdi:waypoint>
  78. </bpmndi:BPMNEdge>
  79. <bpmndi:BPMNEdge bpmnElement="judgeLess" id="BPMNEdge_judgeLess">
  80. <omgdi:waypoint x="624.5530726256983" y="150.44692737430168"></omgdi:waypoint>
  81. <omgdi:waypoint x="735.0" y="150.1392757660167"></omgdi:waypoint>
  82. </bpmndi:BPMNEdge>
  83. <bpmndi:BPMNEdge bpmnElement="directorNotPassFlow" id="BPMNEdge_directorNotPassFlow">
  84. <omgdi:waypoint x="785.0" y="110.0"></omgdi:waypoint>
  85. <omgdi:waypoint x="785.0" y="37.0"></omgdi:waypoint>
  86. <omgdi:waypoint x="455.0" y="37.0"></omgdi:waypoint>
  87. <omgdi:waypoint x="455.0" y="110.0"></omgdi:waypoint>
  88. </bpmndi:BPMNEdge>
  89. <bpmndi:BPMNEdge bpmnElement="bossPassFlow" id="BPMNEdge_bossPassFlow">
  90. <omgdi:waypoint x="655.0" y="295.0"></omgdi:waypoint>
  91. <omgdi:waypoint x="771.0" y="295.0"></omgdi:waypoint>
  92. </bpmndi:BPMNEdge>
  93. <bpmndi:BPMNEdge bpmnElement="judgeMore" id="BPMNEdge_judgeMore">
  94. <omgdi:waypoint x="605.4340277777778" y="169.56597222222223"></omgdi:waypoint>
  95. <omgdi:waypoint x="605.1384083044983" y="255.0"></omgdi:waypoint>
  96. </bpmndi:BPMNEdge>
  97. <bpmndi:BPMNEdge bpmnElement="directorPassFlow" id="BPMNEdge_directorPassFlow">
  98. <omgdi:waypoint x="785.0" y="190.0"></omgdi:waypoint>
  99. <omgdi:waypoint x="785.0" y="281.0"></omgdi:waypoint>
  100. </bpmndi:BPMNEdge>
  101. <bpmndi:BPMNEdge bpmnElement="bossNotPassFlow" id="BPMNEdge_bossNotPassFlow">
  102. <omgdi:waypoint x="555.0" y="295.0"></omgdi:waypoint>
  103. <omgdi:waypoint x="455.0" y="295.0"></omgdi:waypoint>
  104. <omgdi:waypoint x="455.0" y="190.0"></omgdi:waypoint>
  105. </bpmndi:BPMNEdge>
  106. </bpmndi:BPMNPlane>
  107. </bpmndi:BPMNDiagram>
  108. </definitions>

5、测试过程

5.1新增流程

http://localhost:8080/expense/add?userId=100&money=123321

界面显示:提交成功.流程Id为:5009 

5.2 第一步审批

http://localhost:8080/expense/list?userId=100

界面显示:[Task[id=5015, name=出差报销]] 

5.3 第二部审批

http://localhost:8080/expense/apply?taskId=5015

界面显示:processed ok! 

5.4查看流程图

http://localhost:8080/expense/processDiagram?processId=5009

二、界面集成

2.1官网下载

下载地址:Flowable Open Source Code

下载完成后,解压如下图:

 把war包拷贝到tomcat下面,如下图:

 解压war包,修改里面的配置文件:flowable-default.properties

如下:我的mysql是8.0.20的,需要把对于的驱动jar包拷贝到tomcat的lib目录下

  1. spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
  2. spring.datasource.url=jdbc:mysql://localhost:3306/flowable?zeroDateTimeBehavior=convertToNull&serverTimezone=GMT%2B8&useSSL=false&useUnicode=yes&characterEncoding=utf8&autoReconnect=true&nullCatalogMeansCurrent=true
  3. spring.datasource.username=root
  4. spring.datasource.password=root

 2.2访问地址

我这儿是两个文件:

flowable-ui和flowable-rest,把里面对应的配置文件都改了,启动tomcat.

访问:http://localhost:8080/flowable-ui/#/

登录,账户名密码默认:admin/test;

在流程引擎里面可以看到已经连接到自己配置的数据库。

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/天景科技苑/article/detail/982812
推荐阅读
相关标签
  

闽ICP备14008679号