RankService.java 8.9 KB
Newer Older
刘基明's avatar
刘基明 committed
1 2
package com.tanpu.community.service;

张辰's avatar
张辰 committed
3
import com.tanpu.biz.common.enums.clue.PageEnum;
张辰's avatar
张辰 committed
4 5
import com.tanpu.biz.common.enums.community.CollectionTypeEnum;
import com.tanpu.biz.common.enums.community.TopicStatusEnum;
刘基明's avatar
刘基明 committed
6
import com.tanpu.community.api.beans.qo.ThemeAnalysDO;
刘基明's avatar
刘基明 committed
7
import com.tanpu.community.api.beans.qo.TopicRankQo;
8
import com.tanpu.community.api.beans.vo.feign.fatools.UserInfoResp;
9
import com.tanpu.community.cache.RedisCache;
刘基明's avatar
刘基明 committed
10 11
import com.tanpu.community.dao.entity.community.ThemeEntity;
import com.tanpu.community.dao.entity.community.TopicEntity;
刘基明's avatar
刘基明 committed
12
import com.tanpu.community.util.BizUtils;
刘基明's avatar
刘基明 committed
13
import com.tanpu.community.util.ConvertUtil;
刘基明's avatar
刘基明 committed
14
import com.tanpu.community.util.TimeUtils;
刘基明's avatar
刘基明 committed
15
import org.apache.commons.collections4.CollectionUtils;
16
import org.apache.commons.lang3.StringUtils;
刘基明's avatar
刘基明 committed
17 18 19
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

20
import javax.annotation.Resource;
刘基明's avatar
刘基明 committed
21 22 23 24 25
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
刘基明's avatar
刘基明 committed
26 27
import java.util.stream.Collectors;

刘基明's avatar
刘基明 committed
28
import static com.tanpu.community.api.constants.RedisKeyConstant.CACHE_FEIGN_USER_INFO;
29

刘基明's avatar
刘基明 committed
30 31 32 33 34 35 36 37 38 39 40
@Service
public class RankService {
    @Autowired
    private ThemeService themeService;
    @Autowired
    private CollectionService collectionService;
    @Autowired
    private CommentService commentService;
    @Autowired
    private TopicService topicService;
    @Autowired
刘基明's avatar
刘基明 committed
41
    private VisitLogService visitLogService;
刘基明's avatar
刘基明 committed
42

张辰's avatar
张辰 committed
43 44 45
    @Autowired
    private FeignService feignService;

46 47 48 49
    @Autowired
    private RedisCache redisCache;

    @Resource
刘基明's avatar
刘基明 committed
50
    private RankLogService rankLogService;
51

52
    //最热
张辰's avatar
张辰 committed
53
    private List<ThemeAnalysDO> hotestThemes = new ArrayList<>();
刘基明's avatar
刘基明 committed
54

刘基明's avatar
刘基明 committed
55 56
    private List<TopicRankQo> rankTopicList = new ArrayList<>();
    private List<TopicRankQo> rankTopicListTop4 = new ArrayList<>();
刘基明's avatar
刘基明 committed
57 58


刘基明's avatar
刘基明 committed
59 60 61
    /**
     * 计算主题热度排行
     */
刘基明's avatar
刘基明 committed
62
    public void rankThemes() {
刘基明's avatar
刘基明 committed
63 64

        LocalDateTime start = LocalDateTime.now();
65
        //7天内所有主题进行热度值排序
刘基明's avatar
刘基明 committed
66
        List<ThemeEntity> themeEntities = themeService.queryRecentdays(7);
刘基明's avatar
刘基明 committed
67
        if (CollectionUtils.isEmpty(themeEntities)) {
刘基明's avatar
刘基明 committed
68 69
            return;
        }
刘基明's avatar
刘基明 committed
70
        List<ThemeAnalysDO> themeAnalysDOS = ConvertUtil.themeEntityToAnalysDOs(themeEntities);
刘基明's avatar
刘基明 committed
71 72 73 74 75 76
        //批量查询
        List<String> themeIds = themeAnalysDOS.stream().map(ThemeAnalysDO::getThemeId).collect(Collectors.toList());
        Map<String, Integer> likeCountMap = collectionService.getCountMapByType(themeIds, CollectionTypeEnum.LIKE_THEME);
        Map<String, Integer> bookCountMap = collectionService.getCountMapByType(themeIds, CollectionTypeEnum.COLLECT_THEME);
        Map<String, Integer> commentCountMap = commentService.getCountMapByThemeIds(themeIds);
        Map<String, Integer> forwardCountMap = themeService.getForwardCountMap(themeIds);
张辰's avatar
张辰 committed
77
        Map<String, Integer> visitCountMap = visitLogService.getCountMapByTargetIds(themeIds, PageEnum.COMM_VISIT_THEME.getId());
刘基明's avatar
刘基明 committed
78

刘基明's avatar
刘基明 committed
79 80
        for (ThemeAnalysDO theme : themeAnalysDOS) {
            String themeId = theme.getThemeId();
刘基明's avatar
刘基明 committed
81
            theme.setCommentCount(commentCountMap.getOrDefault(themeId, 0));
刘基明's avatar
刘基明 committed
82
            theme.setLikeCount(likeCountMap.getOrDefault(themeId, 0));
刘基明's avatar
刘基明 committed
83 84 85
            theme.setForwardCount(forwardCountMap.getOrDefault(themeId, 0));
            theme.setCollectCount(bookCountMap.getOrDefault(themeId, 0));
            theme.setViewCount(visitCountMap.getOrDefault(themeId, 0));
86 87
            //查询用户质量
            String authorId = theme.getAuthorId();
88 89
            UserInfoResp authorInfo = redisCache.getObject(StringUtils.joinWith("_", CACHE_FEIGN_USER_INFO, authorId),
                    60, () -> feignService.getUserInfoById(authorId), UserInfoResp.class);
90 91 92
            if (authorInfo == null || authorInfo.getLevelGrade() == null) {
                theme.setUserWeight(0.0);
            } else {
张辰's avatar
张辰 committed
93
                // 设置用户权重
94 95 96
                theme.setUserWeight(authorInfo.getLevelGrade() * 1.0);

            }
刘基明's avatar
刘基明 committed
97
        }
刘基明's avatar
刘基明 committed
98
        //打分
刘基明's avatar
刘基明 committed
99
        Map<ThemeAnalysDO, Double> map = themeAnalysDOS.stream().collect(Collectors.toMap(o -> o, ThemeAnalysDO::getRank));
刘基明's avatar
刘基明 committed
100
        //排序
张辰's avatar
张辰 committed
101 102 103
        hotestThemes = map.entrySet().stream()
                .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
                .map(e -> e.getKey()).collect(Collectors.toList());
刘基明's avatar
刘基明 committed
104
        //落库
刘基明's avatar
刘基明 committed
105
        rankLogService.logThemeRank(hotestThemes, start, TimeUtils.calMillisTillNow(start));
106 107
    }

108

刘基明's avatar
刘基明 committed
109 110 111 112 113 114
    /**
     * 计算话题热度
     *
     * @return
     */
    public void rankTopics() {
刘基明's avatar
刘基明 committed
115
        LocalDateTime start = LocalDateTime.now();
刘基明's avatar
刘基明 committed
116
        List<TopicEntity> topicEntities = topicService.queryAll();
刘基明's avatar
刘基明 committed
117
        if (CollectionUtils.isEmpty(topicEntities)) {
刘基明's avatar
刘基明 committed
118
            return;
刘基明's avatar
刘基明 committed
119
        }
刘基明's avatar
刘基明 committed
120
        List<TopicRankQo> topicRankQos = ConvertUtil.topicEntityToHotQos(topicEntities);
刘基明's avatar
刘基明 committed
121
        List<String> topicIds = topicRankQos.stream().map(TopicRankQo::getTopicId).collect(Collectors.toList());
122
        Map<String, Integer> topicViewMap = visitLogService.getCountMapByTargetIds(topicIds, PageEnum.COMM_VISIT_TOPIC_DETAIL.getId());
刘基明's avatar
刘基明 committed
123
        for (TopicRankQo topic : topicRankQos) {
刘基明's avatar
刘基明 committed
124
            List<String> themeIds = themeService.queryThemeIdsByTopic(topic.getTopicId());
125
            if (CollectionUtils.isEmpty(themeIds)) {
刘基明's avatar
刘基明 committed
126
                topic.setViewCount(topicViewMap.getOrDefault(topic.getTopicId(), 0));
刘基明's avatar
刘基明 committed
127
                topic.setDisscussCount(0);
刘基明's avatar
刘基明 committed
128
                topic.setThemeWeight(0.0);
刘基明's avatar
刘基明 committed
129 130
                topic.setFormatViewCount(BizUtils.formatCountNumber(topic.getViewCount()));
                topic.setFormatDisscussCount(BizUtils.formatCountNumber(topic.getDisscussCount()));
刘基明's avatar
刘基明 committed
131 132
                continue;
            }
张辰's avatar
张辰 committed
133
            // 浏览量
刘基明's avatar
刘基明 committed
134
            Integer topicPV = topicViewMap.getOrDefault(topic.getTopicId(), 0);
刘基明's avatar
刘基明 committed
135
            Integer themePV = visitLogService.queryThemeVisit(themeIds);
刘基明's avatar
刘基明 committed
136
            topic.setViewCount(topicPV + themePV + topic.getViewCntAdjust());
刘基明's avatar
刘基明 committed
137
            //讨论数=发布主题贴数+回复总数
刘基明's avatar
刘基明 committed
138
            Integer commentCount = commentService.getTotalCountByThemeIds(themeIds);
刘基明's avatar
刘基明 committed
139
            topic.setDisscussCount(themeIds.size() + commentCount);
刘基明's avatar
刘基明 committed
140 141
            //帖子权重,求和
            double themeSum = getHotestThemes().stream().filter(o -> topic.getTopicId().equals(o.getTopicId()))
刘基明's avatar
刘基明 committed
142
                    .mapToDouble(ThemeAnalysDO::getRank)
刘基明's avatar
刘基明 committed
143
                    .sum();
刘基明's avatar
刘基明 committed
144
            topic.setThemeWeight(themeSum);
刘基明's avatar
刘基明 committed
145 146 147
            //格式化浏览量、讨论量
            topic.setFormatViewCount(BizUtils.formatCountNumber(topic.getViewCount()));
            topic.setFormatDisscussCount(BizUtils.formatCountNumber(topic.getDisscussCount()));
刘基明's avatar
刘基明 committed
148
        }
刘基明's avatar
刘基明 committed
149
        Map<TopicRankQo, Double> map = topicRankQos.stream().collect(Collectors.toMap(o -> o, TopicRankQo::getRank));
张辰's avatar
张辰 committed
150 151 152 153
        List<TopicRankQo> rankList = map.entrySet().stream()
                .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
                .map(Map.Entry::getKey)
                .collect(Collectors.toList());
刘基明's avatar
刘基明 committed
154
        rankList.get(0).setType(TopicStatusEnum.HOTTEST.getCode());
刘基明's avatar
刘基明 committed
155 156
        this.rankTopicList = rankList;
        this.rankTopicListTop4 = rankList.stream().limit(4).collect(Collectors.toList());
刘基明's avatar
刘基明 committed
157 158

        //落库
刘基明's avatar
刘基明 committed
159
        rankLogService.logTopicRank(rankList, start, TimeUtils.calMillisTillNow(start));
刘基明's avatar
刘基明 committed
160
        return;
刘基明's avatar
刘基明 committed
161 162 163

    }

刘基明's avatar
刘基明 committed
164
    /**
刘基明's avatar
刘基明 committed
165
     * 从排序列表中返回话题详情
166
     *
刘基明's avatar
刘基明 committed
167 168 169
     * @param topicId 话题Id
     * @return
     */
170 171
    public TopicRankQo getTopicDetail(String topicId) {
        if (this.rankTopicList.size() == 0) {
刘基明's avatar
刘基明 committed
172 173
            rankTopics();
        }
刘基明's avatar
刘基明 committed
174
        List<TopicRankQo> matchTopic = this.rankTopicList.stream().filter(o -> topicId.equals(o.getTopicId())).limit(1).collect(Collectors.toList());
刘基明's avatar
刘基明 committed
175 176 177 178 179
        matchTopic.add(new TopicRankQo());
        return matchTopic.get(0);
    }


刘基明's avatar
刘基明 committed
180
    public List<TopicRankQo> getRankTopicList(String keyword) {
181
        if (this.rankTopicList.size() == 0) {
刘基明's avatar
刘基明 committed
182 183
            this.rankTopics();
        }
刘基明's avatar
刘基明 committed
184
        if (StringUtils.isEmpty(keyword)) {
刘基明's avatar
刘基明 committed
185
            return rankTopicList;
刘基明's avatar
刘基明 committed
186
        } else {
刘基明's avatar
刘基明 committed
187
            //过滤关键字
刘基明's avatar
刘基明 committed
188
            return this.rankTopicList.stream().filter(o -> o.getTopicTitle().contains(keyword)).collect(Collectors.toList());
刘基明's avatar
刘基明 committed
189
        }
刘基明's avatar
刘基明 committed
190 191 192
    }

    public List<TopicRankQo> getRankTopicListTop4() {
193
        if (this.rankTopicList.size() == 0) {
刘基明's avatar
刘基明 committed
194 195
            this.rankTopics();
        }
刘基明's avatar
刘基明 committed
196 197
        return rankTopicListTop4;
    }
刘基明's avatar
刘基明 committed
198

张辰's avatar
张辰 committed
199 200
    public List<ThemeAnalysDO> getHotestThemes() {
        if (this.hotestThemes.size() == 0) {
201 202
            rankThemes();
        }
张辰's avatar
张辰 committed
203
        return hotestThemes;
204 205
    }

张辰's avatar
张辰 committed
206
    public List<String> getRankThemeListByTopic(String topicId, List<String> excludeIds) {
张辰's avatar
张辰 committed
207
        if (this.hotestThemes.size() == 0) {
刘基明's avatar
刘基明 committed
208 209
            this.rankThemes();
        }
张辰's avatar
张辰 committed
210 211 212

        return hotestThemes.stream()
                .filter(o -> topicId.equals(o.getTopicId()) && !excludeIds.contains(o.getThemeId()))
刘基明's avatar
刘基明 committed
213 214
                .map(ThemeAnalysDO::getThemeId)
                .collect(Collectors.toList());
刘基明's avatar
刘基明 committed
215
    }
刘基明's avatar
刘基明 committed
216

刘基明's avatar
刘基明 committed
217
}