1.消息撤回功能
2.管理员拉黑功能
3.管理员撤回消息功能
4.消息类型可扩展
This commit is contained in:
zhongzb
2023-06-05 13:02:09 +08:00
parent cf5eb9f455
commit 44244c0ba2
60 changed files with 1182 additions and 74 deletions

View File

@@ -8,9 +8,11 @@ import com.abin.mallchat.common.common.domain.vo.response.CursorPageBaseResp;
import com.abin.mallchat.common.common.utils.RequestHolder;
import com.abin.mallchat.common.user.domain.enums.BlackTypeEnum;
import com.abin.mallchat.common.user.service.cache.UserCache;
import com.abin.mallchat.custom.chat.domain.vo.request.ChatMessageBaseReq;
import com.abin.mallchat.custom.chat.domain.vo.request.ChatMessageMarkReq;
import com.abin.mallchat.custom.chat.domain.vo.request.ChatMessagePageReq;
import com.abin.mallchat.custom.chat.domain.vo.request.ChatMessageReq;
import com.abin.mallchat.custom.chat.domain.vo.request.msg.TextMsgReq;
import com.abin.mallchat.custom.chat.domain.vo.response.ChatMemberResp;
import com.abin.mallchat.custom.chat.domain.vo.response.ChatMemberStatisticResp;
import com.abin.mallchat.custom.chat.domain.vo.response.ChatMessageResp;
@@ -23,6 +25,7 @@ import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
/**
@@ -89,6 +92,10 @@ public class ChatController {
@FrequencyControl(time = 30, count = 5, target = FrequencyControl.Target.UID)
@FrequencyControl(time = 60, count = 10, target = FrequencyControl.Target.UID)
public ApiResult<ChatMessageResp> sendMsg(@Valid @RequestBody ChatMessageReq request) {
if (Objects.isNull(request.getBody())) {
TextMsgReq req = new TextMsgReq(request.getContent(), request.getReplyMsgId());//todo 消息兼容之后删了
request.setBody(req);
}
Long msgId = chatService.sendMsg(request, RequestHolder.get().getUid());
//返回完整消息格式,方便前端展示
return ApiResult.success(chatService.getMsgResp(msgId, RequestHolder.get().getUid()));
@@ -100,7 +107,14 @@ public class ChatController {
public ApiResult<Void> setMsgMark(@Valid @RequestBody ChatMessageMarkReq request) {
chatService.setMsgMark(RequestHolder.get().getUid(), request);
return ApiResult.success();
}
@PutMapping("/msg/recall")
@ApiOperation("撤回消息")
@FrequencyControl(time = 20, count = 3, target = FrequencyControl.Target.UID)
public ApiResult<Void> recallMsg(@Valid @RequestBody ChatMessageBaseReq request) {
chatService.recallMsg(RequestHolder.get().getUid(), request);
return ApiResult.success();
}
}

View File

@@ -0,0 +1,29 @@
package com.abin.mallchat.custom.chat.domain.vo.request;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotNull;
/**
* Description: 消息基础请求体
* Author: <a href="https://github.com/zongzibinbin">abin</a>
* Date: 2023-03-23
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class ChatMessageBaseReq {
@NotNull
@ApiModelProperty("消息id")
private Long msgId;
@NotNull
@ApiModelProperty("会话id")
private Long roomId;
}

View File

@@ -1,11 +1,11 @@
package com.abin.mallchat.custom.chat.domain.vo.request;
import com.abin.mallchat.common.chat.domain.enums.MessageTypeEnum;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotNull;
@@ -20,16 +20,21 @@ import javax.validation.constraints.NotNull;
@AllArgsConstructor
@NoArgsConstructor
public class ChatMessageReq {
@NotNull
@Length(max = 10000, message = "消息内容过长服务器扛不住啊兄dei")
@ApiModelProperty("消息内容")
private String content;
@NotNull
@ApiModelProperty("会话id")
private Long roomId;
@ApiModelProperty("消息类型")
private Integer msgType = MessageTypeEnum.TEXT.getType();
@ApiModelProperty("消息内容类型不同传值不同见https://www.yuque.com/snab/mallcaht/rkb2uz5k1qqdmcmd")
private Object body;
@ApiModelProperty("消息内容")
@Deprecated
private String content;
@ApiModelProperty("回复的消息id,如果没有别传就好")
@Deprecated
private Long replyMsgId;
}

View File

@@ -0,0 +1,25 @@
package com.abin.mallchat.custom.chat.domain.vo.request.msg;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* Description: 文本消息入参
* Author: <a href="https://github.com/zongzibinbin">abin</a>
* Date: 2023-06-04
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class TextMsgReq {
@ApiModelProperty("消息内容")
private String content;
@ApiModelProperty("回复的消息id,如果没有别传就好")
private Long replyMsgId;
}

View File

@@ -45,12 +45,16 @@ public class ChatMessageResp {
private Long id;
@ApiModelProperty("消息发送时间")
private Date sendTime;
@ApiModelProperty("消息内容")
@ApiModelProperty("消息内容-废弃")
@Deprecated
private String content;
@ApiModelProperty("消息链接映射")
@ApiModelProperty("消息链接映射-废弃")
@Deprecated
private Map<String, String> urlTitleMap;
@ApiModelProperty("消息类型 1正常文本 2.爆赞 点赞超过103.危险发言举报超5")
@ApiModelProperty("消息类型 1正常文本 2.撤回消息")
private Integer type;
@ApiModelProperty("消息内容不同的消息类型内容体不同见https://www.yuque.com/snab/mallcaht/rkb2uz5k1qqdmcmd")
private Object body;
@ApiModelProperty("消息标记")
private MessageMark messageMark;
@ApiModelProperty("父消息如果没有父消息返回的是null")
@@ -59,6 +63,7 @@ public class ChatMessageResp {
}
@Data
@Deprecated
public static class ReplyMsg {
@ApiModelProperty("消息id")
private Long id;

View File

@@ -0,0 +1,48 @@
package com.abin.mallchat.custom.chat.domain.vo.response.msg;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Map;
/**
* Description: 文本消息返回体
* Author: <a href="https://github.com/zongzibinbin">abin</a>
* Date: 2023-06-04
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class TextMsgResp {
@ApiModelProperty("消息内容")
private String content;
@ApiModelProperty("消息链接映射")
private Map<String, String> urlTitleMap;
@ApiModelProperty("父消息如果没有父消息返回的是null")
private TextMsgResp.ReplyMsg reply;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public static class ReplyMsg {
@ApiModelProperty("消息id")
private Long id;
@ApiModelProperty("用户uid")
private Long uid;
@ApiModelProperty("用户名称")
private String username;
@ApiModelProperty("消息类型 1正常文本 2.撤回消息")
private Integer type;
@ApiModelProperty("消息内容不同的消息类型,见父消息内容体")
private Object body;
@ApiModelProperty("是否可消息跳转 0否 1是")
private Integer canCallback;
@ApiModelProperty("跳转间隔的消息条数")
private Integer gapCount;
}
}

View File

@@ -3,6 +3,7 @@ package com.abin.mallchat.custom.chat.service;
import com.abin.mallchat.common.chat.domain.entity.Message;
import com.abin.mallchat.common.common.domain.vo.request.CursorPageBaseReq;
import com.abin.mallchat.common.common.domain.vo.response.CursorPageBaseResp;
import com.abin.mallchat.custom.chat.domain.vo.request.ChatMessageBaseReq;
import com.abin.mallchat.custom.chat.domain.vo.request.ChatMessageMarkReq;
import com.abin.mallchat.custom.chat.domain.vo.request.ChatMessagePageReq;
import com.abin.mallchat.custom.chat.domain.vo.request.ChatMessageReq;
@@ -73,4 +74,6 @@ public interface ChatService {
ChatMemberStatisticResp getMemberStatistic();
void setMsgMark(Long uid, ChatMessageMarkReq request);
void recallMsg(Long uid, ChatMessageBaseReq request);
}

View File

@@ -2,8 +2,8 @@ package com.abin.mallchat.custom.chat.service.adapter;
import cn.hutool.core.bean.BeanUtil;
import com.abin.mallchat.common.chat.domain.entity.Message;
import com.abin.mallchat.common.chat.domain.entity.MessageExtra;
import com.abin.mallchat.common.chat.domain.entity.MessageMark;
import com.abin.mallchat.common.chat.domain.entity.msg.MessageExtra;
import com.abin.mallchat.common.chat.domain.enums.MessageMarkTypeEnum;
import com.abin.mallchat.common.chat.domain.enums.MessageStatusEnum;
import com.abin.mallchat.common.common.domain.enums.YesOrNoEnum;
@@ -14,6 +14,8 @@ import com.abin.mallchat.common.user.domain.entity.ItemConfig;
import com.abin.mallchat.common.user.domain.entity.User;
import com.abin.mallchat.custom.chat.domain.vo.request.ChatMessageReq;
import com.abin.mallchat.custom.chat.domain.vo.response.ChatMessageResp;
import com.abin.mallchat.custom.chat.service.strategy.msg.AbstractMsgHandler;
import com.abin.mallchat.custom.chat.service.strategy.msg.MsgHandlerFactory;
import java.util.*;
import java.util.stream.Collectors;
@@ -24,14 +26,12 @@ import java.util.stream.Collectors;
* Date: 2023-03-26
*/
public class MessageAdapter {
public static final int CAN_CALLBACK_GAP_COUNT = 50;
public static final int CAN_CALLBACK_GAP_COUNT = 100;
private static final PrioritizedUrlTitleDiscover URL_TITLE_DISCOVER = new PrioritizedUrlTitleDiscover();
public static Message buildMsgSave(ChatMessageReq request, Long uid) {
return Message.builder()
.replyMsgId(request.getReplyMsgId())
.content(request.getContent())
.fromUid(uid)
.roomId(request.getRoomId())
.status(MessageStatusEnum.NORMAL.getStatus())
@@ -61,8 +61,11 @@ public class MessageAdapter {
ChatMessageResp.Message messageVO = new ChatMessageResp.Message();
BeanUtil.copyProperties(message, messageVO);
messageVO.setSendTime(message.getCreateTime());
AbstractMsgHandler msgHandler = MsgHandlerFactory.getStrategyNoNull(message.getType());
messageVO.setBody(msgHandler.showMsg(message));
messageVO.setUrlTitleMap(Optional.ofNullable(message.getExtra()).map(MessageExtra::getUrlTitleMap).orElse(null));
Message replyMessage = replyMap.get(message.getReplyMsgId());
//回复消息
if (Objects.nonNull(replyMessage)) {
ChatMessageResp.ReplyMsg replyMsgVO = new ChatMessageResp.ReplyMsg();

View File

@@ -2,6 +2,8 @@ package com.abin.mallchat.custom.chat.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Pair;
import com.abin.mallchat.common.chat.dao.MessageDao;
import com.abin.mallchat.common.chat.dao.MessageMarkDao;
@@ -10,19 +12,21 @@ 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.chat.domain.enums.MessageTypeEnum;
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.MessageSendEvent;
import com.abin.mallchat.common.common.exception.BusinessException;
import com.abin.mallchat.common.common.utils.AssertUtil;
import com.abin.mallchat.common.user.dao.UserDao;
import com.abin.mallchat.common.user.domain.entity.ItemConfig;
import com.abin.mallchat.common.user.domain.entity.User;
import com.abin.mallchat.common.user.domain.enums.ChatActiveStatusEnum;
import com.abin.mallchat.common.user.domain.enums.RoleEnum;
import com.abin.mallchat.common.user.service.IRoleService;
import com.abin.mallchat.common.user.service.cache.ItemCache;
import com.abin.mallchat.common.user.service.cache.UserCache;
import com.abin.mallchat.custom.chat.domain.vo.request.ChatMessageBaseReq;
import com.abin.mallchat.custom.chat.domain.vo.request.ChatMessageMarkReq;
import com.abin.mallchat.custom.chat.domain.vo.request.ChatMessagePageReq;
import com.abin.mallchat.custom.chat.domain.vo.request.ChatMessageReq;
@@ -37,6 +41,9 @@ 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 com.abin.mallchat.custom.chat.service.strategy.msg.AbstractMsgHandler;
import com.abin.mallchat.custom.chat.service.strategy.msg.MsgHandlerFactory;
import com.abin.mallchat.custom.chat.service.strategy.msg.RecallMsgHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
@@ -73,6 +80,10 @@ public class ChatServiceImpl implements ChatService {
private MessageMarkDao messageMarkDao;
@Autowired
private ItemCache itemCache;
@Autowired
private IRoleService iRoleService;
@Autowired
private RecallMsgHandler recallMsgHandler;
/**
* 发送消息
@@ -80,22 +91,12 @@ public class ChatServiceImpl implements ChatService {
@Override
@Transactional
public Long sendMsg(ChatMessageReq request, Long uid) {
//校验下回复消息
Message replyMsg = null;
if (Objects.nonNull(request.getReplyMsgId())) {
replyMsg = messageDao.getById(request.getReplyMsgId());
AssertUtil.isNotEmpty(replyMsg, "回复消息不存在");
AssertUtil.equal(replyMsg.getRoomId(), request.getRoomId(), "只能回复相同会话内的消息");
}
AbstractMsgHandler msgHandler = MsgHandlerFactory.getStrategyNoNull(request.getMsgType());//todo 这里先不扩展,后续再改
msgHandler.checkMsg(request);
//同步获取消息的跳转链接标题
Message insert = MessageAdapter.buildMsgSave(request, uid);
messageDao.save(insert);
//如果有回复消息
if (Objects.nonNull(replyMsg)) {
Integer gapCount = messageDao.getGapCount(request.getRoomId(), replyMsg.getId(), insert.getId());
messageDao.updateGapCount(insert.getId(), gapCount);
}
msgHandler.saveMsg(insert, request);
//发布消息发送事件
applicationEventPublisher.publishEvent(new MessageSendEvent(this, insert.getId()));
return insert.getId();
@@ -186,13 +187,26 @@ public class ChatServiceImpl implements ChatService {
}
}
private Integer transformAct(Integer actType) {
if (actType == 1) {
return YesOrNoEnum.NO.getStatus();
} else if (actType == 2) {
return YesOrNoEnum.YES.getStatus();
@Override
public void recallMsg(Long uid, ChatMessageBaseReq request) {
Message message = messageDao.getById(request.getMsgId());
//校验能不能执行撤回
checkRecall(uid, message);
//执行消息撤回
recallMsgHandler.recall(uid, message);
}
private void checkRecall(Long uid, Message message) {
AssertUtil.isNotEmpty(message, "消息有误");
AssertUtil.notEqual(message.getType(), MessageTypeEnum.RECALL, "消息无法撤回");
boolean hasPower = iRoleService.hasPower(uid, RoleEnum.CHAT_MANAGER);
if (hasPower) {
return;
}
throw new BusinessException("动作类型 1确认 2取消");
boolean self = Objects.equals(uid, message.getFromUid());
AssertUtil.isTrue(self, "抱歉,您没有权限");
long between = DateUtil.between(message.getCreateTime(), new Date(), DateUnit.MINUTE);
AssertUtil.isTrue(between < 2, "覆水难收超过2分钟的消息不能撤回哦~~");
}
public List<ChatMessageResp> getMsgRespBatch(List<Message> messages, Long receiveUid) {

View File

@@ -23,7 +23,7 @@ public class DisLikeStrategy extends AbstractMsgMarkStrategy {
@Override
public void doMark(Long uid, Long msgId) {
super.mark(uid, msgId);
super.doMark(uid, msgId);
//同时取消点赞的动作
MsgMarkFactory.getStrategyNoNull(MessageMarkTypeEnum.LIKE.getType()).unMark(uid, msgId);
}

View File

@@ -18,7 +18,7 @@ public class LikeStrategy extends AbstractMsgMarkStrategy {
@Override
public void doMark(Long uid, Long msgId) {
super.mark(uid, msgId);
super.doMark(uid, msgId);
//同时取消点踩的动作
MsgMarkFactory.getStrategyNoNull(MessageMarkTypeEnum.DISLIKE.getType()).unMark(uid, msgId);
}

View File

@@ -0,0 +1,31 @@
package com.abin.mallchat.custom.chat.service.strategy.msg;
import com.abin.mallchat.common.chat.domain.entity.Message;
import com.abin.mallchat.common.chat.domain.enums.MessageTypeEnum;
import com.abin.mallchat.custom.chat.domain.vo.request.ChatMessageReq;
import javax.annotation.PostConstruct;
/**
* Description: 消息处理器抽象类
* Author: <a href="https://github.com/zongzibinbin">abin</a>
* Date: 2023-06-04
*/
public abstract class AbstractMsgHandler {
@PostConstruct
private void init() {
MsgHandlerFactory.register(getMsgTypeEnum().getType(), this);
}
abstract MessageTypeEnum getMsgTypeEnum();
public abstract void checkMsg(ChatMessageReq req);
public abstract void saveMsg(Message msg, ChatMessageReq req);
public abstract Object showMsg(Message msg);
public abstract Object showReplyMsg(Message msg);
}

View File

@@ -0,0 +1,11 @@
package com.abin.mallchat.custom.chat.service.strategy.msg;
import com.abin.mallchat.common.chat.domain.entity.Message;
public interface MsgHandler<RESP, REQ> {
void saveMsg(Message msg, REQ req);
RESP showMsg(Message msg);
}

View File

@@ -0,0 +1,26 @@
package com.abin.mallchat.custom.chat.service.strategy.msg;
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-06-04
*/
public class MsgHandlerFactory {
private static final Map<Integer, AbstractMsgHandler> STRATEGY_MAP = new HashMap<>();
public static void register(Integer code, AbstractMsgHandler strategy) {
STRATEGY_MAP.put(code, strategy);
}
public static AbstractMsgHandler getStrategyNoNull(Integer code) {
AbstractMsgHandler strategy = STRATEGY_MAP.get(code);
AssertUtil.isNotEmpty(strategy, CommonErrorEnum.PARAM_VALID);
return strategy;
}
}

View File

@@ -0,0 +1,79 @@
package com.abin.mallchat.custom.chat.service.strategy.msg;
import com.abin.mallchat.common.chat.dao.MessageDao;
import com.abin.mallchat.common.chat.domain.dto.ChatMsgRecallDTO;
import com.abin.mallchat.common.chat.domain.entity.Message;
import com.abin.mallchat.common.chat.domain.entity.msg.MessageExtra;
import com.abin.mallchat.common.chat.domain.entity.msg.MsgRecall;
import com.abin.mallchat.common.chat.domain.enums.MessageTypeEnum;
import com.abin.mallchat.common.chat.service.cache.MsgCache;
import com.abin.mallchat.common.common.event.MessageRecallEvent;
import com.abin.mallchat.common.user.domain.entity.User;
import com.abin.mallchat.common.user.service.cache.UserCache;
import com.abin.mallchat.custom.chat.domain.vo.request.ChatMessageReq;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.Objects;
/**
* Description: 撤回文本消息
* Author: <a href="https://github.com/zongzibinbin">abin</a>
* Date: 2023-06-04
*/
@Component
public class RecallMsgHandler extends AbstractMsgHandler {
@Autowired
private MessageDao messageDao;
@Autowired
private UserCache userCache;
@Autowired
private MsgCache msgCache;
@Autowired
private ApplicationEventPublisher applicationEventPublisher;
@Override
MessageTypeEnum getMsgTypeEnum() {
return MessageTypeEnum.RECALL;
}
@Override
public void checkMsg(ChatMessageReq request) {
throw new UnsupportedOperationException();
}
@Override
public void saveMsg(Message msg, ChatMessageReq request) {
throw new UnsupportedOperationException();
}
@Override
public Object showMsg(Message msg) {//todo 后期让前端来做
MsgRecall recall = msg.getExtra().getRecall();
if (!Objects.equals(recall.getRecallUid(), msg.getFromUid())) {
User userInfo = userCache.getUserInfo(recall.getRecallUid());
return "管理员\"" + userInfo.getName() + "\"撤回了一条成员消息";
}
User userInfo = userCache.getUserInfo(msg.getFromUid());
return "\"" + userInfo.getName() + "\"撤回了一条消息";
}
@Override
public Object showReplyMsg(Message msg) {
return "原消息已被撤回";
}
public void recall(Long recallUid, Message message) {//todo 消息覆盖问题用版本号解决
MessageExtra extra = message.getExtra();
extra.setRecall(new MsgRecall(recallUid, new Date()));
Message update = new Message();
update.setId(message.getId());
update.setType(MessageTypeEnum.RECALL.getType());
update.setExtra(extra);
messageDao.updateById(update);
applicationEventPublisher.publishEvent(new MessageRecallEvent(this, new ChatMsgRecallDTO(message.getId(), message.getRoomId(), recallUid)));
}
}

View File

@@ -0,0 +1,101 @@
package com.abin.mallchat.custom.chat.service.strategy.msg;
import cn.hutool.core.bean.BeanUtil;
import com.abin.mallchat.common.chat.dao.MessageDao;
import com.abin.mallchat.common.chat.domain.entity.Message;
import com.abin.mallchat.common.chat.domain.entity.msg.MessageExtra;
import com.abin.mallchat.common.chat.domain.enums.MessageStatusEnum;
import com.abin.mallchat.common.chat.domain.enums.MessageTypeEnum;
import com.abin.mallchat.common.chat.service.cache.MsgCache;
import com.abin.mallchat.common.common.domain.enums.YesOrNoEnum;
import com.abin.mallchat.common.common.utils.AssertUtil;
import com.abin.mallchat.common.user.domain.entity.User;
import com.abin.mallchat.common.user.service.cache.UserCache;
import com.abin.mallchat.custom.chat.domain.vo.request.ChatMessageReq;
import com.abin.mallchat.custom.chat.domain.vo.request.msg.TextMsgReq;
import com.abin.mallchat.custom.chat.domain.vo.response.msg.TextMsgResp;
import com.abin.mallchat.custom.chat.service.adapter.MessageAdapter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Objects;
import java.util.Optional;
/**
* Description: 普通文本消息
* Author: <a href="https://github.com/zongzibinbin">abin</a>
* Date: 2023-06-04
*/
@Component
public class TextMsgHandler extends AbstractMsgHandler {
@Autowired
private MessageDao messageDao;
@Autowired
private MsgCache msgCache;
@Autowired
private UserCache userCache;
@Override
MessageTypeEnum getMsgTypeEnum() {
return MessageTypeEnum.TEXT;
}
@Override
public void checkMsg(ChatMessageReq request) {
TextMsgReq body = BeanUtil.toBean(request.getBody(), TextMsgReq.class);
AssertUtil.isNotEmpty(body.getContent(), "内容不能为空");
AssertUtil.isTrue(body.getContent().length() < 500, "消息内容过长服务器扛不住啊兄dei");
//校验下回复消息
if (Objects.nonNull(body.getReplyMsgId())) {
Message replyMsg = messageDao.getById(body.getReplyMsgId());
AssertUtil.isNotEmpty(replyMsg, "回复消息不存在");
AssertUtil.equal(replyMsg.getRoomId(), request.getRoomId(), "只能回复相同会话内的消息");
}
}
@Override
public void saveMsg(Message msg, ChatMessageReq request) {//插入文本内容
TextMsgReq body = BeanUtil.toBean(request.getBody(), TextMsgReq.class);
Message update = new Message();
update.setId(msg.getId());
update.setContent(body.getContent());
//如果有回复消息
if (Objects.nonNull(body.getReplyMsgId())) {
Integer gapCount = messageDao.getGapCount(request.getRoomId(), body.getReplyMsgId(), msg.getId());
update.setGapCount(gapCount);
update.setReplyMsgId(body.getReplyMsgId());
}
messageDao.updateById(update);
}
@Override
public Object showMsg(Message msg) {
TextMsgResp resp = new TextMsgResp();
resp.setContent(msg.getContent());
resp.setUrlTitleMap(Optional.ofNullable(msg.getExtra()).map(MessageExtra::getUrlTitleMap).orElse(null));
//回复消息
Optional<Message> reply = Optional.ofNullable(msg.getReplyMsgId())
.map(msgCache::getMsg)
.filter(a -> Objects.equals(a.getStatus(), MessageStatusEnum.NORMAL.getStatus()));
if (reply.isPresent()) {
Message replyMessage = reply.get();
TextMsgResp.ReplyMsg replyMsgVO = new TextMsgResp.ReplyMsg();
replyMsgVO.setId(replyMessage.getId());
replyMsgVO.setUid(replyMessage.getFromUid());
replyMessage.setType(replyMessage.getType());
replyMsgVO.setBody(MsgHandlerFactory.getStrategyNoNull(replyMessage.getType()).showReplyMsg(replyMessage));
User replyUser = userCache.getUserInfo(replyMessage.getFromUid());
replyMsgVO.setUsername(replyUser.getName());
replyMsgVO.setCanCallback(YesOrNoEnum.toStatus(Objects.nonNull(msg.getGapCount()) && msg.getGapCount() <= MessageAdapter.CAN_CALLBACK_GAP_COUNT));
replyMsgVO.setGapCount(msg.getGapCount());
resp.setReply(replyMsgVO);
}
return resp;
}
@Override
public Object showReplyMsg(Message msg) {
return msg.getContent();
}
}