我也沒想到 Springboot + Flowable 開發工作流會這麼簡單

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":">本文收錄在個人博客:"},{"type":"link","attrs":{"href":"http://www.chengxy-nds.top","title":""},"content":[{"type":"text","text":"www.chengxy-nds.top"}]},{"type":"text","text":",技術資料共享,同進步"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"程序員是塊磚,哪裏需要哪裏搬"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"公司內部的OA系統最近要升級改造,由於人手不夠就把我借調過去了,但說真的我還沒做過這方面的功能,第一次接觸工作流的開發,還是有點好奇是個怎樣的流程。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"項目主要用 "},{"type":"codeinline","content":[{"type":"text","text":"Springboot"}]},{"type":"text","text":" + "},{"type":"codeinline","content":[{"type":"text","text":"Flowable"}]},{"type":"text","text":" 重構原有的工作流程,"},{"type":"codeinline","content":[{"type":"text","text":"Flowable"}]},{"type":"text","text":" 是個用 "},{"type":"codeinline","content":[{"type":"text","text":"Java"}]},{"type":"text","text":"語言寫的輕量級工作流引擎,上手比較簡單開發效率也挺高的,一起學習下這個框架。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"官方地址:"},{"type":"codeinline","content":[{"type":"text","text":"https://www.flowable.org/docs/userguide/index.html"}]},{"type":"text","text":",分享的只是簡單應用,深入研究還得看官方文檔。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":" Flowable 核心依賴"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"javascript"},"content":[{"type":"text","text":"\n\n\torg.flowable\n\tflowable-spring-boot-starter\n\t6.3.0\n\n\n\torg.springframework.boot\n\tspring-boot-starter-jdbc\n\n\n\torg.springframework.boot\n\tspring-boot-starter-web\n\n\n\torg.mybatis.spring.boot\n\tmybatis-spring-boot-starter\n\t1.3.2\n\n\n\tmysql\n\tmysql-connector-java\n\truntime\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"流程設計"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"工作流開發的核心是任務流程的設計,"},{"type":"codeinline","content":[{"type":"text","text":"Flowable"}]},{"type":"text","text":" 官方建議採用業界標準"},{"type":"codeinline","content":[{"type":"text","text":"BPMN2.0"}]},{"type":"text","text":"的 "},{"type":"codeinline","content":[{"type":"text","text":"XML"}]},{"type":"text","text":"來描述需要定義的工作流。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們需要在 "},{"type":"codeinline","content":[{"type":"text","text":"resource"}]},{"type":"text","text":" 目錄下創建 "},{"type":"codeinline","content":[{"type":"text","text":"processes"}]},{"type":"text","text":"路徑,存放相關的 "},{"type":"codeinline","content":[{"type":"text","text":"XML"}]},{"type":"text","text":"流程配置文件。"},{"type":"codeinline","content":[{"type":"text","text":"Flowable"}]},{"type":"text","text":" 框架會默認加載此目錄下的工作流文件並解析 "},{"type":"codeinline","content":[{"type":"text","text":"XML"}]},{"type":"text","text":",並將解析後的流程配置信息持久化到數據庫。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/57/57703222a45ef0aeb613658c1b886328.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"Flowable"}]},{"type":"text","text":" 是依賴於數據庫的,但它並不需要我們手動的創建表,而是在程序第一次啓動時,自動的向"},{"type":"codeinline","content":[{"type":"text","text":"MySQL"}]},{"type":"text","text":" 中創建它所需要的一系列表。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"javascript"},"content":[{"type":"text","text":"spring:\n datasource:\n url: jdbc:mysql://47.93.6.5:3306/order?serverTimezone=UTC\n username: root\n password: 123455"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/d8/d8d26d5eb4d226db5e36c39a50742a29.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"看到項目啓動成功一共生成了60個表,數量還是比較多的,建議使用專門的數據庫存在這些工作流表。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/52/528d8fb873c39d2ce1f5a0fc972e65c6.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"舉個栗子:假如一個請假流程,需要經理審覈通過,請假才能生效,如果他駁回流程結束。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/99/99d546e3a31766144994872d7f57d21d.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"接下來我們用 "},{"type":"codeinline","content":[{"type":"text","text":"XML"}]},{"type":"text","text":" 翻譯下上邊的請假流程圖,整體非常簡單隻要夠細心就行了,一起看看每個標籤都是什麼含義。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"其實就是把流程圖的各種線條邏輯,用不同的"},{"type":"codeinline","content":[{"type":"text","text":"XML"}]},{"type":"text","text":"標籤描繪出來了。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":""}]},{"type":"text","text":" : 表示一個完整的工作流"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":""}]},{"type":"text","text":" : 對工作流的描述"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":""}]},{"type":"text","text":" : 工作流中起點位置(開始)"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":""}]},{"type":"text","text":" : 工作流中結束位置(結束)"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":""}]},{"type":"text","text":" : 代表一個任務審覈節點(組長、經理等角色)"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":""}]},{"type":"text","text":" : 邏輯判斷節點,相當於流程圖中的菱形框"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":""}]},{"type":"text","text":" :鏈接各個節點的線條,"},{"type":"codeinline","content":[{"type":"text","text":"sourceRef"}]},{"type":"text","text":" 屬性表示線的起始節點,"},{"type":"codeinline","content":[{"type":"text","text":"targetRef"}]},{"type":"text","text":" 屬性表示線指向的節點。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"上邊這一大坨"},{"type":"codeinline","content":[{"type":"text","text":"XML"}]},{"type":"text","text":"是不是看着超級麻煩,要是有自動生成工具就好了,我發現"},{"type":"codeinline","content":[{"type":"text","text":"IDEA"}]},{"type":"text","text":"自帶設計工具,但實在是太難用了。"}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/fd/fd0685f53081c6640959ccb8636b57fe.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"作爲一個面向百度編程的程序員,別的不行上網找答案的能力還是可以的,既然我都覺得寫"},{"type":"codeinline","content":[{"type":"text","text":"XML"}]},{"type":"text","text":"麻煩,那麼想來官方肯定也想到了,說不定有現成的工具,逛了一圈官網"},{"type":"codeinline","content":[{"type":"text","text":"https://www.flowable.org/downloads.html"}]},{"type":"text","text":" ,居然真的找到了。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"github"}]},{"type":"text","text":"下載地址:https://github.com/flowable/flowable-engine/releases/download/flowable-6.4.0/flowable-6.4.0.zip,下載速度那是相當感人,而且這個工具需要自己安裝......."}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/83/830eda2a751d851c428e18936b006764.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"又找了個在線編輯的工具: http://www.learun.cn:8090/home_online.htm,各種折騰~,設計完流程後,直接複製自動生成的代碼即可。"}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/c9/c916c8a17daeb81adc78dc659c04e7e3.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"流程審批"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"流程設計完後剩下的就是對工作流的審批和生成流程圖。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"首先啓動一個請假的流程,以員工ID "},{"type":"codeinline","content":[{"type":"text","text":"staffId"}]},{"type":"text","text":" 作爲唯一標識,"},{"type":"codeinline","content":[{"type":"text","text":"XML"}]},{"type":"text","text":"文件中會接收變量 "},{"type":"codeinline","content":[{"type":"text","text":"leaveTask"}]},{"type":"text","text":","},{"type":"codeinline","content":[{"type":"text","text":"Flowable"}]},{"type":"text","text":"內部會進行數據庫持久化,並返回一個流程Id "},{"type":"codeinline","content":[{"type":"text","text":"processId"}]},{"type":"text","text":" ,用它可以查詢工作流的整體情況,任務Id "},{"type":"codeinline","content":[{"type":"text","text":"task"}]},{"type":"text","text":"爲員工具體的請假任務。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"注意"},{"type":"text","text":":一個請假流程 "},{"type":"codeinline","content":[{"type":"text","text":"processId"}]},{"type":"text","text":"中可以包含多個請假任務 "},{"type":"codeinline","content":[{"type":"text","text":"taskId"}]},{"type":"text","text":"。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"javascript"},"content":[{"type":"text","text":"/**\n * @author xiaofu\n * @description 啓動流程\n * @date 2020/8/26 17:36\n */\n @RequestMapping(value = \"startLeaveProcess\")\n @ResponseBody\n public String startLeaveProcess(String staffId) {\n HashMap map = new HashMap<>();\n map.put(\"leaveTask\", staffId);\n ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(\"Leave\", map);\n StringBuilder sb = new StringBuilder();\n sb.append(\"創建請假流程 processId:\" + processInstance.getId());\n List tasks = taskService.createTaskQuery().taskAssignee(staffId).orderByTaskCreateTime().desc().list();\n for (Task task : tasks) {\n sb.append(\"任務taskId:\" + task.getId());\n }\n return sb.toString();\n }"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"用啓動流程時返回的 "},{"type":"codeinline","content":[{"type":"text","text":"processId"}]},{"type":"text","text":" 看一下一下當前的流程圖"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"java"},"content":[{"type":"text","text":"http://localhost:4000/leave/createProcessDiagramPic?processId=37513"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/b9/b904094c4b0095e2fd9aeafc704fa1a6.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"接下來將請假申請進行駁回 ,傳入相應的 "},{"type":"codeinline","content":[{"type":"text","text":"taskId"}]},{"type":"text","text":" 後執行駁回,再看看整個工作流的效果。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"javascript"},"content":[{"type":"text","text":"http://localhost:4000/leave/rejectTask?taskId=10086"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"javascript"},"content":[{"type":"text","text":" /**\n * @param taskId\n * @author xinzhifu\n * @description 駁回\n * @date 2020/8/27 14:30\n */\n @ResponseBody\n @RequestMapping(value = \"rejectTask\")\n public String rejectTask(String taskId) {\n HashMap map = new HashMap<>();\n map.put(\"checkResult\", \"駁回\");\n taskService.complete(taskId, map);\n return \"申請審覈駁回~\";\n }"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"看到整個請假流程在經理審覈這成功阻斷了。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"javascript"},"content":[{"type":"text","text":"http://localhost:4000/leave/createProcessDiagramPic?processId=37513"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/7c/7ce7908d4bd8292e7f6b62bf7f0f6580.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"總結"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"開發工作流一般多用在OA系統等傳統項目中,我也是第一次嘗試做此類功能,收穫還是蠻多的,技術棧又壓進了一個知識點。今天分享的是個超級簡單的"},{"type":"codeinline","content":[{"type":"text","text":"demo"}]},{"type":"text","text":",因爲也是剛開始接觸,等我用的賊溜的時候,再給小夥伴們做更成熟更深入的分享。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"demo"}]},{"type":"text","text":"的"},{"type":"codeinline","content":[{"type":"text","text":"github"}]},{"type":"text","text":" 地址:"},{"type":"codeinline","content":[{"type":"text","text":"https://github.com/chengxy-nds/Springboot-Notebook/tree/master/springboot-work-flowable"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"horizontalrule"},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"原創不易,燃燒秀髮輸出內容,如果有一丟丟收穫,點個贊鼓勵一下吧!"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"整理了幾百本各類技術電子書,送給小夥伴們。關注公號回覆【"},{"type":"text","marks":[{"type":"strong"}],"text":"666"},{"type":"text","text":"】自行領取。和一些小夥伴們建了一個技術交流羣,一起探討技術、分享技術資料,旨在共同學習進步,如果感興趣就加入我們吧!"}]}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章