Commit eb2d3c39e21ed1f607ef4afe76de2df43a1baf55
1 parent
b5f5c408
♻️ refactor(im):用户申请列表,增加流式查询,避免一次性加载过多,或者历史无法被加载到。
Showing
4 changed files
with
47 additions
and
12 deletions
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/friend/ImFriendRequestController.java
| 1 | 1 | package cn.iocoder.yudao.module.im.controller.admin.friend; |
| 2 | 2 | |
| 3 | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | +import cn.hutool.core.util.ObjUtil; | |
| 4 | 5 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 5 | 6 | import cn.iocoder.yudao.framework.common.util.collection.MapUtils; |
| 6 | 7 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| ... | ... | @@ -15,6 +16,7 @@ import io.swagger.v3.oas.annotations.Parameter; |
| 15 | 16 | import io.swagger.v3.oas.annotations.tags.Tag; |
| 16 | 17 | import jakarta.annotation.Resource; |
| 17 | 18 | import jakarta.validation.Valid; |
| 19 | +import jakarta.validation.constraints.Min; | |
| 18 | 20 | import jakarta.validation.constraints.NotNull; |
| 19 | 21 | import jakarta.validation.constraints.Size; |
| 20 | 22 | import org.springframework.validation.annotation.Validated; |
| ... | ... | @@ -75,12 +77,29 @@ public class ImFriendRequestController { |
| 75 | 77 | } |
| 76 | 78 | |
| 77 | 79 | @GetMapping("/list") |
| 78 | - @Operation(summary = "查询「我相关」的好友申请列表(含我发起的、别人加我的)") | |
| 79 | - public CommonResult<List<ImFriendRequestRespVO>> getMyFriendRequestList() { | |
| 80 | - List<ImFriendRequestDO> list = friendRequestService.getMyFriendRequestList(getLoginUserId()); | |
| 80 | + @Operation(summary = "查询「我相关」的好友申请列表(游标分页:传 lastRequestId 加载更多)") | |
| 81 | + public CommonResult<List<ImFriendRequestRespVO>> getMyFriendRequestList( | |
| 82 | + @Parameter(description = "当前列表最旧记录的 id;首页不传") | |
| 83 | + @RequestParam(value = "lastRequestId", required = false) Long lastRequestId, | |
| 84 | + @Parameter(description = "单次拉取条数", required = true) @RequestParam("limit") @Min(1) Integer limit) { | |
| 85 | + List<ImFriendRequestDO> list = friendRequestService.getMyFriendRequestList(getLoginUserId(), lastRequestId, limit); | |
| 81 | 86 | return success(buildList(list)); |
| 82 | 87 | } |
| 83 | 88 | |
| 89 | + @GetMapping("/get") | |
| 90 | + @Operation(summary = "按 id 单查「我相关」的申请记录(带越权过滤;WebSocket 通知到达后用)") | |
| 91 | + @Parameter(name = "id", description = "申请记录编号", required = true) | |
| 92 | + public CommonResult<ImFriendRequestRespVO> getMyFriendRequest(@RequestParam("id") Long id) { | |
| 93 | + ImFriendRequestDO request = friendRequestService.getFriendRequest(id); | |
| 94 | + // 越权过滤:fromUser / toUser 必有一方是当前用户,否则当不存在返回 null | |
| 95 | + Long currentUserId = getLoginUserId(); | |
| 96 | + if (request == null || (ObjUtil.notEqual(request.getFromUserId(), currentUserId) | |
| 97 | + && ObjUtil.notEqual(request.getToUserId(), currentUserId))) { | |
| 98 | + return success(null); | |
| 99 | + } | |
| 100 | + return success(CollUtil.getFirst(buildList(Collections.singletonList(request)))); | |
| 101 | + } | |
| 102 | + | |
| 84 | 103 | // ========== 私有方法:VO 组装 ========== |
| 85 | 104 | |
| 86 | 105 | private List<ImFriendRequestRespVO> buildList(List<ImFriendRequestDO> list) { | ... | ... |
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/friend/ImFriendRequestMapper.java
| ... | ... | @@ -24,10 +24,14 @@ public interface ImFriendRequestMapper extends BaseMapperX<ImFriendRequestDO> { |
| 24 | 24 | .last("LIMIT 1")); |
| 25 | 25 | } |
| 26 | 26 | |
| 27 | - default List<ImFriendRequestDO> selectMyList(Long userId, int limit) { | |
| 28 | - // 先放扩展过滤再放双向 OR;否则 .and() 返回 LambdaQueryWrapper 基类,丢失 eqIfPresent 等扩展方法 | |
| 27 | + /** | |
| 28 | + * 拉取「我相关」的好友申请列表;游标分页:lastRequestId 为 null 拉首页,非 null 拉 id 严格小于它的下一页 | |
| 29 | + */ | |
| 30 | + default List<ImFriendRequestDO> selectMyList(Long userId, Long lastRequestId, int limit) { | |
| 31 | + // 先放扩展过滤再放双向 OR;否则 .and() 返回 LambdaQueryWrapper 基类,丢失 ltIfPresent 等扩展方法 | |
| 29 | 32 | LambdaQueryWrapperX<ImFriendRequestDO> wrapper = new LambdaQueryWrapperX<>(); |
| 30 | - wrapper.and(w -> w.eq(ImFriendRequestDO::getFromUserId, userId) | |
| 33 | + wrapper.ltIfPresent(ImFriendRequestDO::getId, lastRequestId) | |
| 34 | + .and(w -> w.eq(ImFriendRequestDO::getFromUserId, userId) | |
| 31 | 35 | .or().eq(ImFriendRequestDO::getToUserId, userId)) |
| 32 | 36 | .orderByDesc(ImFriendRequestDO::getId) |
| 33 | 37 | .last("LIMIT " + limit); | ... | ... |
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/friend/ImFriendRequestService.java
| ... | ... | @@ -39,11 +39,18 @@ public interface ImFriendRequestService { |
| 39 | 39 | void refuseFriendRequest(Long userId, Long requestId, String handleContent); |
| 40 | 40 | |
| 41 | 41 | /** |
| 42 | - * 查询「我相关」的申请列表(含我发起的、别人加我的) | |
| 42 | + * 查询「我相关」的申请列表(含我发起的、别人加我的);游标分页:传 lastRequestId 拉它之前的下一页 | |
| 43 | 43 | * |
| 44 | - * @param userId 用户编号 | |
| 45 | - * @return 申请记录列表 | |
| 44 | + * @param userId 用户编号 | |
| 45 | + * @param lastRequestId 当前列表最旧记录的 id;首页传 null | |
| 46 | + * @param limit 单次拉取条数(page size,由前端常量控制) | |
| 47 | + * @return 申请记录列表,按 id 倒序 | |
| 46 | 48 | */ |
| 47 | - List<ImFriendRequestDO> getMyFriendRequestList(Long userId); | |
| 49 | + List<ImFriendRequestDO> getMyFriendRequestList(Long userId, Long lastRequestId, Integer limit); | |
| 50 | + | |
| 51 | + /** | |
| 52 | + * 按 id 单查申请记录;通用读接口,调用方自行做越权过滤 | |
| 53 | + */ | |
| 54 | + ImFriendRequestDO getFriendRequest(Long id); | |
| 48 | 55 | |
| 49 | 56 | } | ... | ... |
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/friend/ImFriendRequestServiceImpl.java
| ... | ... | @@ -183,8 +183,13 @@ public class ImFriendRequestServiceImpl implements ImFriendRequestService { |
| 183 | 183 | } |
| 184 | 184 | |
| 185 | 185 | @Override |
| 186 | - public List<ImFriendRequestDO> getMyFriendRequestList(Long userId) { | |
| 187 | - return friendRequestMapper.selectMyList(userId, imProperties.getFriend().getRequestListMaxSize()); | |
| 186 | + public List<ImFriendRequestDO> getMyFriendRequestList(Long userId, Long lastRequestId, Integer limit) { | |
| 187 | + return friendRequestMapper.selectMyList(userId, lastRequestId, limit); | |
| 188 | + } | |
| 189 | + | |
| 190 | + @Override | |
| 191 | + public ImFriendRequestDO getFriendRequest(Long id) { | |
| 192 | + return friendRequestMapper.selectById(id); | |
| 188 | 193 | } |
| 189 | 194 | |
| 190 | 195 | /** | ... | ... |