{"id":10006163,"date":"2022-08-10T16:56:10","date_gmt":"2022-08-10T08:56:10","guid":{"rendered":"https:\/\/ityet.com\/?p=10006163"},"modified":"2022-08-10T16:56:10","modified_gmt":"2022-08-10T08:56:10","slug":"springbootvueflowable%ef%bc%8c%e6%a8%a1%e6%8b%9f%e4%b8%80%e4%b8%aa%e8%af%b7%e5%81%87%e5%ae%a1%e6%89%b9%e6%b5%81%e7%a8%8b%ef%bc%81","status":"publish","type":"post","link":"https:\/\/itmax.cn\/?p=10006163","title":{"rendered":"SpringBoot+Vue+Flowable\uff0c\u6a21\u62df\u4e00\u4e2a\u8bf7\u5047\u5ba1\u6279\u6d41\u7a0b\uff01"},"content":{"rendered":"<p>\u5c0f\u4f19\u4f34\u4eec\u77e5\u9053\u677e\u54e5\u6700\u8fd1\u5728\u5f55 TienChin \u9879\u76ee\u89c6\u9891\uff0c\u8fd9\u4e2a\u9879\u76ee\u4f1a\u7528\u5230\u5de5\u4f5c\u6d41\uff0c\u4e3a\u4e86\u5e2e\u52a9\u5c0f\u4f19\u4f34\u4eec\u66f4\u597d\u7684\u7406\u89e3\u8fd9\u4e2a\u9879\u76ee\uff0c\u677e\u54e5\u6700\u8fd1\u4f1a\u51fa\u51e0\u7bc7\u6587\u7ae0\u548c\u5927\u4f19\u804a\u4e00\u804a\u5de5\u4f5c\u6d41 flowable \u7684\u4f7f\u7528\uff0c\u7b97\u662f\u7ed9 TienChin \u9879\u76ee\u7684\u7b2c\u4e00\u4e2a\u94fa\u57ab\uff0c\u5f53\u7136\uff0c\u5728 TienChin \u9879\u76ee\u7684\u7cfb\u5217\u89c6\u9891\u4e2d\uff0c\u6211\u4e5f\u4f1a\u548c\u5927\u5bb6\u8be6\u7ec6\u804a\u4e00\u804a flowable \u6d41\u7a0b\u5f15\u64ce\u7684\u4f7f\u7528\u3002<\/p>\n<p>\u4eca\u5929\u6211\u5c31\u5148\u5199\u4e00\u4e2a\u7b80\u5355\u7684\u8bf7\u5047\u6d41\u7a0b\uff0c\u8ba9\u5c0f\u4f19\u4f34\u4eec\u5bf9 flowable \u5148\u6709\u4e00\u4e2a\u76f4\u89c2\u7684\u8ba4\u77e5\u3002<\/p>\n<h2>1. \u6548\u679c\u5c55\u793a<\/h2>\n<p>\u5728\u6b63\u5f0f\u5f00\u641e\u4e4b\u524d\uff0c\u6211\u5148\u6765\u7ed9\u5c0f\u4f19\u4f34\u4eec\u770b\u4e0b\u6211\u4eec\u4eca\u5929\u8981\u5b8c\u6210\u7684\u6548\u679c\u3002<\/p>\n<p>\u7b80\u5355\u8d77\u89c1\uff0c\u6211\u8fd9\u91cc\u5e76\u6ca1\u6709\u5f15\u5165\u7528\u6237\u3001\u89d2\u8272\u7b49\u6982\u5ff5\uff0c\u6d89\u53ca\u5230\u7528\u6237\u7684\u5730\u65b9\u90fd\u662f\u624b\u52a8\u8f93\u5165\uff0c\u5728\u540e\u7eed\u7684\u6587\u7ae0\u4e2d\u6211\u4f1a\u7ee7\u7eed\u7ed3\u5408 Spring Security \u6765\u548c\u5927\u5bb6\u5c55\u793a\u5f15\u5165\u7528\u6237\u4e4b\u540e\u7684\u60c5\u51b5\u3002<\/p>\n<p>\u6211\u4eec\u5148\u6765\u770b\u770b\u8bf7\u5047\u9875\u9762\uff1a<\/p>\n<p><img decoding=\"async\" referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/remote\/1460000042298178\" alt=\"\" title=\"\" loading=\"lazy\"><\/p>\n<p>\u5458\u5de5\u53ef\u4ee5\u5728\u8fd9\u4e2a\u9875\u9762\u8f93\u5165\u59d3\u540d\uff0c\u8bf7\u5047\u5929\u6570\u4ee5\u53ca\u8bf7\u5047\u7406\u7531\u7b49\uff0c\u7136\u540e\u70b9\u51fb\u6309\u94ae\u63d0\u4ea4\u4e00\u4e2a\u8bf7\u5047\u7533\u8bf7\u3002<\/p>\n<p>\u5f53\u5458\u5de5\u63d0\u4ea4\u8bf7\u5047\u7533\u8bf7\u4e4b\u540e\uff0c\u8fd9\u4e2a\u8bf7\u5047\u7533\u8bf7\u9ed8\u8ba4\u662f\u7531\u7ecf\u7406\u6765\u5904\u7406\u7684\uff0c\u6b64\u65f6\u7ecf\u7406\u767b\u5f55\u4e4b\u540e\uff0c\u5c31\u53ef\u4ee5\u770b\u5230\u5458\u5de5\u63d0\u4ea4\u4e0a\u6765\u7684\u8bf7\u6c42\uff1a<\/p>\n<p><img decoding=\"async\" referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/remote\/1460000042298179\" alt=\"\" title=\"\" loading=\"lazy\"><\/p>\n<p>\u7ecf\u7406\u6b64\u65f6\u53ef\u4ee5\u9009\u62e9\u6279\u51c6\u6216\u8005\u62d2\u7edd\u3002\u65e0\u8bba\u662f\u6279\u51c6\u8fd8\u662f\u62d2\u7edd\uff0c\u90fd\u53ef\u4ee5\u901a\u8fc7\u77ed\u4fe1\u6216\u8005\u90ae\u4ef6\u7b49\u544a\u77e5\u5458\u5de5\u3002<\/p>\n<p>\u5bf9\u4e8e\u5458\u5de5\u6765\u8bf4\uff0c\u4e5f\u53ef\u4ee5\u5728\u4e00\u4e2a\u9875\u9762\u67e5\u8be2\u81ea\u5df1\u8bf7\u5047\u6d41\u7a0b\u7684\u6700\u7ec8\u60c5\u51b5\uff1a<\/p>\n<p><img decoding=\"async\" referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/remote\/1460000042298180\" alt=\"\" title=\"\" loading=\"lazy\"><\/p>\n<p>\u53ef\u80fd\u6709\u5c0f\u4f19\u4f34\u5df2\u7ecf\u6ce8\u610f\u5230\u4e86\uff0c\u6211\u4eec\u8fd9\u91cc\u6240\u6709\u6d89\u53ca\u5230\u7528\u6237\u540d\u7684\u5730\u65b9\uff0c\u90fd\u9700\u8981\u624b\u52a8\u8f93\u5165\u3002\u8fd9\u662f\u56e0\u4e3a\u6211\u4e3a\u4e86\u8ba9\u8fd9\u4e2a\u6848\u4f8b\u8db3\u591f\u7b80\u5355\uff0c\u6682\u65f6\u6ca1\u6709\u5f15\u5165 Spring Security\uff0c\u53ea\u662f\u5355\u7eaf\u7684\u548c\u5927\u5bb6\u5206\u4eab Flowable \u7684\u7528\u6cd5\uff0c\u7b49\u5c0f\u4f19\u4f34\u4eec\u901a\u8fc7\u8fd9\u7bc7\u6587\u7ae0\u638c\u63e1\u4e86 Flowable \u7684\u57fa\u672c\u7528\u6cd5\u4e4b\u540e\uff0c\u4e0b\u7bc7\u6587\u7ae0\u6211\u4f1a\u548c\u5927\u5bb6\u5206\u4eab\u5982\u4f55\u7ed3\u5408\u5177\u4f53\u7684\u7528\u6237\u6765\u4f7f\u7528\u3002<\/p>\n<h2>2. \u5de5\u7a0b\u521b\u5efa<\/h2>\n<p>\u6211\u5c31\u76f4\u63a5\u6765\u548c\u5c0f\u4f19\u4f34\u4eec\u5c55\u793a Spring Boot \u4e2d flowable \u7684\u7528\u6cd5\u4e86\u3002<\/p>\n<p>\u9996\u5148\u6211\u4eec\u521b\u5efa\u4e00\u4e2a Spring Boot \u9879\u76ee\uff0c\u521b\u5efa\u7684\u65f6\u5019\u5f15\u5165 Web \u548c MySQL \u9a71\u52a8\u4f9d\u8d56\u5373\u53ef\uff0c\u9879\u76ee\u521b\u5efa\u6210\u529f\u4e4b\u540e\uff0c\u518d\u5f15\u5165 flowable \u4f9d\u8d56\uff0c\u6700\u7ec8\u7684\u4f9d\u8d56\u6587\u4ef6\u5982\u4e0b\uff1a<\/p>\n<pre><code class=\"xml\">&lt;dependency&gt;\n    &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;\n    &lt;artifactId&gt;spring-boot-starter-web&lt;\/artifactId&gt;\n&lt;\/dependency&gt;\n&lt;dependency&gt;\n    &lt;groupId&gt;org.flowable&lt;\/groupId&gt;\n    &lt;artifactId&gt;flowable-spring-boot-starter&lt;\/artifactId&gt;\n    &lt;version&gt;6.7.2&lt;\/version&gt;\n&lt;\/dependency&gt;\n&lt;dependency&gt;\n    &lt;groupId&gt;mysql&lt;\/groupId&gt;\n    &lt;artifactId&gt;mysql-connector-java&lt;\/artifactId&gt;\n    &lt;scope&gt;runtime&lt;\/scope&gt;\n&lt;\/dependency&gt;<\/code><\/pre>\n<p>\u9879\u76ee\u521b\u5efa\u6210\u529f\u4e4b\u540e\uff0c\u9996\u5148\u9700\u8981\u6211\u4eec\u5728 application.properties \u4e2d\u914d\u7f6e\u4e00\u4e0b\u6570\u636e\u5e93\u8fde\u63a5\u4fe1\u606f\uff0c\u5982\u4e0b\uff1a<\/p>\n<pre><code class=\"properties\">spring.datasource.username=root\nspring.datasource.password=123\nspring.datasource.url=jdbc:mysql:\/\/\/flowable02?serverTimezone=Asia\/Shanghai&amp;useSSL=false&amp;nullCatalogMeansCurrent=true<\/code><\/pre>\n<p>\u914d\u7f6e\u5b8c\u6210\u4e4b\u540e\uff0c\u5f53 Spring Boot \u9879\u76ee\u7b2c\u4e00\u6b21\u542f\u52a8\u7684\u65f6\u5019\uff0c\u4f1a\u81ea\u52a8\u521b\u5efa\u51fa\u6765\u5bf9\u5e94\u7684\u8868\u548c\u9700\u8981\u7684\u6570\u636e\u3002<\/p>\n<p>\u540c\u65f6\uff0cSpring Boot \u9879\u76ee\u4e5f\u4f1a\u81ea\u52a8\u521b\u5efa\u5e76\u66b4\u9732 Flowable \u4e2d\u7684 ProcessEngine\u3001CmmnEngine\u3001DmnEngine\u3001FormEngine\u3001ContentEngine \u53ca IdmEngine \u7b49 Bean\u3002<\/p>\n<p>\u5e76\u4e14\u6240\u6709\u7684 Flowable \u670d\u52a1\u90fd\u66b4\u9732\u4e3a Spring Bean\u3002\u4f8b\u5982 RuntimeService\u3001TaskService\u3001HistoryService \u7b49\u7b49\u670d\u52a1\uff0c\u6211\u4eec\u90fd\u53ef\u4ee5\u5728\u9700\u8981\u4f7f\u7528\u7684\u65f6\u5019\uff0c\u76f4\u63a5\u6ce8\u5165\u5c31\u53ef\u4ee5\u4f7f\u7528\u4e86\u3002<\/p>\n<p>\u540c\u65f6\uff1a<\/p>\n<ul>\n<li>resources\/processes \u76ee\u5f55\u4e0b\u7684\u4efb\u4f55 BPMN 2.0 \u6d41\u7a0b\u5b9a\u4e49\u90fd\u4f1a\u88ab\u81ea\u52a8\u90e8\u7f72\uff0c\u6240\u4ee5\u5728 Spring Boot \u9879\u76ee\u4e2d\uff0c\u6211\u4eec\u53ea\u9700\u8981\u5c06\u81ea\u5df1\u7684\u6d41\u7a0b\u6587\u4ef6\u653e\u5bf9\u4f4d\u7f6e\u5373\u53ef\uff0c\u5269\u4e0b\u7684\u4e8b\u60c5\u5c31\u4f1a\u81ea\u52a8\u5b8c\u6210\u3002<\/li>\n<li>cases \u76ee\u5f55\u4e0b\u7684\u4efb\u4f55 CMMN 1.1 \u4e8b\u4f8b\u90fd\u4f1a\u88ab\u81ea\u52a8\u90e8\u7f72\u3002<\/li>\n<li>forms \u76ee\u5f55\u4e0b\u7684\u4efb\u4f55 Form \u5b9a\u4e49\u90fd\u4f1a\u88ab\u81ea\u52a8\u90e8\u7f72\u3002<\/li>\n<\/ul>\n<h2>3. \u6d41\u7a0b\u56fe\u5206\u6790<\/h2>\n<p>\u4eca\u5929\u8fd9\u4e2a\u4f8b\u5b50\u6bd4\u8f83\u7b80\u5355\uff0c\u5c31\u662f\u4e00\u4e2a\u8bf7\u5047\u6d41\u7a0b\uff0c\u6211\u6682\u65f6\u5148\u4e0d\u8ddf\u5c0f\u4f19\u4f34\u4eec\u53bb\u626f\u753b\u6d41\u7a0b\u56fe\u7684\u4e8b\uff0c\u54b1\u4eec\u76f4\u63a5\u7528\u4e00\u4e2a\u5b98\u7f51\u73b0\u6210\u7684\u8bf7\u5047\u6d41\u7a0b\u56fe\uff1a<\/p>\n<p><img decoding=\"async\" referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/remote\/1460000042298181\" alt=\"\" title=\"\" loading=\"lazy\"><\/p>\n<p>\u6211\u4eec\u5148\u6765\u7b80\u5355\u5206\u6790\u4e00\u4e0b\u8fd9\u5f20\u56fe\uff1a<\/p>\n<ol>\n<li>\u6700\u5de6\u4fa7\u7684\u5706\u5708\u53eb\u505a\u542f\u52a8\u4e8b\u4ef6(start event)\uff0c\u8fd9\u8868\u793a\u4e00\u4e2a\u6d41\u7a0b\u5b9e\u4f8b\u7684\u8d77\u70b9\u3002<\/li>\n<li>\u4e00\u4e2a\u6d41\u7a0b\u542f\u52a8\u4e4b\u540e\uff0c\u9996\u5148\u5230\u8fbe\u7b2c\u4e00\u4e2a\u6709\u7528\u6237\u56fe\u6807\u7684\u77e9\u5f62\u4e2d\uff0c\u8fd9\u4e2a\u77e9\u5f62\u79f0\u4e3a\u4e00\u4e2a User Task\uff0c\u5728\u8fd9\u4e2a User Task \u4e2d\uff0c\u7ecf\u7406\u53ef\u4ee5\u9009\u62e9\u6279\u51c6\u4ea6\u6216\u8005\u62d2\u7edd\u3002<\/li>\n<li>UserTask \u7684\u4e0b\u4e00\u6b65\u662f\u4e00\u4e2a\u83f1\u5f62\uff0c\u8fd9\u4e2a\u79f0\u4f5c\u6392\u4ed6\u7f51\u5173\uff08Exclusive Gateway\uff09,\u8fd9\u4e2a\u4f1a\u5c06\u8bf7\u6c42\u8def\u7531\u5230\u4e0d\u540c\u7684\u5730\u65b9\u3002<\/li>\n<li>\u5148\u8bf4\u6279\u51c6\uff0c\u5982\u679c\u5728\u7b2c\u4e00\u4e2a\u77e9\u5f62\u4e2d\uff0c\u7ecf\u7406\u9009\u62e9\u4e86\u6279\u51c6\uff0c\u90a3\u4e48\u5c31\u4f1a\u8fdb\u5165\u5230\u4e00\u4e2a\u5e26\u6709\u9f7f\u8f6e\u56fe\u6807\u7684\u77e9\u5f62\u4e2d\uff0c\u5728\u8fd9\u4e2a\u77e9\u5f62\u4e2d\u6211\u4eec\u6211\u4eec\u53ef\u4ee5\u989d\u5916\u505a\u4e00\u4e9b\u4e8b\u60c5\uff0c\u7136\u540e\u53c8\u4f1a\u8c03\u7528\u5230\u4e00\u4e2a UserTask\uff0c\u6700\u7ec8\u5b8c\u6210\u6574\u4e2a\u6d41\u7a0b\u3002<\/li>\n<li>\u5982\u679c\u7ecf\u7406\u9009\u62e9\u4e86\u62d2\u7edd\uff0c\u5219\u4f1a\u8fdb\u5165\u5230\u4e0b\u9762\u7684\u53d1\u90ae\u4ef6\u7684\u77e9\u5f62\u4e2d\uff0c\u5728\u8fd9\u4e2a\u4e2d\u6211\u4eec\u53ef\u4ee5\u7ed9\u5458\u5de5\u53d1\u9001\u4e00\u4e2a\u901a\u77e5\uff0c\u544a\u77e5\u4ed6\u8bf7\u5047\u6ca1\u6709\u901a\u8fc7\u3002<\/li>\n<li>\u5f53\u7cfb\u7edf\u8d70\u5230\u6700\u53f3\u8fb9\u7684\u5706\u5708\u4e4b\u540e\uff0c\u5c31\u8868\u793a\u8fd9\u4e2a\u6d41\u7a0b\u6267\u884c\u7ed3\u675f\u4e86\u3002<\/li>\n<\/ol>\n<p>\u8fd9\u4e2a\u6d41\u7a0b\u56fe\u5bf9\u5e94\u7684 XML \u6587\u4ef6\u4f4d\u4e8e src\/main\/resources\/processes\/holiday-request.bpmn20.xml \u4f4d\u7f6e\uff0c\u5176\u5185\u5bb9\u5982\u4e0b\uff1a<\/p>\n<pre><code class=\"xml\">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;\n&lt;definitions xmlns=&quot;http:\/\/www.omg.org\/spec\/BPMN\/20100524\/MODEL&quot; xmlns:xsi=&quot;http:\/\/www.w3.org\/2001\/XMLSchema-instance&quot;\n             xmlns:flowable=&quot;http:\/\/flowable.org\/bpmn&quot;\n             typeLanguage=&quot;http:\/\/www.w3.org\/2001\/XMLSchema&quot; expressionLanguage=&quot;http:\/\/www.w3.org\/1999\/XPath&quot;\n             targetNamespace=&quot;http:\/\/www.flowable.org\/processdef&quot;&gt;\n    &lt;process id=&quot;holidayRequest&quot; name=&quot;Holiday Request&quot; isExecutable=&quot;true&quot;&gt;\n\n        &lt;startEvent id=&quot;startEvent&quot;\/&gt;\n        &lt;sequenceFlow sourceRef=&quot;startEvent&quot; targetRef=&quot;approveTask&quot;\/&gt;\n\n        &lt;userTask id=&quot;approveTask&quot; name=&quot;Approve or reject request&quot; flowable:candidateGroups=&quot;managers&quot;\/&gt;\n        &lt;sequenceFlow sourceRef=&quot;approveTask&quot; targetRef=&quot;decision&quot;\/&gt;\n\n        &lt;exclusiveGateway id=&quot;decision&quot;\/&gt;\n        &lt;sequenceFlow sourceRef=&quot;decision&quot; targetRef=&quot;externalSystemCall&quot;&gt;\n            &lt;conditionExpression xsi:type=&quot;tFormalExpression&quot;&gt;\n                &lt;![CDATA[\n          ${approved}\n        ]]&gt;\n            &lt;\/conditionExpression&gt;\n        &lt;\/sequenceFlow&gt;\n        &lt;sequenceFlow  sourceRef=&quot;decision&quot; targetRef=&quot;rejectLeave&quot;&gt;\n            &lt;conditionExpression xsi:type=&quot;tFormalExpression&quot;&gt;\n                &lt;![CDATA[\n          ${!approved}\n        ]]&gt;\n            &lt;\/conditionExpression&gt;\n        &lt;\/sequenceFlow&gt;\n\n        &lt;serviceTask id=&quot;externalSystemCall&quot; name=&quot;Enter holidays in external system&quot;\n                     flowable:class=&quot;org.javaboy.flowable02.flowable.Approve&quot;\/&gt;\n        &lt;sequenceFlow sourceRef=&quot;externalSystemCall&quot; targetRef=&quot;holidayApprovedTask&quot;\/&gt;\n\n        &lt;userTask id=&quot;holidayApprovedTask&quot; flowable:assignee=&quot;${employee}&quot; name=&quot;Holiday approved&quot;\/&gt;\n        &lt;sequenceFlow sourceRef=&quot;holidayApprovedTask&quot; targetRef=&quot;approveEnd&quot;\/&gt;\n\n        &lt;serviceTask id=&quot;rejectLeave&quot; name=&quot;Send out rejection email&quot;\n                     flowable:class=&quot;org.javaboy.flowable02.flowable.Reject&quot;\/&gt;\n        &lt;sequenceFlow sourceRef=&quot;rejectLeave&quot; targetRef=&quot;rejectEnd&quot;\/&gt;\n\n        &lt;endEvent id=&quot;approveEnd&quot;\/&gt;\n\n        &lt;endEvent id=&quot;rejectEnd&quot;\/&gt;\n\n    &lt;\/process&gt;\n&lt;\/definitions&gt;<\/code><\/pre>\n<p>\u5f88\u591a\u60f3\u5b66\u4e60\u6d41\u7a0b\u5f15\u64ce\u7684\u5c0f\u4f19\u4f34\u90fd\u4f1a\u88ab\u8fd9\u4e2a XML \u6587\u4ef6\u529d\u9000\uff0c\u4f46\u662f\uff01\uff01\uff01<\/p>\n<p>\u5982\u679c\u4f60\u613f\u610f\u9759\u4e0b\u5fc3\u6765\u8ba4\u771f\u9605\u8bfb\u8fd9\u4e2a XML \u6587\u4ef6\uff0c\u4f60\u4f1a\u53d1\u73b0\u6d41\u7a0b\u5f15\u64ce\u539f\u6765\u5982\u6b64\u7b80\u5355\uff01<\/p>\n<p>\u6211\u4eec\u6765\u6328\u4e2a\u770b\u4e0b\u8fd9\u91cc\u7684\u6bcf\u4e00\u4e2a\u8282\u70b9\uff1a<\/p>\n<ol>\n<li>process\uff1a\u8fd9\u8868\u793a\u4e00\u4e2a\u6d41\u7a0b\uff0c\u4f8b\u5982\u672c\u6587\u548c\u5927\u5bb6\u5206\u4eab\u7684\u8bf7\u5047\u5c31\u662f\u4e00\u4e2a\u6d41\u7a0b\u3002<\/li>\n<li>startEvent\uff1a\u8fd9\u8868\u793a\u6d41\u7a0b\u7684\u5f00\u59cb\uff0c\u8fd9\u5c31\u662f\u4e00\u4e2a\u5f00\u59cb\u4e8b\u4ef6\u3002<\/li>\n<li>userTask\uff1a\u8fd9\u5c31\u662f\u4e00\u4e2a\u5177\u4f53\u7684\u6d41\u7a0b\u8282\u70b9\u4e86\uff0cflowable:candidateGroups \u5c5e\u6027\u8868\u793a\u8fd9\u4e2a\u8282\u70b9\u8be5\u7531\u54ea\u4e2a\u7528\u6237\u7ec4\u4e2d\u7684\u7528\u6237\u6765\u5904\u7406\u3002<\/li>\n<li>sequenceFlow\uff1a\u8fd9\u5c31\u662f\u8fde\u63a5\u5404\u4e2a\u6d41\u7a0b\u8282\u70b9\u4e4b\u95f4\u7684\u7ebf\u6761\uff0c\u8fd9\u4e2a\u91cc\u8fb9\u4e00\u822c\u6709\u4e24\u4e2a\u5c5e\u6027\uff0csourceRef \u548c targetRef\uff0c\u524d\u8005\u8868\u793a\u7ebf\u6761\u7684\u8d77\u70b9\uff0c\u540e\u8005\u8868\u793a\u7ebf\u6761\u7684\u7ec8\u70b9\u3002<\/li>\n<li>exclusiveGateway\uff1a\u8868\u793a\u4e00\u4e2a\u6392\u4ed6\u6027\u7f51\u5173\uff0c\u4e5f\u5c31\u662f\u90a3\u4e2a\u83f1\u5f62\u9009\u62e9\u6846\u3002<\/li>\n<li>\u4ece\u6392\u4ed6\u6027\u7f51\u5173\u51fa\u6765\u7684\u7ebf\u6761\u6709\u4e24\u4e2a\uff0c\u5927\u5bb6\u6ce8\u610f\u770b\u4e0a\u9762\u7684\u4ee3\u7801\uff0c\u8fd9\u4e24\u4e2a\u7ebf\u6761\u4e2d\u90fd\u6d89\u53ca\u5230\u4e00\u4e2a\u53d8\u91cf approved\uff0c\u5982\u679c\u8fd9\u4e2a\u53d8\u91cf\u4e3a true\uff0c\u5219 targeRef \u5c31\u662f externalSystemCall\uff1b\u5982\u679c\u8fd9\u4e2a\u53d8\u91cf\u4e3a false\uff0c\u5219 targetRef \u5c31\u662f rejectLeave\u3002<\/li>\n<li>serviceTask\uff1a\u8fd9\u5c31\u662f\u6211\u4eec\u5b9a\u4e49\u7684\u4e00\u4e2a\u5177\u4f53\u7684\u5916\u90e8\u670d\u52a1\uff0c\u5982\u679c\u5728\u6574\u4e2a\u6d41\u7a0b\u6267\u884c\u7684\u8fc7\u7a0b\u4e2d\uff0c\u4f60\u6709\u4e00\u4e9b\u9700\u8981\u81ea\u5df1\u5b8c\u6210\u7684\u4e8b\u60c5\uff0c\u90a3\u4e48\u53ef\u4ee5\u901a\u8fc7 serviceTask \u6765\u5b9e\u73b0\uff0c\u8fd9\u4e2a\u8282\u70b9\u4f1a\u6709\u4e00\u4e2a flowable:class \u5c5e\u6027\uff0c\u8fd9\u4e2a\u5c5e\u6027\u7684\u503c\u5c31\u662f\u4e00\u4e2a\u81ea\u5b9a\u4e49\u7c7b\u3002<\/li>\n<li>\u53e6\u5916\uff0c\u4e0a\u6587\u4e2d\u90e8\u5206\u8282\u70b9\u4e2d\u8fd8\u6d89\u53ca\u5230\u53d8\u91cf ${}\uff0c\u8fd9\u4e2a\u53d8\u91cf\u662f\u5728\u6d41\u7a0b\u6267\u884c\u7684\u8fc7\u7a0b\u4e2d\u4f20\u5165\u8fdb\u6765\u7684\u3002<\/li>\n<\/ol>\n<p>\u603b\u800c\u8a00\u4e4b\uff0c\u53ea\u8981\u5c0f\u4f19\u4f34\u4eec\u9759\u4e0b\u5fc3\u6765\u8ba4\u771f\u9605\u8bfb\u4e00\u4e0b\u4e0a\u9762\u7684 XML\uff0c\u4f60\u4f1a\u53d1\u73b0 So Easy\uff01<\/p>\n<h2>4. \u8bf7\u5047\u7533\u8bf7<\/h2>\n<p>\u597d\u4e86\uff0c\u63a5\u4e0b\u6765\u6211\u4eec\u5c31\u6765\u770b\u4e00\u4e2a\u5177\u4f53\u7684\u8bf7\u5047\u7533\u8bf7\u3002\u7531\u4e8e\u8bf7\u5047\u6d41\u7a0b\u53ea\u8981\u653e\u5bf9\u4f4d\u7f6e\uff0c\u5c31\u4f1a\u81ea\u52a8\u52a0\u8f7d\uff0c\u6240\u4ee5\u6211\u4eec\u5e76\u4e0d\u9700\u8981\u624b\u52a8\u52a0\u8f7d\u8bf7\u5047\u6d41\u7a0b\uff0c\u76f4\u63a5\u5f00\u59cb\u4e00\u4e2a\u8bf7\u5047\u7533\u8bf7\u6d41\u7a0b\u5373\u53ef\u3002<\/p>\n<h3>4.1 \u670d\u52a1\u7aef\u63a5\u53e3<\/h3>\n<p>\u9996\u5148\u6211\u4eec\u9700\u8981\u4e00\u4e2a\u5b9e\u4f53\u7c7b\u6765\u63a5\u53d7\u524d\u7aef\u4f20\u6765\u7684\u8bf7\u5047\u53c2\u6570\uff1a\u7528\u6237\u540d\u3001\u8bf7\u5047\u5929\u6570\u4ee5\u53ca\u8bf7\u5047\u7406\u7531\uff1a<\/p>\n<pre><code class=\"java\">public class AskForLeaveVO {\n    private String name;\n    private Integer days;\n    private String reason;\n    \/\/ \u7701\u7565 getter\/setter\n}<\/code><\/pre>\n<p>\u518d\u62ff\u51fa\u7956\u4f20\u7684 RespBean\uff0c\u4ee5\u4fbf\u54cd\u5e94\u6570\u636e\u65b9\u4fbf\u4e00\u4e9b\uff1a<\/p>\n<pre><code class=\"java\">public class RespBean {\n    private Integer status;\n    private String msg;\n    private Object data;\n\n    public static RespBean ok(String msg, Object data) {\n        return new RespBean(200, msg, data);\n    }\n\n\n    public static RespBean ok(String msg) {\n        return new RespBean(200, msg, null);\n    }\n\n\n    public static RespBean error(String msg, Object data) {\n        return new RespBean(500, msg, data);\n    }\n\n\n    public static RespBean error(String msg) {\n        return new RespBean(500, msg, null);\n    }\n\n    private RespBean() {\n    }\n\n    private RespBean(Integer status, String msg, Object data) {\n        this.status = status;\n        this.msg = msg;\n        this.data = data;\n    }\n    \/\/ \u7701\u7565 getter\/setter\n}<\/code><\/pre>\n<p>\u63a5\u4e0b\u6765\u6211\u4eec\u63d0\u4f9b\u4e00\u4e2a\u5904\u7406\u8bf7\u5047\u7533\u8bf7\u7684\u63a5\u53e3\uff1a<\/p>\n<pre><code class=\"java\">@RestController\npublic class AskForLeaveController {\n\n    @Autowired\n    AskForLeaveService askForLeaveService;\n\n    @PostMapping(&quot;\/ask_for_leave&quot;)\n    public RespBean askForLeave(@RequestBody AskForLeaveVO askForLeaveVO) {\n        return askForLeaveService.askForLeave(askForLeaveVO);\n    }\n}<\/code><\/pre>\n<p>\u6838\u5fc3\u903b\u8f91\u5728 AskForLeaveService \u4e2d\uff0c\u6765\u7ee7\u7eed\u770b\uff1a<\/p>\n<pre><code class=\"java\">@Service\npublic class AskForLeaveService {\n\n    @Autowired\n    RuntimeService runtimeService;\n\n    @Transactional\n    public RespBean askForLeave(AskForLeaveVO askForLeaveVO) {\n        Map&lt;String, Object&gt; variables = new HashMap&lt;&gt;();\n        variables.put(&quot;name&quot;, askForLeaveVO.getName());\n        variables.put(&quot;days&quot;, askForLeaveVO.getDays());\n        variables.put(&quot;reason&quot;, askForLeaveVO.getReason());\n        try {\n            runtimeService.startProcessInstanceByKey(&quot;holidayRequest&quot;, askForLeaveVO.getName(), variables);\n            return RespBean.ok(&quot;\u5df2\u63d0\u4ea4\u8bf7\u5047\u7533\u8bf7&quot;);\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n        return RespBean.error(&quot;\u63d0\u4ea4\u7533\u8bf7\u5931\u8d25&quot;);\n    }\n}<\/code><\/pre>\n<p>\u5c0f\u4f19\u4f34\u4eec\u770b\u4e00\u4e0b\uff0c\u5728\u63d0\u4ea4\u8bf7\u5047\u7533\u8bf7\u7684\u65f6\u5019\uff0c\u5206\u522b\u4f20\u5165\u4e86 name\u3001days \u4ee5\u53ca reason \u4e09\u4e2a\u53c2\u6570\uff0c\u6211\u4eec\u5c06\u8fd9\u4e09\u4e2a\u53c2\u6570\u653e\u5165\u5230\u4e00\u4e2a Map \u4e2d\uff0c\u7136\u540e\u901a\u8fc7 RuntimeService#startProcessInstanceByKey \u65b9\u6cd5\u6765\u5f00\u542f\u4e00\u4e2a\u6d41\u7a0b\uff0c\u5f00\u542f\u6d41\u7a0b\u7684\u65f6\u5019\u4e00\u5171\u4f20\u5165\u4e86\u4e09\u4e2a\u53c2\u6570\uff1a<\/p>\n<ol>\n<li>\u7b2c\u4e00\u4e2a\u53c2\u6570\u8868\u793a\u6d41\u7a0b\u5f15\u64ce\u7684\u540d\u5b57\uff0c\u8fd9\u5c31\u662f\u6211\u4eec\u521a\u624d\u5728\u6d41\u7a0b\u7684 XML \u6587\u4ef6\u4e2d\u5b9a\u4e49\u7684\u540d\u5b57\u3002<\/li>\n<li>\u7b2c\u4e8c\u4e2a\u53c2\u6570\u8868\u793a\u5f53\u524d\u8fd9\u4e2a\u6d41\u7a0b\u7684 key\uff0c\u6211\u7528\u4e86\u7533\u8bf7\u4eba\u7684\u540d\u5b57\uff0c\u5c06\u6765\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u7533\u8bf7\u4eba\u7684\u540d\u5b57\u67e5\u8be2\u8fd9\u4e2a\u4eba\u66fe\u7ecf\u63d0\u4ea4\u7684\u6240\u6709\u7533\u8bf7\u6d41\u7a0b\u3002<\/li>\n<li>\u7b2c\u4e09\u4e2a\u53c2\u6570\u5c31\u662f\u6211\u4eec\u7684\u53d8\u91cf\u4e86\u3002<\/li>\n<\/ol>\n<p>\u597d\u4e86\uff0c\u8fd9\u670d\u52a1\u7aef\u5c31\u5199\u597d\u4e86\u3002<\/p>\n<h3>4.2 \u524d\u7aef\u9875\u9762<\/h3>\n<p>\u63a5\u4e0b\u6765\u6211\u4eec\u6765\u5f00\u53d1\u524d\u7aef\u9875\u9762\u3002<\/p>\n<p>\u524d\u7aef\u6211\u4f7f\u7528 Vue+ElementUI+Axios\uff0c\u54b1\u4eec\u8fd9\u4e2a\u6848\u4f8b\u6bd4\u8f83\u7b80\u5355\uff0c\u5c31\u6ca1\u6709\u5fc5\u8981\u642d\u5efa\u5355\u9875\u9762\u4e86\uff0c\u76f4\u63a5\u7528\u666e\u901a\u7684 HTML \u5c31\u884c\u4e86\u3002\u53e6\u5916\uff0cVue \u6211\u662f\u7528\u4e86 Vue3\uff1a<\/p>\n<pre><code class=\"html\">&lt;!DOCTYPE html&gt;\n&lt;html lang=&quot;en&quot;&gt;\n&lt;head&gt;\n    &lt;meta charset=&quot;UTF-8&quot;&gt;\n    &lt;title&gt;Title&lt;\/title&gt;\n    &lt;script src=&quot;https:\/\/unpkg.com\/axios\/dist\/axios.min.js&quot;&gt;&lt;\/script&gt;\n    &lt;!-- Import style --&gt;\n    &lt;link rel=&quot;stylesheet&quot; href=&quot;\/\/unpkg.com\/element-plus\/dist\/index.css&quot;\/&gt;\n    &lt;script src=&quot;https:\/\/unpkg.com\/vue@3&quot;&gt;&lt;\/script&gt;\n    &lt;!-- Import component library --&gt;\n    &lt;script src=&quot;\/\/unpkg.com\/element-plus&quot;&gt;&lt;\/script&gt;\n&lt;\/head&gt;\n&lt;body&gt;\n&lt;div id=&quot;app&quot;&gt;\n    &lt;h1&gt;\u5f00\u59cb\u4e00\u4e2a\u8bf7\u5047\u6d41\u7a0b&lt;\/h1&gt;\n    &lt;table&gt;\n        &lt;tr&gt;\n            &lt;td&gt;\u8bf7\u8f93\u5165\u59d3\u540d\uff1a&lt;\/td&gt;\n            &lt;td&gt;\n                &lt;el-input type=&quot;text&quot; v-model=&quot;afl.name&quot;\/&gt;\n            &lt;\/td&gt;\n        &lt;\/tr&gt;\n        &lt;tr&gt;\n            &lt;td&gt;\u8bf7\u8f93\u5165\u8bf7\u5047\u5929\u6570\uff1a&lt;\/td&gt;\n            &lt;td&gt;\n                &lt;el-input type=&quot;text&quot; v-model=&quot;afl.days&quot;\/&gt;\n            &lt;\/td&gt;\n        &lt;\/tr&gt;\n        &lt;tr&gt;\n            &lt;td&gt;\u8bf7\u8f93\u5165\u8bf7\u5047\u7406\u7531\uff1a&lt;\/td&gt;\n            &lt;td&gt;\n                &lt;el-input type=&quot;text&quot; v-model=&quot;afl.reason&quot;\/&gt;\n            &lt;\/td&gt;\n        &lt;\/tr&gt;\n    &lt;\/table&gt;\n    &lt;el-button type=&quot;primary&quot; @click=&quot;submit&quot;&gt;\u63d0\u4ea4\u8bf7\u5047\u7533\u8bf7&lt;\/el-button&gt;\n&lt;\/div&gt;\n&lt;script&gt;\n    Vue.createApp(\n        {\n            data() {\n                return {\n                    afl: {\n                        name: 'javaboy',\n                        days: 3,\n                        reason: '\u4f11\u606f\u4e00\u4e0b'\n                    }\n                }\n            },\n            methods: {\n                submit() {\n                    let _this = this;\n                    axios.post('\/ask_for_leave', this.afl)\n                        .then(function (response) {\n                            if (response.data.status == 200) {\n                                \/\/\u63d0\u4ea4\u6210\u529f\n                                _this.$message.success(response.data.msg);\n                            } else {\n                                \/\/\u63d0\u4ea4\u5931\u8d25\n                                _this.$message.error(response.data.msg);\n                            }\n                        })\n                        .catch(function (error) {\n                            console.log(error);\n                        });\n                }\n            }\n        }\n    ).use(ElementPlus).mount('#app')\n&lt;\/script&gt;\n&lt;\/body&gt;\n&lt;\/html&gt;<\/code><\/pre>\n<p>\u8fd9\u4e2a\u9875\u9762\u6709\u51e0\u4e2a\u9700\u8981\u6ce8\u610f\u7684\u70b9\uff1a<\/p>\n<ol>\n<li>\u901a\u8fc7 Vue.createApp \u6765\u521b\u5efa\u4e00\u4e2a Vue \u5b9e\u4f8b\uff0c\u8fd9\u8ddf\u4ee5\u524d Vue2 \u4e2d\u76f4\u63a5 new \u4e00\u4e2a Vue \u5b9e\u4f8b\u4e0d\u4e00\u6837\u3002<\/li>\n<li>\u5728\u6700\u4e0b\u9762\uff0c\u901a\u8fc7 use \u6765\u914d\u7f6e ElementPlus \u63d2\u4ef6\uff0c\u8fd9\u4e2a\u8ddf Vue2 \u4e5f\u4e0d\u4e00\u6837\u3002\u5728 Vue2 \u4e2d\uff0c\u5982\u679c\u6211\u4eec\u5355\u7eaf\u7684\u5728 HTML \u9875\u9762\u4e2d\u5f15\u7528 ElementUI \u5e76\u4e0d\u9700\u8981\u8fd9\u4e2a\u6b65\u9aa4\u3002<\/li>\n<li>\u5269\u4e0b\u7684\u4e1c\u897f\u5c31\u6bd4\u8f83\u7b80\u5355\u4e86\uff0c\u4e0a\u9762\u5148\u5f15\u5165 Vue3\u3001Axios \u4ee5\u53ca ElementPlus\uff0c\u7136\u540e\u4e09\u4e2a\u8f93\u5165\u6846\uff0c\u70b9\u51fb\u6309\u94ae\u63d0\u4ea4\u8bf7\u6c42\uff0c\u53c2\u6570\u5c31\u662f\u4e09\u4e2a\u8f93\u5165\u6846\u4e2d\u7684\u6570\u636e\uff0c\u63d0\u4ea4\u6210\u529f\u6216\u8005\u5931\u8d25\uff0c\u5206\u522b\u5f39\u4e2a\u6846\u51fa\u6765\u63d0\u793a\u4e00\u4e0b\u5c31\u884c\u4e86\u3002<\/li>\n<\/ol>\n<p>\u597d\u5566\uff0c\u8fd9\u5c31\u5199\u597d\u4e86\u3002<\/p>\n<p>\u7136\u800c\uff0c\u63d0\u4ea4\u5b8c\u6210\u540e\uff0c\u6ca1\u6709\u4e00\u4e2a\u76f4\u89c2\u7684\u5c55\u793a\uff0c\u867d\u7136\u524d\u7aef\u63d0\u793a\u8bf4\u63d0\u4ea4\u6210\u529f\u4e86\uff0c\u4f46\u662f\u7a76\u7adf\u6210\u529f\u6ca1\uff0c\u8fd8\u5f97\u773c\u89c1\u4e3a\u5b9e\u3002<\/p>\n<h2>5. \u4efb\u52a1\u5c55\u793a<\/h2>\n<p>\u597d\u4e86\uff0c\u63a5\u4e0b\u6765\u6211\u4eec\u8981\u505a\u7684\u4e8b\u60c5\u5c31\u662f\u628a\u7528\u6237\u63d0\u4ea4\u7684\u6d41\u7a0b\u5c55\u793a\u51fa\u6765\u3002<\/p>\n<p>\u6309\u7406\u8bf4\uff0c\u6bd4\u5982\u7ecf\u7406\u767b\u5f55\u6210\u529f\u4e4b\u540e\uff0c\u7cfb\u7edf\u9875\u9762\u5c31\u81ea\u52a8\u5c55\u793a\u51fa\u6765\u7ecf\u7406\u9700\u8981\u5ba1\u6279\u7684\u6d41\u7a0b\uff0c\u4f46\u662f\u6211\u4eec\u5f53\u524d\u8fd9\u4e2a\u4f8b\u5b50\u4e3a\u4e86\u7b80\u5355\uff0c\u5c31\u6ca1\u6709\u767b\u5f55\u8fd9\u4e2a\u64cd\u4f5c\u4e86\uff0c\u9700\u8981\u9700\u8981\u7528\u6237\u5c06\u6765\u5728\u7f51\u9875\u4e0a\u9009\u4e00\u4e0b\u81ea\u5df1\u7684\u8eab\u4efd\uff0c\u63a5\u4e0b\u6765\u5c31\u4f1a\u5c55\u793a\u51fa\u8fd9\u4e2a\u8eab\u4efd\u6240\u5bf9\u5e94\u7684\u9700\u8981\u64cd\u4f5c\u7684\u6d41\u7a0b\u3002<\/p>\n<p>\u6211\u4eec\u6765\u770b\u4efb\u52a1\u63a5\u53e3\uff1a<\/p>\n<pre><code class=\"java\">@GetMapping(&quot;\/list&quot;)\npublic RespBean leaveList(String identity) {\n    return askForLeaveService.leaveList(identity);\n}<\/code><\/pre>\n<p>\u8fd9\u4e2a\u8bf7\u6c42\u53c2\u6570 identity \u5c31\u8868\u793a\u5f53\u524d\u7528\u6237\u7684\u8eab\u4efd\uff08\u672c\u6765\u5e94\u8be5\u662f\u767b\u5f55\u540e\u81ea\u52a8\u83b7\u53d6\uff0c\u4f46\u662f\u56e0\u4e3a\u6211\u4eec\u76ee\u524d\u6ca1\u6709\u767b\u5f55\uff0c\u6240\u4ee5\u8fd9\u4e2a\u53c2\u6570\u662f\u7531\u524d\u7aef\u4f20\u9012\u8fc7\u6765\uff09\u3002\u6765\u7ee7\u7eed\u770b askForLeaveService \u4e2d\u7684\u65b9\u6cd5\uff1a<\/p>\n<pre><code class=\"java\">@Service\npublic class AskForLeaveService {\n\n    @Autowired\n    TaskService taskService;\n\n    public RespBean leaveList(String identity) {\n        List&lt;Task&gt; tasks = taskService.createTaskQuery().taskCandidateGroup(identity).list();\n        List&lt;Map&lt;String, Object&gt;&gt; list = new ArrayList&lt;&gt;();\n        for (int i = 0; i &lt; tasks.size(); i++) {\n            Task task = tasks.get(i);\n            Map&lt;String, Object&gt; variables = taskService.getVariables(task.getId());\n            variables.put(&quot;id&quot;, task.getId());\n            list.add(variables);\n        }\n        return RespBean.ok(&quot;\u52a0\u8f7d\u6210\u529f&quot;, list);\n    }\n}<\/code><\/pre>\n<p>Task \u5c31\u662f\u6d41\u7a0b\u4e2d\u8981\u505a\u7684\u6bcf\u4e00\u4ef6\u4e8b\u60c5\uff0c\u6211\u4eec\u9996\u5148\u901a\u8fc7 TaskService\uff0c\u67e5\u8be2\u51fa\u6765\u8fd9\u4e2a\u7528\u6237\u9700\u8981\u5904\u7406\u7684\u4efb\u52a1\uff0c\u4f8b\u5982\u524d\u7aef\u524d\u4f20\u6765\u7684\u662f managers\uff0c\u90a3\u4e48\u8fd9\u91cc\u5c31\u662f\u67e5\u8be2\u6240\u6709\u9700\u8981\u7531 managers \u7528\u6237\u7ec4\u5904\u7406\u7684\u4efb\u52a1\u3002<\/p>\n<p>\u8fd9\u6bb5\u4ee3\u7801\u8981\u7ed3\u5408\u6d41\u7a0b\u56fe\u4e00\u8d77\u6765\u7406\u89e3\uff0c\u5c0f\u4f19\u4f34\u4eec\u56de\u987e\u4e0b\u6211\u4eec\u6d41\u7a0b\u56fe\u4e2d\u6709\u5982\u4e0b\u4e00\u53e5\uff1a<\/p>\n<pre><code class=\"xml\">&lt;userTask id=&quot;approveTask&quot; name=&quot;Approve or reject request&quot; flowable:candidateGroups=&quot;managers&quot;\/&gt;<\/code><\/pre>\n<p>\u8fd9\u610f\u601d\u5c31\u662f\u8bf4\u8fd9\u4e2a userTask \u662f\u7531 managers \u8fd9\u4e2a\u7ec4\u4e2d\u7684\u7528\u6237\u6765\u5904\u7406\uff0c\u6240\u4ee5\u4e0a\u9762 Java \u4ee3\u7801\u4e2d\u7684\u67e5\u8be2\u5c31\u662f\u67e5\u8be2 managers \u8fd9\u4e2a\u7ec4\u4e2d\u7684\u7528\u6237\u9700\u8981\u5ba1\u6279\u7684\u4efb\u52a1\u3002<\/p>\n<p>\u6211\u4eec\u5c06\u6240\u6709\u9700\u8981\u5ba1\u6279\u7684\u4efb\u52a1\u67e5\u8be2\u51fa\u6765\u540e\uff0c\u901a\u8fc7 taskId \u53ef\u4ee5\u8fdb\u4e00\u6b65\u67e5\u8be2\u5230\u8fd9\u4e2a\u4efb\u52a1\u4e2d\u5f53\u65f6\u4f20\u5165\u7684\u5404\u79cd\u53d8\u91cf\uff0c\u6211\u4eec\u5c06\u8fd9\u4e9b\u6570\u636e\u5c01\u88c5\u6210\u4e00\u4e2a\u5bf9\u8c61\uff0c\u5e76\u6700\u7ec8\u8fd4\u56de\u5230\u524d\u7aef\u3002<\/p>\n<p>\u6700\u540e\uff0c\u6211\u4eec\u518d\u6765\u770b\u4e0b\u524d\u7aef\u9875\u9762\uff1a<\/p>\n<pre><code class=\"html\">&lt;!DOCTYPE html&gt;\n&lt;html lang=&quot;en&quot;&gt;\n&lt;head&gt;\n    &lt;meta charset=&quot;UTF-8&quot;&gt;\n    &lt;title&gt;Title&lt;\/title&gt;\n    &lt;script src=&quot;https:\/\/unpkg.com\/axios\/dist\/axios.min.js&quot;&gt;&lt;\/script&gt;\n    &lt;!-- Import style --&gt;\n    &lt;link rel=&quot;stylesheet&quot; href=&quot;\/\/unpkg.com\/element-plus\/dist\/index.css&quot;\/&gt;\n    &lt;script src=&quot;https:\/\/unpkg.com\/vue@3&quot;&gt;&lt;\/script&gt;\n    &lt;!-- Import component library --&gt;\n    &lt;script src=&quot;\/\/unpkg.com\/element-plus&quot;&gt;&lt;\/script&gt;\n&lt;\/head&gt;\n&lt;body&gt;\n&lt;div id=&quot;app&quot;&gt;\n    &lt;div&gt;\n        &lt;div&gt;\u8bf7\u9009\u62e9\u4f60\u7684\u8eab\u4efd\uff1a&lt;\/div&gt;\n        &lt;div&gt;\n            &lt;el-select name=&quot;&quot; id=&quot;&quot; v-model=&quot;identity&quot; @change=&quot;initTasks&quot;&gt;\n                &lt;el-option :value=&quot;iden&quot; v-for=&quot;(iden,index) in identities&quot; :key=&quot;index&quot; :label=&quot;iden&quot;&gt;&lt;\/el-option&gt;\n            &lt;\/el-select&gt;\n            &lt;el-button type=&quot;primary&quot; @click=&quot;initTasks&quot;&gt;\u5237\u65b0\u4e00\u4e0b&lt;\/el-button&gt;\n        &lt;\/div&gt;\n\n    &lt;\/div&gt;\n    &lt;el-table border strip :data=&quot;tasks&quot;&gt;\n        &lt;el-table-column prop=&quot;name&quot; label=&quot;\u59d3\u540d&quot;&gt;&lt;\/el-table-column&gt;\n        &lt;el-table-column prop=&quot;days&quot; label=&quot;\u8bf7\u5047\u5929\u6570&quot;&gt;&lt;\/el-table-column&gt;\n        &lt;el-table-column prop=&quot;reason&quot; label=&quot;\u8bf7\u5047\u539f\u56e0&quot;&gt;&lt;\/el-table-column&gt;\n        &lt;el-table-column lable=&quot;\u64cd\u4f5c&quot;&gt;\n            &lt;template #default=&quot;scope&quot;&gt;\n                &lt;el-button type=&quot;primary&quot; @click=&quot;approveOrReject(scope.row.id,true,scope.row.name)&quot;&gt;\u6279\u51c6&lt;\/el-button&gt;\n                &lt;el-button type=&quot;danger&quot; @click=&quot;approveOrReject(scope.row.id,false,scope.row.name)&quot;&gt;\u62d2\u7edd&lt;\/el-button&gt;\n            &lt;\/template&gt;\n        &lt;\/el-table-column&gt;\n    &lt;\/el-table&gt;\n&lt;\/div&gt;\n&lt;script&gt;\n    Vue.createApp(\n        {\n            data() {\n                return {\n                    tasks: [],\n                    identities: [\n                        'managers'\n                    ],\n                    identity: ''\n                }\n            },\n            methods: {\n                initTasks() {\n                    let _this = this;\n                    axios.get('\/list?identity=' + this.identity)\n                        .then(function (response) {\n                            _this.tasks = response.data.data;\n                        })\n                        .catch(function (error) {\n                            console.log(error);\n                        });\n                }\n            }\n        }\n    ).use(ElementPlus).mount('#app')\n&lt;\/script&gt;\n&lt;\/body&gt;\n&lt;\/html&gt;<\/code><\/pre>\n<p>\u5927\u5bb6\u770b\u5230\uff0c\u9996\u5148\u6709\u4e00\u4e2a\u4e0b\u62c9\u6846\uff0c\u6211\u4eec\u5728\u8fd9\u4e2a\u4e0b\u62c9\u6846\u4e2d\u6765\u9009\u62e9\u7528\u6237\u7684\u8eab\u4efd\u3002\u9009\u62e9\u5b8c\u6210\u540e\uff0c\u89e6\u53d1 initTasks \u65b9\u6cd5\uff0c\u7136\u540e\u5728\u8fd9\u4e2a\u65b9\u6cd5\u4e2d\uff0c\u53d1\u8d77\u7f51\u7edc\u8bf7\u6c42\uff0c\u6700\u7ec8\u5c06\u8bf7\u6c42\u7ed3\u679c\u6e32\u67d3\u51fa\u6765\u3002<\/p>\n<p>\u6700\u7ec8\u6548\u679c\u5982\u4e0b\uff1a<\/p>\n<p><img decoding=\"async\" referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/remote\/1460000042298179\" alt=\"\" title=\"\" loading=\"lazy\"><\/p>\n<p>\u5f53\u7136\u7528\u6237\u4e5f\u53ef\u4ee5\u70b9\u51fb\u5237\u65b0\u6309\u94ae\uff0c\u5237\u65b0\u5217\u8868\u3002<\/p>\n<p>\u8fd9\u6837\uff0c\u5f53\u7b2c\u4e94\u5c0f\u8282\u4e2d\uff0c\u5458\u5de5\u63d0\u4ea4\u4e86\u4e00\u4e2a\u8bf7\u5047\u5ba1\u6279\u4e4b\u540e\uff0c\u6211\u4eec\u5728\u8fd9\u4e2a\u5217\u8868\u4e2d\u5c31\u53ef\u4ee5\u67e5\u770b\u5230\u5458\u5de5\u63d0\u4ea4\u7684\u8bf7\u5047\u5ba1\u6279\u4e86\uff08\u5728\u6d41\u7a0b\u56fe\u4e2d\uff0c\u6211\u4eec\u76f4\u63a5\u8bbe\u7f6e\u4e86\u7528\u6237\u7684\u8bf7\u5047\u5ba1\u6279\u56fa\u5b9a\u63d0\u4ea4\u7ed9 managers\uff0c\u5728\u540e\u7eed\u7684\u6587\u7ae0\u4e2d\uff0c\u677e\u54e5\u4f1a\u6559\u5927\u5bb6\u5982\u4f55\u628a\u8fd9\u4e2a\u63d0\u4ea4\u7684\u76ee\u6807\u7528\u6237\u53d8\u6210\u4e00\u4e2a\u52a8\u6001\u7684\uff09\u3002<\/p>\n<h2>6. \u8bf7\u5047\u5ba1\u6279<\/h2>\n<p>\u63a5\u4e0b\u6765\u7ecf\u7406\u5c31\u53ef\u4ee5\u9009\u62e9\u6279\u51c6\u6216\u8005\u662f\u62d2\u7edd\u8fd9\u8bf7\u5047\u4e86\u3002<\/p>\n<p>\u9996\u5148\u6211\u4eec\u5c01\u88c5\u4e00\u4e2a\u5b9e\u4f53\u7c7b\u7528\u6765\u63a5\u53d7\u524d\u7aef\u4f20\u6765\u7684\u8bf7\u6c42\uff1a<\/p>\n<pre><code class=\"java\">public class ApproveRejectVO {\n    private String taskId;\n    private Boolean approve;\n    private String name;\n    \/\/ \u7701\u7565 getter\/setter\n}<\/code><\/pre>\n<p>\u53c2\u6570\u90fd\u597d\u7406\u89e3\uff0capprove \u4e3a true \u8868\u793a\u7533\u8bf7\u901a\u8fc7\uff0cfalse \u8868\u793a\u7533\u8bf7\u88ab\u62d2\u7edd\u3002<\/p>\n<p>\u63a5\u4e0b\u6765\u6211\u4eec\u6765\u770b\u63a5\u53e3\uff1a<\/p>\n<pre><code class=\"java\">@PostMapping(&quot;\/handler&quot;)\npublic RespBean askForLeaveHandler(@RequestBody ApproveRejectVO approveRejectVO) {\n    return askForLeaveService.askForLeaveHandler(approveRejectVO);\n}<\/code><\/pre>\n<p>\u770b\u5177\u4f53\u7684 askForLeaveHandler \u65b9\u6cd5\uff1a<\/p>\n<pre><code class=\"java\">@Service\npublic class AskForLeaveService {\n\n    @Autowired\n    TaskService taskService;\n\n    public RespBean askForLeaveHandler(ApproveRejectVO approveRejectVO) {\n        try {\n            boolean approved = approveRejectVO.getApprove();\n            Map&lt;String, Object&gt; variables = new HashMap&lt;String, Object&gt;();\n            variables.put(&quot;approved&quot;, approved);\n            variables.put(&quot;employee&quot;, approveRejectVO.getName());\n            Task task = taskService.createTaskQuery().taskId(approveRejectVO.getTaskId()).singleResult();\n            taskService.complete(task.getId(), variables);\n            if (approved) {\n                \/\/\u5982\u679c\u662f\u540c\u610f\uff0c\u8fd8\u9700\u8981\u7ee7\u7eed\u8d70\u4e00\u6b65\n                Task t = taskService.createTaskQuery().processInstanceId(task.getProcessInstanceId()).singleResult();\n                taskService.complete(t.getId());\n            }\n            return RespBean.ok(&quot;\u64cd\u4f5c\u6210\u529f&quot;);\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n        return RespBean.error(&quot;\u64cd\u4f5c\u5931\u8d25&quot;);\n    }\n}<\/code><\/pre>\n<p>\u5927\u5bb6\u6ce8\u610f\u8fd9\u4e2a\u5ba1\u6279\u6d41\u7a0b\uff1a<\/p>\n<ol>\n<li>\u5ba1\u6279\u65f6\u9700\u8981\u4e24\u4e2a\u53c2\u6570\uff0capproved \u548c employee\uff0capproved \u4e3a true\uff0c\u5c31\u4f1a\u81ea\u52a8\u8fdb\u5165\u5230\u5ba1\u6279\u901a\u8fc7\u7684\u6d41\u7a0b\u4e2d\uff0capproved \u4e3a false \u5219\u4f1a\u81ea\u52a8\u8fdb\u5165\u5230\u62d2\u7edd\u6d41\u7a0b\u4e2d\u3002<\/li>\n<li>\u901a\u8fc7 taskService\uff0c\u7ed3\u5408 taskId\uff0c\u4ece\u6d41\u7a0b\u4e2d\u67e5\u8be2\u51fa\u5bf9\u5e94\u7684 task\uff0c\u7136\u540e\u8c03\u7528 taskService.complete \u65b9\u6cd5\u4f20\u5165 taskId \u548c \u53d8\u91cf\uff0c\u4ee5\u4f7f\u6d41\u7a0b\u5411\u4e0b\u8d70\u3002<\/li>\n<li>\u5c0f\u4f19\u4f34\u4eec\u518d\u56de\u987e\u4e00\u4e0b\u6211\u4eec\u524d\u9762\u7684\u6d41\u7a0b\u56fe\uff0c\u5982\u679c\u8bf7\u6c42\u88ab\u6279\u51c6\u5907\u4e86\uff0c\u90a3\u4e48\u5728\u6267\u884c\u5b8c\u81ea\u5b9a\u4e49\u7684 Approve \u903b\u8f91\u540e\uff0c\u5c31\u4f1a\u8fdb\u5165\u5230 Holiday approved \u8fd9\u4e2a userTask \u4e2d\uff0c\u6ce8\u610f\u6b64\u65f6\u5e76\u4e0d\u4f1a\u7ee7\u7eed\u5411\u4e0b\u8d70\u4e86\uff08\u8fd8\u5dee\u4e00\u6b65\u5230\u7ed3\u675f\u4e8b\u4ef6\uff09\uff1b\u5982\u679c\u662f\u8bf7\u6c42\u62d2\u7edd\uff0c\u5219\u5728\u6267\u884c\u5b8c\u81ea\u5b9a\u4e49\u7684 Reject \u903b\u8f91\u540e\uff0c\u5c31\u8fdb\u5165\u5230\u7ed3\u675f\u4e8b\u4ef6\u4e86\uff0c\u8fd9\u4e2a\u6d41\u7a0b\u5c31\u7ed3\u675f\u4e86\u3002<\/li>\n<li>\u9488\u5bf9\u7b2c\u4e09\u6761\uff0c\u6240\u4ee5\u4ee3\u7801\u4e2d\u6211\u4eec\u8fd8\u9700\u8981\u989d\u5916\u518d\u52a0\u4e00\u6b65\uff0c\u5982\u679c\u662f approved \u4e3a true\uff0c\u90a3\u4e48\u5c31\u518d\u4ece\u5f53\u524d\u6d41\u7a0b\u4e2d\u67e5\u8be2\u51fa\u6765\u9700\u8981\u6267\u884c\u7684 task\uff0c\u518d\u8c03\u7528 complete \u7ee7\u7eed\u8d70\u4e00\u6b65\uff0c\u6b64\u65f6\u5c31\u5230\u4e86\u7ed3\u675f\u4e8b\u4ef6\u4e86\uff0c\u8fd9\u4e2a\u6d41\u7a0b\u5c31\u7ed3\u675f\u4e86\u3002\u6ce8\u610f\u8fd9\u6b21\u7684\u67e5\u8be2\u662f\u6839\u636e\u5f53\u524d\u6d41\u7a0b\u7684 ID \u67e5\u8be2\u7684\uff0c\u4e00\u4e2a\u6d41\u7a0b\u5c31\u662f\u4e00\u6761\u7ebf\uff0c\u8fd9\u6761\u7ebf\u4e0a\u6709\u5f88\u591a Task\uff0c\u6211\u4eec\u53ef\u4ee5\u4ece Task \u4e2d\u83b7\u53d6\u5230\u6d41\u7a0b\u7684 ID\u3002<\/li>\n<\/ol>\n<p>\u597d\u5566\uff0c\u63a5\u53e3\u5c31\u5199\u597d\u4e86\u3002<\/p>\n<p>\u5f53\u7136\uff0c\u8fd9\u91cc\u8fd8\u6d89\u53ca\u5230\u4e24\u4e2a\u81ea\u5b9a\u4e49\u7684\u903b\u8f91\uff0c\u5c31\u662f\u6279\u51c6\u6216\u8005\u62d2\u7edd\u4e4b\u540e\u7684\u81ea\u5b9a\u4e49\u903b\u8f91\uff0c\u8fd9\u4e2a\u5176\u5b9e\u5f88\u597d\u5199\uff0c\u5982\u4e0b\uff1a<\/p>\n<pre><code class=\"java\">public class Approve implements JavaDelegate {\n    @Override\n    public void execute(DelegateExecution execution) {\n        System.out.println(&quot;\u7533\u8bf7\u901a\u8fc7:&quot;+execution.getVariables());\n    }\n}<\/code><\/pre>\n<p>\u6211\u4eec\u81ea\u5b9a\u4e49\u7c7b\u5b9e\u73b0 JavaDelegate \u63a5\u53e3\u5373\u53ef\uff0c\u7136\u540e\u6211\u4eec\u5728 execute \u65b9\u6cd5\u4e2d\u505a\u81ea\u5df1\u60f3\u8981\u505a\u7684\u4e8b\u60c5\u5373\u53ef\uff0cexecution \u4e2d\u6709\u8fd9\u4e2a\u6d41\u7a0b\u4e2d\u7684\u6240\u6709\u53d8\u91cf\u3002\u6211\u4eec\u53ef\u4ee5\u5728\u8fd9\u91cc\u53d1\u90ae\u4ef6\uff08\u516c\u4f17\u53f7\u6c5f\u5357\u4e00\u70b9\u96e8\u540e\u53f0\u56de\u590d 666 \u6709\u53d1\u90ae\u4ef6\u6559\u7a0b\uff09\u3001\u53d1\u77ed\u4fe1\u7b49\u7b49\u3002Reject \u7684\u5b9a\u4e49\u65b9\u5f0f\u4e5f\u662f\u7c7b\u4f3c\u7684\u3002\u8fd9\u4e9b\u81ea\u5b9a\u4e49\u7c7b\u5199\u597d\u4e4b\u540e\uff0c\u5c06\u6765\u914d\u7f6e\u5230\u6d41\u7a0b\u56fe\u4e2d\u5373\u53ef\uff08\u53ef\u67e5\u770b\u4e0a\u6587\u7684\u6d41\u7a0b\u56fe\uff09\u3002<\/p>\n<p>\u6700\u540e\u518d\u6765\u770b\u770b\u524d\u7aef\u63d0\u4ea4\u65b9\u6cd5\u5c31\u7b80\u5355\u4e86\uff08\u9875\u9762\u6e90\u7801\u4e0a\u6587\u5df2\u7ecf\u5217\u51fa\uff09\uff1a<\/p>\n<pre><code class=\"js\">approveOrReject(taskId, approve,name) {\n    let _this = this;\n    axios.post('\/handler', {taskId: taskId, approve: approve,name:name})\n        .then(function (response) {\n            _this.initTasks();\n        })\n        .catch(function (error) {\n            console.log(error);\n        });\n}<\/code><\/pre>\n<p>\u8fd9\u5c31\u4e00\u4e2a\u666e\u901a\u7684 Ajax \u8bf7\u6c42\uff0c\u6279\u51c6\u7684\u8bdd\u7b2c\u4e8c\u4e2a\u53c2\u6570\u5c31\u4e3a true\uff0c\u62d2\u7edd\u7684\u8bdd\u7b2c\u4e8c\u4e2a\u53c2\u6570\u5c31\u4e3a false\u3002<\/p>\n<h2>7. \u7ed3\u679c\u67e5\u8be2<\/h2>\n<p>\u6700\u540e\uff0c\u6bcf\u4e2a\u7528\u6237\u90fd\u53ef\u4ee5\u67e5\u770b\u81ea\u5df1\u66fe\u7ecf\u7684\u7533\u8bf7\u8bb0\u5f55\u3002\u672c\u6765\u8fd9\u4e2a\u767b\u5f55\u4e4b\u540e\u5c31\u53ef\u4ee5\u5c55\u793a\u4e86\uff0c\u4f46\u662f\u56e0\u4e3a\u6211\u4eec\u6ca1\u6709\u767b\u5f55\uff0c\u6240\u4ee5\u8fd9\u91cc\u4e5f\u662f\u9700\u8981\u624b\u52a8\u8f93\u5165\u67e5\u8be2\u7684\u7528\u6237\uff0c\u7136\u540e\u6839\u636e\u7528\u6237\u540d\u67e5\u8be2\u8fd9\u4e2a\u7528\u6237\u7684\u5386\u53f2\u8bb0\u5f55\uff0c\u6211\u4eec\u5148\u6765\u770b\u67e5\u8be2\u63a5\u53e3\uff1a<\/p>\n<pre><code class=\"java\">@GetMapping(&quot;\/search&quot;)\npublic RespBean searchResult(String name) {\n    return askForLeaveService.searchResult(name);\n}<\/code><\/pre>\n<p>\u53c2\u6570\u5c31\u662f\u8981\u67e5\u8be2\u7684\u7528\u6237\u540d\u3002\u5177\u4f53\u7684\u67e5\u8be2\u6d41\u7a0b\u5982\u4e0b\uff1a<\/p>\n<pre><code class=\"java\">public RespBean searchResult(String name) {\n    List&lt;HistoryInfo&gt; historyInfos = new ArrayList&lt;&gt;();\n    List&lt;HistoricProcessInstance&gt; historicProcessInstances = historyService.createHistoricProcessInstanceQuery().processInstanceBusinessKey(name).finished().orderByProcessInstanceEndTime().desc().list();\n    for (HistoricProcessInstance historicProcessInstance : historicProcessInstances) {\n        HistoryInfo historyInfo = new HistoryInfo();\n        Date startTime = historicProcessInstance.getStartTime();\n        Date endTime = historicProcessInstance.getEndTime();\n        List&lt;HistoricVariableInstance&gt; historicVariableInstances = historyService.createHistoricVariableInstanceQuery()\n                .processInstanceId(historicProcessInstance.getId())\n                .list();\n        for (HistoricVariableInstance historicVariableInstance : historicVariableInstances) {\n            String variableName = historicVariableInstance.getVariableName();\n            Object value = historicVariableInstance.getValue();\n            if (&quot;reason&quot;.equals(variableName)) {\n                historyInfo.setReason((String) value);\n            } else if (&quot;days&quot;.equals(variableName)) {\n                historyInfo.setDays(Integer.parseInt(value.toString()));\n            } else if (&quot;approved&quot;.equals(variableName)) {\n                historyInfo.setStatus((Boolean) value);\n            } else if (&quot;name&quot;.equals(variableName)) {\n                historyInfo.setName((String) value);\n            }\n        }\n        historyInfo.setStartTime(startTime);\n        historyInfo.setEndTime(endTime);\n        historyInfos.add(historyInfo);\n    }\n    return RespBean.ok(&quot;ok&quot;, historyInfos);\n}<\/code><\/pre>\n<ol>\n<li>\u6211\u4eec\u5f53\u65f6\u5728\u5f00\u542f\u6d41\u7a0b\u7684\u65f6\u5019\uff0c\u4f20\u5165\u4e86\u4e00\u4e2a\u53c2\u6570 key\uff0c\u8fd9\u91cc\u5c31\u662f\u518d\u6b21\u901a\u8fc7\u8fd9\u4e2a key\uff0c\u4e5f\u5c31\u662f\u7528\u6237\u540d\u53bb\u67e5\u8be2\u5386\u53f2\u6d41\u7a0b\uff0c\u67e5\u8be2\u7684\u65f6\u5019\u8fd8\u52a0\u4e0a\u4e86 finished \u65b9\u6cd5\uff0c\u8fd9\u4e2a\u8868\u793a\u8981\u67e5\u8be2\u7684\u6d41\u7a0b\u5fc5\u987b\u662f\u6267\u884c\u5b8c\u6bd5\u7684\u6d41\u7a0b\uff0c\u5bf9\u4e8e\u6ca1\u6709\u6267\u884c\u5b8c\u6bd5\u7684\u6d41\u7a0b\uff0c\u8fd9\u91cc\u4e0d\u67e5\u8be2\uff0c\u67e5\u5b8c\u4e4b\u540e\uff0c\u6309\u7167\u6d41\u7a0b\u6700\u540e\u7684\u5904\u7406\u65f6\u95f4\u8fdb\u884c\u6392\u5e8f\u3002<\/li>\n<li>\u904d\u5386\u7b2c\u4e00\u6b65\u7684\u67e5\u8be2\u7ed3\u679c\uff0c\u4ece HistoricProcessInstance \u4e2d\u63d0\u53d6\u51fa\u6bcf\u4e00\u4e2a\u6d41\u7a0b\u7684\u8be6\u7ec6\u4fe1\u606f\uff0c\u5e76\u5b58\u5165\u5230\u96c6\u5408\u4e2d\uff0c\u5e76\u6700\u7ec8\u8fd4\u56de\u3002<\/li>\n<li>\u8fd9\u91cc\u6d89\u53ca\u5230\u4e24\u4e2a\u5386\u53f2\u6570\u636e\u67e5\u8be2\uff0ccreateHistoricProcessInstanceQuery \u7528\u6765\u67e5\u8be2\u5386\u53f2\u6d41\u7a0b\uff0c\u800c createHistoricVariableInstanceQuery \u5219\u4e3b\u8981\u662f\u7528\u6765\u67e5\u8be2\u6d41\u7a0b\u53d8\u91cf\u7684\u3002<\/li>\n<\/ol>\n<p>\u6700\u540e\uff0c\u524d\u7aef\u901a\u8fc7\u8868\u683c\u5c55\u793a\u8fd9\u4e2a\u6570\u636e\u5373\u53ef\uff1a<\/p>\n<pre><code class=\"html\">&lt;!DOCTYPE html&gt;\n&lt;html lang=&quot;en&quot;&gt;\n&lt;head&gt;\n    &lt;meta charset=&quot;UTF-8&quot;&gt;\n    &lt;title&gt;Title&lt;\/title&gt;\n    &lt;script src=&quot;https:\/\/unpkg.com\/axios\/dist\/axios.min.js&quot;&gt;&lt;\/script&gt;\n    &lt;!-- Import style --&gt;\n    &lt;link rel=&quot;stylesheet&quot; href=&quot;\/\/unpkg.com\/element-plus\/dist\/index.css&quot;\/&gt;\n    &lt;script src=&quot;https:\/\/unpkg.com\/vue@3&quot;&gt;&lt;\/script&gt;\n    &lt;!-- Import component library --&gt;\n    &lt;script src=&quot;\/\/unpkg.com\/element-plus&quot;&gt;&lt;\/script&gt;\n&lt;\/head&gt;\n&lt;body&gt;\n&lt;div id=&quot;app&quot;&gt;\n    &lt;div style=&quot;margin-top: 50px&quot;&gt;\n        &lt;el-input v-model=&quot;name&quot; style=&quot;width: 300px&quot; placeholder=&quot;\u8bf7\u8f93\u5165\u7528\u6237\u540d&quot;&gt;&lt;\/el-input&gt;\n        &lt;el-button type=&quot;primary&quot; @click=&quot;search&quot;&gt;\u67e5\u8be2&lt;\/el-button&gt;\n    &lt;\/div&gt;\n\n    &lt;div&gt;\n        &lt;el-table border strip :data=&quot;historyInfos&quot;&gt;\n            &lt;el-table-column prop=&quot;name&quot; label=&quot;\u59d3\u540d&quot;&gt;&lt;\/el-table-column&gt;\n            &lt;el-table-column prop=&quot;startTime&quot; label=&quot;\u63d0\u4ea4\u65f6\u95f4&quot;&gt;&lt;\/el-table-column&gt;\n            &lt;el-table-column prop=&quot;endTime&quot; label=&quot;\u5ba1\u6279\u65f6\u95f4&quot;&gt;&lt;\/el-table-column&gt;\n            &lt;el-table-column prop=&quot;reason&quot; label=&quot;\u4e8b\u7531&quot;&gt;&lt;\/el-table-column&gt;\n            &lt;el-table-column prop=&quot;days&quot; label=&quot;\u5929\u6570&quot;&gt;&lt;\/el-table-column&gt;\n            &lt;el-table-column label=&quot;\u72b6\u6001&quot;&gt;\n                &lt;template #default=&quot;scope&quot;&gt;\n                    &lt;el-tag type=&quot;success&quot; v-if=&quot;scope.row.status&quot;&gt;\u5df2\u901a\u8fc7&lt;\/el-tag&gt;\n                    &lt;el-tag type=&quot;danger&quot; v-else&gt;\u5df2\u62d2\u7edd&lt;\/el-tag&gt;\n                &lt;\/template&gt;\n            &lt;\/el-table-column&gt;\n        &lt;\/el-table&gt;\n    &lt;\/div&gt;\n&lt;\/div&gt;\n&lt;script&gt;\n    Vue.createApp(\n        {\n            data() {\n                return {\n                    historyInfos: [],\n                    name: 'zhangsan'\n                }\n            },\n            methods: {\n                search() {\n                    let _this = this;\n                    axios.get('\/search?name=' + this.name)\n                        .then(function (response) {\n                            if (response.data.status == 200) {\n                                _this.historyInfos=response.data.data;\n                            } else {\n                                _this.$message.error(response.data.msg);\n                            }\n                        })\n                        .catch(function (error) {\n                            console.log(error);\n                        });\n                }\n        }\n    ).use(ElementPlus).mount('#app')\n&lt;\/script&gt;\n&lt;\/body&gt;\n&lt;\/html&gt;<\/code><\/pre>\n<p>\u8fd9\u4e2a\u90fd\u662f\u4e00\u4e9b\u5e38\u89c4\u64cd\u4f5c\uff0c\u6211\u5c31\u4e0d\u591a\u8bf4\u4e86\uff0c\u6700\u7ec8\u5c55\u793a\u6548\u679c\u5982\u4e0b\uff1a<\/p>\n<p><img decoding=\"async\" referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/remote\/1460000042298182\" alt=\"\" title=\"\" loading=\"lazy\"><\/p>\n<h2>8. \u5c0f\u7ed3<\/h2>\n<p>\u597d\u5566\uff0c\u4e00\u4e2a\u7b80\u5355\u7684\u8bf7\u5047\u6d41\u7a0b\uff0c\u8ba9\u5927\u5bb6\u5bf9 Flowable \u7684\u73a9\u6cd5\u6709\u4e00\u4e2a\u57fa\u672c\u7684\u8ba4\u77e5\uff0c\u4e0b\u7bc7\u6587\u7ae0\u677e\u54e5\u6765\u548c\u5927\u5bb6\u7ee7\u7eed\u5b8c\u5584\u672c\u6587\u3002Flowable \u7684\u89c6\u9891\u5c06\u4f1a\u51fa\u73b0\u5728 TienChin \u9879\u76ee\u4e2d\uff0c\u5927\u5bb6\u4e0d\u8981\u9519\u8fc7\u54e6\uff1a<a href=\"https:\/\/link.segmentfault.com\/?enc=oYS0%2BYkjf37%2Fih0ImNjfxA%3D%3D.8VFjJl9f3zdbtZswTo3LxYzW9FpU0NHz0NYWCfWSh3hJ%2Bf2xknqEleHDU4GUlIX9%2B4wwgsUtbh9em%2FE1TgR1ew%3D%3D\" rel=\"nofollow\">TienChin \u9879\u76ee\u914d\u5957\u89c6\u9891\u6765\u5566<\/a>\u3002<\/p>\n<p><a href=\"https:\/\/segmentfault.com\/a\/1190000042298176\">https:\/\/segmentfault.com\/a\/1190000042298176<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u5c0f\u4f19\u4f34\u4eec\u77e5\u9053\u677e\u54e5\u6700\u8fd1\u5728\u5f55 TienChin \u9879\u76ee\u89c6\u9891\uff0c\u8fd9\u4e2a\u9879\u76ee\u4f1a\u7528\u5230\u5de5\u4f5c\u6d41\uff0c\u4e3a\u4e86\u5e2e\u52a9\u5c0f\u4f19\u4f34\u4eec\u66f4\u597d\u7684\u7406\u89e3\u8fd9\u4e2a\u9879\u76ee [&hellip;]<\/p>\n","protected":false},"author":0,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[],"tags":[],"class_list":["post-10006163","post","type-post","status-publish","format-standard","hentry"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/itmax.cn\/index.php?rest_route=\/wp\/v2\/posts\/10006163","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/itmax.cn\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/itmax.cn\/index.php?rest_route=\/wp\/v2\/types\/post"}],"replies":[{"embeddable":true,"href":"https:\/\/itmax.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=10006163"}],"version-history":[{"count":0,"href":"https:\/\/itmax.cn\/index.php?rest_route=\/wp\/v2\/posts\/10006163\/revisions"}],"wp:attachment":[{"href":"https:\/\/itmax.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=10006163"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/itmax.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=10006163"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/itmax.cn\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=10006163"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}