Posted on 2010-01-17 14:03
長城 阅读(734)
评论(1) 编辑 收藏
前两天我们已经完成了流程定义的管理和表单的定义的管理。今天们将整合这两大模块,使他们形成一个标准的工作流程。
在学习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,上面就完成了起草申请的整个过程!
二、审批流转之待我审批
待我审批,查看数据库中的任务记录,那些分配给“我”(由“我”负责)的任务,便是待我审批的任务。
1.待我审批
/** * 待我审批(我的任务列表) */ public ActionForward taskList(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { // 获取当前页码 int pageNum = RequestUtils.getIntParam(request, "pageNum", 1); // 获取当前用户 User user = (User) request.getSession().getAttribute("user"); // 当前用户 未完成的 任务列表 PageView pageView = formInstanceService.getTaskPageView(user .getEmployee(), pageNum); request.setAttribute("pageView", pageView); return mapping.findForward("taskList"); } |
其中的“formInstanceService.getTaskPageView”如下:
// 查询TaskInfo的列表 @SuppressWarnings("unchecked") public PageView getTaskPageView(Employee employee, int pageNum) { int pageSize = 10; // 获取待我审批的任务数量 int count = ((Number) getSession().createQuery(// "SELECT COUNT(ti) FROM org.jbpm.taskmgmt.exe.TaskInstance ti WHERE actorId=? AND ti.end IS NULL")// .setParameter(0, employee.getId().toString())// .uniqueResult())// .intValue(); // 获取待我审批的任务列表 int firstResult = PageView.calcFirstResult(pageNum, pageSize); List<TaskInstance> taskInstanceList = getSession().createQuery(// "FROM org.jbpm.taskmgmt.exe.TaskInstance ti WHERE actorId=? AND ti.end IS NULL")// .setParameter(0, employee.getId().toString())// .setFirstResult(firstResult)// .setMaxResults(pageSize)// .list(); // 页面中需要显示表单实例信息,且仅需要任务实例的ID List<FormInstance> formInstanceList = new ArrayList<FormInstance>(); for (TaskInstance ti : taskInstanceList) { FormInstance formInstance = (FormInstance) ti.getContextInstance().getVariable("formInstance"); formInstance.setCurrentTaskInstanceId(ti.getId()); formInstanceList.add(formInstance); } // 显示 return new PageView(pageNum, pageSize, count, formInstanceList); } |
2.审批页面
/** * 审批页面 */ public ActionForward approveUI(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { // 获取表单实例ID Long formInstanceId = Long.parseLong(request .getParameter("formInstanceId")); // 获取表单实例,表单实例包含审批信息 FormInstance formInstance = formInstanceService.getById(formInstanceId); request.setAttribute("formInstance", formInstance); return mapping.findForward("approveUI"); } |
3.审批
/** * 审批 */ public ActionForward approve(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { // 获取表单数据 ApproveInfoActionForm actionForm = (ApproveInfoActionForm) form; FormInstance formInstance = formInstanceService.getById(actionForm .getFormInstanceId()); // 获取当前用户 User user = (User) request.getSession().getAttribute("user"); // 创建审批信息 ApproveInfo approveInfo = new ApproveInfo(); approveInfo.setApprover(user.getEmployee()); approveInfo.setApproveTime(new Date()); approveInfo.setApproval(actionForm.isApproval()); approveInfo.setComment(actionForm.getComment()); approveInfo.setTaskInstanceId(actionForm.getTaskInstanceId()); approveInfo.setFormInstance(formInstance); // 审批 formInstanceService.approve(approveInfo); return mapping.findForward("toTaskList"); } |
其中的“formInstanceService.approve”如下:
/** * 审批 */ public void approve(ApproveInfo approveInfo) { // 保存审批信息 getSession().save(approveInfo); // 办理任务:审批 FormInstance formInstance = approveInfo.getFormInstance(); TaskInstance ti = getJbpmContext().getTaskInstance(approveInfo.getTaskInstanceId()); ProcessInstance pi = ti.getProcessInstance(); // 如果未通过 if (!approveInfo.isApproval()) { // 停止任务向下流转 ti.setSignalling(false); ti.start(); ti.end(); // 结束流程实例 pi.end(); // 设置流程状态为“未通过审批” formInstance.setStatus(FormInstance.STATUS_NOT_APPROVED); } // 如果审批通过 else { // 正常执行任务,向下流转 ti.start(); ti.end(); // 如果流程已结束, 就代表本次为最后一个审批 if (pi.hasEnded()) { // 设置流程状态为“已通过审批” formInstance.setStatus(FormInstance.STATUS_APPROVED); } } // 需要手动更新流程数据(如果FormInstance的lazy属性为false呢!) getSession().update(formInstance); } |
OK,待我审批完成!
三、表单查询
这部分的内容有“我的申请”、“经我审批”和“所有表单”,其中涉及条件查询在此就不一一总结了。不过这些模块中有一个十分有趣的功能——“查看流程图”。
在以前的工作中,我经涉及到图片和画板的应用开发。我的查看流程图思路是将图片画到画板上然后根据坐标信息(gpd.xml)画出对应流程模块的矩形,然后保存图板图,最后将图片显示到页面。但汤老师的实现比较优雅,直接将流程图显示到页面,然后向页面中添加一个div,并设置div的坐标、尺寸和边框颜色。
由此可见,我还需要一些工作经验将这些技术熟练掌握!
通过OA项目的学习,使我知道应该如何学习下一个项目——《教育办公系统》。希望自己能将这个系统做的更好!
加油!