
flowable工作流-过滤发起人节点表单
基于开源项目KonBAI / RuoYi-Flowable-Plus使用的部分功能调整。原代码展示所有节点配置的自定义表单。现因系统配置要求,需且过滤掉未填写的发起人节点空表单。
·
基于开源项目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工作流功能项目
点击阅读全文
更多推荐
目录
所有评论(0)