Commit b0221c21cdc6c54205033ce85aae48896f8104ca

Authored by YunaiV
1 parent b51ca455

♻️ refactor(im):好友模块清理——删 ImFriendServiceImpl 无效的 getSelf 自代理 + Controller 回调参数命…

…名展开 + Consumer 补日志 + silent re-add 注释补充
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/friend/ImFriendController.java
@@ -100,9 +100,9 @@ public class ImFriendController { @@ -100,9 +100,9 @@ public class ImFriendController {
100 // 批量聚合 AdminUser 信息(昵称 / 头像),避免 N+1 100 // 批量聚合 AdminUser 信息(昵称 / 头像),避免 N+1
101 Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap( 101 Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
102 convertList(friends, ImFriendDO::getFriendUserId)); 102 convertList(friends, ImFriendDO::getFriendUserId));
103 - return convertList(friends, f -> {  
104 - ImFriendRespVO vo = BeanUtils.toBean(f, ImFriendRespVO.class);  
105 - MapUtils.findAndThen(userMap, f.getFriendUserId(), user -> 103 + return convertList(friends, friend -> {
  104 + ImFriendRespVO vo = BeanUtils.toBean(friend, ImFriendRespVO.class);
  105 + MapUtils.findAndThen(userMap, friend.getFriendUserId(), user ->
106 vo.setNickname(user.getNickname()).setAvatar(user.getAvatar())); 106 vo.setNickname(user.getNickname()).setAvatar(user.getAvatar()));
107 // 备注 / 昵称的拼音,给前端做字母分桶 + 拼音搜索 107 // 备注 / 昵称的拼音,给前端做字母分桶 + 拼音搜索
108 vo.setDisplayNamePinyin(StrUtils.toPinyin(vo.getDisplayName())) 108 vo.setDisplayNamePinyin(StrUtils.toPinyin(vo.getDisplayName()))
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/friend/ImFriendRequestController.java
@@ -87,13 +87,15 @@ public class ImFriendRequestController { @@ -87,13 +87,15 @@ public class ImFriendRequestController {
87 if (CollUtil.isEmpty(list)) { 87 if (CollUtil.isEmpty(list)) {
88 return Collections.emptyList(); 88 return Collections.emptyList();
89 } 89 }
90 - Set<Long> userIds = convertSetByFlatMap(list, r -> Stream.of(r.getFromUserId(), r.getToUserId())); 90 + // 双向 OR 列表,userIds 取 from + to 两组并集
  91 + Set<Long> userIds = convertSetByFlatMap(list,
  92 + request -> Stream.of(request.getFromUserId(), request.getToUserId()));
91 Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(userIds); 93 Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(userIds);
92 - return convertList(list, r -> {  
93 - ImFriendRequestRespVO vo = BeanUtils.toBean(r, ImFriendRequestRespVO.class);  
94 - MapUtils.findAndThen(userMap, r.getFromUserId(), user -> 94 + return convertList(list, request -> {
  95 + ImFriendRequestRespVO vo = BeanUtils.toBean(request, ImFriendRequestRespVO.class);
  96 + MapUtils.findAndThen(userMap, request.getFromUserId(), user ->
95 vo.setFromNickname(user.getNickname()).setFromAvatar(user.getAvatar())); 97 vo.setFromNickname(user.getNickname()).setFromAvatar(user.getAvatar()));
96 - MapUtils.findAndThen(userMap, r.getToUserId(), user -> 98 + MapUtils.findAndThen(userMap, request.getToUserId(), user ->
97 vo.setToNickname(user.getNickname()).setToAvatar(user.getAvatar())); 99 vo.setToNickname(user.getNickname()).setToAvatar(user.getAvatar()));
98 return vo; 100 return vo;
99 }); 101 });
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/mq/consumer/friend/AdminUserProfileUpdateConsumer.java
@@ -33,6 +33,7 @@ public class AdminUserProfileUpdateConsumer { @@ -33,6 +33,7 @@ public class AdminUserProfileUpdateConsumer {
33 @EventListener 33 @EventListener
34 @Async // Spring Event 默认在 Producer 发送的线程,通过 @Async 实现异步 34 @Async // Spring Event 默认在 Producer 发送的线程,通过 @Async 实现异步
35 public void onMessage(AdminUserProfileUpdateMessage message) { 35 public void onMessage(AdminUserProfileUpdateMessage message) {
  36 + log.info("[onMessage][消息内容({})]", message);
36 Long userId = message.getUserId(); 37 Long userId = message.getUserId();
37 // 1. 找当前用户的所有有效好友(DISABLE 已删的不推) 38 // 1. 找当前用户的所有有效好友(DISABLE 已删的不推)
38 List<ImFriendDO> friends = friendService.getFriendList(userId); 39 List<ImFriendDO> friends = friendService.getFriendList(userId);
@@ -41,6 +42,7 @@ public class AdminUserProfileUpdateConsumer { @@ -41,6 +42,7 @@ public class AdminUserProfileUpdateConsumer {
41 } 42 }
42 43
43 // 2. 给每个好友的多端推 FRIEND_INFO_UPDATED;payload 里 operatorUserId / friendUserId 都是「资料被改的人」 44 // 2. 给每个好友的多端推 FRIEND_INFO_UPDATED;payload 里 operatorUserId / friendUserId 都是「资料被改的人」
  45 + int notifyCount = 0;
44 for (ImFriendDO friend : friends) { 46 for (ImFriendDO friend : friends) {
45 if (CommonStatusEnum.isDisable(friend.getStatus())) { 47 if (CommonStatusEnum.isDisable(friend.getStatus())) {
46 continue; 48 continue;
@@ -49,7 +51,9 @@ public class AdminUserProfileUpdateConsumer { @@ -49,7 +51,9 @@ public class AdminUserProfileUpdateConsumer {
49 .setOperatorUserId(userId).setFriendUserId(userId); 51 .setOperatorUserId(userId).setFriendUserId(userId);
50 websocketService.sendPrivateMessageAsync(friend.getFriendUserId(), ImPrivateMessageDTO.ofFriendNotification( 52 websocketService.sendPrivateMessageAsync(friend.getFriendUserId(), ImPrivateMessageDTO.ofFriendNotification(
51 ImMessageTypeEnum.FRIEND_INFO_UPDATED.getType(), userId, friend.getFriendUserId(), payload)); 53 ImMessageTypeEnum.FRIEND_INFO_UPDATED.getType(), userId, friend.getFriendUserId(), payload));
  54 + notifyCount++;
52 } 55 }
  56 + log.info("[onMessage][userId({}) 推送 FRIEND_INFO_UPDATED 给 {} 位好友]", userId, notifyCount);
53 } 57 }
54 58
55 } 59 }
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/friend/ImFriendServiceImpl.java
1 package cn.iocoder.yudao.module.im.service.friend; 1 package cn.iocoder.yudao.module.im.service.friend;
2 2
3 import cn.hutool.core.util.BooleanUtil; 3 import cn.hutool.core.util.BooleanUtil;
4 -import cn.hutool.extra.spring.SpringUtil;  
5 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; 4 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
6 import cn.iocoder.yudao.framework.common.pojo.PageResult; 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
7 import cn.iocoder.yudao.module.im.controller.admin.friend.vo.ImFriendUpdateReqVO; 6 import cn.iocoder.yudao.module.im.controller.admin.friend.vo.ImFriendUpdateReqVO;
@@ -124,8 +123,8 @@ public class ImFriendServiceImpl implements ImFriendService { @@ -124,8 +123,8 @@ public class ImFriendServiceImpl implements ImFriendService {
124 Long toUserId = request.getToUserId(); 123 Long toUserId = request.getToUserId();
125 // 1. 双向建立关系:A 侧带申请的 displayName / addSource;B 侧 displayName 为空、addSource 同来源 124 // 1. 双向建立关系:A 侧带申请的 displayName / addSource;B 侧 displayName 为空、addSource 同来源
126 // FRIEND_STATE 双向失效由方法上的 @Caching 注解处理;framework 已开 transactionAware 自动延迟到 afterCommit 125 // FRIEND_STATE 双向失效由方法上的 @Caching 注解处理;framework 已开 transactionAware 自动延迟到 afterCommit
127 - getSelf().addFriend0(fromUserId, toUserId, request.getDisplayName(), request.getAddSource());  
128 - getSelf().addFriend0(toUserId, fromUserId, null, request.getAddSource()); 126 + addFriend0(fromUserId, toUserId, request.getDisplayName(), request.getAddSource());
  127 + addFriend0(toUserId, fromUserId, null, request.getAddSource());
129 128
130 // 2.1 推 TIP 系统消息(双方私聊会话里看到「你们已成为好友」);TIP 走会话入库,FRIEND_ADD 走事件通知 129 // 2.1 推 TIP 系统消息(双方私聊会话里看到「你们已成为好友」);TIP 走会话入库,FRIEND_ADD 走事件通知
131 privateMessageService.sendTipPrivateMessage(fromUserId, toUserId, FRIEND_ADD_TIP_MESSAGE); 130 privateMessageService.sendTipPrivateMessage(fromUserId, toUserId, FRIEND_ADD_TIP_MESSAGE);
@@ -150,7 +149,8 @@ public class ImFriendServiceImpl implements ImFriendService { @@ -150,7 +149,8 @@ public class ImFriendServiceImpl implements ImFriendService {
150 @Transactional(rollbackFor = Exception.class) 149 @Transactional(rollbackFor = Exception.class)
151 public void silentReAddFriend(Long userId, Long friendUserId, String displayName, Integer addSource) { 150 public void silentReAddFriend(Long userId, Long friendUserId, String displayName, Integer addSource) {
152 // 1. 单边重新启用我侧好友关系 151 // 1. 单边重新启用我侧好友关系
153 - getSelf().addFriend0(userId, friendUserId, displayName, addSource); 152 + // 不推 TIP 系统消息:sendPrivateMessage 是 (sender, receiver) 单条入库 + 双向可见,无法仅 userId 单边可见;对方不应感知 silent 重启,TIP 整体省略
  153 + addFriend0(userId, friendUserId, displayName, addSource);
154 154
155 // 2. 仅推 FRIEND_ADD 给 userId 多端(不通知对方,保持「对方一直把我当好友」的错觉) 155 // 2. 仅推 FRIEND_ADD 给 userId 多端(不通知对方,保持「对方一直把我当好友」的错觉)
156 // operatorUserId 填 friendUserId(对方):让 userId 多端 UI 呈现「对方加了我」的视觉效果,与 silent 语义对齐 156 // operatorUserId 填 friendUserId(对方):让 userId 多端 UI 呈现「对方加了我」的视觉效果,与 silent 语义对齐
@@ -169,7 +169,7 @@ public class ImFriendServiceImpl implements ImFriendService { @@ -169,7 +169,7 @@ public class ImFriendServiceImpl implements ImFriendService {
169 public void deleteFriend(Long userId, Long friendUserId) { 169 public void deleteFriend(Long userId, Long friendUserId) {
170 // 1. 单边软删:仅 userId 视角的关系置 DISABLE;friendUserId 视角不动 170 // 1. 单边软删:仅 userId 视角的关系置 DISABLE;friendUserId 视角不动
171 // 不推 TIP 系统消息:单边删除语义下对方不应感知;userId 端反馈由前端 toast 承担,多端同步靠下面的 FRIEND_DELETE 171 // 不推 TIP 系统消息:单边删除语义下对方不应感知;userId 端反馈由前端 toast 承担,多端同步靠下面的 FRIEND_DELETE
172 - getSelf().deleteFriend0(userId, friendUserId); 172 + deleteFriend0(userId, friendUserId);
173 173
174 // 2. 推 FRIEND_DELETE 给 userId 多端做同步(friendUserId 不感知) 174 // 2. 推 FRIEND_DELETE 给 userId 多端做同步(friendUserId 不感知)
175 FriendDeleteNotification payload = (FriendDeleteNotification) new FriendDeleteNotification() 175 FriendDeleteNotification payload = (FriendDeleteNotification) new FriendDeleteNotification()
@@ -287,8 +287,4 @@ public class ImFriendServiceImpl implements ImFriendService { @@ -287,8 +287,4 @@ public class ImFriendServiceImpl implements ImFriendService {
287 return friendMapper.selectPage(reqVO); 287 return friendMapper.selectPage(reqVO);
288 } 288 }
289 289
290 - private ImFriendServiceImpl getSelf() {  
291 - return SpringUtil.getBean(getClass());  
292 - }  
293 -  
294 } 290 }