赞
踩
基于开源项目KonBAI / RuoYi-Flowable-Plus使用的部分功能调整。原代码展示所有节点配置的自定义表单。现因系统配置要求,需且过滤掉未填写的发起人节点空表单。
根据RuoYi-Flowable-Plus开发文档,一个工作流程的申请节点必须由以下两点组成:
1.startEvent(开始事件节点):配置自定义申请表单
2.userTask(发起人用户任务节点):审批人选择发起人
当流程实例启动时,第一个用户任务为发起人,则自动完成任务轮到下一节点(eg:审批)。当在开始节点和发起人节点设置自定义表单时,发起人节点处的表单填写会被跳过,流程详情中也会展示该节点的空表单。
因为无法在前端页面上限制不能给发起人节点(实际上也是userTask用户任务)配置表单,所以在返回流程详情的表单列表时,将发起人节点(此处定义为开始节点直连的用户任务节点)的表单过滤掉。外加给表单列表添加处理人和处理时间出参展示。
为了将发起人任务节点与其他任务节点区分开,在第一个用户任务启动时,将其优先级设置为1(默认是50)。
/** * 启动第一个任务 * @param processInstance 流程实例 * @param variables 流程参数 */ @Override public void startFirstTask(ProcessInstance processInstance, Map<String, Object> variables) { // 若第一个用户任务为发起人,则自动完成任务,无需发送待办消息提醒 List<Task> tasks = taskService.createTaskQuery().processInstanceId(processInstance.getProcessInstanceId()).list(); if (CollUtil.isNotEmpty(tasks)) { String userIdStr = (String) variables.get(TaskConstants.PROCESS_INITIATOR); for (Task task : tasks) { if (StrUtil.equals(task.getAssignee(), userIdStr)) { // new >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> taskService.setPriority(task.getId(), 1); // 设置开始任务优先级为1 // --------------------------------------------- taskService.addComment(task.getId(), processInstance.getProcessInstanceId(), FlowComment.NORMAL.getType(), LoginHelper.getNickName() + "发起流程申请"); taskService.complete(task.getId(), variables); } } } }
在查询流程详情表单时,对优先级进行过滤。
/** * 获取历史流程表单信息 */ private List<FormConf> processFormList(BpmnModel bpmnModel, String procInsId, String deployId) { List<FormConf> procFormList = new ArrayList<>(); HistoricProcessInstance historicProcIns = historyService.createHistoricProcessInstanceQuery().processInstanceId(procInsId).includeProcessVariables().singleResult(); List<HistoricActivityInstance> activityInstanceList = historyService.createHistoricActivityInstanceQuery() .processInstanceId(procInsId).finished() .activityTypes(CollUtil.newHashSet(BpmnXMLConstants.ELEMENT_EVENT_START, BpmnXMLConstants.ELEMENT_TASK_USER)) .orderByHistoricActivityInstanceStartTime().asc() .list(); List<String> processFormKeys = new ArrayList<>(); // new >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> // 查询该流程关联的历史任务集合,设置任务id与优先级Map List<HistoricTaskInstance> hisTaskList = historyService.createHistoricTaskInstanceQuery().processInstanceId(procInsId).list(); Map<String, Integer> taskPriorityMap = hisTaskList.stream().collect(Collectors.toMap(HistoricTaskInstance::getId, HistoricTaskInstance::getPriority)); // --------------------------------------------- for (HistoricActivityInstance activityInstance : activityInstanceList) { // 获取当前节点流程元素信息 FlowElement flowElement = ModelUtils.getFlowElementById(bpmnModel, activityInstance.getActivityId()); // 获取当前节点表单Key String formKey = ModelUtils.getFormKey(flowElement); if (formKey == null) { continue; } // new >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> // 如果该节点对应的任务优先级为1,代表是开始节点后的发起人节点,过滤表单 Integer taskPriority = taskPriorityMap.get(activityInstance.getTaskId()); if (taskPriority != null && taskPriority == 1) { continue; } // --------------------------------------------- boolean localScope = Convert.toBool(ModelUtils.getElementAttributeValue(flowElement, ProcessConstants.PROCESS_FORM_LOCAL_SCOPE), false); Map<String, Object> variables; if (localScope) { // 查询任务节点参数,并转换成Map variables = historyService.createHistoricVariableInstanceQuery() .processInstanceId(procInsId) .taskId(activityInstance.getTaskId()) .list() .stream() .collect(Collectors.toMap(HistoricVariableInstance::getVariableName, HistoricVariableInstance::getValue)); } else { if (processFormKeys.contains(formKey)) { continue; } variables = historicProcIns.getProcessVariables(); processFormKeys.add(formKey); } // 非节点表单此处查询结果可能有多条,只获取第一条信息 List<WfDeployFormVo> formInfoList = deployFormMapper.selectVoList(new LambdaQueryWrapper<WfDeployForm>() .eq(WfDeployForm::getDeployId, deployId) .eq(WfDeployForm::getFormKey, formKey) .eq(localScope, WfDeployForm::getNodeKey, flowElement.getId())); WfDeployFormVo formInfo = formInfoList.iterator().next(); if (ObjectUtil.isNotNull(formInfo)) { // 旧数据 formInfo.getFormName() 为 null String formName = Optional.ofNullable(formInfo.getFormName()).orElse(StringUtils.EMPTY); String title = localScope ? formName.concat("(" + flowElement.getName() + ")") : formName; FormConf formConf = JsonUtils.parseObject(formInfo.getContent(), FormConf.class); if (null != formConf) { formConf.setTitle(title); formConf.setDisabled(true); formConf.setFormBtns(false); // new >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> // 填充处理人和处理时间 if (BpmnXMLConstants.ELEMENT_EVENT_START.equals(activityInstance.getActivityType())) { // 如果是开始节点 String startUserId = historicProcIns.getStartUserId(); SysUser user = userService.selectUserById(Long.parseLong(startUserId)); if (user != null) { formConf.setHandleBy(user.getNickName()); // 任务的处理人 formConf.setHandleTime(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", activityInstance.getEndTime())); // 任务处理时间 } } else if (BpmnXMLConstants.ELEMENT_TASK_USER.equals(activityInstance.getActivityType())) { // 如果是用户审批节点 if (StringUtils.isNotBlank(activityInstance.getAssignee())) { SysUser user = userService.selectUserById(Long.parseLong(activityInstance.getAssignee())); if (user != null) { formConf.setHandleBy(user.getNickName()); formConf.setHandleTime(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", activityInstance.getEndTime())); } } } // --------------------------------------------- ProcessFormUtils.fillFormData(formConf, variables); procFormList.add(formConf); } } } return procFormList; }
参考资料:
KonBAI / RuoYi-Flowable-Plus 基于 RuoYi-Vue-Plus 进行二次开发扩展Flowable工作流功能项目
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。