springboot集成flowable創建請假流程實例


 

  springboot如何集成flowable,如何部署flowable在線編輯器畫bpm圖以及bpm圖的畫法,我在上一篇博客中寫了,這里直接上代碼(源碼地址:晚安/flowable_holiday (gitee.com))。 

  這是我畫的請假流程bpm圖。

  然會到代碼部分。

  首先,先寫一個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();
                }
            }
        }

     

  測試。

  • 發起流程。可以看到后台打印了監聽器中的內容,說明執行了監聽器。

 

 

 

  • 獲取審批列表。
  • 通過經理審批。taskId可以從act_ru_task表中查看。

     

  • 查看流程圖。

     

  • 老板駁回請求。

     

  • 再次查看流程圖。可以看到駁回請求后,又回到申請人節點。 

 

 

  • 如果老板也通過的話,整個流程就結束了。

       整個流程到這里就演示完了。當時在學的時候,流程卡在第一個節點不往下執行,最后發現只有上一個節點任務完成,才會到下一個節點,發起人節點要手動完成任務。其實在實際開發中,當發起人提交表單時,任務也就完成了,流程會接着往下執行。

 

  最后補充一下個人認為比較重要的幾個表:

  act_ru_execution:運行流程實例表。發起的運行中流程可以在此表中看到。

  act_ru_task:運行時任務表。可以查看運行的任務id和任務執行到哪個節點。

  act_re_procdef:已經發布定義的流程可以在此表中看到。

  act_id_user:用戶信息表。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM