在上一篇的获得我的申请中,可以看到js代码中还包含了预览和完成任务的代码,既然上一篇已经罗列了相关代码,这里也就不重复。
那么需要补充的是,在上边的完成任务的js代码中,我们还调用了getTaskForm请求,目的是从后台获取提交任务时的其他数据,例如指定下一个处理人等,当然了,根据不同的业务逻辑可能有所变化。
那么这个请求对应的后台代码如下,如果弄明白了整个数据库的设计,那么对于这些代码就很容易明白。
@RequestMapping(value = "/getTaskForm.do", method = RequestMethod.POST, produces = "application/json;charset=utf-8") @ResponseBody public Object getTaskForm(@RequestBody String taskFormKey) { Map<String, String> map = new HashMap<String, String>(); //System.out.println(taskFormKey); taskFormKey = taskFormKey.replace("=", ""); String form = myFormService.findFormByFormName(taskFormKey); // (String)formService.getRenderedTaskForm(taskFormKey); map.put("form", form); return map; }
这里边的findFormByFormName方法在前边的章节中讲过,就是很简单的根据一个字段查询整条记录的操作。
那么这里补充的说明完了,下一步就是提交申请,把任务交到下一个人的手上,也就是上边的js中的complete.do请求,这个请求的后台代码如下:
/** * @throwsXMLStreamException * 完成个人任务 * * @author:tuzongxun * @Title: completeTask * @param@return * @return Object * @date Mar 17, 20164:55:31 PM * @throws */ @RequestMapping(value = "/completeTask.do", method = RequestMethod.POST, produces = "application/json;charset=utf-8") @ResponseBody public Object completeTask(HttpServletRequest req) throws XMLStreamException { Map<String, String[]> formMap = req.getParameterMap(); String taskId = (String) formMap.get("taskId")[0]; boolean isLogin = this.isLogin(req); if (isLogin) { if (taskId != null) { // 根据taskName和流程节点中的名字判断当前节点之后是否还有任务 Task task = taskService.createTaskQuery().taskId(taskId) .singleResult(); String taskName = task.getName(); Iterator<FlowElement> flows = this.findFlow(task .getProcessDefinitionId()); String row0 = null; Map<String, Object> formProperties = new HashMap<String, Object>(); while (flows.hasNext()) { FlowElement flowElement = flows.next(); // 找到当前节点,查询出下下一个节点是否是结束节点,如果不是则需要设置下一个任务人,否则直接保存相关流程变量结束 // 同时要查处当前任务的行数用来设置流程变量名称 if (taskName.equals(flowElement.getName())) { // 设置行号 row0 = flowElement.getXmlRowNumber() + ""; FlowElement flowElement3 = flows.next(); System.out.println("SequenceFlow".equals(flowElement3 .getClass().getSimpleName())); if ("SequenceFlow".equals(flowElement3.getClass() .getSimpleName())) { SequenceFlow seq = (SequenceFlow) flowElement3; System.out.println(seq.getConditionExpression() + "," + seq.getName()); } FlowElement flowElement2 = flows.next(); // 当前任务不是最后一个任务,流程没有结束,需要设置下一个处理人 if (flowElement2 != null && !("EndEvent".equals(flowElement2.getClass() .getSimpleName()) && !("SequenceFlow" .equals(flowElement2.getClass() .getSimpleName())))) { UserTask userTask = (UserTask) flowElement2; // 获取userTask中的 String assignee = userTask.getAssignee(); int index1 = assignee.indexOf("{"); int index2 = assignee.indexOf("}"); String person1 = (String) formMap.get("data_1")[0]; formProperties.put( assignee.substring(index1 + 1, index2), person1); } break; } } // 从request中读取参数然后转换0 Set<Entry<String, String[]>> entrySet = formMap.entrySet(); for (Entry<String, String[]> entry : entrySet) { String key = entry.getKey() + row0; String value = entry.getValue()[0]; if (!key.equals("taskId")) { formProperties.put(key, value); } } taskService.complete(taskId, formProperties); ; } } return null; }
因为这一个完成任务的方法和之后处理别人提交给自己的任务方法共用了,因此我便同时列出查询别人提交给我的任务的后台代码,如下:
/** * @throwsXMLStreamException * 查询别人提交给我的任务 * * @author:tuzongxun * @Title: findTask * @param@return * @return Object * @date Mar 17, 20162:44:11 PM * @throws */ @RequestMapping(value = "/findTask.do", method = RequestMethod.POST, produces = "application/json;charset=utf-8") @ResponseBody public Object findTask(HttpServletRequest req) throws XMLStreamException{ Map<String, Object> map = new HashMap<String, Object>(); boolean isLogin = this.isLogin(req); if (isLogin) { List<TaskModel> taskList = new ArrayList<TaskModel>(); HttpSession session = req.getSession(); String assginee = (String) session.getAttribute("userName"); List<Task> taskList1 = taskService.createTaskQuery() .taskAssignee(assginee).list(); if (taskList1 != null && taskList1.size() > 0) { for (Task task : taskList1) { TaskModel taskModel = new TaskModel(); // 获取部署名 String processdefintionId = task.getProcessDefinitionId(); ProcessDefinition processDefinition = repositoryService .createProcessDefinitionQuery() .processDefinitionId(processdefintionId) .singleResult(); // 根据taskname和节点判断是否是第一个 String taskName = task.getName(); Iterator<FlowElement> iterator = this .findFlow(processdefintionId); String row0 = null; String eleName0 = null; String rowStart = null; // 保存上上一个节点的信息 FlowElement flowElement00 = null; findFole: while (iterator.hasNext()) { FlowElement flowElement0 = iterator.next(); // 注意usertask下一个节点是连线而不是task FlowElement flowElement = null; String eleName = null; // 得到流程启动节点的行号 if (flowElement0.getClass().getSimpleName() .equals("StartEvent")) { rowStart = flowElement0.getXmlRowNumber() + ""; // 如果当前不是连线,则下一个是 } else if (flowElement0 != null && !(flowElement0.getClass().getSimpleName() .equals("SequenceFlow")) && iterator.hasNext()) { do { iterator.next(); if (iterator.hasNext()) { flowElement = iterator.next(); eleName = flowElement.getName(); // 下下一个节点 if (taskName.equals(eleName)) { row0 = flowElement0.getXmlRowNumber() + ""; eleName0 = flowElement0.getClass() .getSimpleName(); flowElement00 = flowElement0; break findFole; } else { flowElement0 = flowElement; } } } while (true); } } // 此处需要修改,怎么判断是别人提交给我的?如果当前节点名是申请,那么当上一个节点类名是StartEvent时,证明是自己的申请 if (eleName0 != null && !("StartEvent".equals(eleName0))) { // 先查询出上一个任务(已完成),根据流程实例id List<HistoricTaskInstance> hisTaskList = historyService .createHistoricTaskInstanceQuery() .processDefinitionId(processdefintionId) .finished() .orderByHistoricTaskInstanceEndTime().desc() .list(); String formName = null; if (hisTaskList != null && hisTaskList.size() > 0) { HistoricTaskInstance historicTaskInstance = hisTaskList .get(0); formName = historicTaskInstance.getFormKey(); String form = this.getTaskForm1(formName); taskModel.setLastForm(form); } // 当是别人提交过来的任务时,form就应该是任务相关的form,task里边保存的有formName taskModel.setAssignee(task.getAssignee()); taskModel.setCreateTime(task.getCreateTime()); taskModel.setId(task.getId()); taskModel.setName(task.getName()); taskModel.setProcessInstanceId(task .getProcessInstanceId()); taskModel .setProcessDefId(task.getProcessDefinitionId()); taskModel.setFormKey(task.getFormKey()); String deploymentId = processDefinition .getDeploymentId(); Deployment deployment = repositoryService .createDeploymentQuery() .deploymentId(deploymentId).singleResult(); String deploymentName = deployment.getName(); taskModel.setDeploymentName(deploymentName); List<HistoricVariableInstance> variables = historyService .createHistoricVariableInstanceQuery() .processInstanceId(task.getProcessInstanceId()) .list(); // 获取上一个节点填写的数据 Map<String, String> formData = new HashMap<String,String>(); Map<String, String> formData1 = new HashMap<String,String>(); for (HistoricVariableInstance variableInstance : variables) { System.out.println(variableInstance); String varName = variableInstance.getVariableName(); System.out.println(varName); System.out.println(variableInstance.getValue()); if (varName.contains(row0)) { formData.put(varName, (String) variableInstance.getValue()); } if (varName.contains(rowStart)) { formData1.put(varName, (String) variableInstance.getValue()); } } // 获取流程启动时填写的数据,即申请数据 // 获取流程启动的表单form String firstForm = this.getStartForm1(deploymentId); // 这里的代码提取出去成为getStartFormAndData StringBuffer firstFormAndData = setFormAndData( rowStart, formData1, firstForm); taskModel.setFirstFormAndData(firstFormAndData .toString()); taskModel.setFormData(formData); taskList.add(taskModel); } } } map.put("isLogin", "yes"); map.put("userName", (String) req.getSession().getAttribute("userName")); map.put("result", "success"); map.put("data", taskList); } else { map.put("isLogin", "no"); } return map; }
我觉得这里边最重要的便是如何判断究竟是别人提交给我的,还是我自己申请的任务,而这里边如果用流程节点flowElevent来判断的话,会出现一些问题,因为我操作的过程中发现,当一个任务后便的连线不唯一时,各个节点的顺序也是不固定的,endEvent并不一定就在最后边,因此还需要从其他的地方进行判断。
如果有需要了解的朋友,可以把之前的那个我的申请列表的代码和这个一起拿到eclipse中对比一下,然后大概就能了解个七七八八了。
那么对于我的任务,也就是别人提交给我的任务列表,其相关的前端代码,与我的申请的前端代码非常类似,我也就不列出了。
还有之后的历史任务等等,也都可以结合之前的内容,只要了解了流程节点的结构,以及各个表的关联关系,那么简单实现自定义应该就不是太难。难得就是真正的要逻辑非常缜密,然后更加智能。