Commit 716738ac5d521ba6013f28bf6a9264fbc00c3b95
1 parent
92a993b2
fix(im):群昵称修改改为静默同步
- 后端将 GROUP_MEMBER_NICKNAME_UPDATE 改为非持久化事件,避免写入群聊历史消息 - 保留群昵称变更的 WebSocket 在线同步,继续更新成员 displayUserName - Vue3 聊天侧栏从当前群成员的 displayUserName 回填「我在本群的昵称」 - Vue3 WebSocket 收到 GROUP_MEMBER_NICKNAME_UPDATE 时只同步 groupStore,不再插入消息列表 - 补充后端单测,覆盖群昵称变更事件不入库但仍推送
Showing
4 changed files
with
18 additions
and
4 deletions
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/enums/ImContentTypeEnum.java
| ... | ... | @@ -281,9 +281,9 @@ public enum ImContentTypeEnum implements ArrayValuable<Integer> { |
| 281 | 281 | /** |
| 282 | 282 | * 对应 OpenIM:sdkws.GroupMemberInfoSetTips(GroupMemberInfoSetNotification 1516,窄化到 displayUserName) |
| 283 | 283 | * 对应自己的类:GroupMemberNicknameUpdateNotification |
| 284 | - * 场景:成员修改自己在群里的昵称,全员广播;前端按 displayUserName 局部更新对应 member | |
| 284 | + * 场景:成员修改自己在群里的昵称,在线成员同步对应 member | |
| 285 | 285 | */ |
| 286 | - GROUP_MEMBER_NICKNAME_UPDATE(1516, "成员昵称变更", true, false), | |
| 286 | + GROUP_MEMBER_NICKNAME_UPDATE(1516, "成员昵称变更", false, false), | |
| 287 | 287 | /** |
| 288 | 288 | * 对应 OpenIM:GroupMemberSetToAdminNotification 1517 |
| 289 | 289 | * 对应自己的类:GroupAdminAddNotification | ... | ... |
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/group/ImGroupMemberServiceImpl.java
| ... | ... | @@ -258,7 +258,7 @@ public class ImGroupMemberServiceImpl implements ImGroupMemberService { |
| 258 | 258 | .setId(member.getId()); |
| 259 | 259 | groupMemberMapper.updateById(updateObj); |
| 260 | 260 | |
| 261 | - // 3.1 displayUserName 是公开字段,单独走 GROUP_MEMBER_NICKNAME_UPDATE 广播给全员;空串视为「清空昵称」也要广播;与旧值相同跳过 | |
| 261 | + // 3.1 displayUserName 是公开字段,单独走 GROUP_MEMBER_NICKNAME_UPDATE 在线同步给全员;空串视为「清空昵称」也要同步;与旧值相同跳过 | |
| 262 | 262 | if (updateReqVO.getDisplayUserName() != null |
| 263 | 263 | && ObjUtil.notEqual(updateReqVO.getDisplayUserName(), member.getDisplayUserName())) { |
| 264 | 264 | groupMessageService.sendGroupMessage(userId, ImGroupMessageSendDTO.ofGroupMemberNicknameUpdate( | ... | ... |
yudao-module-im/src/test/java/cn/iocoder/yudao/module/im/service/group/ImGroupMemberServiceImplTest.java
| ... | ... | @@ -242,7 +242,7 @@ public class ImGroupMemberServiceImplTest extends BaseMockitoUnitTest { |
| 242 | 242 | verify(groupMemberMapper).updateById(captor.capture()); |
| 243 | 243 | assertEquals(50L, captor.getValue().getId()); |
| 244 | 244 | assertTrue(captor.getValue().getSilent()); |
| 245 | - // 公开字段昵称变化 → 全员广播 GROUP_MEMBER_NICKNAME_UPDATE | |
| 245 | + // 公开字段昵称变化 → 全员在线同步 GROUP_MEMBER_NICKNAME_UPDATE | |
| 246 | 246 | verify(groupMessageService).sendGroupMessage(eq(1L), any(cn.iocoder.yudao.module.im.service.message.dto.ImGroupMessageSendDTO.class)); |
| 247 | 247 | // 个人字段 silent 变化 → 仅自己多端同步 GROUP_MEMBER_SETTING_UPDATE |
| 248 | 248 | verify(groupMessageService).sendGroupMessage(eq(1L), eq(ListUtil.of(1L)), | ... | ... |
yudao-module-im/src/test/java/cn/iocoder/yudao/module/im/service/message/ImGroupMessageServiceImplTest.java
| ... | ... | @@ -961,6 +961,20 @@ public class ImGroupMessageServiceImplTest extends BaseMockitoUnitTest { |
| 961 | 961 | } |
| 962 | 962 | |
| 963 | 963 | @Test |
| 964 | + public void testSendGroupMessage_dto_groupMemberNicknameUpdateNotInserted() { | |
| 965 | + // 准备:成员昵称变更只做在线同步,不入库 | |
| 966 | + ImGroupMessageSendDTO dto = ImGroupMessageSendDTO.ofGroupMemberNicknameUpdate(10L, 1L, "群昵称"); | |
| 967 | + when(groupMemberService.getActiveGroupMemberUserIdsByGroupId(10L)).thenReturn(List.of(1L, 2L)); | |
| 968 | + | |
| 969 | + groupMessageService.sendGroupMessage(1L, dto); | |
| 970 | + | |
| 971 | + verify(groupMessageMapper, never()).insert(any(ImGroupMessageDO.class)); | |
| 972 | + verify(imWebSocketService).sendNotificationAsync(argThat((Collection<Long> ids) -> | |
| 973 | + ids.size() == 2 && ids.contains(1L) && ids.contains(2L)), | |
| 974 | + anyInt(), eq(ImContentTypeEnum.GROUP_MEMBER_NICKNAME_UPDATE.getType()), any()); | |
| 975 | + } | |
| 976 | + | |
| 977 | + @Test | |
| 964 | 978 | public void testSendGroupMessage_threeArg_explicitTargetsBypassActiveMembers() { |
| 965 | 979 | // 准备:调用方传入显式 targets(解散场景成员已被批量 DISABLE,必须按移除前快照推送) |
| 966 | 980 | Set<Long> targets = Set.of(1L, 2L, 3L); | ... | ... |