博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Activiti动态设置办理人扩展
阅读量:5051 次
发布时间:2019-06-12

本文共 11615 字,大约阅读时间需要 38 分钟。

Activiti动态设置办理人扩展

作者:邓家海

扩展是要求对Activiti基础有一定的功底的

我们一直在努力,不是为了改变世界,只是不让世界去改变我们。

关键词:Assignee、Candidate users、Candidate groups;setAssignee、taskCandidateUser、taskCandidateGroup

主要解决问题:Activiti动态给任务节点设置办理人。

情景:

我们在做工作流开发,学习的时候一般都有这么一个过程:

第一阶段:最开始学习的时候,喜欢在设计流程的时候写死人名(即)办理人,这个阶段是入门级。而且你也会觉得这样做非常 so easy(方便、简单)。可是慢慢的,你就会发现,每次需要换人,你就要重新设计流程实例(workflow processInstance),一系列的design->Deployment->start processInstance,从此你再也不觉得so easy 了。

第二阶段:于是你开始使用了EL表达式变量,这个阶段代表你已经到了提升阶段。可以使用委托类来设置办理人了,是动态的设置哦。但是,你并没有整合自己的权限系统,用的还是Activiti官方的user表和group表,慢慢的,你发现一旦自己的权限系统角色和用户做了调整,那么自己还得去维护这几个表。

第三阶段:于是,你开始整合自己的权限系统,这个阶段基本是熟练了,可以说是已经完美了。但是这个阶段,每次发送的时候,我们还需要选择一个人去办理他,但是个人觉得,要达到完美状态是不可能的,但是我们还可以自己去做扩展使得它更加的好用,达到我们逾期的目的,(个人观点)。

第四阶段:其实很多人都会去扩展功能的,源码改造,或者模块扩展。在流程部署的时候就设置好办理人,这样,每次发送的时候,我们并不需要去选择办理人。

设置办理人色几种方案

我们先回顾一下,比较传统的动态设置任务办理人的几种方法:

第一种:在流程设置死,这个感觉无需多说,就是在设计流程的时候,在Assignee里面填写我们的办理人姓名或者相关的ID即可。

 

第二种:通过委托类(监听类)设置。在流程设计的时候设置监听类,并且在办理人里面设置EL表达式 ${UserId}(随便自己命名)。然后每次办理的时候选择一个办理人。然后传递一个变量过去,然后下一个环节的监听类会设置办理人。

 

1   Map
map = delegateTask.getVariables();2 3 delegateTask.setAssignee(map.get("UserId").toString());

 

 

 

设置办理人可能有三种方案,

设置办理人的三种方案是有优先级的。

设置办理人优先级:

Assignee>Candidate users>Candidate groups。

设置办理人色几种模式

第一种:指定办理人模式,即设置办理人,就是设置Assignee。Assignee 受让人; 受托人,代理人; 被指定人;办理人只能指定一个人,不能使用逗号分隔。默认执行签收操作taskService.claim(taskId, currentUserId);在ACT_HI_TASKINST和ACT_RU_TASK会产生数据,这两个表里面的Assignee_字段就是设置的办理人姓名或者对象的ID

第二种:设置候选用户,候选用户设置办理人不是很多的情况下使用,而且需要签收,也就是说我们常说的抢件模式,Candidate users  候选用户,设置候选组的前提是没有指定Assignee,(即没有执行签收操作)。设置候选组需要主动签taskService.claim(taskId, currentUserId);

 

 

第三种:这只候选组,这个就是这只办理角色或者办理岗位,适合使用在办理人比较多的情况下,而且涉及到几个部门的情形。Candidate groups  候选组

候选组与候选用户类似,只是要获取候选用户,需要根据候选组找到对应的用户。

 

涉及API:

 

1 taskService.createTaskQuery().taskAssignee(param);

根据用户来查询任务(待办任务)

 

1 taskService.createTaskQuery().taskCandidateUser(param);

根据候选用户查询任务(待签收任务)

 

1 taskService.createTaskQuery().taskCandidateGroup(param);

候选组查询任务(待签收任务)

 

1 TaskService().setAssignee(taskId,userId);

设置办理人 

 

1 taskService().addCandidateGroup(taskId, groupid);

这只候选组,可以添加多个,每次一个addCandidateGroup添加一个

 

1 taskService().addCandidateUser(taskId,userid);

这只候选用户,可以添加多个,每次一个addCandidateUser添加一个

 

1 taskService.claim(taskId, currentUserId);

签收操作。

 

扩展实现

扩展需要添加中间表,我们使用TDD(驱动开发模式)来实现。

需呀增加一个中间表。

流程办理人表(act_comm_taskassignee)

字段

名称

是否为空

备注

ID

主键ID

M

 

SID

节点ID

M

 

assignee

办理人

O

 

rolegroup

候选组

O

 

assigneeType

办理人类型

M

1办理人,2为候选人,3为候选组

activitiname

节点名称

O

 

 

建表SQL:

1 CREATE TABLE `act_comm_taskassignee` ( 2  3   `Id` int(11) NOT NULL AUTO_INCREMENT, 4  5   `Sid` varchar(45) NOT NULL, 6  7   `assignee` varchar(45) DEFAULT NULL, 8  9   `rolegroup` varchar(45) DEFAULT NULL,10 11   `assigneeType` varchar(45) DEFAULT NULL,12 13   `assigneename` varchar(200) DEFAULT NULL,14 15   `activitiname` varchar(255) DEFAULT NULL,16 17   PRIMARY KEY (`Id`),18 19   UNIQUE KEY `Id_UNIQUE` (`Id`)20 21 ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;

 

实体Model:

 

1 /**  2   3  *  4   5  */  6   7 package light.mvc.model.workflow;  8   9   10  11 import javax.persistence.Entity; 12  13 import javax.persistence.Table; 14  15   16  17 import light.mvc.model.base.IdEntity; 18  19   20  21 import org.hibernate.annotations.DynamicInsert; 22  23 import org.hibernate.annotations.DynamicUpdate; 24  25   26  27 /**  28  29  *   30  31  * 项目名称:lightmvc  32  33  * 类名称:FlowAssignee  34  35  * 类描述:  36  37  * 创建人:邓家海  38  39  * 创建时间:2017年8月15日 下午10:01:46  40  41  * 修改人:deng  42  43  * 修改时间:2017年8月15日 下午10:01:46  44  45  * 修改备注:  46  47  * @version   48  49  *   50  51  */ 52  53 @Entity 54  55 @Table(name="act_comm_taskassignee") 56  57 @DynamicInsert(true) 58  59 @DynamicUpdate(true) 60  61 public class FlowAssignee extends IdEntity implements java.io.Serializable { 62  63       private String sid; 64  65       /** 66  67        * @return the activitiname 68  69        */ 70  71       public String getActivitiname() { 72  73            return activitiname; 74  75       } 76  77   78  79       /** 80  81        * @param activitiname the activitiname to set 82  83        */ 84  85       public void setActivitiname(String activitiname) { 86  87            this.activitiname = activitiname; 88  89       } 90  91   92  93       private String assignee; 94  95       private String rolegroup; 96  97       private String activitiname; 98  99       private Integer assigneetype;100 101      102 103       public FlowAssignee(){104 105            super();106 107       }108 109      110 111       public FlowAssignee(String sid,String assignee,String rolegroup,Integer assigneetype,String activitiname){112 113            super();114 115            this.assignee=assignee;116 117            this.sid=sid;118 119            this.rolegroup=rolegroup;120 121            this.assigneetype=assigneetype;122 123            this.activitiname=activitiname;124 125       }126 127  128 129       /**130 131        * @return the sid132 133        */134 135       public String getSid() {136 137            return sid;138 139       }140 141  142 143       /**144 145        * @param sid the sid to set146 147        */148 149       public void setSid(String sid) {150 151            this.sid = sid;152 153       }154 155  156 157       /**158 159        * @return the assignee160 161        */162 163       public String getAssignee() {164 165            return assignee;166 167       }168 169  170 171       /**172 173        * @param assignee the assignee to set174 175        */176 177       public void setAssignee(String assignee) {178 179            this.assignee = assignee;180 181       }182 183  184 185       /**186 187        * @return the rolegroup188 189        */190 191       public String getRolegroup() {192 193            return rolegroup;194 195       }196 197  198 199       /**200 201        * @param rolegroup the rolegroup to set202 203        */204 205       public void setRolegroup(String rolegroup) {206 207            this.rolegroup = rolegroup;208 209       }210 211  212 213       /**214 215        * @return the assigneetype216 217        */218 219       public Integer getAssigneetype() {220 221            return assigneetype;222 223       }224 225  226 227       /**228 229        * @param assigneetype the assigneetype to set230 231        */232 233       public void setAssigneetype(Integer assigneetype) {234 235            this.assigneetype = assigneetype;236 237       }238 239      240 241 }

 

 

核心实现代码:

第一步:根据部署ID来查找所有的节点,目的(找到节点ID):

1 @Test 2  3     public void getDeploymentActivitiIdList(){ 4  5         ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); 6  7         8  9         String deploymantId="57577";10 11                12 13         ProcessDefinition processDefinition=processEngine.getRepositoryService().createProcessDefinitionQuery().deploymentId(deploymantId).singleResult();14 15        16 17         ProcessDefinitionEntity processDefinitionEntity=(ProcessDefinitionEntity)((RepositoryServiceImpl) processEngine18 19                 .getRepositoryService()).getDeployedProcessDefinition(processDefinition.getId());20 21        22 23         List
activityList=processDefinitionEntity.getActivities();24 25 26 27 for(ActivityImpl activiti:activityList) {28 29 System.out.println("节点ID:"+activiti.getId());30 31 32 33 System.out.println("节点名称:"+activiti.getProperty("name"));34 35 }36 37 }

 

 

 

 

 

 

第二步,设置办理人,或者候选组,用户:

 

1 /** 2  3      * 1.设置办理人,一个节点一个办理人,指定办理人模式,不需要签收,办理人模式 4  5      * 2。设置岗位    1)通过角色,查找权限表,签收模式,角色岗位模式 6  7      *          2)通过节点——>办理人,签收模式,节点(一)-->办理人(多)  ,角色岗位模式 8  9      */10 11     @Test12 13     public void setAgneeByActivitiSid(){14 15         Session session = sessionFactory.openSession();16 17         String sid="sid-AEC4023A-DEB1-44C8-8784-C3C10F6B484A";   //节点id18 19         String ActivitiName="总经理";     //节点名称20 21         FlowAssignee fa=new FlowAssignee(); 22 23         fa.setActivitiname(ActivitiName);  24 25         fa.setAssignee("张三");  //办理人26 27         fa.setAssigneetype(1);  //1是指定办理人,2是指定岗位28 29         fa.setSid(sid);30 31         session.save(fa);32 33    34 35        36 37         sid="sid-C8781FAE-02B8-4F8D-9A7D-A8AB4A8CB95A";   //节点id38 39          ActivitiName="经理";     //节点名称40 41         fa=new FlowAssignee(); 42 43         fa.setActivitiname(ActivitiName); 44 45         fa.setActivitiname(ActivitiName);46 47         //fa.setAssignee("李四");  //办理人  设置候选组,不能设置办理人48 49         fa.setRolegroup("产品部");  //办理岗位50 51         fa.setAssigneetype(1);  //1是指定办理人,2是指定岗位52 53         fa.setSid(sid);54 55         session.save(fa);56 57        58 59         session.flush();60 61     }

 

 

 

 

 

第三步:设置启动流程,并设置第一个环节的办理人:

1 @Test 2  3     public void SetAgnee(){ 4  5         ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); 6  7         8  9         String deploymantId="57577";10 11         String pid=processEngine.getRepositoryService().createProcessDefinitionQuery().deploymentId(deploymantId)12 13                 .singleResult().getId();14 15         ProcessInstance pi = processEngine.getRuntimeService()//与正在执行的流程实例和执行对象相关的service16 17         .startProcessInstanceById(pid);//使用流程定义的KEY启动流程实例,key对应helloword。bpmn中对应的ID属性值18 19        20 21         String pdid=pi.getProcessDefinitionId();22 23        24 25         List
taskList=processEngine.getTaskService().createTaskQuery().deploymentId(deploymantId).active().list();26 27 28 29 for(Task task:taskList){30 31 ExecutionEntity execution = (ExecutionEntity)processEngine.getRuntimeService().createExecutionQuery().executionId(task.getExecutionId())32 33 .singleResult();34 35 String activitiId = execution.getActivityId();36 37 38 39 Session session = sessionFactory.openSession();40 41 List
list=session.createQuery("from FlowAssignee where sid='"+activitiId+"'").list();42 43 44 45 if(list.size()>0)46 47 for(FlowAssignee fa:list){48 49 if(fa.getAssigneetype()==1){50 51 processEngine.getTaskService().setAssignee(task.getId(), fa.getAssignee());52 53 }else if(fa.getAssigneetype()==2){54 55 processEngine.getTaskService().addCandidateUser(task.getId(), fa.getAssignee());56 57 }else if(fa.getAssigneetype()==3){58 59 processEngine.getTaskService().addCandidateGroup(task.getId(), fa.getRolegroup());60 61 } 62 63 64 65 66 67 } 68 69 70 71 }72 73 }

 

 

 

到这里,我们的就已经完成了根据节点设置办理人的人:

 

查询一下:

1 @Test 2  3     public void getMyTask(){ 4  5         ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); 6  7         String CandGroup="产品部"; 8  9         Task task=processEngine.getTaskService().createTaskQuery().taskCandidateGroup(CandGroup).active().singleResult();10 11         List
ilList=processEngine.getTaskService().getIdentityLinksForTask(task.getId());12 13 System.out.println("办理人:"+task.getAssignee());14 15 System.out.println("任务ID:"+task.getId());16 17 System.out.println("任务ID:"+task.getName());18 19 for(IdentityLink i:ilList){20 21 System.out.println("组ID:"+i.getGroupId());22 23 System.out.println("用户:"+i.getUserId());24 25 }26 27 28 29 }

 

 

 

 

 

结果是正确的。

 

注意:

设置办理人、候选人、候选组,三个是有有优先级的,不能同时设置,同时设置等价于执行了签收操作。

扩展是要求对Activiti基础有一定的功底的,如果不是很熟悉,请先使用委托类或者直接设置办理人

 

本文主要实现了核心功能,整合到系统功能暂时还没实现。但是有基础的人看完本文就会知道怎么进行扩展。

 

 Activiti交流QQ群:634320089

 

转载于:https://www.cnblogs.com/dengjiahai/p/7536999.html

你可能感兴趣的文章
react之项目目录
查看>>
wamp自定义网站根目录及多站点配置
查看>>
GPT转MBR完整图文教程
查看>>
转载:《TypeScript 中文入门教程》 6、命名空间
查看>>
友情链接
查看>>
JavaScript测试工具
查看>>
QC学习三:Excel数据导入导出QC操作流程
查看>>
Combination Sum II
查看>>
对象数组的练习
查看>>
xamarin android 实现二维码带logo生成效果
查看>>
requirejs amd module load example
查看>>
实验13
查看>>
递归插入排序
查看>>
iOS学习之iOS程序名称及内容国际化(本地化)
查看>>
生产案例、Linux出现假死,怎么回事?
查看>>
树结构(三)---- 多路查找树
查看>>
07深入理解C指针之---指针类型和长度
查看>>
06深入理解C指针之---指针操作和比较
查看>>
SQL Server发送邮件的存储过程
查看>>
【20160924】GOCVHelper 图像处理部分(3)
查看>>