package com.tanpu.community.service; import com.tanpu.common.api.CommonResp; import com.tanpu.common.exception.BizException; import com.tanpu.community.api.beans.qo.ThemeAnalysDO; import com.tanpu.community.api.beans.qo.TopicRankQo; import com.tanpu.community.api.beans.vo.feign.fatools.UserInfoNew; import com.tanpu.community.api.enums.CollectionTypeEnum; import com.tanpu.community.api.enums.TopicStatusEnum; import com.tanpu.community.cache.RedisCache; import com.tanpu.community.dao.entity.community.ThemeEntity; import com.tanpu.community.dao.entity.community.TopicEntity; import com.tanpu.community.feign.fatools.FeignClientForFatools; import com.tanpu.community.util.ConvertUtil; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.*; import java.util.stream.Collectors; import static com.tanpu.community.api.constants.RedisKeyConstant.CACHE_FEIGN_USER_INFO; @Service public class RankService { @Autowired private ThemeService themeService; @Autowired private CollectionService collectionService; @Autowired private CommentService commentService; @Autowired private TopicService topicService; @Autowired private VisitSummaryService visitSummaryService; @Autowired private RedisCache redisCache; @Resource private FeignClientForFatools feignClientForFatools; //最热 private List<ThemeAnalysDO> rankThemeList = new ArrayList<>(); private List<TopicRankQo> rankTopicList = new ArrayList<>(); private List<TopicRankQo> rankTopicListTop4 = new ArrayList<>(); /** * 计算主题热度排行 */ public void rankThemes() { //7天内所有主题进行热度值排序 List<ThemeEntity> themeEntities = themeService.queryRecentdays(7); List<ThemeAnalysDO> themeAnalysDOS = ConvertUtil.themeEntityToAnalysDOs(themeEntities); for (ThemeAnalysDO theme : themeAnalysDOS) { String themeId = theme.getThemeId(); Integer likeCount = collectionService.getCountByTypeAndId(themeId, CollectionTypeEnum.LIKE_THEME); Integer bookCount = collectionService.getCountByTypeAndId(themeId, CollectionTypeEnum.COLLECT_THEME); Integer commentCount = commentService.getCommentCountByThemeId(themeId); Integer forwardCount = themeService.getForwardCountById(themeId); Integer viewCount = visitSummaryService.queryThemeVisit(themeId); theme.setCommentCount(commentCount); theme.setLikeCount(likeCount); theme.setForwardCount(forwardCount); theme.setCollectCount(bookCount); theme.setViewCount(viewCount); //查询用户质量 String authorId = theme.getAuthorId(); UserInfoNew authorInfo = redisCache.getObject(StringUtils.joinWith(CACHE_FEIGN_USER_INFO, authorId), 60 * 10, () -> this.getUserInfo(authorId), UserInfoNew.class); if (authorInfo == null || authorInfo.getLevelGrade() == null) { theme.setUserWeight(0.0); } else { theme.setUserWeight(authorInfo.getLevelGrade() * 1.0); } } //打分 Map<ThemeAnalysDO, Double> map = themeAnalysDOS.stream().collect(Collectors.toMap(o -> o, ThemeAnalysDO::getScore)); //排序 rankThemeList = map.entrySet().stream().sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())).map(e -> e.getKey()).collect(Collectors.toList()); } private UserInfoNew getUserInfo(String authorId) { CommonResp<UserInfoNew> userInfoNewCommonResp = feignClientForFatools.queryUsersListNew(authorId); if (userInfoNewCommonResp.isNotSuccess()) { throw new BizException("内部接口调用失败"); } return userInfoNewCommonResp.getData(); } /** * 计算话题热度 * * @return */ public void rankTopics() { List<TopicEntity> topicEntities = topicService.queryAll(); List<TopicRankQo> topicRankQos = ConvertUtil.topicEntityToHotQos(topicEntities); if (topicRankQos.size() == 0) { return; } for (TopicRankQo topic : topicRankQos) { List<String> themeIds = themeService.queryThemeIdsByTopic(topic.getTopicId()); if (CollectionUtils.isEmpty(themeIds)) { topic.setViewCount(0); topic.setDisscussCount(0); continue; } //浏览量 Integer topicPV = visitSummaryService.queryTopicDetailVisit(topic.getTopicId()); Integer themePV = visitSummaryService.queryThemeVisit(themeIds); topic.setViewCount(topicPV + themePV); //讨论数=发布主题贴数+回复总数 Integer commentCount = commentService.getCommentCountByThemeIds(themeIds); topic.setDisscussCount(themeIds.size() + commentCount); } Map<TopicRankQo, Integer> map = topicRankQos.stream().collect(Collectors.toMap(o -> o, TopicRankQo::getRank)); List<TopicRankQo> rankList = map.entrySet().stream().sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())).map(Map.Entry::getKey).collect(Collectors.toList()); rankList.get(0).setType(TopicStatusEnum.HOTTEST.getCode()); this.rankTopicList = rankList; this.rankTopicListTop4 = rankList.stream().limit(4).collect(Collectors.toList()); return; } /** * 最新和热门主题集合 * * @param hotCount * @param newCount * @return */ public List<String> getHotAndNewThemes(Integer hotCount, Integer newCount, String userId) { Set<String> hotThemeIds = this.rankThemeList.stream().limit(hotCount) .filter(o -> !userId.equals(o.getAuthorId())) .map(ThemeAnalysDO::getThemeId) .collect(Collectors.toSet()); Set<String> newThemeIds = themeService.selectExcludeUser(null, null, newCount) .stream().map(ThemeEntity::getThemeId).collect(Collectors.toSet()); hotThemeIds.addAll(newThemeIds); return new ArrayList<>(hotThemeIds); } /** * 话题详情 * * @param topicId 话题Id * @return */ public TopicRankQo getTopicDetail(String topicId) { if (this.rankTopicList.size() == 0) { rankTopics(); } List<TopicRankQo> matchTopic = this.rankTopicList.stream().filter(o -> topicId.equals(o.getTopicId())).limit(1).collect(Collectors.toList()); matchTopic.add(new TopicRankQo()); return matchTopic.get(0); } public List<TopicRankQo> getRankTopicList(String keyword) { if (this.rankTopicList.size() == 0) { this.rankTopics(); } if (StringUtils.isEmpty(keyword)){ return rankTopicList; }else { //过滤关键字 return this.rankTopicList.stream().filter(o->o.getTopicTitle().contains(keyword)).collect(Collectors.toList()); } } public List<TopicRankQo> getRankTopicListTop4() { if (this.rankTopicList.size() == 0) { this.rankTopics(); } return rankTopicListTop4; } public List<ThemeAnalysDO> getRankThemeList() { if (this.rankThemeList.size() == 0) { rankThemes(); } return rankThemeList; } public List<String> getRankThemeListByTopic(String topicId) { if (this.rankThemeList.size() == 0) { this.rankThemes(); } return rankThemeList.stream().filter(o -> topicId.equals(o.getTopicId())) .map(ThemeAnalysDO::getThemeId) .collect(Collectors.toList()); } }