學習資料:《Activiti實戰》java
第六章 任務表單(二)外置表單app
6.3 外置表單ide
考慮到動態表單的缺點(見上節),外置表單使用的更多。單元測試
外置表單的特色:學習
1 頁面的原樣顯示 2 字段值的自動填充
6.3.1 流程定義測試
(1)form文件ui
leave-start.form做爲示例展現(字段要和後面代碼中variables變量的key互相對應):spa
1 <div class="control-group"> 2 <label class="control-label" for="startDate">開始時間:</label> 3 <div class="controls"> 4 <input type="text" id="startDate" name="startDate" class="datepicker" data-date-format="yyyy-mm-dd" required /> 5 </div> 6 </div> 7 <div class="control-group"> 8 <label class="control-label" for="endDate">結束時間:</label> 9 <div class="controls"> 10 <input type="text" id="endDate" name="endDate" class="datepicker" data-date-format="yyyy-mm-dd" required /> 11 </div> 12 </div> 13 <div class="control-group"> 14 <label class="control-label" for="reason">請假緣由:</label> 15 <div class="controls"> 16 <textarea id="reason" name="reason" required></textarea> 17 </div> 18 </div>
(2)流程文件code
這裏只顯示部分xml內容,其餘的一些見上節動態表單。這裏的xml文件只是爲了展現外置表單的使用方法。orm
基本使用方式就是:activiti:formkey="chapter6/leave-formkey/approve.form"
form的值支持動態設置:activiti:formkey="${fooFormName}.form"
1 <process id="leave-formkey" name="請假流程-外置表單"> 2 <startEvent id="startevent1" name="Start" 3 activiti:initiator="applyUserId" 4 activiti:formkey="chapter6/leave-formkey/leave-start.form"> 5 </startEvent> 6 <userTask id="deptLeaderVerify" name="部門經理審批" 7 activiti:candidateGroups="deptLeader" 8 activiti:formkey="chapter6/leave-formkey/approve.form"> 9 </userTask> 10 <userTask id="hrVerify" name="人事審批" 11 activiti:candidateGroups="hr" 12 activiti:formkey="chapter6/leave-formkey/approve.form"> 13 </userTask> 14 <userTask id="reportBack" name="銷假" 15 activiti:assignee="${applyUserId}" 16 activiti:formkey="chapter6/leave-formkey/report-back.form"> 17 </userTask> 18 <userTask id="modifyApply" name="調整申請內容" 19 activiti:assignee="${applyUserId}" 20 activiti:formkey="chapter6/leave-formkey/modify-apply.form"> 21 </userTask> 22 <endEvent id="endevent1" name="End" 23 </endEvent> 24 </process>
(3)單元測試
部署表單流程時須要把bpmn文件和form文件同時打包部署。這樣部署了同名的form文件時多個流程定義,或相同流程不一樣版本之間,都不會有衝突。
1 public class LeaveFormKeyTest extends AbstractTest { 2 3 @Test 4 @Deployment(resources = {"chapter6/leave-formkey/leave-formkey.bpmn", 5 "chapter6/leave-formkey/leave-start.form", 6 "chapter6/leave-formkey/approve-deptLeader.form", 7 "chapter6/leave-formkey/approve-hr.form", 8 "chapter6/leave-formkey/report-back.form", 9 "chapter6/leave-formkey/modify-apply.form"}) 10 11 public void allPass() throws Exception { 12 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); 13 Map<String, String> variables = new HashMap<String, String>(); 14 Calendar ca = Calendar.getInstance(); 15 String startDate = sdf.format(ca.getTime()); 16 ca.add(Calendar.DAY_OF_MONTH, 2); // 當前日期加2天 17 String endDate = sdf.format(ca.getTime()); 18 19 // 啓動流程 20 variables.put("startDate", startDate); 21 variables.put("endDate", endDate); 22 variables.put("reason", "公休"); 23 24 ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().singleResult(); 25 26 // 讀取啓動表單 27 Object renderedStartForm = formService.getRenderedStartForm(processDefinition.getId()); 28 assertNotNull(renderedStartForm); 29 30 // 啓動流程 31 // 設置當前用戶 32 String currentUserId = "henryyan"; 33 identityService.setAuthenticatedUserId(currentUserId); 34 ProcessInstance processInstance = formService.submitStartFormData(processDefinition.getId(), variables); 35 assertNotNull(processInstance); 36 37 // 部門領導審批經過 38 Task deptLeaderTask = taskService.createTaskQuery().taskCandidateGroup("deptLeader").singleResult(); 39 assertNotNull(formService.getRenderedTaskForm(deptLeaderTask.getId())); 40 variables = new HashMap<String, String>(); 41 variables.put("deptLeaderApproved", "true"); 42 formService.submitTaskFormData(deptLeaderTask.getId(), variables); 43 44 // 人事審批經過 45 Task hrTask = taskService.createTaskQuery().taskCandidateGroup("hr").singleResult(); 46 assertNotNull(formService.getRenderedTaskForm(hrTask.getId()));// 讀取任務表單 47 variables = new HashMap<String, String>(); 48 variables.put("hrApproved", "true"); 49 formService.submitTaskFormData(hrTask.getId(), variables); 50 51 // 銷假(根據申請人的用戶ID讀取) 52 Task reportBackTask = taskService.createTaskQuery().taskAssignee(currentUserId).singleResult(); 53 assertNotNull(formService.getRenderedTaskForm(reportBackTask.getId())); 54 variables = new HashMap<String, String>(); 55 variables.put("reportBackDate", sdf.format(ca.getTime())); 56 formService.submitTaskFormData(reportBackTask.getId(), variables); 57 58 // 驗證流程是否已經結束 59 HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().finished().singleResult(); 60 assertNotNull(historicProcessInstance); 61 62 // 讀取歷史變量 63 Map<String, Object> historyVariables = packageVariables(processInstance); 64 65 // 驗證執行結果 66 assertEquals("ok", historyVariables.get("result")); 67 68 } 69 ... 70 }
6.3.2 自定義表單引擎
activiti既能夠能夠支持B/S結構的應用,也能夠支持C/S結構的應用。getRenderd***Form()返回的內容是通過activiti的默認Form引擎處理過的,返回的值能夠讓B/S結構的應用直接使用,可是卻不能直接支持C/S結構的應用。因此若是要生成C/S程序須要的java控件,須要事先自定義的form引擎。
這一塊暫時用不到,略過。
6.3.3 讀取流程啓動表單
Activiti Explorer支持動態表單,卻不支持外置表單。因此須要爲Activiti Explorer增長外置表單支持。