`

jbpm请假工作流

阅读更多

请假流程(备用)

工作中要用到JBPM写工作流,自习的时候找到一篇较好的文章,贴过来共享下!

示例:
在某一公司中,部门员工要休假的话需要部门主管的批准。如果休假天数大于10天的话,在部门主管的同意后,还必须上级主管批准。如果是部门主管要休假只要上级主管批准即可。在休假被批准之前,申请人可以撤销休假申请。
每个员工还有多少天休假必须管理起来,在员工提交休假申请时要检查申请天数是否超过可用天数。申请批准后,要在可用天数里减去申请天数。每次休假申请结束之后,不管通过未通过或是否取消,都必须记录下来。主管在批复申请之后,系统要将批复结果Email给申请人。对于大于10天的申请,如果部门主管已批准同意而上级主管还未批准,这时申请人撤销申请后,系统应发Email通知部门主管申请已撤销。 
  processdefinition.xml如下:

xml 代码
  1. <!----><?xml version="1.0" encoding="UTF-8"?>
    <!-- edited with XMLSPY v2004 rel. 3 U (http://www.xmlspy.com) by Keller (zju) -->
    <!DOCTYPE process-definition PUBLIC
        "-//jBpm/jBpm Mapping DTD 2.0//EN"
        "http://jbpm.org/dtd/processdefinition-2.0.dtd">
    <process-definition name="RequestLeave">
     <swimlane name="requester">
      <description>申请者</description>
     </swimlane>
     <swimlane name="chief">
      <description>部门主管</description>
      <delegation class="kellerdu.jbpm.delegation.ChiefSwimlane" />
     </swimlane>
     <swimlane name="boss">
      <description>上级主管</description>
      <delegation class="kellerdu.jbpm.delegation.BossSwimlane" />
     </swimlane>
     <start-state name="request" swimlane="requester">
      <transition to="Begin Request" />
     </start-state>
     <fork name="Begin Request">
      <transition to="Requester Cancel" />
      <transition to="IsChief" />
     </fork>
     <decision name="IsChief">
      <delegation class="kellerdu.jbpm.delegation.ChiefDecision" />
      <transition name="Boss Approve" to="Boss Approve" />
      <transition name="Chief Approve" to="Chief Approve" />
     </decision>
     <state name="Requester Cancel">
      <assignment swimlane="requester" />
      <transition name="cancel" to="Decided">
       <action>
        <!-- 将请假的状态改变为“取消”-->
        <delegation class="kellerdu.jbpm.action.RequestCancel" />
       </action>
      </transition>
     </state>
     <state name="Chief Approve">
      <assignment swimlane="chief" />
      <transition name="approve" to="NeedBossApprove">
       <action>
        <!-- 将请假的状态改变为“主管批准”-->
        <delegation class="kellerdu.jbpm.action.ChiefApprove" />
       </action>
      </transition>
      <transition name="disapprove" to="Decided">
       <action>
        <!-- 将请假的状态改变为“主管否决”-->
        <delegation
         class="kellerdu.jbpm.action.ChiefDisapprove" />
       </action>
      </transition>
     </state>
     <state name="Boss Approve">
      <assignment swimlane="boss" />
      <transition name="approve" to="Decided">
       <action>
        <!-- 将请假的状态改变为“老板批准”-->
        <delegation class="kellerdu.jbpm.action.BossApprove" />
       </action>
      </transition>
      <transition name="disapprove" to="Decided">
       <action>
        <!-- 将请假的状态改变为“老板否决”-->
        <delegation class="kellerdu.jbpm.action.BossDisapprove" />
       </action>
      </transition>
     </state>
     <decision name="NeedBossApprove">
      <!-- 请假天数大于10天的要老板批准  -->
      <delegation
       class="kellerdu.jbpm.delegation.NeedBossApproveDecision" />
      <transition name="need" to="Boss Approve" />
      <transition name="notNeed" to="Decided" />
     </decision>
     <join name="Decided">
      <description>有一个先到达即进行父Token</description>
      <delegation class="kellerdu.jbpm.delegation.DecidedJoin" />
      <transition to="Do Something" />
     </join>
     <decision name="Do Something">
      <description>
       根据请求的状态决定。
       (1)“主管或者老板批准”-‘approve’:修改员工休假的总天数,设定发给用户E-Mail的信息。
       (2)“主管或者老板否决”-“disapprove”:设定发给用户E-Mail的信息。
       (3)“撤销”-"cancel"-设定发给用户E-Mail的信息。如果主管批准,要发给主管消息说明已经撤销。
      </description>
      <delegation
       class="kellerdu.jbpm.delegation.DoSomethingDecision" />
      <transition name="disapprove" to="Finished">
       <action>
        <delegation class="kellerdu.jbpm.action.Disapprove" />
       </action>
      </transition>
      <transition name="approve" to="Finished">
       <action>
        <delegation class="kellerdu.jbpm.action.Approve" />
       </action>
      </transition>
      <transition name="cancel" to="Finished">
       <action>
        <delegation class="kellerdu.jbpm.action.Cancel" />
       </action>
      </transition>
     </decision>
     <end-state name="Finished" />
     <action event-type="process-end">
      <!-- 发送E-Mail消息给申请者,记录请假日志 -->
      <delegation class="kellerdu.jbpm.action.ProcessEndAction" />
     </action>
    </process-definition>

 

Action指明的是当前状态要执行的一些额外的操作,如记录log、发邮件等。
(1)Swimline的delegation要做的就是判别当前Actor的身份。

java 代码
  1. package kellerdu.jbpm.delegation;   
  2.   
  3. import org.jbpm.delegation.*;   
  4. import kellerdu.jbpm.LogsFactory;   
  5. import org.apache.commons.logging.Log;   
  6.   
  7. public class BossSwimlane implements AssignmentHandler {   
  8.     public BossSwimlane() {   
  9.     }   
  10.   
  11.     /**  
  12.      * 当前的状态有哪个actor来具体负责处理,选择是老板的actor来处理。  
  13.      *  
  14.      * 如果王林是老板,那么他请假可以用他的名称来开始一个请假流程,当他检查他需要批示的  
  15.      * 请假时,使用actorId=boss来找出所有的批示。这时selectActor返回的值就是一个常量“boss”  
  16.      *  
  17.      *  
  18.      * @param assignmentContext AssignmentContext  
  19.      * @return String  
  20.      * @todo Implement this org.jbpm.delegation.AssignmentHandler method  
  21.      */  
  22.     public String selectActor(AssignmentContext assignmentContext) {   
  23.         Log log = LogsFactory.getLogInstance(this.getClass());   
  24.         log.info("任务分配给老板");   
  25.         return "boss";   
  26.     }   
  27. }   
  28. ========================================   
  29. ackage kellerdu.jbpm.delegation;   
  30.   
  31. import org.jbpm.delegation.*;   
  32. import kellerdu.jbpm.LogsFactory;   
  33. import org.apache.commons.logging.Log;   
  34.   
  35. public class ChiefSwimlane implements AssignmentHandler {   
  36.     public ChiefSwimlane() {   
  37.     }   
  38.   
  39.     /**  
  40.      * selectActor  
  41.      * @see BossSwimlane  
  42.      *  
  43.      * @param assignmentContext AssignmentContext  
  44.      * @return String  
  45.      * @todo Implement this org.jbpm.delegation.AssignmentHandler method  
  46.      */  
  47.     public String selectActor(AssignmentContext assignmentContext) {   
  48.        Log log = LogsFactory.getLogInstance(this.getClass());   
  49.         log.info("任务分配给上级主管");   
  50.        return "chief";   
  51.     }   
  52. }   

(二)Decision

java 代码
  1. package kellerdu.jbpm.delegation;   
  2.   
  3. import org.jbpm.delegation.*;   
  4. import kellerdu.jbpm.LogsFactory;   
  5. import org.apache.commons.logging.Log;   
  6. import kellerdu.jbpm.Constants;   
  7.   
  8. public class ChiefDecision implements DecisionHandler {   
  9.     public ChiefDecision() {   
  10.     }   
  11.   
  12.     /**  
  13.      * 判断是否需要主管批准,决定下一个要进行的transition  
  14.      *  
  15.      * @param executionContext ExecutionContext  
  16.      * @return String  
  17.      * @todo Implement this org.jbpm.delegation.DecisionHandler method  
  18.      */  
  19.     public String decide(ExecutionContext executionContext) {   
  20.         Log log=LogsFactory.getLogInstance(this.getClass());   
  21.         String ac=(String)executionContext.getVariable(Constants.USER_NAME);   
  22.         if(ac!=null&&(ac.equals("dali")||ac.equals("wang"))){   
  23.             log.info(ac+"需要老板批准!");   
  24.             return "BossApprove";   
  25.         }else{   
  26.             log.info(ac+"需要先经主管批准");   
  27.             return "ChiefApprove";   
  28.         }   
  29.     }   
  30. }   
  31.   

=======================
(三)fork

java 代码
  1. package kellerdu.jbpm.delegation;   
  2.   
  3. import org.jbpm.*;   
  4. import org.jbpm.delegation.*;   
  5. import org.jbpm.model.execution.*;   
  6. import java.util.*;   
  7.   
  8. public class DecidedJoin implements JoinHandler {   
  9.     public DecidedJoin() {   
  10.     }   
  11.   
  12.     /**  
  13.      * fork,只要一个分支到达,即可进行下一步操作,同时取消其它同时进行的分支。  
  14.      * 这里就是用户如果取消,请假就取消。如果用户请假批准,则用户不能取消。  
  15.      *  
  16.      * @param forkContext ForkContext  
  17.      * @throws ExecutionException  
  18.      * @todo Implement this org.jbpm.delegation.ForkHandler method  
  19.      */  
  20.     public void join(JoinContext joinContext) throws ExecutionException {   
  21.         Iterator it=joinContext.getConcurrentTokens().values().iterator();   
  22.         Token arrivingToken = joinContext.getToken();   
  23.         while(it.hasNext()){   
  24.             Token to=(Token)it.next();   
  25.             if(to.getId().equals(arrivingToken.getId())){   
  26.                 //取消其它执行的Token   
  27.                 joinContext.getExecutionService().cancelToken(to.getId());   
  28.             }   
  29.         }   
  30.          // reactivate the parent token.   
  31.           joinContext.reactivateToken( arrivingToken.getParent() );   
  32.     }   
  33. }   
  34.     

(一)  开始一个请假流程

java 代码
  1. //user是请假人的actorId   
  2.       ExecutionService es=JbpmServiceFactory.getInstance().openExecutionService(user);   
  3.        HashMap vs=new HashMap();   
  4.       //一些参数   
  5.        vs.put(Constants.REQUEST_STATUS,String.valueOf(0));   
  6.        vs.put(Constants.REQUEST_RETURN_INFO,"No info!");   
  7.        vs.put(Constants.USER_NAME,EncodeTransfer.toISO(user));   
  8.        vs.put(Constants.REQUEST_DAYS,String.valueOf(rea.getDays()));   
  9.        try {   
  10.           //开启请假流程   
  11.            es.startProcessInstance(Constants.WORK_NAME, vs);   
  12.            log.info("["+user+"]"+"申请假期开始!请假"+rea.getDays()+"天!");   
  13.            return am.findForward("main");   
  14.        } catch (ExecutionException ex) {   
  15.            ex.printStackTrace();   
  16.            log.error("请假进程无法开始!");   
  17.            return am.findForward("error");   
  18.        }finally{   
  19.            es.close();   
  20.        }   

(二)当前执行任务
    对于部门经理或者老板,找到要处理的请假。

java 代码
  1. String actorId = (String) req.getSession().getAttribute(Constants.USER);   
  2.           if(actorId.equals("wang")){   
  3.               actorId="boss";   
  4.           }else if(actorId.equals("bigli")){   
  5.               actorId="chief";   
  6.           }   
  7.           // get the execution service   
  8.           ExecutionService executionService = JbpmServiceFactory.getInstance().   
  9.                                               openExecutionService(actorId);   
  10.   
  11.           // get the tasklist from jbpm for user   
  12.           List tasks = new ArrayList();   
  13.           // add the jbpm tasks   
  14.           tasks.addAll(executionService.getTaskList(actorId));   
  15.           // put the tasklist into the form   
  16.           mf.setTasks(tasks);   
  17.           // get the tasklist from jbpm for user   
  18.           List definitions = new ArrayList();   
  19.           // add the jbpm definitions   
  20.           definitions.addAll(executionService.getLatestDefinitions());   
  21.           // put the tasklist into the form   
  22.           mf.setRequests(definitions);   
  23.           // close the execution service   
  24.           executionService.close();   
  25.           req.getSession().setAttribute("mainForm",mf);   
  26.           log.debug("任务: " + tasks);   
  27.           log.debug("当前可以执行的请求: " + definitions);   

(三)处理请假

java 代码
  1. String actorId = (String) reqrest.getSession().getAttribute(Constants.   
  2.                     USER);   
  3.             Long tokenId=new Long(req.getParameter("tokenId"));   
  4.             // get the execution service   
  5.             ExecutionService executionService = JbpmServiceFactory.getInstance().   
  6.                                                 openExecutionService(actorId);   
  7.             Map hm=executionService.getVariables(tokenId);//变量   
  8.             String act=req.getParameter("action");//进行转换的transition   
  9.             executionService.endOfState(tokenId,hm,act);   
  10.             executionService.close();   
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics