前两天我们已经完成了流程定义的管理和表单的定义的管理。今天们将整合这两大模块,使他们形成一个标准的工作流程。
在学习 OA 项目时,就像学习其他知识一样跟着老师的思路走。有的时候东西讲的比较多就一头雾水,这是正常的。但最近我在写学习总结时候发现老师讲的东西很简单,为什么我们会一头雾水?原因一,我们用错的学习方法。首先老师讲的是什么他已经给了我们框架了,所以在老师讲某个东西时我们要在自己的脑子里有一个宏观的实现框架。然后再去听细节,这样老师无论怎么讲我们都在自己的框架内。如果自己的框架错了就改一下。原因二,我们畏惧新知识,未知领域是我们意象中的巨大敌人。这是错误的,我们应该像那样,我们应该藐视敌人。
你知道吗?我近两天就使用这样的方法,老师讲什么我先在自己的脑子中有框架。然后十分藐视 OA 项目,我看它看得非常简单。当老师讲完某一应用时,我发现自己的框架和实现过程是完全正确的。我应该继续保持和提升这样的方法,加强以后的工作和学习效率。
只要我们用心去体会与发现身边的事物,我们就可以从他们身上获得更多的知识。我写日志本想是能在文字和文章结构上有所提升,但现在提升的远不只这些。清晰的思路,对知识点的掌握 … 。
今日的重点内容是将表单实例与流程实例整合运行,关于各申请信息的查询在此就不做总结了。
一、 审批流转 之起草申请
起草申请便是将所有添加的申请表单列出来,然后用户选择相应的申请表单并填写,然后提交申请:
下面我们来看一下 ApprovalflowAction 的实现:
1. 起草申请
/**
* 起草申请(表单定义列表)
*/
public ActionForward list(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
// 获取表单定义列表
List<FormDefinition> formDefinitionList = formDefinitionService
.findAll();
request.setAttribute( "formDefinitionList" , formDefinitionList);
return mapping.findForward( "list" ); // list. jsp
}
|
有关 service 的实现,我就不列出来了,因为那十分简单。
2. 申请页面
我们应该如何显示自定义表单?在“ FormDefinition ”实体中有一个“ templatePath ”属性,我们在显示页面调用“ < jsp:include page = " ${formInstance.formDefinition.templatePath} " /> ”即可显示相关表单。
/**
* 申请页面(填写表单的页面)
*/
public ActionForward applyUI(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
// 获取表单定义 ID
Long id = Long. parseLong (request.getParameter( "formDefinitionId" ));
// 获取表单文件路径
FormDefinition formDefinition = formDefinitionService .getById(id);
return new ActionForward (formDefinition.getTemplatePath());
}
|
3. 提交申请
/**
* 提交表单
*/
public ActionForward apply(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
// 获取表单定义
Long formDefinitionId = Long. parseLong (request
.getParameter( "formDefinitionId" ));
FormDefinition formDefinition = formDefinitionService
.getById( formDefinitionId );
// 获取当前用户
User user = (User) request.getSession().getAttribute( "user" );
// 创建表单实例
FormInstance formInstance = new FormInstance();
formInstance.setApplicant(user.getEmployee());
formInstance.setApplyTime( new Date());
formInstance.setFormDefinition(formDefinition);
// 保存表单数据
for (String name : formDefinition.getFieldDefinitionList().keySet()) {
String strValue = request.getParameter(name);
Class valueType = formDefinition.getFieldDefinitionList().get(name);
Converter converter = ConvertUtils. lookup (valueType);
Serializable value = (Serializable) converter.convert(valueType,
strValue);
formInstance.getPropertyMap().put(name, value);
}
// 提交
formInstanceService .submitFormInstance(formInstance);
// 转到我的申请列表
return mapping.findForward( "toMyApplicationList" );
}
|
我们有必要,列出“ submitFormInstance ”方法的实现。提交申请后,我们需要将申请数据保存到数据库中。并开启流程,使流程开始流转:
/**
* 保存申请并开始流转
*/
public void submitFormInstance(FormInstance formInstance) {
// 保存表单数据
getSession().save(formInstance);
//------------------ 开启流程 ---------------
// 创建流程实例
ProcessDefinition pd = getJbpmContext().getGraphSession().findLatestProcessDefinition( "leave" );
ProcessInstance pi = pd.createProcessInstance();
// 设置变量
String applicantActorId = formInstance.getApplicant().getId().toString();
// 第一个任务分配给(在这里是申请人)
pi.getContextInstance().setVariable( "applicantActorId" , applicantActorId);
// 申请的数据
pi.getContextInstance().setVariable( "formInstance" , formInstance);
// 更新 FormInstance
// 标题格式: { 表单名称 }_{ 申请人姓名 }_{ 申请日期 }
formInstance.setTitle(formInstance.getFormDefinition().getName() + "_" + formInstance.getApplicant().getName() + "_" //
+ sdf .format(formInstance.getApplyTime()));
// 设置状态为:正在流转 ...
formInstance.setStatus(FormInstance. STATUS_PROCESSING );
formInstance.setProcessInstanceId(pi.getId());
// Signal
pi.signal();
// 办理任务:提交申请
TaskInstance ti = (TaskInstance) pi.getTaskMgmtInstance() //
.getUnfinishedTasks(pi.getRootToken()) //
.iterator().next();
ti.start();
// 此处会自动将下一个任务触发(保存到数据库中)
ti.end();
}
|
OK ,上面就完成了起草申请的整个过程!