jBPM(二):jbpm4 请假demo

一. 请假流程如下图,即:申请人申请-->部门负责人审批-->人事部审批-->申请人归档

对应的xml文件为:
<?xml version="1.0" encoding="UTF-8"?>

<process name="flowTest" xmlns="http://jbpm.org/4.3/jpdl">
   <start g="58,45,48,48" name="开始">
      <transition g="-81,-22" name="to 申请人申请" to="申请人申请"/>
   </start>
   <task g="279,40,92,52" name="申请人申请">  
      <assignment-handler class="jbpm.TaskAssignment"> 
      </assignment-handler> 
      <transition g="-105,-22" name="to 部门负责人审批" to="部门负责人审批"/>
   </task>
   <task g="591,48,114,52" name="部门负责人审批"> 
      <assignment-handler class="jbpm.TaskAssignment"> 
      </assignment-handler> 
      <transition g="-81,-22" name="to 人事部审批" to="人事部审批"/>
   </task>
   <task g="606,152,92,52" name="人事部审批"> 
      <assignment-handler class="jbpm.TaskAssignment"> 
      </assignment-handler>  
      <transition g="-81,-22" name="to 申请人归档" to="申请人归档"/>
   </task>
   <task g="334,153,92,52" name="申请人归档">
      <assignment-handler class="jbpm.TaskAssignment"> 
      </assignment-handler>  
      <transition g="-50,-22" name="to end1" to="结束"/>
   </task>
   <end g="65,150,48,48" name="结束"/>
</process>


二. 管理员登录系统,设置部门与人员信息如下:
  
    张三(zhangsan) -- 研发部(员工)
    朱孝敏(zxm)     -- 研发部(负责人)
    周慧(zhouhui)  -- 人事部


三. 管理员部署程序:
String deploymentId = processEngine.getRepositoryService()
		                 .createDeployment()
		        .addResourceFromClasspath(resourceName)
		                 .deploy();

  
四. 请假流程:

    1. 步骤1 : 张三发起流程申请

   

      发起流程主要逻辑:
      (1)获取当前登录用户的信息,用于页面显示
      (2)启动流程时,将当前信息存入
      (3)根据当前节点,获得下一步的节点信息,以及下一步节点的参与者
	public String start() throws Exception{
		
		date = new Date();
		
		// 获得当前登录用户信息
		User curLoginUser = WebUtils.getLoginUser(request); 
		if(curLoginUser==null){
			return "error";
		}
		userName = curLoginUser.getUserName();
		Department dept = (Department)getCommonService().get(Department.class, curLoginUser.getDeptId());
		deptName = dept.getDeptName();
		
		// 启动流程时存入当前用户信息
		Map<String,Object> initData = new HashMap<String,Object>(); 
		initData.put(Constants.FLOW_CUR_USER, curLoginUser.getLoginName());
		
		processInstance = getJbpmService().startProcessByKey(processKey,initData);  
		if(processInstance!=null){ 
			// 流程定义
			processDefinitionId = processInstance.getProcessDefinitionId();
			processDefinition = getJbpmService().getProcessDefinition(processDefinitionId);
			
			curTask = getJbpmService().getCurTask(processInstance.getId());
			if(curTask!=null){
				taskId = curTask.getId();
				executionId = curTask.getExecutionId();
			}
			curActivity = getJbpmService().getCurActivity(processInstance.getId()); 
			List<Transition> transitions = curActivity.getOutgoingTransitions();
			// 此处只取第一个(测试代码,假设只有一个outgoing)
			if(transitions!=null&&transitions.size()>0){
				Transition transition = transitions.get(0);
				nextActivity = transition.getDestination();
			}	 
			userList = getCommonService().getLeaders(curLoginUser);   
		}
		return "start";
	}


    张三输入申请信息之后,提交流程,后台的主要逻辑是:

    (1)将下一节点的参与者存入流程
    (2)新建表单对象FormData ,存储输入的申请信息,(FormData与流程id关联)
    (3)根据用户的勾选(下一步 or 退回)进行处理



    2. 步骤2:部门负责人(朱孝敏)登录,在待办公文中可以看到待办任务, 
        TaskService的findPersonalTasks方法,可以根据用户名获取该用户的待办任务。

      

       点击“处理”链接,进行流程审批,此处的逻辑是:

       (1)获得表单信息以及对应的审批信息
       (2)根据当前任务获得下一节点信息,取得对应的任务执行者
       (3)获得可退回节点信息(即已执行的节点信息)

	public String edit() throws Exception{
		// 1. 表单信息
		formData = (FormData)getCommonService().get(FormData.class, formDataId);
		spDataList = getCommonService().findAll(SpData.class, " formDataId = '"+formDataId+"' ");
		
		// 2. 流程定义
		processDefinition = getJbpmService().getProcessDefinition(processDefinitionId);
		// 3. 流程的可流转信息
		curTask = getJbpmService().getCurTask(processInstanceId); 
		
		/**
		 * 处理的关键:下一步信息(节点,人员) ; 退回信息(全部节点--人员)
		 */
		
		// 4. 下一步
		nextNodeUserInfo = new HashMap<String,Object>();
		String nextActivityName = "";
		
		curActivity = getJbpmService().getCurActivity(processInstanceId); 
		List<Transition> transitions = curActivity.getOutgoingTransitions();
		// 此处只取第一个
		if(transitions!=null&&transitions.size()>0){
			Transition transition = transitions.get(0);
			Activity destination = transition.getDestination();
			if(destination!=null){
				nextActivityName = destination.getName();
			}
			// 根据下一节点,获得人员信息
			List<User> userList = getCommonService().getUserList(nextActivityName,processInstanceId);
			nextNodeUserInfo.put(nextActivityName, userList); 
		} 
		 
		
		// 5. 可退回步骤
		Activity firstActivity = getJbpmService().getAllActivities(processInstanceId).get(1);
		if(firstActivity.getName().contains(curTask.getActivityName())){
			ifCanBack = 0;   
		}else{
			ifCanBack = 1;
		}
		if(ifCanBack.intValue()==1){
			canBackNames = getJbpmService().getBeforeNodeNames(processInstanceId, "");
		} 
		return "edit"; 
	}


      部门负责人输入审批意见后进行 退回操作,页面如下图:

  

     提交之后,流程退回到张三处,张三登录系统,查看待办公文:



     进入之后,可以看到部门负责人的审批信息;然后其输入对应内容,再次提交到部门负责人处。



     步骤3:部门负责人登录之后,同意该请假,提交到人事部审批;

      步骤4:人事部(周慧)登录系统,可以查看到待办公文,并进行审批;



     步骤5:人事部同意请假之后,申请人(张三)进行归档操作,流程结束。





说明:

1. 流程中每一个Task都配置assignment-handler来动态设置参与者,所以在提交时需要将下一节点的参与者传入流程中。
1.启动流程之后,流程进入到第一个节点  
2.任务分配器TaskAssignment在第一个任务complete之后执行,所以,设置变量信息需要在complete方法执行之前完成。



2. 退回部分代码:根据jbpm4_hist_actinst /// jbpm4_hist_task 表获得流程中对应节点的历史参与者。

		EnvironmentImpl envImpl = ((EnvironmentFactory)processEngine).openEnvironment();    
	      try {   
	          //动态回退
	    	  Task task = getTaskService().getTask(taskId);
	          ExecutionImpl e = (ExecutionImpl)getExecutionService().findExecutionById(task.getExecutionId());  
	          ActivityImpl currentActivityImpl = e.getActivity();  
	            
	          ProcessDefinitionImpl processDefinitionImpl = currentActivityImpl.getProcessDefinition();  
	            
	          //生成一个transition  
	          ActivityImpl destActivityImpl = processDefinitionImpl.findActivity(backActivityName);   // 获取退回目的地的活动定义对象
	           
	          TransitionImpl backTransition = currentActivityImpl.createOutgoingTransition();  
	          backTransition.setSource(currentActivityImpl);  
	          backTransition.setDestination(destActivityImpl);  
	          
	          //获得退回任务的历史参与者 (根据 jbpm4_hist_actinst /// jbpm4_hist_task 表获得 )
	          String user = getHistTaskUser(String.valueOf(e.getDbid()),backActivityName);
	          Map<String,Object> initData = new HashMap<String,Object>(); 
	  		  initData.put(Constants.FLOW_CUR_USER, user);
	          
	          getTaskService().completeTask(taskId,initData);
	      } catch (Exception e) {  
	          e.printStackTrace();  
	      }finally{  
	          envImpl.close();  
	      }  

猜你喜欢

转载自lijiejava.iteye.com/blog/1934708