Ver Fonte

优化打卡广场 qxy

liudongzhi há 1 mês atrás
pai
commit
66165d4503

+ 23 - 0
alien-entity/src/main/java/shop/alien/mapper/CommonCommentMapper.java

@@ -59,6 +59,29 @@ public interface CommonCommentMapper extends BaseMapper<CommonComment> {
     List<CommonCommentVo> getCommentCount(Integer type);
 
     /**
+     * 批量查询评论数量(按sourceId分组统计)
+     * 
+     * @param sourceType 来源类型
+     * @param sourceIds 来源ID列表
+     * @return sourceId -> commentCount 的映射列表
+     */
+    @Select("<script>" +
+            "SELECT cc.source_id AS sourceId, COUNT(*) AS commentCount " +
+            "FROM common_comment cc " +
+            "WHERE cc.source_type = #{sourceType} " +
+            "AND cc.delete_flag = 0 " +
+            "<if test='sourceIds != null and sourceIds.size() > 0'>" +
+            "AND cc.source_id IN " +
+            "<foreach collection='sourceIds' item='id' open='(' separator=',' close=')'>" +
+            "#{id}" +
+            "</foreach>" +
+            "</if>" +
+            "GROUP BY cc.source_id" +
+            "</script>")
+    List<CommonCommentVo> batchGetCommentCount(@Param("sourceType") Integer sourceType, 
+                                                @Param("sourceIds") List<Integer> sourceIds);
+
+    /**
      * 批量逻辑删除评论(使用原生 SQL 绕过 @TableLogic 注解限制)
      *
      * @param sourceType 来源类型

+ 110 - 84
alien-store/src/main/java/shop/alien/store/service/impl/StoreClockInServiceImpl.java

@@ -69,6 +69,8 @@ public class StoreClockInServiceImpl extends ServiceImpl<StoreClockInMapper, Sto
 
     private final CommonCommentService commonCommentService;
 
+    private final CommonCommentMapper commonCommentMapper;
+
     private final WebSocketProcess webSocketProcess;
 
     // 初始化线程池
@@ -132,15 +134,19 @@ public class StoreClockInServiceImpl extends ServiceImpl<StoreClockInMapper, Sto
     @Override
     public IPage<StoreClockInVo> getStoreClockInList(Integer userId, int page, int size, String phoneId, int mySelf,Integer storeId) {
         IPage<StoreClockIn> iPage = new Page<>(page, size);
-        // 查询我的点赞
+        
+        // 优化:提前查询所有需要的数据,避免在循环中查询
+        // 查询我的点赞 - 使用Set提高查找效率
         LambdaQueryWrapper<LifeLikeRecord> likeWrapper = new LambdaQueryWrapper<>();
         likeWrapper.eq(LifeLikeRecord::getDianzanId, phoneId);
         likeWrapper.eq(LifeLikeRecord::getType, "5");
         List<LifeLikeRecord> lifeLikeList = lifeLikeRecordMapper.selectList(likeWrapper);
-        List<String> likeList = lifeLikeList.stream().map(LifeLikeRecord::getHuifuId).collect(Collectors.toList());
-
+        Set<String> likeSet = lifeLikeList.stream()
+                .map(LifeLikeRecord::getHuifuId)
+                .collect(Collectors.toSet());
 
-        if(StringUtils.isNotBlank(String.valueOf(storeId)) && !String.valueOf(storeId).equals("null")){
+        // 优化:使用Objects.nonNull判断storeId
+        if (Objects.nonNull(storeId)) {
             IPage<StoreClockInVo> storeClockInIPage1 = storeClockInMapper.getStoreClockInList(iPage, new QueryWrapper<StoreClockIn>()
                     .eq("clock.store_id", storeId)
                     .eq("clock.delete_flag", 0)
@@ -155,15 +161,24 @@ public class StoreClockInServiceImpl extends ServiceImpl<StoreClockInMapper, Sto
                                                     .eq("clock.user_id", userId)
                                     ))
                     .orderByDesc("created_time"));
-            storeClockInIPage1.getRecords().forEach(vo -> {
-                if (likeList.contains(String.valueOf(vo.getId()))) {
-                    vo.setIsLike("1");
-                } else {
-                    vo.setIsLike("0");
-                }
-            });
+            
+            List<StoreClockInVo> records = storeClockInIPage1.getRecords();
+            if (!records.isEmpty()) {
+                // 批量查询评论数量
+                List<Integer> clockInIds = records.stream()
+                        .map(StoreClockInVo::getId)
+                        .collect(Collectors.toList());
+                Map<Integer, Integer> commentCountMap = batchGetCommentCountMap(clockInIds);
+                
+                records.forEach(vo -> {
+                    vo.setIsLike(likeSet.contains(String.valueOf(vo.getId())) ? "1" : "0");
+                    vo.setCommentCount(commentCountMap.getOrDefault(vo.getId(), 0));
+                    setStoreTypeNew(vo);
+                });
+            }
             return storeClockInIPage1;
         }
+        
         QueryWrapper<StoreClockIn> wrapper = new QueryWrapper<>();
         wrapper.eq(1 == mySelf, "clock.user_id", userId);
         wrapper.isNotNull(0 == mySelf, "clock.img_url");
@@ -181,96 +196,107 @@ public class StoreClockInServiceImpl extends ServiceImpl<StoreClockInMapper, Sto
         wrapper.orderByDesc("clock.created_time");
 
         IPage<StoreClockInVo> storeClockInIPage = storeClockInMapper.getStoreClockInList(iPage, wrapper);
+        List<StoreClockInVo> records = storeClockInIPage.getRecords();
+        
+        if (records.isEmpty()) {
+            return storeClockInIPage;
+        }
 
-        // 查询我的关注
+        // 优化:批量查询所有需要的数据
+        // 查询我的关注 - 使用Set提高查找效率
         LambdaQueryWrapper<LifeFans> lifeFansWrapper = new LambdaQueryWrapper<>();
         lifeFansWrapper.eq(LifeFans::getFansId, phoneId);
         List<LifeFans> lifeFansList = lifeFansMapper.selectList(lifeFansWrapper);
-        List<String> followList = lifeFansList.stream().map(LifeFans::getFollowedId).collect(Collectors.toList());
+        Set<String> followSet = lifeFansList.stream()
+                .map(LifeFans::getFollowedId)
+                .collect(Collectors.toSet());
 
-        // 查询我的粉丝
+        // 查询我的粉丝 - 使用Set提高查找效率
         lifeFansWrapper = new LambdaQueryWrapper<>();
         lifeFansWrapper.eq(LifeFans::getFollowedId, phoneId);
         lifeFansList = lifeFansMapper.selectList(lifeFansWrapper);
-        List<String> fansList = lifeFansList.stream().map(LifeFans::getFansId).collect(Collectors.toList());
+        Set<String> fansSet = lifeFansList.stream()
+                .map(LifeFans::getFansId)
+                .collect(Collectors.toSet());
 
-
-
-        // 查询我的收藏
+        // 查询我的收藏 - 使用Set提高查找效率
         LambdaQueryWrapper<LifeCollect> collectWrapper = new LambdaQueryWrapper<>();
         collectWrapper.eq(LifeCollect::getUserId, String.valueOf(userId));
         List<LifeCollect> lifeCollectList = lifeCollectMapper.selectList(collectWrapper);
-        List<String> collectList = lifeCollectList.stream().map(LifeCollect::getStoreId).collect(Collectors.toList());
-
-
-        storeClockInIPage.getRecords().forEach(vo -> {
-            if (followList.contains(vo.getPhoneId())) {
-                vo.setIsFollowThis("1");
-            } else {
-                vo.setIsFollowThis("0");
-            }
-            if (fansList.contains(vo.getPhoneId())) {
-                vo.setIsFollowMe("1");
-            } else {
-                vo.setIsFollowMe("0");
-            }
-            if (likeList.contains(String.valueOf(vo.getId()))) {
-                vo.setIsLike("1");
-            } else {
-                vo.setIsLike("0");
-            }
-            if (collectList.contains(String.valueOf(vo.getStoreId()))) {
-                vo.setIsCollect("1");
-            } else {
-                vo.setIsCollect("0");
-            }
-
-//            // 该用户的打卡记录
-//            LambdaQueryWrapper<StoreClockIn> clockInWrapper = new LambdaQueryWrapper<>();
-//            clockInWrapper.eq(StoreClockIn::getUserId, vo.getUserId());
-//            List<StoreClockIn> clockInList = storeClockInMapper.selectList(clockInWrapper);
-//
-//            Set<Integer> clockInSet = clockInList.stream().map(StoreClockIn::getStoreId).collect(Collectors.toSet());
-//            // 该用户今天打卡记录
-//            Set<Integer> clockInTodaySet = clockInList.stream().filter(item -> item.getCreatedTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate().equals(LocalDate.now())).map(StoreClockIn::getStoreId).collect(Collectors.toSet());
-//
-//            // 在该店铺的打卡次数
-//            Map<Integer, Long> clockInStoreNumMap = clockInList.stream().collect(Collectors.groupingBy(StoreClockIn::getStoreId, Collectors.counting()));
-//
-//            // 该用户打卡的所有店铺次数(一个店铺只算一次)
-//            int clockInNum = (int) clockInList.stream().map(StoreClockIn::getStoreId).distinct().count();
-//
-//            // 是否在该店铺打过卡
-//            if (clockInSet.contains(vo.getStoreId())){
-//                vo.setClockInStore("1");
-//            } else {
-//                vo.setClockInStore("0");
-//            }
-//            // 今天是否在该店铺打过卡
-//            if (clockInTodaySet.contains(vo.getStoreId())){
-//                vo.setClockInStoreToday("1");
-//            } else {
-//                vo.setClockInStoreToday("0");
-//            }
-//            // 在该店铺打卡次数clockInStoreNum
-//            vo.setClockInStoreNum(clockInStoreNumMap.get(vo.getStoreId()));
-//            // 打卡次数
-//            vo.setClockInNum(clockInNum);
-            Map<String, Object> commitCount = commonCommentService.getCommitCount(vo.getId(), CommentSourceTypeEnum.CLOCK_IN_COMMENT.getType(), userId.toString(), null);
-            vo.setCommentCount(Integer.parseInt(commitCount.get("commentCount").toString()));
-            if(Arrays.asList("酒吧", "KTV", "洗浴汗蒸", "按摩足疗").contains(vo.getBusinessSectionName())){
-                vo.setStoreTypeNew(1);
-            } else if (Arrays.asList("丽人美发", "运动健身").contains(vo.getBusinessSectionName())){
-                vo.setStoreTypeNew(2);
-            } else if (Arrays.asList("特色美食").contains(vo.getBusinessSectionName())){
-                vo.setStoreTypeNew(3);
-            }
+        Set<String> collectSet = lifeCollectList.stream()
+                .map(LifeCollect::getStoreId)
+                .collect(Collectors.toSet());
+
+        // 优化:批量查询评论数量,避免N+1问题
+        List<Integer> clockInIds = records.stream()
+                .map(StoreClockInVo::getId)
+                .collect(Collectors.toList());
+        Map<Integer, Integer> commentCountMap = batchGetCommentCountMap(clockInIds);
+
+        // 优化:使用Set进行O(1)查找,而不是List的O(n)查找
+        records.forEach(vo -> {
+            vo.setIsFollowThis(followSet.contains(vo.getPhoneId()) ? "1" : "0");
+            vo.setIsFollowMe(fansSet.contains(vo.getPhoneId()) ? "1" : "0");
+            vo.setIsLike(likeSet.contains(String.valueOf(vo.getId())) ? "1" : "0");
+            vo.setIsCollect(collectSet.contains(String.valueOf(vo.getStoreId())) ? "1" : "0");
+            vo.setCommentCount(commentCountMap.getOrDefault(vo.getId(), 0));
+            setStoreTypeNew(vo);
         });
 
-
         return storeClockInIPage;
     }
 
+    /**
+     * 批量查询评论数量
+     * 
+     * @param clockInIds 打卡记录ID列表
+     * @return 打卡记录ID -> 评论数量的映射
+     */
+    private Map<Integer, Integer> batchGetCommentCountMap(List<Integer> clockInIds) {
+        if (clockInIds == null || clockInIds.isEmpty()) {
+            return Collections.emptyMap();
+        }
+        
+        try {
+            List<shop.alien.entity.store.vo.CommonCommentVo> commentCountList = 
+                    commonCommentMapper.batchGetCommentCount(
+                            CommentSourceTypeEnum.CLOCK_IN_COMMENT.getType(), 
+                            clockInIds
+                    );
+            
+            return commentCountList.stream()
+                    .filter(item -> item.getSourceId() != null && item.getCommentCount() != null)
+                    .collect(Collectors.toMap(
+                            item -> item.getSourceId().intValue(),
+                            item -> item.getCommentCount(),
+                            (existing, replacement) -> existing
+                    ));
+        } catch (Exception e) {
+            log.error("批量查询评论数量失败", e);
+            return Collections.emptyMap();
+        }
+    }
+
+    /**
+     * 设置店铺类型
+     * 
+     * @param vo 打卡记录VO
+     */
+    private void setStoreTypeNew(StoreClockInVo vo) {
+        String businessSectionName = vo.getBusinessSectionName();
+        if (businessSectionName == null) {
+            return;
+        }
+        
+        if (Arrays.asList("酒吧", "KTV", "洗浴汗蒸", "按摩足疗").contains(businessSectionName)) {
+            vo.setStoreTypeNew(1);
+        } else if (Arrays.asList("丽人美发", "运动健身").contains(businessSectionName)) {
+            vo.setStoreTypeNew(2);
+        } else if (Arrays.asList("特色美食").contains(businessSectionName)) {
+            vo.setStoreTypeNew(3);
+        }
+    }
+
     @Override
     public int deleteClockIn(Integer id) {
         return storeClockInMapper.deleteById(id);