Commit 28cf87ac8afff15d1e362152e8aa65dfca1f7a04

Authored by YunaiV
1 parent 0d7cb763

feat(im): 重构普通消息类型,和 openim 的消息编号对齐

yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/enums/ImCommonConstants.java
@@ -54,15 +54,4 @@ public interface ImCommonConstants { @@ -54,15 +54,4 @@ public interface ImCommonConstants {
54 */ 54 */
55 int MESSAGE_GROUP_PULL_MAX_DAYS = 30; 55 int MESSAGE_GROUP_PULL_MAX_DAYS = 30;
56 56
57 - // ==================== 好友相关提示消息 ====================  
58 -  
59 - /**  
60 - * 好友添加系统提示  
61 - */  
62 - String FRIEND_ADD_TIP_MESSAGE = "你们已成为好友,现在可以开始聊天了";  
63 - /**  
64 - * 好友删除系统提示(仅自己可见,单边推送)  
65 - */  
66 - String FRIEND_DELETE_TIP_MESSAGE = "你已删除好友";  
67 -  
68 } 57 }
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/enums/message/ImMessageTypeEnum.java
@@ -17,20 +17,49 @@ import java.util.Arrays; @@ -17,20 +17,49 @@ import java.util.Arrays;
17 @RequiredArgsConstructor 17 @RequiredArgsConstructor
18 public enum ImMessageTypeEnum implements ArrayValuable<Integer> { 18 public enum ImMessageTypeEnum implements ArrayValuable<Integer> {
19 19
20 - // ========== 用户聊天消息 ==========  
21 - TEXT(0, "文本", true, true), // 对应 TextMessage 类  
22 - IMAGE(1, "图片", true, true), // 对应 ImageMessage 类  
23 - FILE(2, "文件", true, true), // 对应 FileMessage 类  
24 - VOICE(3, "语音", true, true), // 对应 AudioMessage 类  
25 - VIDEO(4, "视频", true, true), // 对应 VideoMessage 类  
26 -  
27 - // ========== 信号类 ==========  
28 - RECALL(10, "撤回", true, false), // 对应 RecallMessage 类  
29 - READ(11, "已读", false, false), // 暂无  
30 - RECEIPT(12, "回执", false, false), // 暂无 20 + // ========== 用户聊天消息(101-105 直接复用 OpenIM 段位编号) ==========
  21 + /**
  22 + * 对应 OpenIM:Text 101
  23 + * 对应自己的类:TextMessage
  24 + */
  25 + TEXT(101, "文本", true, true),
  26 + /**
  27 + * 对应 OpenIM:Picture 102
  28 + * 对应自己的类:ImageMessage
  29 + */
  30 + IMAGE(102, "图片", true, true),
  31 + /**
  32 + * 对应 OpenIM:Sound 103
  33 + * 对应自己的类:AudioMessage
  34 + */
  35 + VOICE(103, "语音", true, true),
  36 + /**
  37 + * 对应 OpenIM:Video 104
  38 + * 对应自己的类:VideoMessage
  39 + */
  40 + VIDEO(104, "视频", true, true),
  41 + /**
  42 + * 对应 OpenIM:File 105
  43 + * 对应自己的类:FileMessage
  44 + */
  45 + FILE(105, "文件", true, true),
31 46
32 - // ========== 系统提示 ==========  
33 - TIP_TEXT(21, "系统提示", true, false), // 对应 TextMessage 类 47 + // ========== 信号类(2101 / 2200 直接复用 OpenIM 段位编号;2201 自有扩展) ==========
  48 + /**
  49 + * 对应 OpenIM:RevokeNotification 2101
  50 + * 对应自己的类:RecallMessage
  51 + */
  52 + RECALL(2101, "撤回", true, false),
  53 + /**
  54 + * 对应 OpenIM:HasReadReceipt 2200
  55 + * 对应自己的类:无(payload 走 ImXxxMessageDTO 顶层字段)
  56 + */
  57 + RECEIPT(2200, "回执", false, false),
  58 + /**
  59 + * 对应 OpenIM:无(自有扩展,OpenIM 走 ConversationChangeNotification 1300 路径)
  60 + * 对应自己的类:无(payload 走 ImXxxMessageDTO 顶层字段)
  61 + */
  62 + READ(2201, "已读", false, false),
34 63
35 // ========== 好友通知(1201-1210 直接复用 OpenIM 段位编号) ========== 64 // ========== 好友通知(1201-1210 直接复用 OpenIM 段位编号) ==========
36 /** 65 /**
@@ -52,11 +81,12 @@ public enum ImMessageTypeEnum implements ArrayValuable&lt;Integer&gt; { @@ -52,11 +81,12 @@ public enum ImMessageTypeEnum implements ArrayValuable&lt;Integer&gt; {
52 */ 81 */
53 FRIEND_REQUEST_RECEIVED(1203, "收到新的好友申请", false, false), 82 FRIEND_REQUEST_RECEIVED(1203, "收到新的好友申请", false, false),
54 /** 83 /**
55 - * 对应 OpenIM:FriendAddedNotification 1204 84 + * 对应 OpenIM:FriendAddedNotification 1204(OpenIM friendAdded.isSendMsg=false 默认不入消息流;本系统改为入库当会话气泡)
56 * 对应自己的类:FriendAddNotification 85 * 对应自己的类:FriendAddNotification
57 - * 场景:双方建立好友关系(同意申请 / 管理员导入),推给 A、B 双方多端 86 + * 场景:双方建立好友关系,单条入库(sender=fromUserId, receiver=toUserId);双向 WebSocket 自动覆盖双方多端
  87 + * 注意:silentReAddFriend 单边语义场景,发送时显式 setPersistent(false) 覆盖默认值
58 */ 88 */
59 - FRIEND_ADD(1204, "新增好友", false, false), 89 + FRIEND_ADD(1204, "新增好友", true, false),
60 /** 90 /**
61 * 对应 OpenIM:FriendDeletedNotification 1205 91 * 对应 OpenIM:FriendDeletedNotification 1205
62 * 对应自己的类:FriendDeleteNotification 92 * 对应自己的类:FriendDeleteNotification
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/friend/ImFriendServiceImpl.java
@@ -11,6 +11,7 @@ import cn.iocoder.yudao.module.im.dal.mysql.friend.ImFriendMapper; @@ -11,6 +11,7 @@ import cn.iocoder.yudao.module.im.dal.mysql.friend.ImFriendMapper;
11 import cn.iocoder.yudao.module.im.enums.friend.ImFriendStateEnum; 11 import cn.iocoder.yudao.module.im.enums.friend.ImFriendStateEnum;
12 import cn.iocoder.yudao.module.im.enums.message.ImMessageTypeEnum; 12 import cn.iocoder.yudao.module.im.enums.message.ImMessageTypeEnum;
13 import cn.iocoder.yudao.module.im.service.message.ImPrivateMessageService; 13 import cn.iocoder.yudao.module.im.service.message.ImPrivateMessageService;
  14 +import cn.iocoder.yudao.module.im.service.message.dto.ImPrivateMessageSendDTO;
14 import cn.iocoder.yudao.module.im.service.websocket.ImWebSocketService; 15 import cn.iocoder.yudao.module.im.service.websocket.ImWebSocketService;
15 import cn.iocoder.yudao.module.im.service.websocket.dto.ImPrivateMessageDTO; 16 import cn.iocoder.yudao.module.im.service.websocket.dto.ImPrivateMessageDTO;
16 import cn.iocoder.yudao.module.im.service.websocket.dto.notification.friend.*; 17 import cn.iocoder.yudao.module.im.service.websocket.dto.notification.friend.*;
@@ -32,8 +33,6 @@ import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionU @@ -32,8 +33,6 @@ import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionU
32 import static cn.iocoder.yudao.module.im.dal.redis.RedisKeyConstants.FRIEND_STATE; 33 import static cn.iocoder.yudao.module.im.dal.redis.RedisKeyConstants.FRIEND_STATE;
33 import static cn.iocoder.yudao.module.im.enums.ErrorCodeConstants.FRIEND_NOT_BLOCKED; 34 import static cn.iocoder.yudao.module.im.enums.ErrorCodeConstants.FRIEND_NOT_BLOCKED;
34 import static cn.iocoder.yudao.module.im.enums.ErrorCodeConstants.FRIEND_NOT_FRIEND; 35 import static cn.iocoder.yudao.module.im.enums.ErrorCodeConstants.FRIEND_NOT_FRIEND;
35 -import static cn.iocoder.yudao.module.im.enums.ImCommonConstants.FRIEND_ADD_TIP_MESSAGE;  
36 -import static cn.iocoder.yudao.module.im.enums.ImCommonConstants.FRIEND_DELETE_TIP_MESSAGE;  
37 36
38 /** 37 /**
39 * IM 好友关系 Service 实现类 38 * IM 好友关系 Service 实现类
@@ -130,19 +129,12 @@ public class ImFriendServiceImpl implements ImFriendService { @@ -130,19 +129,12 @@ public class ImFriendServiceImpl implements ImFriendService {
130 addFriend0(fromUserId, toUserId, request.getDisplayName(), request.getAddSource()); 129 addFriend0(fromUserId, toUserId, request.getDisplayName(), request.getAddSource());
131 addFriend0(toUserId, fromUserId, null, request.getAddSource()); 130 addFriend0(toUserId, fromUserId, null, request.getAddSource());
132 131
133 - // 2.1 推 TIP 系统消息(双方私聊会话里看到「你们已成为好友」);TIP 走会话入库,FRIEND_ADD 走事件通知  
134 - privateMessageService.sendTipPrivateMessage(fromUserId, toUserId, FRIEND_ADD_TIP_MESSAGE);  
135 -  
136 - // 2.2.1 推 FRIEND_ADD 给 fromUser 多端  
137 - FriendAddNotification toFrom = (FriendAddNotification) new FriendAddNotification()  
138 - .setOperatorUserId(toUserId).setFriendUserId(toUserId);  
139 - websocketService.sendPrivateMessageAsync(fromUserId, ImPrivateMessageDTO.ofFriendNotification(  
140 - ImMessageTypeEnum.FRIEND_ADD.getType(), toUserId, fromUserId, toFrom));  
141 - // 2.2.2 推 FRIEND_ADD 给 toUser 多端  
142 - FriendAddNotification toTo = (FriendAddNotification) new FriendAddNotification()  
143 - .setOperatorUserId(fromUserId).setFriendUserId(fromUserId);  
144 - websocketService.sendPrivateMessageAsync(toUserId, ImPrivateMessageDTO.ofFriendNotification(  
145 - ImMessageTypeEnum.FRIEND_ADD.getType(), fromUserId, toUserId, toTo)); 132 + // 2. 发送 FRIEND_ADD 入库(双方拉历史都能看到「你们已成为好友」会话气泡)+ 双向 WebSocket 自动覆盖双方多端
  133 + // operatorUserId=fromUserId 标记申请发起方;前端按 (currentUserId === operatorUserId) 区分视角,文案固定不依赖此字段
  134 + FriendAddNotification payload = (FriendAddNotification) new FriendAddNotification()
  135 + .setOperatorUserId(fromUserId).setFriendUserId(toUserId);
  136 + privateMessageService.sendPrivateMessage(fromUserId, new ImPrivateMessageSendDTO()
  137 + .setReceiverId(toUserId).setType(ImMessageTypeEnum.FRIEND_ADD.getType()).setContent(payload));
146 } 138 }
147 139
148 @Override 140 @Override
@@ -155,15 +147,14 @@ public class ImFriendServiceImpl implements ImFriendService { @@ -155,15 +147,14 @@ public class ImFriendServiceImpl implements ImFriendService {
155 // 1. 单边重新启用我侧好友关系 147 // 1. 单边重新启用我侧好友关系
156 addFriend0(userId, friendUserId, displayName, addSource); 148 addFriend0(userId, friendUserId, displayName, addSource);
157 149
158 - // 2. 推 TIP「你们已成为好友」走单边语义(persistent=false):不入库 + 仅推 userId 多端,对方完全不感知  
159 - privateMessageService.sendTipPrivateMessage(userId, friendUserId, FRIEND_ADD_TIP_MESSAGE, false);  
160 -  
161 - // 3. 仅推 FRIEND_ADD 给 userId 多端(不通知对方,保持「对方一直把我当好友」的错觉)  
162 - // operatorUserId 填 friendUserId(对方):让 userId 多端 UI 呈现「对方加了我」的视觉效果,与 silent 语义对齐 150 + // 2. 走 sendPrivateMessage + persistent=false:不入库 + 仅推 userId 多端(对方完全不感知,保持「对方一直把我当好友」错觉)
  151 + // operatorUserId 填 friendUserId(对方):让 userId 多端 UI 呈现「对方加了我」视角,与 silent 语义对齐
  152 + // 前端按 type=FRIEND_ADD 渲染会话气泡(瞬时,不入库刷新即消失)
163 FriendAddNotification payload = (FriendAddNotification) new FriendAddNotification() 153 FriendAddNotification payload = (FriendAddNotification) new FriendAddNotification()
164 .setOperatorUserId(friendUserId).setFriendUserId(friendUserId); 154 .setOperatorUserId(friendUserId).setFriendUserId(friendUserId);
165 - websocketService.sendPrivateMessageAsync(userId, ImPrivateMessageDTO.ofFriendNotification(  
166 - ImMessageTypeEnum.FRIEND_ADD.getType(), friendUserId, userId, payload)); 155 + privateMessageService.sendPrivateMessage(userId, new ImPrivateMessageSendDTO()
  156 + .setReceiverId(friendUserId).setType(ImMessageTypeEnum.FRIEND_ADD.getType())
  157 + .setContent(payload).setPersistent(false));
167 } 158 }
168 159
169 @Override 160 @Override
@@ -176,17 +167,14 @@ public class ImFriendServiceImpl implements ImFriendService { @@ -176,17 +167,14 @@ public class ImFriendServiceImpl implements ImFriendService {
176 // 1. 单边软删:仅 userId 视角的关系置 DISABLE;friendUserId 视角不动 167 // 1. 单边软删:仅 userId 视角的关系置 DISABLE;friendUserId 视角不动
177 deleteFriend0(userId, friendUserId); 168 deleteFriend0(userId, friendUserId);
178 169
179 - // 2. 仅 clear=false 时推 TIP「你已删除好友」(单边 persistent=false);  
180 - // clear=true / null 时跳过 —— 避免 TIP 晚于 FRIEND_DELETE 到达把刚清的会话复活  
181 - if (Boolean.FALSE.equals(clear)) {  
182 - privateMessageService.sendTipPrivateMessage(userId, friendUserId, FRIEND_DELETE_TIP_MESSAGE, false);  
183 - }  
184 -  
185 - // 3. 推 FRIEND_DELETE 给 userId 多端做同步(friendUserId 不感知);clear 透传让多端清理动作一致 170 + // 2. 走 sendPrivateMessage + persistent=false:不入库 + 仅推 userId 多端(friendUserId 不感知);clear 透传让多端清理动作一致
  171 + // clear=false 时前端按 type=FRIEND_DELETE 渲染「你已删除好友」会话气泡(瞬时);
  172 + // clear=true 时前端按 clear 字段直接清会话,跳过气泡渲染
186 FriendDeleteNotification payload = ((FriendDeleteNotification) new FriendDeleteNotification() 173 FriendDeleteNotification payload = ((FriendDeleteNotification) new FriendDeleteNotification()
187 .setOperatorUserId(userId).setFriendUserId(friendUserId)).setClear(clear); 174 .setOperatorUserId(userId).setFriendUserId(friendUserId)).setClear(clear);
188 - websocketService.sendPrivateMessageAsync(userId, ImPrivateMessageDTO.ofFriendNotification(  
189 - ImMessageTypeEnum.FRIEND_DELETE.getType(), userId, userId, payload)); 175 + privateMessageService.sendPrivateMessage(userId, new ImPrivateMessageSendDTO()
  176 + .setReceiverId(friendUserId).setType(ImMessageTypeEnum.FRIEND_DELETE.getType())
  177 + .setContent(payload).setPersistent(false));
190 } 178 }
191 179
192 @Override 180 @Override
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/message/ImPrivateMessageService.java
@@ -38,25 +38,6 @@ public interface ImPrivateMessageService { @@ -38,25 +38,6 @@ public interface ImPrivateMessageService {
38 ImPrivateMessageDO sendPrivateMessage(Long senderId, ImPrivateMessageSendDTO dto); 38 ImPrivateMessageDO sendPrivateMessage(Long senderId, ImPrivateMessageSendDTO dto);
39 39
40 /** 40 /**
41 - * 【系统调用】发送系统提示消息(TIP_TEXT)  
42 - *  
43 - * @param senderId 发送人编号  
44 - * @param receiverId 接收人编号  
45 - * @param content 提示文本  
46 - */  
47 - void sendTipPrivateMessage(Long senderId, Long receiverId, String content);  
48 -  
49 - /**  
50 - * 【系统调用】发送系统提示消息(TIP_TEXT),可覆盖 persistent  
51 - *  
52 - * @param senderId 发送人编号  
53 - * @param receiverId 接收人编号  
54 - * @param content 提示文本  
55 - * @param persistent null 走默认;false 单边(不入库 + 仅推 sender 多端,对方不感知);true 强制双向 + 入库  
56 - */  
57 - void sendTipPrivateMessage(Long senderId, Long receiverId, String content, Boolean persistent);  
58 -  
59 - /**  
60 * 【用户调用】撤回私聊消息 41 * 【用户调用】撤回私聊消息
61 * 42 *
62 * @param userId 当前用户编号 43 * @param userId 当前用户编号
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/message/ImPrivateMessageServiceImpl.java
@@ -123,17 +123,6 @@ public class ImPrivateMessageServiceImpl implements ImPrivateMessageService { @@ -123,17 +123,6 @@ public class ImPrivateMessageServiceImpl implements ImPrivateMessageService {
123 } 123 }
124 124
125 @Override 125 @Override
126 - public void sendTipPrivateMessage(Long senderId, Long receiverId, String content) {  
127 - sendTipPrivateMessage(senderId, receiverId, content, null);  
128 - }  
129 -  
130 - @Override  
131 - public void sendTipPrivateMessage(Long senderId, Long receiverId, String content, Boolean persistent) {  
132 - sendPrivateMessage(senderId, new ImPrivateMessageSendDTO().setReceiverId(receiverId)  
133 - .setType(ImMessageTypeEnum.TIP_TEXT.getType()).setContent(content).setPersistent(persistent));  
134 - }  
135 -  
136 - @Override  
137 @Transactional(rollbackFor = Exception.class) 126 @Transactional(rollbackFor = Exception.class)
138 public ImPrivateMessageDO recallPrivateMessage(Long userId, Long messageId) { 127 public ImPrivateMessageDO recallPrivateMessage(Long userId, Long messageId) {
139 // 1.1 校验消息存在 128 // 1.1 校验消息存在
yudao-module-im/src/test/java/cn/iocoder/yudao/module/im/service/friend/ImFriendServiceImplTest.java
@@ -178,10 +178,8 @@ public class ImFriendServiceImplTest extends BaseMockitoUnitTest { @@ -178,10 +178,8 @@ public class ImFriendServiceImplTest extends BaseMockitoUnitTest {
178 verify(adminUserApi).validateUser(2L); 178 verify(adminUserApi).validateUser(2L);
179 // 断言:双向插入 2 条好友关系 179 // 断言:双向插入 2 条好友关系
180 verify(imFriendMapper, times(2)).insert(any(ImFriendDO.class)); 180 verify(imFriendMapper, times(2)).insert(any(ImFriendDO.class));
181 - // 断言:发送提示消息 + 给双方各推送一次好友添加事件  
182 - verify(privateMessageService).sendTipPrivateMessage(eq(1L), eq(2L), anyString());  
183 - verify(imWebSocketService).sendPrivateMessageAsync(eq(1L), any(ImPrivateMessageDTO.class));  
184 - verify(imWebSocketService).sendPrivateMessageAsync(eq(2L), any(ImPrivateMessageDTO.class)); 181 + // 断言:FRIEND_ADD 单条入库(双向 WebSocket 推送由 sendPrivateMessage 内部完成,mock 下不可见)
  182 + verify(privateMessageService).sendPrivateMessage(eq(1L), any());
185 } 183 }
186 } 184 }
187 185
@@ -250,10 +248,8 @@ public class ImFriendServiceImplTest extends BaseMockitoUnitTest { @@ -250,10 +248,8 @@ public class ImFriendServiceImplTest extends BaseMockitoUnitTest {
250 248
251 // 断言:双向更新为 DISABLE 249 // 断言:双向更新为 DISABLE
252 verify(imFriendMapper, times(2)).updateById(any(ImFriendDO.class)); 250 verify(imFriendMapper, times(2)).updateById(any(ImFriendDO.class));
253 - // 断言:推送提示消息 + 双方各推送一次好友删除事件  
254 - verify(privateMessageService).sendTipPrivateMessage(eq(1L), eq(2L), anyString()); 251 + // 断言:仅给 userId 多端推送 FRIEND_DELETE 事件(friendUserId 不感知)
255 verify(imWebSocketService).sendPrivateMessageAsync(eq(1L), any(ImPrivateMessageDTO.class)); 252 verify(imWebSocketService).sendPrivateMessageAsync(eq(1L), any(ImPrivateMessageDTO.class));
256 - verify(imWebSocketService).sendPrivateMessageAsync(eq(2L), any(ImPrivateMessageDTO.class));  
257 } 253 }
258 } 254 }
259 255
yudao-module-im/src/test/java/cn/iocoder/yudao/module/im/service/message/ImGroupMessageServiceImplTest.java
@@ -562,9 +562,9 @@ public class ImGroupMessageServiceImplTest extends BaseMockitoUnitTest { @@ -562,9 +562,9 @@ public class ImGroupMessageServiceImplTest extends BaseMockitoUnitTest {
562 // 调用 562 // 调用
563 ImGroupMessageDO result = groupMessageService.recallGroupMessage(1L, 50L); 563 ImGroupMessageDO result = groupMessageService.recallGroupMessage(1L, 50L);
564 564
565 - // 断言:返回 TIP_TEXT 消息 565 + // 断言:返回撤回消息
566 assertNotNull(result); 566 assertNotNull(result);
567 - // 验证:更新原消息状态 + 插入 tipMessage 567 + // 验证:更新原消息状态 + 插入 RecallMessage
568 verify(groupMessageMapper).updateById(any(ImGroupMessageDO.class)); 568 verify(groupMessageMapper).updateById(any(ImGroupMessageDO.class));
569 verify(groupMessageMapper).insert(any(ImGroupMessageDO.class)); 569 verify(groupMessageMapper).insert(any(ImGroupMessageDO.class));
570 // 验证:给 2 个活跃成员推送撤回提示 570 // 验证:给 2 个活跃成员推送撤回提示
yudao-module-im/src/test/java/cn/iocoder/yudao/module/im/service/message/ImPrivateMessageServiceImplTest.java
@@ -206,9 +206,9 @@ public class ImPrivateMessageServiceImplTest extends BaseMockitoUnitTest { @@ -206,9 +206,9 @@ public class ImPrivateMessageServiceImplTest extends BaseMockitoUnitTest {
206 // 调用 206 // 调用
207 ImPrivateMessageDO result = privateMessageService.recallPrivateMessage(1L, 10L); 207 ImPrivateMessageDO result = privateMessageService.recallPrivateMessage(1L, 10L);
208 208
209 - // 断言:返回 TIP_TEXT 消息 209 + // 断言:返回撤回消息
210 assertNotNull(result); 210 assertNotNull(result);
211 - // 验证:更新原消息状态 + 插入 tipMessage 211 + // 验证:更新原消息状态 + 插入 RecallMessage
212 verify(privateMessageMapper).updateById(any(ImPrivateMessageDO.class)); 212 verify(privateMessageMapper).updateById(any(ImPrivateMessageDO.class));
213 verify(privateMessageMapper).insert(any(ImPrivateMessageDO.class)); 213 verify(privateMessageMapper).insert(any(ImPrivateMessageDO.class));
214 // 验证推送了消息(给接收方和发送方) 214 // 验证推送了消息(给接收方和发送方)
@@ -375,29 +375,6 @@ public class ImPrivateMessageServiceImplTest extends BaseMockitoUnitTest { @@ -375,29 +375,6 @@ public class ImPrivateMessageServiceImplTest extends BaseMockitoUnitTest {
375 verify(imWebSocketService).sendPrivateMessageAsync(eq(2L), any(ImPrivateMessageDTO.class)); 375 verify(imWebSocketService).sendPrivateMessageAsync(eq(2L), any(ImPrivateMessageDTO.class));
376 } 376 }
377 377
378 - // ========== sendTipPrivateMessage ==========  
379 -  
380 - @Test  
381 - public void testSendTipPrivateMessage_success() {  
382 - // 调用  
383 - privateMessageService.sendTipPrivateMessage(1L, 2L, "好友添加成功");  
384 -  
385 - // 断言:插入一条 TIP_TEXT 提示消息  
386 - ArgumentCaptor<ImPrivateMessageDO> captor = ArgumentCaptor.forClass(ImPrivateMessageDO.class);  
387 - verify(privateMessageMapper).insert(captor.capture());  
388 - ImPrivateMessageDO tip = captor.getValue();  
389 - assertEquals(1L, tip.getSenderId());  
390 - assertEquals(2L, tip.getReceiverId());  
391 - assertEquals(ImMessageTypeEnum.TIP_TEXT.getType(), tip.getType());  
392 - assertEquals("好友添加成功", tip.getContent());  
393 - assertEquals(ImMessageStatusEnum.UNREAD.getStatus(), tip.getStatus());  
394 - assertNotNull(tip.getClientMessageId());  
395 - assertNotNull(tip.getSendTime());  
396 - // 断言:给双方各推送一次  
397 - verify(imWebSocketService).sendPrivateMessageAsync(eq(1L), any(ImPrivateMessageDTO.class));  
398 - verify(imWebSocketService).sendPrivateMessageAsync(eq(2L), any(ImPrivateMessageDTO.class));  
399 - }  
400 -  
401 // ========== getPrivateMessageList ========== 378 // ========== getPrivateMessageList ==========
402 379
403 @Test 380 @Test