|
|
@@ -7,6 +7,7 @@ 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.RequiredArgsConstructor;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.beans.BeanUtils;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.util.CollectionUtils;
|
|
|
@@ -15,15 +16,18 @@ import org.springframework.util.StringUtils;
|
|
|
import shop.alien.entity.store.*;
|
|
|
import shop.alien.entity.store.vo.*;
|
|
|
import shop.alien.mapper.*;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
import shop.alien.util.common.constant.CommentSourceTypeEnum;
|
|
|
|
|
|
import java.util.*;
|
|
|
+import java.util.concurrent.CompletableFuture;
|
|
|
import java.util.stream.Collectors;
|
|
|
import java.util.stream.Stream;
|
|
|
|
|
|
/**
|
|
|
* 用户动态
|
|
|
*/
|
|
|
+@Slf4j
|
|
|
@Service
|
|
|
@RequiredArgsConstructor
|
|
|
public class LifeUserDynamicsService extends ServiceImpl<LifeUserDynamicsMapper, LifeUserDynamics> {
|
|
|
@@ -55,6 +59,8 @@ public class LifeUserDynamicsService extends ServiceImpl<LifeUserDynamicsMapper,
|
|
|
private final CommonCommentMapper commonCommentMapper;
|
|
|
|
|
|
private final CommonRatingService commonRatingService;
|
|
|
+
|
|
|
+ private final CommonRatingMapper commonRatingMapper;
|
|
|
|
|
|
public int addLiulanCount(String id) {
|
|
|
LambdaUpdateWrapper<LifeUserDynamics> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
|
|
|
@@ -159,60 +165,63 @@ public class LifeUserDynamicsService extends ServiceImpl<LifeUserDynamicsMapper,
|
|
|
// 查询动态数据并按类型过滤
|
|
|
List<LifeUserDynamicsVo> lifeUserDynamicsVoList = lifeUserDynamicsMapper.getLifeUserDynamicsList();
|
|
|
|
|
|
- // 店铺id
|
|
|
- // TODO 可以优化小驴:优化方案直接sql分组查询评价数量,避免循环查询
|
|
|
+ // 店铺id - 优化:批量查询评价数量,避免N+1查询
|
|
|
List<String> storeUserIdList = new ArrayList<>();
|
|
|
- Map<String, Integer> commitCountMap = new HashMap<>();
|
|
|
//对lifeUserDynamicsVoList数据进行处理,当type为2的时候,把userName的数值赋值到storeName
|
|
|
lifeUserDynamicsVoList.forEach(item -> {
|
|
|
if (item.getType().equals("2")) {
|
|
|
item.setStoreName(item.getUserName());
|
|
|
- storeUserIdList.add(item.getStoreUserId());
|
|
|
+ if (item.getStoreUserId() != null) {
|
|
|
+ storeUserIdList.add(item.getStoreUserId());
|
|
|
+ }
|
|
|
}
|
|
|
});
|
|
|
|
|
|
- for (String storeId : storeUserIdList) {
|
|
|
- Integer totalCount = 0;
|
|
|
- double storeScore;
|
|
|
- Object ratingObj = commonRatingService.getRatingCount(Integer.parseInt(storeId), 1);
|
|
|
- if (ratingObj != null) {
|
|
|
- Map<String, Object> ratingMap = (Map<String, Object>) ratingObj;
|
|
|
- Object totalCountObj = ratingMap.get("totalCount");
|
|
|
- if (totalCountObj != null) {
|
|
|
- // 安全转换为整数
|
|
|
- try {
|
|
|
- totalCount = Integer.parseInt(totalCountObj.toString().trim());
|
|
|
- } catch (NumberFormatException e) {
|
|
|
- totalCount = 0; // 转换失败时默认值
|
|
|
- }
|
|
|
- } else {
|
|
|
- totalCount = 0;
|
|
|
- }
|
|
|
- }
|
|
|
- commitCountMap.put(storeId, totalCount);
|
|
|
- }
|
|
|
+ // 批量查询评价数量(优化:从N+1查询改为批量查询)
|
|
|
+ Map<String, Integer> commitCountMap = batchGetRatingCount(storeUserIdList);
|
|
|
if (!StringUtils.isEmpty(type)) {
|
|
|
lifeUserDynamicsVoList = lifeUserDynamicsVoList.stream().filter(item -> type.equals(item.getType())).collect(Collectors.toList());
|
|
|
}
|
|
|
|
|
|
- // 查询我的关注信息,构建关注者ID列表
|
|
|
- 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());
|
|
|
+ // 并发查询关注、粉丝、点赞信息(优化:并行执行多个独立查询)
|
|
|
+ CompletableFuture<List<String>> followListFuture = CompletableFuture.supplyAsync(() -> {
|
|
|
+ if (StringUtils.isEmpty(phoneId)) {
|
|
|
+ return Collections.emptyList();
|
|
|
+ }
|
|
|
+ LambdaQueryWrapper<LifeFans> wrapper = new LambdaQueryWrapper<>();
|
|
|
+ wrapper.eq(LifeFans::getFansId, phoneId);
|
|
|
+ return lifeFansMapper.selectList(wrapper).stream()
|
|
|
+ .map(LifeFans::getFollowedId)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ });
|
|
|
|
|
|
- // 查询我的粉丝信息,构建粉丝ID列表
|
|
|
- lifeFansWrapper = new LambdaQueryWrapper<>();
|
|
|
- lifeFansWrapper.eq(LifeFans::getFollowedId, phoneId);
|
|
|
- lifeFansList = lifeFansMapper.selectList(lifeFansWrapper);
|
|
|
- List<String> fansList = lifeFansList.stream().map(LifeFans::getFansId).collect(Collectors.toList());
|
|
|
+ CompletableFuture<List<String>> fansListFuture = CompletableFuture.supplyAsync(() -> {
|
|
|
+ if (StringUtils.isEmpty(phoneId)) {
|
|
|
+ return Collections.emptyList();
|
|
|
+ }
|
|
|
+ LambdaQueryWrapper<LifeFans> wrapper = new LambdaQueryWrapper<>();
|
|
|
+ wrapper.eq(LifeFans::getFollowedId, phoneId);
|
|
|
+ return lifeFansMapper.selectList(wrapper).stream()
|
|
|
+ .map(LifeFans::getFansId)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ });
|
|
|
|
|
|
- // 查询我的点赞记录,构建点赞ID列表
|
|
|
- LambdaQueryWrapper<LifeLikeRecord> likeWrapper = new LambdaQueryWrapper<>();
|
|
|
- likeWrapper.eq(LifeLikeRecord::getDianzanId, phoneId);
|
|
|
- likeWrapper.eq(LifeLikeRecord::getType, "2");
|
|
|
- List<LifeLikeRecord> lifeLikeList = lifeLikeRecordMapper.selectList(likeWrapper);
|
|
|
- List<String> likeList = lifeLikeList.stream().map(LifeLikeRecord::getHuifuId).collect(Collectors.toList());
|
|
|
+ CompletableFuture<List<String>> likeListFuture = CompletableFuture.supplyAsync(() -> {
|
|
|
+ if (StringUtils.isEmpty(phoneId)) {
|
|
|
+ return Collections.emptyList();
|
|
|
+ }
|
|
|
+ LambdaQueryWrapper<LifeLikeRecord> wrapper = new LambdaQueryWrapper<>();
|
|
|
+ wrapper.eq(LifeLikeRecord::getDianzanId, phoneId)
|
|
|
+ .eq(LifeLikeRecord::getType, "2");
|
|
|
+ return lifeLikeRecordMapper.selectList(wrapper).stream()
|
|
|
+ .map(LifeLikeRecord::getHuifuId)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ });
|
|
|
+
|
|
|
+ // 等待所有查询完成
|
|
|
+ List<String> followList = followListFuture.join();
|
|
|
+ List<String> fansList = fansListFuture.join();
|
|
|
+ List<String> likeList = likeListFuture.join();
|
|
|
|
|
|
// 根据myself参数过滤动态:自己或非本人动态
|
|
|
if ("1".equals(myself)) {
|
|
|
@@ -226,10 +235,15 @@ public class LifeUserDynamicsService extends ServiceImpl<LifeUserDynamicsMapper,
|
|
|
lifeUserDynamicsVoList = lifeUserDynamicsVoList.stream().filter(item -> followList.contains(item.getPhoneId())).collect(Collectors.toList());
|
|
|
}
|
|
|
|
|
|
-// List<StoreCommentVo> rootCommitCount = storeCommentMapper.getRootCommitCount(2, null);
|
|
|
-// List<StoreCommentVo> sonCommitCount = storeCommentMapper.getSonCommitCount(2, null);
|
|
|
-
|
|
|
- List<CommonCommentVo> commonCommentVo= commonCommentMapper.getCommentCount(CommentSourceTypeEnum.DYNAMIC_COMMENT.getType());
|
|
|
+ // 批量查询评论数量(优化:一次性查询所有动态的评论数)
|
|
|
+ List<CommonCommentVo> commonCommentVo = commonCommentMapper.getCommentCount(CommentSourceTypeEnum.DYNAMIC_COMMENT.getType());
|
|
|
+ // 转换为Map,提升查找性能
|
|
|
+ Map<Long, Integer> commentCountMap = commonCommentVo.stream()
|
|
|
+ .collect(Collectors.toMap(
|
|
|
+ vo -> Long.parseLong(vo.getSourceId().toString()),
|
|
|
+ CommonCommentVo::getCommentCount,
|
|
|
+ (v1, v2) -> v1 + v2 // 如果有重复key,累加
|
|
|
+ ));
|
|
|
|
|
|
// 设置动态对象的状态信息:是否关注对方、是否被关注、是否点赞及评论数量
|
|
|
// 设置.imagePath。视频为mp4+jpg格式,图片为jpg/png格式。
|
|
|
@@ -255,23 +269,9 @@ public class LifeUserDynamicsService extends ServiceImpl<LifeUserDynamicsMapper,
|
|
|
} else {
|
|
|
vo.setIsLike("0");
|
|
|
}
|
|
|
- List<CommonCommentVo> collect = commonCommentVo.stream().filter(x -> x.getSourceId().equals(Long.parseLong(vo.getId().toString()))).collect(Collectors.toList());
|
|
|
-// List<StoreCommentVo> rootList = rootCommitCount.stream().filter(item -> Objects.equals(item.getBusinessId(), vo.getId())).collect(Collectors.toList());
|
|
|
- if (collect.isEmpty()) {
|
|
|
- vo.setCommentCount(0);
|
|
|
- } else {
|
|
|
- Integer count = 0;
|
|
|
- for (CommonCommentVo commentVo : collect) {
|
|
|
- count += commentVo.getCommentCount();
|
|
|
- }
|
|
|
-// for (CommonCommentVo storeCommentVo : collect) {
|
|
|
-// List<StoreCommentVo> sonList = sonCommitCount.stream().filter(item -> Objects.equals(item.getReplyId(), storeCommentVo.getId())).collect(Collectors.toList());
|
|
|
-// if (!sonList.isEmpty()) {
|
|
|
-// count += sonList.get(0).getCommitCount();
|
|
|
-// }
|
|
|
-// }
|
|
|
- vo.setCommentCount(count);
|
|
|
- }
|
|
|
+ // 优化:直接从Map中获取评论数量,避免stream过滤
|
|
|
+ Integer commentCount = commentCountMap.getOrDefault(Long.parseLong(vo.getId().toString()), 0);
|
|
|
+ vo.setCommentCount(commentCount);
|
|
|
}
|
|
|
|
|
|
// 如果phoneId不为空,处理黑名单逻辑,过滤掉被拉黑用户的动态
|
|
|
@@ -326,6 +326,71 @@ public class LifeUserDynamicsService extends ServiceImpl<LifeUserDynamicsMapper,
|
|
|
return lifeUserDynamicsVoList;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 批量查询评价数量(优化:从N+1查询改为批量查询)
|
|
|
+ *
|
|
|
+ * @param storeUserIdList 店铺ID列表
|
|
|
+ * @return 店铺ID -> 评价数量的映射
|
|
|
+ */
|
|
|
+ private Map<String, Integer> batchGetRatingCount(List<String> storeUserIdList) {
|
|
|
+ Map<String, Integer> commitCountMap = new HashMap<>();
|
|
|
+ if (storeUserIdList == null || storeUserIdList.isEmpty()) {
|
|
|
+ return commitCountMap;
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 转换为Integer列表
|
|
|
+ List<Integer> storeIdList = storeUserIdList.stream()
|
|
|
+ .filter(id -> id != null && !id.isEmpty())
|
|
|
+ .map(id -> {
|
|
|
+ try {
|
|
|
+ return Integer.parseInt(id);
|
|
|
+ } catch (NumberFormatException e) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .filter(Objects::nonNull)
|
|
|
+ .distinct()
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ if (storeIdList.isEmpty()) {
|
|
|
+ return commitCountMap;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 批量查询评价记录(只查询审核通过且展示的)
|
|
|
+ LambdaQueryWrapper<CommonRating> wrapper = new LambdaQueryWrapper<>();
|
|
|
+ wrapper.in(CommonRating::getBusinessId, storeIdList)
|
|
|
+ .eq(CommonRating::getBusinessType, 1)
|
|
|
+ .eq(CommonRating::getAuditStatus, 1)
|
|
|
+ .eq(CommonRating::getIsShow, 1);
|
|
|
+ List<CommonRating> allRatings = commonRatingMapper.selectList(wrapper);
|
|
|
+
|
|
|
+ // 按businessId分组统计评论总数
|
|
|
+ Map<Integer, Long> ratingCountMap = allRatings.stream()
|
|
|
+ .collect(Collectors.groupingBy(
|
|
|
+ CommonRating::getBusinessId,
|
|
|
+ Collectors.counting()
|
|
|
+ ));
|
|
|
+
|
|
|
+ // 转换为String -> Integer映射
|
|
|
+ for (String storeIdStr : storeUserIdList) {
|
|
|
+ try {
|
|
|
+ Integer storeId = Integer.parseInt(storeIdStr);
|
|
|
+ Long count = ratingCountMap.get(storeId);
|
|
|
+ commitCountMap.put(storeIdStr, count != null ? count.intValue() : 0);
|
|
|
+ } catch (NumberFormatException e) {
|
|
|
+ commitCountMap.put(storeIdStr, 0);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("批量获取评价数量失败", e);
|
|
|
+ // 如果批量查询失败,设置默认值
|
|
|
+ storeUserIdList.forEach(storeId -> commitCountMap.put(storeId, 0));
|
|
|
+ }
|
|
|
+
|
|
|
+ return commitCountMap;
|
|
|
+ }
|
|
|
+
|
|
|
public List<LifeUserDynamicsVo> getStoreUserDynamics(String storePhone, String userType, String loginPhone) {
|
|
|
LambdaQueryWrapper<LifeUserDynamics> lambdaQueryWrapper = new LambdaQueryWrapper<>();
|
|
|
lambdaQueryWrapper.eq(LifeUserDynamics :: getPhoneId, storePhone);
|