当前位置: 代码迷 >> Web前端 >> JBPM4基础篇05-设计告假流程,流程的发起,执行,驳回,监控web Demo
  详细解决方案

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

热度:872   发布时间:2012-11-26 11:48:49.0
JBPM4基础篇05-设计请假流程,流程的发起,执行,驳回,监控web Demo
  • 本次,我们在web项目的基础上,设计一个请假流程。申请--->经理审批---->老板审批----->通过。中间有根据一些条件来做判断,让流程进入到不同的节点。
  • 还有,加入了流程监控的功能。


  1. leave.jpdl.xml

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

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

    效果图如下:

  3. index.jsp
    在index页面,有显示流程列表,显示已经启动的流程列表,有待办任务列表
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <%@ page import="java.util.*,org.jbpm.api.*,org.jbpm.api.task.*" %>
    <%@ include file="checkLogin.jsp" %>
    <%
    	String userName = (String)session.getAttribute("userName");
    	ProcessEngine processEngine = Configuration.getProcessEngine(); // 创建一个流程引擎
    	RepositoryService repositoryService = processEngine.getRepositoryService(); // 创建一个流程服务
    	ExecutionService executionService = processEngine.getExecutionService(); // 实例服务
    	TaskService taskService = processEngine.getTaskService(); // 任务
    	
    	List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery().list(); // 获取流程列表
    	List<ProcessInstance> piList = executionService.createProcessInstanceQuery().list(); // 获取实例列表
    	List<Task> taskList = taskService.findPersonalTasks(userName);
    	
    %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
    <link rel="Stylesheet" type="text/css" href="style.css" />
    </head>
    <body>
    	<div>
    		当前登录用户[<%=userName %>]|
    		<a href="deploy.jsp">发布新流程</a>|<a href="login.jsp">登录</a>
    	</div>
    	<div>
    		<h2>流程列表</h2>
    		<table>
    			<tr>
    				<td>ID</td>
    				<td>Name</td>
    				<td>Version</td>
    				<td>操作</td>
    			</tr>
    		<%  
    			for(ProcessDefinition pd : list) {
    		%>
    			<tr>
    				<td><%=pd.getId() %></td>
    				<td><%=pd.getName() %></td>
    				<td><%=pd.getVersion() %></td>
    				<td>
    					<a href="remove.jsp?deploymentId=<%=pd.getDeploymentId() %>">删除</a>|
    					<a href="start.jsp?id=<%=pd.getId() %>">开始</a>
    				</td>
    			</tr>
    		<%
    			}
    		%>
    		</table>
    		
    		<h2>实例列表</h2>
    		<table>
    			<tr>
    				<td>ID</td>
    				<td>活动</td>
    				<td>状态</td>
    				<td>操作</td>
    			</tr>
    		<%  
    			for(ProcessInstance pi : piList) {
    		%>
    			<tr>
    				<td><%=pi.getId() %></td>
    				<td><%=pi.findActiveActivityNames() %></td>
    				<td><%=pi.getState() %></td>
    				<td><a href="view.jsp?id=<%=pi.getId() %>">查看</a></td>
    			</tr>
    		<%
    			}
    		%>
    		</table>
    		
    			<h2>任务列表</h2>
    		<table>
    			<tr>
    				<td>ID</td>
    				<td>名称</td>
    				<td>操作</td>
    			</tr>
    		<%  
    			for(Task task : taskList) {
    		%>
    			<tr>
    				<td><%=task.getId() %></td>
    				<td><%=task.getName() %></td>
    				<td><a href="<%=task.getFormResourceName() %>?taskId=<%=task.getId() %>">查看</a><br /></td>
    			</tr>
    		<%
    			}
    		%>
    		</table>
    	</div>
    
    </body>
    </html>

    页面展示效果如下:

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

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <%@ page import="java.util.*,org.jbpm.api.*"%>
    <%
        ProcessEngine processEngine = Configuration.getProcessEngine(); // 创建一个流程引擎
        RepositoryService repositoryService = processEngine
                .getRepositoryService(); // 创建一个流程服务
    
        repositoryService.createDeployment()
                .addResourceFromClasspath("leave.jpdl.xml").deploy(); // 发布一个流程
    
        response.sendRedirect("index.jsp");
    %>
    


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

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

    效果图如下:
  7. submit.jsp
    当申请人提交了申请之后,我们需要获取其申请单提交的表单元素,将其执行使之进入下一步流程
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <%@ page import="java.util.*,org.jbpm.api.*,org.jbpm.api.task.*" %>
    <%
    	request.setCharacterEncoding("UTF-8");
    	ProcessEngine processEngine = Configuration.getProcessEngine();
    	TaskService taskService = processEngine.getTaskService();
    
    	// 接收任务ID
    	String taskId = request.getParameter("taskId");
    	// 接收用户名
    	String owner = request.getParameter("owner");
    	// 接收请假天数
    	int day = Integer.parseInt(request.getParameter("day"));
    	// 接收请假原因
    	String reason = request.getParameter("reason");
    	
    	Map<String, Object> map = new HashMap<String, Object>();
    	map.put("day", day);
    	map.put("reason", reason);
    	
    	// 执行任务
    	taskService.completeTask(taskId, map);
    	
    	// 跳转到首页
    	response.sendRedirect("index.jsp");
    %>

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


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


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

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

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


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


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


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



    第二:view.jsp
    <%@ page language="java" contentType="text/html; charset=UTF-8"
    	pageEncoding="UTF-8"%>
    <%@ page import="java.util.*,org.jbpm.api.*,org.jbpm.api.model.*"%>
    <%
    	String id = request.getParameter("id"); // 获取流程实例ID
    	ProcessEngine processEngine = Configuration.getProcessEngine();
    	RepositoryService repositoryService = processEngine
    			.getRepositoryService();
    	ExecutionService executionService = processEngine
    			.getExecutionService();
    	ProcessInstance processInstance = executionService
    			.findProcessInstanceById(id); // 根据ID获取流程实例
    	Set<String> activityNames = processInstance
    			.findActiveActivityNames(); // 获取实例执行到的当前节点的名称
    
    	ActivityCoordinates ac = repositoryService.getActivityCoordinates(
    			processInstance.getProcessDefinitionId(), activityNames
    					.iterator().next());
    %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>View</title>
    <link rel="Stylesheet" type="text/css" href="style.css" />
    </head>
    <body>
    	<h2>流程图显示</h2>
    	<img src="pic.jsp?id=<%=id%>"
    		style="position: absolute; left: 0px; top: 0px" />
    	<div
    		style="position:absolute;border:2px solid red;left:<%=ac.getX()%>px;top:<%=ac.getY()%>px;width:<%=ac.getWidth()%>px;height:<%=ac.getHeight()%>px;"></div>
    </body>
    </html>

    第三:pic.jsp(在view.jsp中调用了pic.jsp来获取图片)
    <%@ page language="java" contentType="text/html; charset=UTF-8"
    	pageEncoding="UTF-8"%>
    <%@ page import="java.util.*,org.jbpm.api.*,java.io.*"%>
    <%
    	String id = request.getParameter("id"); // 获取流程实例ID
    	ProcessEngine processEngine = Configuration.getProcessEngine();
    	RepositoryService repositoryService = processEngine
    			.getRepositoryService();
    	ExecutionService executionService = processEngine
    			.getExecutionService();
    	ProcessInstance processInstance = executionService
    			.findProcessInstanceById(id); // 根据ID获取流程实例
    	String processDefinitionId = processInstance
    			.getProcessDefinitionId();
    	ProcessDefinition processDefinition = repositoryService
    			.createProcessDefinitionQuery()
    			.processDefinitionId(processDefinitionId).uniqueResult();
    	InputStream inputStream = repositoryService.getResourceAsStream(
    			processDefinition.getDeploymentId(), "leave.png");
    	
    	byte[] b = new byte[1024];
    	int len = -1;
    	OutputStream ops = response.getOutputStream();
    	while ((len = inputStream.read(b, 0, 1024)) != -1) {
    		ops.write(b, 0, len);
    	}
    %>

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

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

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




  相关解决方案