Springboot整合flowable

简介

  • Flowable 适用于开发人员,系统管理员和业务用户的紧凑且高效的工作流程和业务流程管理(BPM)平台。

  • Flowable 的发布包里包含了大部分源码,以 JAR 文件方式提供。Flowable 的源码也可以通过以下链接获得:https://github.com/flowable/flowable-engine

准备工作

  • pom.xml jar 引入:6.3.0


    org.flowable
    flowable-spring-boot-starter
    ${flowable.version}

项目要点

  • 1.application.yml 配置 添加以下属性

flowable:
  #关闭定时任务JOB
  async-executor-activate: false
#  将databaseSchemaUpdate设置为true。当Flowable发现库与数据库表结构不一致时,会自动将数据库表结构升级至新版本。
  database-schema-update: true
  • 2. 创建 OrderApproval.bpmn20.xml 文件。( 之前使用 activiti 的时候 eclipse 集成的 Activiti Diagram 工具挺好用的,idea 对 bpmn 画图工具集成不是很友好,activiti 中也有自己的 BPMN 可视化工具,也还算友好) 将其放于项目中的 resource 目录下的 processe,当此框架启动的时候它会默认加载 resource 目录下的 processes 时就可以将此流程配置加载到数据库进行持久化。



  
    
    
    
    
    
      
    
    
    
    
    
    
    
    
    
      
    
  
  
    
      
        
      
      
        
      
      
        
      
      
        
      
      
        
      
      
        
      
      
        
      
      
        
        
        
        
      
      
        
        
        
        
      
      
        
        
        
        
      
      
        
        
      
      
        
        
        
        
      
      
        
        
        
        
      
    
  

3. 创建 FlowableController 类

package com.honghh.bootfirst.controller;

import com.honghh.bootfirst.utils.R;
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.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * ClassName: FlowableController
 * Description:
 *
 * @author honghh
 * @date 2019/02/20 18:12
 */
@RestController
@RequestMapping("/flowable")
public class FlowableController {
    @Autowired
    private RepositoryService repositoryService;
    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private HistoryService historyService;

    @Autowired
    private ProcessEngine processEngine;

    /**
     * .提交采购订单的审批请求
     *
     * @param userId 用户id
     */
    @PostMapping("/start/{userId}/{purchaseOrderId}")
    public R startFlow(@PathVariable String userId, @PathVariable String purchaseOrderId) {
        HashMap map = new HashMap<>();
        map.put("userId", userId);
        map.put("purchaseOrderId", purchaseOrderId);
        ProcessInstance processInstance =
                runtimeService.startProcessInstanceByKey("OrderApproval", map);
        String processId = processInstance.getId();
        String name = processInstance.getName();
        System.out.println(processId + ":" + name);
        return R.ok(processId + ":" + name);
    }

    /**
     * .获取用户的任务
     *
     * @param userId 用户id
     */
    @GetMapping("/getTasks/{userId}")
    public R getTasks(@PathVariable String userId) {
        List tasks = taskService.createTaskQuery().taskAssignee(userId).orderByTaskCreateTime().desc().list();
        return R.ok(tasks.toString());
    }

    /**
     * .审批通过
     */
    @PostMapping("/success/{taskId}")
    public R success(@PathVariable String taskId) {
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        if (task == null) {
            return R.error("流程不存在");
        }
        //通过审核
        HashMap map = new HashMap<>();
        map.put("approved", true);
        taskService.complete(taskId, map);
        return R.ok("流程审核通过!");
    }

    /**
     * .审批不通过
     */
    @PostMapping("/faile/{taskId}")
    public R faile(@PathVariable String taskId) {
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        if (task == null) {
            return R.error("流程不存在");
        }
        //通过审核
        HashMap map = new HashMap<>();
        map.put("approved", false);
        taskService.complete(taskId, map);
        return R.ok();
    }
    @RequestMapping(value = "processDiagram")
    public void genProcessDiagram(HttpServletResponse httpServletResponse, String processId) throws Exception {
        ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(processId).singleResult();

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

        //得到正在执行的Activity的Id
        List activityIds = new ArrayList<>();
        List flows = new ArrayList<>();
        for (Execution exe : executions) {
            List 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);
        OutputStream out = null;
        byte[] buf = new byte[1024];
        int legth = 0;
        try {
            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();
            }
        }
    }
}
  • 4. 配置 FlowableConfig 为防止生成的流程图中中文乱码

package com.honghh.bootfirst.config;

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

/**
 * ClassName: FlowableConfig
 * Description:
 *
 * @author honghh
 * @date 2019/02/20 18:43
 */
@Configuration
public class FlowableConfig implements EngineConfigurationConfigurer {

    @Override
    public void configure(SpringProcessEngineConfiguration engineConfiguration) {
        engineConfiguration.setActivityFontName("宋体");
        engineConfiguration.setLabelFontName("宋体");
        engineConfiguration.setAnnotationFontName("宋体");
    }

}

演示效果

  • 1. 提交采购订单的审批请求 http://localhost:8080/flowable/start/1/1

Springboot整合flowable_第1张图片
  • 2. 获取用户的任务 http://localhost:8080/flowable/getTasks/1Springboot整合flowable_第2张图片

  • 3. 审批通过 http://localhost:8080/flowable/success/11Springboot整合flowable_第3张图片

  • 4. 生成当前流程图表 http://localhost:8080/flowable/processDiagram?processId=5Springboot整合flowable_第4张图片

代码获取

https://gitee.com/honghh/boot-demo.git

参考文献

  • Flowable BPMN 用户手册 (v 6.3.0) https://tkjohn.github.io/flowable-userguide/

  • 采用 springboot+flowable 快速实现工作流 https://blog.csdn.net/puhaiyang/article/details/79845248

  • Activiti 学习文档(三)之画流程图并部署流程 https://blog.csdn.net/samile6899/article/details/52578347


作者:AH_HH

来源链接:

https://blog.csdn.net/qq_35098526/article/details/87818988

Springboot整合flowable_第5张图片

你可能感兴趣的:(java,spring,activiti,spring,boot,mybatis)