SpringBoot + Flowable并集成ui,写一个请假流程Demo

 找了好多文章,每个文章多多少少都有坑点,终于是搞出来了,本文只搞整合,如需详细定义可自行去搜索,网上很多。

程序相关

环境
  • jdk1.8

  • maven3

  • SpringBoot 2.7.5

  • flowable 6.6.0

  • MySQL8

目录

图片

图片

依赖
<properties>
    <maven.compiler.source>8</maven.compiler.source>
    <maven.compiler.target>8</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <flowable.version>6.6.0</flowable.version>
</properties>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.7.5</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- 工作流flowable jar包 -->
    <dependency>
        <groupId>org.flowable</groupId>
        <artifactId>flowable-spring-boot-starter</artifactId>
        <version>${flowable.version}</version>
    </dependency>
    <!-- 下面俩皆是flowable-ui所需jar包,不用ui画流程图的可不加 -->
    <dependency>
        <groupId>org.flowable</groupId>
        <artifactId>flowable-spring-boot-starter-ui-idm</artifactId>
        <version>${flowable.version}</version>
    </dependency>
    <dependency>
        <groupId>org.flowable</groupId>
        <artifactId>flowable-spring-boot-starter-ui-modeler</artifactId>
        <version>${flowable.version}</version>
    </dependency>
    <!-- 忘了这家伙干啥的了,好像是解决中途的某个报错的,诸位可去掉验证验证 -->
    <dependency>
        <groupId>org.flowable</groupId>
        <artifactId>flowable-bpmn-layout</artifactId>
        <version>${flowable.version}</version>
    </dependency>
    <!-- mysql数据库连接jar包 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.31</version>
    </dependency>
    <!-- mybatis ORM jar包 -->
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>2.2.2</version>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>
配置

application.properties (可自行改为yml)

#端口
server.port=8081

#ui相关信息
flowable.idm.app.admin.user-id=admin
flowable.idm.app.admin.password=admin
flowable.idm.app.admin.first-name=xxx
flowable.idm.app.admin.last-name=xxx
flowable.database-schema-update=true# 没有数据库表的时候生成数据库表(true)  建表后可关闭(false),下次启动不会再次建表
# 关闭定时任务JOB
flowable.async-executor-activate=false
#数据库
spring.datasource.url=jdbc:mysql://xxxx:3306/flowable-test?autoReconnect=true&useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true #此处的nullCatalogMeansCurrent=true
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
#日志
logging.level.org.flowable=DEBUG

注意

  • &nullCatalogMeansCurrent=true 这个一定要加在url后,不然flowable自动创建表失败

  • 在数据库中创建flowable数据库,启动项目时,flowable服务会自动创建对应的表

  • 启动项目后 网站的登录用户 密码 user-id: admin password: admin

图片

图片

后面还有很多,自动创建的,我也没数过

防止流程图乱码FlowableConfig

package org.example.config;

import org.flowable.spring.SpringProcessEngineConfiguration;
import org.flowable.spring.boot.EngineConfigurationConfigurer;
import org.springframework.context.annotation.Configuration;

/**
 * flowable配置----为放置生成的流程图中中文乱码
 */
@Configuration
public class FlowableConfig implements EngineConfigurationConfigurer<SpringProcessEngineConfiguration> {
 
 
    @Override
    public void configure(SpringProcessEngineConfiguration engineConfiguration) {
        engineConfiguration.setActivityFontName("宋体");
        engineConfiguration.setLabelFontName("宋体");
        engineConfiguration.setAnnotationFontName("宋体");
    }
}

返回结果Result

package org.example.vo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;


@Data
@NoArgsConstructor
@AllArgsConstructor
public class Result {

    private boolean flag;
    private String message;
    private Object data;

    public Result(boolean flag , String message){
        this.flag = flag;
        this.message = message;
    }
}

TaskVO封装审批列表查询结果

package org.example.vo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @ 审批列表查询结果
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class TaskVO {
    private String id;
    private String day;
    private String name;
}

controller请假流程接口

package org.example.controller;

import lombok.extern.slf4j.Slf4j;
import org.example.vo.Result;
import org.example.vo.TaskVO;
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.*;

import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/leave")
@Slf4j
public class LeaveController {
    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private RepositoryService repositoryService;
    @Autowired
    private ProcessEngine processEngine;

    @PostMapping( "add/{day}/{studentUser}")
    public Result sub(@PathVariable("day") Integer day , @PathVariable("studentUser") String studentUser) {
        // 学生提交请假申请
        Map<String, Object> map = new HashMap<>();
        map.put("day", day);
        map.put("studentName", studentUser);
        // stuLeave为学生请假流程xml文件中的id,即后面bpmn20.xml文件的process id="stuLeave"
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("stuLeave", map);
        log.info("流程实例ID:" + processInstance.getId());
        //完成申请任务
        Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
        taskService.complete(task.getId());
        //此处id为流程id
        return new Result(true,"提交成功.流程Id为:" + processInstance.getId()) ;
    }

    @GetMapping("teacherList")
    public Result teacherList() {
        //此处.taskCandidateGroup("a")的值“a”即是画流程图时辅导员审批节点"分配用户-候选组"中填写的值
        List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup("a").list();
        List<TaskVO> taskVOList = tasks.stream().map(task -> {
            Map<String, Object> variables = taskService.getVariables(task.getId());
            return new TaskVO(task.getId(), variables.get("day").toString(), variables.get("studentName").toString());
        }).collect(Collectors.toList());
        log.info("任务列表:" + tasks);
        if (tasks == null || tasks.size() == 0) {
            return new Result(false,"没有任务");
        }
        return new Result(true,"获取成功",taskVOList);
    }

    /**
     * 辅导员批准
     *
     * @param taskId 任务ID,非流程id
     */
    @GetMapping("teacherApply/{taskId}")
    public Result teacherApply(@PathVariable("taskId") String taskId) {
        List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup("a").list();
        Task task = taskService.createTaskQuery().taskCandidateGroup("a").taskId(taskId).singleResult();
        if (task == null) {
            return new Result(false, "没有任务");
        }
        //通过审核
        HashMap<String, Object> map = new HashMap<>();
        map.put("outcome", "通过");
//        for (Task task : tasks) {
//            taskService.complete(task.getId(), map);
//        }
        taskService.complete(task.getId(), map);
        return new Result(true,"审批成功");
    }

    /**
     * 辅导员拒绝
     * @param taskId 任务ID,非流程id
     */
    @GetMapping( "teacherReject/{taskId}")
    public Result teacherReject(@PathVariable("taskId") String taskId) {
        Task task1 = taskService.createTaskQuery().taskCandidateGroup("a").taskId(taskId).singleResult();
        //Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        if (task1 == null) {
            return new Result(false, "没有任务");
        }
        //通过审核
        HashMap<String, Object> map = new HashMap<>();
        map.put("outcome", "驳回");
        taskService.complete(task1.getId(), map);
        return new Result(true,"审批失败");
    }
    /**
     * 院长获取审批管理列表
     */
    @GetMapping("deanList")
    public Result deanList() {
        //此处.taskCandidateGroup("b")的值“b”即是画流程图时辅导员审批节点"分配用户-候选组"中填写的值
        List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup("b").list();
        List<TaskVO> taskVOList = tasks.stream().map(task -> {
            Map<String, Object> variables = taskService.getVariables(task.getId());
            return new TaskVO(task.getId(), variables.get("day").toString(), variables.get("studentName").toString());
        }).collect(Collectors.toList());
        if (tasks == null || tasks.size() == 0) {
            return new Result(false,"没有任务");
        }
        return new Result(true,"获取成功",taskVOList);
    }

    /**
     * 院长批准
     * @param taskId 任务ID,非流程id
     * @return
     */
    @GetMapping("deanApply/{taskId}")
    public Result apply(@PathVariable("taskId") String taskId) {
        List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup("b").list();
        //Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        if (tasks == null) {
            return new Result(false, "没有任务");
        }
        //通过审核
        HashMap<String, Object> map = new HashMap<>();
        map.put("outcome", "通过");
        for (Task task : tasks) {
            taskService.complete(task.getId(), map);
        }
        return new Result(true,"审批成功");
    }

    /**
     * 院长拒绝
     * @param taskId 任务ID,非流程id
     * @return
     */
    @GetMapping("deanReject/{taskId}")
    public Result deanReject(@PathVariable("taskId") String taskId) {
//        List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup("b").list();
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        if (task == null) {
            return new Result(false, "没有任务");
        }
        //通过审核
        HashMap<String, Object> map = new HashMap<>();
        map.put("outcome", "驳回");
//        for (Task task : tasks) {
//            taskService.complete(task.getId(), map);
//        }
        taskService.complete(task.getId(), map);
        return new Result(true,"审批成功");
    }

    /**
     * 再次申请
     * @param piId 流程id
     * @param day
     * @return
     */
    @GetMapping("subAgain/{piId}/{day}")
    public Result subAgain(@PathVariable("piId") String piId, @PathVariable("day") Integer day){
        Task task = taskService.createTaskQuery().processInstanceId(piId).singleResult();
        if(Objects.isNull(task)){
            return new Result(false, "没有任务");
        }
        Map<String, Object> map = new HashMap<>();
        map.put("day", day);
        taskService.complete(task.getId(), map);
        return new Result(true,"申请成功");
    }

    /**
     * 生成流程图
     *
     * @param taskId 流程ID
     */
    @GetMapping( "processDiagram/{taskId}")
    public void genProcessDiagram(HttpServletResponse httpServletResponse,@PathVariable("taskId") String taskId) throws Exception {
        ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(taskId).singleResult();

        //流程走完的不显示图
        if (pi == null) {
            return;
        }
        Task task = taskService.createTaskQuery().processInstanceId(pi.getId()).singleResult();
        //使用流程实例ID,查询正在执行的执行对象表,返回流程实例对象
        String InstanceId = task.getProcessInstanceId();
        List<Execution> executions = runtimeService
                .createExecutionQuery()
                .processInstanceId(InstanceId)
                .list();

        //得到正在执行的Activity的Id
        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 ,true);
        OutputStream out = null;
        byte[] buf = new byte[1024];
        int legth = 0;
        try {
            //此处设置resp的header诸多文章都没写,但是我不写出不来流程图,诸位可去掉试试
            httpServletResponse.setHeader("Content-Type",
                    "image/png;charset=utf-8");
            out = httpServletResponse.getOutputStream();
            while ((legth = in.read(buf)) != -1) {
                out.write(buf, 0, legth);
            }
        } finally {
            if (in != null) {
                in.close();
            }
            if (out != null) {
                out.close();
            }
        }
    }
}

此时可以启动项目了,访问http://localhost:8081 用配置文件配置的账号密码登录

图片

图片

创建流程

图片

图片

图片

图片

简单画图操作

图片

图片

画请假流程

图片

图片

图片

图片

图片

图片

图片

图片

图片

图片

图片

图片

图片

图片

图片

图片

图片

注意:每个审批元素属性中有个独占任务项,我参考的博客是改了的,但是我改不了,不过也没发现有啥问题,大家有兴趣可以去研究研究

图片

图片

在resources下创建processes文件夹,复制下载的"学生请假流程.bpmn20.xml"到该目录即可

<?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="stuLeave" name="学生请假流程" isExecutable="true">
    <documentation>学校学生请假流程</documentation>
    <startEvent id="startEvent1" name="开始" flowable:formFieldValidation="true"></startEvent>
    <userTask id="apply" name="请假申请" flowable:assignee="${studentName}" flowable:formFieldValidation="true">
      <extensionElements>
        <modeler:initiator-can-complete xmlns:modeler="http://flowable.org/modeler"><![CDATA[false]]></modeler:initiator-can-complete>
      </extensionElements>
    </userTask>
    <userTask id="teacherPass" name="辅导员审批" flowable:candidateGroups="a" flowable:formFieldValidation="true"></userTask>
    <exclusiveGateway id="judgeTask" name="判断是否大于2天"></exclusiveGateway>
    <userTask id="principalPass" name="院长审批" flowable:candidateGroups="b" flowable:formFieldValidation="true"></userTask>
    <endEvent id="over" name="结束"></endEvent>
    <sequenceFlow id="judgeLess" name="小于2天" sourceRef="judgeTask" targetRef="over">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${day<=2}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="judgeMore" name="大于2天" sourceRef="judgeTask" targetRef="principalPass">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${day>2}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="flowBeg" name="流程开始" sourceRef="startEvent1" targetRef="apply"></sequenceFlow>
    <sequenceFlow id="sid-F3C3133B-68E1-4D1B-B06B-761EDD44E9F6" name="申请流程" sourceRef="apply" targetRef="teacherPass"></sequenceFlow>
    <sequenceFlow id="TeacherNotPassFlow" name="驳回" sourceRef="teacherPass" targetRef="apply">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${outcome=='驳回'}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="teacherPassFlow" name="通过" sourceRef="teacherPass" targetRef="judgeTask">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${outcome=="通过"}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="presidentNotPassFlow" name="驳回" sourceRef="principalPass" targetRef="apply">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${outcome=='驳回'}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="presidentPassFlow" name="通过" sourceRef="principalPass" targetRef="over">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${outcome=='通过'}]]></conditionExpression>
    </sequenceFlow>
  </process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_stuLeave">
    <bpmndi:BPMNPlane bpmnElement="stuLeave" id="BPMNPlane_stuLeave">
      <bpmndi:BPMNShape bpmnElement="startEvent1" id="BPMNShape_startEvent1">
        <omgdc:Bounds height="30.0" width="30.0" x="100.0" y="163.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="apply" id="BPMNShape_apply">
        <omgdc:Bounds height="80.0" width="100.0" x="209.9999968707562" y="137.99999794363978"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="teacherPass" id="BPMNShape_teacherPass">
        <omgdc:Bounds height="80.0" width="100.0" x="389.99999418854725" y="137.99999794363978"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="judgeTask" id="BPMNShape_judgeTask">
        <omgdc:Bounds height="40.0" width="40.0" x="569.9999915063382" y="157.99999764561656"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="principalPass" id="BPMNShape_principalPass">
        <omgdc:Bounds height="80.0" width="100.0" x="539.9999834597114" y="284.9999915063383"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="over" id="BPMNShape_over">
        <omgdc:Bounds height="28.0" width="28.0" x="794.9999881535771" y="163.9999975562096"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="presidentNotPassFlow" id="BPMNEdge_presidentNotPassFlow">
        <omgdi:waypoint x="539.9999834597114" y="324.9999915063383"></omgdi:waypoint>
        <omgdi:waypoint x="259.9999968707562" y="324.9999915063383"></omgdi:waypoint>
        <omgdi:waypoint x="259.9999968707562" y="217.9499979436398"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="judgeLess" id="BPMNEdge_judgeLess">
        <omgdi:waypoint x="609.4890905518624" y="178.45641965548475"></omgdi:waypoint>
        <omgdi:waypoint x="795.0000204150059" y="178.03191983331223"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="sid-F3C3133B-68E1-4D1B-B06B-761EDD44E9F6" id="BPMNEdge_sid-F3C3133B-68E1-4D1B-B06B-761EDD44E9F6">
        <omgdi:waypoint x="309.94999687075494" y="177.99999794363978"></omgdi:waypoint>
        <omgdi:waypoint x="389.99999418854725" y="177.99999794363978"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="judgeMore" id="BPMNEdge_judgeMore">
        <omgdi:waypoint x="590.4349219597013" y="197.50836625144538"></omgdi:waypoint>
        <omgdi:waypoint x="590.1363337825771" y="284.9999915063383"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flowBeg" id="BPMNEdge_flowBeg">
        <omgdi:waypoint x="129.94999913083947" y="177.99999978727305"></omgdi:waypoint>
        <omgdi:waypoint x="209.99999373428892" y="177.99999865202045"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="presidentPassFlow" id="BPMNEdge_presidentPassFlow">
        <omgdi:waypoint x="639.9499834597113" y="324.9999915063383"></omgdi:waypoint>
        <omgdi:waypoint x="808.9999881535771" y="324.9999915063383"></omgdi:waypoint>
        <omgdi:waypoint x="808.9999881535771" y="191.94992565845044"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="TeacherNotPassFlow" id="BPMNEdge_TeacherNotPassFlow">
        <omgdi:waypoint x="439.99999418854725" y="137.99999794363978"></omgdi:waypoint>
        <omgdi:waypoint x="439.99999418854725" y="68.00000129640101"></omgdi:waypoint>
        <omgdi:waypoint x="259.9999968707562" y="68.00000129640101"></omgdi:waypoint>
        <omgdi:waypoint x="259.9999968707562" y="137.99999794363978"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="teacherPassFlow" id="BPMNEdge_teacherPassFlow">
        <omgdi:waypoint x="489.949994188544" y="178.16594469153907"></omgdi:waypoint>
        <omgdi:waypoint x="570.4333248783485" y="178.43333101762673"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>

演示

提交申请

图片

图片

辅导员审批列表

图片

图片

流程图

图片

图片

辅导员批准

图片

图片

流程图

图片

图片

院长获取审批列表

图片

图片

院长拒绝

图片

图片

流程图

图片

图片

再次申请

图片

图片

流程图

图片

图片

辅导员审批列表

图片

图片

其它流程大家可自行验证

大家一定要注意各个接口的入参id,有的是流程id,有的是任务id,且任务id也会随着节点变动而变动,我是从审批列表中获取的,关于id变动这块,大家有兴趣可深入研究下,我反正是一脸懵,大家可以看看ACT_RU_TASK这张表观察观察每个审批节点的id变化情况

表结构

  • ACT_RE : 'RE’表示 repository。 这个前缀的表包含了流程定义和流程静态资源 (图片,规则,等等)。

  • ACT_RU: 'RU’表示 runtime。 这些运行时的表,包含流程实例,任务,变量,异步任务,等运行中的数据。 Flowable只在流程实例执行过程中保存这些数据, 在流程结束时就会删除这些记录。 这样运行时表可以一直很小速度很快。

  • ACT_HI: 'HI’表示 history。 这些表包含历史数据,比如历史流程实例, 变量,任务等等。

  • ACT_GE:  GE 表示 general。 通用数据, 用于不同场景下

  • ACT_ID:  ’ID’表示identity(组织机构)。这些表包含标识的信息,如用户,用户组,等等。

### 回答1: Spring Boot一个基于Spring框架的快速开发框架,可以帮助开发者快速搭建基于Spring的应用程序。Flowable一个流程引擎,可以帮助开发者快速实现业务流程的自动化管理。Spring BootFlowable的结合可以让开发者更加方便地实现业务流程的自动化管理,提高开发效率和业务效率。 ### 回答2: SpringBoot Flowable是一款基于SpringBootFlowable和RESTful风格的Web应用程序开发框架。SpringBoot框架是一个独立的、基于Spring框架的应用程序开发框架,它简化了Spring应用程序的配置和部署,并提供快速的开发、测试和部署功能。Flowable框架是基于BPMN2.0标准的一个开源的流程引擎框架,它提供了丰富的流程定义、任务管理、历史记录、事件跟踪等功能,便于企业进行复杂业务流程的管理和优化。 SpringBoot Flowable框架的主要特点包括: 1.高效简便:SpringBoot Flowable采用SpringBoot框架简化了Spring应用程序的配置和部署,同时结合Flowable框架,使流程定义和任务管理更加简便高效。 2.易于扩展:SpringBoot Flowable框架采用RESTful风格的接口设计,与其它系统集成更加简单方便,同时也支持二次开发和自定义扩展。 3.丰富的功能:SpringBoot Flowable框架集成Flowable框架所提供的全部功能,包括流程定义、任务管理、历史记录、事件跟踪等,支持企业复杂业务流程的管理和优化。 4.支持多平台:SpringBoot Flowable框架可以部署在不同系统平台上,如Windows、Linux等,实现跨平台共享和应用。 在使用SpringBoot Flowable框架的过程中,需要掌握SpringBoot框架和Flowable框架的相关知识,同时注意提升系统的安全性和稳定性。可以参考SpringBootFlowable的官方文档进行学习和参考,也可以借助其它资料和开发者社区进行交流和分享。 ### 回答3: Spring Boot一个开源的Java开发框架,可以快速地开发基于Java的Web应用程序。它提供了许多内置的功能和自动配置,使开发者能够轻松地构建可扩展的、高度可用的应用程序。而Flowable一个开源的工作流引擎,它基于BPMN(Business Process Model and Notation)标准,可以帮助企业完成复杂的业务流程,实现业务可视化、自动化流转和智能化控制。 Spring BootFlowable的结合使得开发者能够轻松地使用Flowable来构建业务流程。使用Spring BootFlowable代码可以快速地实现流程引擎的集成和管理,同时也方便了开发人员使用Spring Boot框架进行Web开发。 Spring Boot可以使用简便的方式来配置Flowable,使用它提供的自动配置和starter等模块来进行流程引擎的集成和管理。同时,Spring Boot还提供了丰富的开发工具和插件,使得开发者能够轻松地进行代码调试和测试。 在使用Spring BootFlowable进行业务流程开发时,开发者可以使用Flowable提供的任务列表、流程修改等功能,可以轻松地修改业务流程,使得业务流程变得更加智能化和高效化。同时,Spring BootFlowable的结合也使得业务流程的开发变得更加简单和可靠。 总之,Spring BootFlowable的结合可以使开发者轻松地构建高可用、高效率、智能化的业务流程,并且简化了开发和管理流程引擎的过程,帮助企业实现业务的自动化和智能化管理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值