<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          SpringBoot+flowable快速實現(xiàn)工作流,優(yōu)秀的工作流輪子

          共 9246字,需瀏覽 19分鐘

           ·

          2022-02-15 21:20


          1

          背景


          • 使用flowable自帶的flowable-ui制作流程圖

          • 使用springboot開發(fā)流程使用的接口完成流程的業(yè)務(wù)功能



          2

          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.0\wars\flowable-ui.war 丟到Tomcat中跑起來

          3、打開http://localhost:8080/flowable-ui 用賬戶:admin/test 登錄



          4、進入APP.MODELER創(chuàng)建流程,之后可以導(dǎo)出流程到項目中使用,或者配置

          apache-tomcat-9.0.37\webapps\flowable-ui\WEB-INF\classes\flowable-default.properties連接本地數(shù)據(jù)庫



          注意:需要將java驅(qū)動jar(mysql-connector-java-5.1.45.jar)復(fù)制到 apache-tomcat-9.0.37\webapps\flowable-rest\WEB-INF\lib這樣創(chuàng)建的流程后端程序就能直接使用



          3

          繪制流程圖



          根據(jù)業(yè)務(wù)需要在 flowable-ui>APP.MODELER里面繪制流程圖,示例如上圖。先解釋一些概念。


          • 事件(event)通常用于為流程生命周期中發(fā)生的事情建模,圖里是【開始、結(jié)束】兩個圈。

          • 順序流(sequence flow)是流程中兩個元素間的連接器。圖里是【箭頭線段】。

          • 網(wǎng)關(guān)(gateway)用于控制執(zhí)行的流向。圖里是【菱形(中間有X)】

          • 用戶任務(wù)(user task)用于對需要人工執(zhí)行的任務(wù)進行建模。圖里是【矩形】。


          簡單的工作流大概就這些元素(還有很多這里就不擴展了)。下面描述一下工作流是如何流動的。


          首先啟動了工作流后,由【開始】節(jié)點自動流向【學(xué)生】節(jié)點,等待該任務(wù)執(zhí)行。任務(wù)被分配的學(xué)生用戶執(zhí)行后流向 【老師】節(jié)點,再次等待該任務(wù)執(zhí)行。被分配的老師用戶執(zhí)行后流向 【網(wǎng)關(guān)】,網(wǎng)關(guān)以此檢查每個出口,流向符合條件的任務(wù),比如這里老師執(zhí)行任務(wù)時是同意,就流向【校長】節(jié)點,等待該任務(wù)執(zhí)行。執(zhí)行后跟老師類似,同意后就流向【結(jié)束】節(jié)點,整個流程到此結(jié)束。


          繪圖細節(jié):


          1、保留流程模型



          2、順序流可以設(shè)置流條件來限制流動,比如上面的網(wǎng)關(guān)出口就設(shè)置了條件



          3、任務(wù)需要分配任務(wù)的執(zhí)行用戶,可以分配到候選組,也可以直接分配到候選人



          最后導(dǎo)出工作流文件



          文件內(nèi)容


          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-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">
          ??<process?id="leave_approval"?name="請假審批"?isExecutable="true">
          ????<startEvent?id="start"?name="開始"?flowable:initiator="startuser"?flowable:formFieldValidation="true">startEvent>

          ????<userTask?id="stu_task"?name="學(xué)生"?flowable:candidateGroups="stu_group"?flowable:formFieldValidation="true">userTask>

          ????<sequenceFlow?id="flow1"?sourceRef="start"?targetRef="stu_task">sequenceFlow>
          ????<userTask?id="te_task"?name="老師"?flowable:candidateGroups="te_group"?flowable:formFieldValidation="true">userTask>
          ????<exclusiveGateway?id="getway1"?name="網(wǎng)關(guān)1">exclusiveGateway>
          ????<userTask?id="mte_task"?name="校長"?flowable:candidateGroups="mte_group"?flowable:formFieldValidation="true">userTask>
          ????<exclusiveGateway?id="getway2"?name="網(wǎng)關(guān)2">exclusiveGateway>
          ????<endEvent?id="end"?name="結(jié)束">endEvent>
          ????<sequenceFlow?id="flow1"?name="請假"?sourceRef="stu_task"?targetRef="te_task"?skipExpression="${command=='agree'}">sequenceFlow>
          ????<sequenceFlow?id="flow3_1"?name="同意"?sourceRef="getway1"?targetRef="mte_task">
          ??????<conditionExpression?xsi:type="tFormalExpression">conditionExpression>
          ????sequenceFlow>
          ????<sequenceFlow?id="flow2"?name="審批"?sourceRef="te_task"?targetRef="getway1">sequenceFlow>
          ????<sequenceFlow?id="flow3_2"?name="拒絕"?sourceRef="getway1"?targetRef="stu_task">
          ??????<conditionExpression?xsi:type="tFormalExpression">conditionExpression>
          ????sequenceFlow>
          ????<sequenceFlow?id="flow4"?name="審批"?sourceRef="mte_task"?targetRef="getway2">sequenceFlow>
          ????<sequenceFlow?id="flow4_1"?name="同意"?sourceRef="getway2"?targetRef="end"?skipExpression="${command=='free'}">
          ??????<conditionExpression?xsi:type="tFormalExpression">conditionExpression>
          ????sequenceFlow>
          ????<sequenceFlow?id="flow4_2"?name="拒絕"?sourceRef="getway2"?targetRef="stu_task">
          ??????<conditionExpression?xsi:type="tFormalExpression">conditionExpression>
          ????sequenceFlow>
          ??process>
          ??<bpmndi:BPMNDiagram?id="BPMNDiagram_leave_approval">
          ????這里先省略
          ??bpmndi:BPMNDiagram>
          definitions>


          4、bpmn文件導(dǎo)入


          如果需要,可以把這個流程文件下載下來,直接導(dǎo)入使用




          4

          后臺項目搭建


          后臺項目基于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:mysql://localhost:3306/flowable?useSSL=false&characterEncoding=UTF-8&serverTimezone=GMT%2B8
          ????driver-class-name: com.mysql.jdbc.Driver
          ????username: root
          ????password: 123456



          5

          數(shù)據(jù)庫


          1、Flowable的所有數(shù)據(jù)庫表都以ACT_開頭。第二部分是說明表用途的兩字符標(biāo)示符。服務(wù)API的命名也大略符合這個規(guī)則。

          2、ACT_RE_: 'RE’代表repository。帶有這個前綴的表包含“靜態(tài)”信息,例如流程定義與流程資源(圖片、規(guī)則等)。

          3、ACT_RU_: 'RU’代表runtime。這些表存儲運行時信息,例如流程實例(process instance)、用戶任務(wù)(user task)、變量(variable)、作業(yè)(job)等。Flowable只在流程實例運行中保存運行時數(shù)據(jù),并在流程實例結(jié)束時刪除記錄。這樣保證運行時表小和快。

          4、ACT_HI_: 'HI’代表history。這些表存儲歷史數(shù)據(jù),例如已完成的流程實例、變量、任務(wù)等。

          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é)束等非任務(wù)節(jié)點);
          act_hi_attachment:歷史附件表,存放歷史節(jié)點上傳的附件信息(不常用);
          act_hi_comment:歷史意見表;
          act_hi_detail:歷史詳情表,存儲節(jié)點運轉(zhuǎn)的一些信息(不常用);
          act_hi_identitylink:歷史流程人員表,存儲流程各節(jié)點候選、辦理人員信息,常用于查詢某人或部門的已辦任務(wù);
          act_hi_procinst:歷史流程實例表,存儲流程實例歷史數(shù)據(jù)(包含正在運行的流程實例);
          act_hi_taskinst:歷史流程任務(wù)表,存儲歷史任務(wù)節(jié)點;
          act_hi_varinst:流程歷史變量表,存儲流程歷史節(jié)點的變量信息;

          3)用戶相關(guān)表(4個,IdentityService接口操作的表)

          act_id_group:用戶組信息表,對應(yīng)節(jié)點選定候選組信息;
          act_id_info:用戶擴展信息表,存儲用戶擴展信息;
          act_id_membership:用戶與用戶組關(guān)系表;
          act_id_user:用戶信息表,對應(yīng)節(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:運行時流程任務(wù)節(jié)點表,存儲運行中流程的任務(wù)節(jié)點信息,重要,常用于查詢?nèi)藛T或部門的待辦任務(wù)時使用;
          act_ru_event_subscr:監(jiān)聽信息表,不常用;
          act_ru_execution:運行時流程執(zhí)行實例表,記錄運行中流程運行的各個分支信息(當(dāng)沒有子流程時,其數(shù)據(jù)與act_ru_task表數(shù)據(jù)是一一對應(yīng)的);
          act_ru_identitylink:運行時流程人員表,重要,常用于查詢?nèi)藛T或部門的待辦任務(wù)時使用;
          act_ru_job:運行時定時任務(wù)數(shù)據(jù)表,存儲流程的定時任務(wù)信息;
          act_ru_variable:運行時流程變量數(shù)據(jù)表,存儲運行中的流程各節(jié)點的變量信息;



          6

          流程引擎API與服務(wù)


          引擎API是與Flowable交互的最常用手段???cè)肟邳c是ProcessEngine。



          1、RepositoryService很可能是使用Flowable引擎要用的第一個服務(wù)。這個服務(wù)提供了管理與控制部署(deployments)與流程定義(process

          definitions)的操作。管理靜態(tài)信息, 2、RuntimeService用于啟動流程定義的新流程實例。

          3、IdentityService很簡單。它用于管理(創(chuàng)建,更新,刪除,查詢……)組與用戶。

          4、FormService是可選服務(wù)。也就是說Flowable沒有它也能很好地運行,而不必犧牲任何功能。

          5、HistoryService暴露Flowable引擎收集的所有歷史數(shù)據(jù)。要提供查詢歷史數(shù)據(jù)的能力。

          6、ManagementService通常在用Flowable編寫用戶應(yīng)用時不需要使用。它可以讀取數(shù)據(jù)庫表與表原始數(shù)據(jù)的信息,也提供了對作業(yè)(job)的查詢與管理操作。

          7、DynamicBpmnService可用于修改流程定義中的部分內(nèi)容,而不需要重新部署它。例如可以修改流程定義中一個用戶任務(wù)的辦理人設(shè)置,或者修改一個服務(wù)任務(wù)中的類名。


          接下來使用之前的請假流程圖,上代碼


          @Slf4j
          public?class?TestFlowable?{
          ????@Autowired
          ????private?RepositoryService repositoryService;
          ????@Autowired
          ????private?RuntimeService runtimeService;
          ????@Autowired
          ????private?HistoryService historyService;
          ????@Autowired
          ????private?org.flowable.engine.TaskService taskService;
          ????@Autowired
          ????private?org.flowable.engine.IdentityService identityService;
          ????public?void createDeploymentZip() {
          ????????/*
          ?????????* Step 1: 部署xml(壓縮到zip形式,直接xml需要配置相對路徑,麻煩,暫不用)
          ?????????*/

          ????????try?{
          ????????????File zipTemp = new?File("f:/leave_approval.bpmn20.zip");
          ????????????ZipInputStream zipInputStream = new?ZipInputStream(new?FileInputStream(zipTemp));
          ????????????Deployment deployment = repositoryService
          ????????????????????.createDeployment()
          ????????????????????.addZipInputStream(zipInputStream)
          ????????????????????.deploy();
          ????????????log.info("部署成功:{}", deployment.getId());
          ????????} catch?(FileNotFoundException e) {
          ????????????e.printStackTrace();
          ????????}
          ????????/*
          ?????????* Step 2: 查詢部署的流程定義
          ?????????*/

          ????????List list?= repositoryService.createProcessDefinitionQuery().processDefinitionKey("leave_approval").list();
          ????????List pages = repositoryService.createProcessDefinitionQuery().processDefinitionKey("leave_approval").listPage(1, 30);
          ????????/*
          ?????????* Step 3: 啟動流程,創(chuàng)建實例
          ?????????*/

          ????????String processDefinitionKey = "leave_approval";//流程定義的key,對應(yīng)請假的流程圖
          ????????String businessKey = "schoolleave";//業(yè)務(wù)代碼,根據(jù)自己的業(yè)務(wù)用
          ????????Map variablesDefinition = new?HashMap<>();//流程變量,可以自定義擴充
          ????????ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey, businessKey, variablesDefinition);
          ????????log.info("啟動成功:{}", processInstance.getId());
          ????????/*
          ?????????* Step 4: 查詢指定流程所有啟動的實例列表
          ?????????* 列表,或 分頁 刪除
          ?????????*/

          ????????List executions = runtimeService.createExecutionQuery().processDefinitionKey("leave_approval").list();
          ????????List executionPages = runtimeService.createExecutionQuery().processDefinitionKey("leave_approval").listPage(1, 30);
          // runtimeService.deleteProcessInstance(processInstanceId, deleteReason); //刪除實例
          ????????/*
          ?????????* Step 5: 學(xué)生查詢可以操作的任務(wù),并完成任務(wù)
          ?????????*/

          ????????String candidateGroup = "stu_group"; //候選組 xml文件里面的 flowable:candidateGroups="stu_group"
          ????????List taskList = taskService.createTaskQuery().taskCandidateGroup(candidateGroup).orderByTaskCreateTime().desc().list();
          ????????for?(Task task : taskList) {
          ????????????// 申領(lǐng)任務(wù)
          ????????????taskService.claim(task.getId(), "my");
          ????????????// 完成
          ????????????taskService.complete(task.getId());
          ????????}
          ????????/*
          ?????????* Step 6: 老師查詢可以操作的任務(wù),并完成任務(wù)
          ?????????*/

          ????????String candidateGroupTe = "te_group"; //候選組 xml文件里面的 flowable:candidateGroups="te_group"
          ????????List taskListTe = taskService.createTaskQuery().taskCandidateGroup(candidateGroupTe).orderByTaskCreateTime().desc().list();
          ????????for?(Task task : taskListTe) {
          ????????????// 申領(lǐng)任務(wù)
          ????????????taskService.claim(task.getId(), "myte");
          ????????????// 完成
          ????????????Map variables = new?HashMap<>();
          ????????????variables.put("command","agree"); //攜帶變量,用于網(wǎng)關(guān)流程的條件判定,這里的條件是同意
          ????????????taskService.complete(task.getId(), variables);
          ????????}
          ????????/*
          ?????????* Step 7: 歷史查詢,因為一旦流程執(zhí)行完畢,活動的數(shù)據(jù)都會被清空,上面查詢的接口都查不到數(shù)據(jù),但是提供歷史查詢接口
          ?????????*/

          ????????// 歷史流程實例
          ????????List historicProcessList = historyService.createHistoricProcessInstanceQuery().processDefinitionKey("leave_approval").list();
          ????????// 歷史任務(wù)
          ????????List historicTaskList = historyService.createHistoricTaskInstanceQuery().processDefinitionKey("leave_approval").list();
          ????????// 實例歷史變量 , 任務(wù)歷史變量
          ????????// historyService.createHistoricVariableInstanceQuery().processInstanceId(processInstanceId);
          ????????// historyService.createHistoricVariableInstanceQuery().taskId(taskId);
          ????????// *****************************************************分隔符********************************************************************
          ????????// *****************************************************分隔符********************************************************************
          ????????// 可能還需要的API
          ????????// 移動任務(wù),人為跳轉(zhuǎn)任務(wù)
          ????????// runtimeService.createChangeActivityStateBuilder().processInstanceId(processInstanceId)
          ????????// .moveActivityIdTo(currentActivityTaskId, newActivityTaskId).changeState();
          ????????// 如果在數(shù)據(jù)庫配置了分組和用戶,還會用到
          ????????List users = identityService.createUserQuery().list(); //用戶查詢,用戶id對應(yīng)xml 里面配置的用戶
          ????????List groups = identityService.createGroupQuery().list(); //分組查詢,分組id對應(yīng)xml 里面配置的分組 如 stu_group,te_group 在表里是id的值
          ????????// 另外,每個查詢后面都可以拼條件,內(nèi)置恁多查詢,包括模糊查詢,大小比較都有
          ????}
          }


          參考資料

          【1】分享牛Flowable文檔漢化:https://github.com/qiudaoke/flowable-userguide

          【2】貓七姑娘 flowable-6.6.0 運行官方 demo

          【3】華格瑞沙 https://www.cnblogs.com/yangjiming/p/10938515.html


          來源:blog.csdn.net/zhan107876/article/details/120815560



          往期推薦



          節(jié)后面試必備:Spring 面試常見問題,做好跳槽準備了嘛???

          SpringBoot 那些自帶 Buff 的工具類,你用過幾個?

          幾款實用的內(nèi)網(wǎng)穿透工具,推薦!

          神器 Markmap ?。?!

          MySQL 的 varchar 水真的太深了!!

          Nginx配置反向代理,一篇搞定!



          瀏覽 31
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  蜜乳一区二区 | 黑人大屌与欧美成人视频 | 亚洲天堂无码在线观看 | 天堂中文在线观看视频 | 成人午夜无码影院 |