应用场景:在企业或事业单位,经常需要把一个任务分派给多条线去处理,每条线可以由一个或多个步骤构成,多条线的任务完成后需要再汇总一起于某个任务上。如下例子为一个公文下发流程,这个流程就涉及到任务的两级分发。
图一 原流程定义图
图二 执行过程中流程图
以上黄色的代表任务分发,紫黄代表任务汇总。
解决方法一:
我们可以把多个任务线用子流程去实现也可以,这样在分发那里会产生多个子流程,子流程完成后,需要汇总。但若有多级分发与汇总,则需要子流程再嵌套子流程。
解决方法二:
把分发的任务线当作普通的任务来实现,该产生多少个任务可由分发任务决定,这些任务的名称是一样的,但任务实例id不一样,执行人不一样。
在jbpm4或Activiti5上,动态创建子流程及对子流程的处理上,相对要完成的工作多一些,主要是activity或jbpm4上没有提供这块api。而动态创建任务在jbpm4或activiti5上也是没有提供的,只有activiti5上提供了一个taskService.newTask,而该方法产生的新任务则跟流程定义无关,则表示该任务完成后,不能产生后续的任务。在此,我们先提供activiti5的解决办法。Jbpm4的解决方法可以参照该方式实现,以下为解决方案的步骤:
1. 第二种解决方案的关键点在于如何动态创建任务,在这里,我们绕过activiti的API直接对activiti5表进行生成处理,让他生成我们需要流程数据。
如下所示:
/** * 按任务Id,复制另一会签任务出来 * @param orgTaskId * @param assignee * @return */ public ProcessTask newTask(String orgTaskId,String assignee) { String newExecutionId=UniqueIdUtil.getNextId(); String newTaskId=UniqueIdUtil.getNextId(); TaskEntity taskEntity=getTask(orgTaskId); ExecutionEntity executionEntity=null; if(taskEntity.getExecution()!=null){ executionEntity=taskEntity.getExecution(); }else{ executionEntity=getExecution(taskEntity.getExecutionId()); } ProcessExecution newExecution=new ProcessExecution(executionEntity); newExecution.setId(newExecutionId); ProcessTask newTask=new ProcessTask(taskEntity); newTask.setId(newTaskId); newTask.setExecutionId(newExecutionId); newTask.setCreateTime(new Date()); newTask.setAssignee(assignee); newTask.setOwner(assignee); ProcessTaskHistory newTaskHistory=new ProcessTaskHistory(taskEntity); newTaskHistory.setAssignee(assignee); newTaskHistory.setStartTime(new Date()); newTaskHistory.setId(newTaskId); newTaskHistory.setOwner(assignee); executionDao.add(newExecution); taskDao.insertTask(newTask); taskHistoryDao.add(newTaskHistory); return newTask; }
说明:以上代码写在BpmService类里,关键是从原来的任务中复制一份新的数据出来,同时需要复制其Execution的记录以及执行历史的记录。
2. 需要记录分发与汇总的节点
所以在流程节点的设置上,我们提供了以下的配置实体。
public class BpmNodeSet extends BaseModel { /** * 在线表单 */ public static Short FORM_TYPE_ONLINE=0; /** * URL表单 */ public static Short FORM_TYPE_URL=1; /** * 普通任务节点 */ public static Short NODE_TYPE_NORMAL=0; /** * 分发任务节点 */ public static Short NODE_TYPE_FORK=1; // setId protected Long setId; // 流程定义ID protected Long defId; // 节点名 protected String nodeName; // Activiti流程定义ID protected String actDefId; // 节点ID protected String nodeId; // 表单类型(0:在线表单,1:URL表单) protected Short formType=-1; // 表单URL protected String formUrl; // 表单定义ID protected Long formDefId; // 表单名称 protected String formDefName; /** * 任务类型: * 0=普通任务 * 1=分发任务 */ protected Short nodeType; /** * 当任务类型=1时,可以指定汇总任务Key */ protected String joinTaskKey; /** * 当任务类型=1时,指定的汇总任务名称 */ protected String joinTaskName; ... }
然后在任务的创建及完成的事件里加上监听若当前的任务为分发任务,则动态产生分发的任务。若为汇总任务,则只产生最后一个汇总,以免得由Activiti产生多个汇总任务。
在监听事件创建分发任务(TaskCreateListener.java类)
BpmNodeSet bpmNodeSet=bpmNodeSetService.getByActDefIdNodeId(actDefId, nodeId); if(bpmNodeSet!=null && BpmNodeSet.NODE_TYPE_FORK.equals(bpmNodeSet.getNodeType())){//当前任务为分发任务 Map<String,List<String>> nodeUserMap=taskUserAssignService.getNodeUserMap(); //若当前的线程里包含了该任务对应的执行人员列表,则任务的分发用户来自于此 if(nodeUserMap!=null && nodeUserMap.get(nodeId)!=null){ List<String> userIds=nodeUserMap.get(nodeId); bpmService.newForkTasks((TaskEntity)delegateTask, userIds); //产生分发记录,以方便后续的任务汇总处理 taskForkService.newTaskForks(delegateTask,bpmNodeSet.getJoinTaskName(), bpmNodeSet.getJoinTaskKey(), userIds.size()); }else{ ForkUser forkUser=taskUserAssignService.getForkUser(); if(forkUser!=null){ bpmService.newForkTasks((TaskEntity)delegateTask, forkUser.getForkUserIdsAsList()); } } }
以上代码中,分发任务的创建对应的人员来自表单中指定的人员。
任务汇总时,我们需要记录完成的情况,若为汇总节点,我们会根据汇总完成的情况,进行处理,若汇总的任务尚没有全部完成,后续产生的汇总任务我们则采用删除策略,该方法定义在BpmService类中。
/** * 检查及删除重复的汇总任务 * @param processInstanceId */ public void deleteRepeatJoinTask(String processInstanceId){ List<TaskEntity> taskList=getTasks(processInstanceId); for(TaskEntity task:taskList){ //判断后续的节点是否为汇总节点,若是,则需要检查是否需要产生后续的任务 BpmNodeSet joinNodeSet=bpmNodeSetService.getByActDefIdJoinTaskKey(task.getProcessDefinitionId(), task.getTaskDefinitionKey()); if(joinNodeSet!=null){ TaskFork taskFork=taskForkService.getByInstIdJoinTaskKey(task.getProcessInstanceId(), task.getTaskDefinitionKey()); if(taskFork!=null){ if(taskFork.getFininshCount()<taskFork.getForkCount()-1){ taskService.deleteTask(task.getId()); //更新完成任务的个数 taskFork.setFininshCount(taskFork.getFininshCount()+1); taskForkService.update(taskFork); }else{ taskForkService.delById(taskFork.getTaskForkId()); } } } } }
最终实现的效果可以如下所示:
更多资讯请加QQ了解3102760881
相关推荐
2. **jBPM4和jBPM5的改进** - 可能会讨论这些版本引入的新特性,如基于JPA的持久化、增强的GUI工具、流程建模语言BPMN 2.0的支持等。 3. **Activiti5** - Activiti5是一个基于jBPM设计理念的流程引擎,可能会介绍它...
与此同时,Activiti5作为jBPM的一个分支,保留了jBPM4的许多优点,但也引入了新的特性,如更简洁的API,更强大的流程设计器,以及对Web服务和社交网络集成的支持。 总结来说,jBPM与Activiti都是为了提高企业流程...
5. **数据库存储(Persistence)**:jbpm4将流程实例、任务和其他相关数据持久化存储,以便在系统间或不同时间点恢复和跟踪流程状态。 在这个“jbpmDemo”压缩包中,可能包含以下组件: 1. **流程定义文件(.bpmn...
在实际应用中,开发者需要了解JBPM4的工作原理,包括流程实例、任务实例、信号和事件的概念,以及如何通过API或服务任务与外部系统交互。熟悉Maven的使用也是至关重要的,包括理解POM文件的结构、如何添加和排除依赖...
总的来说,这个主题资料包提供了jbpm4和jbpm5的基础知识、实战经验和用户操作指导,对于想要学习或深化jbpm流程管理框架理解的开发者非常有价值。通过学习这些文档,开发者可以掌握jbpm的核心概念,熟练地设计和部署...
TomBaeyens离开的具体原因尚不清楚,但他的离开产生了两个结果:一是jBPM的下一个版本jBPM5完全放弃了jBPM4的基础代码,基于Drools Flow重头来过;二是TomBaeyens加入Alfresco后很快推出了新的基于jBPM4的开源工作流...
- **JBPM4_HIST_TASK**:流程任务实例的历史记录。 - **JBPM4_HIST_VAR**:流程变量的历史记录。 - **JBPM4_ID_GROUP**:组表,用于权限管理。 - **JBPM4_ID_MEMBERSHIP**:用户与角色关联表。 - **JBPM4_ID_USER**...
通过编写Java代码并与jbpm4引擎交互,可以实现流程的动态启动、任务分配、流程监控等功能,从而提高工作效率,规范业务流程。而上述提供的代码和文档,就是实现这一目标的基础。对于开发者来说,深入学习和理解这些...
在这个教程中,我们将深入理解jbpm4的工作原理以及如何将其与SSH框架集成,以构建一个完整的业务流程管理系统。 jbpm4是Java Business Process Management的第四个版本,它是一个开源的工作流和业务流程管理(BPM)...
Activiti 是一个开源的工作流系统,它基于 jBPM4 技术,为企业的业务流程自动化提供了强大的支持。本10分钟入门指南旨在帮助初学者快速理解 Activiti 的基本概念和API接口,通过一个简单的业务流程示例进行讲解。 ...
Activiti 是由 jBPM 的创建者 Tom Baeyens 离开 JBoss 之后建立的项目,构建在开发 jBPM 版本 1 到 4 时积累的多年经验的基础之上,旨在创建下一代的 BPM 解决方案。 Activiti是一个开源的工作流引擎,它实现了...
### 工作流系统技术选型可行性分析:JBPM4与JBPM5 #### 一、引言 在数字化转型的背景下,工作流系统成为提高组织效率的关键技术之一。医院作为一个复杂的组织机构,其内部流程的优化对于提升服务质量至关重要。...
20. **ACT_RU_IDENTITYLINK** - 身份联系表,处理运行时的用户、用户组与任务或流程实例的关联。 21. **ACT_RU_JOB** - 运行中的任务表,存储定时任务和异步任务的相关信息。 22. **ACT_RU_TASK** - 运行时任务...
总的来说,掌握BPMN、jBPM和Activiti不仅可以提升个人在工作流管理领域的专业技能,也有助于企业实现高效、灵活的业务流程管理。通过深入学习这三个工具,你将能够为企业构建出更加智能和自动化的业务流程,提高工作...
### Activiti流程学习总结 #### 一、工作流的基本概念 在深入了解Activiti之前,我们需要先理解工作流的概念。工作流是一种将业务过程部分或全部自动化的方法,它可以帮助组织提高工作效率,减少错误,并且能够更...
在JBoss JBPM4中,一个流程通常由一系列任务组成,这些任务可以由系统自动执行,也可以由人参与完成。请假流程就是一个典型的人工参与的任务流程,包括请假申请、审批等步骤。在这个示例中,我们将探讨以下几个关键...
在jbpm4web中,用户还可以进行流程控制操作,如驳回任务回到上一步骤,或者在某些情况下终止流程。这些控制功能有助于适应业务变化,确保流程的灵活性。 5. **流程监控**: 为了评估流程效率和找出改进点,jbpm4...