mirror of
https://github.com/zongzibinbin/MallChat.git
synced 2026-03-13 21:53:41 +08:00
feat:消息标记重构
This commit is contained in:
@@ -1,19 +1,3 @@
|
||||
/*
|
||||
Navicat Premium Data Transfer
|
||||
|
||||
Source Server : mallchat
|
||||
Source Server Type : MySQL
|
||||
Source Server Version : 50741
|
||||
Source Host : 101.33.251.36:3306
|
||||
Source Schema : mallchat
|
||||
|
||||
Target Server Type : MySQL
|
||||
Target Server Version : 50741
|
||||
File Encoding : 65001
|
||||
|
||||
Date: 10/05/2023 14:25:59
|
||||
*/
|
||||
|
||||
SET NAMES utf8mb4;
|
||||
SET FOREIGN_KEY_CHECKS = 0;
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@
|
||||
<version>2.0.9</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<groupId>org.hibernate.validator</groupId>
|
||||
<artifactId>hibernate-validator</artifactId>
|
||||
<version>6.0.1.Final</version>
|
||||
</dependency>
|
||||
@@ -116,5 +116,14 @@
|
||||
<version>3.17.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
<version>2.4.3</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
|
||||
</build>
|
||||
</project>
|
||||
@@ -16,12 +16,22 @@ import lombok.NoArgsConstructor;
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class ChatMessageMarkDTO {
|
||||
|
||||
@ApiModelProperty("操作者")
|
||||
private Long uid;
|
||||
|
||||
@ApiModelProperty("消息id")
|
||||
private Long msgId;
|
||||
|
||||
/**
|
||||
* @see com.abin.mallchat.common.chat.domain.enums.MessageMarkTypeEnum
|
||||
*/
|
||||
@ApiModelProperty("标记类型 1点赞 2举报")
|
||||
private Integer markType;
|
||||
|
||||
/**
|
||||
* @see com.abin.mallchat.common.chat.domain.enums.MessageMarkActTypeEnum
|
||||
*/
|
||||
@ApiModelProperty("动作类型 1确认 2取消")
|
||||
private Integer actType;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.abin.mallchat.common.chat.domain.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Description: 消息标记动作类型
|
||||
* Author: <a href="https://github.com/zongzibinbin">abin</a>
|
||||
* Date: 2023-03-19
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public enum MessageMarkActTypeEnum {
|
||||
MARK(1, "确认标记"),
|
||||
UN_MARK(2, "取消标记"),
|
||||
;
|
||||
|
||||
private final Integer type;
|
||||
private final String desc;
|
||||
|
||||
private static Map<Integer, MessageMarkActTypeEnum> cache;
|
||||
|
||||
static {
|
||||
cache = Arrays.stream(MessageMarkActTypeEnum.values()).collect(Collectors.toMap(MessageMarkActTypeEnum::getType, Function.identity()));
|
||||
}
|
||||
|
||||
public static MessageMarkActTypeEnum of(Integer type) {
|
||||
return cache.get(type);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.abin.mallchat.common.common.domain.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Description: 是否正常的通用枚举
|
||||
* Author: <a href="https://github.com/zongzibinbin">abin</a>
|
||||
* Date: 2023-03-19
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public enum NormalOrNoEnum {
|
||||
NORMAL(0, "正常"),
|
||||
NOT_NORMAL(1, "不正常"),
|
||||
;
|
||||
|
||||
private final Integer status;
|
||||
private final String desc;
|
||||
|
||||
private static Map<Integer, NormalOrNoEnum> cache;
|
||||
|
||||
static {
|
||||
cache = Arrays.stream(NormalOrNoEnum.values()).collect(Collectors.toMap(NormalOrNoEnum::getStatus, Function.identity()));
|
||||
}
|
||||
|
||||
public static NormalOrNoEnum of(Integer type) {
|
||||
return cache.get(type);
|
||||
}
|
||||
|
||||
public static Integer toStatus(Boolean bool) {
|
||||
return bool ? NORMAL.getStatus() : NOT_NORMAL.getStatus();
|
||||
}
|
||||
}
|
||||
@@ -17,8 +17,8 @@ public enum CommonErrorEnum implements ErrorEnum {
|
||||
FREQUENCY_LIMIT(-3, "请求太频繁了,请稍后再试哦~~"),
|
||||
LOCK_LIMIT(-4, "请求太频繁了,请稍后再试哦~~"),
|
||||
;
|
||||
private Integer code;
|
||||
private String msg;
|
||||
private final Integer code;
|
||||
private final String msg;
|
||||
|
||||
@Override
|
||||
public Integer getErrorCode() {
|
||||
|
||||
@@ -2,10 +2,7 @@ package com.abin.mallchat.common.common.factory;
|
||||
|
||||
import com.abin.mallchat.common.common.handler.GlobalUncaughtExceptionHandler;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.scheduling.concurrent.CustomizableThreadFactory;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
|
||||
@@ -13,14 +10,12 @@ import java.util.concurrent.ThreadFactory;
|
||||
@AllArgsConstructor
|
||||
public class MyThreadFactory implements ThreadFactory {
|
||||
|
||||
private ThreadFactory factory;
|
||||
private final ThreadFactory factory;
|
||||
|
||||
@Override
|
||||
public Thread newThread(Runnable r) {
|
||||
Thread thread =factory.newThread(r);
|
||||
thread.setUncaughtExceptionHandler(new GlobalUncaughtExceptionHandler());
|
||||
thread.setDaemon(false);
|
||||
thread.setPriority(5);
|
||||
return thread;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package com.abin.mallchat.common.common.handler;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
@@ -10,7 +8,7 @@ public class GlobalUncaughtExceptionHandler implements Thread.UncaughtException
|
||||
|
||||
@Override
|
||||
public void uncaughtException(Thread t, Throwable e) {
|
||||
log.error("{} task execute is error",t.getName());
|
||||
log.error("Exception in thread {} ", t.getName(), e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ public class ChatController {
|
||||
return userCache.getBlackMap().getOrDefault(BlackTypeEnum.UID.getType(), new HashSet<>());
|
||||
}
|
||||
|
||||
@GetMapping("public/member/statistic/")
|
||||
@GetMapping("public/member/statistic")
|
||||
@ApiOperation("群成员人数统计")
|
||||
public ApiResult<ChatMemberStatisticResp> getMemberStatistic() {
|
||||
return ApiResult.success(chatService.getMemberStatistic());
|
||||
|
||||
@@ -20,5 +20,6 @@ public class ChatMemberStatisticResp {
|
||||
@ApiModelProperty("在线人数")
|
||||
private Long onlineNum;//在线人数
|
||||
@ApiModelProperty("总人数")
|
||||
@Deprecated
|
||||
private Long totalNum;//总人数
|
||||
}
|
||||
|
||||
@@ -6,15 +6,14 @@ import cn.hutool.core.lang.Pair;
|
||||
import com.abin.mallchat.common.chat.dao.MessageDao;
|
||||
import com.abin.mallchat.common.chat.dao.MessageMarkDao;
|
||||
import com.abin.mallchat.common.chat.dao.RoomDao;
|
||||
import com.abin.mallchat.common.chat.domain.dto.ChatMessageMarkDTO;
|
||||
import com.abin.mallchat.common.chat.domain.entity.Message;
|
||||
import com.abin.mallchat.common.chat.domain.entity.MessageMark;
|
||||
import com.abin.mallchat.common.chat.domain.entity.Room;
|
||||
import com.abin.mallchat.common.chat.domain.enums.MessageMarkActTypeEnum;
|
||||
import com.abin.mallchat.common.common.annotation.RedissonLock;
|
||||
import com.abin.mallchat.common.common.domain.enums.YesOrNoEnum;
|
||||
import com.abin.mallchat.common.common.domain.vo.request.CursorPageBaseReq;
|
||||
import com.abin.mallchat.common.common.domain.vo.response.CursorPageBaseResp;
|
||||
import com.abin.mallchat.common.common.event.MessageMarkEvent;
|
||||
import com.abin.mallchat.common.common.event.MessageSendEvent;
|
||||
import com.abin.mallchat.common.common.exception.BusinessException;
|
||||
import com.abin.mallchat.common.common.utils.AssertUtil;
|
||||
@@ -36,8 +35,9 @@ import com.abin.mallchat.custom.chat.service.adapter.MemberAdapter;
|
||||
import com.abin.mallchat.custom.chat.service.adapter.MessageAdapter;
|
||||
import com.abin.mallchat.custom.chat.service.adapter.RoomAdapter;
|
||||
import com.abin.mallchat.custom.chat.service.helper.ChatMemberHelper;
|
||||
import com.abin.mallchat.custom.chat.service.strategy.mark.AbstractMsgMarkStrategy;
|
||||
import com.abin.mallchat.custom.chat.service.strategy.mark.MsgMarkFactory;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -165,38 +165,25 @@ public class ChatServiceImpl implements ChatService {
|
||||
public ChatMemberStatisticResp getMemberStatistic() {
|
||||
System.out.println(Thread.currentThread().getName());
|
||||
Long onlineNum = userCache.getOnlineNum();
|
||||
Long offlineNum = userCache.getOfflineNum();
|
||||
// Long offlineNum = userCache.getOfflineNum();不展示总人数
|
||||
ChatMemberStatisticResp resp = new ChatMemberStatisticResp();
|
||||
resp.setOnlineNum(onlineNum);
|
||||
resp.setTotalNum(onlineNum + offlineNum);
|
||||
// resp.setTotalNum(onlineNum + offlineNum);
|
||||
return resp;
|
||||
}
|
||||
|
||||
@Override
|
||||
@RedissonLock(key = "#uid")
|
||||
public void setMsgMark(Long uid, ChatMessageMarkReq request) {
|
||||
//用户对该消息的标记
|
||||
MessageMark messageMark = messageMarkDao.get(uid, request.getMsgId(), request.getMarkType());
|
||||
if (Objects.nonNull(messageMark)) {//有标记过消息修改一下就好
|
||||
MessageMark update = MessageMark.builder()
|
||||
.id(messageMark.getId())
|
||||
.status(transformAct(request.getActType()))
|
||||
.build();
|
||||
messageMarkDao.updateById(update);
|
||||
return;
|
||||
AbstractMsgMarkStrategy strategy = MsgMarkFactory.getStrategyNoNull(request.getMarkType());
|
||||
switch (MessageMarkActTypeEnum.of(request.getActType())) {
|
||||
case MARK:
|
||||
strategy.mark(uid, request.getMsgId());
|
||||
break;
|
||||
case UN_MARK:
|
||||
strategy.unMark(uid, request.getMsgId());
|
||||
break;
|
||||
}
|
||||
//没标记过消息,插入一条新消息
|
||||
MessageMark insert = MessageMark.builder()
|
||||
.uid(uid)
|
||||
.msgId(request.getMsgId())
|
||||
.type(request.getMarkType())
|
||||
.status(transformAct(request.getActType()))
|
||||
.build();
|
||||
messageMarkDao.save(insert);
|
||||
//发布消息标记事件
|
||||
ChatMessageMarkDTO dto = new ChatMessageMarkDTO();
|
||||
BeanUtils.copyProperties(request, dto);
|
||||
applicationEventPublisher.publishEvent(new MessageMarkEvent(this, dto));
|
||||
}
|
||||
|
||||
private Integer transformAct(Integer actType) {
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
package com.abin.mallchat.custom.chat.service.strategy.mark;
|
||||
|
||||
import com.abin.mallchat.common.chat.dao.MessageMarkDao;
|
||||
import com.abin.mallchat.common.chat.domain.dto.ChatMessageMarkDTO;
|
||||
import com.abin.mallchat.common.chat.domain.entity.MessageMark;
|
||||
import com.abin.mallchat.common.chat.domain.enums.MessageMarkActTypeEnum;
|
||||
import com.abin.mallchat.common.chat.domain.enums.MessageMarkTypeEnum;
|
||||
import com.abin.mallchat.common.common.domain.enums.YesOrNoEnum;
|
||||
import com.abin.mallchat.common.common.event.MessageMarkEvent;
|
||||
import com.abin.mallchat.common.common.exception.BusinessException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Description: 消息标记抽象类
|
||||
* Author: <a href="https://github.com/zongzibinbin">abin</a>
|
||||
* Date: 2023-05-30
|
||||
*/
|
||||
public abstract class AbstractMsgMarkStrategy {
|
||||
@Autowired
|
||||
private MessageMarkDao messageMarkDao;
|
||||
@Autowired
|
||||
private ApplicationEventPublisher applicationEventPublisher;
|
||||
|
||||
protected abstract MessageMarkTypeEnum getTypeEnum();
|
||||
|
||||
@Transactional
|
||||
public void mark(Long uid, Long msgId) {
|
||||
exec(uid, msgId, MessageMarkActTypeEnum.MARK);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void unMark(Long uid, Long msgId) {
|
||||
exec(uid, msgId, MessageMarkActTypeEnum.UN_MARK);
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
private void init() {
|
||||
MsgMarkFactory.register(getTypeEnum().getType(), this);
|
||||
}
|
||||
|
||||
protected void exec(Long uid, Long msgId, MessageMarkActTypeEnum actTypeEnum) {
|
||||
Integer markType = getTypeEnum().getType();
|
||||
Integer actType = actTypeEnum.getType();
|
||||
MessageMark oldMark = messageMarkDao.get(uid, msgId, markType);
|
||||
if (Objects.isNull(oldMark) && actTypeEnum == MessageMarkActTypeEnum.UN_MARK) {
|
||||
//取消的类型,数据库一定有记录,没有就直接跳过操作
|
||||
return;
|
||||
}
|
||||
//插入一条新消息,或者修改一条消息
|
||||
MessageMark insertOrUpdate = MessageMark.builder()
|
||||
.id(Optional.ofNullable(oldMark).map(MessageMark::getId).orElse(null))
|
||||
.uid(uid)
|
||||
.msgId(msgId)
|
||||
.type(markType)
|
||||
.status(transformAct(actType))
|
||||
.build();
|
||||
boolean modify = messageMarkDao.saveOrUpdate(insertOrUpdate);
|
||||
if (modify) {
|
||||
//修改成功才发布消息标记事件
|
||||
ChatMessageMarkDTO dto = new ChatMessageMarkDTO(uid, msgId, markType, actType);
|
||||
applicationEventPublisher.publishEvent(new MessageMarkEvent(this, dto));
|
||||
}
|
||||
}
|
||||
|
||||
private Integer transformAct(Integer actType) {
|
||||
if (actType == 1) {
|
||||
return YesOrNoEnum.NO.getStatus();
|
||||
} else if (actType == 2) {
|
||||
return YesOrNoEnum.YES.getStatus();
|
||||
}
|
||||
throw new BusinessException("动作类型 1确认 2取消");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.abin.mallchat.custom.chat.service.strategy.mark;
|
||||
|
||||
import com.abin.mallchat.common.chat.domain.enums.MessageMarkTypeEnum;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* Description: 点踩标记策略类
|
||||
* Author: <a href="https://github.com/zongzibinbin">abin</a>
|
||||
* Date: 2023-05-30
|
||||
*/
|
||||
@Component
|
||||
public class DisLikeStrategy extends AbstractMsgMarkStrategy {
|
||||
@Autowired
|
||||
@Lazy
|
||||
private LikeStrategy likeStrategy;
|
||||
|
||||
@Override
|
||||
protected MessageMarkTypeEnum getTypeEnum() {
|
||||
return MessageMarkTypeEnum.DISLIKE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mark(Long uid, Long msgId) {
|
||||
super.mark(uid, msgId);
|
||||
//同时取消点赞的动作
|
||||
MsgMarkFactory.getStrategyNoNull(MessageMarkTypeEnum.LIKE.getType()).unMark(uid, msgId);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.abin.mallchat.custom.chat.service.strategy.mark;
|
||||
|
||||
import com.abin.mallchat.common.chat.domain.enums.MessageMarkTypeEnum;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* Description: 点赞标记策略类
|
||||
* Author: <a href="https://github.com/zongzibinbin">abin</a>
|
||||
* Date: 2023-05-30
|
||||
*/
|
||||
@Component
|
||||
public class LikeStrategy extends AbstractMsgMarkStrategy {
|
||||
|
||||
@Override
|
||||
protected MessageMarkTypeEnum getTypeEnum() {
|
||||
return MessageMarkTypeEnum.LIKE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mark(Long uid, Long msgId) {
|
||||
super.mark(uid, msgId);
|
||||
//同时取消点踩的动作
|
||||
MsgMarkFactory.getStrategyNoNull(MessageMarkTypeEnum.DISLIKE.getType()).unMark(uid, msgId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.abin.mallchat.custom.chat.service.strategy.mark;
|
||||
|
||||
import com.abin.mallchat.common.common.exception.CommonErrorEnum;
|
||||
import com.abin.mallchat.common.common.utils.AssertUtil;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Description: 消息标记策略工厂
|
||||
* Author: <a href="https://github.com/zongzibinbin">abin</a>
|
||||
* Date: 2023-05-30
|
||||
*/
|
||||
public class MsgMarkFactory {
|
||||
private static final Map<Integer, AbstractMsgMarkStrategy> STRATEGY_MAP = new HashMap<>();
|
||||
|
||||
public static void register(Integer markType, AbstractMsgMarkStrategy strategy) {
|
||||
STRATEGY_MAP.put(markType, strategy);
|
||||
}
|
||||
|
||||
public static AbstractMsgMarkStrategy getStrategyNoNull(Integer markType) {
|
||||
AbstractMsgMarkStrategy strategy = STRATEGY_MAP.get(markType);
|
||||
AssertUtil.isNotEmpty(strategy, CommonErrorEnum.PARAM_VALID);
|
||||
return strategy;
|
||||
}
|
||||
}
|
||||
@@ -10,11 +10,13 @@ import com.abin.mallchat.common.common.domain.enums.IdempotentEnum;
|
||||
import com.abin.mallchat.common.common.event.MessageMarkEvent;
|
||||
import com.abin.mallchat.common.user.domain.enums.ItemEnum;
|
||||
import com.abin.mallchat.common.user.service.IUserBackpackService;
|
||||
import com.abin.mallchat.custom.user.service.WebSocketService;
|
||||
import com.abin.mallchat.custom.user.service.adapter.WSAdapter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.event.TransactionalEventListener;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@@ -32,9 +34,11 @@ public class MessageMarkListener {
|
||||
private MessageDao messageDao;
|
||||
@Autowired
|
||||
private IUserBackpackService iUserBackpackService;
|
||||
@Autowired
|
||||
private WebSocketService webSocketService;
|
||||
|
||||
@Async
|
||||
@EventListener(classes = MessageMarkEvent.class)
|
||||
@TransactionalEventListener(classes = MessageMarkEvent.class, fallbackExecution = true)
|
||||
public void changeMsgType(MessageMarkEvent event) {
|
||||
ChatMessageMarkDTO dto = event.getDto();
|
||||
Message msg = messageDao.getById(dto.getMsgId());
|
||||
@@ -53,4 +57,12 @@ public class MessageMarkListener {
|
||||
}
|
||||
}
|
||||
|
||||
@Async
|
||||
@TransactionalEventListener(classes = MessageMarkEvent.class, fallbackExecution = true)
|
||||
public void notifyAll(MessageMarkEvent event) {//后续可做合并查询,目前异步影响不大
|
||||
ChatMessageMarkDTO dto = event.getDto();
|
||||
Integer markCount = messageMarkDao.getMarkCount(dto.getMsgId(), dto.getMarkType());
|
||||
webSocketService.sendToAllOnline(WSAdapter.buildMsgMarkSend(dto, markCount), dto.getUid());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,9 +9,9 @@ import com.abin.mallchat.custom.user.service.WebSocketService;
|
||||
import com.abin.mallchat.custom.user.service.adapter.WSAdapter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.event.TransactionalEventListener;
|
||||
|
||||
/**
|
||||
* 消息发送监听器
|
||||
@@ -29,7 +29,7 @@ public class MessageSendListener {
|
||||
private MessageDao messageDao;
|
||||
|
||||
@Async
|
||||
@EventListener(classes = MessageSendEvent.class)
|
||||
@TransactionalEventListener(classes = MessageSendEvent.class, fallbackExecution = true)
|
||||
public void notifyAllOnline(MessageSendEvent event) {
|
||||
Message message = messageDao.getById(event.getMsgId());
|
||||
ChatMessageResp msgResp = chatService.getMsgResp(message, null);
|
||||
|
||||
@@ -38,7 +38,7 @@ public class UserOnlineListener {
|
||||
User user = event.getUser();
|
||||
userCache.online(user.getId(), user.getLastOptTime());
|
||||
//推送给所有在线用户,该用户登录成功
|
||||
webSocketService.sendToAllOnline(wsAdapter.buildOnlineNotifyResp(event.getUser()), null);
|
||||
webSocketService.sendToAllOnline(wsAdapter.buildOnlineNotifyResp(event.getUser()));
|
||||
}
|
||||
|
||||
@Async
|
||||
|
||||
@@ -33,16 +33,16 @@ public class UserRegisterListener {
|
||||
iUserBackpackService.acquireItem(user.getId(), ItemEnum.MODIFY_NAME_CARD.getId(), IdempotentEnum.UID, user.getId().toString());
|
||||
}
|
||||
|
||||
@Async
|
||||
@EventListener(classes = UserRegisterEvent.class)
|
||||
public void sendBadge(UserRegisterEvent event) {
|
||||
User user = event.getUser();
|
||||
int count = userDao.count();//todo 性能瓶颈,等注册用户多了直接删掉
|
||||
if (count <= 10) {
|
||||
iUserBackpackService.acquireItem(user.getId(), ItemEnum.REG_TOP10_BADGE.getId(), IdempotentEnum.UID, user.getId().toString());
|
||||
} else if (count <= 100) {
|
||||
iUserBackpackService.acquireItem(user.getId(), ItemEnum.REG_TOP100_BADGE.getId(), IdempotentEnum.UID, user.getId().toString());
|
||||
}
|
||||
}
|
||||
// @Async
|
||||
// @EventListener(classes = UserRegisterEvent.class)
|
||||
// public void sendBadge(UserRegisterEvent event) {
|
||||
// User user = event.getUser();
|
||||
// int count = userDao.count();// 性能瓶颈,等注册用户多了直接删掉
|
||||
// if (count <= 10) {
|
||||
// iUserBackpackService.acquireItem(user.getId(), ItemEnum.REG_TOP10_BADGE.getId(), IdempotentEnum.UID, user.getId().toString());
|
||||
// } else if (count <= 100) {
|
||||
// iUserBackpackService.acquireItem(user.getId(), ItemEnum.REG_TOP100_BADGE.getId(), IdempotentEnum.UID, user.getId().toString());
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ public enum WSRespTypeEnum {
|
||||
ONLINE_OFFLINE_NOTIFY(5, "上下线通知", WSOnlineOfflineNotify.class),
|
||||
INVALIDATE_TOKEN(6, "使前端的token失效,意味着前端需要重新登录", null),
|
||||
BLACK(7, "拉黑用户", WSBlack.class),
|
||||
MARK(8, "消息标记", WSMsgMark.class),
|
||||
;
|
||||
|
||||
private final Integer type;
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.abin.mallchat.custom.user.domain.vo.response.ws;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Description:
|
||||
* Author: <a href="https://github.com/zongzibinbin">abin</a>
|
||||
* Date: 2023-03-19
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class WSMsgMark {
|
||||
private List<WSMsgMarkItem> markList;
|
||||
|
||||
@Data
|
||||
public static class WSMsgMarkItem {
|
||||
@ApiModelProperty("操作者")
|
||||
private Long uid;
|
||||
@ApiModelProperty("消息id")
|
||||
private Long msgId;
|
||||
/**
|
||||
* @see com.abin.mallchat.common.chat.domain.enums.MessageMarkTypeEnum
|
||||
*/
|
||||
@ApiModelProperty("标记类型 1点赞 2举报")
|
||||
private Integer markType;
|
||||
@ApiModelProperty("被标记的数量")
|
||||
private Integer markCount;
|
||||
/**
|
||||
* @see com.abin.mallchat.common.chat.domain.enums.MessageMarkActTypeEnum
|
||||
*/
|
||||
@ApiModelProperty("动作类型 1确认 2取消")
|
||||
private Integer actType;
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@ import java.util.List;
|
||||
public class WSOnlineOfflineNotify {
|
||||
private List<ChatMemberResp> changeList = new ArrayList<>();//新的上下线用户
|
||||
private Long onlineNum;//在线人数
|
||||
@Deprecated
|
||||
private Long totalNum;//总人数
|
||||
|
||||
}
|
||||
|
||||
@@ -57,7 +57,14 @@ public interface WebSocketService {
|
||||
* @param wsBaseResp 发送的消息体
|
||||
* @param skipUid 需要跳过的人
|
||||
*/
|
||||
void sendToAllOnline(WSBaseResp wsBaseResp, Long skipUid);
|
||||
void sendToAllOnline(WSBaseResp<?> wsBaseResp, Long skipUid);
|
||||
|
||||
/**
|
||||
* 推动消息给所有在线的人
|
||||
*
|
||||
* @param wsBaseResp 发送的消息体
|
||||
*/
|
||||
void sendToAllOnline(WSBaseResp<?> wsBaseResp);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.abin.mallchat.custom.user.service.adapter;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import com.abin.mallchat.common.chat.domain.dto.ChatMessageMarkDTO;
|
||||
import com.abin.mallchat.common.user.domain.entity.User;
|
||||
import com.abin.mallchat.common.user.domain.enums.ChatActiveStatusEnum;
|
||||
import com.abin.mallchat.custom.chat.domain.vo.response.ChatMemberResp;
|
||||
@@ -8,11 +9,9 @@ import com.abin.mallchat.custom.chat.domain.vo.response.ChatMemberStatisticResp;
|
||||
import com.abin.mallchat.custom.chat.domain.vo.response.ChatMessageResp;
|
||||
import com.abin.mallchat.custom.chat.service.ChatService;
|
||||
import com.abin.mallchat.custom.user.domain.enums.WSRespTypeEnum;
|
||||
import com.abin.mallchat.custom.user.domain.vo.response.ws.WSBaseResp;
|
||||
import com.abin.mallchat.custom.user.domain.vo.response.ws.WSLoginSuccess;
|
||||
import com.abin.mallchat.custom.user.domain.vo.response.ws.WSLoginUrl;
|
||||
import com.abin.mallchat.custom.user.domain.vo.response.ws.WSOnlineOfflineNotify;
|
||||
import com.abin.mallchat.custom.user.domain.vo.response.ws.*;
|
||||
import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@@ -110,4 +109,16 @@ public class WSAdapter {
|
||||
wsBaseResp.setData(msgResp);
|
||||
return wsBaseResp;
|
||||
}
|
||||
|
||||
public static WSBaseResp<WSMsgMark> buildMsgMarkSend(ChatMessageMarkDTO dto, Integer markCount) {
|
||||
WSMsgMark.WSMsgMarkItem item = new WSMsgMark.WSMsgMarkItem();
|
||||
BeanUtils.copyProperties(dto, item);
|
||||
item.setMarkCount(markCount);
|
||||
WSBaseResp<WSMsgMark> wsBaseResp = new WSBaseResp<>();
|
||||
wsBaseResp.setType(WSRespTypeEnum.MARK.getType());
|
||||
WSMsgMark mark = new WSMsgMark();
|
||||
mark.setMarkList(Collections.singletonList(item));
|
||||
wsBaseResp.setData(mark);
|
||||
return wsBaseResp;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -227,7 +227,7 @@ public class WebSocketServiceImpl implements WebSocketService {
|
||||
|
||||
//entrySet的值不是快照数据,但是它支持遍历,所以无所谓了,不用快照也行。
|
||||
@Override
|
||||
public void sendToAllOnline(WSBaseResp wsBaseResp, Long skipUid) {
|
||||
public void sendToAllOnline(WSBaseResp<?> wsBaseResp, Long skipUid) {
|
||||
ONLINE_WS_MAP.forEach((channel, ext) -> {
|
||||
if (ObjectUtil.equal(ext.getUid(), skipUid)) {
|
||||
return;
|
||||
@@ -236,7 +236,12 @@ public class WebSocketServiceImpl implements WebSocketService {
|
||||
});
|
||||
}
|
||||
|
||||
private void sendMsg(Channel channel, WSBaseResp wsBaseResp) {
|
||||
@Override
|
||||
public void sendToAllOnline(WSBaseResp<?> wsBaseResp) {
|
||||
sendToAllOnline(wsBaseResp, null);
|
||||
}
|
||||
|
||||
private void sendMsg(Channel channel, WSBaseResp<?> wsBaseResp) {
|
||||
channel.writeAndFlush(new TextWebSocketFrame(JSONUtil.toJsonStr(wsBaseResp)));
|
||||
}
|
||||
|
||||
|
||||
1
pom.xml
1
pom.xml
@@ -26,7 +26,6 @@
|
||||
<java.version>1.8</java.version>
|
||||
<skipTests>true</skipTests>
|
||||
<docker.host>http://192.168.3.101:2375</docker.host>
|
||||
<docker.maven.plugin.version>0.40.2</docker.maven.plugin.version>
|
||||
<hutool.version>5.8.18</hutool.version>
|
||||
<springfox-swagger.version>3.0.0</springfox-swagger.version>
|
||||
<swagger-models.version>1.6.0</swagger-models.version>
|
||||
|
||||
Reference in New Issue
Block a user