新聞中心
1.概述
我們知道,activiti是一個(gè)不錯(cuò)的流程引擎,它有自身的人員組織架構(gòu),但僅限于用戶、用戶組的管理,流程產(chǎn)生的任務(wù)(UserTask),就涉及到任務(wù)的所屬人(Owner),任務(wù)的執(zhí)行人(assignee),還有任務(wù)的候選人、候選用戶等。而在中國(guó)的流程業(yè)務(wù)需求里,僅靠這塊的人員查找是沒(méi)有辦法滿足目前的業(yè)務(wù)需求的。舉個(gè)請(qǐng)假流程的例子,其流程如下所示:
創(chuàng)新互聯(lián)建站服務(wù)項(xiàng)目包括賓陽(yáng)網(wǎng)站建設(shè)、賓陽(yáng)網(wǎng)站制作、賓陽(yáng)網(wǎng)頁(yè)制作以及賓陽(yáng)網(wǎng)絡(luò)營(yíng)銷(xiāo)策劃等。多年來(lái),我們專(zhuān)注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢(shì)、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,賓陽(yáng)網(wǎng)站推廣取得了明顯的社會(huì)效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到賓陽(yáng)省份的部分城市,未來(lái)相信會(huì)繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!
【說(shuō)明】:其中上級(jí)主管、及所在部門(mén)的領(lǐng)導(dǎo)都跟發(fā)起人所有的組織架構(gòu)有關(guān),這種查找算法可以理解為匯報(bào)線的查找處理。另外在國(guó)內(nèi)的流程處理方案中,還存在一些如其他業(yè)務(wù)的人員查找算法。因此,我們一般都是需要使用我們的業(yè)務(wù)的組織架構(gòu)來(lái)實(shí)現(xiàn)流程的處理。
2.讓Activiti引擎掛接自身的組織架構(gòu)
要實(shí)現(xiàn)流程中的與組織架構(gòu)有關(guān)的整合,我們需要先了解一下目前在哪些業(yè)務(wù)需求上使用了組織架構(gòu)的需求,在我們以往的大量實(shí)施國(guó)內(nèi)的業(yè)務(wù)流程的基礎(chǔ)上,我們總結(jié)有以下幾點(diǎn):
任務(wù)的執(zhí)行人員的分配
任務(wù)的代理
任務(wù)的通知
流程啟動(dòng)的權(quán)限
而Activiti在流程引擎與組織架構(gòu)的整合過(guò)程中,只有第一項(xiàng)跟組織架構(gòu)是有關(guān)的,其他的方面只需要通過(guò)我們自身的擴(kuò)展表來(lái)實(shí)現(xiàn)即可。
2.1 任務(wù)的處理人分配
2.1.1. activiti中對(duì)與人員的組織掛接的默認(rèn)處理
在Activiti中,跟組織架有關(guān)的只有以下幾個(gè)表,我們把它的表結(jié)構(gòu)展示如下:
CREATE TABLE `act_ru_task` ( `ID_` varchar(64) COLLATE utf8_bin NOT NULL DEFAULT '', `REV_` int(11) DEFAULT NULL, `EXECUTION_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, `PROC_INST_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, `PROC_DEF_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, `NAME_` varchar(255) COLLATE utf8_bin DEFAULT NULL, `PARENT_TASK_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, `DESCRIPTION_` varchar(4000) COLLATE utf8_bin DEFAULT NULL, `TASK_DEF_KEY_` varchar(255) COLLATE utf8_bin DEFAULT NULL, `OWNER_` varchar(255) COLLATE utf8_bin DEFAULT NULL, `ASSIGNEE_` varchar(255) COLLATE utf8_bin DEFAULT NULL, `DELEGATION_` varchar(64) COLLATE utf8_bin DEFAULT NULL, `PRIORITY_` int(11) DEFAULT NULL, `CREATE_TIME_` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3), `DUE_DATE_` datetime(3) DEFAULT NULL, `CATEGORY_` varchar(255) COLLATE utf8_bin DEFAULT NULL, `SUSPENSION_STATE_` int(11) DEFAULT NULL, `TENANT_ID_` varchar(255) COLLATE utf8_bin DEFAULT '', `FORM_KEY_` varchar(255) COLLATE utf8_bin DEFAULT NULL, `CREATE_BY_` varchar(64) COLLATE utf8_bin DEFAULT NULL COMMENT '創(chuàng)建人ID', `UPDATE_BY_` varchar(64) COLLATE utf8_bin DEFAULT NULL COMMENT '更新人ID', `UPDATE_TIME_` datetime DEFAULT NULL COMMENT '更新時(shí)間', `SOL_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL COMMENT '業(yè)務(wù)解決方案ID', `AGENT_USER_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL COMMENT '代理人ID', PRIMARY KEY (`ID_`), KEY `ACT_IDX_TASK_CREATE` (`CREATE_TIME_`), KEY `ACT_FK_TASK_EXE` (`EXECUTION_ID_`), KEY `ACT_FK_TASK_PROCINST` (`PROC_INST_ID_`), KEY `ACT_FK_TASK_PROCDEF` (`PROC_DEF_ID_`), CONSTRAINT `ACT_FK_TASK_EXE` FOREIGN KEY (`EXECUTION_ID_`) REFERENCES `act_ru_execution` (`ID_`), CONSTRAINT `ACT_FK_TASK_PROCDEF` FOREIGN KEY (`PROC_DEF_ID_`) REFERENCES `act_re_procdef` (`ID_`), CONSTRAINT `ACT_FK_TASK_PROCINST` FOREIGN KEY (`PROC_INST_ID_`) REFERENCES `act_ru_execution` (`ID_`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;CREATE TABLE `act_ru_identitylink` ( `ID_` varchar(64) COLLATE utf8_bin NOT NULL DEFAULT '', `REV_` int(11) DEFAULT NULL, `GROUP_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, `TYPE_` varchar(255) COLLATE utf8_bin DEFAULT NULL, `USER_ID_` varchar(255) COLLATE utf8_bin DEFAULT NULL, `TASK_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, `PROC_INST_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, `PROC_DEF_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL, PRIMARY KEY (`ID_`), KEY `ACT_IDX_IDENT_LNK_USER` (`USER_ID_`), KEY `ACT_IDX_IDENT_LNK_GROUP` (`GROUP_ID_`), KEY `ACT_IDX_ATHRZ_PROCEDEF` (`PROC_DEF_ID_`), KEY `ACT_FK_TSKASS_TASK` (`TASK_ID_`), KEY `ACT_FK_IDL_PROCINST` (`PROC_INST_ID_`), CONSTRAINT `ACT_FK_ATHRZ_PROCEDEF` FOREIGN KEY (`PROC_DEF_ID_`) REFERENCES `act_re_procdef` (`ID_`), CONSTRAINT `ACT_FK_IDL_PROCINST` FOREIGN KEY (`PROC_INST_ID_`) REFERENCES `act_ru_execution` (`ID_`), CONSTRAINT `ACT_FK_TSKASS_TASK` FOREIGN KEY (`TASK_ID_`) REFERENCES `act_ru_task` (`ID_`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
【說(shuō)明】其中act_ru_task中的owner,assignee為任務(wù)的所屬人與執(zhí)行人,而act_ru_identitylink為任務(wù)的人員關(guān)聯(lián)表,里面的字段,groupId為用戶組Id,userId為用戶Id,taskId為關(guān)聯(lián)的任務(wù)Id,type為用戶參與任務(wù)的類(lèi)型。
若我們?yōu)榱烁雍?jiǎn)化人員對(duì)任務(wù)的參與算法,可以不需要act_ru_identitylink表,進(jìn)而擴(kuò)展自己的參與表,不過(guò)這個(gè)表從目前來(lái)說(shuō)是可以滿足我們對(duì)任務(wù)的人員計(jì)算需求的。
2.1.2.任務(wù)的人員授予
如何通過(guò)activiti原生的api來(lái)實(shí)現(xiàn)人員的授予?首先我們來(lái)說(shuō)授予的時(shí)機(jī),activiti的任務(wù)產(chǎn)生是在流程的狀態(tài)跳至某個(gè)任務(wù)節(jié)點(diǎn)時(shí),其會(huì)產(chǎn)生一條記錄至act_ru_task表中,這時(shí)我們需要在其產(chǎn)生的時(shí)候,通過(guò)流程定義的人員配置屬性,結(jié)合自身的組織架構(gòu)及業(yè)務(wù)查找(如匯報(bào)線)計(jì)算出參與該任務(wù)的人與組,從而把任務(wù)分配給這些用戶。另外是任務(wù)手工進(jìn)行分配授權(quán)。
我們來(lái)說(shuō)第一種,任務(wù)產(chǎn)生時(shí)進(jìn)行人員授權(quán)
activiti提供了任務(wù)的創(chuàng)建事件,所以我們可以在它的這個(gè)事件上定義一個(gè)監(jiān)聽(tīng)即可,如何配置這個(gè)監(jiān)聽(tīng),請(qǐng)參考我們另一個(gè)文章
Activiti的事件機(jī)制及其監(jiān)聽(tīng)處理
關(guān)于activiti的全局事件定義,我們只需要定義以下任務(wù)創(chuàng)建監(jiān)聽(tīng)器(TaskCreateListener),并且獲得任務(wù)的實(shí)體對(duì)象TaskEntity,通過(guò)setAssignee及setOwner改變?nèi)蝿?wù)的執(zhí)行人、任務(wù)的所屬人即可。
taskEntity.setAssignee(nodePath.getAssignee());taskEntity.setOwner(userId);taskEntity.addCandidateUsers(Arrays.asList(uIds));taskEntity.addCandidateGroup(identityInfo.getIdentityInfoId());
現(xiàn)在來(lái)說(shuō)另一種:任務(wù)產(chǎn)生時(shí)進(jìn)行任務(wù)手工分配
這種方式就需要通過(guò)taskService以下api實(shí)現(xiàn)即可
2.2.擴(kuò)展自身的人員查找架構(gòu)
流程的節(jié)點(diǎn)的人員配置很難提供一組通用的配置規(guī)則以實(shí)現(xiàn)用戶的查找,因?yàn)椋覀冎粸楣?jié)點(diǎn)的人員查找設(shè)置config的屬性配置,開(kāi)發(fā)用戶則根據(jù)這些配置實(shí)現(xiàn)對(duì)應(yīng)的定義分類(lèi),并且實(shí)現(xiàn)自己的流程查找方式。
流程的配置方式如下所示:
我們提供一個(gè)總的人員計(jì)算分類(lèi),以使得我們?cè)诹鞒坦?jié)點(diǎn)的人員配置中可以顯示如下的人員配置分類(lèi)列表:
package com.redxun.bpm.core.identity.service;import java.util.ArrayList;import java.util.LinkedHashMap;import java.util.List;import java.util.Map;import org.springframework.beans.factory.InitializingBean;/** * 實(shí)體類(lèi)型分類(lèi)服務(wù)類(lèi) * @author csx * */public class IdentityTypeService implements InitializingBean{ //流程任務(wù)人員計(jì)算服務(wù)類(lèi)映射 private MapidentityCalServicesMap=new LinkedHashMap (); //程任務(wù)人員計(jì)算服務(wù)類(lèi) private List identityCalServices=new ArrayList (); @Override public void afterPropertiesSet() throws Exception { for(IdentityCalService service:identityCalServices){ identityCalServicesMap.put(service.getTypeKey(), service); } } public List getIdentityCalServices() { return identityCalServices; } public void setIdentityCalServices(List identityCalServices) { this.identityCalServices = identityCalServices; } public Map getIdentityCalServicesMap() { return identityCalServicesMap; } } 同時(shí)以根據(jù)流程的節(jié)點(diǎn)配置,實(shí)現(xiàn)用戶的信息計(jì)算,以獲得人員配置的信息,由用戶根據(jù)這個(gè)人員的配置實(shí)現(xiàn)人員的查找,其接口的定義如下:import java.util.Collection;import com.redxun.org.api.model.IdentityInfo;/** * 任務(wù)人員計(jì)算服務(wù)接口類(lèi) * @author mansan * */public interface IdentityCalService { //人員計(jì)算類(lèi)型 public String getTypeKey(); //人員計(jì)算名稱(chēng) public String getTypeName(); //人員計(jì)算描述 public String getDescp(); /** * 計(jì)算節(jié)點(diǎn)返回的人員實(shí)體 * @param idCalConfig * @return */ public Collection calIdentities(IdentityCalConfig idCalConfig); } 其中用戶組的配置及人員查找如下所示:package com.redxun.bpm.core.identity.service;/** * 抽象的實(shí)體計(jì)算服務(wù)類(lèi) * @author csx * */public abstract class AbstractIdentityCalService implements IdentityCalService { //分類(lèi)Key protected String typeKey; //分類(lèi)名稱(chēng) protected String typeName; //分類(lèi)描述 protected String description; //處理的類(lèi)名 protected String handlerClass; public String getTypeKey() { return typeKey; } public void setTypeKey(String typeKey) { this.typeKey = typeKey; } public String getTypeName() { return typeName; } public void setTypeName(String typeName) { this.typeName = typeName; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } @Override public String getDescp() { return this.description; } }
package com.redxun.bpm.core.identity.service.impl;import java.util.ArrayList;import java.util.Collection;import java.util.List;import javax.annotation.Resource;import org.apache.commons.lang3.StringUtils;import com.redxun.bpm.core.identity.service.AbstractIdentityCalService;import com.redxun.bpm.core.identity.service.IdentityCalConfig;import com.redxun.core.constants.MBoolean;import com.redxun.org.api.model.IdentityInfo;import com.redxun.saweb.context.ContextUtil;import com.redxun.sys.org.entity.OsGroup;import com.redxun.sys.org.entity.OsRelType;import com.redxun.sys.org.entity.OsUser;import com.redxun.sys.org.manager.OsGroupManager;import com.redxun.sys.org.manager.OsRelTypeManager;import com.redxun.sys.org.manager.OsUserManager;/** * 用戶組計(jì)算 * @author mansan * */public class GroupCalServiceImpl extends AbstractIdentityCalService{ @Resource private OsGroupManager osGroupManager; @Resource private OsRelTypeManager osRelTypeManager; @Resource private OsUserManager osUserManager; @Override public CollectioncalIdentities(IdentityCalConfig idCalConfig) { OsRelType osRelType=osRelTypeManager.getBelongRelType(); //是否需要計(jì)算用戶 boolean isCalUsers=MBoolean.YES.name().equals(idCalConfig.getIsCalUser()); List identityList=new ArrayList (); //獲得流程的節(jié)點(diǎn)配置信息,并且根據(jù)節(jié)點(diǎn)獲得用戶或組 String jsonConfig=idCalConfig.getJsonConfig(); if(StringUtils.isNotEmpty(jsonConfig)){ String[] groupIds=jsonConfig.split("[,]"); for(String gId:groupIds){ if(isCalUsers){//計(jì)算用戶 List users=osUserManager.getByGroupIdRelTypeId(gId, osRelType.getId()); identityList.addAll(users); }else{//僅計(jì)算其用戶組 OsGroup osGroup=osGroupManager.get(gId); if(osGroup!=null){ identityList.add(osGroup); } } } } return identityList; } }
2.3.自定義查找我的待辦
雖然TaskService有提供按人員的查找任務(wù)API,但從我的個(gè)人來(lái)看,那些是不能滿足我們的查找算法的,因此,很有必要自定義查找我的任務(wù)列表。查找無(wú)非是按Activiti的act_ru_task表來(lái)查,若結(jié)合了用戶對(duì)應(yīng)的用戶組,還需要結(jié)合act_ru_identitylink來(lái)查找。這塊看你的底層的數(shù)據(jù)庫(kù)訪問(wèn)的采用是什么ORM框架,在JSAAS中,我們的界面如下,提供按時(shí)間、事項(xiàng)名稱(chēng)、狀態(tài)等來(lái)查找我的待辦列表,并且分頁(yè)返回,其界面如下:
其查找的自定義Sql如下所示:
開(kāi)源社區(qū)試用DEMO,以及資料,請(qǐng)聯(lián)系QQ:1361783075
網(wǎng)站欄目:在Activiti中如何使用自定義的組織架構(gòu)
新聞來(lái)源:http://www.dlmjj.cn/article/pojooi.html