Commit b0221c21cdc6c54205033ce85aae48896f8104ca
1 parent
b51ca455
♻️ refactor(im):好友模块清理——删 ImFriendServiceImpl 无效的 getSelf 自代理 + Controller 回调参数命…
…名展开 + Consumer 补日志 + silent re-add 注释补充
Showing
4 changed files
with
19 additions
and
17 deletions
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 | } |