package com.tanpu.community.service; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.tanpu.common.api.CommonResp; import com.tanpu.common.exception.BizException; import com.tanpu.common.util.JsonUtil; import com.tanpu.common.uuid.UuidGenHelper; import com.tanpu.community.api.beans.vo.feign.fatools.UserInfoResp; import com.tanpu.community.api.constants.RedisKeyConstant; import com.tanpu.community.api.enums.DeleteTagEnum; import com.tanpu.community.api.enums.NotificationTypeEnum; import com.tanpu.community.cache.RedisCache; import com.tanpu.community.dao.entity.NotificationForwardDO; import com.tanpu.community.dao.entity.NotificationLikeDO; import com.tanpu.community.dao.entity.community.NotificationEntity; import com.tanpu.community.dao.mapper.community.NotificationMapper; import com.tanpu.community.feign.fatools.FeignClientForFatools; import com.tanpu.community.util.TimeUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.time.LocalDateTime; import java.util.Arrays; import java.util.List; @Service public class NotificationService { @Resource private NotificationMapper notificationMapper; @Autowired private UuidGenHelper uuidGenHelper; @Autowired private FeignClientForFatools feignClientForFatools; @Autowired private RedisCache redisCache; public void insert(String operatorId, String notifierId, NotificationTypeEnum type, String targetId, String content) { NotificationEntity entity = NotificationEntity.builder().operatorId(operatorId) .notificationId(uuidGenHelper.getUuidStr()) .notifiedUserId(notifierId) .messageType(type.getCode()) .content(content) .operatorId(operatorId) .targetId(targetId) .build(); insert(entity); } public void insert(String operatorId, String notifierId, NotificationTypeEnum type, String targetId, String content , LocalDateTime createTime) { NotificationEntity entity = NotificationEntity.builder().operatorId(operatorId) .notificationId(uuidGenHelper.getUuidStr()) .notifiedUserId(notifierId) .messageType(type.getCode()) .content(content) .operatorId(operatorId) .targetId(targetId) .createTime(createTime) .updateTime(createTime) .build(); insert(entity); } public void insertForward(String operatorId, String notifierId, String forwardThemeId, String topicId, String text, String themeId) { NotificationForwardDO forwardDO = NotificationForwardDO.builder().topicId(topicId).content(text).themeId(themeId).build(); NotificationEntity entity = NotificationEntity.builder().operatorId(operatorId) .notificationId(uuidGenHelper.getUuidStr()) .notifiedUserId(notifierId) .messageType(NotificationTypeEnum.FORWARD.getCode()) .content(JsonUtil.toJson(forwardDO)) .operatorId(operatorId) .targetId(forwardThemeId) .build(); insert(entity); } @Transactional public void insertLike(String operatorId, String notifierId, String targetId) { NotificationEntity entity = notificationMapper.selectOne(new LambdaQueryWrapper<NotificationEntity>() .eq(NotificationEntity::getMessageType, NotificationTypeEnum.LIKE.getCode()) .eq(NotificationEntity::getTargetId, targetId) .eq(NotificationEntity::getNotifiedUserId, notifierId)); if (entity != null) { NotificationLikeDO notificationLikeDO = JsonUtil.toBean(entity.getContent(), NotificationLikeDO.class); notificationLikeDO.addItem(operatorId); entity.setContent(JsonUtil.toJson(notificationLikeDO)); entity.setUpdateTime(LocalDateTime.now()); notificationMapper.updateById(entity); } else { NotificationLikeDO notificationLikeDO = new NotificationLikeDO(); notificationLikeDO.addItem(operatorId); NotificationEntity build = NotificationEntity.builder().operatorId(operatorId) .notificationId(uuidGenHelper.getUuidStr()) .messageType(NotificationTypeEnum.LIKE.getCode()) .notifiedUserId(notifierId) .content(JsonUtil.toJson(notificationLikeDO)) .targetId(targetId) .operatorId(operatorId) .build(); insert(build); } } @Transactional public void insertLikeComment(String operatorId, String notifierId, String targetId) { NotificationEntity entity = notificationMapper.selectOne(new LambdaQueryWrapper<NotificationEntity>() .eq(NotificationEntity::getMessageType, NotificationTypeEnum.COMMENT_LIKE.getCode()) .eq(NotificationEntity::getTargetId, targetId) .eq(NotificationEntity::getNotifiedUserId, notifierId)); if (entity != null) { NotificationLikeDO notificationLikeDO = JsonUtil.toBean(entity.getContent(), NotificationLikeDO.class); notificationLikeDO.addItem(operatorId); entity.setContent(JsonUtil.toJson(notificationLikeDO)); entity.setUpdateTime(LocalDateTime.now()); notificationMapper.updateById(entity); } else { NotificationLikeDO notificationLikeDO = new NotificationLikeDO(); notificationLikeDO.addItem(operatorId); NotificationEntity build = NotificationEntity.builder().operatorId(operatorId) .notificationId(uuidGenHelper.getUuidStr()) .messageType(NotificationTypeEnum.COMMENT_LIKE.getCode()) .notifiedUserId(notifierId) .content(JsonUtil.toJson(notificationLikeDO)) .targetId(targetId) .operatorId(operatorId) .build(); insert(build); } } @Transactional public void insert(NotificationEntity entity) { notificationMapper.insert(entity); } public NotificationEntity queryById(String notificationId) { return notificationMapper.selectOne(new LambdaQueryWrapper<NotificationEntity>() .eq(NotificationEntity::getNotificationId, notificationId)); } public List<NotificationEntity> query(String userId, Integer type, String lastId, Integer pageSize) { LambdaQueryWrapper<NotificationEntity> queryWrapper = new LambdaQueryWrapper<NotificationEntity>() .eq(NotificationEntity::getNotifiedUserId, userId) .orderByDesc(NotificationEntity::getUpdateTime) .last("limit " + pageSize); if (StringUtils.isNotBlank(lastId)) { NotificationEntity lastOne = notificationMapper.selectOne(new LambdaQueryWrapper<NotificationEntity>() .eq(NotificationEntity::getNotificationId, lastId)); queryWrapper.lt(NotificationEntity::getUpdateTime, lastOne.getCreateTime()); } if (!NotificationTypeEnum.ALL.getCode().equals(type) && !NotificationTypeEnum.LIKE.getCode().equals(type)) { queryWrapper.eq(NotificationEntity::getMessageType, type); } else if (NotificationTypeEnum.LIKE.getCode().equals(type)) { // 类型2点赞返回评论点赞和主题点赞 queryWrapper.in(NotificationEntity::getMessageType, Arrays.asList(NotificationTypeEnum.LIKE.getCode(), NotificationTypeEnum.COMMENT_LIKE.getCode())); } return notificationMapper.selectList(queryWrapper); } public void truncate() { notificationMapper.delete(new LambdaQueryWrapper<NotificationEntity>() .eq(NotificationEntity::getDeleteTag, DeleteTagEnum.NOT_DELETED.getCode())); } public void insertLike(String operatorId, String notifierId, String targetId, LocalDateTime updateTime) { NotificationEntity entity = notificationMapper.selectOne(new LambdaQueryWrapper<NotificationEntity>() .eq(NotificationEntity::getMessageType, NotificationTypeEnum.LIKE.getCode()) .eq(NotificationEntity::getTargetId, targetId) .eq(NotificationEntity::getNotifiedUserId, notifierId)); if (entity != null) { NotificationLikeDO notificationLikeDO = JsonUtil.toBean(entity.getContent(), NotificationLikeDO.class); notificationLikeDO.addItem(operatorId); entity.setContent(JsonUtil.toJson(notificationLikeDO)); entity.setUpdateTime(updateTime); notificationMapper.updateById(entity); } else { NotificationLikeDO notificationLikeDO = new NotificationLikeDO(); notificationLikeDO.addItem(operatorId); NotificationEntity build = NotificationEntity.builder().operatorId(operatorId) .notificationId(uuidGenHelper.getUuidStr()) .messageType(NotificationTypeEnum.LIKE.getCode()) .notifiedUserId(notifierId) .content(JsonUtil.toJson(notificationLikeDO)) .targetId(targetId) .operatorId(operatorId) .createTime(updateTime) .updateTime(updateTime) .build(); insert(build); } } // 消息通知队列缓存 public void putNotifyCache(String notifyUserId, String operatorId, NotificationTypeEnum type) { UserInfoResp userInfo = getUserInfo(operatorId); redisCache.incr(RedisKeyConstant.MESSAGE_NOTIFY_COUNT + notifyUserId); redisCache.set(RedisKeyConstant.MESSAGE_NOTIFY_LAST_TIME + notifyUserId, TimeUtils.format(LocalDateTime.now()), 60 * 60 * 24 * 30); if (NotificationTypeEnum.COMMENT_LIKE.equals(type)) { redisCache.set(RedisKeyConstant.MESSAGE_NOTIFY_LAST_MSG + notifyUserId, userInfo.getNickName() + "点赞了你的评论", 60 * 60 * 24 * 30); } else if (NotificationTypeEnum.FOLLOW.equals(type)) { redisCache.set(RedisKeyConstant.MESSAGE_NOTIFY_LAST_MSG + notifyUserId, userInfo.getNickName() + "关注了你", 60 * 60 * 24 * 30); } else { redisCache.set(RedisKeyConstant.MESSAGE_NOTIFY_LAST_MSG + notifyUserId, userInfo.getNickName() + type.getType() + "了你的内容", 60 * 60 * 24 * 30); } } // 删除评论通知及缓存,并更新 public void deleteCommentNotify(String notifyUserId, String operatorId, String commentId, LocalDateTime commentTime) { // 物理删除 NotificationEntity commentNotify = notificationMapper.selectOne(new LambdaQueryWrapper<NotificationEntity>() .eq(NotificationEntity::getTargetId, commentId) .eq(NotificationEntity::getOperatorId, operatorId) .eq(NotificationEntity::getNotifiedUserId, notifyUserId) .eq(NotificationEntity::getMessageType, NotificationTypeEnum.COMMENT.getCode())); NotificationEntity last = notificationMapper.selectOne(new LambdaQueryWrapper<NotificationEntity>().eq(NotificationEntity::getNotifiedUserId, notifyUserId) .orderByDesc(NotificationEntity::getUpdateTime) .last("limit 1")); if (commentNotify==null || last==null){ return; } notificationMapper.deleteById(commentNotify.getId()); // 如果删除的评论是最後一條通知,则需要从库中再找一条最新的 if (last.getNotificationId().equals(commentNotify.getNotificationId())) { last = notificationMapper.selectOne(new LambdaQueryWrapper<NotificationEntity>().eq(NotificationEntity::getNotifiedUserId, notifyUserId) .orderByDesc(NotificationEntity::getUpdateTime) .last("limit 1")); if (last == null) { // 没有其他通知,置空 redisCache.evict(RedisKeyConstant.MESSAGE_NOTIFY_LAST_MSG + notifyUserId); redisCache.evict(RedisKeyConstant.MESSAGE_NOTIFY_LAST_TIME + notifyUserId); } else { // 有通知 UserInfoResp userInfo = getUserInfo(last.getOperatorId()); redisCache.set(RedisKeyConstant.MESSAGE_NOTIFY_LAST_TIME + notifyUserId, TimeUtils.format(last.getUpdateTime()), 60 * 60 * 24 * 30); if (NotificationTypeEnum.FOLLOW.getCode().equals(last.getMessageType())) { redisCache.set(RedisKeyConstant.MESSAGE_NOTIFY_LAST_MSG + notifyUserId, userInfo.getNickName() + "关注了你", 60 * 60 * 24 * 30); } else { redisCache.set(RedisKeyConstant.MESSAGE_NOTIFY_LAST_MSG + notifyUserId , userInfo.getNickName() + NotificationTypeEnum.lookup(last.getMessageType()) + "了你的内容" , 60 * 60 * 24 * 30); } } } // 处理更新数量 String lastTime = redisCache.get(RedisKeyConstant.MESSAGE_NOTIFY_QUERY_TIME + notifyUserId); LocalDateTime lastQueryTime = StringUtils.isNotBlank(lastTime) ? JsonUtil.toBean(lastTime, LocalDateTime.class) : LocalDateTime.now(); // 如果删除的评论时时间在红点提示时间内,则缓存数-1 if (StringUtils.isBlank(lastTime) || TimeUtils.lessThan(lastQueryTime, commentTime)) { redisCache.decr(RedisKeyConstant.MESSAGE_NOTIFY_COUNT + notifyUserId); } } // init用 public void putNotifyCache(String notifyUserId, String operatorId, NotificationTypeEnum type, LocalDateTime updateTime) { UserInfoResp userInfo = getUserInfo(operatorId); redisCache.incr(RedisKeyConstant.MESSAGE_NOTIFY_COUNT + notifyUserId); String cacheTime = redisCache.get(RedisKeyConstant.MESSAGE_NOTIFY_LAST_TIME + notifyUserId); if (StringUtils.isBlank(cacheTime) || TimeUtils.lessThan(cacheTime, updateTime)) { redisCache.set(RedisKeyConstant.MESSAGE_NOTIFY_LAST_MSG + notifyUserId, userInfo.getNickName() + type.getType() + "了你的内容", 60 * 60 * 24 * 30); redisCache.set(RedisKeyConstant.MESSAGE_NOTIFY_LAST_TIME + notifyUserId, TimeUtils.format(updateTime), 60 * 60 * 24 * 30); } } // init用 public void putNotifyCacheFollow(String notifyUserId, String operatorId, LocalDateTime updateTime) { UserInfoResp userInfo = getUserInfo(operatorId); redisCache.incr(RedisKeyConstant.MESSAGE_NOTIFY_COUNT + notifyUserId); String cacheTime = redisCache.get(RedisKeyConstant.MESSAGE_NOTIFY_LAST_TIME + notifyUserId); if (StringUtils.isBlank(cacheTime) || TimeUtils.lessThan(cacheTime, updateTime)) { redisCache.set(RedisKeyConstant.MESSAGE_NOTIFY_LAST_MSG + notifyUserId, userInfo.getNickName() + "关注了你", 60 * 60 * 24 * 30); redisCache.set(RedisKeyConstant.MESSAGE_NOTIFY_LAST_TIME + notifyUserId, TimeUtils.format(updateTime), 60 * 60 * 24 * 30); } } public void deleteComment(String commentId) { } private UserInfoResp getUserInfo(String authorId) { CommonResp<UserInfoResp> userInfoNewCommonResp = feignClientForFatools.queryUserInfoNew(authorId); if (userInfoNewCommonResp.isNotSuccess()) { throw new BizException("内部接口调用失败"); } return userInfoNewCommonResp.getData(); } }