{"id":10006442,"date":"2022-09-08T18:36:46","date_gmt":"2022-09-08T10:36:46","guid":{"rendered":"https:\/\/ityet.com\/?p=10006442"},"modified":"2022-09-08T18:36:46","modified_gmt":"2022-09-08T10:36:46","slug":"%e8%af%b7%e5%81%87%e8%a6%81%e7%bb%84%e9%95%bf%e5%92%8c%e7%bb%8f%e7%90%86%e5%90%8c%e6%97%b6%e5%ae%a1%e6%89%b9%e8%af%a5%e6%80%8e%e4%b9%88%e5%8a%9e%ef%bc%9f%e6%9d%a5%e7%9c%8b%e7%9c%8b%e5%b7%a5%e4%bd%9c","status":"publish","type":"post","link":"https:\/\/itmax.cn\/?p=10006442","title":{"rendered":"\u8bf7\u5047\u8981\u7ec4\u957f\u548c\u7ecf\u7406\u540c\u65f6\u5ba1\u6279\u8be5\u600e\u4e48\u529e\uff1f\u6765\u770b\u770b\u5de5\u4f5c\u6d41\u4e2d\u7684\u4f1a\u7b7e\u529f\u80fd\uff01"},"content":{"rendered":"<p>@[toc]<br \/>\u4eca\u5929\u677e\u54e5\u548c\u5c0f\u4f19\u4f34\u4eec\u4ecb\u7ecd\u4e00\u4e0b Spring Security \u4e2d\u53e6\u5916\u4e00\u4e2a\u597d\u73a9\u7684\u4f1a\u7b7e\u529f\u80fd\u3002<\/p>\n<p>\u4f1a\u7b7e\u7684\u610f\u601d\u5c31\u662f\uff0c\u5728\u4e00\u4e2a\u6d41\u7a0b\u4e2d\u7684\u67d0\u4e00\u4e2a Task \u4e0a\uff0c\u8fd9\u4e2a Task \u9700\u8981\u591a\u4e2a\u7528\u6237\u5ba1\u6279\uff0c\u5f53\u591a\u4e2a\u7528\u6237\u5168\u90e8\u5ba1\u6279\u901a\u8fc7\uff0c\u6216\u8005\u591a\u4e2a\u7528\u6237\u4e2d\u7684\u67d0\u51e0\u4e2a\u7528\u6237\u5ba1\u6279\u901a\u8fc7\uff0c\u5c31\u7b97\u901a\u8fc7\u3002\u8fd9\u5c31\u662f\u6211\u4eec\u8bf4\u7684 Flowable \u4e2d\u7684\u4f1a\u7b7e\u529f\u80fd\uff01<\/p>\n<p>\u4f8b\u5982\u6211\u4eec\u4e4b\u524d\u7684\u8bf7\u5047\u6d41\u7a0b\uff0c\u5047\u8bbe\u8fd9\u4e2a\u8bf7\u5047\u6d41\u7a0b\u9700\u8981\u7ec4\u957f\u548c\u7ecf\u7406\u90fd\u5ba1\u6279\u4e86\uff0c\u624d\u7b97\u5ba1\u6279\u901a\u8fc7\uff0c\u90a3\u4e48\u6211\u4eec\u5c31\u9700\u8981\u8bbe\u7f6e\u8fd9\u4e2a Task \u662f\u4f1a\u7b7e\u8282\u70b9\u3002<\/p>\n<p>\u4ee5\u6211\u4eec\u4e4b\u524d\u7684\u8bf7\u5047\u6d41\u7a0b\u4e3a\u4f8b\uff0c\u6211\u548c\u5927\u5bb6\u6f14\u793a\u4e00\u4e0b\u6211\u4eec\u8fd9\u6b21\u8981\u5b9e\u73b0\u7684\u6548\u679c\u3002<\/p>\n<ol>\n<li>\u9996\u5148\u5458\u5de5\u63d0\u4ea4\u8bf7\u5047\u7533\u8bf7\uff0c\u53ef\u4ee5\u63d0\u4ea4\u7ed9\u591a\u4e2a\u5ba1\u6279\u4eba\uff1a<\/li>\n<\/ol>\n<p><img decoding=\"async\" referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/remote\/1460000042450857\" alt=\"\" title=\"\" loading=\"lazy\"><\/p>\n<ol start=\"2\">\n<li>\u63d0\u4ea4\u6210\u529f\u4e4b\u540e\uff0c\u5458\u5de5\u7684\u5386\u53f2\u8bf7\u5047\u5217\u8868\u4e2d\uff0c\u53ef\u4ee5\u770b\u5230\u521a\u521a\u63d0\u4ea4\u7684\u8bf7\u5047\u7533\u8bf7\uff0c\u4f46\u662f\u9009\u62e9\u7684\u4e09\u4e2a\u5ba1\u6279\u4eba\u90fd\u662f\u7070\u8272\u7684\uff0c\u8868\u793a\u4e09\u4e2a\u4eba\u90fd\u8fd8\u6ca1\u6709\u5ba1\u6279\u3002<\/li>\n<\/ol>\n<p><img decoding=\"async\" referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/remote\/1460000042450858\" alt=\"\" title=\"\" loading=\"lazy\"><\/p>\n<ol start=\"3\">\n<li>\u63a5\u4e0b\u6765\uff0c\u4ee5 javaboy \u7684\u8eab\u4efd\u767b\u5f55\u5230\u7cfb\u7edf\u4e2d\uff0c\u5c31\u53ef\u4ee5\u770b\u5230\u521a\u521a\u7528\u6237\u63d0\u4ea4\u7684\u8bf7\u5047\u7533\u8bf7\uff0c\u7136\u540e\u8fdb\u884c\u5ba1\u6279\u3002<\/li>\n<\/ol>\n<p><img decoding=\"async\" referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/remote\/1460000042450859\" alt=\"\" title=\"\" loading=\"lazy\"><\/p>\n<ol start=\"4\">\n<li>\u5ba1\u6279\u5b8c\u6210\u540e\uff0c\u4ee5 zhangsan \u7684\u8eab\u4efd\u767b\u5f55\u5230\u7cfb\u7edf\u4e2d\uff0c\u5c31\u53ef\u4ee5\u770b\u5230 javaboy \u5df2\u7ecf\u5b8c\u6210\u5ba1\u6279\u4e86\uff0c\u7b49\u4e09\u4e2a\u4eba\u90fd\u5b8c\u6210\u5ba1\u6279\u4e4b\u540e\uff0c\u8fd9\u4e2a\u8bf7\u5047\u6d41\u7a0b\u7684\u72b6\u6001\u4e5f\u5c31\u4f1a\u53d8\u6210\u5df2\u901a\u8fc7\uff0c\u8981\u662f\u4e09\u4e2a\u4eba\u4e2d\u6709\u4e00\u4e2a\u4eba\u70b9\u51fb\u4e86\u62d2\u7edd\uff0c\u90a3\u4e48\u8fd9\u4e2a\u8bf7\u5047\u6d41\u7a0b\u7684\u72b6\u6001\u5c31\u4f1a\u53d8\u4e3a\u5df2\u62d2\u7edd\u3002<\/li>\n<\/ol>\n<p><img decoding=\"async\" referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/remote\/1460000042450860\" alt=\"\" title=\"\" loading=\"lazy\"><\/p>\n<p>\u597d\u5566\uff0c\u8fd9\u5c31\u662f\u6211\u4eec\u672c\u6587\u8981\u5b9e\u73b0\u7684\u4e00\u4e2a\u529f\u80fd\u3002\u672c\u6587\u4e5f\u662f\u57fa\u4e8e\u4e4b\u524d\u7684\u6587\u7ae0\u5b8c\u6210\uff0c\u5982\u679c\u5c0f\u4f19\u4f34\u4eec\u8fd8\u6ca1\u770b\u8fc7\u677e\u54e5\u4e4b\u524d\u53d1\u7684\u5173\u4e8e Flowable \u6d41\u7a0b\u5f15\u64ce\u7684\u6587\u7ae0\uff0c\u53ef\u4ee5\u5728\u516c\u4f17\u53f7\u6c5f\u5357\u4e00\u70b9\u96e8\u4e0a\u5148\u7ffb\u4e00\u4e0b\u3002<\/p>\n<h2>1. \u4f1a\u7b7e\u6d41\u7a0b\u56fe<\/h2>\n<p>\u9996\u5148\u6211\u4eec\u6765\u753b\u4e00\u4e0b\u8fd9\u4e2a\u8bf7\u5047\u6d41\u7a0b\u56fe\uff0c\u8fd9\u4e2a\u6d41\u7a0b\u56fe\u57fa\u672c\u4e0a\u8fd8\u662f\u548c\u4e4b\u524d\u7684\u4e00\u6837\uff0c\u5982\u4e0b\u56fe\uff1a<\/p>\n<p><img decoding=\"async\" referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/remote\/1460000042450861\" alt=\"\" title=\"\" loading=\"lazy\"><\/p>\n<p>\u8fd9\u8ddf\u6211\u4eec\u4e4b\u524d\u7684\u6d41\u7a0b\u56fe\u6709\u4e24\u4e2a\u4e0d\u4e00\u6837\u7684\u5730\u65b9\uff1a<\/p>\n<ol>\n<li>\u9996\u5148\u5c31\u662f\u6700\u6700\u6838\u5fc3\u7684\u7684\u8fd9\u4e2a\u6279\u51c6\u6216\u8005\u62d2\u7edd\u7684\u8282\u70b9\uff0c\u8fd9\u4e2a\u8282\u70b9\u4e0b\u9762\u591a\u4e2a\u4e09\u4e2a\u7ad6\u7ebf\uff0c\u8fd9\u4e09\u4e2a\u7ad6\u7ebf\u7684\u610f\u601d\u5c31\u662f\u591a\u4e2a\u7528\u6237\u5ba1\u6279\u65f6\u662f\u5e76\u53d1\u6267\u884c\u7684\uff0c\u76f8\u4e92\u4e4b\u95f4\u6ca1\u6709\u5148\u540e\u987a\u5e8f\uff0c\u8fd8\u6709\u4e00\u79cd\u662f\u4e09\u4e2a\u6a2a\u7ebf\uff0c\u4e09\u4e2a\u6a2a\u7ebf\u7684\u610f\u601d\u662f\u591a\u4e2a\u7528\u6237\u987a\u5e8f\u6267\u884c\u3002\u5f53\u7136\uff0c\u8fd9\u91cc\u4e0d\u662f\u8bf4\u6d41\u7a0b\u56fe\u4e0a\u591a\u4e09\u4e2a\u7ad6\u7ebf\u5c31\u884c\u4e86\uff0c\u8fd8\u9700\u8981\u7a0d\u5fae\u914d\u7f6e\u4e00\u4e0b\uff0c\u5982\u4e0b\uff1a<\/li>\n<\/ol>\n<p><img decoding=\"async\" referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/remote\/1460000042450862\" alt=\"\" title=\"\" loading=\"lazy\"><\/p>\n<p>\u8fd9\u91cc\u914d\u7f6e\u7684\u5c5e\u6027\u4e3b\u8981\u6709\u4e94\u4e2a\uff1a<\/p>\n<ul>\n<li>\u591a\u5b9e\u4f8b\u7c7b\u578b\uff1a\u8fd9\u4e2a\u9009\u9879\u4e3b\u8981\u6709\u4e24\u4e2a\uff0c\u5206\u522b\u662f Parallel \u548c Sequential\uff0c\u8868\u793a\u5e76\u53d1\u6267\u884c\u8fd8\u662f\u987a\u5e8f\u6267\u884c\uff0c\u9009\u62e9\u662f Parallel \u5c31\u662f\u591a\u4e2a\u7528\u6237\u5e76\u53d1\u6267\u884c\uff0c\u76f8\u4e92\u4e4b\u95f4\u6ca1\u6709\u5148\u540e\u987a\u5e8f\uff0c\u9009\u62e9 Sequential \u5219\u662f\u987a\u5e8f\u6267\u884c\uff0c\u591a\u4e2a\u7528\u6237\u4e4b\u95f4\u6709\u5148\u540e\u987a\u5e8f\u3002<\/li>\n<li>\u96c6\u5408\uff08\u591a\u5b9e\u4f8b\uff09\uff1a\u8fd9\u4e2a\u5730\u65b9\u6211\u914d\u7f6e\u4e86\u4e00\u4e2a ${userTasks}\uff0c\u8fd9\u4e2a\u8868\u793a\u5f53\u6d41\u7a0b\u6267\u884c\u5230\u8fd9\u4e2a\u8282\u70b9\u7684\u65f6\u5019\uff0c\u6211\u4f1a\u4f20\u8fdb\u6765\u4e00\u4e2a\u53d8\u91cf\uff0c\u8fd9\u4e2a\u53d8\u91cf\u7684\u540d\u5b57\u662f userTasks\uff0c\u8fd9\u4e2a\u53d8\u91cf\u4e2d\u5305\u542b\u4e86\u6240\u6709\u8981\u5ba1\u6279\u8fd9\u4e2a Task \u7684\u7528\u6237\u540d\u3002<\/li>\n<li>\u5143\u7d20\u53d8\u91cf\uff08\u591a\u5b9e\u4f8b\uff09\uff1a\u7531\u4e8e\u4e0a\u9762\u7684\u662f\u4e00\u4e2a\u96c6\u5408\uff0c\u8fd9\u91cc\u914d\u7f6e\u7684\u5219\u662f\u96c6\u5408\u4e2d\u6bcf\u4e00\u4e2a\u5143\u7d20\u7684\u53d8\u91cf\u540d\uff0c\u8fd9\u5c31\u7c7b\u4f3c\u4e8e Java \u91cc\u589e\u5f3a for \u5faa\u73af\u7684\u53d8\u91cf\u540d\u3002<\/li>\n<li>\u5b8c\u6210\u6761\u4ef6\uff08\u591a\u5b9e\u4f8b\uff09\uff1a\u8fd9\u91cc\u6211\u914d\u7f6e\u7684\u503c\u662f <code>${nrOfCompletedInstances== nrOfInstances}<\/code>\uff0c\u6d89\u53ca\u5230\u4e24\u4e2a\u53d8\u91cf\uff0cnrOfCompletedInstances \u8fd9\u4e2a\u8868\u793a\u5df2\u7ecf\u5b8c\u6210\u5ba1\u6279\u7684\u5b9e\u4f8b\u4e2a\u6570\uff0cnrOfInstances \u5219\u8868\u793a\u603b\u5171\u7684\u5b9e\u4f8b\u4e2a\u6570\uff0c\u4e5f\u5c31\u662f\u5f53\u5b8c\u6210\u5ba1\u6279\u7684\u5b9e\u4f8b\u4e2a\u6570\u7b49\u4e8e\u603b\u7684\u5b9e\u4f8b\u4e2a\u6570\u7684\u65f6\u5019\uff0c\u8fd9\u4e2a\u8282\u70b9\u5c31\u7b97\u6267\u884c\u5b8c\u4e86\uff0c\u6362\u53e5\u8bdd\u8bf4\uff0c\u4e5f\u5c31\u662f zhangsan \u5c06\u8bf7\u5047\u7533\u8bf7\u63d0\u4ea4\u7ed9 javaboy \u548c lisi\uff0c\u5fc5\u987b\u8fd9\u4e24\u4e2a\u4eba\u90fd\u5ba1\u6279\u4e86\uff0c\u8fd9\u4e2a\u8282\u70b9\u624d\u7b97\u6267\u884c\u5b8c\u3002\u53e6\u5916\u8fd9\u91cc\u8fd8\u6709\u4e00\u4e2a\u5185\u7f6e\u7684\u53d8\u91cf\u53ef\u7528\u5c31\u662f nrOfActiveInstances \u8868\u793a\u672a\u5b8c\u6210\u5ba1\u6279\u7684\u5b9e\u4f8b\u4e2a\u6570\uff0c\u53ea\u4e0d\u8fc7\u5728\u672c\u6848\u4f8b\u4e2d\u6ca1\u6709\u7528\u5230\u8fd9\u4e2a\u5185\u7f6e\u53d8\u91cf\u3002<\/li>\n<li>\u5206\u914d\u7528\u6237\uff1a\u8fd9\u4e2a\u662f\u8bf4\u8fd9\u4e2a Task \u7684\u6267\u884c\u4eba\uff0c\u5f53\u7136\u5c31\u662f\u6211\u4eec\u524d\u9762\u914d\u7f6e\u7684 userTask\uff0c\u4e5f\u5c31\u662f\u4ece\u96c6\u5408\u4e2d\u62ff\u51fa\u6765\u7684\u6bcf\u4e00\u4e2a\u5143\u7d20\u7684\u53d8\u91cf\u540d\u3002<\/li>\n<\/ul>\n<ol start=\"2\">\n<li>\u53bb\u6389\u4e86\u5ba1\u6279\u901a\u8fc7\u4e4b\u540e\u7684 UserTask\u3002<\/li>\n<\/ol>\n<p>\u5728\u4e4b\u524d\u7684\u8bf7\u5047\u6d41\u7a0b\u56fe\u4e2d\uff0c\u5f53\u8bf7\u5047\u5ba1\u6279\u901a\u8fc7\u4e4b\u540e\uff0c\u53d1\u9001\u4e86\u8bf7\u5047\u901a\u8fc7\u901a\u77e5\u4e4b\u540e\uff0c\u8fd8\u4f1a\u8fdb\u5165\u5230\u4e00\u4e2a UserTask \u6d41\u7a0b\u4e2d\uff0c\u8fd9\u91cc\u4e3a\u4e86\u65b9\u4fbf\uff0c\u6211\u628a\u8fd9\u4e2a\u6d41\u7a0b\u5220\u6389\u4e86\u3002<\/p>\n<p>\u597d\u5566\uff0c\u8fd9\u5c31\u662f\u65b0\u6d41\u7a0b\u56fe\u548c\u4ee5\u524d\u65e7\u6d41\u7a0b\u56fe\u4e4b\u95f4\u7684\u4e00\u4e2a\u533a\u522b\uff0c\u73b0\u5728\u6211\u4eec\u6765\u770b\u4e0b\u8fd9\u4e2a\u6d41\u7a0b\u56fe\u5bf9\u5e94\u7684 XML \u6587\u4ef6\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; xmlns:xsd=&quot;http:\/\/www.w3.org\/2001\/XMLSchema&quot; xmlns:flowable=&quot;http:\/\/flowable.org\/bpmn&quot; xmlns:bpmndi=&quot;http:\/\/www.omg.org\/spec\/BPMN\/20100524\/DI&quot; xmlns:omgdc=&quot;http:\/\/www.omg.org\/spec\/DD\/20100524\/DC&quot; xmlns:omgdi=&quot;http:\/\/www.omg.org\/spec\/DD\/20100524\/DI&quot; typeLanguage=&quot;http:\/\/www.w3.org\/2001\/XMLSchema&quot; expressionLanguage=&quot;http:\/\/www.w3.org\/1999\/XPath&quot; targetNamespace=&quot;http:\/\/www.flowable.org\/processdef&quot; exporter=&quot;Flowable Open Source Modeler&quot; exporterVersion=&quot;6.7.2&quot;&gt;\n  &lt;process id=&quot;holidayRequest&quot; name=&quot;holidayRequest&quot; isExecutable=&quot;true&quot;&gt;\n    &lt;startEvent id=&quot;startEvent1&quot; flowable:formFieldValidation=&quot;true&quot;&gt;&lt;\/startEvent&gt;\n    &lt;userTask id=&quot;sid-1A1AA050-1900-4CAD-A277-18BD97BD61FB&quot; flowable:assignee=&quot;${userTask}&quot; flowable:formFieldValidation=&quot;true&quot;&gt;\n      &lt;extensionElements&gt;\n        &lt;modeler:initiator-can-complete xmlns:modeler=&quot;http:\/\/flowable.org\/modeler&quot;&gt;&lt;![CDATA[false]]&gt;&lt;\/modeler:initiator-can-complete&gt;\n      &lt;\/extensionElements&gt;\n      &lt;multiInstanceLoopCharacteristics isSequential=&quot;false&quot; flowable:collection=&quot;${userTasks}&quot; flowable:elementVariable=&quot;userTask&quot;&gt;\n        &lt;extensionElements&gt;&lt;\/extensionElements&gt;\n        &lt;completionCondition&gt;${nrOfCompletedInstances == nrOfInstances}&lt;\/completionCondition&gt;\n      &lt;\/multiInstanceLoopCharacteristics&gt;\n    &lt;\/userTask&gt;\n    &lt;sequenceFlow id=&quot;sid-2597F958-175E-4F9F-9BEA-6E89D6C5B0A4&quot; sourceRef=&quot;startEvent1&quot; targetRef=&quot;sid-1A1AA050-1900-4CAD-A277-18BD97BD61FB&quot;&gt;&lt;\/sequenceFlow&gt;\n    &lt;exclusiveGateway id=&quot;sid-A04AF65B-D8B2-4F30-BFD5-7F2C9FCEFA51&quot;&gt;&lt;\/exclusiveGateway&gt;\n    &lt;sequenceFlow id=&quot;sid-7CD68B1D-C2CE-4A1A-ABA7-216D0F80BDD8&quot; sourceRef=&quot;sid-1A1AA050-1900-4CAD-A277-18BD97BD61FB&quot; targetRef=&quot;sid-A04AF65B-D8B2-4F30-BFD5-7F2C9FCEFA51&quot;&gt;&lt;\/sequenceFlow&gt;\n    &lt;serviceTask id=&quot;sid-4412386C-15E9-40C6-AB6B-66919A8D1302&quot; flowable:class=&quot;org.javaboy.flowable03.flowable.Approve&quot;&gt;&lt;\/serviceTask&gt;\n    &lt;serviceTask id=&quot;sid-903B79F3-2020-419E-AD42-215C2E26C784&quot; flowable:class=&quot;org.javaboy.flowable03.flowable.Reject&quot;&gt;&lt;\/serviceTask&gt;\n    &lt;endEvent id=&quot;sid-FE27FA28-2B2F-4572-A2D6-BFE83EBA9370&quot;&gt;&lt;\/endEvent&gt;\n    &lt;sequenceFlow id=&quot;sid-474E5177-9B1A-4757-877F-5A0DA72B0A59&quot; sourceRef=&quot;sid-903B79F3-2020-419E-AD42-215C2E26C784&quot; targetRef=&quot;sid-FE27FA28-2B2F-4572-A2D6-BFE83EBA9370&quot;&gt;&lt;\/sequenceFlow&gt;\n    &lt;sequenceFlow id=&quot;sid-85E7B515-734C-4E46-9889-D74FC5A04891&quot; sourceRef=&quot;sid-A04AF65B-D8B2-4F30-BFD5-7F2C9FCEFA51&quot; targetRef=&quot;sid-903B79F3-2020-419E-AD42-215C2E26C784&quot;&gt;\n      &lt;conditionExpression xsi:type=&quot;tFormalExpression&quot;&gt;&lt;![CDATA[${!approved}]]&gt;&lt;\/conditionExpression&gt;\n    &lt;\/sequenceFlow&gt;\n    &lt;sequenceFlow id=&quot;sid-EEC3F695-D61D-40BC-BA68-BCDD4DA40299&quot; sourceRef=&quot;sid-A04AF65B-D8B2-4F30-BFD5-7F2C9FCEFA51&quot; targetRef=&quot;sid-4412386C-15E9-40C6-AB6B-66919A8D1302&quot;&gt;\n      &lt;conditionExpression xsi:type=&quot;tFormalExpression&quot;&gt;&lt;![CDATA[${approved}]]&gt;&lt;\/conditionExpression&gt;\n    &lt;\/sequenceFlow&gt;\n    &lt;endEvent id=&quot;sid-92DA7300-EFD1-437B-96D5-EAADAFABC507&quot;&gt;&lt;\/endEvent&gt;\n    &lt;sequenceFlow id=&quot;sid-E882A39F-9E88-4BB8-B7CE-F975B6ADC862&quot; sourceRef=&quot;sid-4412386C-15E9-40C6-AB6B-66919A8D1302&quot; targetRef=&quot;sid-92DA7300-EFD1-437B-96D5-EAADAFABC507&quot;&gt;&lt;\/sequenceFlow&gt;\n  &lt;\/process&gt;\n&lt;\/definitions&gt;<\/code><\/pre>\n<p>\u8fd9\u4e2a\u6d41\u7a0b\u56fe\u4e5f\u6ca1\u6709\u5565\u7279\u522b\u503c\u5f97\u8bf4\u7684\u5730\u65b9\uff0c\u57fa\u672c\u4e0a\u524d\u9762\u8be5\u8bf4\u7684\u90fd\u8bf4\u4e86\uff0c\u5c0f\u4f19\u4f34\u4eec\u53ef\u4ee5\u81ea\u884c\u7ed3\u5408\u6d41\u7a0b\u56fe\u5bf9\u6bd4\u770b\u4e0b\u8fd9\u4e2a XML \u6587\u4ef6\u3002<\/p>\n<h2>2. \u8bf7\u5047\u5904\u7406<\/h2>\n<h3>2.1 \u524d\u7aef\u63d0\u4ea4\u8bf7\u5047\u6d41\u7a0b<\/h3>\n<p>\u63a5\u4e0b\u6765\u6211\u4eec\u770b\u4e0b\u524d\u7aef\u5982\u4f55\u63d0\u4ea4\u8bf7\u5047\u7533\u8bf7\uff1a<\/p>\n<p>\u5148\u6765\u770b\u9875\u9762\uff1a<\/p>\n<p><img decoding=\"async\" referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/remote\/1460000042450857\" alt=\"\" title=\"\" loading=\"lazy\"><\/p>\n<p>\u5bf9\u5e94\u7684 HTML \u5982\u4e0b\uff1a<\/p>\n<pre><code class=\"html\">&lt;h1&gt;\u63d0\u4ea4\u8bf7\u5047\u7533\u8bf7&lt;\/h1&gt;\n&lt;table&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;tr&gt;\n        &lt;td&gt;\u5ba1\u6279\u4eba\uff1a&lt;\/td&gt;\n        &lt;td&gt;\n            &lt;el-select v-model=&quot;afl.approveUsers&quot; style=&quot;width: 226px&quot; placeholder=&quot;\u8bf7\u9009\u62e9\u5ba1\u6279\u4eba&quot; multiple&gt;\n                &lt;el-option\n                        v-for=&quot;item in users&quot;\n                        :key=&quot;item.id&quot;\n                        :label=&quot;item.username&quot;\n                        :value=&quot;item.username&quot;\/&gt;\n            &lt;\/el-select&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;<\/code><\/pre>\n<p>\u8ddf\u4e4b\u524d\u4e0d\u540c\u7684\u662f\uff0c\u8fd9\u91cc\u7684\u4e0b\u62c9\u6846\u662f\u591a\u9009\u7684\uff0c\u5f53\u7528\u6237\u63d0\u4ea4\u8bf7\u5047\u7533\u8bf7\u7684\u65f6\u5019\uff0c\u53ef\u4ee5\u9009\u62e9\u591a\u4e2a\u5ba1\u6279\u4eba\uff0c\u591a\u4e2a\u5ba1\u6279\u4eba\u7684\u503c\u5c06\u4fdd\u5b58\u5728 afl.approveUsers \u53d8\u91cf\u4e2d\u3002<\/p>\n<p>\u518d\u6765\u770b\u63d0\u4ea4\u8bf7\u5047\u65b9\u6cd5\uff1a<\/p>\n<pre><code class=\"js\">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                _this.search();\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},<\/code><\/pre>\n<p>\u8fd9\u4e2a\u65b9\u6cd5\u5176\u5b9e\u6ca1\u5565\u597d\u8bf4\u7684\uff0c\u552f\u4e00\u9700\u8981\u548c\u5c0f\u4f19\u4f34\u4eec\u5f3a\u8c03\u7684\u662f\u8bf7\u6c42\u7684\u53c2\u6570\uff0c\u6765\u770b\u4e0b\uff1a<\/p>\n<p><img decoding=\"async\" referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/remote\/1460000042450863\" alt=\"\" title=\"\" loading=\"lazy\"><\/p>\n<p>\u6211\u4eec\u6765\u770b\u4e0b\u6211\u8fd9\u91cc\u63d0\u4ea4\u7684\u4e09\u4e2a\u8bf7\u6c42\u53c2\u6570\uff1a<\/p>\n<ol>\n<li>approveUsers\uff1a\u8fd9\u662f\u5ba1\u6279\u5f53\u524d\u6d41\u7a0b\u7684\u4e09\u4e2a\u7528\u6237\uff0c\u5f53\u8fd9\u4e09\u4e2a\u7528\u6237\u90fd\u5ba1\u6279\u901a\u8fc7\u540e\uff0c\u8bf7\u5047\u6d41\u7a0b\u5c31\u901a\u8fc7\u4e86\u3002<\/li>\n<li>days\uff1a\u8fd9\u662f\u8bf7\u5047\u7684\u5929\u6570\u3002<\/li>\n<li>reason\uff1a\u8fd9\u662f\u8bf7\u5047\u7406\u7531\u3002<\/li>\n<\/ol>\n<h3>2.2 \u670d\u52a1\u7aef\u5904\u7406\u8bf7\u5047\u8bf7\u6c42<\/h3>\n<p>\u6211\u4eec\u518d\u6765\u770b\u770b\u670d\u52a1\u7aef\u5982\u4f55\u5904\u7406\u8fd9\u4e2a\u8bf7\u5047\u8bf7\u6c42\uff0c\u6211\u8fd9\u91cc\u8ddf\u5927\u5bb6\u5c55\u793a\u6700\u6838\u5fc3\u7684\u6d41\u7a0b\u5904\u7406\u4ee3\u7801\uff0c\u6587\u672b\u53ef\u4ee5\u4e0b\u8f7d\u5b8c\u6574\u4ee3\u7801\u3002<\/p>\n<pre><code class=\"java\">@Transactional\npublic RespBean askForLeave(AskForLeaveVO askForLeaveVO) {\n    Map&lt;String, Object&gt; variables = new HashMap&lt;&gt;();\n    askForLeaveVO.setName(SecurityContextHolder.getContext().getAuthentication().getName());\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    variables.put(&quot;userTasks&quot;, askForLeaveVO.getApproveUsers());\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}<\/code><\/pre>\n<p>\u53ef\u4ee5\u770b\u5230\uff0c\u4ece\u524d\u7aef\u4e00\u5171\u4f20\u9012\u8fc7\u6765\u4e09\u4e2a\u53c2\u6570\uff0c\u4f46\u662f\u6267\u884c\u8fd9\u4e2a\u6d41\u7a0b\u9700\u8981\u56db\u4e2a\u53c2\u6570\uff0c\u5176\u4e2d\u4e00\u4e2a name \u8868\u793a\u5f53\u524d\u767b\u5f55\u7684\u7528\u6237\u540d\uff0c\u4e5f\u5c31\u662f\u8fd9\u4e2a\u8bf7\u5047\u662f\u8c01\u53d1\u8d77\u7684\u3002\u53e6\u5916\u4e09\u4e2a\u53c2\u6570\u5c31\u662f\u524d\u7aef\u4f20\u6765\u7684\u53c2\u6570\u3002<\/p>\n<h3>2.3 \u670d\u52a1\u7aef\u8fd4\u56de\u5f85\u5ba1\u6279\u6570\u636e<\/h3>\n<p>\u63a5\u4e0b\u6765\u6211\u4eec\u6765\u770b\u770b\u670d\u52a1\u7aef\u5982\u4f55\u8fd4\u56de\u5f85\u5ba1\u6279\u6570\u636e\uff0c\u4e5f\u5c31\u662f\u4e0b\u9762\u8fd9\u5f20\u56fe\u8981\u5c55\u793a\u7684\u6570\u636e\uff1a<\/p>\n<p><img decoding=\"async\" referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/remote\/1460000042450859\" alt=\"\" title=\"\" loading=\"lazy\"><\/p>\n<pre><code class=\"java\">\/**\n * \u5f85\u5ba1\u6279\u5217\u8868\n *\n * @return\n *\/\npublic RespBean leaveList() {\n    String identity = SecurityContextHolder.getContext().getAuthentication().getName();\n    \/\/\u627e\u5230\u6240\u6709\u5206\u914d\u7ed9\u4f60\u7684\u4efb\u52a1\n    List&lt;Task&gt; tasks = taskService.createTaskQuery().taskAssignee(identity).list();\n    \/\/\u91cd\u65b0\u7ec4\u88c5\u8fd4\u56de\u7684\u6570\u636e\uff0c\u4e3a\u6bcf\u4e2a\u6d41\u7a0b\u589e\u52a0\u4efb\u52a1 id\uff0c\u65b9\u4fbf\u540e\u7eed\u6267\u884c\u6279\u51c6\u6216\u8005\u62d2\u7edd\u64cd\u4f5c\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}<\/code><\/pre>\n<p>\u8fd9\u4e2a\u6574\u4f53\u4e0a\u5206\u4e86\u4e24\u6b65\uff1a<\/p>\n<ol>\n<li>\u9996\u5148\u67e5\u8be2\u51fa\u6765\u5f53\u524d\u7528\u6237\u6240\u6709\u5f85\u5ba1\u6279\u7684 Task\u3002<\/li>\n<li>\u67e5\u8be2\u51fa\u6765\u8fd9\u4e9b Task \u4e0a\u7684 variables\uff0c\u8fd9\u662f\u4e00\u4e2a Map \u96c6\u5408\uff0c\u7136\u540e\u6211\u4eec\u518d\u624b\u52a8\u52a0\u4e0a id \u8fd9\u4e2a\u53c2\u6570\u3002<\/li>\n<\/ol>\n<p>\u6700\u540e\u5c06\u7ec4\u88c5\u597d\u7684 list \u5f04\u6210\u4e00\u4e2a JSON \u8fd4\u56de\u5373\u53ef\u3002<\/p>\n<h3>2.4 \u670d\u52a1\u7aef\u6279\u51c6 OR \u62d2\u7edd<\/h3>\n<p>\u6211\u4eec\u518d\u6765\u770b\u770b\u670d\u52a1\u7aef\u6279\u51c6\u6216\u8005\u62d2\u7edd\u8bf7\u5047\u6d41\u7a0b\u7684\u4ee3\u7801\uff1a<\/p>\n<pre><code class=\"java\">public RespBean askForLeaveHandler(ApproveRejectVO approveRejectVO) {\n    try {\n        Task task = taskService.createTaskQuery().taskId(approveRejectVO.getTaskId()).singleResult();\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;approveUser#&quot; + task.getAssignee(), SecurityContextHolder.getContext().getAuthentication().getName());\n        taskService.complete(task.getId(), variables);\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}<\/code><\/pre>\n<p>\u6279\u51c6\u6216\u8005\u62d2\u7edd\uff0c\u6700\u4e3b\u8981\u7684\u53c2\u6570\u5c31\u662f approved\uff0ctrue \u8868\u793a\u6279\u51c6\uff0cfalse \u8868\u793a\u62d2\u7edd\u3002<\/p>\n<p>\u53e6\u4e00\u65b9\u9762\uff0c\u7531\u4e8e\u73b0\u5728\u662f\u4f1a\u7b7e\uff0c\u6211\u4eec\u9700\u8981\u77e5\u9053\u76ee\u524d\u8c01\u5df2\u7ecf\u5ba1\u6279\u4e86\uff0c\u8c01\u8fd8\u6ca1\u5ba1\u6279\uff0c\u6240\u4ee5\u8fd9\u91cc\u989d\u5916\u591a\u52a0\u4e86\u4e00\u4e2a\u53c2\u6570 <code>approveUser#XXX<\/code>\uff0c\u8868\u793a\u5ba1\u6279\u8fd9\u4e2a\u8282\u70b9\u7684\u7528\u6237\u540d\uff08\u4e5f\u5c31\u662f\u5f53\u524d\u767b\u5f55\u7528\u6237\uff09\u3002<\/p>\n<p>\u6ce8\u610f\u8fd9\u4e2a\u53c2\u6570\u7684 key \u6211\u6ca1\u6709\u56fa\u5b9a\uff0c\u4e3b\u8981\u662f\u56e0\u4e3a\u8fd9\u4e2a\u8282\u70b9\u4f1a\u6709\u591a\u4e2a\u4eba\u5ba1\u6279\uff0c\u5982\u679c\u56fa\u5b9a\u7684\u8bdd\uff0c\u540e\u9762\u5ba1\u6279\u7684\u4eba\u4f1a\u8986\u76d6\u6389\u524d\u9762\u7684\u4eba\uff0c\u6240\u4ee5\u8fd9\u4e2a\u8282\u70b9\u7684 key \u8bbe\u7f6e\u6210\u52a8\u6001\u7684\u4e86\uff0c<code>approveUser#<\/code> \u540e\u9762\u52a0\u4e0a\u5904\u7406\u8fd9\u4e2a\u8282\u70b9\u7684\u7528\u6237\u540d\u3002<\/p>\n<h3>2.5 \u670d\u52a1\u7aef\u8fd4\u56de\u6d41\u7a0b\u6570\u636e<\/h3>\n<p>\u6700\u540e\u8fd8\u6709\u670d\u52a1\u7aef\u5c55\u793a\u6d41\u7a0b\u6570\u636e\u3002\u5c31\u662f\u5f53\u7528\u6237\u63d0\u4ea4\u6d41\u7a0b\u4e4b\u540e\uff0c\u60f3\u8981\u67e5\u770b\u81ea\u5df1\u7684\u6d41\u7a0b\u5904\u7406\u5230\u54ea\u4e00\u6b65\u4e86\uff0c\u4e5f\u5c31\u662f\u4e0b\u56fe\u4e2d\u7684\u6570\u636e\uff1a<\/p>\n<p><img decoding=\"async\" referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/remote\/1460000042450860\" alt=\"\" title=\"\" loading=\"lazy\"><\/p>\n<p>\u8fd9\u5f20\u56fe\u4e2d\u7684\u6570\u636e\u5176\u5b9e\u5305\u542b\u4e86\u4e24\u90e8\u5206\uff0c\u4e00\u90e8\u5206\u662f\u5df2\u7ecf\u6267\u884c\u5b8c\u7684\u6d41\u7a0b\uff0c\u8fd8\u6709\u4e00\u90e8\u5206\u662f\u6b63\u5728\u6267\u884c\u4e2d\u7684\u6d41\u7a0b\uff0c\u6240\u4ee5\u5728\u67e5\u8be2\u4e2d\uff0c\u6211\u4eec\u4e5f\u5f97\u5206\u4e3a\u4e24\u6b65\u6765\u5b8c\u6210\uff0c\u5982\u4e0b\uff1a<\/p>\n<pre><code class=\"java\">public RespBean searchResult() {\n    String name = SecurityContextHolder.getContext().getAuthentication().getName();\n    List&lt;HistoryInfo&gt; infos = new ArrayList&lt;&gt;();\n    \/\/\u672a\u5b8c\u6210\u6d41\u7a0b\n    List&lt;HistoricProcessInstance&gt; unFinishedHistoricProcessInstances = historyService.createHistoricProcessInstanceQuery().processInstanceBusinessKey(name).unfinished().orderByProcessInstanceStartTime().desc().list();\n    for (HistoricProcessInstance unFinishedHistoricProcessInstance : unFinishedHistoricProcessInstances) {\n        HistoryInfo historyInfo = new HistoryInfo();\n        Date startTime = unFinishedHistoricProcessInstance.getStartTime();\n        Date endTime = unFinishedHistoricProcessInstance.getEndTime();\n        List&lt;HistoricVariableInstance&gt; historicVariableInstances = historyService.createHistoricVariableInstanceQuery()\n                .processInstanceId(unFinishedHistoricProcessInstance.getId())\n                .list();\n        System.out.println(&quot;historicVariableInstances = &quot; + historicVariableInstances);\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;name&quot;.equals(variableName)) {\n                historyInfo.setName((String) value);\n            } else if (variableName.startsWith(&quot;approveUser&quot;)) {\n                historyInfo.getApproveUsers().add((String) value);\n            } else if (&quot;userTask&quot;.equals(variableName)) {\n                historyInfo.getCandidateUsers().add((String) value);\n            }\n        }\n        historyInfo.setStatus(3);\n        historyInfo.setStartTime(startTime);\n        historyInfo.setEndTime(endTime);\n        infos.add(historyInfo);\n    }\n    \/\/\u5df2\u7ed3\u675f\u6d41\u7a0b\n    List&lt;HistoricProcessInstance&gt; finishHistoricProcessInstances = historyService.createHistoricProcessInstanceQuery().processInstanceBusinessKey(name)\n            .finished()\n            .orderByProcessInstanceStartTime().desc().list();\n    for (HistoricProcessInstance historicProcessInstance : finishHistoricProcessInstances) {\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        System.out.println(historicVariableInstances);\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                Boolean v = (Boolean) value;\n                if (v) {\n                    historyInfo.setStatus(1);\n                } else {\n                    historyInfo.setStatus(2);\n                }\n            } else if (&quot;name&quot;.equals(variableName)) {\n                historyInfo.setName((String) value);\n            } else if (variableName.startsWith(&quot;approveUser&quot;)) {\n                historyInfo.getApproveUsers().add((String) value);\n            } else if (&quot;userTask&quot;.equals(variableName)) {\n                historyInfo.getCandidateUsers().add((String) value);\n            }\n        }\n        historyInfo.setStartTime(startTime);\n        historyInfo.setEndTime(endTime);\n        infos.add(historyInfo);\n    }\n    return RespBean.ok(&quot;ok&quot;, infos);\n}<\/code><\/pre>\n<p>\u8fd9\u6bb5\u4ee3\u7801\u6bd4\u8f83\u957f\uff0c\u4f46\u662f\u6bd4\u8f83\u50cf\u3002\u6574\u4f53\u4e0a\u5206\u4e3a\u4e24\u90e8\u5206\uff0c\u524d\u9762\u662f\u67e5\u8be2\u672a\u6267\u884c\u5b8c\u7684\u6d41\u7a0b\uff0c\u540e\u9762\u662f\u67e5\u8be2\u5df2\u7ecf\u6267\u884c\u5b8c\u6bd5\u7684\u6d41\u7a0b\u3002\u5bf9\u4e8e\u672a\u6267\u884c\u5b8c\u7684\u6d41\u7a0b\uff0c\u6211\u4eec\u5728 historyInfo \u4e2d\u8bbe\u7f6e status \u4e3a 3\uff0c\u8868\u793a\u5f85\u5ba1\u6279\u3002\u5f53\u6211\u4eec\u53bb\u8bfb\u53d6\u4e00\u4e2a\u6d41\u7a0b\u7684\u5386\u53f2\u53d8\u91cf\u65f6\uff0c\u6709\u4e00\u4e2a\u4ee5 approveUser \u5f00\u5934\u7684\u53d8\u91cf\uff0c\u8fd9\u4e2a\u5c31\u8868\u793a\u8fd9\u4e2a\u6d41\u7a0b\u5df2\u7ecf\u88ab\u8c01\u5ba1\u6279\u8fc7\u4e86\uff0c\u6211\u4eec\u5c06\u8fd9\u4e2a\u5b58\u5230\u4e00\u4e2a List \u96c6\u5408\u4e2d\uff0c\u5c06\u6765\u8fd4\u56de\u7ed9\u524d\u7aef\u3002\u6d41\u7a0b\u7684\u5386\u53f2\u53d8\u91cf\u4e2d\u8fd8\u6709\u4e00\u4e2a userTask\uff0c\u8868\u793a\u8fd9\u4e2a\u6d41\u7a0b\u4e2d\u8fd9\u4e2a\u8282\u70b9\u5f85\u5ba1\u6279\u7684\u7528\u6237\u90fd\u6709\u8c01\uff0c\u6211\u4eec\u4e5f\u5c06\u4e4b\u4fdd\u5b58\u5230 List \u96c6\u5408\u4e2d\uff0c\u5c06\u6765\u8fd4\u56de\u7ed9\u524d\u7aef\u3002<\/p>\n<h3>2.6 \u524d\u7aef\u6e32\u67d3\u5ba1\u6279\u6570\u636e<\/h3>\n<p>\u6700\u540e\uff0c\u6211\u4eec\u518d\u6765\u770b\u770b\u524d\u7aef\u5982\u4f55\u6e32\u67d3 2.5 \u5c0f\u8282\u8fd4\u56de\u7684\u6570\u636e\uff0c\u5982\u4e0b\uff1a<\/p>\n<pre><code class=\"html\">&lt;div&gt;\n    &lt;el-tag&gt;\u5386\u53f2\u8bf7\u5047\u5217\u8868&lt;\/el-tag&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;\u5ba1\u6279\u4eba&quot;&gt;\n            &lt;template #default=&quot;scope&quot;&gt;\n                &lt;template v-for=&quot;(cu,i) in scope.row.candidateUsers&quot; :key=&quot;i&quot;&gt;\n                    &lt;el-tag v-if=&quot;scope.row.approveUsers.indexOf(cu)!=-1&quot; type=&quot;success&quot;&gt;\n                        {{cu}}\n                    &lt;\/el-tag&gt;\n                    &lt;el-tag v-else style=&quot;color: gray&quot;&gt;{{cu}}&lt;\/el-tag&gt;\n                &lt;\/template&gt;\n            &lt;\/template&gt;\n        &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==1&quot;&gt;\u5df2\u901a\u8fc7&lt;\/el-tag&gt;\n                &lt;el-tag type=&quot;danger&quot; v-else-if=&quot;scope.row.status==2&quot;&gt;\u5df2\u62d2\u7edd&lt;\/el-tag&gt;\n                &lt;el-tag type=&quot;info&quot; v-else&gt;\u5f85\u5ba1\u6279&lt;\/el-tag&gt;\n            &lt;\/template&gt;\n        &lt;\/el-table-column&gt;\n    &lt;\/el-table&gt;\n&lt;\/div&gt;<\/code><\/pre>\n<p>\u5927\u5bb6\u770b\u5230\uff0c\u5728\u5ba1\u6279\u4eba\u8fd9\u4e2a\u5b57\u6bb5\u4e2d\uff0c\u6211\u4eec\u5148\u53bb\u904d\u5386\u663e\u793a\u8fd9\u4e2a\u6d41\u7a0b\u6240\u6709\u7684\u5ba1\u6279\u4eba\uff08candidateUsers\uff09\uff0c\u5728\u904d\u5386\u7684\u8fc7\u7a0b\u4e2d\uff0c\u5982\u679c\u53d1\u73b0\u8fd9\u4e2a\u7528\u6237\u5b58\u5728\u4e8e approveUsers \u96c6\u5408\u4e2d\uff0c\u5c31\u8868\u793a\u8fd9\u4e2a\u7528\u6237\u5df2\u7ecf\u5ba1\u6279\uff0c\u7528\u7eff\u8272\u7684 el-tag \u663e\u793a\uff0c\u5426\u5219\u8868\u793a\u8fd9\u4e2a\u7528\u6237\u8fd8\u6ca1\u6709\u5ba1\u6279\uff0c\u6211\u4eec\u5c31\u7528\u7070\u8272\u7684 el-tag \u663e\u793a\u3002<\/p>\n<p>\u597d\u5566\uff0c\u8fd9\u5c31\u53ef\u4ee5\u5566\uff01\u4e00\u4e2a\u7b80\u7b80\u5355\u5355\u7684\u4f1a\u7b7e\u529f\u80fd\u5c31\u5b8c\u6210\u4e86\uff0c\u6d4b\u8bd5\u6d41\u7a0b\u6211\u5c31\u4e0d\u6f14\u793a\u4e86\uff0c\u5c0f\u4f19\u4f34\u4eec\u53c2\u8003\u672c\u6587\u4e00\u5f00\u59cb\u7684\u5185\u5bb9\uff5e<\/p>\n<h2>3. \u6216\u7b7e<\/h2>\n<p>\u8bf4\u5b8c\u4e86\u4f1a\u7b7e\uff0c\u518d\u6765\u548c\u5927\u5bb6\u8bf4\u4e00\u8bf4\u6216\u7b7e\u3002<\/p>\n<p>\u6216\u7b7e\u610f\u601d\u5c31\u662f A \u7684\u8bf7\u5047\u6d41\u7a0b\u63d0\u4ea4\u7ed9 B\u3001C\u3001D\uff0c\u4f46\u662f\u5e76\u4e0d\u9700\u8981 B\/C\/D \u540c\u65f6\u5ba1\u6279\u901a\u8fc7\uff0c\u53ea\u9700\u8981 B\/C\/D \u4e2d\u7684\u4efb\u610f\u4e00\u4e2a\u5ba1\u6279\u5373\u53ef\uff0c\u8fd9\u5c31\u662f\u6216\u7b7e\uff0c<strong>\u6ce8\u610f\uff0c\u6211\u8fd9\u91cc\u7684\u8868\u8ff0\uff0c\u53ea\u9700\u8981 B\/C\/D \u4efb\u610f\u4e00\u4e2a\u5ba1\u6279\u5373\u53ef\uff0c\u8fd9\u4e2a\u5ba1\u6279\u5373\u53ef\u4ee5\u662f\u5ba1\u6279\u901a\u8fc7\uff0c\u4e5f\u53ef\u4ee5\u662f\u5ba1\u6279\u62d2\u7edd\uff0c\u53cd\u6b63\u53ea\u8981\u5ba1\u6279\uff0c\u8fd9\u4e2a UserTask \u5c31\u7b97\u5b8c\u6210\u4e86<\/strong>\u3002<\/p>\n<p>\u5c06\u4f1a\u7b7e\u6539\u4e3a\u6216\u7b7e\u5176\u5b9e\u975e\u5e38\u5bb9\u6613\uff0c\u6211\u4eec\u53ea\u9700\u8981\u4fee\u6539\u4e00\u4e0b UserTask \u7684\u5c5e\u6027\u5373\u53ef\uff0c\u548c\u4f1a\u7b7e\u76f8\u6bd4\uff0c\u6211\u8fd9\u91cc\u4e3b\u8981\u6539\u4e86\u4e00\u4e2a\u5730\u65b9\uff0c\u90fd\u5728\u4e0b\u56fe\u4e2d\u7528\u7bad\u5934\u6807\u51fa\u6765\u4e86\uff1a<\/p>\n<p><img decoding=\"async\" referrerpolicy=\"no-referrer\" src=\"https:\/\/segmentfault.com\/img\/remote\/1460000042450864\" alt=\"\" title=\"\" loading=\"lazy\"><\/p>\n<blockquote><p>\u5b8c\u6210\u6761\u4ef6\uff08\u591a\u5b9e\u4f8b\uff09\u8fd9\u91cc\u6539\u4e3a\u4e86 <code>${nrOfCompletedInstances &gt;= 1}<\/code>\uff0c\u8868\u793a\u53ea\u8981\u6709\u4e00\u4e2a\u540c\u610f\u6216\u8005\u62d2\u7edd\uff0c\u8fd9\u4e2a UserTask \u5c31\u7b97\u8fc7\u4e86\u3002<\/p><\/blockquote>\n<p>\u6539\u5b8c\u4e4b\u540e\uff0c\u6211\u4eec\u91cd\u65b0\u4e0b\u8f7d\u8fd9\u4e2a\u6d41\u7a0b\u56fe\u7684 XML \u6587\u4ef6\uff0c\u5e76\u653e\u5230\u524d\u6587\u4e2d\u7684\u4ee3\u7801\u4e0a\u53bb\u8fd0\u884c\uff0c\u5c31\u53ef\u4ee5\u770b\u5230\u6216\u7b7e\u6548\u679c\u4e86\uff0c\u6211\u5c31\u4e0d\u6f14\u793a\u4e86\uff0c\u5c0f\u4f19\u4f34\u4eec\u53ef\u4ee5\u81ea\u884c\u5c1d\u8bd5\u3002<\/p>\n<p>\u672c\u6587\u4e5f\u6709\u914d\u5957\u89c6\u9891\uff0c\u611f\u5174\u8da3\u7684\u5c0f\u4f19\u4f34\u6233\u8fd9\u91cc\u67e5\u770b\u89c6\u9891\u8be6\u60c5\uff1a<a href=\"https:\/\/link.segmentfault.com\/?enc=00ubchHdMjv4rp3StPtqYw%3D%3D.rkACoL3NlFGU5zm3e6SBPlnNnPpNpfi9%2FTaylMiXbszw%2FOz5bW6zEuKZvQZOwMMsrJOjIqW9NP5XB5aGWp4gTg%3D%3D\" rel=\"nofollow\">TienChin \u9879\u76ee\u914d\u5957\u89c6\u9891\u6765\u5566<\/a>\u3002<\/p>\n<p>\u5c0f\u4f19\u4f34\u4eec\u5728\u516c\u4f17\u53f7\u6c5f\u5357\u4e00\u70b9\u96e8\u540e\u53f0\u56de\u590d flowable04 \u53ef\u4ee5\u4e0b\u8f7d\u672c\u6587\u5b8c\u6574\u6848\u4f8b\uff5e<\/p>\n<p><a href=\"https:\/\/segmentfault.com\/a\/1190000042450854\">https:\/\/segmentfault.com\/a\/1190000042450854<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>@[toc]\u4eca\u5929\u677e\u54e5\u548c\u5c0f\u4f19\u4f34\u4eec\u4ecb\u7ecd\u4e00\u4e0b Spring Security \u4e2d\u53e6\u5916\u4e00\u4e2a\u597d\u73a9\u7684\u4f1a\u7b7e\u529f\u80fd\u3002 \u4f1a\u7b7e\u7684\u610f\u601d [&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-10006442","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\/10006442","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=10006442"}],"version-history":[{"count":0,"href":"https:\/\/itmax.cn\/index.php?rest_route=\/wp\/v2\/posts\/10006442\/revisions"}],"wp:attachment":[{"href":"https:\/\/itmax.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=10006442"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/itmax.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=10006442"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/itmax.cn\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=10006442"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}