Android開發之activiti節點跳轉_Android

來源:互聯網
上載者:User

activiti使用的時候,通常需要跟業務緊密的結合在一起,有些業務非常的複雜,比如一個簡單的採購流程:流程如下:

 

供應商上新商品的時候,提交商務審核,商務審核通過提交運營審核,審核失敗退回供應商。

運營審核成功提交合約簽訂。交運營審核審核失敗退回商務審核或者直接退回供應商。

合約簽訂審核通過結束,合約簽訂審核不通過返回運營審核或者退回商務審核,或者退回供應商。

上面的流程就出現了一個問題,什麼問題呢?

我們來觀察一下退回線的問題。

1.商務審核退回供應商上新。

2.運營審核可能退回商務審核,運營審核可能退回供應商上新。

3.合約簽訂可能退回運營審核,合約簽訂可能退回商務審核,合約簽訂可能退回供應商上新。

4....

假如以後我們的流程在添加新的部門審核,是不是我們的退回線更加的多了。其實就是n!的問題,難道我們沒添加一個節點,就要畫很多的退回線嗎?這顯然是一個糟糕的設計。oh my god.

存在的問題就是,我們要是想讓我們的流程更加的通用,我們可能在設計的時候,需要添加很多的退回線控制,防止業務變化,流程跟起來變化,這就是應對了變化,同時在增加了冗餘設計。

那有沒有一種更好的方式,能解決上面的問題呢?很顯然這就是我們本章要解決的問題。

1.1.1. activiti節點跳轉實現

實現之前,我們考慮幾個問題。

1.當前流程在哪一個節點。

2.流程需要跳轉的目標節點。

3.跳轉到目標節點之後,需要添加變數嗎?有可能需要把,總不能無緣無故的跳轉到了目標節點。痕迹肯定要記錄。

4.跳轉到目標節點,那當前節點配置的任務監聽需要觸發嗎?(可參考 activiti監聽器使用).當前節點跳轉到目標節點的時候,如果當前節點配置了任務監聽業務,調轉到目標節點之前,這些當前的任務節點的是否觸發任務監聽業務必須能支援靈活配置。

上面的思考點,也是我們接下來需要重點講解的內容。那下面就開始我們的設計吧。

1.1.1.1. 流程圖

下面我們先定義一個流程如下圖所示:

 

1.1.1.2. xml

下面我們先定義一個xml定義如下所示:

<?xml version="1.0" encoding="UTF-8"?> <definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="daling">  <process id="daling" name="name_daling" isExecutable="true" activiti:candidateStarterUsers="a,b,c,d">   <userTask id="usertask2" name="usertask2" activiti:assignee="c"></userTask>   <userTask id="usertask3" name="usertask3"></userTask>   <sequenceFlow id="flow4" sourceRef="usertask2" targetRef="usertask3"></sequenceFlow>   <userTask id="usertask4" name="usertask4"></userTask>   <sequenceFlow id="flow5" sourceRef="usertask3" targetRef="usertask4"></sequenceFlow>   <userTask id="usertask5" name="usertask5"></userTask>   <sequenceFlow id="flow6" sourceRef="usertask4" targetRef="usertask5"></sequenceFlow>   <endEvent id="endevent1" name="End"></endEvent>   <sequenceFlow id="flow7" sourceRef="usertask5" targetRef="endevent1"></sequenceFlow>   <startEvent id="startevent1" name="Start"></startEvent>   <sequenceFlow id="flow8" sourceRef="startevent1" targetRef="usertask2"></sequenceFlow>  </process>  <bpmndi:BPMNDiagram id="BPMNDiagram_daling">   <bpmndi:BPMNPlane bpmnElement="daling" id="BPMNPlane_daling">    <bpmndi:BPMNShape bpmnElement="usertask2" id="BPMNShape_usertask2">     <omgdc:Bounds height="55.0" width="105.0" x="300.0" y="90.0"></omgdc:Bounds>    </bpmndi:BPMNShape>    <bpmndi:BPMNShape bpmnElement="usertask3" id="BPMNShape_usertask3">     <omgdc:Bounds height="55.0" width="105.0" x="450.0" y="90.0"></omgdc:Bounds>    </bpmndi:BPMNShape>    <bpmndi:BPMNShape bpmnElement="usertask4" id="BPMNShape_usertask4">     <omgdc:Bounds height="55.0" width="105.0" x="600.0" y="90.0"></omgdc:Bounds>    </bpmndi:BPMNShape>    <bpmndi:BPMNShape bpmnElement="usertask5" id="BPMNShape_usertask5">     <omgdc:Bounds height="55.0" width="105.0" x="750.0" y="90.0"></omgdc:Bounds>    </bpmndi:BPMNShape>    <bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">     <omgdc:Bounds height="35.0" width="35.0" x="900.0" y="100.0"></omgdc:Bounds>    </bpmndi:BPMNShape>    <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">     <omgdc:Bounds height="35.0" width="35.0" x="140.0" y="90.0"></omgdc:Bounds>    </bpmndi:BPMNShape>    <bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4">     <omgdi:waypoint x="405.0" y="117.0"></omgdi:waypoint>     <omgdi:waypoint x="450.0" y="117.0"></omgdi:waypoint>    </bpmndi:BPMNEdge>    <bpmndi:BPMNEdge bpmnElement="flow5" id="BPMNEdge_flow5">     <omgdi:waypoint x="555.0" y="117.0"></omgdi:waypoint>     <omgdi:waypoint x="600.0" y="117.0"></omgdi:waypoint>    </bpmndi:BPMNEdge>    <bpmndi:BPMNEdge bpmnElement="flow6" id="BPMNEdge_flow6">     <omgdi:waypoint x="705.0" y="117.0"></omgdi:waypoint>     <omgdi:waypoint x="750.0" y="117.0"></omgdi:waypoint>    </bpmndi:BPMNEdge>    <bpmndi:BPMNEdge bpmnElement="flow7" id="BPMNEdge_flow7">     <omgdi:waypoint x="855.0" y="117.0"></omgdi:waypoint>     <omgdi:waypoint x="900.0" y="117.0"></omgdi:waypoint>    </bpmndi:BPMNEdge>    <bpmndi:BPMNEdge bpmnElement="flow8" id="BPMNEdge_flow8">     <omgdi:waypoint x="175.0" y="107.0"></omgdi:waypoint>     <omgdi:waypoint x="300.0" y="117.0"></omgdi:waypoint>    </bpmndi:BPMNEdge>   </bpmndi:BPMNPlane>  </bpmndi:BPMNDiagram> </definitions>

1.1.1.3. 代碼實現

package com.daling.ch1.jd; import java.util.Iterator; import java.util.Map; import org.activiti.engine.impl.context.Context; import org.activiti.engine.impl.interceptor.Command; import org.activiti.engine.impl.interceptor.CommandContext; import org.activiti.engine.impl.persistence.entity.ExecutionEntity; import org.activiti.engine.impl.persistence.entity.ExecutionEntityManager; import org.activiti.engine.impl.persistence.entity.TaskEntity; import org.activiti.engine.impl.pvm.process.ActivityImpl; /**  *  * JD節點的跳轉  * 分享牛原創(尊重原創 轉載對的時候第一行請註明,轉載出處來自分享牛http://blog.csdn.net/qq_30739519)  */ public class JDJumpTaskCmd implements Command<Void> { protected String executionId; protected ActivityImpl desActivity; protected Map<String, Object> paramvar; protected ActivityImpl currentActivity; /**  * 分享牛原創(尊重原創 轉載對的時候第一行請註明,轉載出處來自分享牛http://blog.csdn.net/qq_30739519)  */ public Void execute(CommandContext commandContext) { ExecutionEntityManager executionEntityManager = Context .getCommandContext().getExecutionEntityManager(); // 擷取當前流程的executionId,因為在並發的情況下executionId是唯一的。 ExecutionEntity executionEntity = executionEntityManager .findExecutionById(executionId); executionEntity.setVariables(paramvar); executionEntity.setEventSource(this.currentActivity); executionEntity.setActivity(this.currentActivity); // 根據executionId 擷取Task Iterator<TaskEntity> localIterator = Context.getCommandContext() .getTaskEntityManager() .findTasksByExecutionId(this.executionId).iterator(); while (localIterator.hasNext()) { TaskEntity taskEntity = (TaskEntity) localIterator.next(); // 觸發任務監聽 taskEntity.fireEvent("complete"); // 刪除任務的原因 Context.getCommandContext().getTaskEntityManager() .deleteTask(taskEntity, "completed", false); } executionEntity.executeActivity(this.desActivity); return null; } /**  * 構造參數 可以根據自己的業務需要添加更多的欄位  * 分享牛原創(尊重原創 轉載對的時候第一行請註明,轉載出處來自分享牛http://blog.csdn.net/qq_30739519)  * @param executionId  * @param desActivity  * @param paramvar  * @param currentActivity  */ public JDJumpTaskCmd(String executionId, ActivityImpl desActivity, Map<String, Object> paramvar, ActivityImpl currentActivity) { this.executionId = executionId; this.desActivity = desActivity; this.paramvar = paramvar; this.currentActivity = currentActivity; } } 

1.1.1.4. 使用

我們先讓流程運轉到usertask3節點的時候開始測試跳轉。

怎麼使用上面的JDJumpTaskCmd類呢,直接new JDJumpTaskCmd()調用,肯定不行了,因為activiti引擎程式沒有擷取,肯定報錯,正確的的使用方式如下:

1.1.1.4.1. 第一種方式

我們先來觀察一下資料庫ACT_RU_TASK表任務的記錄資訊,方便我們的操作,資料庫記錄如下圖所示:

 

可以看到當前的節點在usertask3,我們現在把usertask3跳轉到usertask5節點,看是否能成功,因為usertask3到usertask5沒有連線,如果成功了,就說明我們這個方法正確。

執行下面的代碼,根據自己的資料庫資訊修改相對應的值即可。

Map<String, Object> vars = new HashMap<String, Object>(); String[] v = { "shareniu1", "shareniu2", "shareniu3", "shareniu4" }; vars.put("assigneeList", Arrays.asList(v)); //分享牛原創(尊重原創 轉載對的時候第一行請註明,轉載出處來自分享牛http://blog.csdn.net/qq_30739519) RepositoryService repositoryService = demo.getRepositoryService(); ReadOnlyProcessDefinition processDefinitionEntity = (ReadOnlyProcessDefinition) repositoryService .getProcessDefinition("daling:29:137504"); // 目標節點 ActivityImpl destinationActivity = (ActivityImpl) processDefinitionEntity .findActivity("usertask5"); String executionId = "137509"; // 當前節點   ActivityImpl currentActivity = (ActivityImpl)processDefinitionEntity    .findActivity("usertask3"); demo.getManagementService().executeCommand( new JDJumpTaskCmd(executionId, destinationActivity, vars, currentActivity)); 

執行上面的代碼之後,我們看一下資料庫中的記錄。

 

節點確實跳轉到了usertask5。ok了這個方法確實可以沒問題,下面說一下第二種方式執行executeCommand命令。

1.1.1.4.2. 第二種方式

Map<String, Object> vars = new HashMap<String, Object>(); String[] v = { "shareniu1", "shareniu2", "shareniu3", "shareniu4" }; vars.put("assigneeList", Arrays.asList(v)); //分享牛原創(尊重原創 轉載對的時候第一行請註明,轉載出處來自分享牛http://blog.csdn.net/qq_30739519)   CommandExecutor commandExecutor = taskServiceImpl    .getCommandExecutor();   commandExecutor.execute(new JDJumpTaskCmd(executionId,    destinationActivity, vars, currentActivity)); 

上面的兩種方式都可以執行自訂的Command子類。讀者選擇自己喜歡使用的方式即可。

1.1.2. 小結

1.任意節點的跳轉,前提是節點必須在模板定義中。

2.任意節點的跳轉暫時不能跨流程跳轉。

3.任意節點的跳轉不需要連線即可、

4.任意節點的跳轉可以實現回退、轉辦、轉閱、越級上報、一步到底等等功能,關於這些更多的實戰,我們將在最後的工作流程實戰項目中一步步封裝。使用。

以上所述是小編給大家介紹的activiti節點跳轉的相關知識,希望對大家有所協助!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.