消息通知系统
This commit is contained in:
@@ -1024,7 +1024,7 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
|
||||
account.setIsTrial(1);
|
||||
account.setIsBeginner(1);
|
||||
account.setCreateDate(new Date());
|
||||
account.setCredits(BigDecimal.valueOf(500));
|
||||
account.setCredits(BigDecimal.valueOf(100));
|
||||
accountMapper.insert(account);
|
||||
AccountLoginVO response = CopyUtil.copyObject(account, AccountLoginVO.class);
|
||||
response.setEmail(account.getUserEmail());
|
||||
|
||||
@@ -744,7 +744,7 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
|
||||
redisUtil.addToString(key, new Gson().toJson(generateResultVO), CommonConstant.GENERATE_RESULT_EXPIRE_TIME);
|
||||
|
||||
Long accountId = Long.parseLong(taskId.substring(taskId.lastIndexOf("-") + 1));
|
||||
if (!status.equals("Invalid")){
|
||||
if (!status.equals("Invalid")) {
|
||||
// 4、扣除积分
|
||||
Boolean b = creditsService.taskCreditsDeduction(accountId, taskId);
|
||||
// 3、记录积分变更
|
||||
|
||||
@@ -0,0 +1,243 @@
|
||||
package com.ai.da.service.impl;
|
||||
|
||||
import com.ai.da.common.constant.CommonConstant;
|
||||
import com.ai.da.common.context.UserContext;
|
||||
import com.ai.da.common.response.PageBaseResponse;
|
||||
import com.ai.da.common.utils.CopyUtil;
|
||||
import com.ai.da.common.utils.MinioUtil;
|
||||
import com.ai.da.common.websocket.NotificationConnection;
|
||||
import com.ai.da.mapper.primary.NotificationMapper;
|
||||
import com.ai.da.mapper.primary.SysNotificationReadStatusMapper;
|
||||
import com.ai.da.mapper.primary.entity.Account;
|
||||
import com.ai.da.mapper.primary.entity.Notification;
|
||||
import com.ai.da.mapper.primary.entity.SysNotificationReadStatus;
|
||||
import com.ai.da.model.vo.GetNotificationVO;
|
||||
import com.ai.da.model.vo.NotificationVO;
|
||||
import com.ai.da.model.vo.PublishSysNotificationVO;
|
||||
import com.ai.da.service.AccountService;
|
||||
import com.ai.da.service.MessageCenterService;
|
||||
import com.ai.da.service.PortfolioService;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.google.gson.Gson;
|
||||
import com.mysql.cj.util.StringUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.IOException;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class MessageCenterServiceImpl extends ServiceImpl<NotificationMapper, Notification> implements MessageCenterService {
|
||||
|
||||
@Resource
|
||||
private NotificationConnection notificationConnection;
|
||||
@Resource
|
||||
private SysNotificationReadStatusMapper sysNotificationReadStatusMapper;
|
||||
@Resource
|
||||
private AccountService accountService;
|
||||
@Resource
|
||||
private MinioUtil minioUtil;
|
||||
@Resource
|
||||
private PortfolioService portfolioService;
|
||||
|
||||
|
||||
@Override
|
||||
public Map<String, Long> getAllTypeMessageUnreadCount() {
|
||||
List<Map<String, Object>> typeCount = baseMapper.getTypeCount(UserContext.getUserHolder().getId());
|
||||
Map<String, Long> msgTypeCount = typeCount.stream()
|
||||
.collect(Collectors.toMap(
|
||||
map -> (String) map.get("type"),
|
||||
map -> Objects.isNull(map.get("count")) ? 0L : (Long) map.get("count")));
|
||||
msgTypeCount.put("system", getUnreadSystemNotification());
|
||||
log.info(msgTypeCount.toString());
|
||||
// 整理数据 加上系统消息未读数
|
||||
return msgTypeCount;
|
||||
}
|
||||
|
||||
|
||||
// 获取历史消息 可指定消息类型 分页查询
|
||||
@Override
|
||||
public PageBaseResponse<NotificationVO> getHistoryNotification(GetNotificationVO getNotificationVO) {
|
||||
QueryWrapper<Notification> queryWrapper = new QueryWrapper<>();
|
||||
if (!StringUtils.isNullOrEmpty(getNotificationVO.getType())) {
|
||||
queryWrapper.eq("type", getNotificationVO.getType());
|
||||
}
|
||||
queryWrapper.eq("receiver_id", UserContext.getUserHolder().getId());
|
||||
Page<Notification> notificationPage = baseMapper.selectPage(new Page<>(getNotificationVO.getPage(), getNotificationVO.getSize()), queryWrapper);
|
||||
IPage<NotificationVO> convert = notificationPage.convert(o -> {
|
||||
NotificationVO notificationVO = CopyUtil.copyObject(o, NotificationVO.class);
|
||||
Account account = accountService.getById(notificationVO.getSenderId());
|
||||
notificationVO.setSenderUserName(account.getUserName());
|
||||
notificationVO.setSenderUserAvatar(StringUtils.isNullOrEmpty(account.getAvatar()) ? null : minioUtil.getPreSignedUrl(account.getAvatar(), CommonConstant.MINIO_IMAGE_EXPIRE_TIME));
|
||||
notificationVO.setPortfolioName(portfolioService.getById(notificationVO.getPortfolioId()).getPortfolioName());
|
||||
return notificationVO;
|
||||
});
|
||||
|
||||
return PageBaseResponse.success(convert);
|
||||
}
|
||||
|
||||
public void prePushMessage(Notification notification){
|
||||
// 先判断点赞、关注记录是不是唯一
|
||||
if (!getUniqueLikeAndFollow(notification)){
|
||||
// 1、将数据存数据库
|
||||
if (!notification.getType().equals("system")) {
|
||||
notification.setIsRead(0);
|
||||
}
|
||||
notification.setIsDeleted(0);
|
||||
notification.setCreateTime(LocalDateTime.now());
|
||||
save(notification);
|
||||
}
|
||||
// 推送消息
|
||||
pushMessage(notification.getType(), notification.getSenderId());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 只记录唯一点赞和关注
|
||||
* 重复点赞、关注只会记录最新的一次操作
|
||||
* @param notification
|
||||
* @return
|
||||
*/
|
||||
public Boolean getUniqueLikeAndFollow(Notification notification){
|
||||
Notification existNotification= null;
|
||||
// 对单个作品的点赞和对某个人的关注 具有唯一性
|
||||
if (notification.getType().equals("like") || notification.getType().equals("follow")){
|
||||
existNotification = baseMapper.getUniqueLikeAndFollow(notification.getType(), notification.getSenderId(),
|
||||
notification.getReceiverId(), notification.getPortfolioId());
|
||||
}
|
||||
|
||||
if (!Objects.isNull(existNotification)){
|
||||
// 有记录,则更新 1、删除状态 为0 2、已读状态 为0 3、创建时间 为最新时间 4、更新时间 为最新时间
|
||||
baseMapper.updateUniqueLikeAndFollow(existNotification.getId(), LocalDateTime.now());
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
|
||||
|
||||
// 消息推送 只需要返回当前操作类型和该操作未读消息数量
|
||||
public void pushMessage(String type, Long senderId) {
|
||||
// 推送消息到前端
|
||||
ArrayList<Map<String, Object>> resp = new ArrayList<>();
|
||||
HashMap<String, Object> data = new HashMap<>();
|
||||
Long count;
|
||||
if (!type.equals("system")) {
|
||||
// 个人未读消息
|
||||
count = getUnreadCountByType(type, senderId);
|
||||
} else {
|
||||
// 系统未读消息
|
||||
count = getUnreadSystemNotification();
|
||||
}
|
||||
|
||||
data.put(type, count);
|
||||
resp.add(data);
|
||||
String jsonString = JSON.toJSONString(resp);
|
||||
log.info("消息推送 : {}", jsonString);
|
||||
|
||||
try {
|
||||
notificationConnection.sendMsg(jsonString);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
// 取消点赞、删除评论、取消关注
|
||||
public void cancelPushMessage(String type, Long senderId, Long receiverId, Long portfolioId, Long commentId) {
|
||||
QueryWrapper<Notification> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("type", type)
|
||||
.eq("sender_id", senderId)
|
||||
.eq("receiver_id", receiverId)
|
||||
.eq("is_deleted", 0);
|
||||
|
||||
if (!type.equals("follow")){
|
||||
queryWrapper.eq("portfolio_id", portfolioId);
|
||||
}
|
||||
if (type.equals("comment")) {
|
||||
queryWrapper.eq("comment_id", commentId);
|
||||
}
|
||||
Notification notification = baseMapper.selectOne(queryWrapper);
|
||||
if (!Objects.isNull(notification)) {
|
||||
baseMapper.deleteNotification(notification.getId(), LocalDateTime.now());
|
||||
}
|
||||
// 推送消息
|
||||
pushMessage(type, senderId);
|
||||
}
|
||||
|
||||
// 获取个人指定消息类型未读消息数量
|
||||
private Long getUnreadCountByType(String type, Long receiverId) {
|
||||
QueryWrapper<Notification> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("type", type)
|
||||
.eq("is_read", 0)
|
||||
.eq("receiver_id", receiverId);
|
||||
|
||||
return baseMapper.selectCount(queryWrapper);
|
||||
}
|
||||
|
||||
private Long getUnreadSystemNotification() {
|
||||
// 计算总的系统通知数量
|
||||
QueryWrapper<Notification> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("type", "system");
|
||||
Long totalSysCount = baseMapper.selectCount(queryWrapper);
|
||||
|
||||
// 计算单个用户读了多少条系统数据
|
||||
QueryWrapper<SysNotificationReadStatus> wrapper = new QueryWrapper<>();
|
||||
wrapper.eq("account_id", UserContext.getUserHolder().getId());
|
||||
Long readCount = sysNotificationReadStatusMapper.selectCount(wrapper);
|
||||
|
||||
// 计算差
|
||||
return totalSysCount - readCount;
|
||||
}
|
||||
|
||||
// 设置个人消息的已读状态 (允许一次已读多条个人消息)
|
||||
public Boolean setReadStatus(List<Long> notificationIdList, String type) {
|
||||
|
||||
if (type.equals("system")) {
|
||||
setReadStatusSystem(notificationIdList);
|
||||
} else {
|
||||
UpdateWrapper<Notification> updateWrapper = new UpdateWrapper<>();
|
||||
updateWrapper.in("id", notificationIdList)
|
||||
// .eq("type", type)
|
||||
.set("is_read", 1)
|
||||
.set("update_time", LocalDateTime.now());
|
||||
|
||||
baseMapper.update(null, updateWrapper);
|
||||
}
|
||||
return Boolean.TRUE;
|
||||
|
||||
}
|
||||
|
||||
// 设置系统消息的已读状态 (允许一次已读多条系统消息)
|
||||
public void setReadStatusSystem(List<Long> notificationIdList) {
|
||||
Long id = UserContext.getUserHolder().getId();
|
||||
for (Long notificationId : notificationIdList) {
|
||||
SysNotificationReadStatus sysNotificationReadStatus = new SysNotificationReadStatus(notificationId, id);
|
||||
sysNotificationReadStatus.setCreateTime(LocalDateTime.now());
|
||||
sysNotificationReadStatusMapper.insert(sysNotificationReadStatus);
|
||||
}
|
||||
}
|
||||
|
||||
// todo 全部已读
|
||||
|
||||
// 发布系统消息
|
||||
public void publishSystemNotification(PublishSysNotificationVO message) {
|
||||
Notification notification = new Notification();
|
||||
notification.setType("system");
|
||||
notification.setSenderId(UserContext.getUserHolder().getId());
|
||||
notification.setContent(new Gson().toJson(message));
|
||||
// todo 是否需要定时发送系统通知
|
||||
prePushMessage(notification);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -25,7 +25,6 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import sun.security.krb5.internal.crypto.Des;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.math.BigDecimal;
|
||||
@@ -795,10 +794,16 @@ public class PortfolioServiceImpl extends ServiceImpl<PortfolioMapper, Portfolio
|
||||
|
||||
@Resource
|
||||
private RedisUtil redisUtil;
|
||||
|
||||
@Resource
|
||||
private MessageCenterService messageCenterService;
|
||||
|
||||
@Override
|
||||
public Boolean like(Long id) {
|
||||
AuthPrincipalVo userHolder = UserContext.getUserHolder();
|
||||
redisUtil.likePost(id, userHolder.getId());
|
||||
Portfolio byIdAll = baseMapper.getByIdAll(id);
|
||||
messageCenterService.prePushMessage(new Notification("like", userHolder.getId(), byIdAll.getAccountId(), id));
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
|
||||
@@ -811,6 +816,8 @@ public class PortfolioServiceImpl extends ServiceImpl<PortfolioMapper, Portfolio
|
||||
comment.setCreateTime(LocalDateTime.now());
|
||||
comment.setAccountId(userHolder.getId());
|
||||
commentMapper.insert(comment);
|
||||
Portfolio portfolio = baseMapper.selectById(comment.getPortfolioId());
|
||||
messageCenterService.prePushMessage(new Notification("comment", userHolder.getId(), portfolio.getAccountId(), portfolio.getId(), commentDTO.getComment(), comment.getId()));
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
|
||||
@@ -837,6 +844,8 @@ public class PortfolioServiceImpl extends ServiceImpl<PortfolioMapper, Portfolio
|
||||
public Boolean unlike(Long id) {
|
||||
AuthPrincipalVo userHolder = UserContext.getUserHolder();
|
||||
redisUtil.unLikePost(id, userHolder.getId());
|
||||
Portfolio portfolio = baseMapper.selectById(id);
|
||||
messageCenterService.cancelPushMessage("like", userHolder.getId(), portfolio.getAccountId(), portfolio.getId(), null);
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
|
||||
@@ -869,6 +878,15 @@ public class PortfolioServiceImpl extends ServiceImpl<PortfolioMapper, Portfolio
|
||||
throw new BusinessException("You do not have the permission to delete this comment");
|
||||
}
|
||||
}
|
||||
|
||||
// 获取消息接收者id(即该操作的接收者)
|
||||
Long receiverId;
|
||||
if (!comment.getParentLevel1Id().equals(0L)){
|
||||
receiverId = commentMapper.selectById(comment.getParentLevel1Id()).getAccountId();
|
||||
}else {
|
||||
receiverId = portfolio.getAccountId();
|
||||
}
|
||||
|
||||
// 删除主评论
|
||||
commentMapper.deleteById(id);
|
||||
|
||||
@@ -879,6 +897,7 @@ public class PortfolioServiceImpl extends ServiceImpl<PortfolioMapper, Portfolio
|
||||
.eq(Comment::getParentLevel2Id, id);
|
||||
commentMapper.delete(lambdaQueryWrapper);
|
||||
|
||||
messageCenterService.cancelPushMessage("comment", userHolder.getId(), receiverId, portfolio.getId(), id);
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user