Posted on 2010-01-17 14:03
長城 閱讀(736)
評論(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項目的學習,使我知道應該如何學習下一個項目——《教育辦公系統》。希望自己能將這個系統做的更好!
加油!