Commit ff88d53b3b28f55d17fdee5753791f3d1006f41c

Authored by 安浩浩
1 parent 77f3131e

新增:私聊消息发送成功后保存会话列表

yudao-module-im/yudao-module-im-api/src/main/java/cn/iocoder/yudao/module/im/enums/conversation/ImConversationTypeEnum.java
@@ -13,7 +13,8 @@ import lombok.Getter; @@ -13,7 +13,8 @@ import lombok.Getter;
13 public enum ImConversationTypeEnum { 13 public enum ImConversationTypeEnum {
14 14
15 PRIVATE(1, "单聊"), 15 PRIVATE(1, "单聊"),
16 - GROUP(2, "群聊"); 16 + GROUP(2, "群聊"),
  17 + NOTICE(4, "通知会话");
17 18
18 /** 19 /**
19 * 类型 20 * 类型
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/vo/ImConversationPageReqVO.java
@@ -24,7 +24,7 @@ public class ImConversationPageReqVO extends PageParam { @@ -24,7 +24,7 @@ public class ImConversationPageReqVO extends PageParam {
24 private Integer conversationType; 24 private Integer conversationType;
25 25
26 @Schema(description = "单聊时,用户编号;群聊时,群编号", example = "21454") 26 @Schema(description = "单聊时,用户编号;群聊时,群编号", example = "21454")
27 - private String targetId; 27 + private Long targetId;
28 28
29 @Schema(description = "会话标志 单聊:s_{userId}_{targetId},需要排序 userId 和 targetId 群聊:g_groupId") 29 @Schema(description = "会话标志 单聊:s_{userId}_{targetId},需要排序 userId 和 targetId 群聊:g_groupId")
30 private String no; 30 private String no;
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/vo/ImConversationRespVO.java
@@ -26,7 +26,7 @@ public class ImConversationRespVO { @@ -26,7 +26,7 @@ public class ImConversationRespVO {
26 26
27 @Schema(description = "单聊时,用户编号;群聊时,群编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "21454") 27 @Schema(description = "单聊时,用户编号;群聊时,群编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "21454")
28 @ExcelProperty("单聊时,用户编号;群聊时,群编号") 28 @ExcelProperty("单聊时,用户编号;群聊时,群编号")
29 - private String targetId; 29 + private Long targetId;
30 30
31 @Schema(description = "会话标志 单聊:s_{userId}_{targetId},需要排序 userId 和 targetId 群聊:g_groupId", requiredMode = Schema.RequiredMode.REQUIRED) 31 @Schema(description = "会话标志 单聊:s_{userId}_{targetId},需要排序 userId 和 targetId 群聊:g_groupId", requiredMode = Schema.RequiredMode.REQUIRED)
32 @ExcelProperty("会话标志 单聊:s_{userId}_{targetId},需要排序 userId 和 targetId 群聊:g_groupId") 32 @ExcelProperty("会话标志 单聊:s_{userId}_{targetId},需要排序 userId 和 targetId 群聊:g_groupId")
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/vo/ImConversationSaveReqVO.java
@@ -24,7 +24,7 @@ public class ImConversationSaveReqVO { @@ -24,7 +24,7 @@ public class ImConversationSaveReqVO {
24 24
25 @Schema(description = "单聊时,用户编号;群聊时,群编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "21454") 25 @Schema(description = "单聊时,用户编号;群聊时,群编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "21454")
26 @NotEmpty(message = "单聊时,用户编号;群聊时,群编号不能为空") 26 @NotEmpty(message = "单聊时,用户编号;群聊时,群编号不能为空")
27 - private String targetId; 27 + private Long targetId;
28 28
29 @Schema(description = "会话标志 单聊:s_{userId}_{targetId},需要排序 userId 和 targetId 群聊:g_groupId", requiredMode = Schema.RequiredMode.REQUIRED) 29 @Schema(description = "会话标志 单聊:s_{userId}_{targetId},需要排序 userId 和 targetId 群聊:g_groupId", requiredMode = Schema.RequiredMode.REQUIRED)
30 @NotEmpty(message = "会话标志 单聊:s_{userId}_{targetId},需要排序 userId 和 targetId 群聊:g_groupId不能为空") 30 @NotEmpty(message = "会话标志 单聊:s_{userId}_{targetId},需要排序 userId 和 targetId 群聊:g_groupId不能为空")
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/conversation/ImConversationDO.java
@@ -39,7 +39,7 @@ public class ImConversationDO extends BaseDO { @@ -39,7 +39,7 @@ public class ImConversationDO extends BaseDO {
39 /** 39 /**
40 * 单聊时,用户编号;群聊时,群编号 40 * 单聊时,用户编号;群聊时,群编号
41 */ 41 */
42 - private String targetId; 42 + private Long targetId;
43 /** 43 /**
44 * 会话标志 单聊:s_{userId}_{targetId},需要排序 userId 和 targetId 群聊:g_groupId 44 * 会话标志 单聊:s_{userId}_{targetId},需要排序 userId 和 targetId 群聊:g_groupId
45 */ 45 */
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/conversation/ImConversationService.java
@@ -52,4 +52,11 @@ public interface ImConversationService { @@ -52,4 +52,11 @@ public interface ImConversationService {
52 PageResult<ImConversationDO> getConversationPage(ImConversationPageReqVO pageReqVO); 52 PageResult<ImConversationDO> getConversationPage(ImConversationPageReqVO pageReqVO);
53 53
54 54
  55 + /**
  56 + * 保存私聊会话
  57 + *
  58 + * @param fromUserId 发送者
  59 + * @param receiverId 接收者
  60 + */
  61 + void savePrivateConversation(Long fromUserId, Long receiverId);
55 } 62 }
56 \ No newline at end of file 63 \ No newline at end of file
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/conversation/ImConversationServiceImpl.java
@@ -6,6 +6,8 @@ import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ImConversatio @@ -6,6 +6,8 @@ import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ImConversatio
6 import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ImConversationSaveReqVO; 6 import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ImConversationSaveReqVO;
7 import cn.iocoder.yudao.module.im.dal.dataobject.conversation.ImConversationDO; 7 import cn.iocoder.yudao.module.im.dal.dataobject.conversation.ImConversationDO;
8 import cn.iocoder.yudao.module.im.dal.mysql.conversation.ConversationMapper; 8 import cn.iocoder.yudao.module.im.dal.mysql.conversation.ConversationMapper;
  9 +import cn.iocoder.yudao.module.im.enums.conversation.ImConversationTypeEnum;
  10 +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
9 import jakarta.annotation.Resource; 11 import jakarta.annotation.Resource;
10 import org.springframework.stereotype.Service; 12 import org.springframework.stereotype.Service;
11 import org.springframework.validation.annotation.Validated; 13 import org.springframework.validation.annotation.Validated;
@@ -67,4 +69,28 @@ public class ImConversationServiceImpl implements ImConversationService { @@ -67,4 +69,28 @@ public class ImConversationServiceImpl implements ImConversationService {
67 return conversationMapper.selectPage(pageReqVO); 69 return conversationMapper.selectPage(pageReqVO);
68 } 70 }
69 71
  72 + @Override
  73 + public void savePrivateConversation(Long fromUserId, Long receiverId) {
  74 + // 创建并保存会话
  75 + createAndSaveConversation(fromUserId, receiverId);
  76 + createAndSaveConversation(receiverId, fromUserId);
  77 + }
  78 +
  79 + private void createAndSaveConversation(Long userId, Long targetId) {
  80 + // 创建会话
  81 + ImConversationDO conversation = new ImConversationDO();
  82 + conversation.setUserId(userId);
  83 + conversation.setConversationType(ImConversationTypeEnum.PRIVATE.getType());
  84 + conversation.setTargetId(targetId);
  85 + conversation.setNo("s_" + userId + "_" + targetId);
  86 + conversation.setPinned(false);
  87 +
  88 + // 根据 no 查询是否存在,不存在则新增
  89 + QueryWrapper<ImConversationDO> queryWrapper = new QueryWrapper<>();
  90 + queryWrapper.eq("no", conversation.getNo());
  91 + if (conversationMapper.selectOne(queryWrapper) == null) {
  92 + conversationMapper.insert(conversation);
  93 + }
  94 + }
  95 +
70 } 96 }
71 \ No newline at end of file 97 \ No newline at end of file
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/message/ImMessageService.java
@@ -60,7 +60,7 @@ public interface ImMessageService { @@ -60,7 +60,7 @@ public interface ImMessageService {
60 * @param fromUserId 发送人编号 60 * @param fromUserId 发送人编号
61 * @return id 61 * @return id
62 */ 62 */
63 - Long savePrivateMessage(ImSendMessage imSendMessage, Long fromUserId); 63 + ImMessageDO savePrivateMessage(ImSendMessage imSendMessage, Long fromUserId);
64 64
65 /** 65 /**
66 * 更新消息状态 66 * 更新消息状态
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/message/ImMessageServiceImpl.java
@@ -76,24 +76,25 @@ public class ImMessageServiceImpl implements ImMessageService { @@ -76,24 +76,25 @@ public class ImMessageServiceImpl implements ImMessageService {
76 76
77 77
78 @Override 78 @Override
79 - public Long savePrivateMessage(ImSendMessage message, Long senderId) {  
80 - ImMessageSaveReqVO imMessageSaveReqVO = new ImMessageSaveReqVO();  
81 - imMessageSaveReqVO.setClientMessageId(message.getClientMessageId());  
82 - imMessageSaveReqVO.setSenderId(senderId);  
83 - imMessageSaveReqVO.setReceiverId(message.getReceiverId()); 79 + public ImMessageDO savePrivateMessage(ImSendMessage message, Long senderId) {
  80 + ImMessageDO imMessageDO = new ImMessageDO();
  81 + imMessageDO.setClientMessageId(message.getClientMessageId());
  82 + imMessageDO.setSenderId(senderId);
  83 + imMessageDO.setReceiverId(message.getReceiverId());
84 //查询发送人昵称和发送人头像 84 //查询发送人昵称和发送人头像
85 AdminUserRespDTO user = adminUserApi.getUser(senderId); 85 AdminUserRespDTO user = adminUserApi.getUser(senderId);
86 - imMessageSaveReqVO.setSenderNickname(user.getNickname());  
87 - imMessageSaveReqVO.setSenderAvatar(user.getAvatar());  
88 - imMessageSaveReqVO.setConversationType(message.getConversationType());  
89 - imMessageSaveReqVO.setContentType(message.getContentType());  
90 - imMessageSaveReqVO.setConversationNo(senderId + "_" + message.getReceiverId());  
91 - imMessageSaveReqVO.setContent(message.getContent()); 86 + imMessageDO.setSenderNickname(user.getNickname());
  87 + imMessageDO.setSenderAvatar(user.getAvatar());
  88 + imMessageDO.setConversationType(message.getConversationType());
  89 + imMessageDO.setContentType(message.getContentType());
  90 + imMessageDO.setConversationNo(senderId + "_" + message.getReceiverId());
  91 + imMessageDO.setContent(message.getContent());
92 //消息来源 100-用户发送;200-系统发送(一般是通知);不能为空 92 //消息来源 100-用户发送;200-系统发送(一般是通知);不能为空
93 - imMessageSaveReqVO.setSendFrom(100);  
94 - imMessageSaveReqVO.setSendTime(TimeUtil.now());  
95 - imMessageSaveReqVO.setMessageStatus(ImMessageStatusEnum.SENDING.getStatus());  
96 - return createMessage(imMessageSaveReqVO); 93 + imMessageDO.setSendFrom(100);
  94 + imMessageDO.setSendTime(TimeUtil.now());
  95 + imMessageDO.setMessageStatus(ImMessageStatusEnum.SENDING.getStatus());
  96 + imMessageMapper.insert(imMessageDO);
  97 + return imMessageDO;
97 } 98 }
98 99
99 @Override 100 @Override
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/websocket/ImWebSocketMessageListener.java
@@ -3,9 +3,9 @@ package cn.iocoder.yudao.module.im.websocket; @@ -3,9 +3,9 @@ package cn.iocoder.yudao.module.im.websocket;
3 import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; 3 import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
4 import cn.iocoder.yudao.framework.websocket.core.listener.WebSocketMessageListener; 4 import cn.iocoder.yudao.framework.websocket.core.listener.WebSocketMessageListener;
5 import cn.iocoder.yudao.framework.websocket.core.sender.WebSocketMessageSender; 5 import cn.iocoder.yudao.framework.websocket.core.sender.WebSocketMessageSender;
6 -import cn.iocoder.yudao.framework.websocket.core.session.WebSocketSessionManager;  
7 import cn.iocoder.yudao.framework.websocket.core.util.WebSocketFrameworkUtils; 6 import cn.iocoder.yudao.framework.websocket.core.util.WebSocketFrameworkUtils;
8 import cn.iocoder.yudao.module.im.controller.admin.inbox.vo.ImInboxSaveReqVO; 7 import cn.iocoder.yudao.module.im.controller.admin.inbox.vo.ImInboxSaveReqVO;
  8 +import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO;
9 import cn.iocoder.yudao.module.im.dal.redis.inbox.SequenceGeneratorRedisDao; 9 import cn.iocoder.yudao.module.im.dal.redis.inbox.SequenceGeneratorRedisDao;
10 import cn.iocoder.yudao.module.im.enums.conversation.ImConversationTypeEnum; 10 import cn.iocoder.yudao.module.im.enums.conversation.ImConversationTypeEnum;
11 import cn.iocoder.yudao.module.im.enums.message.ImMessageStatusEnum; 11 import cn.iocoder.yudao.module.im.enums.message.ImMessageStatusEnum;
@@ -19,8 +19,6 @@ import lombok.extern.slf4j.Slf4j; @@ -19,8 +19,6 @@ import lombok.extern.slf4j.Slf4j;
19 import org.springframework.stereotype.Component; 19 import org.springframework.stereotype.Component;
20 import org.springframework.web.socket.WebSocketSession; 20 import org.springframework.web.socket.WebSocketSession;
21 21
22 -import java.util.List;  
23 -  
24 /** 22 /**
25 * WebSocket im 23 * WebSocket im
26 * 24 *
@@ -31,55 +29,100 @@ import java.util.List; @@ -31,55 +29,100 @@ import java.util.List;
31 public class ImWebSocketMessageListener implements WebSocketMessageListener<ImSendMessage> { 29 public class ImWebSocketMessageListener implements WebSocketMessageListener<ImSendMessage> {
32 30
33 @Resource 31 @Resource
34 - private WebSocketMessageSender webSocketMessageSender;  
35 - @Resource  
36 - private ImMessageService imMessageService; 32 + private WebSocketMessageSender webSocketMessageSender; // WebSocket消息发送器
37 @Resource 33 @Resource
38 - private ImConversationService imConversationService; 34 + private ImMessageService imMessageService; // IM消息服务
39 @Resource 35 @Resource
40 - private ImInboxService imInboxService; 36 + private ImConversationService imConversationService; // IM会话服务
41 @Resource 37 @Resource
42 - private SequenceGeneratorRedisDao sequenceGeneratorRedisDao; 38 + private ImInboxService imInboxService; // IM收件箱服务
43 @Resource 39 @Resource
44 - private WebSocketSessionManager webSocketSessionManager; 40 + private SequenceGeneratorRedisDao sequenceGeneratorRedisDao; // 序列生成器Redis DAO
45 41
  42 + /**
  43 + * 处理WebSocket消息
  44 + *
  45 + * @param session WebSocket会话
  46 + * @param message 发送的IM消息
  47 + */
46 @Override 48 @Override
47 public void onMessage(WebSocketSession session, ImSendMessage message) { 49 public void onMessage(WebSocketSession session, ImSendMessage message) {
48 - Long fromUserId = WebSocketFrameworkUtils.getLoginUserId(session);  
49 - //1、插入消息表  
50 - Long messageId = imMessageService.savePrivateMessage(message, fromUserId); 50 + Long fromUserId = WebSocketFrameworkUtils.getLoginUserId(session); // 获取登录用户ID
51 51
52 - // 私聊 52 + // 如果是私人消息,处理私人消息
53 if (message.getConversationType().equals(ImConversationTypeEnum.PRIVATE.getType())) { 53 if (message.getConversationType().equals(ImConversationTypeEnum.PRIVATE.getType())) {
54 - //2、插入收件箱表(私聊:两条,群聊:每个群有一条)  
55 - imInboxService.createInbox(new ImInboxSaveReqVO(message.getReceiverId(), messageId, sequenceGeneratorRedisDao.generateSequence(message.getReceiverId())));  
56 - imInboxService.createInbox(new ImInboxSaveReqVO(fromUserId, messageId, sequenceGeneratorRedisDao.generateSequence(fromUserId))); 54 + ImMessageDO imMessageDO = imMessageService.savePrivateMessage(message, fromUserId); // 保存私人消息
  55 + handlePrivateMessage(fromUserId, imMessageDO, message);
  56 + }
  57 + }
57 58
58 - //3、推送消息  
59 - // 3.1判断是否在线  
60 - List<WebSocketSession> sessions = (List<WebSocketSession>) webSocketSessionManager.getSessionList(UserTypeEnum.ADMIN.getValue(), message.getReceiverId());  
61 - if (sessions.isEmpty()) {  
62 - //更新消息状态,为发送失败  
63 - imMessageService.updateMessageStatus(messageId, ImMessageStatusEnum.FAILURE.getStatus());  
64 - return;  
65 - }  
66 - //3.2发送  
67 - ImReceiveMessage toMessage = new ImReceiveMessage();  
68 - toMessage.setFromId(fromUserId);  
69 - toMessage.setConversationType(ImConversationTypeEnum.PRIVATE.getType());  
70 - toMessage.setContentType(message.getContentType());  
71 - toMessage.setContent(message.getContent());  
72 - webSocketMessageSender.sendObject(UserTypeEnum.ADMIN.getValue(), message.getReceiverId(), // 给指定用户  
73 - "im-message-receive", toMessage);  
74 - //4、更新消息状态,为发送成功  
75 - imMessageService.updateMessageStatus(messageId, ImMessageStatusEnum.SUCCESS.getStatus()); 59 + /**
  60 + * 处理私人消息
  61 + *
  62 + * @param fromUserId 发送者用户ID
  63 + * @param imMessageDO IM消息数据对象
  64 + * @param message 发送的IM消息
  65 + */
  66 + private void handlePrivateMessage(Long fromUserId, ImMessageDO imMessageDO, ImSendMessage message) {
  67 + Long fromUserSequence = sequenceGeneratorRedisDao.generateSequence(fromUserId); // 生成发送者序列
  68 + Long fromUserInboxId = createAndSaveInbox(fromUserId, imMessageDO.getId(), fromUserSequence); // 创建并保存发送者收件箱
  69 + Long receiverSequence = sequenceGeneratorRedisDao.generateSequence(fromUserId); // 生成接收者序列
  70 + Long receiverInboxId = createAndSaveInbox(message.getReceiverId(), imMessageDO.getId(), receiverSequence); // 创建并保存接收者收件箱
76 71
77 - } 72 + // 发送消息给接收者和发送者
  73 + sendMessage(fromUserId, receiverInboxId, imMessageDO, message, "im-message-receive", fromUserSequence);
  74 + sendMessage(fromUserId, fromUserInboxId, imMessageDO, message, "im-message-receive", receiverSequence);
  75 +
  76 + // 更新消息状态为成功
  77 + imMessageService.updateMessageStatus(imMessageDO.getId(), ImMessageStatusEnum.SUCCESS.getStatus());
  78 + // 保存私人会话
  79 + imConversationService.savePrivateConversation(fromUserId, message.getReceiverId());
  80 + }
  81 +
  82 + /**
  83 + * 创建并保存收件箱
  84 + *
  85 + * @param userId 用户ID
  86 + * @param messageId 消息ID
  87 + * @param sequence 序列
  88 + * @return 收件箱ID
  89 + */
  90 + private Long createAndSaveInbox(Long userId, Long messageId, Long sequence) {
  91 + ImInboxSaveReqVO inboxSaveReqVO = new ImInboxSaveReqVO(userId, messageId, sequence); // 创建收件箱保存请求VO
  92 + return imInboxService.createInbox(inboxSaveReqVO); // 创建收件箱
  93 + }
  94 +
  95 + /**
  96 + * 发送消息
  97 + *
  98 + * @param fromUserId 发送者用户ID
  99 + * @param inboxId 收件箱ID
  100 + * @param imMessageDO IM消息数据对象
  101 + * @param message 发送的IM消息
  102 + * @param messageType 消息类型
  103 + * @param sequence 序列
  104 + */
  105 + private void sendMessage(Long fromUserId, Long inboxId, ImMessageDO imMessageDO, ImSendMessage message, String messageType, Long sequence) {
  106 + ImReceiveMessage receiveMessage = new ImReceiveMessage(); // 创建接收消息
  107 + receiveMessage.setFromId(fromUserId); // 设置发送者ID
  108 + receiveMessage.setConversationType(ImConversationTypeEnum.PRIVATE.getType()); // 设置会话类型为私人
  109 + receiveMessage.setContentType(message.getContentType()); // 设置内容类型
  110 + receiveMessage.setContent(message.getContent()); // 设置内容
  111 + receiveMessage.setMessageId(imMessageDO.getId()); // 设置消息ID
  112 + receiveMessage.setInboxId(inboxId); // 设置收件箱ID
  113 + receiveMessage.setSendTime(imMessageDO.getSendTime()); // 设置发送时间
  114 + receiveMessage.setSequence(sequence); // 设置序列
  115 + webSocketMessageSender.sendObject(UserTypeEnum.ADMIN.getValue(), fromUserId, messageType, receiveMessage); // 发送消息
78 } 116 }
79 117
  118 + /**
  119 + * 获取类型
  120 + *
  121 + * @return 类型
  122 + */
80 @Override 123 @Override
81 public String getType() { 124 public String getType() {
82 return "im-message-send"; 125 return "im-message-send";
83 } 126 }
84 127
85 -} 128 -}
  129 +}
86 \ No newline at end of file 130 \ No newline at end of file
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/websocket/message/ImReceiveMessage.java
@@ -2,8 +2,11 @@ package cn.iocoder.yudao.module.im.websocket.message; @@ -2,8 +2,11 @@ package cn.iocoder.yudao.module.im.websocket.message;
2 2
3 import cn.iocoder.yudao.module.im.dal.dataobject.message.body.ImMessageBody; 3 import cn.iocoder.yudao.module.im.dal.dataobject.message.body.ImMessageBody;
4 import io.swagger.v3.oas.annotations.media.Schema; 4 import io.swagger.v3.oas.annotations.media.Schema;
  5 +import jakarta.validation.constraints.NotNull;
5 import lombok.Data; 6 import lombok.Data;
6 7
  8 +import java.time.LocalDateTime;
  9 +
7 @Schema(description = "管理后台 - 消息发送 receive") 10 @Schema(description = "管理后台 - 消息发送 receive")
8 @Data 11 @Data
9 public class ImReceiveMessage { 12 public class ImReceiveMessage {
@@ -20,4 +23,16 @@ public class ImReceiveMessage { @@ -20,4 +23,16 @@ public class ImReceiveMessage {
20 @Schema(description = "消息内容", requiredMode = Schema.RequiredMode.REQUIRED) 23 @Schema(description = "消息内容", requiredMode = Schema.RequiredMode.REQUIRED)
21 private String content; 24 private String content;
22 25
  26 + @Schema(description = "消息编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "12454")
  27 + private Long messageId;
  28 +
  29 + @Schema(description = "发送时间", requiredMode = Schema.RequiredMode.REQUIRED)
  30 + private LocalDateTime sendTime;
  31 +
  32 + @Schema(description = "收件箱编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "18389")
  33 + private Long inboxId;
  34 +
  35 + @Schema(description = "序号,按照 user 递增", requiredMode = Schema.RequiredMode.REQUIRED)
  36 + private Long sequence;
  37 +
23 } 38 }
24 \ No newline at end of file 39 \ No newline at end of file