|
@@ -161,87 +161,154 @@ public class AppHomeServiceImpl implements IAppHomeService {
|
|
|
public Page<PlaceVO> getPlaceList(GetPlaceListDTO getPlaceListDTO) {
|
|
|
Page<PlaceVO> page = new Page<>(getPlaceListDTO.getCurrent(), getPlaceListDTO.getSize());
|
|
|
Page<PlaceVO> placeList = appSiteMapper.getPlaceList(page, getPlaceListDTO.getVenueType());
|
|
|
- if (ObjectUtil.isNotEmpty(placeList)) {
|
|
|
- // 提前收集所有场地ID
|
|
|
- List<String> placeIds = placeList.getRecords().stream()
|
|
|
- .map(PlaceVO::getId)
|
|
|
- .filter(Objects::nonNull)
|
|
|
- .collect(Collectors.toList());
|
|
|
- // 批量查询所有场地位置信息
|
|
|
- List<AppSitePlace> allSitePlaces = new ArrayList<>();
|
|
|
- if (!placeIds.isEmpty()) {
|
|
|
- allSitePlaces = appSitePlaceMapper.selectList(
|
|
|
- Wrappers.<AppSitePlace>lambdaQuery()
|
|
|
- .in(AppSitePlace::getSiteId, placeIds)
|
|
|
- .eq(AppSitePlace::getDelFlag, 0)
|
|
|
- .eq(AppSitePlace::getStatus, 0)
|
|
|
- );
|
|
|
- }
|
|
|
- // 按场地ID分组场地位置信息
|
|
|
- Map<String, List<AppSitePlace>> sitePlacesMap = allSitePlaces.stream()
|
|
|
- .collect(Collectors.groupingBy(AppSitePlace::getSiteId));
|
|
|
- // 收集所有场地位置ID用于查询价格规则
|
|
|
- List<String> sitePlaceIds = allSitePlaces.stream()
|
|
|
- .map(AppSitePlace::getId)
|
|
|
- .filter(Objects::nonNull)
|
|
|
- .collect(Collectors.toList());
|
|
|
- // 批量查询所有价格规则
|
|
|
- List<AppSitePriceRules> allPriceRules = new ArrayList<>();
|
|
|
- if (!sitePlaceIds.isEmpty()) {
|
|
|
- allPriceRules = appSitePriceRulesMapper.selectList(
|
|
|
- Wrappers.<AppSitePriceRules>lambdaQuery()
|
|
|
- .in(AppSitePriceRules::getSitePlaceId, sitePlaceIds)
|
|
|
- .eq(AppSitePriceRules::getDelFlag, 0)
|
|
|
- .eq(AppSitePriceRules::getStatus, 0)
|
|
|
- );
|
|
|
- }
|
|
|
- // 按场地位置ID分组价格规则
|
|
|
- Map<String, List<AppSitePriceRules>> priceRulesMap = allPriceRules.stream()
|
|
|
- .collect(Collectors.groupingBy(AppSitePriceRules::getSitePlaceId));
|
|
|
- // 批量处理场地数据
|
|
|
- placeList.getRecords().forEach(placeVO -> {
|
|
|
- boolean ticketWhether = false;
|
|
|
- // 检查是否有票价规则
|
|
|
- List<AppSitePlace> sitePlaces = sitePlacesMap.getOrDefault(placeVO.getId(), Collections.emptyList());
|
|
|
- for (AppSitePlace sitePlace : sitePlaces) {
|
|
|
- List<AppSitePriceRules> priceRules = priceRulesMap.getOrDefault(
|
|
|
- sitePlace.getId(), Collections.emptyList());
|
|
|
- if (!priceRules.isEmpty()) {
|
|
|
- ticketWhether = true;
|
|
|
- break;
|
|
|
+
|
|
|
+ List<PlaceVO> records = placeList.getRecords();
|
|
|
+ if (ObjectUtil.isNotEmpty(records)) {
|
|
|
+ int recordCount = records.size();
|
|
|
+ if (recordCount > 0) {
|
|
|
+ // 预分配集合大小以减少扩容
|
|
|
+ List<String> placeIds = new ArrayList<>(recordCount);
|
|
|
+
|
|
|
+ // 收集所有场地ID(使用传统循环提高性能)
|
|
|
+ for (int i = 0; i < recordCount; i++) {
|
|
|
+ PlaceVO placeVO = records.get(i);
|
|
|
+ if (placeVO.getId() != null) {
|
|
|
+ placeIds.add(placeVO.getId());
|
|
|
}
|
|
|
}
|
|
|
- // 计算距离
|
|
|
- if (placeVO.getLatitude() != null && placeVO.getLongitude() != null) {
|
|
|
- placeVO.setKm(PositionUtil.calculateDistance(
|
|
|
- getPlaceListDTO.getLatitude(),
|
|
|
- getPlaceListDTO.getLongitude(),
|
|
|
- placeVO.getLatitude().doubleValue(),
|
|
|
- placeVO.getLongitude().doubleValue()));
|
|
|
- } else {
|
|
|
- placeVO.setKm(0.0);
|
|
|
+
|
|
|
+ // 批量查询优化
|
|
|
+ Map<String, List<AppSitePlace>> sitePlacesMap = Collections.emptyMap();
|
|
|
+ Map<String, List<AppSitePriceRules>> priceRulesMap = Collections.emptyMap();
|
|
|
+
|
|
|
+ if (!placeIds.isEmpty()) {
|
|
|
+ // 一次性查询所有场地位置信息
|
|
|
+ List<AppSitePlace> allSitePlaces = appSitePlaceMapper.selectList(
|
|
|
+ Wrappers.<AppSitePlace>lambdaQuery()
|
|
|
+ .in(AppSitePlace::getSiteId, placeIds)
|
|
|
+ .eq(AppSitePlace::getDelFlag, 0)
|
|
|
+ .eq(AppSitePlace::getStatus, 0)
|
|
|
+ );
|
|
|
+
|
|
|
+ if (!allSitePlaces.isEmpty()) {
|
|
|
+ // 按场地ID分组场地位置信息
|
|
|
+ sitePlacesMap = new HashMap<>(placeIds.size());
|
|
|
+ for (AppSitePlace sitePlace : allSitePlaces) {
|
|
|
+ sitePlacesMap.computeIfAbsent(sitePlace.getSiteId(), k -> new ArrayList<>())
|
|
|
+ .add(sitePlace);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 收集所有场地位置ID用于查询价格规则
|
|
|
+ List<String> sitePlaceIds = new ArrayList<>(allSitePlaces.size());
|
|
|
+ for (int i = 0; i < allSitePlaces.size(); i++) {
|
|
|
+ String id = allSitePlaces.get(i).getId();
|
|
|
+ if (id != null) {
|
|
|
+ sitePlaceIds.add(id);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 批量查询所有价格规则
|
|
|
+ if (!sitePlaceIds.isEmpty()) {
|
|
|
+ List<AppSitePriceRules> allPriceRules = appSitePriceRulesMapper.selectList(
|
|
|
+ Wrappers.<AppSitePriceRules>lambdaQuery()
|
|
|
+ .in(AppSitePriceRules::getSitePlaceId, sitePlaceIds)
|
|
|
+ .eq(AppSitePriceRules::getDelFlag, 0)
|
|
|
+ .eq(AppSitePriceRules::getStatus, 0)
|
|
|
+ );
|
|
|
+
|
|
|
+ // 按场地位置ID分组价格规则
|
|
|
+ if (!allPriceRules.isEmpty()) {
|
|
|
+ priceRulesMap = new HashMap<>(sitePlaceIds.size());
|
|
|
+ for (AppSitePriceRules priceRule : allPriceRules) {
|
|
|
+ priceRulesMap.computeIfAbsent(priceRule.getSitePlaceId(), k -> new ArrayList<>())
|
|
|
+ .add(priceRule);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
- // 获取评分信息
|
|
|
- Long scoreNum = evaluateMapper.findByScoreNum(placeVO.getId());
|
|
|
- if (null == scoreNum) {
|
|
|
- scoreNum = 0L;
|
|
|
+
|
|
|
+ // 批量处理场地数据(使用传统循环提高性能)
|
|
|
+ final Map<String, List<AppSitePlace>> finalSitePlacesMap = sitePlacesMap;
|
|
|
+ final Map<String, List<AppSitePriceRules>> finalPriceRulesMap = priceRulesMap;
|
|
|
+
|
|
|
+ for (int i = 0; i < recordCount; i++) {
|
|
|
+ PlaceVO placeVO = records.get(i);
|
|
|
+ processPlaceVO(placeVO, getPlaceListDTO, finalSitePlacesMap, finalPriceRulesMap);
|
|
|
}
|
|
|
- Long scoreSum = evaluateMapper.findByAverageScore(placeVO.getId());
|
|
|
- if (null == scoreSum) {
|
|
|
- scoreSum = 0L;
|
|
|
+
|
|
|
+ // 排序优化
|
|
|
+ sortPlacesIfNecessary(records, getPlaceListDTO.getVenueType());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return placeList;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 处理单个场地VO数据
|
|
|
+ */
|
|
|
+ private void processPlaceVO(PlaceVO placeVO, GetPlaceListDTO getPlaceListDTO,
|
|
|
+ Map<String, List<AppSitePlace>> sitePlacesMap,
|
|
|
+ Map<String, List<AppSitePriceRules>> priceRulesMap) {
|
|
|
+ // 检查是否有票价规则
|
|
|
+ boolean ticketWhether = false;
|
|
|
+ List<AppSitePlace> sitePlaces = sitePlacesMap.getOrDefault(placeVO.getId(), Collections.emptyList());
|
|
|
+
|
|
|
+ if (!sitePlaces.isEmpty()) {
|
|
|
+ for (int i = 0; i < sitePlaces.size(); i++) {
|
|
|
+ AppSitePlace sitePlace = sitePlaces.get(i);
|
|
|
+ List<AppSitePriceRules> priceRules = priceRulesMap.getOrDefault(
|
|
|
+ sitePlace.getId(), Collections.emptyList());
|
|
|
+ if (!priceRules.isEmpty()) {
|
|
|
+ ticketWhether = true;
|
|
|
+ break;
|
|
|
}
|
|
|
- // 设置其他属性
|
|
|
- placeVO.setCategory(getCategoryName(placeVO.getCategoryId()));
|
|
|
- placeVO.setTicketWhether(ticketWhether);
|
|
|
- placeVO.setGoodRate(calculateAverage(scoreSum, scoreNum));
|
|
|
- placeVO.setComments(scoreNum);
|
|
|
- });
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 计算距离
|
|
|
+ if (placeVO.getLatitude() != null && placeVO.getLongitude() != null) {
|
|
|
+ placeVO.setKm(PositionUtil.calculateDistance(
|
|
|
+ getPlaceListDTO.getLatitude(),
|
|
|
+ getPlaceListDTO.getLongitude(),
|
|
|
+ placeVO.getLatitude().doubleValue(),
|
|
|
+ placeVO.getLongitude().doubleValue()));
|
|
|
+ } else {
|
|
|
+ placeVO.setKm(0.0);
|
|
|
}
|
|
|
- // 优化排序逻辑
|
|
|
- if (Arrays.asList("0-2", "1-1", "2-1").contains(getPlaceListDTO.getVenueType())) {
|
|
|
- placeList.getRecords().sort(Comparator.comparing(PlaceVO::getKm));
|
|
|
+
|
|
|
+ // 获取评分信息(考虑批量查询优化)
|
|
|
+ Long scoreNum = evaluateMapper.findByScoreNum(placeVO.getId());
|
|
|
+ if (null == scoreNum) {
|
|
|
+ scoreNum = 0L;
|
|
|
+ }
|
|
|
+
|
|
|
+ Long scoreSum = evaluateMapper.findByAverageScore(placeVO.getId());
|
|
|
+ if (null == scoreSum) {
|
|
|
+ scoreSum = 0L;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 设置其他属性
|
|
|
+ placeVO.setCategory(getCategoryName(placeVO.getCategoryId()));
|
|
|
+ placeVO.setTicketWhether(ticketWhether);
|
|
|
+ placeVO.setGoodRate(calculateAverage(scoreSum, scoreNum));
|
|
|
+ placeVO.setComments(scoreNum);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据条件排序场地列表
|
|
|
+ */
|
|
|
+ private void sortPlacesIfNecessary(List<PlaceVO> records, String venueType) {
|
|
|
+ if ("0-2".equals(venueType) || "1-1".equals(venueType) || "2-1".equals(venueType)) {
|
|
|
+ // 使用数组排序提高性能
|
|
|
+ PlaceVO[] placeArray = records.toArray(new PlaceVO[0]);
|
|
|
+ Arrays.sort(placeArray, Comparator.comparing(PlaceVO::getKm, Comparator.nullsLast(Double::compareTo)));
|
|
|
+ // 复制回原列表
|
|
|
+ for (int i = 0; i < placeArray.length; i++) {
|
|
|
+ records.set(i, placeArray[i]);
|
|
|
+ }
|
|
|
}
|
|
|
- return placeList;
|
|
|
}
|
|
|
|
|
|
@Override
|