diff --git a/minio_data/.minio.sys/buckets/.bloomcycle.bin/xl.meta b/minio_data/.minio.sys/buckets/.bloomcycle.bin/xl.meta index 19efbe3..72f9ca3 100644 Binary files a/minio_data/.minio.sys/buckets/.bloomcycle.bin/xl.meta and b/minio_data/.minio.sys/buckets/.bloomcycle.bin/xl.meta differ diff --git a/minio_data/.minio.sys/buckets/.usage-cache.bin.bkp/xl.meta b/minio_data/.minio.sys/buckets/.usage-cache.bin.bkp/xl.meta index 3b2427f..58608ed 100644 Binary files a/minio_data/.minio.sys/buckets/.usage-cache.bin.bkp/xl.meta and b/minio_data/.minio.sys/buckets/.usage-cache.bin.bkp/xl.meta differ diff --git a/minio_data/.minio.sys/buckets/.usage-cache.bin/xl.meta b/minio_data/.minio.sys/buckets/.usage-cache.bin/xl.meta index ed864e4..34a4875 100644 Binary files a/minio_data/.minio.sys/buckets/.usage-cache.bin/xl.meta and b/minio_data/.minio.sys/buckets/.usage-cache.bin/xl.meta differ diff --git a/minio_data/.minio.sys/buckets/.usage.json/xl.meta b/minio_data/.minio.sys/buckets/.usage.json/xl.meta index 3d1e5b1..a479c26 100644 Binary files a/minio_data/.minio.sys/buckets/.usage.json/xl.meta and b/minio_data/.minio.sys/buckets/.usage.json/xl.meta differ diff --git a/minio_data/.minio.sys/buckets/000000-assets/.usage-cache.bin.bkp/xl.meta b/minio_data/.minio.sys/buckets/000000-assets/.usage-cache.bin.bkp/xl.meta index cadf705..418b72a 100644 Binary files a/minio_data/.minio.sys/buckets/000000-assets/.usage-cache.bin.bkp/xl.meta and b/minio_data/.minio.sys/buckets/000000-assets/.usage-cache.bin.bkp/xl.meta differ diff --git a/minio_data/.minio.sys/buckets/000000-assets/.usage-cache.bin/xl.meta b/minio_data/.minio.sys/buckets/000000-assets/.usage-cache.bin/xl.meta index 8233774..da5d3e9 100644 Binary files a/minio_data/.minio.sys/buckets/000000-assets/.usage-cache.bin/xl.meta and b/minio_data/.minio.sys/buckets/000000-assets/.usage-cache.bin/xl.meta differ diff --git a/minio_data/.minio.sys/buckets/assets/.usage-cache.bin.bkp/xl.meta b/minio_data/.minio.sys/buckets/assets/.usage-cache.bin.bkp/xl.meta index 4c8640d..754d213 100644 Binary files a/minio_data/.minio.sys/buckets/assets/.usage-cache.bin.bkp/xl.meta and b/minio_data/.minio.sys/buckets/assets/.usage-cache.bin.bkp/xl.meta differ diff --git a/minio_data/.minio.sys/buckets/assets/.usage-cache.bin/xl.meta b/minio_data/.minio.sys/buckets/assets/.usage-cache.bin/xl.meta index a7c8b33..30ae789 100644 Binary files a/minio_data/.minio.sys/buckets/assets/.usage-cache.bin/xl.meta and b/minio_data/.minio.sys/buckets/assets/.usage-cache.bin/xl.meta differ diff --git a/src/main/java/org/springblade/modules/martial/service/impl/ScheduleQueryServiceImpl.java b/src/main/java/org/springblade/modules/martial/service/impl/ScheduleQueryServiceImpl.java index 770ae48..bf8b1fe 100644 --- a/src/main/java/org/springblade/modules/martial/service/impl/ScheduleQueryServiceImpl.java +++ b/src/main/java/org/springblade/modules/martial/service/impl/ScheduleQueryServiceImpl.java @@ -98,6 +98,82 @@ public class ScheduleQueryServiceImpl implements IScheduleQueryService { // 获取参赛者列表 boolean isCollective = firstDetail.getProjectType() != null && firstDetail.getProjectType() == 2; List participantDTOs = new ArrayList<>(); + // Batch query optimization: collect all participant IDs first + List participantIds = groupDetails.stream() + .map(ScheduleGroupDetailVO::getParticipantId) + .filter(id -> id != null) + .collect(Collectors.toList()); + + // Batch query all athletes + Map athleteMap = new HashMap<>(); + if (!participantIds.isEmpty()) { + List athletes = athleteMapper.selectBatchIds(participantIds); + athleteMap = athletes.stream().collect(Collectors.toMap(MartialAthlete::getId, a -> a)); + } + + // Batch query teams and members for collective projects + Map>> teamMembersCache = new HashMap<>(); + if (isCollective && !athleteMap.isEmpty()) { + // Collect all team names + Set teamNames = athleteMap.values().stream() + .map(MartialAthlete::getTeamName) + .filter(name -> name != null) + .collect(Collectors.toSet()); + + if (!teamNames.isEmpty()) { + // Batch query all teams + QueryWrapper teamWrapper = new QueryWrapper<>(); + teamWrapper.in("team_name", teamNames); + teamWrapper.eq("is_deleted", 0); + List teams = teamMapper.selectList(teamWrapper); + + if (!teams.isEmpty()) { + // Batch query all team members + List teamIds = teams.stream().map(MartialTeam::getId).collect(Collectors.toList()); + QueryWrapper memberWrapper = new QueryWrapper<>(); + memberWrapper.in("team_id", teamIds); + memberWrapper.eq("is_deleted", 0); + List allMembers = teamMemberMapper.selectList(memberWrapper); + + // Batch query member athletes + List memberAthleteIds = allMembers.stream() + .map(MartialTeamMember::getAthleteId) + .collect(Collectors.toList()); + Map memberAthleteMap = new HashMap<>(); + if (!memberAthleteIds.isEmpty()) { + List memberAthletes = athleteMapper.selectBatchIds(memberAthleteIds); + memberAthleteMap = memberAthletes.stream() + .collect(Collectors.toMap(MartialAthlete::getId, a -> a)); + } + + // Build team members cache + Map teamNameToId = teams.stream() + .collect(Collectors.toMap(MartialTeam::getTeamName, MartialTeam::getId)); + Map> teamMembersMap = allMembers.stream() + .collect(Collectors.groupingBy(MartialTeamMember::getTeamId)); + + for (MartialAthlete athlete : athleteMap.values()) { + if (athlete.getTeamName() != null) { + Long teamId = teamNameToId.get(athlete.getTeamName()); + if (teamId != null) { + List members = teamMembersMap.getOrDefault(teamId, new ArrayList<>()); + List> memberList = new ArrayList<>(); + for (MartialTeamMember member : members) { + Map memberData = new HashMap<>(); + memberData.put("id", member.getId()); + MartialAthlete memberAthlete = memberAthleteMap.get(member.getAthleteId()); + memberData.put("name", memberAthlete != null ? memberAthlete.getPlayerName() : ""); + memberData.put("gender", memberAthlete != null ? memberAthlete.getGender() : ""); + memberList.add(memberData); + } + teamMembersCache.put(athlete.getId(), memberList); + } + } + } + } + } + } + for (ScheduleGroupDetailVO d : groupDetails) { if (d.getParticipantId() == null) continue; @@ -108,41 +184,14 @@ public class ScheduleQueryServiceImpl implements IScheduleQueryService { dto.setSortOrder(d.getPerformanceOrder()); dto.setPlayerName(d.getPlayerName()); - // For collective projects, query team members + // Use cached team members data if (isCollective) { - List> memberList = new ArrayList<>(); - // Step 1: Get athlete record to find team_name - MartialAthlete participantAthlete = athleteMapper.selectById(d.getParticipantId()); - if (participantAthlete != null && participantAthlete.getTeamName() != null) { - // Step 2: Find team by team_name - QueryWrapper teamWrapper = new QueryWrapper<>(); - teamWrapper.eq("team_name", participantAthlete.getTeamName()); - teamWrapper.eq("is_deleted", 0); - MartialTeam team = teamMapper.selectOne(teamWrapper); - if (team != null) { - // Step 3: Query team members - QueryWrapper memberWrapper = new QueryWrapper<>(); - memberWrapper.eq("team_id", team.getId()); - memberWrapper.eq("is_deleted", 0); - List members = teamMemberMapper.selectList(memberWrapper); - // Step 4: Get member athlete info - for (MartialTeamMember member : members) { - Map memberData = new HashMap<>(); - memberData.put("id", member.getId()); - MartialAthlete athlete = athleteMapper.selectById(member.getAthleteId()); - memberData.put("name", athlete != null ? athlete.getPlayerName() : ""); - memberData.put("gender", athlete != null ? athlete.getGender() : ""); - memberList.add(memberData); - } - } - } + List> memberList = teamMembersCache.getOrDefault(d.getParticipantId(), new ArrayList<>()); dto.setMembers(memberList); } participantDTOs.add(dto); } - groupDTO.setParticipants(participantDTOs); - groupDTO.setStatus(calculateGroupStatus(participantDTOs)); groupDTOs.add(groupDTO); } diff --git a/src/test/java/org/springblade/modules/martial/service/impl/ScheduleQueryServiceImplTest.java b/src/test/java/org/springblade/modules/martial/service/impl/ScheduleQueryServiceImplTest.java index 4f524a2..d3a46e4 100644 --- a/src/test/java/org/springblade/modules/martial/service/impl/ScheduleQueryServiceImplTest.java +++ b/src/test/java/org/springblade/modules/martial/service/impl/ScheduleQueryServiceImplTest.java @@ -27,6 +27,15 @@ class ScheduleQueryServiceImplTest { @Mock private MartialScheduleGroupMapper scheduleGroupMapper; + @Mock + private MartialAthleteMapper athleteMapper; + + @Mock + private MartialTeamMapper teamMapper; + + @Mock + private MartialTeamMemberMapper teamMemberMapper; + @Mock private IMartialProjectService projectService;