ThemeManager.java 22.2 KB
Newer Older
刘基明's avatar
刘基明 committed
1 2
package com.tanpu.community.manager;

刘基明's avatar
刘基明 committed
3 4
import com.google.common.collect.Sets;
import com.tanpu.common.api.CommonResp;
刘基明's avatar
刘基明 committed
5
import com.tanpu.common.exception.BizException;
刘基明's avatar
刘基明 committed
6
import com.tanpu.common.util.JsonUtil;
7 8 9 10
import com.tanpu.community.api.beans.qo.ESThemeQo;
import com.tanpu.community.api.beans.qo.FormerThemeQo;
import com.tanpu.community.api.beans.qo.ThemeContentQo;
import com.tanpu.community.api.beans.qo.ThemeQo;
刘基明's avatar
刘基明 committed
11
import com.tanpu.community.api.beans.req.homepage.QueryRecordThemeReq;
刘基明's avatar
刘基明 committed
12
import com.tanpu.community.api.beans.req.theme.*;
刘基明's avatar
刘基明 committed
13
import com.tanpu.community.api.beans.resp.CreateThemeResp;
张辰's avatar
张辰 committed
14
import com.tanpu.community.api.beans.resp.ThemeFullSearchResp;
15
import com.tanpu.community.api.beans.resp.ThemeListResp;
16
import com.tanpu.community.api.beans.vo.feign.fatools.UserInfoNew;
刘基明's avatar
刘基明 committed
17
import com.tanpu.community.api.enums.*;
张辰's avatar
张辰 committed
18
import com.tanpu.community.cache.RedisCache;
刘基明's avatar
刘基明 committed
19
import com.tanpu.community.dao.entity.community.*;
刘基明's avatar
刘基明 committed
20
import com.tanpu.community.feign.fatools.FeignClientForFatools;
刘基明's avatar
刘基明 committed
21
import com.tanpu.community.service.*;
张辰's avatar
张辰 committed
22
import com.tanpu.community.service.base.ESService;
张辰's avatar
张辰 committed
23
import com.tanpu.community.util.BizUtils;
24
import com.tanpu.community.util.ConvertUtil;
刘基明's avatar
刘基明 committed
25
import com.tanpu.community.util.RankUtils;
刘基明's avatar
刘基明 committed
26
import com.tanpu.community.util.TencentcloudUtils;
张辰's avatar
张辰 committed
27
import lombok.extern.slf4j.Slf4j;
刘基明's avatar
刘基明 committed
28
import org.apache.commons.collections4.CollectionUtils;
张辰's avatar
张辰 committed
29
import org.apache.commons.collections4.ListUtils;
刘基明's avatar
刘基明 committed
30
import org.apache.commons.lang3.StringUtils;
张辰's avatar
张辰 committed
31
import org.apache.commons.lang3.exception.ExceptionUtils;
刘基明's avatar
刘基明 committed
32
import org.springframework.beans.BeanUtils;
刘基明's avatar
刘基明 committed
33 34
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
刘基明's avatar
刘基明 committed
35
import org.springframework.transaction.annotation.Transactional;
刘基明's avatar
刘基明 committed
36

刘基明's avatar
刘基明 committed
37
import javax.annotation.Resource;
刘基明's avatar
刘基明 committed
38
import java.time.LocalDateTime;
刘基明's avatar
刘基明 committed
39 40
import java.util.*;
import java.util.stream.Collectors;
刘基明's avatar
刘基明 committed
41

42
import static com.tanpu.community.api.constants.RedisKeyConstant.*;
张辰's avatar
张辰 committed
43

张辰's avatar
张辰 committed
44
@Slf4j
刘基明's avatar
刘基明 committed
45 46
@Service
public class ThemeManager {
刘基明's avatar
刘基明 committed
47
    @Resource
刘基明's avatar
刘基明 committed
48
    private ThemeService themeService;
刘基明's avatar
刘基明 committed
49 50 51 52 53 54 55 56

    @Autowired
    private CollectionService collectionService;

    @Autowired
    private CommentService commentService;

    @Autowired
刘基明's avatar
刘基明 committed
57
    private FollowRelService followRelService;
刘基明's avatar
刘基明 committed
58

刘基明's avatar
刘基明 committed
59 60 61
    @Autowired
    private BlackListService blackListService;

62
    @Autowired
刘基明's avatar
刘基明 committed
63
    private UserInfoService userInfoService;
64

刘基明's avatar
刘基明 committed
65 66 67
    @Autowired
    private ThemeAttachmentService themeAttachmentService;

刘基明's avatar
刘基明 committed
68
    @Resource
刘基明's avatar
刘基明 committed
69
    private BatchFeignCallService batchFeignCallService;
刘基明's avatar
刘基明 committed
70

刘基明's avatar
刘基明 committed
71
    @Autowired
刘基明's avatar
刘基明 committed
72
    private VisitSummaryService visitSummaryService;
刘基明's avatar
刘基明 committed
73

74 75 76
    @Autowired
    private ReportLogService reportLogService;

刘基明's avatar
刘基明 committed
77 78 79
    @Autowired
    private RankService rankService;

张辰's avatar
张辰 committed
80 81 82
    @Autowired
    private ESService esService;

刘基明's avatar
刘基明 committed
83 84 85
    @Autowired
    private FeignClientForFatools feignClientForFatools;

张辰's avatar
张辰 committed
86 87 88
    @Autowired
    private RedisCache redisCache;

89 90 91
    @Autowired
    private RecommendService recommendService;

张辰's avatar
张辰 committed
92
    public ThemeFullSearchResp themeFullSearch(String keyword, Integer pageNo, Integer pageSize, List<String> excludeIds, String userId) {
张辰's avatar
张辰 committed
93
        Integer from = (pageNo - 1) * pageSize;
张辰's avatar
张辰 committed
94
        ThemeFullSearchResp resp = new ThemeFullSearchResp();
张辰's avatar
张辰 committed
95 96

        // 按时间倒叙查询
张辰's avatar
张辰 committed
97 98 99
        List<ESThemeQo> esIds = esService.queryThemeIdByContentAndTitle(keyword, from, pageSize * 5);
        if (esIds.isEmpty()) {
            return resp;
张辰's avatar
张辰 committed
100 101
        }

张辰's avatar
张辰 committed
102 103 104 105 106 107
        // 排除已经展示过的id
        List<String> filterEsIds = esIds.stream().map(ESThemeQo::getThemeId).filter(tId -> {
            return !excludeIds.contains(tId);
        }).limit(pageSize).collect(Collectors.toList());

        resp.themes = convertEntityToQo(themeService.queryByThemeIds(filterEsIds), userId);
张辰's avatar
张辰 committed
108 109 110 111 112 113
        resp.themes.sort(new Comparator<ThemeQo>() {
            @Override
            public int compare(ThemeQo o1, ThemeQo o2) {
                return o2.createTime.compareTo(o1.createTime);
            }
        });
114 115 116 117
        // 截取关键词出现的那一部分段落
        for (ThemeQo theme : resp.themes) {
            theme.briefContent4FullSearch = BizUtils.getThemeContent(keyword, theme);
        }
张辰's avatar
张辰 committed
118 119 120
        resp.excludeIds.addAll(filterEsIds);

        return resp;
张辰's avatar
张辰 committed
121
    }
刘基明's avatar
刘基明 committed
122

张辰's avatar
张辰 committed
123

刘基明's avatar
刘基明 committed
124
    /**
125
     * 发表主题(修改)
刘基明's avatar
刘基明 committed
126
     */
张辰's avatar
张辰 committed
127
    @Transactional
刘基明's avatar
刘基明 committed
128
    public CreateThemeResp publishTheme(CreateThemeReq req, String userId) {
刘基明's avatar
刘基明 committed
129

刘基明's avatar
刘基明 committed
130
        // 保存主题表
刘基明's avatar
刘基明 committed
131
        ThemeEntity themeEntity = new ThemeEntity();
刘基明's avatar
刘基明 committed
132
        BeanUtils.copyProperties(req, themeEntity);
刘基明's avatar
刘基明 committed
133
        themeEntity.setAuthorId(userId);
刘基明's avatar
刘基明 committed
134
        themeEntity.setContent(JsonUtil.toJson(req.getContent()));
刘基明's avatar
刘基明 committed
135
        // 讨论类型,将讨论中的文本放入到discussContent中
刘基明's avatar
刘基明 committed
136 137
        if (ThemeTypeEnum.DISCUSSION.getCode().equals(themeEntity.getThemeType())) {
            String content = req.getContent().get(0).getValue();
刘基明's avatar
刘基明 committed
138 139 140
            // discuss_content字段上限为256个字符
            if (content.length() > 256) {
                content = content.substring(0, 255);
刘基明's avatar
刘基明 committed
141 142 143
            }
            themeEntity.setDiscussContent(content);
        }
刘基明's avatar
刘基明 committed
144

刘基明's avatar
刘基明 committed
145
        // 腾讯云敏感词校验
刘基明's avatar
刘基明 committed
146
        checkContent(themeEntity.getContent());
刘基明's avatar
刘基明 committed
147

刘基明's avatar
刘基明 committed
148
        if (StringUtils.isEmpty(req.getEditThemeId())) {
刘基明's avatar
刘基明 committed
149
            // 新建
刘基明's avatar
刘基明 committed
150
            themeService.insertTheme(themeEntity);
刘基明's avatar
刘基明 committed
151
        } else {
刘基明's avatar
刘基明 committed
152
            // 修改
刘基明's avatar
刘基明 committed
153
            themeService.update(themeEntity, req.getEditThemeId());
刘基明's avatar
刘基明 committed
154
            themeEntity.setThemeId(req.getEditThemeId());
刘基明's avatar
刘基明 committed
155
        }
刘基明's avatar
刘基明 committed
156
        // 保存附件表
刘基明's avatar
刘基明 committed
157
        List<ThemeAttachmentEntity> themeAttachments = ConvertUtil.themeReqToAttachmentList(req, themeEntity.getThemeId());
刘基明's avatar
刘基明 committed
158
        if (StringUtils.isNotEmpty(req.getEditThemeId())) {
刘基明's avatar
刘基明 committed
159
            // 修改需要刪除
刘基明's avatar
刘基明 committed
160
            themeAttachmentService.deleteByThemeId(req.getEditThemeId());
刘基明's avatar
刘基明 committed
161
        }
刘基明's avatar
刘基明 committed
162
        themeAttachmentService.insertList(themeAttachments);
刘基明's avatar
刘基明 committed
163

张辰's avatar
张辰 committed
164 165 166 167 168
        try {
            esService.insertOrUpdateTheme(ConvertUtil.convert(themeEntity));
        } catch (Exception e) {
            log.error("error in save theme to ES. themeId:{}, error:{}", themeEntity.getThemeId(), ExceptionUtils.getStackTrace(e));
        }
刘基明's avatar
刘基明 committed
169

张辰's avatar
张辰 committed
170 171
        redisCache.evict(StringUtils.joinWith("_", CACHE_THEME_ID, themeEntity.getThemeId()));

刘基明's avatar
刘基明 committed
172
        return CreateThemeResp.builder().themeId(themeEntity.getThemeId()).build();
刘基明's avatar
刘基明 committed
173
    }
刘基明's avatar
刘基明 committed
174

刘基明's avatar
刘基明 committed
175
    // 转发主题
刘基明's avatar
刘基明 committed
176 177 178 179 180 181 182 183 184
    public CreateThemeResp forward(ForwardThemeReq req, String userId) {
        ThemeEntity targetTheme = themeService.queryByThemeId(req.getFormerThemeId());
        ThemeEntity themeEntity = ThemeEntity.builder()
                .content(JsonUtil.toJson(req.getContent()))
                .topicId(req.getTopicId())
                .formerThemeId(req.getFormerThemeId())
                .authorId(userId)
                .themeType(ThemeTypeEnum.FORWARD.getCode())
                .build();
刘基明's avatar
刘基明 committed
185

张辰's avatar
张辰 committed
186
        if (StringUtils.isEmpty(req.getEditThemeId()) || req.getEditThemeId().equals(req.getFormerThemeId())) {
刘基明's avatar
刘基明 committed
187
            // 新建
刘基明's avatar
刘基明 committed
188 189
            themeService.insertTheme(themeEntity);
        } else {
刘基明's avatar
刘基明 committed
190
            // 修改
刘基明's avatar
刘基明 committed
191 192 193 194 195 196 197
            themeService.update(themeEntity, req.getEditThemeId());
            themeEntity.setThemeId(req.getEditThemeId());
        }
        return CreateThemeResp.builder().themeId(themeEntity.getThemeId()).build();
    }


198 199 200
    /**
     * 推荐:由最热,最新和python推荐三个部分组成,比例为6,3,1
     */
刘基明's avatar
刘基明 committed
201
    // 查询主题列表:推荐/关注/热门/最新
202
    public ThemeListResp queryThemes(ThemeListReq req, String userId) {
张辰's avatar
张辰 committed
203
        Integer pageStart = (req.page.pageNumber - 1) * req.page.pageSize;
刘基明's avatar
刘基明 committed
204
        Integer pageSize = req.page.pageSize;
张辰's avatar
张辰 committed
205
        Integer querySize = pageSize * 3;
206 207

        List<ThemeEntity> themes = new ArrayList<>();
张辰's avatar
张辰 committed
208

刘基明's avatar
刘基明 committed
209
        if (ThemeListTypeEnum.RECOMMEND.getCode().equals(req.getType())) {
刘基明's avatar
刘基明 committed
210
            //推荐
张辰's avatar
张辰 committed
211 212 213 214
            // 需要筛掉用户访问过详情的 & 最近出现在列表页过的.
            List<String> visitedIds = visitSummaryService.queryUserRecentVisited(userId);
            List<String> excludes = ListUtils.union(req.excludeIds, visitedIds);
            List<String> recmdIds = recommendService.getRecommendThemes(pageStart, querySize, userId, excludes);
张辰's avatar
张辰 committed
215

张辰's avatar
张辰 committed
216
            recmdIds = BizUtils.subList(recmdIds, pageStart, pageSize);
217 218
            themes = themeService.queryByThemeIds(recmdIds);
            themes = RankUtils.sortThemeEntityByIds(themes, recmdIds);
刘基明's avatar
刘基明 committed
219

刘基明's avatar
刘基明 committed
220
        } else if (ThemeListTypeEnum.FOLLOW.getCode().equals(req.getType())) {
张辰's avatar
张辰 committed
221
            // TODO 临时埋点,接入新埋点后删除
刘基明's avatar
刘基明 committed
222 223 224
            if (CollectionUtils.isEmpty(req.getExcludeIds())) {
                visitSummaryService.addPageView(userId, userId, VisitTypeEnum.FOLLOW_THEME_VIEW);
            }
张辰's avatar
张辰 committed
225
            // 根据关注列表查询,按时间倒序
刘基明's avatar
刘基明 committed
226
            List<String> fansList = followRelService.queryFansByFollowerId(userId);
张辰's avatar
张辰 committed
227 228
            themes = themeService.queryByUserIdsCreateDesc(fansList, pageStart, pageSize);

刘基明's avatar
刘基明 committed
229
        } else if (ThemeListTypeEnum.TOPIC_HOT.getCode().equals(req.getType())) {
张辰's avatar
张辰 committed
230
            // 根据话题查询热门
231 232 233
            if (StringUtils.isEmpty(req.getTopicId())) {
                throw new BizException("TopicId为空");
            }
234

张辰's avatar
张辰 committed
235 236
            List<String> rankThemeIds = rankService.getRankThemeListByTopic(req.getTopicId(), req.excludeIds);
            rankThemeIds = BizUtils.subList(rankThemeIds, pageStart, pageSize);
237

238 239
            themes = themeService.queryByThemeIds(rankThemeIds);
            themes = RankUtils.sortThemeEntityByIds(themes, rankThemeIds);
张辰's avatar
张辰 committed
240

刘基明's avatar
刘基明 committed
241
        } else if (ThemeListTypeEnum.TOPIC_LATEST.getCode().equals(req.getType())) {
刘基明's avatar
刘基明 committed
242
            //根据话题查询最新
243 244 245
            if (StringUtils.isEmpty(req.getTopicId())) {
                throw new BizException("TopicId为空");
            }
张辰's avatar
张辰 committed
246
            themes = themeService.queryNewestByTopic(req.topicId, pageStart, querySize, req.excludeIds);
刘基明's avatar
刘基明 committed
247
        }
248

249 250 251
        ThemeListResp resp = new ThemeListResp();
        resp.excludeIds = req.excludeIds;
        resp.excludeIds.addAll(themes.stream().map(ThemeEntity::getThemeId).collect(Collectors.toList()));
刘基明's avatar
刘基明 committed
252
        resp.themes = convertEntityToQo(themes, userId);
253

254
        //组装详情
255
        return resp;
刘基明's avatar
刘基明 committed
256 257
    }

刘基明's avatar
刘基明 committed
258
    // 主题Entity转QO,组装所有信息
259 260 261
    private List<ThemeQo> convertEntityToQo(List<ThemeEntity> themeEntities, String userId) {
        //Entity转Qo
        List<ThemeQo> themeQos = ConvertUtil.themeEntitiesToDTOs(themeEntities);
刘基明's avatar
刘基明 committed
262
        // 批量查询附件detail
263 264 265
        batchFeignCallService.getAttachDetailByBatch(themeQos);
        //其他信息
        for (ThemeQo themeQO : themeQos) {
刘基明's avatar
刘基明 committed
266
            // 通用信息
267
            buildThemeQoExtraInfo(themeQO);
刘基明's avatar
刘基明 committed
268
            // 和用户相关信息
269 270
            buildThemeExtraInfoByUser(userId, themeQO);
        }
刘基明's avatar
刘基明 committed
271

272 273 274
        return themeQos;
    }

刘基明's avatar
刘基明 committed
275
    // 转发对象、点赞、收藏、转发数
276 277
    private void buildThemeQoExtraInfo(ThemeQo themeQo) {
        String themeId = themeQo.getThemeId();
刘基明's avatar
刘基明 committed
278
        // 封装转发对象
279 280 281
        FormerThemeQo former = redisCache.getObject(StringUtils.joinWith("_", CACHE_FORMER_THEME_ID, themeId), 60,
                () -> this.getFormerTheme(themeQo.getFormerThemeId()), FormerThemeQo.class);
        themeQo.setFormerTheme(former);
刘基明's avatar
刘基明 committed
282
        // 点赞,收藏,转发
283 284 285 286 287 288
        Integer likeCount = collectionService.getCountByTypeAndId(themeId, CollectionTypeEnum.LIKE_THEME);
        Integer commentCount = commentService.getCommentCountByThemeId(themeId);
        Integer forwardCount = themeService.getForwardCountById(themeId);
        themeQo.setCommentCount(commentCount);
        themeQo.setLikeCount(likeCount);
        themeQo.setForwardCount(forwardCount);
刘基明's avatar
刘基明 committed
289 290
    }

刘基明's avatar
刘基明 committed
291
    // 组装和当前用户相关信息
292 293
    private void buildThemeExtraInfoByUser(String userId, ThemeQo themeQo) {
        String themeId = themeQo.getThemeId();
刘基明's avatar
刘基明 committed
294
        // 是否关注作者
刘基明's avatar
刘基明 committed
295
        themeQo.setFollow(followRelService.checkFollow(themeQo.getAuthorId(), userId));
刘基明's avatar
刘基明 committed
296
        // 是否点赞
297 298
        CollectionEntity likeEntity = collectionService.getNotDeleteTargetCollection(themeId, userId, CollectionTypeEnum.LIKE_THEME);
        themeQo.setHasLiked(likeEntity != null);
刘基明's avatar
刘基明 committed
299
        // 是否转发
300 301
        Integer forwardCountByUser = themeService.getForwardCountByUser(themeId, userId);
        themeQo.setHasForward(forwardCountByUser > 0);
刘基明's avatar
刘基明 committed
302
        // 是否收藏
303 304 305
        CollectionEntity collectionEntity = collectionService.getNotDeleteTargetCollection(themeId, userId, CollectionTypeEnum.COLLECT_THEME);
        themeQo.setHasCollect(collectionEntity != null);
    }
刘基明's avatar
刘基明 committed
306

刘基明's avatar
刘基明 committed
307
    // 返回用户发布、回复、点赞、收藏的主题列表
刘基明's avatar
刘基明 committed
308
    public List<ThemeQo> queryThemesByUser(QueryRecordThemeReq req, String userId) {
刘基明's avatar
刘基明 committed
309 310 311 312

        List<ThemeEntity> themeEntities = Collections.emptyList();
        switch (req.getRecordType()) {
            case 1://发布
刘基明's avatar
刘基明 committed
313
                themeEntities = themeService.queryThemesByUserId(req.getUserId(), req.getLastId(), req.getPageSize());
刘基明's avatar
刘基明 committed
314
                break;
刘基明's avatar
刘基明 committed
315
            case 2://回复
刘基明's avatar
刘基明 committed
316
                List<ThemeQo> commentThemeList = getCommentThemeQos(req, userId);
刘基明's avatar
刘基明 committed
317
                return commentThemeList;
刘基明's avatar
刘基明 committed
318
            case 3://点赞
319 320 321 322
                List<String> likeThemeIds = collectionService.getListByUser(req.getUserId(), CollectionTypeEnum.LIKE_THEME);
                themeEntities = themeService.queryByThemeIds(likeThemeIds, req.getLastId(), req.getPageSize());
                themeEntities = RankUtils.sortThemeEntityByIds(themeEntities, likeThemeIds);

刘基明's avatar
刘基明 committed
323
                break;
刘基明's avatar
刘基明 committed
324
            case 4://收藏
325 326 327
                List<String> collectThemeIds = collectionService.getListByUser(req.getUserId(), CollectionTypeEnum.COLLECT_THEME);
                themeEntities = themeService.queryByThemeIds(collectThemeIds, req.getLastId(), req.getPageSize());
                themeEntities = RankUtils.sortThemeEntityByIds(themeEntities, collectThemeIds);
刘基明's avatar
刘基明 committed
328 329 330 331 332 333
                break;
        }
        List<ThemeQo> themeQos = convertEntityToQo(themeEntities, userId);
        return themeQos;
    }

刘基明's avatar
刘基明 committed
334

刘基明's avatar
刘基明 committed
335
    // 查询正文
336
    public ThemeQo getThemeDetail(String themeId, String userId) {
刘基明's avatar
刘基明 committed
337 338
        //TODO 临时埋点,接入新埋点后删除
        visitSummaryService.addPageView(userId, themeId, VisitTypeEnum.THEME_PAGE_VIEW);
刘基明's avatar
刘基明 committed
339
        // 查询详情
340
        ThemeQo themeQo = redisCache.getObject(StringUtils.joinWith("_", CACHE_THEME_ID, themeId), 60,
341
                () -> this.getDetailCommon(themeId), ThemeQo.class);
刘基明's avatar
刘基明 committed
342
        // 添加用户相关信息
343
        buildThemeExtraInfoByUser(userId, themeQo);
344 345 346
        return themeQo;
    }

刘基明's avatar
刘基明 committed
347
    // 正文通用信息,与用户无关,可使用缓存
348
    private ThemeQo getDetailCommon(String themeId) {
刘基明's avatar
刘基明 committed
349
        ThemeEntity themeEntity = themeService.queryByThemeId(themeId);
刘基明's avatar
刘基明 committed
350 351
        if (themeEntity == null) {
            throw new BizException("找不到帖子id:" + themeId);
刘基明's avatar
刘基明 committed
352
        }
刘基明's avatar
刘基明 committed
353
        ThemeQo themeQo = ConvertUtil.themeEntityToQo(themeEntity);
刘基明's avatar
刘基明 committed
354
        //附件
刘基明's avatar
刘基明 committed
355
        batchFeignCallService.getAttachDetail(themeQo);
刘基明's avatar
刘基明 committed
356 357

        //转发、收藏、点赞
358
        buildThemeQoExtraInfo(themeQo);
刘基明's avatar
刘基明 committed
359

刘基明's avatar
刘基明 committed
360
        return themeQo;
刘基明's avatar
刘基明 committed
361 362
    }

363

刘基明's avatar
刘基明 committed
364 365
    // 点赞/取消点赞
    public void like(LikeThemeReq req, String userId) {
刘基明's avatar
刘基明 committed
366
        if (OperationTypeEnum.CONFIRM.getCode().equals(req.getType())) {
刘基明's avatar
刘基明 committed
367
            collectionService.saveOrUpdate(req.getThemeId(), userId, CollectionTypeEnum.LIKE_THEME);
刘基明's avatar
刘基明 committed
368
        } else if (OperationTypeEnum.CANCEL.getCode().equals(req.getType())) {
刘基明's avatar
刘基明 committed
369 370 371
            collectionService.delete(req.getThemeId(), userId, CollectionTypeEnum.LIKE_THEME);
        }

刘基明's avatar
刘基明 committed
372 373
    }

刘基明's avatar
刘基明 committed
374 375
    //收藏/取消收藏
    public void collect(CollectThemeReq req, String userId) {
刘基明's avatar
刘基明 committed
376
        if (OperationTypeEnum.CONFIRM.getCode().equals(req.getType())) {
刘基明's avatar
刘基明 committed
377
            collectionService.saveOrUpdate(req.getThemeId(), userId, CollectionTypeEnum.COLLECT_THEME);
刘基明's avatar
刘基明 committed
378
        } else if (OperationTypeEnum.CANCEL.getCode().equals(req.getType())) {
刘基明's avatar
刘基明 committed
379 380
            collectionService.delete(req.getThemeId(), userId, CollectionTypeEnum.COLLECT_THEME);
        }
张辰's avatar
张辰 committed
381 382
    }

刘基明's avatar
刘基明 committed
383 384 385 386 387 388 389 390
    //举报主题
    public void report(ReportThemeReq req, String userId) {
        //更改举报状态
        themeService.updateReportStatus(req.getThemeId());
        //写入举报记录表
        ThemeEntity themeEntity = themeService.queryByThemeId(req.getThemeId());
        reportLogService.insert(ReportTypeEnum.THEME, userId, req.getThemeId(), themeEntity.getAuthorId(), req.getReason());
    }
391

刘基明's avatar
刘基明 committed
392

刘基明's avatar
刘基明 committed
393 394 395 396 397
    //关注用户是否有更新
    public Integer getFollowUpdateCount(String userId) {
        LocalDateTime lastViewTime = visitSummaryService.queryLatestViewFollow(userId);
        List<String> fansList = followRelService.queryFansByFollowerId(userId);
        return themeService.queryCountFromLastTime(fansList, lastViewTime);
刘基明's avatar
刘基明 committed
398 399
    }

刘基明's avatar
刘基明 committed
400 401 402 403 404 405
    //    屏蔽(用户)
    public void blockUser(String blockUser, String userId) {
        BlackListEntity selectOne = blackListService.selectOne(blockUser, userId, BlockTypeEnum.USER.getCode());
        if (selectOne == null) {
            blackListService.addBlock(blockUser, userId, BlockTypeEnum.USER);
        }
刘基明's avatar
刘基明 committed
406
    }
刘基明's avatar
刘基明 committed
407

刘基明's avatar
刘基明 committed
408

刘基明's avatar
刘基明 committed
409 410 411 412 413 414 415 416 417 418 419 420 421 422
    //返回被转发主题
    private FormerThemeQo getFormerTheme(String formerThemeId) {
        if (StringUtils.isNotEmpty(formerThemeId)) {
            ThemeQo formerTheme = ConvertUtil.themeEntityToQo(themeService.queryByThemeId(formerThemeId));
            if (formerTheme != null) {
                batchFeignCallService.getAttachDetail(formerTheme);
                FormerThemeQo f = ConvertUtil.themeQo2FormerThemeQo(formerTheme);
                return f;
            }

        }
        return null;
    }

刘基明's avatar
刘基明 committed
423

424
    //逻辑删除主题
刘基明's avatar
刘基明 committed
425 426 427
    public void delete(String themeId) {
        themeService.deleteById(themeId);
    }
刘基明's avatar
刘基明 committed
428 429


刘基明's avatar
刘基明 committed
430 431
    /**
     * 腾讯云-内容检测
刘基明's avatar
刘基明 committed
432
     *
刘基明's avatar
刘基明 committed
433 434
     * @param content
     */
刘基明's avatar
刘基明 committed
435 436 437 438 439 440 441 442 443 444 445 446 447
    private void checkContent(String content) {
        // 腾讯云接口最多支持5000文字校验,超过5000执行2次
        // 检查内容是否涉黄违法
        CommonResp commonResp = TencentcloudUtils.textModeration(content.length() > 5000 ? content.substring(0, 5000) : content);
        if (!commonResp.isSuccess()) {
            throw new BizException("内容校验失败,请检查内容后重新发送");
        }
        if (content.length() > 5000) {
            CommonResp commonResp2 = TencentcloudUtils.textModeration(content.substring(5000, content.length()));
            if (!commonResp2.isSuccess()) {
                throw new BizException("内容校验失败,请检查内容后重新发送");
            }
        }
刘基明's avatar
刘基明 committed
448
        return;
刘基明's avatar
刘基明 committed
449 450
    }

刘基明's avatar
刘基明 committed
451 452 453

    /**
     * 直播类型做转播检查
刘基明's avatar
刘基明 committed
454
     *
刘基明's avatar
刘基明 committed
455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471
     * @param userId
     * @param contents
     */
    private void liveRelayCheck(String userId, List<ThemeContentReq> contents) {
        for (ThemeContentReq content : contents) {
            if (content != null && content.getType().equals(RelTypeEnum.LIVE.type)) {
                CommonResp<Set<String>> notRelayResp = feignClientForFatools.getNotRelaySet(userId, Sets.newHashSet(content.getValue()));
                if (!notRelayResp.isSuccess()) {
                    throw new BizException("转播失败");
                }
                if (CollectionUtils.isEmpty(notRelayResp.getData())) {
                    throw new BizException("9999", "很抱歉!您需要购买或报名成功后才可以添加这个直播哦~");
                }
            }
        }
    }

刘基明's avatar
刘基明 committed
472

刘基明's avatar
刘基明 committed
473 474 475 476 477 478 479 480 481 482
    /**
     * 查询用户评论过的主题,并封装成转发主题结构
     *
     * @param req
     * @param userId 当前用户
     * @return
     */
    private List<ThemeQo> getCommentThemeQos(QueryRecordThemeReq req, String userId) {
        List<ThemeQo> commentThemeList = new ArrayList<>();
        List<ThemeEntity> themeEntities;
刘基明's avatar
刘基明 committed
483
        // 评论列表
刘基明's avatar
刘基明 committed
484
        List<CommentEntity> commentEntities = commentService.queryCommentsByUserId(req.getUserId(), req.getLastId(), req.getPageSize());
刘基明's avatar
刘基明 committed
485
        // 当前用户信息
刘基明's avatar
刘基明 committed
486
        UserInfoNew userInfo = redisCache.getObject(StringUtils.joinWith(CACHE_FEIGN_USER_INFO, req.getUserId()),
张辰's avatar
张辰 committed
487
                60, () -> this.getUserInfo(req.getUserId()), UserInfoNew.class);
刘基明's avatar
刘基明 committed
488 489 490 491 492 493
        Set<String> replyThemeIds = commentEntities.stream().map(CommentEntity::getThemeId).collect(Collectors.toSet());
        if (CollectionUtils.isEmpty(replyThemeIds)) {
            return commentThemeList;
        }
        themeEntities = themeService.queryByThemeIds(new ArrayList<>(replyThemeIds));
        List<ThemeQo> themeQos = convertEntityToQo(themeEntities, userId);
刘基明's avatar
刘基明 committed
494
        // 组装附件
刘基明's avatar
刘基明 committed
495
        batchFeignCallService.getAttachDetailByBatch(themeQos);
刘基明's avatar
刘基明 committed
496
        // 主题列表
刘基明's avatar
刘基明 committed
497 498
        Map<String, ThemeQo> themeMap = themeQos.stream()
                .collect(Collectors.toMap(ThemeQo::getThemeId, o -> o));
刘基明's avatar
刘基明 committed
499
        // 主题+评论封装转发对象
刘基明's avatar
刘基明 committed
500 501 502 503 504 505 506
        for (CommentEntity commentEntity : commentEntities) {
            String themeId = commentEntity.getThemeId();
            //评论内容包装到ThemeContentQo里
            ThemeContentQo commentContent = ThemeContentQo.builder()
                    .type(RelTypeEnum.TEXT.type)
                    .value(commentEntity.getContent())
                    .build();
刘基明's avatar
刘基明 committed
507

刘基明's avatar
刘基明 committed
508

刘基明's avatar
刘基明 committed
509
            ThemeQo commentThemeQo = ThemeQo.builder()
510 511 512 513 514 515 516 517
                    .authorId(userInfo.getUserId())
                    .nickName(userInfo.getNickName())
                    .userImg(userInfo.getHeadImageUrl())
                    .userType(userInfo.getUserType())
                    .levelGrade(userInfo.getLevelGrade())
                    .userInvestorType(userInfo.getUserInvestorType())
                    .belongUserOrgId(userInfo.getBelongUserOrgId())
                    .belongUserOrgName(userInfo.getBelongUserOrgName())
刘基明's avatar
刘基明 committed
518
                    .content(Collections.singletonList(commentContent))
刘基明's avatar
刘基明 committed
519 520
                    .commentId(commentEntity.getCommentId())
                    .themeType(ThemeTypeEnum.RES_COMMENT.getCode())
刘基明's avatar
刘基明 committed
521
                    .follow(followRelService.checkFollow(userId, userId))
刘基明's avatar
刘基明 committed
522
                    .build();
刘基明's avatar
刘基明 committed
523 524 525

            //原主题包装到formerThemeQo中
            ThemeQo themeQo = themeMap.get(themeId);
刘基明's avatar
刘基明 committed
526
            if (themeQo != null) {
刘基明's avatar
刘基明 committed
527
                FormerThemeQo f = ConvertUtil.themeQo2FormerThemeQo(themeQo);
刘基明's avatar
刘基明 committed
528
                commentThemeQo.setFormerTheme(f);
刘基明's avatar
刘基明 committed
529
            }
刘基明's avatar
刘基明 committed
530 531
            commentThemeList.add(commentThemeQo);
        }
刘基明's avatar
刘基明 committed
532
        return commentThemeList;
刘基明's avatar
刘基明 committed
533 534
    }

535

刘基明's avatar
刘基明 committed
536
    private UserInfoNew getUserInfo(String authorId) {
537 538 539 540 541 542 543
        CommonResp<UserInfoNew> userInfoNewCommonResp = feignClientForFatools.queryUsersListNew(authorId);
        if (userInfoNewCommonResp.isNotSuccess()) {
            throw new BizException("内部接口调用失败");
        }
        return userInfoNewCommonResp.getData();
    }

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