JBPM4基础篇05-设计请假流程,流程的发起,执行,驳回,监控web Demo

来源:互联网 发布:运营商域名劫持 编辑:程序博客网 时间:2024/06/10 04:58

本次,我们在web项目的基础上,设计一个请假流程。申请--->经理审批---->老板审批----->通过。中间有根据一些条件来做判断,让流程进入到不同的节点。
  • 还有,加入了流程监控的功能。


    1. leave.jpdl.xml

      [html] view plaincopyprint?
      1. <?xml version="1.0" encoding="UTF-8"?>  
      2.   
      3. <process name="leave" xmlns="http://jbpm.org/4.3/jpdl">  
      4.    <start g="199,100,48,48" name="start1">  
      5.       <transition to="申请"/>  
      6.    </start>  
      7.    <task assignee="#{owner}" form="request.jsp" g="178,190,92,52" name="申请">  
      8.       <transition to="经理审批"/>  
      9.    </task>  
      10.    <task assignee="manager" form="manager.jsp" g="182,322,92,52" name="经理审批">  
      11.       <transition g="-37,-11" name="批准" to="exclusive1"/>  
      12.       <transition name="驳回" to="申请" g="108,350;106,216:-30,-7"/>  
      13.    </task>  
      14.    <task assignee="boss" form="boss.jsp" g="358,471,92,52" name="老板审批">  
      15.       <transition g="406,571:-47,-17" name="to end1" to="end1"/>  
      16.    </task>  
      17.    <decision expr="#{day > 3 ? 'to 老板审批' : 'to end1'}" g="208,425,48,48" name="exclusive1">  
      18.       <transition g="-47,-17" name="to end1" to="end1"/>  
      19.       <transition g="405,448:-71,-17" name="to 老板审批" to="老板审批"/>  
      20.    </decision>  
      21.    <end g="211,549,48,48" name="end1"/>  
      22. </process>  

    2. login.jsp
      由于在测试的过程中,要展示某某用户有哪些待办流程,或者某某用户发起了一个新流程,所以,做了一个简易的登录页面,登录后,保存当前登录的userName。
      [html] view plaincopyprint?
      1. <%@ page language="java" contentType="text/html; charset=UTF-8"  
      2.     pageEncoding="UTF-8"%>  
      3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
      4. <html>  
      5. <head>  
      6. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
      7. <title>登录</title>  
      8. </head>  
      9. <body>  
      10.   
      11. </body>  
      12.     <form name="loginForm" action="doLogin.jsp" method="post">  
      13.         <div>  
      14.             请输入用户名:<input type="text" name="userName" />   
      15.             <input type="submit" value="登录" />  
      16.         </div>  
      17.     </form>  
      18. </html>  

      效果图如下:

    3. index.jsp
      在index页面,有显示流程列表,显示已经启动的流程列表,有待办任务列表
      [html] view plaincopyprint?
      1. <%@ page language="java" contentType="text/html; charset=UTF-8"  
      2.     pageEncoding="UTF-8"%>  
      3. <%@ page import="java.util.*,org.jbpm.api.*,org.jbpm.api.task.*" %>  
      4. <%@ include file="checkLogin.jsp" %>  
      5. <%  
      6.     String userName = (String)session.getAttribute("userName");  
      7.     ProcessEngine processEngine = Configuration.getProcessEngine(); // 创建一个流程引擎  
      8.     RepositoryService repositoryService = processEngine.getRepositoryService(); // 创建一个流程服务  
      9.     ExecutionService executionService = processEngine.getExecutionService(); // 实例服务  
      10.     TaskService taskService = processEngine.getTaskService(); // 任务  
      11.       
      12.     List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery().list(); // 获取流程列表  
      13.     List<ProcessInstance> piList = executionService.createProcessInstanceQuery().list(); // 获取实例列表  
      14.     List<Task> taskList = taskService.findPersonalTasks(userName);  
      15.       
      16. %>  
      17. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
      18. <html>  
      19. <head>  
      20. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
      21. <title>Insert title here</title>  
      22. <link rel="Stylesheet" type="text/css" href="style.css" />  
      23. </head>  
      24. <body>  
      25.     <div>  
      26.         当前登录用户[<%=userName %>]|  
      27.         <a href="deploy.jsp">发布新流程</a>|<a href="login.jsp">登录</a>  
      28.     </div>  
      29.     <div>  
      30.         <h2>流程列表</h2>  
      31.         <table>  
      32.             <tr>  
      33.                 <td>ID</td>  
      34.                 <td>Name</td>  
      35.                 <td>Version</td>  
      36.                 <td>操作</td>  
      37.             </tr>  
      38.         <%    
      39.             for(ProcessDefinition pd : list) {  
      40.         %>  
      41.             <tr>  
      42.                 <td><%=pd.getId() %></td>  
      43.                 <td><%=pd.getName() %></td>  
      44.                 <td><%=pd.getVersion() %></td>  
      45.                 <td>  
      46.                     <a href="remove.jsp?deploymentId=<%=pd.getDeploymentId() %>">删除</a>|  
      47.                     <a href="start.jsp?id=<%=pd.getId() %>">开始</a>  
      48.                 </td>  
      49.             </tr>  
      50.         <%  
      51.             }  
      52.         %>  
      53.         </table>  
      54.           
      55.         <h2>实例列表</h2>  
      56.         <table>  
      57.             <tr>  
      58.                 <td>ID</td>  
      59.                 <td>活动</td>  
      60.                 <td>状态</td>  
      61.                 <td>操作</td>  
      62.             </tr>  
      63.         <%    
      64.             for(ProcessInstance pi : piList) {  
      65.         %>  
      66.             <tr>  
      67.                 <td><%=pi.getId() %></td>  
      68.                 <td><%=pi.findActiveActivityNames() %></td>  
      69.                 <td><%=pi.getState() %></td>  
      70.                 <td><a href="view.jsp?id=<%=pi.getId() %>">查看</a></td>  
      71.             </tr>  
      72.         <%  
      73.             }  
      74.         %>  
      75.         </table>  
      76.           
      77.             <h2>任务列表</h2>  
      78.         <table>  
      79.             <tr>  
      80.                 <td>ID</td>  
      81.                 <td>名称</td>  
      82.                 <td>操作</td>  
      83.             </tr>  
      84.         <%    
      85.             for(Task task : taskList) {  
      86.         %>  
      87.             <tr>  
      88.                 <td><%=task.getId() %></td>  
      89.                 <td><%=task.getName() %></td>  
      90.                 <td><a href="<%=task.getFormResourceName() %>?taskId=<%=task.getId() %>">查看</a><br /></td>  
      91.             </tr>  
      92.         <%  
      93.             }  
      94.         %>  
      95.         </table>  
      96.     </div>  
      97.   
      98. </body>  
      99. </html>  

      页面展示效果如下:

    4. deploy.jsp
      当在index页面点击“发布新流程”超链接的时候,发起一个新的流程。

      [java] view plaincopyprint?
      1. <%@ page language="java" contentType="text/html; charset=UTF-8"  
      2.     pageEncoding="UTF-8"%>  
      3. <%@ page import="java.util.*,org.jbpm.api.*"%>  
      4. <%  
      5.     ProcessEngine processEngine = Configuration.getProcessEngine(); // 创建一个流程引擎  
      6.     RepositoryService repositoryService = processEngine  
      7.             .getRepositoryService(); // 创建一个流程服务  
      8.   
      9.     repositoryService.createDeployment()  
      10.             .addResourceFromClasspath("leave.jpdl.xml").deploy(); // 发布一个流程  
      11.   
      12.     response.sendRedirect("index.jsp");  
      13. %>  


      发起一个流程后,index页面的效果如下:
    5. start.jsp
      点击首页流程列表中的“开始”,将当前的流程ID获取到,然后根据这个流程ID来启动一个流程
      [java] view plaincopyprint?
      1. <%@ page language="java" contentType="text/html; charset=UTF-8"  
      2.     pageEncoding="UTF-8"%>  
      3. <%@ page import="java.util.*,org.jbpm.api.*,org.jbpm.api.task.*" %>  
      4. <%  
      5.     String id = request.getParameter("id");  
      6.     String userName = (String)session.getAttribute("userName");  
      7.       
      8.     ProcessEngine processEngine = Configuration.getProcessEngine(); // 创建流程引擎  
      9.     ExecutionService executionService = processEngine.getExecutionService(); //   
      10.       
      11.     Map<String, Object> map = new HashMap<String, Object>();  
      12.     map.put("owner", userName);  
      13.     executionService.startProcessInstanceById(id, map);  
      14.       
      15.     response.sendRedirect("index.jsp");  
      16. %>  

      开始一个流程后,index页面的效果图如下:
    6. request.jsp
      假设当前登录用户为owner,由owner发起的流程,现在进入了申请阶段。任务列表中显示的是属于当前用户的待办列表。点击进去查看详情并提交申请。
      [html] view plaincopyprint?
      1. <%@ page language="java" contentType="text/html; charset=UTF-8"  
      2.     pageEncoding="UTF-8"%>  
      3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
      4. <html>  
      5. <head>  
      6. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
      7. <title>Request</title>  
      8. <link rel="Stylesheet" type="text/css" href="style.css" />  
      9. </head>  
      10. <body>  
      11.     <h2>申请</h2>  
      12.     <form action="submit.jsp" method="post">  
      13.         <input type="hidden" name="taskId" value="${param.taskId }" />  
      14.         <table>  
      15.             <tr>  
      16.                 <td>申请人</td>  
      17.                 <td><input type="text" name="owner" value="${sessionScope['userName'] }"/></td>  
      18.             </tr>  
      19.             <tr>  
      20.                 <td>请假时间(天)</td>  
      21.                 <td><input type="text" name="day" value="" /></td>  
      22.             </tr>  
      23.             <tr>  
      24.                 <td>请假原因</td>  
      25.                 <td><input type="text" name="reason" value="" /></td>  
      26.             </tr>  
      27.         </table>  
      28.         <input type="submit" value="提交" />  
      29.     </form>  
      30. </body>  
      31. </html>  

      效果图如下:
    7. submit.jsp
      当申请人提交了申请之后,我们需要获取其申请单提交的表单元素,将其执行使之进入下一步流程
      [java] view plaincopyprint?
      1. <%@ page language="java" contentType="text/html; charset=UTF-8"  
      2.     pageEncoding="UTF-8"%>  
      3. <%@ page import="java.util.*,org.jbpm.api.*,org.jbpm.api.task.*" %>  
      4. <%  
      5.     request.setCharacterEncoding("UTF-8");  
      6.     ProcessEngine processEngine = Configuration.getProcessEngine();  
      7.     TaskService taskService = processEngine.getTaskService();  
      8.   
      9.     // 接收任务ID  
      10.     String taskId = request.getParameter("taskId");  
      11.     // 接收用户名  
      12.     String owner = request.getParameter("owner");  
      13.     // 接收请假天数  
      14.     int day = Integer.parseInt(request.getParameter("day"));  
      15.     // 接收请假原因  
      16.     String reason = request.getParameter("reason");  
      17.       
      18.     Map<String, Object> map = new HashMap<String, Object>();  
      19.     map.put("day", day);  
      20.     map.put("reason", reason);  
      21.       
      22.     // 执行任务  
      23.     taskService.completeTask(taskId, map);  
      24.       
      25.     // 跳转到首页  
      26.     response.sendRedirect("index.jsp");  
      27. %>  

      提交了申请之后,再看index页面,刚才的待办任务已经流转,不显示了。如下图:


      然后使用manager(在leave.jpdl.xml中有定义)登录,查看属于自己的待办任务列表;如下图:


      登录首页后,清楚的看到刚才owner提交的申请已经流转到了manager的名下;如下图:
    8. manager.jsp
      点击index的待办任务列表中“查看”时,JBPM会根据在leave.jpdl.xml中的配置的form属性,自动跳转到manager页面进行经理的审批和驳回;
      [html] view plaincopyprint?
      1. <%@ page language="java" contentType="text/html; charset=UTF-8"  
      2.     pageEncoding="UTF-8"%>  
      3. <%@ page import="java.util.*,org.jbpm.api.*,org.jbpm.api.task.*" %>  
      4. <%  
      5.     ProcessEngine processEngine = Configuration.getProcessEngine();  
      6.     TaskService taskService = processEngine.getTaskService();  
      7.     String taskId = request.getParameter("taskId");  
      8.     Task task = taskService.getTask(taskId); // 获取任务  
      9. %>  
      10. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
      11. <html>  
      12. <head>  
      13. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
      14. <title>Manager</title>  
      15. <link rel="Stylesheet" type="text/css" href="style.css" />  
      16. </head>  
      17. <body>  
      18.     <h2>经理审核</h2>  
      19.     <form action="submit_manager.jsp" method="post">  
      20.         <input type="hidden" name="taskId" value="${param.taskId }" />  
      21.         <table>  
      22.             <tr>  
      23.                 <td>申请人</td>  
      24.                 <td><%=taskService.getVariable(taskId, "owner") %></td>  
      25.             </tr>  
      26.             <tr>  
      27.                 <td>请假时间(天)</td>  
      28.                 <td><%=taskService.getVariable(taskId, "day") %></td>  
      29.             </tr>  
      30.             <tr>  
      31.                 <td>请假原因</td>  
      32.                 <td><%=taskService.getVariable(taskId, "reason") %></td>  
      33.             </tr>  
      34.         </table>  
      35.         <input type="submit" name="result" value="批准" />  
      36.         <input type="submit" name="result" value="驳回" />  
      37.     </form>  
      38. </body>  
      39. </html>  

      效果图如下:
    9. submit_manager.jsp
      manager在提交了审批结果之后,在这里要处理经理提交的结果,批准或者驳回
      [java] view plaincopyprint?
      1. <%@ page language="java" contentType="text/html; charset=UTF-8"  
      2.     pageEncoding="UTF-8"%>  
      3. <%@ page import="java.util.*,org.jbpm.api.*,org.jbpm.api.task.*" %>  
      4. <%  
      5.     request.setCharacterEncoding("UTF-8");  
      6.     ProcessEngine processEngine = Configuration.getProcessEngine();  
      7.     TaskService taskService = processEngine.getTaskService();  
      8.   
      9.     // 接收任务ID  
      10.     String taskId = request.getParameter("taskId");  
      11.     // 接受命令  
      12.     String result = request.getParameter("result");  
      13.       
      14.     // 执行任务  
      15.     /* 
      16.      * jbpm会根据传过去的result来判断流程转向哪个task 
      17.      */  
      18.     taskService.completeTask(taskId, result);  
      19.       
      20.     // 跳转到首页  
      21.     response.sendRedirect("index.jsp");  
      22. %>  

      如果批准,我们再看index页面,属于经理的待办任务已经没了。并且,流程的实例列表也空了,证明这个流程已经流转完毕;如下图:


      我们再创建一个新的流程来测试驳回的效果;结果如下图:


    10. view.jsp和pic.jsp
      点击首页实例列表中的“查看”链接即可查看当前流程走到了哪一步,实现了流程监控


      然后view页面会将此时流程图显示出来,并且能看到当前走到了哪一步;要实现这个,必须进行以下三步:
      第一:将leave.jpdl.xml和自动生成的leave.png打包到一个leave.zip文件中(注意不要包含任何一层多的文件夹),并且存放在src下或者根目录下。如下图:



      第二:view.jsp
      [html] view plaincopyprint?
      1. <%@ page language="java" contentType="text/html; charset=UTF-8"  
      2.     pageEncoding="UTF-8"%>  
      3. <%@ page import="java.util.*,org.jbpm.api.*,org.jbpm.api.model.*"%>  
      4. <%  
      5.     String id = request.getParameter("id"); // 获取流程实例ID  
      6.     ProcessEngine processEngine = Configuration.getProcessEngine();  
      7.     RepositoryService repositoryService = processEngine  
      8.             .getRepositoryService();  
      9.     ExecutionService executionService = processEngine  
      10.             .getExecutionService();  
      11.     ProcessInstance processInstance = executionService  
      12.             .findProcessInstanceById(id); // 根据ID获取流程实例  
      13.     Set<String> activityNames = processInstance  
      14.             .findActiveActivityNames(); // 获取实例执行到的当前节点的名称  
      15.   
      16.     ActivityCoordinates ac = repositoryService.getActivityCoordinates(  
      17.             processInstance.getProcessDefinitionId(), activityNames  
      18.                     .iterator().next());  
      19. %>  
      20. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
      21. <html>  
      22. <head>  
      23. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
      24. <title>View</title>  
      25. <link rel="Stylesheet" type="text/css" href="style.css" />  
      26. </head>  
      27. <body>  
      28.     <h2>流程图显示</h2>  
      29.     <img src="pic.jsp?id=<%=id%>"  
      30.         style="position: absolute; left: 0px; top: 0px" />  
      31.     <div  
      32.         style="position:absolute;border:2px solid red;left:<%=ac.getX()%>px;top:<%=ac.getY()%>px;width:<%=ac.getWidth()%>px;height:<%=ac.getHeight()%>px;"></div>  
      33. </body>  
      34. </html>  

      第三:pic.jsp(在view.jsp中调用了pic.jsp来获取图片)
      [java] view plaincopyprint?
      1. <%@ page language="java" contentType="text/html; charset=UTF-8"  
      2.     pageEncoding="UTF-8"%>  
      3. <%@ page import="java.util.*,org.jbpm.api.*,java.io.*"%>  
      4. <%  
      5.     String id = request.getParameter("id"); // 获取流程实例ID  
      6.     ProcessEngine processEngine = Configuration.getProcessEngine();  
      7.     RepositoryService repositoryService = processEngine  
      8.             .getRepositoryService();  
      9.     ExecutionService executionService = processEngine  
      10.             .getExecutionService();  
      11.     ProcessInstance processInstance = executionService  
      12.             .findProcessInstanceById(id); // 根据ID获取流程实例  
      13.     String processDefinitionId = processInstance  
      14.             .getProcessDefinitionId();  
      15.     ProcessDefinition processDefinition = repositoryService  
      16.             .createProcessDefinitionQuery()  
      17.             .processDefinitionId(processDefinitionId).uniqueResult();  
      18.     InputStream inputStream = repositoryService.getResourceAsStream(  
      19.             processDefinition.getDeploymentId(), "leave.png");  
      20.       
      21.     byte[] b = new byte[1024];  
      22.     int len = -1;  
      23.     OutputStream ops = response.getOutputStream();  
      24.     while ((len = inputStream.read(b, 01024)) != -1) {  
      25.         ops.write(b, 0, len);  
      26.     }  
      27. %>  

      OK,现在我们来看看,当前的展示效果:

      上图的红框是程序自动生成的,并非作图的效果;

    11. boss.jsp,submit_boss.jsp
      这个页面来处理经理审批过后,大于3天的请假流程(规则在leave.jpdl.xml中定义)。
      需要查看详细代码和运行效果,请下载我的完整项目:
      链接稍后奉上!
      点击此处去下载完整Demo

  • 0 0