1、优化任务列表查询接口

This commit is contained in:
2026-02-02 06:24:29 +08:00
parent 66a06093d7
commit f57b506af6
5 changed files with 330 additions and 49 deletions

View File

@@ -4,7 +4,8 @@ public enum TaskQryTypeEnum {
EXEC(0, "我执行的"),
ATTENTION(1, "我关注的"),
ALL(2, "所有"),
ISSUE(3, "分发的");
ISSUE(3, "分发的"),
UN_ISSUE(4, "未分发的");
private final Integer code;
private final String desc;

View File

@@ -61,4 +61,6 @@ public interface SimulationTaskMapper extends BaseMapper<SimulationTask> {
List<SpdmTaskVo> getTaskListByIdList(@Param("taskIdList") List<String> taskIdList);
List<SpdmTaskVo> optimisedGtTaskList(@Param("tenantId") Long tenantId, @Param("req") SpdmTaskListReq req);
}

View File

@@ -141,4 +141,6 @@ public class SpdmTaskListReq {
* */
private List<TaskNodeTag> nodeTypeMap;
private Long userId;
}

View File

@@ -79,6 +79,7 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.StopWatch;
import javax.annotation.Resource;
import java.io.File;
@@ -379,15 +380,46 @@ public class TaskServiceImpl implements ITaskService {
}
// 我分发的(仿真负责人)
if (type == 3) {
// 我分发的现在需要细化出未分发和已分发
// 已分发任务type=3【执行人不为空】
// 未分发任务type=4【执行人为空】
if (type == 3 || type == 4) {
if (CollectionUtils.isEmpty(taskMemberVoList)) {
return new ArrayList<>();
}
List<String> myTaskIdList = taskMemberVoList.stream()
.filter(member -> MemberTypeEnum.PRINCIPAL.getCode().equals(member.getType()) && userId.equals(member.getUserId()))
// 筛选出【我作为仿真负责人】的所有任务ID
Set<String> myPrincipalTaskIdSet = taskMemberVoList.stream()
.filter(member -> MemberTypeEnum.PRINCIPAL.getCode().equals(member.getType())
&& userId.equals(member.getUserId()))
.map(SpdmTaskMemberVo::getTaskId)
.collect(Collectors.toSet()); // 用Set提升后续contains判断效率大数据量更优
if (CollectionUtils.isEmpty(myPrincipalTaskIdSet)) {
return new ArrayList<>();
}
// 筛选出【有执行人】的任务ID集合
Set<String> hasExecutorTaskIdSet = taskMemberVoList.stream()
.filter(member -> MemberTypeEnum.EXECUTOR.getCode().equals(member.getType()))
.map(SpdmTaskMemberVo::getTaskId)
.collect(Collectors.toSet());
// 按类型过滤出最终需要的任务ID我的分发任务 + 有/无执行人)
Set<String> finalTaskIdSet;
if (type == 3) {
// 已分发type=3我的分发任务 且 有执行人 → 两个集合的交集
finalTaskIdSet = myPrincipalTaskIdSet.stream()
.filter(hasExecutorTaskIdSet::contains)
.collect(Collectors.toSet());
} else { // type == 4
// 未分发type=4我的分发任务 且 无执行人 → 我的任务ID中排除有执行人的ID
finalTaskIdSet = myPrincipalTaskIdSet.stream()
.filter(taskId -> !hasExecutorTaskIdSet.contains(taskId))
.collect(Collectors.toSet());
}
// 根据最终任务ID从任务列表中匹配出具体的任务数据并返回
return taskList.stream()
.filter(task -> finalTaskIdSet.contains(task.getUuid()))
.collect(Collectors.toList());
return taskList.stream().filter(task -> myTaskIdList.contains(task.getUuid())).collect(Collectors.toList());
}
// 我关注的
@@ -436,45 +468,47 @@ public class TaskServiceImpl implements ITaskService {
}
// 维度2项目节点授权人员
Set<String> projectNodeIdSet = taskList.stream()
.map(SpdmTaskVo::getTag1)
.filter(StringUtils::isNotBlank)
.collect(Collectors.toSet());
if (CollectionUtils.isNotEmpty(projectNodeIdSet)) {
Map<String, Set<Long>> nodeAuthUserIdMap = nodeMapper.getNodeMemberListByNodeIdList(new ArrayList<>(projectNodeIdSet))
.stream()
.filter(member -> member != null && StringUtils.isNotBlank(member.getNodeId()) && member.getUserId() != null)
.collect(Collectors.groupingBy(
SpdmNodeMemberVo::getNodeId,
Collectors.mapping(SpdmNodeMemberVo::getUserId, Collectors.toSet())
));
// Set<String> projectNodeIdSet = taskList.stream()
// .map(SpdmTaskVo::getTag1)
// .filter(StringUtils::isNotBlank)
// .collect(Collectors.toSet());
// if (CollectionUtils.isNotEmpty(projectNodeIdSet)) {
// Map<String, Set<Long>> nodeAuthUserIdMap = nodeMapper.getNodeMemberListByNodeIdList(new ArrayList<>(projectNodeIdSet))
// .stream()
// .filter(member -> member != null && StringUtils.isNotBlank(member.getNodeId()) && member.getUserId() != null)
// .collect(Collectors.groupingBy(
// SpdmNodeMemberVo::getNodeId,
// Collectors.mapping(SpdmNodeMemberVo::getUserId, Collectors.toSet())
// ));
//
// if (MapUtils.isNotEmpty(nodeAuthUserIdMap)) {
// taskList.stream()
// .filter(task -> StringUtils.isNotBlank(task.getTag1()))
// .filter(task -> nodeAuthUserIdMap.getOrDefault(task.getTag1(), Collections.emptySet()).contains(userId))
// .forEach(returnTaskSet::add);
// }
// }
//
// // 维度3任务成员
// List<SpdmTaskMemberVo> taskMemberVoList = batchData.getTaskMemberVoList();
// if (CollectionUtils.isNotEmpty(taskMemberVoList)) {
// Map<String, Set<Long>> taskAuthUserIdMap = taskMemberVoList.stream()
// .filter(member -> member != null && StringUtils.isNotBlank(member.getTaskId()) && member.getUserId() != null)
// .collect(Collectors.groupingBy(
// SpdmTaskMemberVo::getTaskId,
// Collectors.mapping(SpdmTaskMemberVo::getUserId, Collectors.toSet())
// ));
//
// if (MapUtils.isNotEmpty(taskAuthUserIdMap)) {
// taskList.stream()
// .filter(task -> StringUtils.isNotBlank(task.getUuid()))
// .filter(task -> taskAuthUserIdMap.getOrDefault(task.getUuid(), Collections.emptySet()).contains(userId))
// .forEach(returnTaskSet::add);
// }
// }
if (MapUtils.isNotEmpty(nodeAuthUserIdMap)) {
taskList.stream()
.filter(task -> StringUtils.isNotBlank(task.getTag1()))
.filter(task -> nodeAuthUserIdMap.getOrDefault(task.getTag1(), Collections.emptySet()).contains(userId))
.forEach(returnTaskSet::add);
}
}
// 维度3任务成员
List<SpdmTaskMemberVo> taskMemberVoList = batchData.getTaskMemberVoList();
if (CollectionUtils.isNotEmpty(taskMemberVoList)) {
Map<String, Set<Long>> taskAuthUserIdMap = taskMemberVoList.stream()
.filter(member -> member != null && StringUtils.isNotBlank(member.getTaskId()) && member.getUserId() != null)
.collect(Collectors.groupingBy(
SpdmTaskMemberVo::getTaskId,
Collectors.mapping(SpdmTaskMemberVo::getUserId, Collectors.toSet())
));
if (MapUtils.isNotEmpty(taskAuthUserIdMap)) {
taskList.stream()
.filter(task -> StringUtils.isNotBlank(task.getUuid()))
.filter(task -> taskAuthUserIdMap.getOrDefault(task.getUuid(), Collections.emptySet()).contains(userId))
.forEach(returnTaskSet::add);
}
}
returnTaskSet.addAll(taskList);
return new ArrayList<>(returnTaskSet);
}
@@ -584,6 +618,15 @@ public class TaskServiceImpl implements ITaskService {
* 分页处理任务列表
*/
private List<SpdmTaskVo> pageTaskList(List<SpdmTaskVo> taskList, SpdmTaskListReq req) {
Integer sortOrder = req.getSortOrder();
if (sortOrder != null) {
if (sortOrder == 0) {
taskList = taskList.stream().sorted(Comparator.comparing(SpdmTaskVo::getCreateTime)).toList();
}else if (sortOrder == 1) {
taskList = taskList.stream().sorted(Comparator.comparing(SpdmTaskVo::getCreateTime).reversed()).toList();
}
}
int current = req.getCurrent();
int size = req.getSize();
int start = (current - 1) * size;
@@ -832,7 +875,11 @@ public class TaskServiceImpl implements ITaskService {
preProcessReq(req);
// 2. 基础任务列表查询
List<SpdmTaskVo> allTaskList = mapper.getTaskList(tenantId, req);
req.setUserId(userId);
StopWatch stopWatch = new StopWatch("所有任务方法计时");
stopWatch.start("查所有任务");
List<SpdmTaskVo> allTaskList = mapper.optimisedGtTaskList(tenantId, req);
stopWatch.stop();
JSONObject jsonObject = buildEmptyJsonResp(req);
if (CollectionUtils.isEmpty(allTaskList)) {
log.info("根据tenantId{},未查询到任务", tenantId);
@@ -840,17 +887,23 @@ public class TaskServiceImpl implements ITaskService {
}
// 3. 节点标签过滤
stopWatch.start("节点标签过滤");
List<SpdmTaskVo> taskList = filterTaskByNodeTag(allTaskList, req);
stopWatch.stop();
if (CollectionUtils.isEmpty(taskList)) {
log.info("节点标签过滤后无任务数据");
return SdmResponse.success(jsonObject);
}
// 4. 批量查询关联数据
stopWatch.start("批量查询关联数据");
BatchAssociatedData batchData = batchQueryAssociatedData(taskList,req);
stopWatch.stop();
// 5. 按类型过滤任务(我执行的/我关注的/我分发的/所有)
stopWatch.start("按类型过滤任务");
taskList = filterTaskByType(taskList, req.getType(), userId, batchData.getTaskMemberVoList(), batchData.getAttentionMemberList());
stopWatch.stop();
if (CollectionUtils.isEmpty(taskList)) {
log.info("按类型过滤后无任务数据");
jsonObject.put("total", 0);
@@ -858,33 +911,41 @@ public class TaskServiceImpl implements ITaskService {
}
// 6. 权限过滤(项目参与人/节点授权/任务成员)
stopWatch.start("权限过滤");
taskList = filterTaskByPermission(taskList, userId, batchData);
if (CollectionUtils.isEmpty(taskList)) {
log.info("权限过滤后无任务数据");
jsonObject.put("total", 0);
return SdmResponse.success(jsonObject);
}
stopWatch.stop();
// 7. 负责人/执行人参数过滤
stopWatch.start("负责人/执行人参数过滤");
taskList = filterTaskByMemberParam(taskList, req, batchData.getTaskMemberVoList());
if (CollectionUtils.isEmpty(taskList)) {
log.info("负责人/执行人参数过滤后无任务数据");
jsonObject.put("total", 0);
return SdmResponse.success(jsonObject);
}
stopWatch.stop();
// 8. 节点标签转换(批量处理)
stopWatch.start("节点标签转换");
handleNodeTagBatch(taskList, req, batchData.getNodeMap());
stopWatch.stop();
// 9. 分页
stopWatch.start("分页");
int total = taskList.size();
log.info("id:{}",taskList.stream().sorted(Comparator.comparing(SpdmTaskVo::getUuid)).map(SpdmTaskVo::getId).toList());
// log.info("id:{}",taskList.stream().sorted(Comparator.comparing(SpdmTaskVo::getUuid)).map(SpdmTaskVo::getId).toList());
jsonObject.put("total", total);
List<SpdmTaskVo> pageTaskList = pageTaskList(taskList, req);
stopWatch.stop();
// 10. 转换为返回VO
stopWatch.start("转换为返回VO");
List<SpdmNewTaskVo> newTaskList = convertToNewVoBatch(pageTaskList, batchData);
stopWatch.stop();
// 输出计时结果(两种方式:格式化打印/自定义输出)
System.out.println("===== 格式化打印所有任务耗时(推荐日志输出) =====");
System.out.println(stopWatch.prettyPrint()); // Spring内置格式化含耗时百分比直接打印日志即可
// 11. 最终返回
jsonObject.put("data", newTaskList);
jsonObject.put("currentPage", req.getCurrent());

View File

@@ -467,5 +467,220 @@
)
</select>
<select id="optimisedGtTaskList" resultType="com.sdm.common.entity.resp.project.SpdmTaskVo">
SELECT st.*
FROM simulation_task st
LEFT JOIN simulation_task_member stm ON st.uuid = stm.task_id
WHERE stm.user_id = #{req.userId}
AND st.tenant_id = #{tenantId}
<if test="req.demandId != null and req.demandId != ''">
and demand_id = #{req.demandId}
</if>
<if test="req.taskName != null and req.taskName != ''">
<bind name="searchKey" value="'%' + req.taskName + '%'"/>
and task_name like #{searchKey}
</if>
<if test="req.progress != null and req.progress != ''">
and progress = #{req.progress}
</if>
<if test="(req.exeStatusList != null and req.exeStatusList.size > 0) or (req.todayTmrTasks != null and req.todayTmrTasks != '')">
and (
<choose>
<!-- 只有状态条件 -->
<when test="req.exeStatusList != null and req.exeStatusList.size > 0 and (req.todayTmrTasks == null or req.todayTmrTasks == '')">
exe_status in (
<foreach collection='req.exeStatusList' item='exeStatus' index='index' separator=','>
#{exeStatus}
</foreach>
)
</when>
<!-- 只有时间条件 -->
<when test="(req.exeStatusList == null or req.exeStatusList.size == 0) and req.todayTmrTasks != null and req.todayTmrTasks != ''">
<![CDATA[
STR_TO_DATE(end_time,'%Y-%m-%d') >= CURRENT_DATE()
and STR_TO_DATE(end_time,'%Y-%m-%d') <= DATE_ADD(CURRENT_DATE(), INTERVAL 2 DAY)
]]>
</when>
<!-- 两个条件都有(并集) -->
<otherwise>
exe_status in (
<foreach collection='req.exeStatusList' item='exeStatus' index='index' separator=','>
#{exeStatus}
</foreach>
)
<![CDATA[ OR ]]>
<![CDATA[
STR_TO_DATE(end_time,'%Y-%m-%d') >= CURRENT_DATE()
and STR_TO_DATE(end_time,'%Y-%m-%d') <= DATE_ADD(CURRENT_DATE(), INTERVAL 2 DAY)
]]>
</otherwise>
</choose>
)
</if>
<if test="req.achieveStatusList != null and req.achieveStatusList.size > 0">
and achieve_status in (
<foreach collection='req.achieveStatusList' item='achieveStatus' index='index' separator=','>
#{achieveStatus}
</foreach>
)
</if>
<if test="req.approvalStatusList != null and req.approvalStatusList.size > 0">
and approval_status in (
<foreach collection='req.approvalStatusList' item='approvalStatus' index='index' separator=','>
#{approvalStatus}
</foreach>
)
</if>
<if test="req.beginSTime != null and req.beginSTime != ''">
<![CDATA[
and STR_TO_DATE(begin_time,'%Y-%m-%d %H:%i:%s') >= #{req.beginSTime}
]]>
</if>
<if test="req.beginETime != null and req.beginETime != ''">
<![CDATA[
and STR_TO_DATE(begin_time,'%Y-%m-%d %H:%i:%s') <= #{req.beginETime}
]]>
</if>
<if test="req.endSTime != null and req.endSTime != ''">
<![CDATA[
and STR_TO_DATE(end_time,'%Y-%m-%d %H:%i:%s') >= #{req.endSTime}
]]>
</if>
<if test="req.endETime != null and req.endETime != ''">
<![CDATA[
and STR_TO_DATE(end_time,'%Y-%m-%d %H:%i:%s') <= #{req.endETime}
]]>
</if>
<if test="req.finishSTime != null and req.finishSTime != ''">
<![CDATA[
and STR_TO_DATE(finish_time,'%Y-%m-%d %H:%i:%s') >= #{req.finishSTime}
]]>
</if>
<if test="req.finishETime != null and req.finishETime != ''">
<![CDATA[
and STR_TO_DATE(finish_time,'%Y-%m-%d %H:%i:%s') <= #{req.finishETime}
]]>
</if>
<!-- <if test='req.sortOrder != null and req.sortOrder == "0"'>-->
<!-- order by create_time-->
<!-- </if>-->
<!-- <if test='req.sortOrder != null and req.sortOrder == "1"'>-->
<!-- order by create_time desc-->
<!-- </if>-->
UNION
SELECT st.*
FROM simulation_task st
LEFT JOIN simulation_node_member snm ON st.tag1 = snm.nodeId
WHERE snm.user_id = #{req.userId}
AND st.tenant_id = #{tenantId}
<if test="req.demandId != null and req.demandId != ''">
and demand_id = #{req.demandId}
</if>
<if test="req.taskName != null and req.taskName != ''">
<bind name="searchKey" value="'%' + req.taskName + '%'"/>
and task_name like #{searchKey}
</if>
<if test="req.progress != null and req.progress != ''">
and progress = #{req.progress}
</if>
<if test="(req.exeStatusList != null and req.exeStatusList.size > 0) or (req.todayTmrTasks != null and req.todayTmrTasks != '')">
and (
<choose>
<!-- 只有状态条件 -->
<when test="req.exeStatusList != null and req.exeStatusList.size > 0 and (req.todayTmrTasks == null or req.todayTmrTasks == '')">
exe_status in (
<foreach collection='req.exeStatusList' item='exeStatus' index='index' separator=','>
#{exeStatus}
</foreach>
)
</when>
<!-- 只有时间条件 -->
<when test="(req.exeStatusList == null or req.exeStatusList.size == 0) and req.todayTmrTasks != null and req.todayTmrTasks != ''">
<![CDATA[
STR_TO_DATE(end_time,'%Y-%m-%d') >= CURRENT_DATE()
and STR_TO_DATE(end_time,'%Y-%m-%d') <= DATE_ADD(CURRENT_DATE(), INTERVAL 2 DAY)
]]>
</when>
<!-- 两个条件都有(并集) -->
<otherwise>
exe_status in (
<foreach collection='req.exeStatusList' item='exeStatus' index='index' separator=','>
#{exeStatus}
</foreach>
)
<![CDATA[ OR ]]>
<![CDATA[
STR_TO_DATE(end_time,'%Y-%m-%d') >= CURRENT_DATE()
and STR_TO_DATE(end_time,'%Y-%m-%d') <= DATE_ADD(CURRENT_DATE(), INTERVAL 2 DAY)
]]>
</otherwise>
</choose>
)
</if>
<if test="req.achieveStatusList != null and req.achieveStatusList.size > 0">
and achieve_status in (
<foreach collection='req.achieveStatusList' item='achieveStatus' index='index' separator=','>
#{achieveStatus}
</foreach>
)
</if>
<if test="req.approvalStatusList != null and req.approvalStatusList.size > 0">
and approval_status in (
<foreach collection='req.approvalStatusList' item='approvalStatus' index='index' separator=','>
#{approvalStatus}
</foreach>
)
</if>
<if test="req.beginSTime != null and req.beginSTime != ''">
<![CDATA[
and STR_TO_DATE(begin_time,'%Y-%m-%d %H:%i:%s') >= #{req.beginSTime}
]]>
</if>
<if test="req.beginETime != null and req.beginETime != ''">
<![CDATA[
and STR_TO_DATE(begin_time,'%Y-%m-%d %H:%i:%s') <= #{req.beginETime}
]]>
</if>
<if test="req.endSTime != null and req.endSTime != ''">
<![CDATA[
and STR_TO_DATE(end_time,'%Y-%m-%d %H:%i:%s') >= #{req.endSTime}
]]>
</if>
<if test="req.endETime != null and req.endETime != ''">
<![CDATA[
and STR_TO_DATE(end_time,'%Y-%m-%d %H:%i:%s') <= #{req.endETime}
]]>
</if>
<if test="req.finishSTime != null and req.finishSTime != ''">
<![CDATA[
and STR_TO_DATE(finish_time,'%Y-%m-%d %H:%i:%s') >= #{req.finishSTime}
]]>
</if>
<if test="req.finishETime != null and req.finishETime != ''">
<![CDATA[
and STR_TO_DATE(finish_time,'%Y-%m-%d %H:%i:%s') <= #{req.finishETime}
]]>
</if>
<!-- <if test='req.sortOrder != null and req.sortOrder == "0"'>-->
<!-- order by create_time-->
<!-- </if>-->
<!-- <if test='req.sortOrder != null and req.sortOrder == "1"'>-->
<!-- order by create_time desc-->
<!-- </if>-->
</select>
</mapper>