fix(registration): 修复我的报名列表信息显示不全问题
- 修改list接口返回VO而非Entity - 添加getListWithRelations方法批量加载关联数据 - 返回赛事名称、地点、时间、项目名称、选手名称等完整信息 - 优化批量查询减少数据库访问次数
This commit is contained in:
@@ -16,6 +16,7 @@ import org.springblade.core.tool.utils.Func;
|
||||
import org.springblade.modules.martial.pojo.entity.MartialAthlete;
|
||||
import org.springblade.modules.martial.pojo.entity.MartialRegistrationOrder;
|
||||
import org.springblade.modules.martial.pojo.dto.RegistrationSubmitDTO;
|
||||
import org.springblade.modules.martial.pojo.vo.MartialRegistrationOrderVO;
|
||||
import org.springblade.modules.martial.service.IMartialAthleteService;
|
||||
import org.springblade.modules.martial.service.IMartialRegistrationOrderService;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@@ -44,41 +45,26 @@ public class MartialRegistrationOrderController extends BladeController {
|
||||
@GetMapping("/detail")
|
||||
@Operation(summary = "详情", description = "传入ID")
|
||||
public R detail(@RequestParam Long id) {
|
||||
// 返回包含关联数据的完整详情
|
||||
return R.data(registrationOrderService.getDetailWithRelations(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页列表 - 只返回当前用户的报名记录
|
||||
* 分页列表 - 只返回当前用户的报名记录(包含关联数据)
|
||||
*/
|
||||
@GetMapping("/list")
|
||||
@Operation(summary = "分页列表", description = "分页查询当前用户的报名记录")
|
||||
public R<IPage<MartialRegistrationOrder>> list(MartialRegistrationOrder registrationOrder, Query query) {
|
||||
// 获取当前登录用户ID
|
||||
public R<IPage<MartialRegistrationOrderVO>> list(MartialRegistrationOrder registrationOrder, Query query) {
|
||||
Long userId = AuthUtil.getUserId();
|
||||
Integer status = registrationOrder.getStatus();
|
||||
|
||||
// 构建查询条件 - 只查询当前用户的订单
|
||||
LambdaQueryWrapper<MartialRegistrationOrder> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(MartialRegistrationOrder::getUserId, userId);
|
||||
|
||||
// 如果传入了状态参数,添加状态过滤
|
||||
if (registrationOrder.getStatus() != null) {
|
||||
queryWrapper.eq(MartialRegistrationOrder::getStatus, registrationOrder.getStatus());
|
||||
}
|
||||
|
||||
// 按创建时间倒序
|
||||
queryWrapper.orderByDesc(MartialRegistrationOrder::getCreateTime);
|
||||
|
||||
// 分页查询
|
||||
IPage<MartialRegistrationOrder> page = new Page<>(query.getCurrent(), query.getSize());
|
||||
IPage<MartialRegistrationOrder> pages = registrationOrderService.page(page, queryWrapper);
|
||||
IPage<MartialRegistrationOrderVO> pages = registrationOrderService.getListWithRelations(
|
||||
userId, status, query.getCurrent(), query.getSize());
|
||||
|
||||
return R.data(pages);
|
||||
}
|
||||
|
||||
/**
|
||||
* 提交报名订单
|
||||
* 接收前端传来的 athleteIds 和 projectIds,更新选手的 orderId
|
||||
*/
|
||||
@PostMapping("/submit")
|
||||
@Operation(summary = "提交报名", description = "提交报名订单并关联选手")
|
||||
@@ -92,7 +78,7 @@ public class MartialRegistrationOrderController extends BladeController {
|
||||
log.info("联系电话: {}", dto.getContactPhone());
|
||||
log.info("总金额: {}", dto.getTotalAmount());
|
||||
|
||||
// 1. 创建订单实体
|
||||
// Create order entity
|
||||
MartialRegistrationOrder order = new MartialRegistrationOrder();
|
||||
order.setOrderNo(dto.getOrderNo());
|
||||
order.setCompetitionId(dto.getCompetitionId());
|
||||
@@ -101,11 +87,11 @@ public class MartialRegistrationOrderController extends BladeController {
|
||||
order.setUserId(AuthUtil.getUserId());
|
||||
order.setUserName(AuthUtil.getUserName());
|
||||
|
||||
// 解析选手ID列表
|
||||
// Parse athlete IDs
|
||||
List<Long> athleteIds = Func.toLongList(dto.getAthleteIds());
|
||||
order.setTotalParticipants(athleteIds.size());
|
||||
|
||||
// 2. 保存订单
|
||||
// Save order
|
||||
boolean saved = registrationOrderService.save(order);
|
||||
if (!saved) {
|
||||
return R.fail("创建订单失败");
|
||||
@@ -114,18 +100,17 @@ public class MartialRegistrationOrderController extends BladeController {
|
||||
Long orderId = order.getId();
|
||||
log.info("订单创建成功,订单ID: {}", orderId);
|
||||
|
||||
// 3. 解析项目ID列表
|
||||
// Parse project IDs
|
||||
List<Long> projectIds = Func.toLongList(dto.getProjectIds());
|
||||
Long firstProjectId = projectIds.isEmpty() ? null : projectIds.get(0);
|
||||
|
||||
// 4. 更新选手的 orderId、competitionId 和 projectId
|
||||
// Update athletes with orderId, competitionId and projectId
|
||||
if (!athleteIds.isEmpty()) {
|
||||
LambdaUpdateWrapper<MartialAthlete> updateWrapper = new LambdaUpdateWrapper<>();
|
||||
updateWrapper.in(MartialAthlete::getId, athleteIds)
|
||||
.set(MartialAthlete::getOrderId, orderId)
|
||||
.set(MartialAthlete::getCompetitionId, dto.getCompetitionId());
|
||||
|
||||
// 如果只有一个项目,设置项目ID
|
||||
if (firstProjectId != null) {
|
||||
updateWrapper.set(MartialAthlete::getProjectId, firstProjectId);
|
||||
}
|
||||
@@ -134,7 +119,6 @@ public class MartialRegistrationOrderController extends BladeController {
|
||||
log.info("更新选手关联,选手数量: {}, 更新结果: {}", athleteIds.size(), updated);
|
||||
}
|
||||
|
||||
// 5. 返回订单信息
|
||||
return R.data(order);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.springblade.modules.martial.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import org.springblade.modules.martial.pojo.entity.MartialRegistrationOrder;
|
||||
import org.springblade.modules.martial.pojo.vo.MartialRegistrationOrderVO;
|
||||
@@ -19,4 +20,15 @@ public interface IMartialRegistrationOrderService extends IService<MartialRegist
|
||||
*/
|
||||
MartialRegistrationOrderVO getDetailWithRelations(Long id);
|
||||
|
||||
/**
|
||||
* 获取报名订单列表(包含关联数据)
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @param status 状态
|
||||
* @param current 当前页
|
||||
* @param size 每页大小
|
||||
* @return 订单列表VO
|
||||
*/
|
||||
IPage<MartialRegistrationOrderVO> getListWithRelations(Long userId, Integer status, Integer current, Integer size);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package org.springblade.modules.martial.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springblade.modules.martial.pojo.entity.MartialAthlete;
|
||||
@@ -16,7 +18,9 @@ import org.springblade.modules.martial.service.IMartialRegistrationOrderService;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@@ -34,40 +38,176 @@ public class MartialRegistrationOrderServiceImpl extends ServiceImpl<MartialRegi
|
||||
|
||||
@Override
|
||||
public MartialRegistrationOrderVO getDetailWithRelations(Long id) {
|
||||
// 获取订单基本信息
|
||||
MartialRegistrationOrder order = this.getById(id);
|
||||
if (order == null) {
|
||||
return null;
|
||||
}
|
||||
return convertToVO(order);
|
||||
}
|
||||
|
||||
// 创建VO对象
|
||||
@Override
|
||||
public IPage<MartialRegistrationOrderVO> getListWithRelations(Long userId, Integer status, Integer current, Integer size) {
|
||||
// Build query
|
||||
LambdaQueryWrapper<MartialRegistrationOrder> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(MartialRegistrationOrder::getUserId, userId);
|
||||
if (status != null) {
|
||||
queryWrapper.eq(MartialRegistrationOrder::getStatus, status);
|
||||
}
|
||||
queryWrapper.orderByDesc(MartialRegistrationOrder::getCreateTime);
|
||||
|
||||
// Paginate
|
||||
IPage<MartialRegistrationOrder> page = new Page<>(current, size);
|
||||
IPage<MartialRegistrationOrder> orderPage = this.page(page, queryWrapper);
|
||||
|
||||
// Convert to VO page
|
||||
IPage<MartialRegistrationOrderVO> voPage = new Page<>(current, size, orderPage.getTotal());
|
||||
|
||||
if (orderPage.getRecords().isEmpty()) {
|
||||
voPage.setRecords(new ArrayList<>());
|
||||
return voPage;
|
||||
}
|
||||
|
||||
// Batch load competition info
|
||||
List<Long> competitionIds = orderPage.getRecords().stream()
|
||||
.map(MartialRegistrationOrder::getCompetitionId)
|
||||
.filter(id -> id != null)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
|
||||
Map<Long, MartialCompetition> competitionMap = competitionIds.isEmpty() ?
|
||||
Map.of() :
|
||||
competitionService.listByIds(competitionIds).stream()
|
||||
.collect(Collectors.toMap(MartialCompetition::getId, c -> c));
|
||||
|
||||
// Batch load athletes by order IDs
|
||||
List<Long> orderIds = orderPage.getRecords().stream()
|
||||
.map(MartialRegistrationOrder::getId)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
LambdaQueryWrapper<MartialAthlete> athleteWrapper = new LambdaQueryWrapper<>();
|
||||
athleteWrapper.in(MartialAthlete::getOrderId, orderIds);
|
||||
List<MartialAthlete> allAthletes = athleteService.list(athleteWrapper);
|
||||
|
||||
Map<Long, List<MartialAthlete>> athletesByOrder = allAthletes.stream()
|
||||
.collect(Collectors.groupingBy(MartialAthlete::getOrderId));
|
||||
|
||||
// Batch load projects
|
||||
List<Long> projectIds = allAthletes.stream()
|
||||
.map(MartialAthlete::getProjectId)
|
||||
.filter(id -> id != null)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
|
||||
Map<Long, MartialProject> projectMap = projectIds.isEmpty() ?
|
||||
Map.of() :
|
||||
projectService.listByIds(projectIds).stream()
|
||||
.collect(Collectors.toMap(MartialProject::getId, p -> p));
|
||||
|
||||
// Convert each order to VO
|
||||
List<MartialRegistrationOrderVO> voList = orderPage.getRecords().stream()
|
||||
.map(order -> {
|
||||
MartialRegistrationOrderVO vo = new MartialRegistrationOrderVO();
|
||||
BeanUtils.copyProperties(order, vo);
|
||||
|
||||
// Set competition info
|
||||
MartialCompetition competition = competitionMap.get(order.getCompetitionId());
|
||||
if (competition != null) {
|
||||
vo.setCompetitionName(competition.getCompetitionName());
|
||||
vo.setLocation(competition.getLocation());
|
||||
vo.setStartTime(competition.getCompetitionStartTime() != null ?
|
||||
competition.getCompetitionStartTime().toString() : null);
|
||||
vo.setEndTime(competition.getCompetitionEndTime() != null ?
|
||||
competition.getCompetitionEndTime().toString() : null);
|
||||
}
|
||||
|
||||
// Set athlete info
|
||||
List<MartialAthlete> athletes = athletesByOrder.getOrDefault(order.getId(), new ArrayList<>());
|
||||
if (!athletes.isEmpty()) {
|
||||
String athleteNames = athletes.stream()
|
||||
.map(MartialAthlete::getPlayerName)
|
||||
.collect(Collectors.joining("、"));
|
||||
vo.setAthleteNames(athleteNames);
|
||||
|
||||
List<MartialRegistrationOrderVO.AthleteInfo> athleteList = athletes.stream()
|
||||
.map(athlete -> {
|
||||
MartialRegistrationOrderVO.AthleteInfo info = new MartialRegistrationOrderVO.AthleteInfo();
|
||||
info.setId(athlete.getId());
|
||||
info.setPlayerName(athlete.getPlayerName());
|
||||
info.setGender(athlete.getGender());
|
||||
info.setIdCard(athlete.getIdCard());
|
||||
return info;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
vo.setAthleteList(athleteList);
|
||||
|
||||
// Set project info
|
||||
List<Long> orderProjectIds = athletes.stream()
|
||||
.map(MartialAthlete::getProjectId)
|
||||
.filter(id -> id != null)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (!orderProjectIds.isEmpty()) {
|
||||
List<MartialProject> projects = orderProjectIds.stream()
|
||||
.map(projectMap::get)
|
||||
.filter(p -> p != null)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
String projectNames = projects.stream()
|
||||
.map(MartialProject::getProjectName)
|
||||
.collect(Collectors.joining("、"));
|
||||
vo.setProjectNames(projectNames);
|
||||
|
||||
List<MartialRegistrationOrderVO.ProjectInfo> projectList = projects.stream()
|
||||
.map(project -> {
|
||||
MartialRegistrationOrderVO.ProjectInfo info = new MartialRegistrationOrderVO.ProjectInfo();
|
||||
info.setId(project.getId());
|
||||
info.setProjectName(project.getProjectName());
|
||||
Integer type = project.getType();
|
||||
info.setProjectType(type == 1 ? "个人" : "集体");
|
||||
return info;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
vo.setProjectList(projectList);
|
||||
}
|
||||
}
|
||||
|
||||
return vo;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
||||
voPage.setRecords(voList);
|
||||
return voPage;
|
||||
}
|
||||
|
||||
private MartialRegistrationOrderVO convertToVO(MartialRegistrationOrder order) {
|
||||
MartialRegistrationOrderVO vo = new MartialRegistrationOrderVO();
|
||||
BeanUtils.copyProperties(order, vo);
|
||||
|
||||
// 获取赛事信息
|
||||
// Get competition info
|
||||
if (order.getCompetitionId() != null) {
|
||||
MartialCompetition competition = competitionService.getById(order.getCompetitionId());
|
||||
if (competition != null) {
|
||||
vo.setCompetitionName(competition.getCompetitionName());
|
||||
vo.setLocation(competition.getLocation());
|
||||
vo.setStartTime(competition.getCompetitionStartTime() != null ? competition.getCompetitionStartTime().toString() : null);
|
||||
vo.setEndTime(competition.getCompetitionEndTime() != null ? competition.getCompetitionEndTime().toString() : null);
|
||||
vo.setStartTime(competition.getCompetitionStartTime() != null ?
|
||||
competition.getCompetitionStartTime().toString() : null);
|
||||
vo.setEndTime(competition.getCompetitionEndTime() != null ?
|
||||
competition.getCompetitionEndTime().toString() : null);
|
||||
}
|
||||
}
|
||||
|
||||
// 获取该订单的所有选手
|
||||
// Get athletes for this order
|
||||
LambdaQueryWrapper<MartialAthlete> athleteWrapper = new LambdaQueryWrapper<>();
|
||||
athleteWrapper.eq(MartialAthlete::getOrderId, id);
|
||||
athleteWrapper.eq(MartialAthlete::getOrderId, order.getId());
|
||||
List<MartialAthlete> athletes = athleteService.list(athleteWrapper);
|
||||
|
||||
if (!athletes.isEmpty()) {
|
||||
// 设置选手名称列表
|
||||
String athleteNames = athletes.stream()
|
||||
.map(MartialAthlete::getPlayerName)
|
||||
.collect(Collectors.joining("、"));
|
||||
vo.setAthleteNames(athleteNames);
|
||||
|
||||
// 设置选手详细列表
|
||||
List<MartialRegistrationOrderVO.AthleteInfo> athleteList = athletes.stream()
|
||||
.map(athlete -> {
|
||||
MartialRegistrationOrderVO.AthleteInfo info = new MartialRegistrationOrderVO.AthleteInfo();
|
||||
@@ -80,7 +220,7 @@ public class MartialRegistrationOrderServiceImpl extends ServiceImpl<MartialRegi
|
||||
.collect(Collectors.toList());
|
||||
vo.setAthleteList(athleteList);
|
||||
|
||||
// 获取项目信息(从选手的项目ID中去重)
|
||||
// Get project info
|
||||
List<Long> projectIds = athletes.stream()
|
||||
.map(MartialAthlete::getProjectId)
|
||||
.filter(projectId -> projectId != null)
|
||||
@@ -90,22 +230,18 @@ public class MartialRegistrationOrderServiceImpl extends ServiceImpl<MartialRegi
|
||||
if (!projectIds.isEmpty()) {
|
||||
List<MartialProject> projects = projectService.listByIds(projectIds);
|
||||
|
||||
// 设置项目名称列表
|
||||
String projectNames = projects.stream()
|
||||
.map(MartialProject::getProjectName)
|
||||
.collect(Collectors.joining("、"));
|
||||
vo.setProjectNames(projectNames);
|
||||
|
||||
// 设置项目详细列表
|
||||
List<MartialRegistrationOrderVO.ProjectInfo> projectList = projects.stream()
|
||||
.map(project -> {
|
||||
MartialRegistrationOrderVO.ProjectInfo info = new MartialRegistrationOrderVO.ProjectInfo();
|
||||
info.setId(project.getId());
|
||||
info.setProjectName(project.getProjectName());
|
||||
//类型(1-个人,2-双人,3-集体)
|
||||
Integer type = project.getType();
|
||||
String strType = type == 1 ? "个人":"集体";
|
||||
info.setProjectType(strType);
|
||||
info.setProjectType(type == 1 ? "个人" : "集体");
|
||||
return info;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
||||
Reference in New Issue
Block a user