您的位置:首页 > 产品设计 > 产品经理

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

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

leave.jpdl.xml



[html] view
plaincopy

<?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>

login.jsp

由于在测试的过程中,要展示某某用户有哪些待办流程,或者某某用户发起了一个新流程,所以,做了一个简易的登录页面,登录后,保存当前登录的userName。

[html] view
plaincopy

<%@ 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>

效果图如下:



index.jsp

在index页面,有显示流程列表,显示已经启动的流程列表,有待办任务列表

[html] view
plaincopy

<%@ 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>

页面展示效果如下:



deploy.jsp

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



[java] view
plaincopy

<%@ 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页面的效果如下:



start.jsp

点击首页流程列表中的“开始”,将当前的流程ID获取到,然后根据这个流程ID来启动一个流程

[java] view
plaincopy

<%@ 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页面的效果图如下:



request.jsp

假设当前登录用户为owner,由owner发起的流程,现在进入了申请阶段。任务列表中显示的是属于当前用户的待办列表。点击进去查看详情并提交申请。

[html] view
plaincopy

<%@ 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>

效果图如下:



submit.jsp

当申请人提交了申请之后,我们需要获取其申请单提交的表单元素,将其执行使之进入下一步流程

[java] view
plaincopy

<%@ 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的名下;如下图:



manager.jsp

点击index的待办任务列表中“查看”时,JBPM会根据在leave.jpdl.xml中的配置的form属性,自动跳转到manager页面进行经理的审批和驳回;

[html] view
plaincopy

<%@ 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>

效果图如下:



submit_manager.jsp

manager在提交了审批结果之后,在这里要处理经理提交的结果,批准或者驳回

[java] view
plaincopy

<%@ 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页面,属于经理的待办任务已经没了。并且,流程的实例列表也空了,证明这个流程已经流转完毕;如下图:



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



view.jsp和pic.jsp

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



然后view页面会将此时流程图显示出来,并且能看到当前走到了哪一步;要实现这个,必须进行以下三步:

第一:将leave.jpdl.xml和自动生成的leave.png打包到一个leave.zip文件中(注意不要包含任何一层多的文件夹),并且存放在src下或者根目录下。如下图:





第二:view.jsp

[html] view
plaincopy

<%@ 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来获取图片)

[java] view
plaincopy

<%@ 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,现在我们来看看,当前的展示效果:



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

boss.jsp,submit_boss.jsp

这个页面来处理经理审批过后,大于3天的请假流程(规则在leave.jpdl.xml中定义)。

需要查看详细代码和运行效果,请下载我的完整项目:

链接稍后奉上!

点击此处去下载完整Demo
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: