springboot如何集成flowable,如何部署flowable在线编辑器画bpm图以及bpm图的画法,我在上一篇博客中写了,这里直接上代码。 

  这是我画的请假流程bpm图。

springboot集成flowable创建请假流程实例_ide

  然会到代码部分。

  首先,先写一个config类,避免生成的bpm图中文乱码。

package com.example.config;

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


@Configuration
public class FlowableConfig implements EngineConfigurationConfigurer<SpringProcessEngineConfiguration> {
    @Override
    public void configure(SpringProcessEngineConfiguration springProcessEngineConfiguration) {
        springProcessEngineConfiguration.setActivityFontName("宋体");
        springProcessEngineConfiguration.setLabelFontName("宋体");
        springProcessEngineConfiguration.setAnnotationFontName("宋体");
    }
}

 

  由于我在画bpm图的时候,给“经理审批”节点和“老板审批”节点设置了监听器。所以接下来写监听器类

  • 经理审批节点监听器。指定任务受理人为“领导”。
    package com.example.listen;
    
    import org.flowable.engine.delegate.TaskListener;
    import org.flowable.task.service.delegate.DelegateTask;
    
    public class ManagerTaskHandler implements TaskListener {
        
        @Override
        public void notify(DelegateTask delegateTask) {
            delegateTask.setAssignee("领导");
            System.out.println("执行监听器————————————————————————————————————");
        }
    }

     

 

  • 老板审批节点监听器。指定任务受理人为“老板”。
    package com.example.listen;
    
    import org.flowable.engine.delegate.TaskListener;
    import org.flowable.task.service.delegate.DelegateTask;
    
    public class BossTaskHandler implements TaskListener {
    
        @Override
        public void notify(DelegateTask delegateTask) {
            delegateTask.setAssignee("老板");
        }
    }

     

 

  接下来到controller。

  • 发起请假流程。这里要说明一下,只有在上一个节点完成任务后,流程才会执行到下一个节点。所以这里在发起流程后,就手动完成了任务,让流程进行到下一个节点。
    /**
     * 发起请假
     *
     * @param userId    用户Id
     * @param days     请假天数
     * @param descption 描述
     */ 
@RequestMapping(value = "/add")
    @ResponseBody
    public String addExpense(String userId, Integer money, String descption) {

        //启动流程
        HashMap<String, Object> map = new HashMap<>();
        map.put("taskUser", userId);
        map.put("days", days);
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("leave-flow", map);
        Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
        taskService.complete(task.getId());

        return "提交成功.流程Id为:" + processInstance.getId() + "任务id: " + task.getId() ;
    }
  • 其他操作。
        /**
         * 获取审批管理列表
         */
        @RequestMapping(value = "/list")
        @ResponseBody
        public Object list(String userId) {
            List<Task> tasks = taskService.createTaskQuery().taskAssignee(userId).orderByTaskCreateTime().desc().list();
            for (Task task : tasks) {
            }
            System.out.println(tasks.toString());
    
            return tasks.toString();
        }
    
    
        /**
         * 批准
         *
         * @param taskId 任务ID
         */
        @RequestMapping(value = "apply")
        @ResponseBody
        public String apply(String taskId) {
            List<Task> t = taskService.createTaskQuery().list();
            Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
    
            //Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
    
            if (task == null) {
                throw new RuntimeException("流程不存在");
            }
            //通过审核
            HashMap<String, Object> map = new HashMap<>();
            map.put("result", "同意");
            taskService.complete(taskId, map);
            return "processed ok!";
        }
    
        /**
         * 拒绝
         */
        @ResponseBody
        @RequestMapping(value = "reject")
        public String reject(String taskId) {
            HashMap<String, Object> map = new HashMap<>();
            map.put("result", "驳回");
            taskService.complete(taskId, map);
            return "reject";
        }
    
        /**
         * 生成流程图
         *
         * @param processId 任务ID
         */
        @RequestMapping(value = "processDiagram")
        public void genProcessDiagram(HttpServletResponse httpServletResponse, String processId) throws Exception {
            List<ProcessInstance> t = runtimeService.createProcessInstanceQuery().list();
            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<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);
            InputStream in = diagramGenerator.generateDiagram(bpmnModel, "png", activityIds, Collections.emptyList(), engconf.getActivityFontName(), engconf.getLabelFontName(), engconf.getAnnotationFontName(), null, 1.0, false);
            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();
                }
            }
        }

     

  测试。

  • 发起流程。可以看到后台打印了监听器中的内容,说明执行了监听器。springboot集成flowable创建请假流程实例_提交表单_02

springboot集成flowable创建请假流程实例_spring_03

 

 

 

  • 获取审批列表。springboot集成flowable创建请假流程实例_ide_04
  • 通过经理审批。taskId可以从act_ru_task表中查看。springboot集成flowable创建请假流程实例_监听器_05

     

  • 查看流程图。springboot集成flowable创建请假流程实例_提交表单_06

     

  • 老板驳回请求。springboot集成flowable创建请假流程实例_流程图_07

     

  • 再次查看流程图。可以看到驳回请求后,又回到申请人节点。 

springboot集成flowable创建请假流程实例_提交表单_08

 

 

  • 如果老板也通过的话,整个流程就结束了。

       整个流程到这里就演示完了。当时在学的时候,流程卡在第一个节点不往下执行,最后发现只有上一个节点任务完成,才会到下一个节点,发起人节点要手动完成任务。其实在实际开发中,当发起人提交表单时,任务也就完成了,流程会接着往下执行。

 

  最后补充一下个人认为比较重要的几个表:

  act_ru_execution:运行流程实例表。发起的运行中流程可以在此表中看到。

  act_ru_task:运行时任务表。可以查看运行的任务id和任务执行到哪个节点。

  act_re_procdef:已经发布定义的流程可以在此表中看到。

  act_id_user:用户信息表。

每天坚持学一点点!