feat(registration): add team members info for group registration certificate view

- Add teamId, isTeam, members fields to AthleteInfo
- Add MemberInfo class for team member details
- Query martial_team and martial_team_member tables for group projects
- Return member name, gender, idCard for frontend display

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
This commit is contained in:
2026-01-23 13:17:51 +08:00
parent 00429b2b27
commit c9e1f069a7
2 changed files with 203 additions and 17 deletions
@@ -101,5 +101,33 @@ public class MartialRegistrationOrderVO extends MartialRegistrationOrder {
@Schema(description = "身份证号")
private String idCard;
@Schema(description = "集体ID(集体项目时有值)")
private Long teamId;
@Schema(description = "是否为集体项目")
private Boolean isTeam;
@Schema(description = "集体成员列表(集体项目时有值)")
private List<MemberInfo> members;
}
/**
* 集体成员信息
*/
@Data
@Schema(description = "集体成员信息")
public static class MemberInfo {
@Schema(description = "成员ID")
private Long id;
@Schema(description = "成员姓名")
private String name;
@Schema(description = "性别")
private Integer gender;
@Schema(description = "身份证号")
private String idCard;
}
}
@@ -9,11 +9,15 @@ import org.springblade.modules.martial.pojo.entity.MartialAthlete;
import org.springblade.modules.martial.pojo.entity.MartialCompetition;
import org.springblade.modules.martial.pojo.entity.MartialProject;
import org.springblade.modules.martial.pojo.entity.MartialRegistrationOrder;
import org.springblade.modules.martial.pojo.entity.MartialTeam;
import org.springblade.modules.martial.pojo.entity.MartialTeamMember;
import org.springblade.modules.martial.pojo.vo.MartialRegistrationOrderVO;
import org.springblade.modules.martial.mapper.MartialRegistrationOrderMapper;
import org.springblade.modules.martial.mapper.MartialTeamMemberMapper;
import org.springblade.modules.martial.service.IMartialAthleteService;
import org.springblade.modules.martial.service.IMartialCompetitionService;
import org.springblade.modules.martial.service.IMartialProjectService;
import org.springblade.modules.martial.service.IMartialTeamService;
import org.springblade.modules.martial.service.IMartialRegistrationOrderService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
@@ -21,6 +25,7 @@ import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
/**
@@ -35,6 +40,8 @@ public class MartialRegistrationOrderServiceImpl extends ServiceImpl<MartialRegi
private final IMartialCompetitionService competitionService;
private final IMartialAthleteService athleteService;
private final IMartialProjectService projectService;
private final IMartialTeamService teamService;
private final MartialTeamMemberMapper teamMemberMapper;
@Override
public MartialRegistrationOrderVO getDetailWithRelations(Long id) {
@@ -92,7 +99,7 @@ public class MartialRegistrationOrderServiceImpl extends ServiceImpl<MartialRegi
// Batch load competition info
List<Long> competitionIds = orderPage.getRecords().stream()
.map(MartialRegistrationOrder::getCompetitionId)
.filter(id -> id != null)
.filter(cid -> cid != null)
.distinct()
.collect(Collectors.toList());
@@ -117,7 +124,7 @@ public class MartialRegistrationOrderServiceImpl extends ServiceImpl<MartialRegi
// Batch load projects
List<Long> projectIds = allAthletes.stream()
.map(MartialAthlete::getProjectId)
.filter(id -> id != null)
.filter(pid -> pid != null)
.distinct()
.collect(Collectors.toList());
@@ -126,6 +133,51 @@ public class MartialRegistrationOrderServiceImpl extends ServiceImpl<MartialRegi
projectService.listByIds(projectIds).stream()
.collect(Collectors.toMap(MartialProject::getId, p -> p));
// Batch load teams by team names from athletes
Set<String> teamNames = allAthletes.stream()
.map(MartialAthlete::getTeamName)
.filter(name -> name != null && !name.isEmpty())
.collect(Collectors.toSet());
Map<String, MartialTeam> teamByName = Map.of();
Map<Long, List<MartialTeamMember>> membersByTeam = Map.of();
Map<Long, MartialAthlete> athleteById = Map.of();
if (!teamNames.isEmpty()) {
LambdaQueryWrapper<MartialTeam> teamWrapper = new LambdaQueryWrapper<>();
teamWrapper.in(MartialTeam::getTeamName, teamNames);
teamWrapper.eq(MartialTeam::getIsDeleted, 0);
List<MartialTeam> teams = teamService.list(teamWrapper);
teamByName = teams.stream()
.collect(Collectors.toMap(MartialTeam::getTeamName, t -> t, (a, b) -> a));
// Load team members
if (!teams.isEmpty()) {
List<Long> teamIds = teams.stream().map(MartialTeam::getId).collect(Collectors.toList());
LambdaQueryWrapper<MartialTeamMember> memberWrapper = new LambdaQueryWrapper<>();
memberWrapper.in(MartialTeamMember::getTeamId, teamIds);
memberWrapper.eq(MartialTeamMember::getIsDeleted, 0);
List<MartialTeamMember> allMembers = teamMemberMapper.selectList(memberWrapper);
membersByTeam = allMembers.stream()
.collect(Collectors.groupingBy(MartialTeamMember::getTeamId));
// Load member athlete details
Set<Long> memberAthleteIds = allMembers.stream()
.map(MartialTeamMember::getAthleteId)
.collect(Collectors.toSet());
if (!memberAthleteIds.isEmpty()) {
List<MartialAthlete> memberAthletes = athleteService.listByIds(memberAthleteIds);
athleteById = memberAthletes.stream()
.collect(Collectors.toMap(MartialAthlete::getId, a -> a, (a, b) -> a));
}
}
}
// Make final references for lambda
final Map<String, MartialTeam> finalTeamByName = teamByName;
final Map<Long, List<MartialTeamMember>> finalMembersByTeam = membersByTeam;
final Map<Long, MartialAthlete> finalAthleteById = athleteById;
// Convert each order to VO
List<MartialRegistrationOrderVO> voList = orderPage.getRecords().stream()
.map(order -> {
@@ -165,6 +217,39 @@ public class MartialRegistrationOrderServiceImpl extends ServiceImpl<MartialRegi
info.setPlayerName(athlete.getPlayerName());
info.setGender(athlete.getGender());
info.setIdCard(athlete.getIdCard());
// Check if this is a team entry
String teamName = athlete.getTeamName();
if (teamName != null && !teamName.isEmpty()) {
MartialTeam team = finalTeamByName.get(teamName);
if (team != null) {
info.setIsTeam(true);
info.setTeamId(team.getId());
// Get team members
List<MartialTeamMember> members = finalMembersByTeam.getOrDefault(team.getId(), new ArrayList<>());
List<MartialRegistrationOrderVO.MemberInfo> memberInfoList = members.stream()
.map(m -> {
MartialRegistrationOrderVO.MemberInfo mi = new MartialRegistrationOrderVO.MemberInfo();
MartialAthlete ma = finalAthleteById.get(m.getAthleteId());
if (ma != null) {
mi.setId(ma.getId());
mi.setName(ma.getPlayerName());
mi.setGender(ma.getGender());
mi.setIdCard(ma.getIdCard());
}
return mi;
})
.filter(mi -> mi.getId() != null)
.collect(Collectors.toList());
info.setMembers(memberInfoList);
} else {
info.setIsTeam(false);
}
} else {
info.setIsTeam(false);
}
return info;
},
(existing, replacement) -> existing
@@ -177,7 +262,7 @@ public class MartialRegistrationOrderServiceImpl extends ServiceImpl<MartialRegi
// Set project info
List<Long> orderProjectIds = athletes.stream()
.map(MartialAthlete::getProjectId)
.filter(id -> id != null)
.filter(pid -> pid != null)
.distinct()
.collect(Collectors.toList());
@@ -194,12 +279,12 @@ public class MartialRegistrationOrderServiceImpl extends ServiceImpl<MartialRegi
List<MartialRegistrationOrderVO.ProjectInfo> projectList = projects.stream()
.map(project -> {
MartialRegistrationOrderVO.ProjectInfo info = new MartialRegistrationOrderVO.ProjectInfo();
info.setId(project.getId());
info.setProjectName(project.getProjectName());
MartialRegistrationOrderVO.ProjectInfo pinfo = new MartialRegistrationOrderVO.ProjectInfo();
pinfo.setId(project.getId());
pinfo.setProjectName(project.getProjectName());
Integer type = project.getType();
info.setProjectType(type == 1 ? "个人" : "集体");
return info;
pinfo.setProjectType(type == 1 ? "个人" : "集体");
return pinfo;
})
.collect(Collectors.toList());
vo.setProjectList(projectList);
@@ -214,7 +299,7 @@ public class MartialRegistrationOrderServiceImpl extends ServiceImpl<MartialRegi
final Integer filterStatus = status;
if (filterStatus != null && filterStatus > 0) {
voList = voList.stream()
.filter(vo -> filterStatus.equals(vo.getStatus()))
.filter(v -> filterStatus.equals(v.getStatus()))
.collect(Collectors.toList());
}
@@ -253,6 +338,48 @@ public class MartialRegistrationOrderServiceImpl extends ServiceImpl<MartialRegi
.collect(Collectors.joining(""));
vo.setAthleteNames(athleteNames);
// Load teams for team entries
Set<String> teamNames = athletes.stream()
.map(MartialAthlete::getTeamName)
.filter(name -> name != null && !name.isEmpty())
.collect(Collectors.toSet());
Map<String, MartialTeam> teamByName = Map.of();
Map<Long, List<MartialTeamMember>> membersByTeam = Map.of();
Map<Long, MartialAthlete> athleteById = Map.of();
if (!teamNames.isEmpty()) {
LambdaQueryWrapper<MartialTeam> teamWrapper = new LambdaQueryWrapper<>();
teamWrapper.in(MartialTeam::getTeamName, teamNames);
teamWrapper.eq(MartialTeam::getIsDeleted, 0);
List<MartialTeam> teams = teamService.list(teamWrapper);
teamByName = teams.stream()
.collect(Collectors.toMap(MartialTeam::getTeamName, t -> t, (a, b) -> a));
if (!teams.isEmpty()) {
List<Long> teamIds = teams.stream().map(MartialTeam::getId).collect(Collectors.toList());
LambdaQueryWrapper<MartialTeamMember> memberWrapper = new LambdaQueryWrapper<>();
memberWrapper.in(MartialTeamMember::getTeamId, teamIds);
memberWrapper.eq(MartialTeamMember::getIsDeleted, 0);
List<MartialTeamMember> allMembers = teamMemberMapper.selectList(memberWrapper);
membersByTeam = allMembers.stream()
.collect(Collectors.groupingBy(MartialTeamMember::getTeamId));
Set<Long> memberAthleteIds = allMembers.stream()
.map(MartialTeamMember::getAthleteId)
.collect(Collectors.toSet());
if (!memberAthleteIds.isEmpty()) {
List<MartialAthlete> memberAthletes = athleteService.listByIds(memberAthleteIds);
athleteById = memberAthletes.stream()
.collect(Collectors.toMap(MartialAthlete::getId, a -> a, (a, b) -> a));
}
}
}
final Map<String, MartialTeam> finalTeamByName = teamByName;
final Map<Long, List<MartialTeamMember>> finalMembersByTeam = membersByTeam;
final Map<Long, MartialAthlete> finalAthleteById = athleteById;
List<MartialRegistrationOrderVO.AthleteInfo> athleteList = athletes.stream()
.collect(Collectors.toMap(
MartialAthlete::getPlayerName,
@@ -262,6 +389,37 @@ public class MartialRegistrationOrderServiceImpl extends ServiceImpl<MartialRegi
info.setPlayerName(athlete.getPlayerName());
info.setGender(athlete.getGender());
info.setIdCard(athlete.getIdCard());
String teamName = athlete.getTeamName();
if (teamName != null && !teamName.isEmpty()) {
MartialTeam team = finalTeamByName.get(teamName);
if (team != null) {
info.setIsTeam(true);
info.setTeamId(team.getId());
List<MartialTeamMember> members = finalMembersByTeam.getOrDefault(team.getId(), new ArrayList<>());
List<MartialRegistrationOrderVO.MemberInfo> memberInfoList = members.stream()
.map(m -> {
MartialRegistrationOrderVO.MemberInfo mi = new MartialRegistrationOrderVO.MemberInfo();
MartialAthlete ma = finalAthleteById.get(m.getAthleteId());
if (ma != null) {
mi.setId(ma.getId());
mi.setName(ma.getPlayerName());
mi.setGender(ma.getGender());
mi.setIdCard(ma.getIdCard());
}
return mi;
})
.filter(mi -> mi.getId() != null)
.collect(Collectors.toList());
info.setMembers(memberInfoList);
} else {
info.setIsTeam(false);
}
} else {
info.setIsTeam(false);
}
return info;
},
(existing, replacement) -> existing
@@ -272,14 +430,14 @@ public class MartialRegistrationOrderServiceImpl extends ServiceImpl<MartialRegi
vo.setAthleteList(athleteList);
// Get project info
List<Long> projectIds = athletes.stream()
List<Long> pids = athletes.stream()
.map(MartialAthlete::getProjectId)
.filter(projectId -> projectId != null)
.distinct()
.collect(Collectors.toList());
if (!projectIds.isEmpty()) {
List<MartialProject> projects = projectService.listByIds(projectIds);
if (!pids.isEmpty()) {
List<MartialProject> projects = projectService.listByIds(pids);
String projectNames = projects.stream()
.map(MartialProject::getProjectName)
@@ -288,12 +446,12 @@ public class MartialRegistrationOrderServiceImpl extends ServiceImpl<MartialRegi
List<MartialRegistrationOrderVO.ProjectInfo> projectList = projects.stream()
.map(project -> {
MartialRegistrationOrderVO.ProjectInfo info = new MartialRegistrationOrderVO.ProjectInfo();
info.setId(project.getId());
info.setProjectName(project.getProjectName());
MartialRegistrationOrderVO.ProjectInfo pinfo = new MartialRegistrationOrderVO.ProjectInfo();
pinfo.setId(project.getId());
pinfo.setProjectName(project.getProjectName());
Integer type = project.getType();
info.setProjectType(type == 1 ? "个人" : "集体");
return info;
pinfo.setProjectType(type == 1 ? "个人" : "集体");
return pinfo;
})
.collect(Collectors.toList());
vo.setProjectList(projectList);