在这次学习工作流的进程中,工作流如何与业务结合有多种方式,虽然很简单,但是每次都要再次梳理几分钟,这次拿出来整理1下,将它真正成为自己的知识。
从启动流程开始说:
申请页面:选择所用流程(即画的流程图的id)
<table cellpadding="0" cellspacing="0" class="mainForm">
<tr>
<td width="120px">
<div>
所用流程:<s:select name="processDefinitionKey" cssClass="SelectStyle"
list="processDefinitionList" listKey="key" listValue="key"/>
</div>
</td>
</tr>
<tr>
<td>申请名称:</td>
<td><input type="text" name="title" cssClass="InputStyle" /></td>
</tr>
<tr>
<td>申请理由:</td>
<td><input type="text" name="reason" cssClass="InputStyle" /></td>
</tr>
</table>
提交申请:获得前台传来的值
/** 提交申请 */
public String submit() throws Exception {
// 封装申请信息
Application application = new Application();
title=new String(title.getBytes("iso⑻859⑴"),"utf⑻");
reason=new String(reason.getBytes("iso⑻859⑴"),"utf⑻");
application.setApplicant(getCurrentUser()); // 申请人,当前用户
application.setTitle(title);
application.setReason(reason);
String processDefinitionKeyStr=new String(processDefinitionKey.getBytes("iso⑻859⑴"),"utf⑻");
application.setProcessDefinitionKey(processDefinitionKeyStr);
// 调用业务方法(保存申请信息,并启动流程开始流转)
applicationService.submit(application);
return "toMyApplicationList"; // 成功后转到"我的申请查询"
}
public void submit(Application application) {
// 1,设置属性并保存application
application.setApplyTime(sdf.format(new Date())); // 申请时间,当前时间
application.setStatus(Application.STATUS_RUNNING);
// 2,启动程程实例开始流转
// >> 准备流程变量
Map<String, Object> variablesMap = new HashMap<String, Object>();
variablesMap.put("application", application);
// >> 启动流程实例,并带上流程变量(当前的申请信息)
//获得流程定义的key
String pdKey = application.getProcessDefinitionKey();
//根据流程定义的key值和相应的流程变量启动流程
ProcessInstance pi = processEngine.getExecutionService()//
.startProcessInstanceByKey(pdKey, variablesMap);
application.setExecuteId(pi.getId());
getSession().save(application); // 保存
// >> 办理完第1个任务“提交申请”
Task task = processEngine.getTaskService()//
.createTaskQuery()// 查询出本流程实例中当前唯一的1个任务“提交申请”
.processInstanceId(pi.getId())//
.uniqueResult();
processEngine.getTaskService().completeTask(task.getId());
}
当点击提交申请时application,我们来看看工作流的各个表的变化:
jbpm4_execution:
jbpm4_task:
jbpm4_variable:
那末通过查看上面表的变化,我们不难发现履行的流程是通过甚么和业务绑定的,即jbpm4_execution和jbpm4_variable的关系。
从流程的启动开始,就与业务绑定关系,那末接下来如何利用呢?
下面只是简单介绍,对1些结合业务的查询问题会单独再说明:
查看待办任务:1般是根据用户名来查看(当前登陆用户)
/** 待我审批(我的任务列表) */
public String myTaskList() throws Exception {
List<TaskView> taskViewList = applicationService.getMyTaskViewList(getCurrentUser());
//List<TaskView> taskViewList = applicationService.getMyTaskViewList(user);
ActionContext.getContext().put("taskViewList", taskViewList);
return "myTaskList";
}
审批处理:
本环节由于单独出来有1个审批意见表,故会将所有的审批意见添加的审批意见表中,故这个环节的内容是保存数据然后办理任务并判断流程是不是结束。固然我们也能够不单独设计审批意见表,而是将所有的审批意见存储到流程变量中。
办理任务需要获得任务id,也就是在查看任务列表中获得taskViewList。
审批处理页面,审批处理:
/** 审批处理页面 */
public String approveUI() throws Exception {
Set<String> outcomes = applicationService.getOutcomesByTaskId(taskId);
ActionContext.getContext().put("outcomes", outcomes);
return "approveUI";
}
/** 审批处理 */
public String approve() throws Exception {
// 封装
ApproveInfo approveInfo = new ApproveInfo();
comment=new String(comment.getBytes("iso⑻859⑴"),"utf⑻");
approveInfo.setComment(comment);
approveInfo.setApproval(approval);
approveInfo.setApplication(applicationService.getById(applicationId));
approveInfo.setApprover(getCurrentUser()); // 审批人,当前登录用户
approveInfo.setApproveTime(sdf.format(new Date())); // 当前时间
if(outcome!=null){
// 调用用业务方法(保存本次审批信息,并办理完任务,并保护申请的状态)
outcome=new String(outcome.getBytes("iso⑻859⑴"),"utf⑻");
}
applicationService.approve(approveInfo, taskId, outcome);
return "toMyTaskList"; // 成功后转到待我审批页面
}
//办理任务
public void approve(ApproveInfo approveInfo, String taskId, String outcome) {
// 1,保存本次审批信息
getSession().save(approveInfo);
// 2,办理完任务
Task task = processEngine.getTaskService().getTask(taskId); // 1定要先取出Task对象,再完成任务,否则拿不到,由于履行完就变成历史信息了。
if (outcome == null) {
processEngine.getTaskService().completeTask(taskId);
} else {
processEngine.getTaskService().completeTask(taskId, outcome);
}
// >> 取出所属的流程实例,如果取出的为null,说明流程实例履行完成了,已变成了历史记录
ProcessInstance pi = processEngine.getExecutionService().findProcessInstanceById(task.getExecutionId());
// 3,保护申请的状态
Application application = approveInfo.getApplication();
if (!approveInfo.isApproval()) {
// 如果本环节不同意,则流程实例直接结束,申请的状态为:未通过
if (pi != null) { // 如果流程还未结束
processEngine.getExecutionService().endProcessInstance(task.getExecutionId(), ProcessInstance.STATE_ENDED);
}
application.setStatus(Application.STATUS_REJECTED);
} else {
// 如果本环节同意,而且本环节是最后1个环节,则流程实例正常结束,申请的状态为:已通过
if (pi == null) { // 本环节是最后1个环节,即流程已结束了
application.setStatus(Application.STATUS_APPROVED);
}
}
getSession().update(application);
}
查看流转记录:即类似淘宝查看物流信息类似,完全使用业务信息
/** 查看流转记录 applicationId*/
public String approveHistory() throws Exception {
Application application = applicationService.getById(applicationId);
System.out.println(application.getTitle());
ActionContext.getContext().put("approveInfos", application.getApproveInfos());
return "approveHistory";
}
查看我的申请:完全查看自己的业务信息表便可
/** 我的申请查询 */
public String myApplicationList() throws Exception {
String strHQL="from Application where applicant="+getCurrentUser().getUserId() ;
// 准备数据
List<Application> applicationList = applicationService.findByHql(strHQL);
ActionContext.getContext().put("applicationList", applicationList);
return "myApplicationList";
}
/**
* 查看流程图,高亮当前正在履行的节点
*/
public String showProcessImageUI() throws Exception {
/*boolean isEnded = "true".equals(request.getParameter("isEnded")); // 是不是已履行完
String processInstanceId = getParameter(request, "processInstanceId");*/
//未斟酌是不是完成情况
//boolean isEnded=false;
//启动的实例id
//String processInstanceId="ApplyDepartment.8";
// 1,获得当前正在履行的活动名称
String deploymentId = null;
String processDefinitionId = null;
Set<String> activityNames = null;
status=new String(status.getBytes("iso⑻859⑴"),"utf⑻");
if (!status.equals("审批中")) {
// 已履行完的,就查询历史
HistoryProcessInstance hpi = processEngine.getHistoryService()//
.createHistoryProcessInstanceQuery()//
.processInstanceId(processInstanceId)//
.uniqueResult();
processDefinitionId = hpi.getProcessDefinitionId();
activityNames = new HashSet<String>();
activityNames.add(hpi.getEndActivityName()); // 结束的活动名称
} else {
// 正在履行的,就使用ExecutionService查询
ProcessInstance pi = processEngine.getExecutionService()//
.createProcessInstanceQuery()//
.processInstanceId(processInstanceId)//
.uniqueResult();
processDefinitionId = pi.getProcessDefinitionId();
activityNames = new HashSet<String>(pi.findActiveActivityNames()); // 当前正在履行的活动的名称
}
ActionContext.getContext().put("processDefinitionId", processDefinitionId);
// 2,找出他们的坐标
Set<ActivityCoordinates> coordList = new HashSet<ActivityCoordinates>();
for (String activityName : activityNames) {
ActivityCoordinates coord = processEngine.getRepositoryService().getActivityCoordinates(
processDefinitionId, activityName);
coordList.add(coord);
}
ActionContext.getContext().put("coordList", coordList);
// 3,获得 deploymentId
deploymentId = processEngine.getRepositoryService().createProcessDefinitionQuery()//
.processDefinitionId(processDefinitionId)//
.uniqueResult()//
.getDeploymentId();
ActionContext.getContext().put("deploymentId", deploymentId);
return "showProcessImageUI";
}
总结:
其实写这篇博客的目的是结合工作流的数据库来分析业务与流程是如何绑定的,那末对流程中需要的1些经常使用方法的使用在这里也简单的介绍了1番,这样做的目的也是为后面的Activiti中的利用实例的经常使用方法介绍做个对照,其实不管是JBPM4.4还是它的升级版Activiti本质上都是1样的。