1.概述
我们知道,activiti是一个不错的流程引擎,它有自身的人员组织架构,但仅限于用户、用户组的管理,流程产生的任务(UserTask),就涉及到任务的所属人(Owner),任务的执行人(assignee),还有任务的候选人、候选用户等。而在中国的流程业务需求里,仅靠这块的人员查找是没有办法满足目前的业务需求的。举个请假流程的例子,其流程如下所示:
【说明】:其中上级主管、及所在部门的领导都跟发起人所有的组织架构有关,这种查找算法可以理解为汇报线的查找处理。另外在国内的流程处理方案中,还存在一些如其他业务的人员查找算法。因此,我们一般都是需要使用我们的业务的组织架构来实现流程的处理。
2.让Activiti引擎挂接自身的组织架构
要实现流程中的与组织架构有关的整合,我们需要先了解一下目前在哪些业务需求上使用了组织架构的需求,在我们以往的大量实施国内的业务流程的基础上,我们总结有以下几点:
- 任务的执行人员的分配
- 任务的代理
- 任务的通知
- 流程启动的权限
而Activiti在流程引擎与组织架构的整合过程中,只有第一项跟组织架构是有关的,其他的方面只需要通过我们自身的扩展表来实现即可。
2.1 任务的处理人分配
2.1.1. activiti中对与人员的组织挂接的默认处理
在Activiti中,跟组织架有关的只有以下几个表,我们把它的表结构展示如下:
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 '创建人ID', `UPDATE_BY_` varchar(64) COLLATE utf8_bin DEFAULT NULL COMMENT '更新人ID', `UPDATE_TIME_` datetime DEFAULT NULL COMMENT '更新时间', `SOL_ID_` varchar(64) COLLATE utf8_bin DEFAULT NULL COMMENT '业务解决方案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;
【说明】其中act_ru_task中的owner,assignee为任务的所属人与执行人,而act_ru_identitylink为任务的人员关联表,里面的字段,groupId为用户组Id,userId为用户Id,taskId为关联的任务Id,type为用户参与任务的类型。
若我们为了更加简化人员对任务的参与算法,可以不需要act_ru_identitylink表,进而扩展自己的参与表,不过这个表从目前来说是可以满足我们对任务的人员计算需求的。
2.1.2.任务的人员授予
如何通过activiti原生的api来实现人员的授予?首先我们来说授予的时机,activiti的任务产生是在流程的状态跳至某个任务节点时,其会产生一条记录至act_ru_task表中,这时我们需要在其产生的时候,通过流程定义的人员配置属性,结合自身的组织架构及业务查找(如汇报线)计算出参与该任务的人与组,从而把任务分配给这些用户。另外是任务手工进行分配授权。
我们来说第一种,任务产生时进行人员授权
activiti提供了任务的创建事件,所以我们可以在它的这个事件上定义一个监听即可,如何配置这个监听,请参考我们另一个文章
关于activiti的全局事件定义,我们只需要定义以下任务创建监听器(TaskCreateListener),并且获得任务的实体对象TaskEntity,通过setAssignee及setOwner改变任务的执行人、任务的所属人即可。
taskEntity.setAssignee(nodePath.getAssignee()); taskEntity.setOwner(userId); taskEntity.addCandidateUsers(Arrays.asList(uIds)); taskEntity.addCandidateGroup(identityInfo.getIdentityInfoId());
现在来说另一种:任务产生时进行任务手工分配
这种方式就需要通过taskService以下api实现即可
2.2.扩展自身的人员查找架构
流程的节点的人员配置很难提供一组通用的配置规则以实现用户的查找,因为,我们只为节点的人员查找设置config的属性配置,开发用户则根据这些配置实现对应的定义分类,并且实现自己的流程查找方式。
流程的配置方式如下所示:
我们提供一个总的人员计算分类,以使得我们在流程节点的人员配置中可以显示如下的人员配置分类列表:
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; /** * 实体类型分类服务类 * @author csx * */ public class IdentityTypeService implements InitializingBean{ //流程任务人员计算服务类映射 private Map<String, IdentityCalService> identityCalServicesMap=new LinkedHashMap<String, IdentityCalService>(); //程任务人员计算服务类 private List<IdentityCalService> identityCalServices=new ArrayList<IdentityCalService>(); @Override public void afterPropertiesSet() throws Exception { for(IdentityCalService service:identityCalServices){ identityCalServicesMap.put(service.getTypeKey(), service); } } public List<IdentityCalService> getIdentityCalServices() { return identityCalServices; } public void setIdentityCalServices(List<IdentityCalService> identityCalServices) { this.identityCalServices = identityCalServices; } public Map<String, IdentityCalService> getIdentityCalServicesMap() { return identityCalServicesMap; } } 同时以根据流程的节点配置,实现用户的信息计算,以获得人员配置的信息,由用户根据这个人员的配置实现人员的查找,其接口的定义如下: import java.util.Collection; import com.redxun.org.api.model.IdentityInfo; /** * 任务人员计算服务接口类 * @author mansan * */ public interface IdentityCalService { //人员计算类型 public String getTypeKey(); //人员计算名称 public String getTypeName(); //人员计算描述 public String getDescp(); /** * 计算节点返回的人员实体 * @param idCalConfig * @return */ public Collection<IdentityInfo> calIdentities(IdentityCalConfig idCalConfig); } 其中用户组的配置及人员查找如下所示: package com.redxun.bpm.core.identity.service; /** * 抽象的实体计算服务类 * @author csx * */ public abstract class AbstractIdentityCalService implements IdentityCalService { //分类Key protected String typeKey; //分类名称 protected String typeName; //分类描述 protected String description; //处理的类名 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; /** * 用户组计算 * @author mansan * */ public class GroupCalServiceImpl extends AbstractIdentityCalService{ @Resource private OsGroupManager osGroupManager; @Resource private OsRelTypeManager osRelTypeManager; @Resource private OsUserManager osUserManager; @Override public Collection<IdentityInfo> calIdentities(IdentityCalConfig idCalConfig) { OsRelType osRelType=osRelTypeManager.getBelongRelType(); //是否需要计算用户 boolean isCalUsers=MBoolean.YES.name().equals(idCalConfig.getIsCalUser()); List<IdentityInfo> identityList=new ArrayList<IdentityInfo>(); //获得流程的节点配置信息,并且根据节点获得用户或组 String jsonConfig=idCalConfig.getJsonConfig(); if(StringUtils.isNotEmpty(jsonConfig)){ String[] groupIds=jsonConfig.split("[,]"); for(String gId:groupIds){ if(isCalUsers){//计算用户 List<OsUser> users=osUserManager.getByGroupIdRelTypeId(gId, osRelType.getId()); identityList.addAll(users); }else{//仅计算其用户组 OsGroup osGroup=osGroupManager.get(gId); if(osGroup!=null){ identityList.add(osGroup); } } } } return identityList; } }
2.3.自定义查找我的待办
虽然TaskService有提供按人员的查找任务API,但从我的个人来看,那些是不能满足我们的查找算法的,因此,很有必要自定义查找我的任务列表。查找无非是按Activiti的act_ru_task表来查,若结合了用户对应的用户组,还需要结合act_ru_identitylink来查找。这块看你的底层的数据库访问的采用是什么ORM框架,在JSAAS中,我们的界面如下,提供按时间、事项名称、状态等来查找我的待办列表,并且分页返回,其界面如下:
其查找的自定义Sql如下所示:
<select id="getByUserIdRelTypeId" parameterType="java.util.Map" resultMap="BpmTask">
SELECT V.* FROM(
SELECT T.* FROM ACT_RU_TASK T WHERE T.ASSIGNEE_=#{userId}
UNION
SELECT T.* FROM ACT_RU_TASK T LEFT JOIN ACT_RU_IDENTITYLINK I ON T.ID_=I.TASK_ID_ WHERE I.USER_ID_=#{userId} AND I.TYPE_='candidate' AND T.ASSIGNEE_ IS NULL
UNION
SELECT T.* FROM ACT_RU_TASK T,ACT_RU_IDENTITYLINK I,OS_REL_INST R WHERE T.ASSIGNEE_ IS NULL AND T.ID_=I.TASK_ID_ AND I.GROUP_ID_=R.PARTY1_ and R.PARTY2_=#{userId} and I.TYPE_='candidate' AND R.REL_TYPE_ID_=#{relTypeId}
) V
WHERE 1=1
<if test="name!=null">
and NAME_ like #{name}
</if>
<if test="description!=null">
and DESCRIPTION_ like #{description}
</if>
<if test="createtime1">
and CREATE_TIME_ >= #{createtime1}
</if>
<if test="createtime2">
and CREATE_TIME_ <= #{createtime2}
</if>
<if test="orderByClause!=null">
ORDER BY ${orderByClause}
</if>
</select>
更多的关于任务的人员及其他人员的整合处理细节,请参考在线的演示版本:
相关推荐
在 Activiti 的中文用户手册中,你将找到以下关键知识点: 1. **Activiti简介**:了解Activiti的基本概念,包括其设计理念、架构和主要特性。Activiti不仅支持BPMN 2.0标准,还提供了一个直观的流程设计器,使得...
在“activiti第一天2_2”的学习中,我们将深入探讨Activiti的核心概念和关键特性,为后续四天的学习打下坚实的基础。 首先,了解Activiti的基本架构是至关重要的。Activiti采用了模型驱动的设计,允许用户通过图形...
尽管Activiti自带了一些基础的组织机构管理功能,但为了满足更复杂的需求,通常会结合自定义的身份认证系统进行集成。 总之,Activiti 是一个强大且易用的BPM框架,它通过BPMN标准提供流程建模,利用数据库存储和...
在“activiti第一天2_1”的学习中,我们即将深入理解Activiti的核心概念、架构以及如何开始使用它。这个学习过程分为五个阶段,确保逐步掌握Activiti的所有关键要素。 首先,我们需要了解什么是工作流。工作流是指...
流程定义通常存储在数据库中,可以通过XML文件导入或在Activiti Modeler中创建。 7. **数据库支持**: Activiti 5.8 支持多种数据库,包括MySQL、Oracle、PostgreSQL等,提供了一种灵活的方式来存储和管理流程实例...
- **插件机制**:Activiti采用插件式架构,方便添加新的功能模块或替换现有组件。 - **RESTful API**:提供了丰富的RESTful API接口,便于与其他系统进行集成。 - **Spring集成**:与Spring框架深度集成,简化了依赖...
该书还覆盖了Activiti与外部系统的集成,包括通过WS/REST API以及数据库接口,使得Activiti能够作为一个核心组件融入到更广泛的企业IT架构中。无论是对于希望深入了解Activiti的开发者,还是寻求提高业务流程效率的...
这使得 Activiti 可以无缝嵌入到企业现有的 IT 基础架构中。 8. **安全性与权限**:Activiti-app 支持用户认证和授权,可以根据角色和组织结构设置访问控制,确保敏感流程信息的安全。 9. **自定义和扩展性**:...
虽然Activiti提供了基础的组织机构管理功能,但在实际应用中,可能需要自定义更复杂的用户认证和权限管理模块来满足特定需求。 在第二天的学习中,可能会涉及到更多高级概念,如连线、排他网关(Exclusive Gateway...
任务组(Groups)在Activiti中用于组织用户,这些组可以被用来指定任务的候选人或参与者。通过任务组,可以实现任务的并发处理和角色权限管理。例如,一个任务可以被分配给一个销售团队,团队内的所有成员都能看到并...
在Activiti中,你可以使用Alfresco提供的 Activiti Modeler 或直接编辑XML文件来创建流程定义。 接下来,我们要在代码中部署这个流程定义。通过Activiti API,你可以将流程定义加载到Activiti引擎中,使其变为可...
在实际应用中,为了满足更复杂的身份管理和认证需求,通常需要自定义开发相关功能,因为Activiti自带的组织机构管理功能较为基础。而act_ge_bytearray和act_ge_property表则用于存储非流程相关的数据和系统级属性。 ...
在组织结构管理方面,Activiti提供了一系列表(如act_id_group用户组信息表、act_id_user用户信息表等),但建议对于用户认证方面的使用需求,由于组件自带的功能可能过于简单,建议进行自定义开发以满足特定需求。...
在MyEclipse中使用Activiti Designer,开发者可以快速构建流程定义,将其部署到Activiti工作流引擎中运行,从而实现业务流程自动化。此外,Activiti Designer还提供了丰富的API和自定义扩展点,允许开发人员根据实际...
Activiti 是一个开源的工作流程和业务自动化引擎,它在企业级应用中被广泛使用来管理业务流程。在5.15版本中,Activiti 提供了与 Spring MVC 的集成,使得开发者可以方便地将工作流功能融入到基于Spring MVC的Web...
Activiti 5.22 是这个工作流引擎的一个重要版本,它基于Java技术,支持服务导向架构(SOA),并且与Spring框架高度集成,使得在Java环境中部署和使用变得非常便捷。以下是一些关键特性: 1. **流程定义**: Activiti...
在activiti-master中,你可能会发现如Activiti Designer(一个流程图设计工具)、Activiti Explorer(用于管理和监控流程实例的Web应用)等组件的源代码。 mean3x7标签可能指的是这个压缩包中包含了与MEAN(MongoDB...
这些表通常用于基本的组织机构管理,但在实际使用中可能需要自定义功能来满足更多需求。 综上所述,Activiti是一个功能强大且灵活的开源业务流程管理框架,能够帮助企业高效地管理和执行复杂的业务流程。通过其提供...
在实际应用中,尽管Activiti提供了基础的组织机构管理功能,但往往需要根据具体业务需求自定义开发更复杂的用户认证系统。 综上所述,Activiti工作流提供了一套全面的工具集,从流程设计到执行、监控和历史追踪,为...
青锋后台管理系统是一种基于springboot,layui,activiti工作流,实现了代码生成器,自定义表格,拖曳可视化报表大屏的后台脚手架系统,包含基础架构的常用功能,可以拿来即用声明:代码开源相邻难免不足之处,还望...