flowable多任務實現(xiàn)會簽、或簽

1簡介

做工作流,基本會遇到會簽、或簽的需求。而flowable是通過多任務方式來實現(xiàn)的

2主要實現(xiàn)方式

在流程運行到任務節(jié)點時不是按照默認規(guī)則只生成一條任務記錄,而是根據(jù)需要同時生成多條任務記錄,甚至生成的多條任務都能分別對應到指定的各個審批人。而不再需要領取。這種就叫多任務

要實現(xiàn)多任務,則需要對 需要的任務節(jié)點需要做相關處理

下面介紹了解到兩種方式處理

2.1 xml方式

此種方式是直接通過在xml的相應節(jié)點來定義多任務,這種官方有大量的xml 例子

【官方】多任務的xml

使用flowable 官方的套件來配置多任務的交互見面大概如下(圖片來源于網(wǎng)上):

[圖片上傳失敗...(image-211f1c-1666348348264)]

最終對應到實際的核心xml詳細如下 (下面xml不嚴格對應上圖)

    <bpmn2:userTask id="Activity_1g65lke" name="審批啊14" flowable:assignee="${assignee}" flowable:candidateGroups="2317,2347" flowable:category="CHECK">
      <bpmn2:extensionElements>
        <flowable:executionListener class="***.listens.MultiInstanceListen" event="start" />

      </bpmn2:extensionElements>
      <bpmn2:incoming>Flow_1666168081285</bpmn2:incoming>
      <bpmn2:outgoing>Flow_03sldqb</bpmn2:outgoing>

      <bpmn2:multiInstanceLoopCharacteristics isSequential="false" flowable:collection="assigneeList" flowable:elementVariable="assignee">
        <bpmn2:extensionElements>
          
        </bpmn2:extensionElements>
        <bpmn2:completionCondition>${nrOfCompletedInstances>=1}</bpmn2:completionCondition>
      </bpmn2:multiInstanceLoopCharacteristics>

    </bpmn2:userTask>

如果你不是用的官方的UI來生成的xml, 那么你的自己想辦法也需要構造出上面的xml

2.2 java類后端處理

此種方式是我在調研時看到的,我并未嘗試過,不太切合我們的需求,但是也是一種方式

此種方式就是運行到相應節(jié)點,后端通過調用api來生成多任務所需要的一切

這邊就不放核心代碼了,直接可以點擊網(wǎng)友已經(jīng)做好的整理

3 核心參數(shù)解釋

上面應該能看到我們需要配置一些東西才能支持多任務。這里詳細說下相關參數(shù)及重要點

3.1 相關參數(shù)

  1. isSequential: 表示并行,還是順序。(xml跟配圖可能有出入)

  2. loop cardinality:循環(huán)基數(shù)??蛇x項??梢灾苯犹钫麛?shù),表示會簽、或簽的人數(shù) - (會創(chuàng)建基數(shù)個任務實例)

    使用該參數(shù)只能保證生成相應的任務,但是生成的任務沒有assign

    該參數(shù)跟下面 collection 二選一就行

  3. flowable:collection: 此種方式是表示的會簽、或簽的具體人。這里xml只需要約定好固定的格式 即可。比如 flowable:collection="assigneeList"

  4. flowable:elementVariable: 元素變量, 這里xml只需要約定好固定的格式 即可 flowable:elementVariable="assignee"

  5. completionCondition:完成條件。這個條件控制著這里是會簽、或簽如何才能算完成。

    1. nrOfCompletedInstances: 完成的任務實例數(shù)
    2. nrOfInstances: 總共生成的任務實例數(shù)(根據(jù)會簽、或簽指定的人數(shù)生成相應的任務數(shù))

    參考配置

    當是或簽時,直接固定配置: ${nrOfCompletedInstances>=1} 即可

    當是會簽時,固定配置: ${nrOfCompletedInstances==nrOfInstances} 即可

3.2 重要點

  1. 在會簽、或簽節(jié)點增加 multiInstanceLoopCharacteristics 相應的標簽

  2. 指定生成的任務數(shù)。這里更建議使用 collection。 因為它可以相關配置做到 給生成的任務實例時就有assign

  3. 任務標簽上屬性 flowable:assignee="${assignee}" 必須固定這么指定,否則創(chuàng)建的多任務記錄里面 assign還是沒值

    屬性assignee 取 Element varible的值,比如Element varible設置為assignee,Assignents就設置為${assignee}

  4. 如果節(jié)點是審批節(jié)點,那么一定需要在用戶任務節(jié)點 的 extensionElements下添加 監(jiān)聽器

4 collection 賦值

4.1 使用原因

首先我們?yōu)槭裁匆褂?collection 再次簡單說下,通過上面的配置,當指定了 collection 的流程變量后,在引擎自動生成多任務時每個任務的assign都有值了。就不再需要增加業(yè)務邏輯處理(遍歷多任務后然后拿到審批人,依次給每個任務塞 處理人)

4.2 如何賦值

做下來覺得最難的地方就是 collection 賦值的問題。思路線索很多,但是都存在問題

4.2.1 官方

首先說還是說官方的例子 點擊查看MultiInstanceTest

里面竟然是通過在發(fā)起流程就指定了審批人。這種也太DEMO了點。審批人即使是配置時固定的人,在開始發(fā)起流程就有知道審批人,那么就需要去解析xml, 找到相應節(jié)點的審批人。這種一開始只被我用來做最后的打算

官方還給出另一種表達式方案 點擊查看multiinstancemodel.bpmn

    <endEvent id="sid-194696BA-1A7D-47D7-95A9-A77390D25048"></endEvent>
    <userTask id="userTask1" name="User task 1" flowable:async="true" flowable:exclusive="false">
      <multiInstanceLoopCharacteristics isSequential="false" flowable:elementVariable="participant">
        <extensionElements>
          <flowable:collection flowable:class="org.flowable.engine.test.bpmn.multiinstance.JSONCollectionHandler">
            <flowable:string>
              <![CDATA[[
                   {
                     "principalType" : "User",
                     "role" : "PotentialOwner",
                     "principal" : "wfuser1",
                     "version" : 1
                   },
                   {
                     "principalType" : "User",
                     "role" : "PotentialOwner",
                     "principal" : "wfuser2",
                     "version" : 1
                   }
                 ]]]>
            </flowable:string>
          </flowable:collection>
        </extensionElements>
      </multiInstanceLoopCharacteristics>
    </userTask>

然后這種方式我是各種嘗試,但是在流程走到該節(jié)點就出現(xiàn)解析不成功問題

最后我也查到了這種方式的來源是這篇帖子 Multi-instance collection syntax proposal 有更感興趣的可以去看看

4.2.2 事件

在嘗試使用上面方式失敗后,我開始嘗試用監(jiān)聽事件的方式來賦值collection 。

我嘗試過 FlowableEngineEventType.ACTIVITY_STARTED 事件 , FlowableEngineEventType.TASK_CREATED 事件

但是發(fā)現(xiàn)都不行,他們都是在多任務已經(jīng)創(chuàng)建完后才會執(zhí)行相關的事件方法。這個時候已經(jīng)生成的多個任務,但是它們的assign都是空的

4.2.3 執(zhí)行監(jiān)聽器

我在網(wǎng)上查詢方案,終于在一篇文中 activiti多實例設置(會簽/或簽) 看到能在任務創(chuàng)建前賦值collection 的可能。

然后我根據(jù)這個信息查到配置執(zhí)行監(jiān)聽器最終做到在正確時機給 collection 賦值

首先,需要在xml需要添加監(jiān)聽器 (完整可以看看上面的xml)

<flowable:executionListener class="***.listens.MultiInstanceListen" event="start" />

然后看看實現(xiàn)

/**
 *  多任務監(jiān)聽,主要是把 多人任務xml設置的集合給填充掉
 */
@Component
@Slf4j
public class MultiInstanceListen implements ExecutionListener {

    @Override
    public void notify(DelegateExecution execution) {
        FlowElement element = execution.getCurrentFlowElement();
        if (element instanceof UserTask) {
            UserTask userTask = (UserTask) element;
            List<String> candidateGroups = userTask.getCandidateGroups();
            // 設置 setVariableLocal 會導致找不到 assigneeList 變量
            execution.setVariable("assigneeList", candidateGroups);
        }
    }
}

通過此方式,就會在創(chuàng)建多任務之前執(zhí)行該監(jiān)聽器,從而讓 assigneeList 集合存放在流程變量中

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容