写到这,jbpm的准备工作都差不多了,开始进入正题,开始简单的请假流程……

一、创建流程实例

  • 界面部分概述:员工登录后填写请假单,然后点击提交……
  • 后台java处理:由于我没有用到hibernate,所以都是jdbc操作数据库(真心后悔没用hibernate),总的思路如下:
  1. Struct2接收完请假信息后,调用service层我写好的函数(jbpm相关操作)
  2.  punlic ProcessInstance createProcessInstance(String actorId);请看注释:
         
         
         
         
    1. /**
    2. * 本函数负责根据流程名("leaveProcess")创建一个流程实例
    3. * 将创建者的名字放进 variables对象中,取名为"name"
    4. * 返回流程实例对象pi
    5. */
    6. @Override 
    7.     public ProcessInstance createProcessInstance(String actorId) {  
    8.         deploy();  
    9.         Map variables = new HashMap();  
    10.         variables.put("name", actorId);  
    11.         ProcessInstance pi = processEngine.getExecutionService()  
    12.                 .startProcessInstanceByKey("leaveProcess", variables);  
    13.         System.out.println("id :" + pi.getId() + ", processDefination id:  " 
    14.                 + pi.getProcessDefinitionId());  
    15.         return pi;  
    16.     } 
  3. 将流程实例提交,持久化到数据库中
  4. public void submitApplication(String actorId, float days,ProcessInstance pi, int id)
          
          
          
          
    1. /**  
    2.      * submitApplication 2012-7-9  
    3.      */ 
    4.     @Override 
    5.     public void submitApplication(String actorId, float days,  
    6.             ProcessInstance pi, int id) {  
    7.         String taskId = processEngine.getTaskService().createTaskQuery()  
    8.                 .processInstanceId(pi.getId()).uniqueResult().getId();  
    9.         // 根据流程实例ID寻找TASKID  
    10.         LeaveDao dao = new LeaveDaoImpl();// 寻找上级  
    11.         Leaves leaves = null;  
    12.         try {  
    13.             List all = dao.queryParentById(id, 1);  
    14.             for (int i = 0; i < all.size(); i++) {  
    15.                 leaves = all.get(i);  
    16.             }  
    17.         } catch (Exception e) {  
    18.         }  
    19.         //System.out.println("TaskId" + taskId);  
    20.         Task tasks = processEngine.getTaskService().getTask(taskId);//根据taskId寻找task  
    21.         String executionId = tasks.getExecutionId();//根据task寻找executionId(跟processId好像没区别)  
    22.         processEngine.getExecutionService().setVariable(executionId,  
    23.                 "parentId",new String(leaves.getL_emp_id()+""));//给这个流程添加领导的id  
    24.         processEngine.getExecutionService().setVariable(executionId, "days",//给这个流程添加时间  
    25.                 days);  
    26.         processEngine.getTaskService().completeTask(taskId);//提交任务  
    27.     } 
  5. 最后,我们需要将流程实例跟你的请假单绑定,这样你的请假单就会跟着流程一起流转啦!!所以,在数据库设计上我们要在Leaves表中增加一个外键l_leave_processId varchar类型,因为processInstranceId是String类型的
  6. 我的Action(主要负责整合这几部分,我设计的比较烂)
   
   
   
   
  1. public String apply() throws Exception {  
  2.         session = ActionContext.getContext().getSession();  
  3.         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");  
  4.         String lf = leaveInfo.getFromtime();  
  5.         String lt = leaveInfo.getTotime();  
  6.         Date df = sdf.parse(lf);  
  7.         Date dt = sdf.parse(lt);  
  8.         Leaves l = new Leaves();  
  9.         l.setL_emp_id(leaveInfo.getE_emp_id());  
  10.         l.setL_leave_depart_id(leaveInfo.getD_depart_id());  
  11.         l.setL_leave_from(df);  
  12.         l.setL_leave_to(dt);  
  13.         l.setL_leave_type_id(leaveInfo.getLeaveTypeId());  
  14.         l.setL_leave_reason(leaveInfo.getReason());// 乱码  
  15.         LeaveDao dao = new LeaveDaoImpl();  
  16.  
  17.         // LeaveWorkFlow lwf = new LeaveWorkFlow();  
  18.         // // 开始流程  
  19.         float days = ((LeaveDaoImpl) dao).getDays(df, dt);  
  20.         // List approvalList  
  21.         // =lwf.submitApplication(leaveInfo.getE_emp_id(), days, 9);  
  22.         // session.put("aprovalList", approvalList);  
  23.         EmployeeDao employeeDao = new EmployeeDaoImpl();  
  24.         Employee e = employeeDao.findEmployeeById(leaveInfo.getE_emp_id());  
  25.         // 如果days 大于3天,需要多executive审批  
  26.         JbpmFecade jbpmFecade = new JbpmFecadeImpl();  
  27.         ProcessInstance pi = jbpmFecade.createProcessInstance(e.getE_name_cn());  
  28.         jbpmFecade.submitApplication(e.getE_name_cn(), days, pi,  
  29.                 leaveInfo.getE_emp_id());// 提交公文  
  30.         // 插入数据库  
  31.         l.setL_leave_processId(pi.getProcessInstance().getId());  
  32.         dao.insertLeavesApplication(l);  
  33.         all = dao.queryAllLeavesByPV(leaveInfo.getE_emp_id());  
  34.         return "leaveApplyList";  
  35.     } 

 到此,创建流程实例的部分已经结束,下面是领导审批部分

二、领导审批

  • 界面部分概述:领导登录后查看任务列表,之后看请假的详细信息,进行审批
  • 后台java处理:我们需要几个方法,(1)查询自己任务列表的方法 (2)审批的方法
  1. 查询任务列表
  2. 根据领导的名字查询自己的任务列表
  3.     
        
        
        
    1. public ArrayList findTaskViewList(String actorId) throws Exception {  
    2.         // 1 tasks  
    3.         List tasks = processEngine.getTaskService()//  
    4.                 .findPersonalTasks(actorId);  
    5.         // 2  流程 变量 封装到tasklist  
    6.         Leaves leave = null;  
    7.         ArrayList list = new ArrayList();  
    8.         for (Task task : tasks) {  
    9.             String processInstanceId = processEngine.getTaskService()//  
    10.                     .getTask(task.getId())//  
    11.                     .getExecutionId();  
    12.             leave = new Leaves();  
    13.             LeaveDao dao = new LeaveDaoImpl();  
    14.             leave = dao.findLeaveByProcessId(processInstanceId);  
    15.             list.add(leave);  
    16.         }  
    17.         return list;  
    18.     } 
  4. 领导审批
  5.  public void approveByManager(String actorId, boolean status, int did,int id);
  6.     
        
        
        
    1. /**  
    2.      * approveByManager 2012-7-9  
    3.      */ 
    4.     @Override 
    5.     public void approveByManager(String actorId, boolean status, int did,int id) {  
    6.         LeaveDao dao = new LeaveDaoImpl();  
    7.         /**  
    8.          * 查找上级  
    9.          */ 
    10.         Leaves l = null;  
    11.         try {  
    12.             List all = dao.queryParentById(id, 1);  
    13.             for (int i = 0; i < all.size(); i++) {  
    14.                 l = all.get(i);  
    15.             }  
    16.         } catch (Exception e) {  
    17.         }  
    18.         List tasks = processEngine.getTaskService()//根据自己的名字查询任务列表       
    19.                 .findPersonalTasks(actorId);  
    20.         Leaves leaves = null;  
    21.         for (Task t : tasks) {//循环判断任务列表  
    22.             System.out.println(" id " + t.getId() + " ,name " + t.getName() + // 得到任务名称  
    23.                     " assignee " + t.getAssignee() + // 得到 任务的代理人  
    24.                     " , createTime " + t.getCreateTime()//  
    25.             );  
    26.             // 2 处理task  
    27.             String processInstanceId = processEngine.getTaskService()//  
    28.                     .getTask(t.getId())//  
    29.                     .getExecutionId();  
    30.             // 根据流程实例id 获取公文id  
    31.             try {  
    32.                 leaves = dao.findLeaveByProcessId(processInstanceId);  
    33.             } catch (Exception e) {  
    34.                 // TODO: handle exception  
    35.             }  
    36.  
    37.             if (did == leaves.getL_leave_id()) {//比较所传人的请假单id和公文id是否相等  
    38.                 if (status) {//领导审批通过状态(true or false)  
    39.                     processEngine.getExecutionService().setVariable(processInstanceId,  
    40.                             "exeId"new String(l.getL_emp_id()+""));//将自己领导的id存入exeId中  
    41.                     processEngine.getTaskService()//  
    42.                             .completeTask(t.getId(), "ManagerApproved");  
    43.                       
    44.                 } else {  
    45.                     processEngine.getTaskService()//  
    46.                             .completeTask(t.getId(), "ManagerDisApproved");  
    47.                 }  
    48.                 break;  
    49.             }  
    50.         }  
    51.     } 


    解释一下:首先我们接收几个参数:领导的名字>>>actorId、请假单的ID>>>did、领导审批的状态变量>>>status、领导自己的Id>>>id

    用途:

    actorId 负责查询任务列表tasks,所以只会查到自己下属提交的

    status 的值为true or false ,这样任务会提交到不同的地方

    did 上层模块传来公文id(请假单的id,很好获得)当循环遍历任务列表时,我们可以通过task t获取流程实例t.getId(),根据流程实例id获取那个请假单的id,大体过程如下:id>>>> processInstanceId>>>>l_leave_id,然后我们就和这个did进行比较就好啦,如果相等则证明这个是当前要审批的请假单啦,好乱!!

    id 上层模块传来的领导自己的id,用来查找自己上级(因为请假天数大于3天后会增加一个高层来审批,也就是你的上级)

    高层审批hr确认实际上跟这部分类似,这里就不再多写了