Flowable集成springboot

1.创建springboot项目

1.1 引入依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.lidoudou</groupId>
  <artifactId>FlowableTest</artifactId>
  <version>1.0</version>


  <properties>
    <java.version>1.8</java.version>
  </properties>

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.6.4</version>
    <relativePath/>
  </parent>

  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
      <groupId>org.flowable</groupId>
      <artifactId>flowable-spring-boot-starter</artifactId>
      <version>6.7.2</version>
    </dependency>

    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.32</version>
    </dependency>

    <!--springboot程序测试依赖,如果是自动创建项目默认添加-->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-test</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <scope>test</scope>
    </dependency>


    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
    </dependency>
  </dependencies>


</project>

1.2 配置yml

spring:
  datasource:
    username: root
    password: root
    url: jdbc:mysql:///flowable?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8&autoReconnect=true
    driver-class-name: com.mysql.cj.jdbc.Driver

server:
  port: 8080

1.3 启动项目

附件:项目目录

启动成功后会自动帮我们创建flowable所需要的表格

2.画流程图

2.1 安装IDEA 插件 Flowable BPMN visualizer

2.2 开始画一个简单的流程图

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:flowable="http://flowable.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.flowable.org/processdef">
    <process id="ask_for_leave" name="ask_for_leave" isExecutable="true">
        <userTask id="leaveTask" name="请假" flowable:assignee="#{leaveTask}"/>
        <userTask id="zuzhangTask" name="组长审核" flowable:assignee="#{zuzhangTask}"/>
        <userTask id="managerTask" name="经理审核" flowable:assignee="#{managerTask}"/>
        <exclusiveGateway id="managerJudgeTask"/>
        <exclusiveGateway id="zuzhangJudeTask"/>
        <endEvent id="endLeave" name="结束"/>
        <startEvent id="startLeave" name="开始"/>
        <sequenceFlow id="flowStart" sourceRef="startLeave" targetRef="leaveTask"/>
        <sequenceFlow id="modeFlow" sourceRef="leaveTask" targetRef="zuzhangTask"/>
        <sequenceFlow id="zuzhang_go" sourceRef="zuzhangJudeTask" targetRef="managerTask" name="通过">
            <conditionExpression xsi:type="tFormalExpression"><![CDATA[${checkResult=='通过'}]]></conditionExpression>
        </sequenceFlow>
        <sequenceFlow id="zuzhang_reject" sourceRef="zuzhangJudeTask" targetRef="sendMail" name="拒绝">
            <conditionExpression xsi:type="tFormalExpression"><![CDATA[${checkResult=='拒绝'}]]></conditionExpression>
        </sequenceFlow>
        <sequenceFlow id="jugdeFlow" sourceRef="managerTask" targetRef="managerJudgeTask"/>
        <sequenceFlow id="flowEnd" name="通过" sourceRef="managerJudgeTask" targetRef="endLeave">
            <conditionExpression xsi:type="tFormalExpression"><![CDATA[${checkResult=='通过'}]]></conditionExpression>
        </sequenceFlow>
        <sequenceFlow id="rejectFlow" name="拒绝" sourceRef="managerJudgeTask" targetRef="sendMail">
            <conditionExpression xsi:type="tFormalExpression"><![CDATA[${checkResult=='拒绝'}]]></conditionExpression>
        </sequenceFlow>
        <serviceTask id="sendMail" flowable:exclusive="true" name="发送失败提示" isForCompensation="true" flowable:class="com.lidoudou.Controller.AskForLeaveFail"/>
        <sequenceFlow id="endFlow" sourceRef="sendMail" targetRef="askForLeaveFail"/>
        <endEvent id="askForLeaveFail" name="请假失败"/>
        <sequenceFlow id="zuzhangTask_zuzhangJudeTask" sourceRef="zuzhangTask" targetRef="zuzhangJudeTask"/>
    </process>
</definitions>

2.3 编写controller 开始测试

package com.lidoudou.Controller;

import lombok.extern.log4j.Log4j2;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.engine.*;
import org.flowable.engine.runtime.Execution;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.image.ProcessDiagramGenerator;
import org.flowable.task.api.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @program: FlowableTest
 * @description:
 * @author: ldd
 * @create: 2024-05-10 15:42
 **/

@RestController
@Log4j2
public class FlowController {
    @Autowired
    RuntimeService runtimeService;

    @Autowired
    TaskService taskService;

    @Autowired
    RepositoryService repositoryService;

    @Autowired
    ProcessEngine processEngine;

    @GetMapping("/pic")
    public void showPic(HttpServletResponse resp, String processId) throws Exception {
        ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(processId).singleResult();
        if (pi == null) {
            return;
        }
        List<Execution> executions = runtimeService
                .createExecutionQuery()
                .processInstanceId(processId)
                .list();

        List<String> activityIds = new ArrayList<>();
        List<String> flows = new ArrayList<>();
        for (Execution exe : executions) {
            List<String> ids = runtimeService.getActiveActivityIds(exe.getId());
            activityIds.addAll(ids);
        }

        /**
         * 生成流程图
         */
        BpmnModel bpmnModel = repositoryService.getBpmnModel(pi.getProcessDefinitionId());
        ProcessEngineConfiguration engconf = processEngine.getProcessEngineConfiguration();
        ProcessDiagramGenerator diagramGenerator = engconf.getProcessDiagramGenerator();
        InputStream in = diagramGenerator.generateDiagram(bpmnModel, "png", activityIds, flows, engconf.getActivityFontName(), engconf.getLabelFontName(), engconf.getAnnotationFontName(), engconf.getClassLoader(), 1.0, false);
        OutputStream out = null;
        byte[] buf = new byte[1024];
        int legth = 0;
        try {
            out = resp.getOutputStream();
            while ((legth = in.read(buf)) != -1) {
                out.write(buf, 0, legth);
            }
        } finally {
            if (in != null) {
                in.close();
            }
            if (out != null) {
                out.close();
            }
        }
    }

    String staffId = "1000";
    /**
     * 开启一个流程
     */
    @GetMapping("/begin")
    public   void askForLeave() {
        HashMap<String, Object> map = new HashMap<>();
        map.put("leaveTask", staffId);
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("ask_for_leave", map);
        runtimeService.setVariable(processInstance.getId(), "name", "javaboy");
        runtimeService.setVariable(processInstance.getId(), "reason", "休息一下");
        runtimeService.setVariable(processInstance.getId(), "days", 10);
        System.out.println(processInstance.getId());
    }



    String zuzhangId = "90";
    /**
     * 提交给组长审批
     */

    @GetMapping("/submitToZuzhang")
   public   void submitToZuzhang() {
        //员工查找到自己的任务,然后提交给组长审批
        List<Task> list = taskService.createTaskQuery().taskAssignee(staffId).orderByTaskId().desc().list();
        for (Task task : list) {
            log.info("任务 ID:{};任务处理人:{};任务是否挂起:{}", task.getId(), task.getAssignee(), task.isSuspended());
            Map<String, Object> map = new HashMap<>();
            //提交给组长的时候,需要指定组长的 id
            map.put("zuzhangTask", zuzhangId);
            taskService.complete(task.getId(), map);
        }
    }

    String managerId = "80";

    /**
     * 组长审批-批准
     */
    @GetMapping("/zuZhangApprove")
    void zuZhangApprove() {
        List<Task> list = taskService.createTaskQuery().taskAssignee(zuzhangId).orderByTaskId().desc().list();
        for (Task task : list) {
            log.info("组长 {} 在审批 {} 任务", task.getAssignee(), task.getId());
            Map<String, Object> map = new HashMap<>();
            //组长审批的时候,如果是同意,需要指定经理的 id
            map.put("managerTask", managerId);
            map.put("checkResult", "通过");
            taskService.complete(task.getId(), map);
        }
    }


    /**
     * 组长审批-拒绝
     */
    @GetMapping("/zuZhangReject")
    public void zuZhangReject() {
        List<Task> list = taskService.createTaskQuery().taskAssignee(zuzhangId).orderByTaskId().desc().list();
        for (Task task : list) {
            log.info("组长 {} 在审批 {} 任务", task.getAssignee(), task.getId());
            Map<String, Object> map = new HashMap<>();
            //组长审批的时候,如果是拒绝,就不需要指定经理的 id
            map.put("checkResult", "拒绝");
            taskService.complete(task.getId(), map);
        }
    }

    /**
     * 经理审批自己的任务-批准
     */

    @GetMapping("/managerApprove")
    public void managerApprove() {
        List<Task> list = taskService.createTaskQuery().taskAssignee(managerId).orderByTaskId().desc().list();
        for (Task task : list) {
            log.info("经理 {} 在审批 {} 任务", task.getAssignee(), task.getId());
            Map<String, Object> map = new HashMap<>();
            map.put("checkResult", "通过");
            taskService.complete(task.getId(), map);
        }
    }

    /**
     * 经理审批自己的任务-拒绝
     */
    @GetMapping("/managerReject")
    public void managerReject() {
        List<Task> list = taskService.createTaskQuery().taskAssignee(managerId).orderByTaskId().desc().list();
        for (Task task : list) {
            log.info("经理 {} 在审批 {} 任务", task.getAssignee(), task.getId());
            Map<String, Object> map = new HashMap<>();
            map.put("checkResult", "拒绝");
            taskService.complete(task.getId(), map);
        }
    }

}

2.3 当组长或者经理拒绝时,触发我们定义的这个类

@Component
public class AskForLeaveFail implements JavaDelegate {
    @Override
    public void execute(DelegateExecution delegateExecution) {
        System.out.println("请假失败。。。");
    }
}

可以自己手动实践实践,需要案例可以私聊

  • 13
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 添加依赖 在`pom.xml`文件中添加以下依赖: ```xml <dependency> <groupId>org.flowable</groupId> <artifactId>flowable-spring-boot-starter</artifactId> <version>${flowable.version}</version> </dependency> ``` 2. 配置数据库 在`application.yml`文件中添加以下配置: ```yaml spring: datasource: url: jdbc:mysql://localhost:3306/flowable?useUnicode=true&characterEncoding=utf-8&useSSL=false username: root password: root driver-class-name: com.mysql.jdbc.Driver ``` 3. 配置流程引擎 在`application.yml`文件中添加以下配置: ```yaml flowable: database-schema-update: true history-level: full ``` 4. 自定义流程引擎配置 可以通过继承`ProcessEngineConfigurationConfigurer`接口来自定义流程引擎配置,例如: ```java @Configuration public class FlowableConfig { @Bean public ProcessEngineConfigurationConfigurer processEngineConfigurationConfigurer() { return processEngineConfiguration -> { processEngineConfiguration.setAsyncExecutorActivate(false); processEngineConfiguration.setActivityFontName("宋体"); processEngineConfiguration.setLabelFontName("宋体"); }; } } ``` 5. 编写流程定义 在`src/main/resources/processes`目录下创建流程定义文件,例如`leave.bpmn20.xml`: ```xml <?xml version="1.0" encoding="UTF-8"?> <definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" targetNamespace="http://www.flowable.org/processdef"> <process id="leave" name="请假流程" isExecutable="true"> <startEvent id="start" name="开始"/> <userTask id="apply" name="申请请假"> <extensionElements> <flowable:formProperty id="reason" name="请假原因" type="string" required="true"/> <flowable:formProperty id="days" name="请假天数" type="long" required="true"/> </extensionElements> <documentation>请假申请节点,需要填写请假原因和请假天数</documentation> <incoming>startToApply</incoming> <outgoing>applyToApprove</outgoing> <potentialOwner> <resourceAssignmentExpression> <formalExpression>applyer</formalExpression> </resourceAssignmentExpression> </potentialOwner> </userTask> <userTask id="approve" name="审批"> <extensionElements> <flowable:formProperty id="result" name="审批结果" type="enum" required="true"> <flowable:value id="pass" name="通过"/> <flowable:value id="reject" name="驳回"/> </flowable:formProperty> <flowable:formProperty id="comment" name="审批意见" type="string" required="false"/> </extensionElements> <documentation>审批节点,需要填写审批结果和审批意见</documentation> <incoming>applyToApprove</incoming> <outgoing>approveToEnd</outgoing> <potentialOwner> <resourceAssignmentExpression> <formalExpression>approver</formalExpression> </resourceAssignmentExpression> </potentialOwner> </userTask> <endEvent id="end" name="结束"> <incoming>approveToEnd</incoming> </endEvent> <sequenceFlow id="startToApply" sourceRef="start" targetRef="apply"/> <sequenceFlow id="applyToApprove" sourceRef="apply" targetRef="approve"/> <sequenceFlow id="approveToEnd" sourceRef="approve" targetRef="end"/> </process> <bpmndi:BPMNDiagram> <bpmndi:BPMNPlane bpmnElement="leave"> <bpmndi:BPMNShape id="start_shape" bpmnElement="start"> <omgdc:Bounds x="180" y="80" width="50" height="50"/> </bpmndi:BPMNShape> <bpmndi:BPMNShape id="apply_shape" bpmnElement="apply"> <omgdc:Bounds x="250" y="60" width="100" height="80"/> </bpmndi:BPMNShape> <bpmndi:BPMNShape id="approve_shape" bpmnElement="approve"> <omgdc:Bounds x="400" y="60" width="100" height="80"/> </bpmndi:BPMNShape> <bpmndi:BPMNShape id="end_shape" bpmnElement="end"> <omgdc:Bounds x="550" y="80" width="50" height="50"/> </bpmndi:BPMNShape> <bpmndi:BPMNEdge id="startToApply_edge" bpmnElement="startToApply"> <omgdi:waypoint x="205" y="105"/> <omgdi:waypoint x="250" y="100"/> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge id="applyToApprove_edge" bpmnElement="applyToApprove"> <omgdi:waypoint x="350" y="100"/> <omgdi:waypoint x="400" y="100"/> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge id="approveToEnd_edge" bpmnElement="approveToEnd"> <omgdi:waypoint x="500" y="100"/> <omgdi:waypoint x="550" y="105"/> </bpmndi:BPMNEdge> </bpmndi:BPMNPlane> </bpmndi:BPMNDiagram> </definitions> ``` 6. 编写流程服务 编写流程服务,例如: ```java @Service public class LeaveService { @Autowired private RuntimeService runtimeService; @Autowired private TaskService taskService; public void startProcess(String applyer, String reason, long days) { Map<String, Object> variables = new HashMap<>(); variables.put("applyer", applyer); variables.put("reason", reason); variables.put("days", days); runtimeService.startProcessInstanceByKey("leave", variables); } public void approveTask(String taskId, String result, String comment) { Map<String, Object> variables = new HashMap<>(); variables.put("result", result); variables.put("comment", comment); taskService.complete(taskId, variables); } public List<Task> getTasks(String assignee) { return taskService.createTaskQuery().taskAssignee(assignee).list(); } } ``` 7. 测试流程服务 编写测试类,例如: ```java @SpringBootTest @RunWith(SpringRunner.class) public class LeaveServiceTest { @Autowired private LeaveService leaveService; @Test public void testLeaveProcess() { String applyer = "张三"; String reason = "生病了"; long days = 3; leaveService.startProcess(applyer, reason, days); List<Task> tasks = leaveService.getTasks("approver"); Assert.assertNotNull(tasks); Assert.assertEquals(1, tasks.size()); Task task = tasks.get(0); Assert.assertEquals(reason, task.getFormProperty("reason").getValue()); Assert.assertEquals(days, task.getFormProperty("days").getValue()); leaveService.approveTask(task.getId(), "pass", "同意"); tasks = leaveService.getTasks("approver"); Assert.assertEquals(0, tasks.size()); } } ``` 8. 运行应用程序 运行应用程序,访问http://localhost:8080/actuator/flowable,可以查看流程引擎的状态信息。 以上是集成FlowableSpringBoot的基本步骤。具体实现可能因应用场景和需求而异,需要根据实际情况进行调整和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值