JBPM4.4 使用泳道动态指定下一个任务节点任务人的两种方式之一 (assignment-handler)

本文介绍了在JBPM4.4中如何使用泳道和assignment-handler动态指定任务节点的下一任执行人。流程涉及多级部门任务发布,包括任务的申请、审核和完成过程。通过示例jbpm.xml代码和AssignTask.java类的讲解,阐述了如何根据部门成员的角色动态确定任务审批人。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

近期在学习  JBPM  工作流,上一篇博文描述了实现一个简单请假工作流的过程

之后花了好几天的时间来实现一个基于泳道的任务发布工作流:

简要流程如下:

 

某级部门(暂定为A级部门)manager 启动一个新任务发布工作流

通过泳道将该任务发布给A级部门的子部门(B)和孙子部门(C)

 

B和C部门的所有成员都能够看到该任务,并可以点击链接查看该任务的详细信息

一旦有成员apply 该任务,则其他人都不能再次apply该任务

如果该成员只是C级部门的成员,不具有manager 的角色,则该次申请还需要提交给C级部门的经理进行审核。

如果该成员是C级部门的经理,则不需要审核,直接进入tryfinish 待办任务

 

当获取了任务的assignee 认为自己完成了该项任务时,则可以提交tryfinish 任务,然后该请求进入工作流发布人的待办任务列表中

如果工作流发布者批准该次任务完成,则该次工作流结束。否则重新进入tryfinish 环节。

具体jbpm。xml  代码如下所示

 

 

 

 

 

 

<?xml version="1.0" encoding="UTF-8"?>

<process name="assignment" xmlns="http://jbpm.org/4.4/jpdl">
    <swimlane candidate-groups="#{assignGroup}" name="assignmentswin">
    </swimlane>
   <start g="336,33,64,58" name="start1">
      <transition to="assign"/>
   </start>
   <task assignee="#{assignOwner}" form="/SSH/LeaveJSP/assign_add.jsp" g="322,107,80,40" name="assign">
      <transition to="tryAssign"/>
   </task>
   <task form="/SSH/LeaveJSP/assign_trytake.jsp" g="323,180,92,52" name="tryAssign" swimlane="assignmentswin">
      <transition to="exclusive1"/>
   </task>
   <decision expr="#{role=='manager'? 'totryFinish':'tomanagerAprove'}" g="351,278,48,48" name="exclusive1">
      <transition g="-92,-18" name="tomanagerAprove" to="managerAprove"/>
      <transition to="tryFinish" name="totryFinish"/>
   </decision><!--
   <task assignee="#{assignManager}" form="leaveAction!toAssign_Manager.action" g="118,287,92,52" name="managerAprove">
   -->
  
    <task  form="leaveAction!toAssign_Manager.action" g="118,287,92,52" name="managerAprove">
  
     <assignment-handler class="com.util.AssignTask"> 
    <field name="assignee"> 
        <string value="1"/> 
     </field> 
  </assignment-handler> 
   
      <transition g="-61,-18" name="approveTry" to="tryFinish"/>
      <transition g="-59,-18" name="notApproveTry" to="tryAssign"/>
   </task>
   <task form="leaveAction!toAssign_tryFinish.action" g="332,464,92,52" name="tryFinish" swimlane="assignmentswin">
      <transition to="ifFinish"/>
   </task>
   <end g="355,711,48,48" name="end1"/>
   <task assignee="#{assignOwner}" form="leaveAction!toAssign_ifFinish.action" g="339,611,92,52" name="ifFinish">
      <transition name="AcceptFinish" to="end1" g="-65,-18"/>
      <transition g="504,599:-82,-18" name="NotAcceptFinish" to="tryFinish"/>
   </task>
</process>

 

 

 

 

 

这个版本的jbpm。xml 文件采用了 assignment-handler  来实现根据C级部门成员apply 任务时确定C级部门的manager ,即确定批准C级成员apply 该任务的manager。

我这次的工作就花了很长的时间在确定manager 上。

当C级部门成员apply 该才任务时,工作流进入了部门manager 批准的环节,在这个环节中使用到了 assignment-handler,通过该环节的executionId来获取到该次工作流的历史任务列表。然后从历史人物列表的最后一个历史任务中取到apply 任务的C级部门成员的assign name。取到了上一个任务的assign name ,也就可以将 assign 所在部门的manager name 放入到当前任务的assingee 。从而确定了当前任务的assignee。

 

下面是AssignTask   的代码。

AssignTask.java    

 

 

package com.util;

import java.util.List;

import org.jbpm.api.ProcessEngine;
import org.jbpm.api.TaskService;
import org.jbpm.api.history.HistoryTask;
import org.jbpm.api.model.OpenExecution;
import org.jbpm.api.task.Assignable;
import org.jbpm.api.task.AssignmentHandler;
import org.jbpm.api.task.Task;
import org.jbpm.pvm.internal.history.model.HistoryTaskImpl;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.model.User;
import com.service.UserService;
import com.service.imp.UserServiceImp;

public class AssignTask implements AssignmentHandler{
    String assignee;
 private UserService userService;
 private ProcessEngine processEngine;
 
 @Override
 public void assign(Assignable assignable, OpenExecution openExecution) throws Exception {
 
 ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
processEngine=(ProcessEngine) context.getBean("processEngine");
userService=(UserService)context.getBean("userService");
 
    String executionId= openExecution.getId();
    System.out.println("executionId-----------"+executionId);
    List <HistoryTask>list = processEngine.getHistoryService().createHistoryTaskQuery().executionId(executionId).list();
    String tryAssignUserName="";
    for(int i=0;i<list.size();i++){
     HistoryTaskImpl taskImpl=(HistoryTaskImpl)list.get(i);
     tryAssignUserName=    taskImpl.getAssignee();
               
         Task task = processEngine.getTaskService().getTask(list.get(i).getId());

               if(task!=null&&task.getName().equals("tryAssign")){
             
               
               }
      
         }
 if(!tryAssignUserName.equals("")){
  User user1=userService.findUserByName(tryAssignUserName);
  User assignManager=user1.getDepartment().getManagerUser();
  assignable.setAssignee(assignManager.getUsername());
 
 }
  
   
 }

}

 

 

对这段代码需要作如下的说明:

// 我们已经知道了上一个任务节点的名称是“tryAssign”,所以可以对历史任务列表中的每一个历史任务进行取出任务名称并和“tryAssign”进行比对,如果相同,则将该历史任务的assignee 取出。该assingee 就是C级部门apply 任务的组成员名。

不过在这里只能取到 tryAssign  的HistoryTaskImpl 而不能取到 task,不过由于上一个任务节点肯定是在历史任务列表的最后一个位置,所以可以通过取巧的方式获取到历史人物列表最后一个HistoryTaskImpl 的assignee 来确定tryAssign 的assingee。

 

 

 

 

 

对泳道的说明:

 

在jbpm.xml 文件中,有两处swimlane="assignmentswin"   ,分别是在tryAssign 和tryFinish  任务节点时。

因为在tryAssign 时,泳道确定了获取tryAssign 任务的assignee ,则jbpm 会将assignee 保存起来,在下次D任务节点用到swimlane="assignmentswin"   时,D任务节点会将任务的assingee 自动分配给这个泳道的assignee

 

 

 

 

 

下面是action 中tryAssign 方法的代码:

 

 

 

 


   public String applayAssign(){
       Map map=new HashMap();
       String tryAssignUserName="";
       User user=(User)ActionContext.getContext().getSession().get("user");
       User user2=user.getDepartment().getManagerUser();
       if(user.equals(user2)){
           map.put("role", "manager");
          
       }
       else {map.put("role", "common");
           }
       map.put("tryTime", tryTime);
       map.put("tryCondition", tryCondition);
      
       taskService.takeTask(taskId,user.getUsername() );
      
       String executionId = processEngine.getTaskService().getTask(taskId).getExecutionId();
       List <HistoryTask>list = processEngine.getHistoryService().createHistoryTaskQuery().executionId(executionId).list();

       for(int i=0;i<list.size();i++){
HistoryTaskImpl taskImpl=(HistoryTaskImpl)list.get(i);
            String tempName=    taskImpl.getAssignee();
          
       Task task = processEngine.getTaskService().getTask(list.get(i).getId());

          if(task!=null&&task.getName().equals("tryAssign")){
              tryAssignUserName=tempName;
             
          }
   
       }
      User user4= this.userServcie.findUserByName(tryAssignUserName);
      User assignManager=user4.getDepartment().getManagerUser();
    //  map.put("assignManager", assignManager.getUsername());
       taskService.completeTask(taskId,map);
       return "addLeaveApplay";
   }

 

方法一和方法二在这里的区别,就是没有将   assignManager进行赋值并传递给 managerAprove  任务中。

 

 

 

 

 

 

 

 

 

 

 

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值