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

王亚雷's avatar
王亚雷 committed
3
import com.google.common.collect.Sets;
张辰's avatar
张辰 committed
4 5 6
import com.tanpu.biz.common.enums.community.CollectionTypeEnum;
import com.tanpu.biz.common.enums.community.CommentTypeEnum;
import com.tanpu.biz.common.enums.community.ReportTypeEnum;
刘基明's avatar
刘基明 committed
7
import com.tanpu.common.api.CommonResp;
8
import com.tanpu.common.constant.ErrorCodeConstant;
刘基明's avatar
刘基明 committed
9
import com.tanpu.common.exception.BizException;
刘基明's avatar
刘基明 committed
10
import com.tanpu.community.api.beans.qo.CommentQo;
刘基明's avatar
刘基明 committed
11
import com.tanpu.community.api.beans.req.comment.CreateCommentReq;
刘基明's avatar
刘基明 committed
12
import com.tanpu.community.api.beans.req.comment.LikeCommentReq;
13
import com.tanpu.community.api.beans.req.comment.ReportCommentReq;
14
import com.tanpu.community.api.beans.vo.feign.fatools.UserInfoResp;
15
import com.tanpu.community.api.constants.BizConstant;
刘基明's avatar
刘基明 committed
16
import com.tanpu.community.api.enums.NotificationTypeEnum;
刘基明's avatar
刘基明 committed
17
import com.tanpu.community.api.enums.OperationTypeEnum;
张辰's avatar
张辰 committed
18
import com.tanpu.community.cache.RedisCache;
刘基明's avatar
刘基明 committed
19
import com.tanpu.community.dao.entity.community.CommentEntity;
刘基明's avatar
刘基明 committed
20
import com.tanpu.community.dao.entity.community.ThemeEntity;
刘基明's avatar
刘基明 committed
21
import com.tanpu.community.feign.fatools.FeignClientForFatools;
刘基明's avatar
刘基明 committed
22 23
import com.tanpu.community.service.CollectionService;
import com.tanpu.community.service.CommentService;
刘基明's avatar
刘基明 committed
24
import com.tanpu.community.service.FeignService;
刘基明's avatar
刘基明 committed
25
import com.tanpu.community.service.NotificationService;
26
import com.tanpu.community.service.ReportLogService;
刘基明's avatar
刘基明 committed
27
import com.tanpu.community.service.ThemeService;
刘基明's avatar
刘基明 committed
28
import com.tanpu.community.service.TopicService;
张辰's avatar
张辰 committed
29
import com.tanpu.community.service.quartz.TopicReportService;
刘基明's avatar
刘基明 committed
30
import com.tanpu.community.util.ConvertUtil;
张辰's avatar
张辰 committed
31
import org.apache.commons.lang3.StringUtils;
刘基明's avatar
刘基明 committed
32 33
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
刘基明's avatar
刘基明 committed
34
import org.springframework.transaction.annotation.Transactional;
刘基明's avatar
刘基明 committed
35

刘基明's avatar
刘基明 committed
36
import javax.annotation.Resource;
37
import java.time.LocalDateTime;
刘基明's avatar
刘基明 committed
38
import java.util.ArrayDeque;
刘基明's avatar
刘基明 committed
39
import java.util.Comparator;
刘基明's avatar
刘基明 committed
40 41
import java.util.List;
import java.util.Set;
刘基明's avatar
刘基明 committed
42
import java.util.stream.Collectors;
刘基明's avatar
刘基明 committed
43

刘基明's avatar
刘基明 committed
44
import static com.tanpu.community.api.constants.RedisKeyConstant.CACHE_FEIGN_USER_INFO;
张辰's avatar
张辰 committed
45

刘基明's avatar
刘基明 committed
46 47 48 49 50 51 52
@Service
public class CommentManager {

    @Autowired
    private CommentService commentService;

    @Autowired
刘基明's avatar
刘基明 committed
53
    private FeignClientForFatools feignClientForFatools;
刘基明's avatar
刘基明 committed
54 55 56 57

    @Autowired
    private CollectionService collectionService;

刘基明's avatar
刘基明 committed
58
    @Resource
59
    private ReportLogService reportLogService;
刘基明's avatar
刘基明 committed
60

张辰's avatar
张辰 committed
61 62 63
    @Autowired
    private RedisCache redisCache;

刘基明's avatar
刘基明 committed
64 65
    @Autowired
    private NotificationService notificationService;
刘基明's avatar
刘基明 committed
66

刘基明's avatar
刘基明 committed
67 68
    @Autowired
    private ThemeService themeService;
张辰's avatar
张辰 committed
69

刘基明's avatar
刘基明 committed
70 71
    @Resource
    private TopicService topicService;
张辰's avatar
张辰 committed
72

刘基明's avatar
刘基明 committed
73 74
    @Resource
    private FeignService feignService;
刘基明's avatar
刘基明 committed
75

张辰's avatar
张辰 committed
76 77 78
    @Autowired
    private TopicReportService topicReportService;

刘基明's avatar
刘基明 committed
79
    // 评论(对主题)
刘基明's avatar
刘基明 committed
80
    // 发表评论(对主题)
刘基明's avatar
刘基明 committed
81
    public CommentQo comment(CreateCommentReq req, String userId) {
82

83 84 85
        if (StringUtils.isEmpty(req.getComment())) {
            throw new IllegalArgumentException("评论内容不能为空");
        }
刘基明's avatar
刘基明 committed
86
        if (req.getComment().length() > 500) {
87 88 89
            throw new IllegalArgumentException("评论内容不能超过500字");
        }

90
        LocalDateTime now = LocalDateTime.now();
刘基明's avatar
刘基明 committed
91 92 93 94
        CommentEntity commentEntity = CommentEntity.builder()
                .themeId(req.getThemeId())
                .parentId(req.getParentId())
                .replyId(req.getReplyId())
刘基明's avatar
刘基明 committed
95
                .replyUserId(req.getReplyUserId())
刘基明's avatar
刘基明 committed
96
                .authorId(userId)
刘基明's avatar
刘基明 committed
97
                .content(req.getComment())
刘基明's avatar
刘基明 committed
98
                .commentType(CommentTypeEnum.THEME.getCode())
99 100
                .createTime(now)
                .updateTime(now)
刘基明's avatar
刘基明 committed
101 102 103
                .build();

        commentService.insertComment(commentEntity);
刘基明's avatar
刘基明 committed
104 105
        CommentQo commentQo = ConvertUtil.commentEntity2Qo(commentEntity);
        buildUserInfo(commentQo);
刘基明's avatar
刘基明 committed
106 107
        // 消息通知
        ThemeEntity themeEntity = themeService.queryByThemeId(req.getThemeId());
刘基明's avatar
刘基明 committed
108 109
        if (themeEntity == null) {
            throw new BizException(ErrorCodeConstant.UNREACHABLE);
110
        }
张辰's avatar
张辰 committed
111

刘基明's avatar
刘基明 committed
112 113

        // 一级回复通知发帖人,二级回复通知一级评论人
114
        if (StringUtils.isNotBlank(req.getReplyUserId())) {
刘基明's avatar
刘基明 committed
115 116
            notificationService.insert(userId, req.getReplyUserId(), NotificationTypeEnum.COMMENT_REPLY, commentEntity.getCommentId(), req.getComment());
            notificationService.putNotifyCache(req.getReplyUserId(), userId, NotificationTypeEnum.COMMENT_REPLY);
117
        } else {
刘基明's avatar
刘基明 committed
118 119
            notificationService.insert(userId, themeEntity.getAuthorId(), NotificationTypeEnum.COMMENT, commentEntity.getCommentId(), req.getComment());
            notificationService.putNotifyCache(themeEntity.getAuthorId(), userId, NotificationTypeEnum.COMMENT);
刘基明's avatar
刘基明 committed
120 121 122

        }

123 124 125 126 127 128

        // 评论同步转发并消息通知
        if (req.getSyncForward() == BizConstant.SyncForwardType.SYNC_FORWARD) {
            String themeId = themeService.commentSyncForward(req, userId);

            // 消息通知
刘基明's avatar
刘基明 committed
129 130 131
            ThemeEntity commentTheme = themeService.queryByThemeId(req.getThemeId());
            notificationService.insertForward(userId, commentTheme.getAuthorId(), commentTheme.getThemeId(), "", req.getComment(), themeId);
            notificationService.putNotifyCache(commentTheme.getAuthorId(), userId, NotificationTypeEnum.FORWARD);
132 133
        }

张辰's avatar
张辰 committed
134 135 136
        if (StringUtils.isNotBlank(themeEntity.getTopicId())) {
            topicReportService.reportTopicOnTime(themeEntity.getTopicId());
        }
137

刘基明's avatar
刘基明 committed
138
        return commentQo;
刘基明's avatar
刘基明 committed
139 140
    }

刘基明's avatar
刘基明 committed
141
    // 查询评论
刘基明's avatar
刘基明 committed
142
    public List<CommentQo> queryComments(String themeId, String userId) {
刘基明's avatar
刘基明 committed
143 144
        // 因为需要排序,所以从库中查询所有评论
        List<CommentEntity> commentEntities = commentService.selectByThemeId(themeId);
刘基明's avatar
刘基明 committed
145 146
        List<CommentQo> commentQos = ConvertUtil.commentEntity2Qos(commentEntities);

王亚雷's avatar
王亚雷 committed
147 148 149 150 151 152
        Set<String> likeCommentList;
        if (StringUtils.isNotEmpty(userId)) {
            likeCommentList = collectionService.getSetByUser(userId, CollectionTypeEnum.LIKE_COMMENT);
        } else {
            likeCommentList = Sets.newHashSetWithExpectedSize(0);
        }
刘基明's avatar
刘基明 committed
153 154
        // 查询管理员
        ThemeEntity themeEntity = themeService.queryByThemeId(themeId);
刘基明's avatar
刘基明 committed
155
        Set<String> managerId = topicService.getManagerId(themeEntity.getTopicId());
刘基明's avatar
刘基明 committed
156 157

        for (CommentQo commentQo : commentQos) {
刘基明's avatar
刘基明 committed
158 159 160
            // 封装用户信息
            buildUserInfo(commentQo);
            // 是否点赞及点赞数
刘基明's avatar
刘基明 committed
161
            String commentId = commentQo.getCommentId();
刘基明's avatar
刘基明 committed
162 163
            Integer likeCount = collectionService.getCountByTypeAndId(commentId, CollectionTypeEnum.LIKE_COMMENT);
            commentQo.setLikeCount(likeCount);
刘基明's avatar
刘基明 committed
164
            commentQo.setHasLiked(likeCommentList.contains(commentId));
刘基明's avatar
刘基明 committed
165
            // 是否管理员
刘基明's avatar
刘基明 committed
166
            if (managerId.contains(commentQo.getAuthorId())) {
刘基明's avatar
刘基明 committed
167 168 169 170 171
                commentQo.setManager(true);
            } else {
                commentQo.setManager(false);
            }

刘基明's avatar
刘基明 committed
172 173

        }
刘基明's avatar
刘基明 committed
174
        //排序:点赞降序+时间降序
刘基明's avatar
刘基明 committed
175 176
        return commentQos.stream().sorted(Comparator.comparing(CommentQo::getLikeCount, Comparator.reverseOrder()).
                thenComparing(CommentQo::getUpdateTime, Comparator.reverseOrder()))
刘基明's avatar
刘基明 committed
177
                .collect(Collectors.toList());
刘基明's avatar
刘基明 committed
178
    }
刘基明's avatar
刘基明 committed
179

刘基明's avatar
刘基明 committed
180 181 182 183

    private void buildUserInfo(CommentQo commentQo) {
        String authorId = commentQo.getAuthorId();
        UserInfoResp userInfo = redisCache.getObject(StringUtils.joinWith("_", CACHE_FEIGN_USER_INFO, authorId),
刘基明's avatar
刘基明 committed
184
                60, () -> this.getUserInfo(authorId), UserInfoResp.class);
刘基明's avatar
刘基明 committed
185 186 187 188 189 190 191 192 193
        if (userInfo != null) {
            commentQo.setUserImg(userInfo.getHeadImageUrl());
            commentQo.setNickName(userInfo.getNickName());
            commentQo.setUserType(userInfo.getUserType());
            commentQo.setLevelGrade(userInfo.getLevelGrade());
            commentQo.setUserInvestorType(userInfo.getUserInvestorType());
            commentQo.setBelongUserOrgId(userInfo.getBelongUserOrgId());
            commentQo.setBelongUserOrgName(userInfo.getBelongUserOrgName());
        }
刘基明's avatar
刘基明 committed
194
        // 回复用户名
刘基明's avatar
刘基明 committed
195
        if (StringUtils.isNotBlank(commentQo.getReplyUserId())) {
刘基明's avatar
刘基明 committed
196 197 198
            UserInfoResp userResp = feignService.getUserInfoById(commentQo.getReplyUserId());
            if (userResp != null) {
                commentQo.setReplyUserName(userResp.getNickName());
刘基明's avatar
刘基明 committed
199
            }
刘基明's avatar
刘基明 committed
200
        }
刘基明's avatar
刘基明 committed
201

刘基明's avatar
刘基明 committed
202 203 204 205
        commentQo.setHasLiked(false);
        commentQo.setLikeCount(0);
    }

刘基明's avatar
刘基明 committed
206
    private UserInfoResp getUserInfo(String authorId) {
207
        CommonResp<UserInfoResp> userInfoNewCommonResp = feignClientForFatools.queryUserInfoNew(authorId);
刘基明's avatar
刘基明 committed
208 209 210 211 212 213
        if (userInfoNewCommonResp.isNotSuccess()) {
            throw new BizException("内部接口调用失败");
        }
        return userInfoNewCommonResp.getData();
    }

刘基明's avatar
刘基明 committed
214 215
    //点赞评论/取消点赞
    public void likeComment(LikeCommentReq req, String userId) {
刘基明's avatar
刘基明 committed
216
        if (OperationTypeEnum.CONFIRM.getCode().equals(req.getType())) {
217
            boolean b = collectionService.saveOrUpdate(req.getCommentId(), userId, CollectionTypeEnum.LIKE_COMMENT);
刘基明's avatar
刘基明 committed
218
            if (b) {
219
                CommentEntity commentEntity = commentService.queryByCommentId(req.getCommentId());
刘基明's avatar
刘基明 committed
220
                notificationService.insertLikeComment(userId, commentEntity.getAuthorId(), req.getCommentId());
221 222
                notificationService.putNotifyCache(commentEntity.getAuthorId(), userId, NotificationTypeEnum.COMMENT_LIKE);
            }
刘基明's avatar
刘基明 committed
223

刘基明's avatar
刘基明 committed
224
        } else if (OperationTypeEnum.CANCEL.getCode().equals(req.getType())) {
刘基明's avatar
刘基明 committed
225 226 227 228
            collectionService.delete(req.getCommentId(), userId, CollectionTypeEnum.LIKE_COMMENT);
        }

    }
229 230

    //举报评论
刘基明's avatar
刘基明 committed
231
    @Transactional
232 233 234
    public void report(ReportCommentReq req, String userId) {
        //更改举报状态
        commentService.updateReportStatus(req.getCommentId());
刘基明's avatar
刘基明 committed
235
        //写入举报记录表
刘基明's avatar
刘基明 committed
236
        CommentEntity commentEntity = commentService.queryByIdIncludeDelete(req.getCommentId());
刘基明's avatar
刘基明 committed
237
        reportLogService.insert(ReportTypeEnum.COMMENT, userId, req.getCommentId(), commentEntity.getAuthorId(), req.getReason());
238
    }
刘基明's avatar
刘基明 committed
239 240 241 242


    //删除评论
    public void delete(String commentId, String userId) {
刘基明's avatar
刘基明 committed
243
        if (StringUtils.isBlank(commentId)) {
244 245
            throw new BizException("commentId不能为空");
        }
刘基明's avatar
刘基明 committed
246 247 248
        ArrayDeque<CommentEntity> queue = new ArrayDeque<>();
        queue.add(commentService.queryByIdIncludeDelete(commentId));

249
        // 循环删除二级评论的一级评论
刘基明's avatar
刘基明 committed
250 251 252
        while (!queue.isEmpty()) {

            CommentEntity pop = queue.pop();
253
            // 逻辑删除comment
刘基明's avatar
刘基明 committed
254
            CommentEntity commentEntity = commentService.delete(pop.getCommentId(), pop.getAuthorId());
255 256 257 258
            // 删除站内信
            ThemeEntity themeEntity = themeService.queryByThemeId(commentEntity.getThemeId());
            notificationService.deleteCommentNotify(themeEntity.getAuthorId(), userId, commentId, commentEntity.getCreateTime());
            // 递归
刘基明's avatar
刘基明 committed
259
            queue.addAll(commentService.queryReplyForComment(commentEntity.getCommentId()));
260
        }
261

刘基明's avatar
刘基明 committed
262
    }
刘基明's avatar
刘基明 committed
263

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