Commit 28cf87ac8afff15d1e362152e8aa65dfca1f7a04
1 parent
0d7cb763
feat(im): 重构普通消息类型,和 openim 的消息编号对齐
Showing
8 changed files
with
72 additions
and
122 deletions
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/enums/ImCommonConstants.java
| ... | ... | @@ -54,15 +54,4 @@ public interface ImCommonConstants { |
| 54 | 54 | */ |
| 55 | 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 | 17 | @RequiredArgsConstructor |
| 18 | 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 | 64 | // ========== 好友通知(1201-1210 直接复用 OpenIM 段位编号) ========== |
| 36 | 65 | /** |
| ... | ... | @@ -52,11 +81,12 @@ public enum ImMessageTypeEnum implements ArrayValuable<Integer> { |
| 52 | 81 | */ |
| 53 | 82 | FRIEND_REQUEST_RECEIVED(1203, "收到新的好友申请", false, false), |
| 54 | 83 | /** |
| 55 | - * 对应 OpenIM:FriendAddedNotification 1204 | |
| 84 | + * 对应 OpenIM:FriendAddedNotification 1204(OpenIM friendAdded.isSendMsg=false 默认不入消息流;本系统改为入库当会话气泡) | |
| 56 | 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 | 91 | * 对应 OpenIM:FriendDeletedNotification 1205 |
| 62 | 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 | 11 | import cn.iocoder.yudao.module.im.enums.friend.ImFriendStateEnum; |
| 12 | 12 | import cn.iocoder.yudao.module.im.enums.message.ImMessageTypeEnum; |
| 13 | 13 | import cn.iocoder.yudao.module.im.service.message.ImPrivateMessageService; |
| 14 | +import cn.iocoder.yudao.module.im.service.message.dto.ImPrivateMessageSendDTO; | |
| 14 | 15 | import cn.iocoder.yudao.module.im.service.websocket.ImWebSocketService; |
| 15 | 16 | import cn.iocoder.yudao.module.im.service.websocket.dto.ImPrivateMessageDTO; |
| 16 | 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 | 33 | import static cn.iocoder.yudao.module.im.dal.redis.RedisKeyConstants.FRIEND_STATE; |
| 33 | 34 | import static cn.iocoder.yudao.module.im.enums.ErrorCodeConstants.FRIEND_NOT_BLOCKED; |
| 34 | 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 | 38 | * IM 好友关系 Service 实现类 |
| ... | ... | @@ -130,19 +129,12 @@ public class ImFriendServiceImpl implements ImFriendService { |
| 130 | 129 | addFriend0(fromUserId, toUserId, request.getDisplayName(), request.getAddSource()); |
| 131 | 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 | 140 | @Override |
| ... | ... | @@ -155,15 +147,14 @@ public class ImFriendServiceImpl implements ImFriendService { |
| 155 | 147 | // 1. 单边重新启用我侧好友关系 |
| 156 | 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 | 153 | FriendAddNotification payload = (FriendAddNotification) new FriendAddNotification() |
| 164 | 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 | 160 | @Override |
| ... | ... | @@ -176,17 +167,14 @@ public class ImFriendServiceImpl implements ImFriendService { |
| 176 | 167 | // 1. 单边软删:仅 userId 视角的关系置 DISABLE;friendUserId 视角不动 |
| 177 | 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 | 173 | FriendDeleteNotification payload = ((FriendDeleteNotification) new FriendDeleteNotification() |
| 187 | 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 | 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 | 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 | 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 | 123 | } |
| 124 | 124 | |
| 125 | 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 | 126 | @Transactional(rollbackFor = Exception.class) |
| 138 | 127 | public ImPrivateMessageDO recallPrivateMessage(Long userId, Long messageId) { |
| 139 | 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 | 178 | verify(adminUserApi).validateUser(2L); |
| 179 | 179 | // 断言:双向插入 2 条好友关系 |
| 180 | 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 | 248 | |
| 251 | 249 | // 断言:双向更新为 DISABLE |
| 252 | 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 | 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 | 562 | // 调用 |
| 563 | 563 | ImGroupMessageDO result = groupMessageService.recallGroupMessage(1L, 50L); |
| 564 | 564 | |
| 565 | - // 断言:返回 TIP_TEXT 消息 | |
| 565 | + // 断言:返回撤回消息 | |
| 566 | 566 | assertNotNull(result); |
| 567 | - // 验证:更新原消息状态 + 插入 tipMessage | |
| 567 | + // 验证:更新原消息状态 + 插入 RecallMessage | |
| 568 | 568 | verify(groupMessageMapper).updateById(any(ImGroupMessageDO.class)); |
| 569 | 569 | verify(groupMessageMapper).insert(any(ImGroupMessageDO.class)); |
| 570 | 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 | 206 | // 调用 |
| 207 | 207 | ImPrivateMessageDO result = privateMessageService.recallPrivateMessage(1L, 10L); |
| 208 | 208 | |
| 209 | - // 断言:返回 TIP_TEXT 消息 | |
| 209 | + // 断言:返回撤回消息 | |
| 210 | 210 | assertNotNull(result); |
| 211 | - // 验证:更新原消息状态 + 插入 tipMessage | |
| 211 | + // 验证:更新原消息状态 + 插入 RecallMessage | |
| 212 | 212 | verify(privateMessageMapper).updateById(any(ImPrivateMessageDO.class)); |
| 213 | 213 | verify(privateMessageMapper).insert(any(ImPrivateMessageDO.class)); |
| 214 | 214 | // 验证推送了消息(给接收方和发送方) |
| ... | ... | @@ -375,29 +375,6 @@ public class ImPrivateMessageServiceImplTest extends BaseMockitoUnitTest { |
| 375 | 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 | 378 | // ========== getPrivateMessageList ========== |
| 402 | 379 | |
| 403 | 380 | @Test | ... | ... |