1、任务列表二次查询

This commit is contained in:
2026-03-14 17:11:05 +08:00
parent 55f146d8e6
commit d74695140b
3 changed files with 250 additions and 34 deletions

View File

@@ -2,9 +2,11 @@ package com.sdm.project.model.req;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.sdm.common.entity.req.data.TagReq;
import com.sdm.common.validator.annotation.EnumValue; import com.sdm.common.validator.annotation.EnumValue;
import com.sdm.project.common.TaskQryTypeEnum; import com.sdm.project.common.TaskQryTypeEnum;
import com.sdm.project.model.bo.TaskNodeTag; import com.sdm.project.model.bo.TaskNodeTag;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import lombok.Data; import lombok.Data;
@@ -145,4 +147,15 @@ public class SpdmTaskListReq {
private String taskId; private String taskId;
/**
* 标签请求参数 设置tag1-tag10 ,taskId, runId记录文件所属节点信息
*/
@Schema(description = "标签请求参数")
private TagReq tagReq;
/**
* 提出人
*/
private String submitterName;
} }

View File

@@ -4,8 +4,10 @@ import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.sdm.common.entity.pojo.BaseEntity; import com.sdm.common.entity.pojo.BaseEntity;
import com.sdm.common.entity.req.data.TagReq;
import com.sdm.common.entity.resp.system.CIDUserResp; import com.sdm.common.entity.resp.system.CIDUserResp;
import com.sdm.common.entity.resp.project.TaskNodeExtraPo; import com.sdm.common.entity.resp.project.TaskNodeExtraPo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import java.util.List; import java.util.List;
@@ -268,4 +270,10 @@ public class SpdmNewTaskVo extends BaseEntity {
@JsonProperty(value = "payAttentionMemberList") @JsonProperty(value = "payAttentionMemberList")
private List<CIDUserResp> payAttentionMemberList; private List<CIDUserResp> payAttentionMemberList;
/**
* 标签请求参数 设置tag1-tag10 ,taskId, runId记录文件所属节点信息
*/
@Schema(description = "标签请求参数")
private TagReq tagReq;
} }

View File

@@ -93,8 +93,10 @@ import java.text.SimpleDateFormat;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.ZoneId; import java.time.ZoneId;
import java.util.*; import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
@@ -246,39 +248,193 @@ public class TaskServiceImpl implements ITaskService {
return jsonObject; return jsonObject;
} }
// /**
// * 按节点标签过滤任务
// */
// private List<SpdmTaskVo> filterTaskByNodeTag(List<SpdmTaskVo> allTaskList, SpdmTaskListReq req) {
// TagReq tagReq = req.getTagReq();
// List<TaskNodeTag> taskNodeTagList = buildTaskNodeTagList(tagReq);
// if (CollectionUtils.isEmpty(taskNodeTagList)) {
// return allTaskList;
// }
// int totalTagSize = taskNodeTagList.size();
// List<SpdmTaskVo> filteredList = new ArrayList<>();
// for (SpdmTaskVo spdmTaskVo : allTaskList) {
// int currentTagSize = 0;
// for (TaskNodeTag taskNodeTag : taskNodeTagList) {
// try {
// String currentNodeTagId = getTagProperty(spdmTaskVo, taskNodeTag.getKey());
// if (StringUtils.isBlank(currentNodeTagId)) {
// break;
// }
// for (String currentNodeTagIdItem : Arrays.stream(currentNodeTagId.split(",")).toList()) {
// if (taskNodeTag.getValue().contains(currentNodeTagIdItem)) {
// currentTagSize += 1;
// break;
// }
// }
//
// } catch (Exception e) {
// log.error("节点标签过滤异常taskId:{}", spdmTaskVo.getUuid(), e);
// }
// }
// if (currentTagSize == totalTagSize) {
// filteredList.add(spdmTaskVo);
// }
// }
// return filteredList;
// }
/** /**
* 节点标签过滤任务 * 根据节点标签过滤任务列表
*/ */
private List<SpdmTaskVo> filterTaskByNodeTag(List<SpdmTaskVo> allTaskList, SpdmTaskListReq req) { private List<SpdmTaskVo> filterTaskByNodeTag(List<SpdmTaskVo> allTaskList, SpdmTaskListReq req) {
List<TaskNodeTag> idMapList = req.getIdMap(); // 1. 空值快速返回
if (CollectionUtils.isEmpty(idMapList)) { if (CollectionUtils.isEmpty(allTaskList) || req == null) {
log.error("任务列表中的idMap不能为空"); return Collections.emptyList();
return new ArrayList<>();
} }
// 过滤非空key的标签 TagReq tagReq = req.getTagReq();
List<TaskNodeTag> realIdMapList = idMapList.stream() List<TaskNodeTag> taskNodeTagList = buildTaskNodeTagList(tagReq);
.filter(idMap -> StringUtils.isNotBlank(idMap.getKey()))
.collect(Collectors.toList()); // 2. 无过滤标签时直接返回原列表
if (CollectionUtils.isEmpty(realIdMapList)) { if (CollectionUtils.isEmpty(taskNodeTagList)) {
return allTaskList; return allTaskList;
} }
TaskNodeTag realTaskNodeTag = realIdMapList.get(realIdMapList.size() - 1); // 3. 预处理标签
log.info("实际查询节点类型为:{}", JSON.toJSONString(realTaskNodeTag)); Map<String, Set<String>> tagConditionMap = preprocessTagConditions(taskNodeTagList);
int totalTagSize = tagConditionMap.size();
// 4. 判断单个任务是否匹配所有标签条件
return allTaskList.stream()
.filter(task -> matchAllTagConditions(task, tagConditionMap, totalTagSize))
.collect(Collectors.toList());
}
/**
* 预处理标签条件将标签值转为Set提升后续查找效率
* @param taskNodeTagList 原始标签列表
* @return 处理后的标签条件Mapkey:标签键value:标签值集合)
*/
private Map<String, Set<String>> preprocessTagConditions(List<TaskNodeTag> taskNodeTagList) {
return taskNodeTagList.stream()
.filter(tag -> tag != null && StringUtils.isNotBlank(tag.getKey()) && StringUtils.isNotEmpty(tag.getValue()))
.collect(Collectors.toMap(
TaskNodeTag::getKey,
tag -> {
// 将单个字符串按逗号拆分去空去重后转Set
return Arrays.stream(tag.getValue().split(","))
.map(String::trim) // 去除首尾空格
.filter(StringUtils::isNotBlank) // 过滤空字符串
.collect(Collectors.toSet());
},
(existing, replacement) -> existing // 处理重复key保留第一个
));
}
/**
* 判断单个任务是否匹配所有标签条件
* @param task 待判断任务
* @param tagConditionMap 预处理后的标签条件Map
* @param totalTagSize 总标签数量
* @return 是否匹配所有条件
*/
private boolean matchAllTagConditions(SpdmTaskVo task, Map<String, Set<String>> tagConditionMap, int totalTagSize) {
if (task == null) {
return false;
}
int matchedTagCount = 0;
for (Map.Entry<String, Set<String>> entry : tagConditionMap.entrySet()) {
String tagKey = entry.getKey();
Set<String> tagValueSet = entry.getValue();
List<SpdmTaskVo> filteredList = new ArrayList<>();
for (SpdmTaskVo spdmTaskVo : allTaskList) {
try { try {
String currentNodeTagId = getTagProperty(spdmTaskVo, realTaskNodeTag.getValue()); // 获取当前任务的标签值
if (StringUtils.isNotBlank(currentNodeTagId) && currentNodeTagId.contains(realTaskNodeTag.getKey())) { String currentNodeTagId = getTagProperty(task, tagKey);
filteredList.add(spdmTaskVo); if (StringUtils.isBlank(currentNodeTagId)) {
break; // 该标签无值,不匹配,直接跳出
}
// 拆分标签值并判断是否匹配
boolean isMatched = Arrays.stream(currentNodeTagId.split(","))
.map(String::trim) // 处理空格
.anyMatch(tagValueSet::contains);
if (isMatched) {
matchedTagCount++;
} else {
break; // 该标签不匹配,直接跳出
} }
} catch (Exception e) { } catch (Exception e) {
log.error("节点标签过滤异常taskId:{}", spdmTaskVo.getUuid(), e); log.error("节点标签过滤异常taskId:{}", task.getUuid(), e);
break; // 异常时视为不匹配
} }
} }
return filteredList;
// 所有标签都匹配才返回true
return matchedTagCount == totalTagSize;
}
// 内部静态类封装tag的key和取值逻辑
private static class TagConfig {
private final String tagKey;
private final Supplier<String> valueSupplier;
public TagConfig(String tagKey, Supplier<String> valueSupplier) {
this.tagKey = tagKey;
this.valueSupplier = valueSupplier;
}
public String getTagKey() {
return tagKey;
}
public Supplier<String> getValueSupplier() {
return valueSupplier;
}
}
/**
* 构建tag过滤参数集合
* @param tagReq
* @return
*/
private List<TaskNodeTag> buildTaskNodeTagList(TagReq tagReq) {
List<TaskNodeTag> taskNodeTagList = new ArrayList<>();
if (tagReq == null) {
return taskNodeTagList;
}
// 定义标签key和对应的取值函数统一管理tag
List<TagConfig> tagConfigs = List.of(
new TagConfig("tag1", tagReq::getTag1),
new TagConfig("tag2", tagReq::getTag2),
new TagConfig("tag3", tagReq::getTag3),
new TagConfig("tag4", tagReq::getTag4),
new TagConfig("tag5", tagReq::getTag5),
new TagConfig("tag6", tagReq::getTag6),
new TagConfig("tag7", tagReq::getTag7),
new TagConfig("tag8", tagReq::getTag8),
new TagConfig("tag9", tagReq::getTag9),
new TagConfig("tag10", tagReq::getTag10)
);
// 处理所有tag
for (TagConfig config : tagConfigs) {
String tagValue = config.getValueSupplier().get();
if (StringUtils.isNotBlank(tagValue)) {
TaskNodeTag taskNodeTag = new TaskNodeTag();
taskNodeTag.setKey(config.getTagKey());
taskNodeTag.setValue(tagValue);
taskNodeTagList.add(taskNodeTag);
}
}
return taskNodeTagList;
} }
/** /**
@@ -1015,6 +1171,27 @@ public class TaskServiceImpl implements ITaskService {
return SdmResponse.success(jsonObject); return SdmResponse.success(jsonObject);
} }
// 提前根据提出人过滤(如果传了提出人参数的情况)
// 将利元亨的用户工号与userId映射
Map<String, Long> usernameToUserIdMap = new HashMap<>();
Map<Long, String> userIdToNickNameMap = new HashMap<>();
UserListReq userListReq = new UserListReq();
userListReq.setTenantId(tenantId);
userListReq.setCurrent(1);
userListReq.setSize(9999);
SdmResponse<PageDataResp<List<CIDUserResp>>> pageDataRespSdmResponse = sysUserFeignClient.listUser(userListReq);
if (pageDataRespSdmResponse.isSuccess() && pageDataRespSdmResponse.getData().getData() != null) {
List<CIDUserResp> userList = pageDataRespSdmResponse.getData().getData();
usernameToUserIdMap = userList.stream().collect(Collectors.toMap(CIDUserResp::getUsername, CIDUserResp::getUserId));
userIdToNickNameMap = userList.stream().collect(Collectors.toMap(CIDUserResp::getUserId,CIDUserResp::getNickname));
}
if (StringUtils.isNotBlank(req.getSubmitterName())) {
List<String> submitterNameList = Arrays.stream(req.getSubmitterName().split(",")).toList();
Map<Long, String> finalUserIdToNickNameMap = userIdToNickNameMap;
allTaskList = allTaskList.stream().filter(task -> task.getCreator() != null
&& submitterNameList.contains(finalUserIdToNickNameMap.get(task.getCreator()))).toList();
}
// 3. 节点标签过滤 // 3. 节点标签过滤
stopWatch.start("节点标签过滤"); stopWatch.start("节点标签过滤");
List<SpdmTaskVo> taskList = filterTaskByNodeTag(allTaskList, req); List<SpdmTaskVo> taskList = filterTaskByNodeTag(allTaskList, req);
@@ -1070,19 +1247,6 @@ public class TaskServiceImpl implements ITaskService {
stopWatch.stop(); stopWatch.stop();
// 10. 转换为返回VO // 10. 转换为返回VO
stopWatch.start("转换为返回VO"); stopWatch.start("转换为返回VO");
// 将利元亨的用户工号与userId映射
Map<String, Long> usernameToUserIdMap = new HashMap<>();
Map<Long, String> userIdToNickNameMap = new HashMap<>();
UserListReq userListReq = new UserListReq();
userListReq.setTenantId(tenantId);
userListReq.setCurrent(1);
userListReq.setSize(9999);
SdmResponse<PageDataResp<List<CIDUserResp>>> pageDataRespSdmResponse = sysUserFeignClient.listUser(userListReq);
if (pageDataRespSdmResponse.isSuccess() && pageDataRespSdmResponse.getData().getData() != null) {
List<CIDUserResp> userList = pageDataRespSdmResponse.getData().getData();
usernameToUserIdMap = userList.stream().collect(Collectors.toMap(CIDUserResp::getUsername, CIDUserResp::getUserId));
userIdToNickNameMap = userList.stream().collect(Collectors.toMap(CIDUserResp::getUserId,CIDUserResp::getNickname));
}
List<SpdmNewTaskVo> newTaskList = convertToNewVoBatch(pageTaskList, batchData,usernameToUserIdMap,userIdToNickNameMap); List<SpdmNewTaskVo> newTaskList = convertToNewVoBatch(pageTaskList, batchData,usernameToUserIdMap,userIdToNickNameMap);
stopWatch.stop(); stopWatch.stop();
// 输出计时结果(两种方式:格式化打印/自定义输出) // 输出计时结果(两种方式:格式化打印/自定义输出)
@@ -1099,12 +1263,45 @@ public class TaskServiceImpl implements ITaskService {
spdmNewTaskVo.setApprovalStatus("0"); spdmNewTaskVo.setApprovalStatus("0");
} }
} }
// 返回值赋值tagReq
fillTaskTagReq(newTaskList);
jsonObject.put("data", newTaskList); jsonObject.put("data", newTaskList);
jsonObject.put("currentPage", req.getCurrent()); jsonObject.put("currentPage", req.getCurrent());
jsonObject.put("pageSize", req.getSize()); jsonObject.put("pageSize", req.getSize());
return SdmResponse.success(jsonObject); return SdmResponse.success(jsonObject);
} }
// 通用的标签设置方法
private void setTagField(TagReq tagReq, String tagValue, String tagName,
BiConsumer<TagReq, String> tagSetter,
BiConsumer<TagReq, String> tagNameSetter) {
if (tagValue != null) {
tagSetter.accept(tagReq, tagValue);
}
if (tagName != null) {
tagNameSetter.accept(tagReq, tagName);
}
}
private void fillTaskTagReq(List<SpdmNewTaskVo> newTaskList) {
for (SpdmNewTaskVo spdmNewTaskVo : newTaskList) {
TagReq tagReq = new TagReq();
setTagField(tagReq, spdmNewTaskVo.getNewTag1(), spdmNewTaskVo.getTag1(), TagReq::setTag1, TagReq::setTag1Name);
setTagField(tagReq, spdmNewTaskVo.getNewTag2(), spdmNewTaskVo.getTag2(), TagReq::setTag2, TagReq::setTag2Name);
setTagField(tagReq, spdmNewTaskVo.getNewTag3(), spdmNewTaskVo.getTag3(), TagReq::setTag3, TagReq::setTag3Name);
setTagField(tagReq, spdmNewTaskVo.getNewTag4(), spdmNewTaskVo.getTag4(), TagReq::setTag4, TagReq::setTag4Name);
setTagField(tagReq, spdmNewTaskVo.getNewTag5(), spdmNewTaskVo.getTag5(), TagReq::setTag5, TagReq::setTag5Name);
setTagField(tagReq, spdmNewTaskVo.getNewTag6(), spdmNewTaskVo.getTag6(), TagReq::setTag6, TagReq::setTag6Name);
setTagField(tagReq, spdmNewTaskVo.getNewTag7(), spdmNewTaskVo.getTag7(), TagReq::setTag7, TagReq::setTag7Name);
setTagField(tagReq, spdmNewTaskVo.getNewTag8(), spdmNewTaskVo.getTag8(), TagReq::setTag8, TagReq::setTag8Name);
setTagField(tagReq, spdmNewTaskVo.getNewTag9(), spdmNewTaskVo.getTag9(), TagReq::setTag9, TagReq::setTag9Name);
setTagField(tagReq, spdmNewTaskVo.getNewTag10(), spdmNewTaskVo.getTag10(), TagReq::setTag10, TagReq::setTag10Name);
tagReq.setTaskId(spdmNewTaskVo.getUuid());
tagReq.setTaskName(spdmNewTaskVo.getTaskName());
spdmNewTaskVo.setTagReq(tagReq);
}
}
// 设置工位号 // 设置工位号
private void setWorkSpaceNodeCode(SpdmNewTaskVo spdmNewTaskVo, SpdmTaskVo taskVo, private void setWorkSpaceNodeCode(SpdmNewTaskVo spdmNewTaskVo, SpdmTaskVo taskVo,
Map<String, SimulationNode> allNodeMap, TaskNodeTag taskNodeTag) { Map<String, SimulationNode> allNodeMap, TaskNodeTag taskNodeTag) {
@@ -2070,8 +2267,6 @@ public class TaskServiceImpl implements ITaskService {
)); ));
} }
ProjectNodePo eachProjectNodePo;
for (SpdmAnalysisTaskVo task : taskVoList) { for (SpdmAnalysisTaskVo task : taskVoList) {
TagReq taskTagReq = task.getTagReq(); TagReq taskTagReq = task.getTagReq();