最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊

SpringBoot+flowable快速實(shí)現(xiàn)工作流,超級方便

2023-03-21 10:53 作者:要寵你上天  | 我要投稿

前言

工作流框架大家一定不陌生,各種OA系統(tǒng)里我們常常用到。

對于JAVA領(lǐng)域來說一說起工作流框架第一浮現(xiàn)我在腦海中的便是大名鼎鼎的Activiti了。很久以前學(xué)習(xí)Activiti框架時(shí)我也曾記錄過一篇文章。盡管當(dāng)時(shí)只是學(xué)習(xí)了一下在之后的相關(guān)工作和項(xiàng)目中并沒有用到,通過學(xué)習(xí)后了解了下, 僅對于知識廣度進(jìn)行了擴(kuò)寬。

最近在一個(gè)開源項(xiàng)目里見到有使用另一個(gè)工做流框架:flowable 。簡單用了下感覺還是挺方便的,于是乎決定還是要來使用下并在此做下記錄,便于后面用到時(shí)可以“拿來主義”,哈哈!

什么是flowable?

對于flowable是什么以及關(guān)于此框架的具體信息可以參看此項(xiàng)目的官方文檔:

https://www.flowable.org/docs/userguide/index.html

官網(wǎng)對于此項(xiàng)目如何使用有非常詳細(xì)的描述,只是目前還沒有對應(yīng)的中文文檔。

Flowable is a light-weight business process engine written in Java.

這是官網(wǎng)文檔對此框架的完美解釋:Flowable是一個(gè)用java語言寫的輕量級工作流引擎。

在簡單了解flowable后與activiti框架相比的第一感覺就是開發(fā)方便快速,易與springBoot等各種框架快速整合。如果項(xiàng)目中需要快速實(shí)現(xiàn)一些工作流的相關(guān)功能那么用此框架是一個(gè)不錯(cuò)的選擇。

使用版本

用測試方便,這里都使用springBoot和flowable最新的穩(wěn)定版本

  • springBoot版本:2.0.1.RELEASE

  • flowable版本:6.3.0

Flowable與springBoot項(xiàng)目整合

添加依賴

將flowable的依賴加入到POM中即可,flowable使用需要一個(gè)數(shù)據(jù)庫,這里為了方便我選擇mysql

<dependencies> ? ?<dependency> ? ? ? ?<groupId>org.springframework.boot</groupId> ? ? ? ?<artifactId>spring-boot-starter-web</artifactId> ? ?</dependency> ? ?<!--flowable工作流依賴--> ? ?<dependency> ? ? ? ?<groupId>org.flowable</groupId> ? ? ? ?<artifactId>flowable-spring-boot-starter</artifactId> ? ? ? ?<version>6.3.0</version> ? ?</dependency> ? ?<!--mysql依賴--> ? ?<dependency> ? ? ? ?<groupId>mysql</groupId> ? ? ? ?<artifactId>mysql-connector-java</artifactId> ? ? ? ?<version>5.1.45</version> ? ?</dependency> </dependencies>

flowable配置

測試方便flowable配置為默認(rèn)的即可。為了測試時(shí)方便看日志信息,我這里將flowable的定時(shí)job功能暫時(shí)關(guān)閉,其他的都用默認(rèn)的

當(dāng)然記得要添加一個(gè)數(shù)據(jù)源,我這里添加的mysql,并且記得建好對應(yīng)的mysql庫,如果沒有建就自己建一個(gè)吧

like this:

CREATE DATABASE flowable-spring-boot DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;

spring: ?datasource: ? ?url: jdbc:mysql://127.0.0.1:3306/flowable-spring-boot?characterEncoding=UTF-8 ? ?username: root ? ?password: root flowable: #關(guān)閉定時(shí)任務(wù)JOB ?async-executor-activate: false

這樣操作后,flowable與springBoot的整個(gè)就完成了!個(gè)人非常方便!

然后就可以運(yùn)行了,初次運(yùn)行時(shí)flowable會(huì)將自動(dòng)執(zhí)行flowable中的初始化腳本完成工作流所需要的數(shù)據(jù)表的建立,如果指定的數(shù)據(jù)庫中還未創(chuàng)建過flowable的相關(guān)數(shù)據(jù)表的話。

定義流程文件

上面已經(jīng)完成了flowable與springboot的整合了,接下來就可以使用此框架進(jìn)行流程需要開發(fā)了!

同樣在flowable官方文檔中對于流程文件它有這樣的建議:

The Flowable engine expects processes to be defined in the BPMN 2.0 format, which is an XML standard that is widely accepted in the industry.

flowable建議采用業(yè)界標(biāo)準(zhǔn)BPMN2.0的XML來描述需要定義的工作流。

那么BPMN這個(gè)流程文件應(yīng)該怎么寫呢?

Typically, such a process definition is modeled with a visual modeling tool, such as the Flowable Designer (Eclipse) or the Flowable Modeler (web application).

上官方文檔中有看到這樣的描述后即便我不會(huì)寫也不怕了。通常都是通過專門的流程建模工具來畫出來的,可以用Eclipse里的流程插件來畫。同時(shí)Flowable也提供了對應(yīng)的web管理臺可以對流程文件進(jìn)行創(chuàng)建。詳見:

https://www.flowable.org/docs/userguide/index.html#flowableUIApps

為了方便測試,這里采用一個(gè)開源項(xiàng)目中的流程文件,其描述如下:

<?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: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="Expense" name="ExpenseProcess" isExecutable="true"> ? ? ? ?<documentation>報(bào)銷流程</documentation> ? ? ? ?<startEvent id="start" name="開始"></startEvent> ? ? ? ?<userTask id="fillTask" name="出差報(bào)銷" flowable:assignee="${taskUser}"> ? ? ? ? ? ?<extensionElements> ? ? ? ? ? ? ? ?<modeler:initiator-can-complete xmlns:modeler="http://flowable.org/modeler"> ? ? ? ? ? ? ? ? ? ?<![CDATA[false]]></modeler:initiator-can-complete> ? ? ? ? ? ?</extensionElements> ? ? ? ?</userTask> ? ? ? ?<exclusiveGateway id="judgeTask"></exclusiveGateway> ? ? ? ?<userTask id="directorTak" name="經(jīng)理審批"> ? ? ? ? ? ?<extensionElements> ? ? ? ? ? ? ? ?<flowable:taskListener event="create" ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? class="com.haiyang.flowable.listener.ManagerTaskHandler"></flowable:taskListener> ? ? ? ? ? ?</extensionElements> ? ? ? ?</userTask> ? ? ? ?<userTask id="bossTask" name="老板審批"> ? ? ? ? ? ?<extensionElements> ? ? ? ? ? ? ? ?<flowable:taskListener event="create" ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? class="com.haiyang.flowable.listener.BossTaskHandler"></flowable:taskListener> ? ? ? ? ? ?</extensionElements> ? ? ? ?</userTask> ? ? ? ?<endEvent id="end" name="結(jié)束"></endEvent> ? ? ? ?<sequenceFlow id="directorNotPassFlow" name="駁回" sourceRef="directorTak" targetRef="fillTask"> ? ? ? ? ? ?<conditionExpression xsi:type="tFormalExpression"><![CDATA[${outcome=='駁回'}]]></conditionExpression> ? ? ? ?</sequenceFlow> ? ? ? ?<sequenceFlow id="bossNotPassFlow" name="駁回" sourceRef="bossTask" targetRef="fillTask"> ? ? ? ? ? ?<conditionExpression xsi:type="tFormalExpression"><![CDATA[${outcome=='駁回'}]]></conditionExpression> ? ? ? ?</sequenceFlow> ? ? ? ?<sequenceFlow id="flow1" sourceRef="start" targetRef="fillTask"></sequenceFlow> ? ? ? ?<sequenceFlow id="flow2" sourceRef="fillTask" targetRef="judgeTask"></sequenceFlow> ? ? ? ?<sequenceFlow id="judgeMore" name="大于500元" sourceRef="judgeTask" targetRef="bossTask"> ? ? ? ? ? ?<conditionExpression xsi:type="tFormalExpression"><![CDATA[${money > 500}]]></conditionExpression> ? ? ? ?</sequenceFlow> ? ? ? ?<sequenceFlow id="bossPassFlow" name="通過" sourceRef="bossTask" targetRef="end"> ? ? ? ? ? ?<conditionExpression xsi:type="tFormalExpression"><![CDATA[${outcome=='通過'}]]></conditionExpression> ? ? ? ?</sequenceFlow> ? ? ? ?<sequenceFlow id="directorPassFlow" name="通過" sourceRef="directorTak" targetRef="end"> ? ? ? ? ? ?<conditionExpression xsi:type="tFormalExpression"><![CDATA[${outcome=='通過'}]]></conditionExpression> ? ? ? ?</sequenceFlow> ? ? ? ?<sequenceFlow id="judgeLess" name="小于500元" sourceRef="judgeTask" targetRef="directorTak"> ? ? ? ? ? ?<conditionExpression xsi:type="tFormalExpression"><![CDATA[${money <= 500}]]></conditionExpression> ? ? ? ?</sequenceFlow> ? ?</process> ? ?<bpmndi:BPMNDiagram id="BPMNDiagram_Expense"> ? ? ? ?<bpmndi:BPMNPlane bpmnElement="Expense" id="BPMNPlane_Expense"> ? ? ? ? ? ?<bpmndi:BPMNShape bpmnElement="start" id="BPMNShape_start"> ? ? ? ? ? ? ? ?<omgdc:Bounds height="30.0" width="30.0" x="285.0" y="135.0"></omgdc:Bounds> ? ? ? ? ? ?</bpmndi:BPMNShape> ? ? ? ? ? ?<bpmndi:BPMNShape bpmnElement="fillTask" id="BPMNShape_fillTask"> ? ? ? ? ? ? ? ?<omgdc:Bounds height="80.0" width="100.0" x="405.0" y="110.0"></omgdc:Bounds> ? ? ? ? ? ?</bpmndi:BPMNShape> ? ? ? ? ? ?<bpmndi:BPMNShape bpmnElement="judgeTask" id="BPMNShape_judgeTask"> ? ? ? ? ? ? ? ?<omgdc:Bounds height="40.0" width="40.0" x="585.0" y="130.0"></omgdc:Bounds> ? ? ? ? ? ?</bpmndi:BPMNShape> ? ? ? ? ? ?<bpmndi:BPMNShape bpmnElement="directorTak" id="BPMNShape_directorTak"> ? ? ? ? ? ? ? ?<omgdc:Bounds height="80.0" width="100.0" x="735.0" y="110.0"></omgdc:Bounds> ? ? ? ? ? ?</bpmndi:BPMNShape> ? ? ? ? ? ?<bpmndi:BPMNShape bpmnElement="bossTask" id="BPMNShape_bossTask"> ? ? ? ? ? ? ? ?<omgdc:Bounds height="80.0" width="100.0" x="555.0" y="255.0"></omgdc:Bounds> ? ? ? ? ? ?</bpmndi:BPMNShape> ? ? ? ? ? ?<bpmndi:BPMNShape bpmnElement="end" id="BPMNShape_end"> ? ? ? ? ? ? ? ?<omgdc:Bounds height="28.0" width="28.0" x="771.0" y="281.0"></omgdc:Bounds> ? ? ? ? ? ?</bpmndi:BPMNShape> ? ? ? ? ? ?<bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1"> ? ? ? ? ? ? ? ?<omgdi:waypoint x="315.0" y="150.0"></omgdi:waypoint> ? ? ? ? ? ? ? ?<omgdi:waypoint x="405.0" y="150.0"></omgdi:waypoint> ? ? ? ? ? ?</bpmndi:BPMNEdge> ? ? ? ? ? ?<bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2"> ? ? ? ? ? ? ? ?<omgdi:waypoint x="505.0" y="150.16611295681062"></omgdi:waypoint> ? ? ? ? ? ? ? ?<omgdi:waypoint x="585.4333333333333" y="150.43333333333334"></omgdi:waypoint> ? ? ? ? ? ?</bpmndi:BPMNEdge> ? ? ? ? ? ?<bpmndi:BPMNEdge bpmnElement="judgeLess" id="BPMNEdge_judgeLess"> ? ? ? ? ? ? ? ?<omgdi:waypoint x="624.5530726256983" y="150.44692737430168"></omgdi:waypoint> ? ? ? ? ? ? ? ?<omgdi:waypoint x="735.0" y="150.1392757660167"></omgdi:waypoint> ? ? ? ? ? ?</bpmndi:BPMNEdge> ? ? ? ? ? ?<bpmndi:BPMNEdge bpmnElement="directorNotPassFlow" id="BPMNEdge_directorNotPassFlow"> ? ? ? ? ? ? ? ?<omgdi:waypoint x="785.0" y="110.0"></omgdi:waypoint> ? ? ? ? ? ? ? ?<omgdi:waypoint x="785.0" y="37.0"></omgdi:waypoint> ? ? ? ? ? ? ? ?<omgdi:waypoint x="455.0" y="37.0"></omgdi:waypoint> ? ? ? ? ? ? ? ?<omgdi:waypoint x="455.0" y="110.0"></omgdi:waypoint> ? ? ? ? ? ?</bpmndi:BPMNEdge> ? ? ? ? ? ?<bpmndi:BPMNEdge bpmnElement="bossPassFlow" id="BPMNEdge_bossPassFlow"> ? ? ? ? ? ? ? ?<omgdi:waypoint x="655.0" y="295.0"></omgdi:waypoint> ? ? ? ? ? ? ? ?<omgdi:waypoint x="771.0" y="295.0"></omgdi:waypoint> ? ? ? ? ? ?</bpmndi:BPMNEdge> ? ? ? ? ? ?<bpmndi:BPMNEdge bpmnElement="judgeMore" id="BPMNEdge_judgeMore"> ? ? ? ? ? ? ? ?<omgdi:waypoint x="605.4340277777778" y="169.56597222222223"></omgdi:waypoint> ? ? ? ? ? ? ? ?<omgdi:waypoint x="605.1384083044983" y="255.0"></omgdi:waypoint> ? ? ? ? ? ?</bpmndi:BPMNEdge> ? ? ? ? ? ?<bpmndi:BPMNEdge bpmnElement="directorPassFlow" id="BPMNEdge_directorPassFlow"> ? ? ? ? ? ? ? ?<omgdi:waypoint x="785.0" y="190.0"></omgdi:waypoint> ? ? ? ? ? ? ? ?<omgdi:waypoint x="785.0" y="281.0"></omgdi:waypoint> ? ? ? ? ? ?</bpmndi:BPMNEdge> ? ? ? ? ? ?<bpmndi:BPMNEdge bpmnElement="bossNotPassFlow" id="BPMNEdge_bossNotPassFlow"> ? ? ? ? ? ? ? ?<omgdi:waypoint x="555.0" y="295.0"></omgdi:waypoint> ? ? ? ? ? ? ? ?<omgdi:waypoint x="455.0" y="295.0"></omgdi:waypoint> ? ? ? ? ? ? ? ?<omgdi:waypoint x="455.0" y="190.0"></omgdi:waypoint> ? ? ? ? ? ?</bpmndi:BPMNEdge> ? ? ? ?</bpmndi:BPMNPlane> ? ?</bpmndi:BPMNDiagram> </definitions>

其中的兩個(gè)代理類為:

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("經(jīng)理"); ? ?} }public class BossTaskHandler implements TaskListener { ? ?@Override ? ?public void notify(DelegateTask delegateTask) { ? ? ? ?delegateTask.setAssignee("老板"); ? ?} }

為了方便,也可以去掉這兩個(gè)JAVA類,將其對應(yīng)的task改寫為如下的形式:

<userTask id="holidayApprovedTask" name="Holiday approved" flowable:assignee="${employee}"/>

盡管上面的BPMN文件很長,但放心,畢竟那是通過相關(guān)的工具生成出來的,對于核心的邏輯部分也很少(主要在process 標(biāo)簽內(nèi)) ,如需要詳細(xì)了解的可自行學(xué)習(xí)下BPMN的標(biāo)簽即可!當(dāng)然,在flowable的使用文檔中也有相關(guān)的描述,詳見:

https://www.flowable.org/docs/userguide/index.html#configuration

如上定義好一個(gè)流程文件后,將其命令為ExpenseProcess.bpmn20.xml并將其放于項(xiàng)目中的resource目錄下的processes(如此目錄不存在自行創(chuàng)建)目錄下就可以了。

like this:

這樣當(dāng)此框架啟動(dòng)的時(shí)候它會(huì)默認(rèn)加載resource目錄下的processes時(shí)就可以將此流程配置加載到數(shù)據(jù)庫進(jìn)行持久化了

測試controller

為了方便這里通過一個(gè)controller來完成此DEMO的快速編寫

@Controller @RequestMapping(value = "expense") public class ExpenseController { ? ?@Autowired ? ?private RuntimeService runtimeService; ? ?@Autowired ? ?private TaskService taskService; ? ?@Autowired ? ?private RepositoryService repositoryService; ? ?@Autowired ? ?private ProcessEngine processEngine; /***************此處為業(yè)務(wù)代碼******************/ }

寫一個(gè)controller,并注入由flowable框架啟動(dòng)時(shí)自動(dòng)注冊的幾個(gè)bean,下面的功能將會(huì)用到!

開始流程

/** * 添加報(bào)銷 * * @param userId ? ?用戶Id * @param money ? ? 報(bào)銷金額 * @param descption 描述 */ @RequestMapping(value = "add") @ResponseBody public String addExpense(String userId, Integer money, String descption) { ? ?//啟動(dòng)流程 ? ?HashMap<String, Object> map = new HashMap<>(); ? ?map.put("taskUser", userId); ? ?map.put("money", money); ? ?ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("Expense", map); ? ?return "提交成功.流程Id為:" + processInstance.getId(); }

上面的代碼通過接收用戶的一個(gè)請求傳入用戶的ID和金額以及描述信息來開啟一個(gè)報(bào)銷流程,并返回給用戶這個(gè)流程的Id

查詢流程列表,待辦列表

/** * 獲取審批管理列表 */ @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(task.toString()); ? ?} ? ?return tasks.toArray().toString(); }

通過上面的代碼獲取出此用戶需要處理的流程。

批準(zhǔn),同意

/** * 批準(zhǔn) * * @param taskId 任務(wù)ID */ @RequestMapping(value = "apply") @ResponseBody public String apply(String taskId) { ? ?Task task = taskService.createTaskQuery().taskId(taskId).singleResult(); ? ?if (task == null) { ? ? ? ?throw new RuntimeException("流程不存在"); ? ?} ? ?//通過審核 ? ?HashMap<String, Object> map = new HashMap<>(); ? ?map.put("outcome", "通過"); ? ?taskService.complete(taskId, map); ? ?return "processed ok!"; }

通過前端傳入的任務(wù)ID來對此流程進(jìn)行同意處理

拒絕,不同意

/** * 拒絕 */ @ResponseBody @RequestMapping(value = "reject") public String reject(String taskId) { ? ?HashMap<String, Object> map = new HashMap<>(); ? ?map.put("outcome", "駁回"); ? ?taskService.complete(taskId, map); ? ?return "reject"; }

生成當(dāng)前流程圖表

? ?/** ? ? * 生成流程圖 ? ? * ? ? * @param processId 任務(wù)ID ? ? */ ? ?@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(); ? ? ? ?//使用流程實(shí)例ID,查詢正在執(zhí)行的執(zhí)行對象表,返回流程實(shí)例對象 ? ? ? ?String InstanceId = task.getProcessInstanceId(); ? ? ? ?List<Execution> executions = runtimeService ? ? ? ? ? ? ? ?.createExecutionQuery() ? ? ? ? ? ? ? ?.processInstanceId(InstanceId) ? ? ? ? ? ? ? ?.list(); ? ? ? ?//得到正在執(zhí)行的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); ? ? ? ?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(); ? ? ? ? ? ?} ? ? ? ?} ? ?}

通過傳入流程ID生成當(dāng)前流程的流程圖給前端,如果流程中使用到中文且生成的圖片是亂碼的,則需要進(jìn)配置下字體:

/** * @author haiyangp * desc: flowable配置----為放置生成的流程圖中中文亂碼 */ @Configuration public class FlowableConfig implements EngineConfigurationConfigurer<SpringProcessEngineConfiguration> { ? ?@Override ? ?public void configure(SpringProcessEngineConfiguration engineConfiguration) { ? ? ? ?engineConfiguration.setActivityFontName("宋體"); ? ? ? ?engineConfiguration.setLabelFontName("宋體"); ? ? ? ?engineConfiguration.setAnnotationFontName("宋體"); ? ?} }

整體演示

上面的代碼寫好后就可以演示下整體流程了

1.先啟動(dòng)好此項(xiàng)目,然后創(chuàng)建一個(gè)流程:

訪問:http://localhost:8080/expense/add?userId=123&money=123321

返回:提交成功.流程Id為:2501

2. 查詢待辦列表:

訪問:http://localhost:8080/expense/list?userId=123

輸出:Task[id=2507, name=出差報(bào)銷]

3. 同意:

訪問:http://localhost:8080/expense/apply?taskId=2507

返回:processed ok!

4. 生成流程圖:

訪問:http://localhost:8080/expense/processDiagram?processId=2501

返回如下圖片:

整體流程截圖如下:

總結(jié)

通過springBoot與flowable的整合體驗(yàn)到了工作流的開發(fā)原來如此簡單方便。

給此框架點(diǎn)贊,向巨人們致敬!

本文源碼地址:https://github.com/puhaiyang/flowable-springboot



SpringBoot+flowable快速實(shí)現(xiàn)工作流,超級方便的評論 (共 條)

分享到微博請遵守國家法律
灵丘县| 隆回县| 陆河县| 当雄县| 长兴县| 嘉义县| 大兴区| 大石桥市| 阿拉尔市| 老河口市| 邵阳县| 阜城县| 大方县| 峡江县| 宜黄县| 晋江市| 神池县| 昌都县| 郸城县| 乌拉特前旗| 平乐县| 湖南省| 西畴县| 上栗县| 福海县| 五莲县| 屯门区| 昆山市| 石泉县| 尚义县| 塔河县| 衡山县| 玛纳斯县| 武冈市| 正阳县| 塔城市| 霞浦县| 册亨县| 河曲县| 天长市| 阳西县|