- 使用flowable自帶的flowable-ui制作流程圖
- 使用springboot開發(fā)流程使用的接口完成流程的業(yè)務功能
一、flowable-ui部署運行
flowable-6.6.0 運行 官方demo
參考文檔:
https://flowable.com/open-source/docs/bpmn/ch14-Applications/
1、從官網(wǎng)下載flowable-6.6.0 : https://github.com/flowable/flowable-engine/releases/download/flowable-6.6.0/flowable-6.6.0.zip
2、將壓縮包中的 flowable-6.6.0warsflowable-ui.war
丟到Tomcat中跑起來
3、打開http://localhost:8080/flowable-ui
用賬戶:admin/test 登錄
4、進入APP.MODELER創(chuàng)建流程,之后可以導出流程到項目中使用,或者配置apache-tomcat-9.0.37webappsflowable-uiWEB-INFclassesflowable-default.properties
連接本地數(shù)據(jù)庫
注意:需要將java驅(qū)動jar(
mysql-connector-java-5.1.45.jar
)復制到apache-tomcat-9.0.37webappsflowable-restWEB-INFlib
這樣創(chuàng)建的流程后端程序就能直接使用
二、繪制流程圖
根據(jù)業(yè)務需要在 flowable-ui>APP.MODELER里面繪制流程圖,示例如上圖。先解釋一些概念。
- 事件(event) 通常用于為流程生命周期中發(fā)生的事情建模,圖里是【開始、結(jié)束】兩個圈。
- 順序流(sequence flow) 是流程中兩個元素間的連接器。圖里是【箭頭線段】。
- 網(wǎng)關(guān)(gateway) 用于控制執(zhí)行的流向。圖里是【菱形(中間有X)】
- 用戶任務(user task) 用于對需要人工執(zhí)行的任務進行建模。圖里是【矩形】。
簡單的工作流大概就這些元素(還有很多這里就不擴展了)。下面描述一下工作流是如何流動的。
首先啟動了工作流后,由【開始】節(jié)點自動流向【學生】節(jié)點,等待該任務執(zhí)行。任務被分配的學生用戶執(zhí)行后流向 【老師】節(jié)點,再次等待該任務執(zhí)行。被分配的老師用戶執(zhí)行后流向 【網(wǎng)關(guān)】,網(wǎng)關(guān)以此檢查每個出口,流向符合條件的任務,比如這里老師執(zhí)行任務時是同意,就流向【校長】節(jié)點,等待該任務執(zhí)行。執(zhí)行后跟老師類似,同意后就流向【結(jié)束】節(jié)點,整個流程到此結(jié)束。
繪圖細節(jié):
1、保留流程模型
2、順序流可以設(shè)置流條件來限制流動,比如上面的網(wǎng)關(guān)出口就設(shè)置了條件
3、任務需要分配任務的執(zhí)行用戶,可以分配到候選組,也可以直接分配到候選人
最后導出工作流文件
文件內(nèi)容
<definitionsxmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"xmlns:xsi="http://www.w3.org/2001/XMLSchema-insmtece"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">
<processid="leave_approval"name="請假審批"isExecutable="true">
<startEventid="start"name="開始"flowable:initiator="startuser"flowable:formFieldValidation="true">startEvent>
<userTaskid="stu_task"name="學生"flowable:candidateGroups="stu_group"flowable:formFieldValidation="true">userTask>
<sequenceFlowid="flow1"sourceRef="start"targetRef="stu_task">sequenceFlow>
<userTaskid="te_task"name="老師"flowable:candidateGroups="te_group"flowable:formFieldValidation="true">userTask>
<exclusiveGatewayid="getway1"name="網(wǎng)關(guān)1">exclusiveGateway>
<userTaskid="mte_task"name="校長"flowable:candidateGroups="mte_group"flowable:formFieldValidation="true">userTask>
<exclusiveGatewayid="getway2"name="網(wǎng)關(guān)2">exclusiveGateway>
<endEventid="end"name="結(jié)束">endEvent>
<sequenceFlowid="flow1"name="請假"sourceRef="stu_task"targetRef="te_task"skipExpression="${command=='agree'}">sequenceFlow>
<sequenceFlowid="flow3_1"name="同意"sourceRef="getway1"targetRef="mte_task">
<conditionExpressionxsi:type="tFormalExpression">conditionExpression>
sequenceFlow>
<sequenceFlowid="flow2"name="審批"sourceRef="te_task"targetRef="getway1">sequenceFlow>
<sequenceFlowid="flow3_2"name="拒絕"sourceRef="getway1"targetRef="stu_task">
<conditionExpressionxsi:type="tFormalExpression">conditionExpression>
sequenceFlow>
<sequenceFlowid="flow4"name="審批"sourceRef="mte_task"targetRef="getway2">sequenceFlow>
<sequenceFlowid="flow4_1"name="同意"sourceRef="getway2"targetRef="end"skipExpression="${command=='free'}">
<conditionExpressionxsi:type="tFormalExpression">conditionExpression>
sequenceFlow>
<sequenceFlowid="flow4_2"name="拒絕"sourceRef="getway2"targetRef="stu_task">
<conditionExpressionxsi:type="tFormalExpression">conditionExpression>
sequenceFlow>
process>
<bpmndi:BPMNDiagramid="BPMNDiagram_leave_approval">
這里先省略
bpmndi:BPMNDiagram>
definitions>
4、bpmn文件導入
如果需要,可以把這個流程文件下載下來,直接導入使用
三、后臺項目搭建
后臺項目基于jdk8,使用springboot框架
spring 版本
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.3.0.RELEASEversion>
<relativePath/>
parent>
項目依賴pom.xml
<dependency>
<groupId>org.flowablegroupId>
<artifactId>flowable-spring-boot-starterartifactId>
<version>6.6.0version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>5.1.45version>
dependency>
項目配置application.yml
spring:
datasource:
url:jdbc//localhost:3306/flowable?useSSL=false&characterEncoding=UTF-8&serverTimezone=GMT%2B8
driver-class-name:com.mysql.jdbc.Driver
username:root
password:123456
四、數(shù)據(jù)庫
1、Flowable的所有數(shù)據(jù)庫表都以ACT_開頭。第二部分是說明表用途的兩字符標示符。服務API的命名也大略符合這個規(guī)則。
2、ACT_RE_
: 'RE’代表repository。帶有這個前綴的表包含“靜態(tài)”信息,例如流程定義與流程資源(圖片、規(guī)則等)。
3、ACT_RU_
: 'RU’代表runtime。這些表存儲運行時信息,例如流程實例(process instance)、用戶任務(user task)、變量(variable)、作業(yè)(job)等。Flowable只在流程實例運行中保存運行時數(shù)據(jù),并在流程實例結(jié)束時刪除記錄。這樣保證運行時表小和快。
4、ACT_HI_
: 'HI’代表history。這些表存儲歷史數(shù)據(jù),例如已完成的流程實例、變量、任務等。
5、ACT_GE_
: 通用數(shù)據(jù)。在多處使用。
1)通用數(shù)據(jù)表(2個)
- act_ge_bytearray:二進制數(shù)據(jù)表,如流程定義、流程模板、流程圖的字節(jié)流文件;
- act_ge_property:屬性數(shù)據(jù)表(不常用);
2)歷史表(8個,HistoryService接口操作的表)
- act_hi_actinst:歷史節(jié)點表,存放流程實例運轉(zhuǎn)的各個節(jié)點信息(包含開始、結(jié)束等非任務節(jié)點);
- act_hi_attachment:歷史附件表,存放歷史節(jié)點上傳的附件信息(不常用);
- act_hi_comment:歷史意見表;
- act_hi_detail:歷史詳情表,存儲節(jié)點運轉(zhuǎn)的一些信息(不常用);
- act_hi_identitylink:歷史流程人員表,存儲流程各節(jié)點候選、辦理人員信息,常用于查詢某人或部門的已辦任務;
- act_hi_procinst:歷史流程實例表,存儲流程實例歷史數(shù)據(jù)(包含正在運行的流程實例);
- act_hi_taskinst:歷史流程任務表,存儲歷史任務節(jié)點;
- act_hi_varinst:流程歷史變量表,存儲流程歷史節(jié)點的變量信息;
3)用戶相關(guān)表(4個,IdentityService接口操作的表)
- act_id_group:用戶組信息表,對應節(jié)點選定候選組信息;
- act_id_info:用戶擴展信息表,存儲用戶擴展信息;
- act_id_membership:用戶與用戶組關(guān)系表;
- act_id_user:用戶信息表,對應節(jié)點選定辦理人或候選人信息;
4)流程定義、流程模板相關(guān)表(3個,RepositoryService接口操作的表)
- act_re_deployment:部屬信息表,存儲流程定義、模板部署信息;
- act_re_procdef:流程定義信息表,存儲流程定義相關(guān)描述信息,但其真正內(nèi)容存儲在act_ge_bytearray表中,以字節(jié)形式存儲;
- act_re_model:流程模板信息表,存儲流程模板相關(guān)描述信息,但其真正內(nèi)容存儲在act_ge_bytearray表中,以字節(jié)形式存儲;
5)流程運行時表(6個,RuntimeService接口操作的表)
- act_ru_task:運行時流程任務節(jié)點表,存儲運行中流程的任務節(jié)點信息,重要,常用于查詢?nèi)藛T或部門的待辦任務時使用;
- act_ru_event_subscr:監(jiān)聽信息表,不常用;
- act_ru_execution:運行時流程執(zhí)行實例表,記錄運行中流程運行的各個分支信息(當沒有子流程時,其數(shù)據(jù)與act_ru_task表數(shù)據(jù)是一一對應的);
- act_ru_identitylink:運行時流程人員表,重要,常用于查詢?nèi)藛T或部門的待辦任務時使用;
- act_ru_job:運行時定時任務數(shù)據(jù)表,存儲流程的定時任務信息;
- act_ru_variable:運行時流程變量數(shù)據(jù)表,存儲運行中的流程各節(jié)點的變量信息;
五、流程引擎API與服務
引擎API是與Flowable交互的最常用手段???cè)肟邳c是ProcessEngine。
1、RepositoryService很可能是使用Flowable引擎要用的第一個服務。這個服務提供了管理與控制部署(deployments)與流程定義(process definitions)的操作。管理靜態(tài)信息,
2、RuntimeService用于啟動流程定義的新流程實例。
3、IdentityService很簡單。它用于管理(創(chuàng)建,更新,刪除,查詢……)組與用戶。
4、FormService是可選服務。也就是說Flowable沒有它也能很好地運行,而不必犧牲任何功能。
5、HistoryService暴露Flowable引擎收集的所有歷史數(shù)據(jù)。要提供查詢歷史數(shù)據(jù)的能力。
6、ManagementService通常在用Flowable編寫用戶應用時不需要使用。它可以讀取數(shù)據(jù)庫表與表原始數(shù)據(jù)的信息,也提供了對作業(yè)(job)的查詢與管理操作。
7、DynamicBpmnService可用于修改流程定義中的部分內(nèi)容,而不需要重新部署它。例如可以修改流程定義中一個用戶任務的辦理人設(shè)置,或者修改一個服務任務中的類名。
接下來使用之前的請假流程圖,上代碼
代碼
importlombok.extern.slf4j.Slf4j;
importorg.flowable.engine.HistoryService;
importorg.flowable.engine.RepositoryService;
importorg.flowable.engine.RuntimeService;
importorg.flowable.engine.history.HistoricProcessInstance;
importorg.flowable.engine.repository.Deployment;
importorg.flowable.engine.repository.ProcessDefinition;
importorg.flowable.engine.runtime.Execution;
importorg.flowable.engine.runtime.ProcessInstance;
importorg.flowable.idm.api.Group;
importorg.flowable.idm.api.User;
importorg.flowable.task.api.Task;
importorg.flowable.task.api.history.HistoricTaskInstance;
importorg.springframework.beans.factory.annotation.Autowired;
importjava.io.File;
importjava.io.FileInputStream;
importjava.io.FileNotFoundException;
importjava.util.HashMap;
importjava.util.List;
importjava.util.Map;
importjava.util.zip.ZipInputStream;
/**
*TestFlowable
*
*@Author
*@Date:2021/10/1723:35
*@Version1.0
*/
@Slf4j
publicclassTestFlowable{
@Autowired
privateRepositoryServicerepositoryService;
@Autowired
privateRuntimeServiceruntimeService;
@Autowired
privateHistoryServicehistoryService;
@Autowired
privateorg.flowable.engine.TaskServicetaskService;
@Autowired
privateorg.flowable.engine.IdentityServiceidentityService;
publicvoidcreateDeploymentZip(){
/*
*@Date:2021/10/1723:38
*Step1:部署xml(壓縮到zip形式,直接xml需要配置相對路徑,麻煩,暫不用)
*/
try{
FilezipTemp=newFile("f:/leave_approval.bpmn20.zip");
ZipInputStreamzipInputStream=newZipInputStream(newFileInputStream(zipTemp));
Deploymentdeployment=repositoryService
.createDeployment()
.addZipInputStream(zipInputStream)
.deploy();
log.info("部署成功:{}",deployment.getId());
}catch(FileNotFoundExceptione){
e.printStackTrace();
}
/*
*@Date:2021/10/1723:40
*Step2:查詢部署的流程定義
*/
Listlist=repositoryService.createProcessDefinitionQuery().processDefinitionKey("leave_approval").list();
Listpages=repositoryService.createProcessDefinitionQuery().processDefinitionKey("leave_approval").listPage(1,30);
/*
*@Date:2021/10/1723:40
*Step3:啟動流程,創(chuàng)建實例
*/
StringprocessDefinitionKey="leave_approval";//流程定義的key,對應請假的流程圖
StringbusinessKey="schoolleave";//業(yè)務代碼,根據(jù)自己的業(yè)務用
MapvariablesDefinition=newHashMap<>();//流程變量,可以自定義擴充
ProcessInstanceprocessInstance=runtimeService.startProcessInstanceByKey(processDefinitionKey,businessKey,variablesDefinition);
log.info("啟動成功:{}",processInstance.getId());
/*
*@Date:2021/10/1723:40
*Step4:查詢指定流程所有啟動的實例列表
*列表,或分頁刪除
*/
Listexecutions=runtimeService.createExecutionQuery().processDefinitionKey("leave_approval").list();
ListexecutionPages=runtimeService.createExecutionQuery().processDefinitionKey("leave_approval").listPage(1,30);
//runtimeService.deleteProcessInstance(processInstanceId,deleteReason);//刪除實例
/*
*@Date:2021/10/1723:40
*Step5:學生查詢可以操作的任務,并完成任務
*/
StringcandidateGroup="stu_group";//候選組xml文件里面的flowable:candidateGroups="stu_group"
ListtaskList=taskService.createTaskQuery().taskCandidateGroup(candidateGroup).orderByTaskCreateTime().desc().list();
for(Tasktask:taskList){
//申領(lǐng)任務
taskService.claim(task.getId(),"my");
//完成
taskService.complete(task.getId());
}
/*
*@Date:2021/10/1723:40
*Step6:老師查詢可以操作的任務,并完成任務
*/
StringcandidateGroupTe="te_group";//候選組xml文件里面的flowable:candidateGroups="te_group"
ListtaskListTe=taskService.createTaskQuery().taskCandidateGroup(candidateGroupTe).orderByTaskCreateTime().desc().list();
for(Tasktask:taskListTe){
//申領(lǐng)任務
taskService.claim(task.getId(),"myte");
//完成
Mapvariables=newHashMap<>();
variables.put("command","agree");//攜帶變量,用于網(wǎng)關(guān)流程的條件判定,這里的條件是同意
taskService.complete(task.getId(),variables);
}
/*
*@Date:2021/10/180:17
*Step7:歷史查詢,因為一旦流程執(zhí)行完畢,活動的數(shù)據(jù)都會被清空,上面查詢的接口都查不到數(shù)據(jù),但是提供歷史查詢接口
*/
//歷史流程實例
ListhistoricProcessList=historyService.createHistoricProcessInstanceQuery().processDefinitionKey("leave_approval").list();
//歷史任務
ListhistoricTaskList=historyService.createHistoricTaskInstanceQuery().processDefinitionKey("leave_approval").list();
//實例歷史變量,任務歷史變量
//historyService.createHistoricVariableInstanceQuery().processInstanceId(processInstanceId);
//historyService.createHistoricVariableInstanceQuery().taskId(taskId);
//*****************************************************分隔符********************************************************************
//*****************************************************分隔符********************************************************************
//可能還需要的API
//移動任務,人為跳轉(zhuǎn)任務
//runtimeService.createChangeActivityStateBuilder().processInstanceId(processInstanceId)
//.moveActivityIdTo(currentActivityTaskId,newActivityTaskId).changeState();
//如果在數(shù)據(jù)庫配置了分組和用戶,還會用到
Listusers=identityService.createUserQuery().list();//用戶查詢,用戶id對應xml里面配置的用戶
Listgroups=identityService.createGroupQuery().list();//分組查詢,分組id對應xml里面配置的分組如stu_group,te_group在表里是id的值
//另外,每個查詢后面都可以拼條件,內(nèi)置恁多查詢,包括模糊查詢,大小比較都有
}
}
-
數(shù)據(jù)庫
+關(guān)注
關(guān)注
7文章
3767瀏覽量
64279 -
流程圖
+關(guān)注
關(guān)注
2文章
63瀏覽量
18718 -
代碼
+關(guān)注
關(guān)注
30文章
4753瀏覽量
68368
原文標題:SpringBoot+flowable快速實現(xiàn)工作流,so easy!
文章出處:【微信號:AndroidPush,微信公眾號:Android編程精選】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論