Liferay7 BPM門戶開發之23: 瞭解內建工作流(Kaleo Workflow)
阿新 • • 發佈:2020-10-13
參考:https://www.cnblogs.com/starcrm/p/6047344.html
Liferay7 BPM門戶開發之23: 瞭解內建工作流(Kaleo Workflow)
Liferay內建的工作流是企業版的功能,雖然簡單粗糙,但依然不支援社群版。既然要用更強大的Activiti來替代它,那就非常有必要學習一下內建工作流的一些思想,以便借鑑。
它的特點:
- 實體的工作流操作可以通過service layer進行整合;
- 需要新增4個額外的欄位來跟蹤流程狀態;
- 通過Service Builder來建立欄位,然後更新service layer;
- 檢視層UI可以顯示實體的工作流狀態。
實體整合邏輯
比如,釋出一個實體類的工作流支援,首先添加註解:
@Component( property = {"model.class.name=com.my.app.package.model.FooEntity"}, service = WorkflowHandler.class )
開發XXXWorkflowHandler,實現Override 三個方法
package com.liferay.docs.foo.workflow; ... public class FooEntityWorkflowHandler extends BaseWorkflowHandler { public static final String CLASS_NAME = FooEntity.class.getName(); @Override public String getClassName() { return CLASS_NAME; } @Override public String getType(Locale locale) { return LanguageUtil.get(locale, "model.resource" + CLASS_NAME); } @Override public Object updateStatus(int status, Map<String, Serializable> workflowContext) throws PortalException, SystemException { long userId = GetterUtil.getLong( (String)workflowContext.get(WorkflowConstants.CONTEXT_USER_ID)); long fooEntityId = GetterUtil.getLong( (String)workflowContext.get( WorkflowConstants.CONTEXT_ENTRY_CLASS_PK)); ServiceContext serviceContext = (ServiceContext)workflowContext.get( "serviceContext"); return FooEntityLocalServiceUtil.updateStatus( userId, fooEntityId, status, serviceContext); } }
為了記錄實體的當前流程狀態,必須要有以下4個欄位(通過Service Builder)
service.xml中新增:
<column name="status" type="int" /> <column name="statusByUserId" type="long" /> <column name="statusByUserName" type="String" /> <column name="statusDate" type="Date" />
比如在更新實體時,自動通過這4個欄位,把實體和流程狀態相關聯:
fooEntity.setStatus(status); fooEntity.setStatusByUserId(user.getUserId()); fooEntity.setStatusByUserName(user.getFullName()); fooEntity.setStatusDate(serviceContext.getModifiedDate(now)); fooEntityPersistence.update(fooEntity);
啟動一個和實體關聯的流程:
WorkflowHandlerRegistryUtil.startWorkflowInstance(fooEntity.getCompanyId(), fooEntity.getGroupId(), fooEntity.getUserId(), FooEntity.class.getName(), fooEntity.getPrimaryKey(), fooEntity, serviceContext);
如果實體屬於Assets,那在為實體設定工作流欄位後,就可以新增任何附加的邏輯方法。
例如,如果想根據其工作流狀態來設定可見性(未審批就不顯示):
if (status == WorkflowConstants.STATUS_APPROVED) { assetEntryLocalService.updateEntry( FooEntity.class.getName(), fooEntityId, fooEntity.getDisplayDate(), null, true, true); } else { assetEntryLocalService.updateVisible( fooEntity.class.getName(), entryId, false); }
為了在檢視中展示,需要設定finder (service.xml)
<finder name="G_S" return-type="Collection"> <finder-column name="groupId"></finder-column> <finder-column name="status"></finder-column> </finder>
實現一個Getter:
public List<FooEntity> getFooEntities(long groupId, int status) throws SystemException { return fooEntityPersistence.findByG_S(groupId, WorkflowConstants.STATUS_APPROVED); } jsp UI: <liferay-ui:search-container-results results="<%=FooEntityLocalServiceUtil.getFooEntities(scopeGroupId, fooEntityId(), Workflowconstants.STATUS_APPROVED, searchContainer.getStart(), searchContainer.getEnd())%>" ...
流程設計器
這個屬於企業版功能,有點弱
這個有點意思:
設定啟動任務的簽收者,
一共有6種類型:
- 建立者
- 某角色
- 角色ID
- 通過一個程式碼段來指定
- 特定的使用者
- 通過資源
在Kaleo中,只有這6種節點,這實在可憐,恐怕要實現複雜的流程將依靠編寫大量的程式碼來實現。
現在知道為啥Kaleo叫workflow而不是叫BPM了吧,因為其不能實現業務流程整合,但實現僅簡單順序流程,還是沒有問題的。
- Condition: 通過指令碼來實現條件邏輯(script包含幾種語言:Beanshell、Drl、Groovy、JavaScript、Python、Ruby),這有點不太友好和方便;
- Fork: 並行處理
- Join: Fork並行後的彙總,這個可以實現會籤,比如說一個節點由領導A、領導B同時稽核才能結束,往下走;
- Join XOR: 異或邏輯的彙總,通俗的說就是實現搶籤,有點像Activiti的候選組的概念,比如說一個節點由領導A、領導B稽核,隨便一個領導先稽核了,節點就結束,往下走;
- State: 狀態節點,比如開始、結束就是屬於這個型別;
- Task: 任務節點,比如審批、填寫表單....
一個XML的描述檔案: