在这里我想说的外置表单,是说我们将我们自己的jsp(.form,.html)等页面上传到工作流的数据库中,当任务执行到当前结点时,给我们像前台发送绑定好的表单。
此处是给表单绑定表单的过程
不同意为:${deptLeaderPass =='false'}
下面我们看对应的页面内容:
start.form简单的html页面:
- <table border="1">
- <tr>
- <td>请假类型:</td>
- <td>
- <select id="leaveType" name="fp_leaveType">
- <option>公休</option>
- <option>病假</option>
- <option>调休</option>
- <option>事假</option>
- <option>婚假</option>
- </select>
- </td>
- </tr>
- <tr>
- <td>开始时间:</td>
- <td><input type="text" id="startTime" name="fp_startTime" class="datetime required" /></td>
- </tr>
- <tr>
- <td>结束时间:</td>
- <td><input type="text" id="endTime" name="fp_endTime" class="datetime required" /></td>
- </tr>
- <tr>
- <td>请假原因:</td>
- <td>
- <textarea id="reason" name="fp_reason"></textarea>
- </td>
- </tr>
- </table>
dept-leader-audit.form页面:
- <table class='view-info'>
- <tr>
- <td width="100" class="label">申请人:</td>
- <td name="userId">${applyUserId}</td>
- </tr>
- <tr>
- <td class="label">假种:</td>
- <td name="leaveType">${leaveType}</td>
- </tr>
- <tr>
- <td class="label">请假<font color="red">开始</font>时间:</td>
- <td name="startTime">${startTime}</td>
- </tr>
- <tr>
- <td class="label">请假<font color="red">结束</font>时间:</td>
- <td name="endTime">${endTime}</td>
- </tr>
- <tr>
- <td class="label">请假事由:</td>
- <td name="reason">${reason}</td>
- </tr>
- <tr>
- <td class="label">是否同意申请:</td>
- <td>
- <select id="deptLeaderPass" name="fp_deptLeaderPass">
- <option value="true">同意</option>
- <option value="false">驳回</option>
- </select>
- </td>
- </tr>
- <tr id="leaderBackReasonTr">
- <td class="label">驳回理由:</td>
- <td>
- <textarea id="leaderBackReason" name="fp_leaderBackReason"></textarea>
- </td>
- </tr>
- </table>
hr-audit.form也类似均是很简单的HTML页面。
对应的核心工作流实现代码:
- /*
- * 启动流程 启动流程,只考虑首次登录。 首次登录:启动工作流,并且更新/{processDefinitionId} @RequestMapping(value = "get-form/start/{processDefinitionId}")
- */
- @RequestMapping(value = "/start/{processDefinitionId}")
- public String start(@PathVariable("processDefinitionId") String processDefinitionId,HttpServletRequest request) throws Exception {
- try {
- // 定义map用于往工作流数据库中传值。
- Map<String, String> formProperties = new HashMap<String, String>();
- //启动流程-何静媛-2015年5月24日--processDefinitionId,
- ProcessInstance processInstance = formService
- .submitStartFormData(processDefinitionId,
- formProperties);
- // 返回到显示用户信息的controller
- logger.debug("start a processinstance: {}", processInstance);
- return "redirect:/workflow/auto/get-form/task/"+ processInstance.getId();
- } catch (Exception e) {
- throw e;
- } finally {
- identityService.setAuthenticatedUserId(null);
- }
- }
- /**
- * 读取Task的表单
- * @RequestMapping(value = "get-form/task/{processDefinitionkey}")
- * @PathVariable("processDefinitionkey") String processDefinitionkey
- */
- @RequestMapping(value = "/get-form/task/{processInstanceId}")
- @ResponseBody
- public ModelAndView findTaskForm(
- @PathVariable("processInstanceId") String processInstanceId,
- HttpServletRequest request) throws Exception {
- ModelAndView mav = new ModelAndView("leave/apply");
- // 获取当前登陆人信息。
- /* User user = UserUtil.getUserFromSession(request.getSession()); */
- TaskQuery taskQuery = taskService.createTaskQuery()
- .processInstanceId(processInstanceId).orderByProcessInstanceId().desc();
- List<Task> tasks = taskQuery.list();
- if (tasks.size()==0) {
- ModelAndView mav2 = new ModelAndView("leave/finish");
- return mav2;
- }
- Task task = tasks.get(0);
- Object renderedTaskForm = formService.getRenderedTaskForm(task.getId());
- System.out.println(renderedTaskForm.toString());
- mav.addObject("renderedTaskForm", renderedTaskForm.toString());//整个页面,参数已经赋值(整个页面是什么时候赋上值的?)
- mav.addObject("taskId", task.getId());
- mav.addObject("processInstanceId", processInstanceId);
- return mav;
- }
- /**
- * 办理任务,提交task的并保存form
- */
- @RequestMapping(value = "task/complete/{taskId}/{processInstanceId}")
- @SuppressWarnings("unchecked")
- public String completeTask(@PathVariable("taskId") String taskId,@PathVariable("processInstanceId") String processInstanceId, RedirectAttributes redirectAttributes, HttpServletRequest request) {
- Map<String, String> formProperties = new HashMap<String, String>();
- // 从request中读取参数然后转换
- Map<String, String[]> parameterMap = request.getParameterMap();
- Set<Entry<String, String[]>> entrySet = parameterMap.entrySet();
- for (Entry<String, String[]> entry : entrySet) {
- String key = entry.getKey();
- /*
- * 参数结构:fq_reason,用_分割 fp的意思是form paremeter 最后一个是属性名称
- */
- if (StringUtils.defaultString(key).startsWith("fp_")) {
- String[] paramSplit = key.split("_");
- formProperties.put(paramSplit[1], entry.getValue()[0]);
- }
- }
- logger.debug("start form parameters: {}", formProperties);
- try {
- formService.submitTaskFormData(taskId, formProperties);
- } finally {
- identityService.setAuthenticatedUserId(null);
- }
- redirectAttributes.addFlashAttribute("message", "任务完成:taskId=" + taskId);
- return "redirect:/workflow/auto/get-form/task/"+processInstanceId;
- }
那么对应的提交表单的方式怎么实现的呢?
Apply.jsp
- <%@ page language="java" contentType="text/html; charset=UTF-8"
- pageEncoding="UTF-8"%>
- <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
- <html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
- <title>申请信息</title>
- </head>
- <body>
- <form name="form1" id="form1" action="${pageContext.request.contextPath}/workflow/auto/task/complete/${taskId}/${processInstanceId}">
- <div style="margin: 0 auto;">${renderedTaskForm}</div>
- <input type="hidden" name="taskId"
- value="${taskId}">
- <input type="hidden" name="processInstanceId"
- value="${processInstanceId}">
- <div>
- <table style="margin: auto" width="600">
- <tr>
- <td align="right" >
- <input type="submit" value="下一步" />
- </td>
- </tr>
- </table>
- </div>
- </form>
- </body>
- </html>
我们让所有的表单(在没有完成任务时,均返回到apply.jsp页面中,可以让每个页面均添加上下一步的按钮)因为对于完成来说,所有的任务均对应以上的方法实现。
总结:使用这种外置表单的方式相比我们静态表单的方式有什么区别呢?
1,外置表单的方式不需要我们建立任何实体,所有的数据均存放到工作流的数据库,任何业务来了均可以使用,当然工作流也支持保存到工作流库中的数据的所有查询操作,直接调用相应的api即可。
2,需要我们画简单的html页面,对于提交表单等的操作可以使用js单独来操作,如果添加到jsp或html页面中,工作流表单在执行时是不识别的,会报错误
附录:demo说明
1,修改连接的数据库
2,初始化用户,初始化脚本在src/resources目录下
3,访问地址http://localhost:8080/activitiDemo
4,登录后,需要部署流程才可以使用,流程文件在diagrams文件夹下,打成压缩包上传即可。