`

Jbpm4或Activiti5的流程任务分发与汇总

阅读更多

在企业或事业单位,经常需要把一个任务分派给多条线去处理,每条线可以由一个或多个步骤构成,多条线的任务完成后需要再汇总一起于某个任务上。最常见的应用例子就是总经理把一个任务分发下去给多个部门领导,每个部门领导再分发给多个主管,每个主管再分发给多个人处理,然后再汇总给每个主管,每个主管再汇总给部门领导,每个部门领导再汇总至总经理。这就是我们说的任务层层分发,再层层汇总的概念,我们统称为多级分发与汇总。


分发与汇总

以下示意图为该流程在运行过程中的实例产生任务的示例,可以看到分发出来的任务是动态的,并且其后续的任务也会随着产生出来。

该流程在运行过程中的实例产生任务的示例



解决方法一:
我们可以把多个任务线用子流程去实现也可以,这样在分发那里会产生多个子流程,子流程完成后,需要汇总。但若有多级分发与汇总,则需要子流程再嵌套子流程。

解决方法二:
把分发的任务线当作普通的任务来实现,该产生多少个任务可由分发任务决定,这些任务的名称是一样的,但任务实例id不一样,执行人不一样。

在Jbpm4或Activiti5上,动态创建子流程及对子流程的处理上,相对要完成的工作多一些,主要是activity或jbpm4上没有提供这块 api。而动态创建任务在jbpm4或activiti5上也是没有提供的,只有activiti5上提供了一个 taskService.newTask,而该方法产生的新任务则跟流程定义无关,则表示该任务完成后,不能产生后续的任务。在此,我们先提供 activiti5的解决办法。Jbpm4的解决方法可以参照该方式实现,以下为解决方案的步骤:

以下我们来分析如按第二种方法来实现,首先要解决两个问题,一个是分发,另一个是汇总。
分发任务其实就是复制任务的实现,Activiti任务产生后,我们再基于该任务复制新的任务出来以实现任务分发的功能。实现代码如下所示:


/**
* 从一个任务中复制另一任务出来
* @param taskEntity
* @param uIds 用户Id或组织Id或角色Id或岗位ID
* @param userType 值来自TaskUser里的type值
*/
public void newForkTasks(TaskEntity taskEntity,Set<String>uIds,String userType){
//获取当前任务的分发的令牌, value as T_1 or T_1_2
String token=(String)taskEntity.getVariableLocal(TaskFork.TAKEN_VAR_NAME);
if(token==null) token=TaskFork.TAKEN_PRE;
Iterator<String> uIt=uIds.iterator();
int i=0;
while(uIt.hasNext()){
if(i++==0){//原activiti产生的流程仅需要进行人员授权
assignTask(taskEntity,uIt.next(),userType);
//加上分发令牌变量
taskEntity.setVariableLocal(TaskFork.TAKEN_VAR_NAME, token+ "_"+ i);
//同时改变其Execution,以防止当该线的任务进行汇总时,其exectionId及proc_inst_id_相同时,删除该任务引起关联级别的错误
changeTaskExecution(taskEntity);
}else{//扩展产生的流程任务,另需要加上审批意见的记录
ProcessTask processTask=newTask(taskEntity,uIt.next(),userType);

TaskEntity newTask=getTask(processTask.getId());
//加上新的任务至新任务列队,以方便后续的任务回退处理
TaskThreadService.addTask(newTask);

//加上分发令牌变量
taskService.setVariableLocal(processTask.getId(),TaskFork.TAKEN_VAR_NAME, token+ "_"+ i);
TaskOpinion taskOpinion=new TaskOpinion(processTask);
try{
taskOpinion.setOpinionId(UniqueIdUtil.genId());
taskOpinion.setTaskToken(token);
taskOpinionService.add(taskOpinion);
}catch(Exception ex){
logger.error(ex.getMessage());
}
}
}
}


在任务分发时,还包括了分发的令牌处理,令牌的作用是用于区别不同分发线上的任务,如上图,“主管2分发”退回至“部门领导分发 ”时,不会对主管3的任务产生影响,当主管1,主管2汇总任务时,仅产生一个“部门领导汇总”的任务。令牌的变化规则如下图所示:


令牌的变化规则

T令牌格式为:T_层序号,分发的时候,不断加上层序号,如两层分发则令牌变化为T_层序号_层序号。令牌的保存目前是存于任务的变量中,以方便任务获取,作用域仅限于任务。任务的汇总就是需要把多个任务合并回一个任务,实现该目标的方法就是利用任务跳转时,检查其后面的任务节点是否为汇总节点,若是的话,还要看同线上的兄弟节点是否已经完成,若没有完成,则仅是完成该任务则可,若已经完成,则产生后续的汇总节点。实现的代码如下所示:

//若目标节点为空,则代表没有进行自由跳转,同时后续的节点也不为汇总节点
if (destAct == null){
//完成当前任务
taskService.complete(task.getId(), variables);
return;
}
//是否需要去除当前任务的后续跳转线
boolean isNeedRemoveTran=false;

//检查目标任务是否为汇总节点,若为汇总节点,需要拿到当前任务的令牌,检查该令牌对应的TaskFork的已经汇总的任务个数,若目前的任务为最后一个汇总,则删除TaskFork,并且任务进行下一步的跳转,
//若目前任务不是最后一个汇总,则需要更新汇总完成的任务个数,并且只是完成当前任务,不作跳转。
if(bpmNodeSet==null){
bpmNodeSet=bpmNodeSetService.getByActDefIdJoinTaskKey(task.getProcessDefinitionId(), destAct.getId());
}
if(bpmNodeSet!=null){//目前该目标任务为分发汇总
//取当前任务的分发令牌
String token=(String)taskService.getVariableLocal(task.getId(),TaskFork.TAKEN_VAR_NAME);
if(token!=null){
TaskFork taskFork =taskForkService.getByInstIdJoinTaskKeyForkToken(task.getProcessInstanceId(), destAct.getId(), token);
if(taskFork!=null){
if(taskFork.getFininshCount()<taskFork.getForkCount()-1){
//更新完成任务的个数
taskFork.setFininshCount(taskFork.getFininshCount()+1);
taskForkService.update(taskFork);
//更新Token
String[]tokenSplits=token.split("[_]");
if(tokenSplits.length==2){//若为最外层的汇总,格式如T_1,则需要删除该令牌
taskService.setVariableLocal(task.getId(), TaskFork.TAKEN_VAR_NAME, null);
}
isNeedRemoveTran=true;
}else{
taskForkService.delById(taskFork.getTaskForkId());
//更新Token
String[]tokenSplits=token.split("[_]");
if(tokenSplits.length==2){//若为最外层的汇总,格式如T_1,则需要删除该令牌
taskService.setVariableLocal(task.getId(), TaskFork.TAKEN_VAR_NAME, null);
}else if(tokenSplits.length>=3){//更新token,转换如:T_1_1转成T_1
String newToken=token.substring(0, token.lastIndexOf("_"+tokenSplits[tokenSplits.length-1]));
taskService.setVariableLocal(task.getId(), TaskFork.TAKEN_VAR_NAME, newToken);
}
}
}
}
}
//进行锁定
lockTransto.lock();
//记录原来的跳转线
List<PvmTransition> backTransList = new ArrayList<PvmTransition>();
backTransList.addAll(curActi.getOutgoingTransitions());
try{

// 清除当前任务的外出节点
curActi.getOutgoingTransitions().clear();
if(!isNeedRemoveTran){
//创建一个连接
TransitionImpl transitionImpl = curActi.createOutgoingTransition();
transitionImpl.setDestination(destAct);
}
//完成当前任务
taskService.complete(task.getId(), variables);
}
finally{
// 删除创建的输出
curActi.getOutgoingTransitions().clear();
//加回原来的旧连接
curActi.getOutgoingTransitions().addAll(backTransList);
}
//解除锁定。
lockTransto.unlock();


数据结构


表名:BPM_TASK_FORK
功能说明:任务的分发与汇总记录
字段名 字段类型 备注
TASKFORKID NUMBER(18) TASKFORKID
ACTINSTID VARCHAR2(128) 流程实例ID
FORKTASKNAME VARCHAR2(256) 分发任务名称
FORKTASKKEY VARCHAR2(256) 分发任务Key
FORKSN NUMBER(0,0) 分发序号
FORKCOUNT NUMBER(0,0) 分发个数
FININSHCOUNT NUMBER(0,0) 完成个数
FORKTIME DATE 分发时间
JOINTASKNAME VARCHAR2(256) 汇总任务名称
JOINTASKKEY VARCHAR2(256) 汇总任务Key
FORKTOKENS VARCHAR2(512) 分发令牌号 格式如: T_1_1,T_1_2,T_1_3, 或 T_1,T_2,T_3,
FORKTOKENPRE VARCHAR2(64) 格式为T_ 或格式T_1 或T_1_2等

当任务进行分发时,需要在此表加记录,任务完成时,也需要对此表进行记录,任务的分发与汇总设置在BPM_NODE_SET表中也有记录,如下表的红色部分:

表名:BPM_NODE_SET
功能说明:BPM_NODE_SET
字段名 字段类型 备注
SETID NUMBER(18) SETID
DEFID NUMBER(18) 流程定义ID
NODENAME VARCHAR2(128) 节点名
NODEID VARCHAR2(128) activiti 节点ID
FORMTYPE NUMBER(0,0) 0=在线流程表单 1=URL表单
FORMURL VARCHAR2(128) 当表单类型为1时,表单对应的url
ACTDEFID VARCHAR2(127) Act流程发布ID
FORMDEFNAME VARCHAR2(128) FORMDEFNAME
NODETYPE NUMBER(0,0) NODETYPE
JOINTASKKEY VARCHAR2(128) JOINTASKKEY
JOINTASKNAME VARCHAR2(128) JOINTASKNAME
BEFOREHANDLER VARCHAR2(100) 前置处理器
AFTERHANDLER VARCHAR2(100) 后置处理器
ISALLOWBACK NUMBER(0,0) 1=允许 2=不允许
JUMPTYPE VARCHAR2(32) JUMPTYPE
SETTYPE NUMBER(1) 设置类型 0.任务节点1.开始表单2.默认表单
FORMKEY NUMBER(18) 表单KEY


剩下的工作则是进行分发节点的设置与如何根据分发的用户人数进行分发处理。

分发节点的设置类似如下所示:


分发节点的设置

任务的分发其实就是任务复制的过程,可以在TaskCreateListener里进行处理,任务汇总时,需要进行任务的合并,则不是最后一个分支,不进行新的后续的任务产生则可。

分享到:
评论

相关推荐

    node-v7.7.2-linux-x86.tar.xz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    前后端分离的毕业论文(设计)管理系统 (SpringBoot+Vue)

    关于基于SpringBoot和Vue的毕业论文(设计)管理系统,到了一些相关的资源和示例项目,这些资源可能对您的毕业设计有所帮助。 1. **SpringBoot+Vue的三只松鼠商城**: 这个项目是一个基于SpringBoot和Vue的在线购物系统,采用了前后端分离的架构模式。系统实现了管理员模块和用户模块,包括用户管理、地址管理、订单管理、商品管理、支付功能等。这个项目是一个B2C电商平台,使用了MySQL和Redis数据库。 2. **大学生校园社团管理系统**: 这是一个基于SpringBoot和Vue的校园社团管理系统,旨在简化社团报名和组织活动的流程。系统包括用户管理、社团管理、活动信息管理等功能。该项目展示了如何使用前后端分离架构来构建一个校园社团管理系统。 3. **智慧宿舍管理系统**: 这个项目是基于SpringBoot和Vue的智慧宿舍管理系统,旨在提高宿舍管理的效率和便利性。系统包括学生宿舍信息管理、设备监控、安全管理和生活服务等功能。该项目展示了如何使用前后端分离架构来构建一个智能宿舍管理系统。 这些项目可以为您的毕业设计提供灵感和实际的技术指导。您可以

    238.html

    238.html

    基于tensorflow深度学习的地理位置的命名实体识别.zip

    基于tensorflow深度学习的地理位置的命名实体识别.zip

    优秀项目 基于STM32单片机+Python+OpenCV的二自由度人脸跟踪舵机云台源码+详细文档+全部数据资料.zip

    【资源说明】 优秀项目 基于STM32单片机+Python+OpenCV的二自由度人脸跟踪舵机云台源码+详细文档+全部数据资料.zip 【备注】 1、该项目是个人高分项目源码,已获导师指导认可通过,答辩评审分达到95分 2、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 3、本项目适合计算机相关专业(如软件工程、计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载使用,也可作为毕业设计、课程设计、作业、项目初期立项演示等,当然也适合小白学习进阶。 4、如果基础还行,可以在此代码基础上进行修改,以实现其他功能,也可直接用于毕设、课设、作业等。 欢迎下载,沟通交流,互相学习,共同进步!

    文件I/O基础-I.MX6U嵌入式Linux C应用编程学习笔记基于正点原子阿尔法开发板

    文件I/O基础-I.MX6U嵌入式Linux C应用编程学习笔记基于正点原子阿尔法开发板

    基于深度神经网络的图像分类任务.zip

    基于深度神经网络的图像分类任务.zip

    强化学习基准代码,已经针对Tensoflow2.x版本修改,可以直接使用

    强化学习基准代码,已经针对Tensoflow2.x版本修改,可以直接使用

    node-v7.7.4-linux-ppc64.tar.xz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    DZT0227-2010 地质岩心钻探规程.pdf

    DZT0227-2010 地质岩心钻探规程.pdf

    自动泊车之AVM环视系统算法及其框架.pdf

    自动泊车之AVM环视系统算法及其框架

    HTML+CSS+JS精品网页模板H70.rar

    HTML+CSS+JS精品网页模板,设置导航条、轮翻效果,鼠标滑动效果,自动弹窗,点击事件、链接等功能;适用于大学生期末大作业或公司网页的设计制作。响应式网页,可以根据不同的设备屏幕大小自动调整页面布局; 支持如Dreamweaver、HBuilder、Text 、Vscode 等任意html编辑软件进行编辑修改; 支持包括IE、Firefox、Chrome、Safari主流浏览器浏览; 下载文件解压缩,用Dreamweaver、HBuilder、Text 、Vscode 等任意html编辑软件打开,只需更改源代码中的文字和图片可直接使用。图片的命名和格式需要与原图片的名字和格式一致,其他的无需更改。如碰到HTML5+CSS+JS等专业技术问题,以及需要对应行业的模板等相关源码、模板、资料、教程等,随时联系博主咨询。 网页设计和制作、大学生网页课程设计、期末大作业、毕业设计、网页模板,网页成品源代码等,5000+套Web案例源码,主题涵盖各行各业,关注作者联系获取更多源码; 更多优质网页博文、网页模板移步查阅我的CSDN主页:angella.blog.csdn.net。

    高分项目 基于STM32单片机的窗户控制系统APP源代码+项目资料齐全+教程文档.zip

    【资源概览】 高分项目 基于STM32的窗户控制系统APP源代码+项目资料齐全+教程文档.zip高分项目 基于STM32的窗户控制系统APP源代码+项目资料齐全+教程文档.zip高分项目 基于STM32的窗户控制系统APP源代码+项目资料齐全+教程文档.zip 【资源说明】 高分项目源码:此资源是在校高分项目的完整源代码,经过导师的悉心指导与认可,答辩评审得分高达95分,项目的质量与深度有保障。 测试运行成功:所有的项目代码在上传前都经过了严格的测试,确保在功能上完全符合预期,您可以放心下载并使用。 适用人群广泛:该项目不仅适合计算机相关专业(如电子信息、物联网、通信工程、自动化等)的在校学生和老师,还可以作为毕业设计、课程设计、作业或项目初期立项的演示材料。对于希望进阶学习的小白来说,同样是一个极佳的学习资源。 代码灵活性高:如果您具备一定的编程基础,可以在此代码基础上进行个性化的修改,以实现更多功能。当然,直接用于毕业设计、课程设计或作业也是完全可行的。 欢迎下载,与我一起交流学习,共同进步!

    Windows 系统下 Xshell 安装使用教程

    附件是Windows 系统下 Xshell 安装使用教程,仅供交流学习使用,无任何商业目的! Xshell 是一款功能丰富的 SSH 客户端,除了基本的远程命令行访问,还提供了许多高级功能,如标签式界面、强大的脚本功能等。通过实践和探索,你可以更深入地了解 Xshell 的各种功能。

    node-v0.12.17-x86.msi

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    node-v7.1.0-linux-arm64.tar.xz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    基于深度学习的机器翻译模型.zip

    基于深度学习的机器翻译模型.zip

    stm32 嵌入式RTOS

    e-kernel for stm32h7xx, 适用stm32h7xx系列MCU,简洁好用的嵌入式RTOS

    附件1-2-山东煤矿安全监察局_煤矿安全监控系统、煤矿井下作业人员管理系统联网规范.pdf

    附件1-2-山东煤矿安全监察局_煤矿安全监控系统、煤矿井下作业人员管理系统联网规范.pdf

    node-v7.7.2-linux-armv6l.tar.xz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

Global site tag (gtag.js) - Google Analytics