生活随笔
收集整理的這篇文章主要介紹了
Activiti 工作流会签开发设计思路
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
在流程業務管理中,任務是通常都是由一個人去處理的,而多個人同時處理一個任 務,這種任務我們稱之為會簽任務。這種業務需求也很常見,如一個請款單,領導審批環節中,就需要多個部門領導簽字。在流程業務中,我們可以把每個領導簽字 的環節都定義為任務,但若這樣,這個流程業務有一點是固定的,就是簽批人是固定的。而任務是由一個領導簽完再到另一領導,當然也可以由多個領導同時簽字。
傳統的用流程業務來解決可以采用以下的做法:
串行會簽
并行會簽?
前者在流程業務中,叫串行會簽,也即是由一個領導簽完再至另一領導簽。后者我們稱之為并行會簽,表示幾個領導同時進行簽發,而不清楚最終是誰先簽。
?
以上的解決方式有兩大業務需求下是不能滿足的,若會簽的領導不是固定的,即可 以由上一任務審批人提交前隨意進行選擇,另一種是對于會簽業務中,要求若其中一部分領導審批通過,即直接往下走,不需要全部領導進行審批。另外,對于這種 情況下,統計最終領導會簽的結果也是比較困難的,即對審批單的意見是同意還是否決沒有辦法清楚。以上兩種業務需求也是很常見的日常需求,但我們若采用了固 定的流程節點,則不能實現。在這里,可以采用Activiti的節點多實例來處理,以上流程則可以簡化為下:
?
?
何謂多任務實例節點?在Activiti5上的解析則為動態的多任務節 點,可以根據傳入的動態人員數進行動態生成任務。生成的任務數則不固定,可以進行并行會簽,也可以進行串行會簽。會簽任務最終是否需要往下執行,由會簽設 置的規則來進行約束。如我們可以常規去設置“一票通過”、“一票否決”、“少數服務多數”等會簽規則。因此,我們需要在會簽節點上綁定我們的設計規則。會簽規則設置界面如下:
?
通過會簽設計規則,可以清楚最終會簽人員的投票結果。其數據結構如下所示:?
?
會簽任務的定義本身已經由Activiti來實現了,但需要動態傳入動態的人員數
Java代碼 ?<userTask?activiti:assignee="${assignee}"?id="SignTask1"?name="領導會簽">??<extensionElements>??<activiti:taskListener?class="com.hotent.platform.service.bpm.listener.TaskSignCreateListener"?event="create"/>??<activiti:taskListener?class="com.hotent.platform.service.bpm.listener.TaskAssignListener"?event="assignment"/>??<activiti:taskListener?class="com.hotent.platform.service.bpm.listener.TaskCompleteListener"?event="complete"/>??</extensionElements>??<multiInstanceLoopCharacteristics?activiti:elementVariable="assignee"?isSequential="false"?activiti:collection="${taskUserAssignService.getSignUser(execution)}">??<completionCondition>${signComplete.isComplete(execution)}</completionCondition>??</multiInstanceLoopCharacteristics>??</userTask>??
?其中,isSequential為true則為串行會簽,若為 false則為并行會簽,而activiti:collection可以來自我們Spring容器中的接口及方法,表示獲取會簽用戶集 合,taskUserAssignService.getSignUser(execution)。其獲取會簽的用戶值來自兩個方面,一個在界面中指定的會簽人員,另一個在后臺會簽節點上配置的人員。
?
后臺會簽節點人員設置
?
任務審批面上選擇下一任務會簽人員
<completeCondition>為完成會簽的條件signComplete.isComplete(execution),可以在這里根據我們的會簽規則及目前的會簽情況,決定會簽是否完成。其實現如下所示:
最終實現邏輯:
Java代碼 ?@Override??public?boolean?isComplete(ActivityExecution?execution)?{????????????logger.debug("entert?the?SignComplete?isComplete?method...");????????????String?nodeId=execution.getActivity().getId();??????String?actInstId=execution.getProcessInstanceId();????????????ProcessDefinition?processDefinition=bpmService.getProcessDefinitionByProcessInanceId(actInstId);????????????BpmNodeSign?bpmNodeSign=bpmNodeSignService.getByDefIdAndNodeId(processDefinition.getId(),?nodeId);????????????Integer?completeCounter=(Integer)execution.getVariable("nrOfCompletedInstances");????????????Integer?instanceOfNumbers=(Integer)execution.getVariable("nrOfInstances");????????????VoteResult?voteResult=calcResult(bpmNodeSign,?actInstId,?nodeId,?completeCounter,instanceOfNumbers);????????????String?signResult=voteResult.getSignResult();??????boolean?isCompleted=voteResult.getIsComplete();?????????????????????????if(isCompleted){??????????????????????????????bpmService.delLoopAssigneeVars(execution.getId());??????????logger.debug("set?the?sign?result?+?"?+?signResult);????????????????????taskSignDataService.batchUpdateCompleted(actInstId,?nodeId);????????????????????execution.setVariable("signResult_"?+?nodeId?,?signResult);????????????????????Short?status=TaskOpinion.STATUS_PASSED;??????????if(signResult.equals(SIGN_RESULT_REFUSE)){??????????????status=TaskOpinion.STATUS_NOT_PASSED;??????????}????????????????????bpmProStatusDao.updStatus(actInstId,?nodeId,status);????????????????????taskUserAssignService.clearSignUser();??????}????????????return?isCompleted;??}????**???*?根據會簽規則計算投票結果。???*?<pre>???*?1.如果會簽規則為空,那么需要所有的人同意通過會簽,否則不通過。???*?2.否則按照規則計算投票結果。???*?</pre>???*?@param?bpmNodeSign???????會簽規則???*?@param?actInstId?????????流程實例ID???*?@param?nodeId????????????節點id名稱???*?@param?completeCounter???????循環次數???*?@param?instanceOfNumbers?????總的會簽次數。???*?@return???*/??private?VoteResult?calcResult(BpmNodeSign?bpmNodeSign,String?actInstId,String?nodeId,Integer?completeCounter,Integer?instanceOfNumbers){??????VoteResult?voteResult=new?VoteResult();????????????if(instanceOfNumbers==0){??????????return?voteResult;??????}????????????Integer?agreeVotesCounts=taskSignDataService.getAgreeVoteCount(actInstId,?nodeId);??????????????????if(bpmNodeSign==null){????????????????????if(completeCounter<instanceOfNumbers){??????????????return?voteResult;??????????}??????????else{????????????????????????????if(agreeVotesCounts.equals(instanceOfNumbers)){??????????????????return?new?VoteResult(SIGN_RESULT_PASS,true);??????????????}??????????????else{??????????????????return?new?VoteResult(SIGN_RESULT_REFUSE,true);??????????????}??????????}??????}??????????????????Integer?refuseVotesCounts=taskSignDataService.getRefuseVoteCount(actInstId,?nodeId);??????????????????if(BpmNodeSign.VOTE_TYPE_PERCENT.equals(bpmNodeSign.getVoteType())){??????????float?percents=0;????????????????????if(BpmNodeSign.DECIDE_TYPE_PASS.equals(bpmNodeSign.getDecideType())){??????????????percents=agreeVotesCounts/instanceOfNumbers;????????????????????????????if(percents>=bpmNodeSign.getVoteAmount()){??????????????????voteResult=new?VoteResult(SIGN_RESULT_PASS,?true);??????????????}????????????????????????????else?if(completeCounter.equals(instanceOfNumbers)){??????????????????voteResult=new?VoteResult(SIGN_RESULT_REFUSE,?true);??????????????}??????????}????????????????????else{??????????????percents=refuseVotesCounts/instanceOfNumbers;????????????????????????????if(percents>=bpmNodeSign.getVoteAmount()){??????????????????voteResult=new?VoteResult(SIGN_RESULT_REFUSE,?true);??????????????}????????????????????????????else?if(completeCounter.equals(instanceOfNumbers)){??????????????????voteResult=new?VoteResult(SIGN_RESULT_PASS,?true);??????????????}??????????}??????}????????????else{????????????????????if(BpmNodeSign.DECIDE_TYPE_PASS.equals(bpmNodeSign.getDecideType())){????????????????????????????if(agreeVotesCounts>=bpmNodeSign.getVoteAmount()){??????????????????voteResult=new?VoteResult(SIGN_RESULT_PASS,?true);??????????????}????????????????????????????else?if(completeCounter.equals(instanceOfNumbers)){??????????????????voteResult=new?VoteResult(SIGN_RESULT_REFUSE,?true);??????????????}??????????}????????????????????else{????????????????????????????if(refuseVotesCounts>=bpmNodeSign.getVoteAmount()){??????????????????voteResult=new?VoteResult(SIGN_RESULT_REFUSE,?true);??????????????}????????????????????????????else?if(completeCounter.equals(instanceOfNumbers)){??????????????????voteResult=new?VoteResult(SIGN_RESULT_PASS,?true);??????????????}??????????}??????}??????return?voteResult;??}?
新人創作打卡挑戰賽發博客就能抽獎!定制產品紅包拿不停!
總結
以上是生活随笔為你收集整理的Activiti 工作流会签开发设计思路的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。