Posted on 2010-01-15 23:29
長城 閱讀(734)
評論(0) 編輯 收藏
來到北京,今天的天氣似乎是最好的,希望不要再有降溫天氣了。今日繼續我們的審批流程,今天的內容似乎有點多,同學們需要努力學習哦!
我個人認為今天的內容多,是為因今天加入了測試部分。使用JBPM開發OA系統,說簡單些就是將自定義表單數據放到JBPM工作流中流轉。我們所需要實現的功能就是,使用戶可以向系統中部署自定義工作流,用戶可以自己添加自定義表單。我們通過編寫通用表單實體,讓任何自定義表單在工作流中流轉即可。
我來總結一下今天的各部分重點內容。
一、表單定義
我們可以使用FCKEDIT這個免費的工具來設計自定義表單,但我們并未使用外部工具。而是自己編寫了一個簡單的表單設計工具,在下面我會一一介紹。
與其他模塊一樣,我們需要為表單定義(表單模板管理)編寫自己的DispathcAction,根據下面的表單模板管理流程,編寫DispatchAction。

在實現DispatchAction有必須先定義struts的ActionForm和表單定義的實體(FormDefinition),因為我們的OA系統可以添加任意自定義的表單,所以我們需要編寫一個通用的ActionForm和FormDefinition。實體中具有哪些屬性字段,是這里的難點。湯老師,在OA項目的第一就領著大家把事個系統簡單分析了一下,之后的每次講課都從大模塊框架開始。因為只有講了整個相關功能的大模塊應用,才能更好的理解這些小模塊需要什么,比如下面定義的實體是因為在生成表單實例時、提交申請和工作流流轉時使用。我們先來看一下實體的全景圖:

(新增加:FormDefinition、FormInstance、ApproveInfo,今日我們只學習FormDefinition)
FormDefinitionActionForm:
public class FormDefinitionActionForm extends ActionForm { private static final long serialVersionUID = 1L; private Long id; private String name; // 自定義表單名稱 private String templatePath;// 自定義表單存放路徑(html) private String processName;// 自定義表單使用的流程名稱 private String[] propertyNameList; // 存放表單字段名稱的數組與propertyValueTypeList對應 private Class[] propertyValueTypeList;// 存放表單字段類型的數組與propertyNameList對應 // setters and getters… } |
FormDefinition:
public class FormDefinition { private Long id; private String name; // 自定義表單名稱 private String templatePath;// 自定義表單存放路徑(html) private String processName;// 自定義表單使用的流程名稱 // 存放表單字段名稱與字段類型的MAP private Map<String,Class> fieldDefinitionList = new HashMap<String, Class>(); // setters and getters… } |
一如繼往還需要一個FormDefinitionService和FormDefinitionService,不需要為它們添加任何額外實現直接繼承自DaoBase就可以了,因為jbpm也使用hibernate哦!而我們的DaoBase是一個通用的數據庫基本操作。
DispatchAction:
1.表單定義列表
/** * 顯示自定義表單列表 */ public ActionForward list(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { // 查詢數據列表并將信息添加到request的formDefinitionList屬性中 List<FormDefinition> formDefinitionList = formDefinitionService.findAll(); request.setAttribute("formDefinitionList", formDefinitionList); return mapping.findForward("list"); // list.jsp } |
2.顯示添加表單頁面
/** * 添加自定義表單頁面 */ public ActionForward addUI(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { // 獲取自定義表單需要使用的流程信息 List<String> processNameList = processDefinitionService .findAllNameList(); // 將流程信息添加到request中,用于在頁面顯示 request.setAttribute("processNameList", processNameList); return mapping.findForward("addUI"); // addUI.jsp } |
3.添加表單
/** * 添加自定義表單 */ public ActionForward add(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { // 獲取表單提單過來的信息 FormDefinitionActionForm actionForm = (FormDefinitionActionForm) form; // 將ActionForm中的信息封裝到FormDefinition中 FormDefinition formDefinition = new FormDefinition(); BeanUtils.copyProperties(formDefinition, actionForm); // 下面就是用戶自定義的所有表單字段 for (int i = 0; i < actionForm.getPropertyNameList().length; i++) { String name = actionForm.getPropertyNameList()[i]; Class valueType = actionForm.getPropertyValueTypeList()[i]; // 判斷字段名稱是否有效 if (name != null && name.trim().length() > 0) { formDefinition.getFieldDefinitionList().put(name, valueType); } } // 保存表單定義 formDefinitionService.save(formDefinition); return mapping.findForward("toList"); } |
4.刪除表單
/** * 刪除自定義表單 */ public ActionForward del(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { // 獲取將被刪除的表單記錄id Long id = Long.parseLong(request.getParameter("id")); formDefinitionService.delete(id); return mapping.findForward("toList"); } |
二、設計流程
我們學習的內容以“請假流程”為例。
1. 設計流程
開始->提交申請->部門經理審批->結束:

| 開始 |
為其添加一個名稱為“提交申請”的Task,設置它的Assignment的Actor為“#{applicantActorId}”。 |
為其添加一個名稱為“審批”的Task,設置它的Assignment的handler為“cn.itcast.oa.process.leave.DeptManagerAssignmentHandler”。 |
結束 |
DeptManagerAssignmentHandler類的實現明天再列出,將上面設計的流程部署到OA項目中。然后編寫測試類對流程進行測試。因為使用JBPM流程在前邊已經講過了,所以在些就不詳細列出了。上面的流程執行過程為,開始:創建流程實例à辦理任務:提交申請à辦理任務:部門經理審批à結束。
三、表單實例
我們已經將流程定義、表單定義搞定了和測試執行流程,接下來我們應該生成表單實例。將表單實例入到流程中進行流轉處理。
通過第一部分的全景圖我們知道:FormDefinition、FormInstance、ApproveInfo與Employee之間的關系。
FormDefinition:表單定義,能過定義生成實例。
FormInstance:表單實例,一個流程中只能有一個表單實例。
ApproveInfo:審批信息,一個流程中可以具有多個審批。
Employee:職員
FormInstance:
public class FormInstance { // 表單狀態常量 public static final String STATUS_PROCESSING = "正在審批中"; public static final String STATUS_APPROVED = "已通過審批"; public static final String STATUS_NOT_APPROVED = "未通過審批"; private Long id; private FormDefinition formDefinition;// 使用的表單定義 private Map<String, Serializable> propertyMap = new HashMap<String, Serializable>();// 表單信息 private Employee applicant; // 申請人 private Date applyTime; // 申請時間 private String title; // 標題 private String status; // 狀態 private Set<ApproveInfo> approveInfos = new HashSet<ApproveInfo>();// 審批信息 private Long processInstanceId; // 流程實例ID //setters and getters… } |
ApproveInfo:
public class ApproveInfo { private Long id; private Employee approver;//審批人 private Date approveTime;//審批時間 private FormInstance formInstance;//表單實例 private boolean approval;//是否同意 private String comment;//意見 private Long taskInstanceId;//任務實例ID //setters and getters… } |
現在看一看什么才是最重要的?就是這些實體,實體體現了業務邏輯。把業務邏輯搞明白了,實體設計出來了。實現上沒有什么太難的。
明日將學習具體生成表單實例并應用到流程中,生成審批信息等。我們也可以查看自己的申請和待我申請等與審批模塊相關的操作信息。