Pārlūkot izejas kodu

refactor(app): 优化场地列表查询性能

- 重构 getPlaceList 方法,提高查询和处理效率
- 使用传统循环替换部分 Stream 操作,提升性能
-优化批量查询逻辑,减少数据库访问次数
- 改进排序算法,使用数组排序提高速度
SheepHy 1 nedēļu atpakaļ
vecāks
revīzija
1c9980517a

+ 141 - 74
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/app/service/impl/AppHomeServiceImpl.java

@@ -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