问题描述
在商铺分页查询功能中,前端存在以下显示问题:
- 选择分类后往下翻不能自动滚动分页查询所有数据。
- 点击距离排序后,第一页数据被查询了两次,后续页面正常。
原因分析
经排查,根源在于后端 Redis GEO 查询的 Limit 参数与前端分页大小不匹配,导致数据流截断异常。Redis 预查的数据量不足以满足当前分页需求,造成前端滚动加载失效或重复请求。
代码实现
Controller 层
/**
* 根据商铺类型分页查询商铺信息
* @param typeId 商铺类型
* @param current 页码
* @param x 经度
* @param y 纬度
* @return 商铺列表
*/
@GetMapping("/of/type")
public Result queryShopByType(
@RequestParam("typeId") Integer typeId,
@RequestParam(value = "current", defaultValue = "1") Integer current,
@RequestParam("x") Double x,
@RequestParam("y") Double y) {
// 调用 Service 层方法(修正方法名驼峰规范)
return shopService.queryShopByType(typeId, current, x, y);
}
ServiceImpl 层
@Override
public Result queryShopByType(Integer typeId, Integer current, Double x, Double y) {
if (x == null || y == null) {
// 直接返回对应类型的店铺就行了
Page<Shop> page = query()
.eq("type_id", typeId)
.page(new Page<>(current, SystemConstants.DEFAULT_PAGE_SIZE));
return Result.ok(page.getRecords());
}
int from = (current - 1) * SystemConstants.DEFAULT_PAGE_SIZE;
int current * SystemConstants.DEFAULT_PAGE_SIZE;
+ typeId;
(, Metrics.METERS);
GeoResults<RedisGeoCommands.GeoLocation<String>> geoResults = stringRedisTemplate.opsForGeo()
.search(key,
GeoReference.fromCoordinate( (x, y)),
distance,
RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs()
.sortAscending()
.limit(end)
.includeDistance()
.includeCoordinates());
(geoResults == || geoResults.getContent().isEmpty()) {
Result.ok(Collections.emptyList());
}
List<GeoResult<RedisGeoCommands.GeoLocation<String>>> pageGeoList = geoResults.getContent().stream()
.skip(from)
.limit(SystemConstants.DEFAULT_PAGE_SIZE)
.collect(Collectors.toList());
List<Long> shopIds = pageGeoList.stream()
.map(geoResult -> Long.valueOf(geoResult.getContent().getName()))
.collect(Collectors.toList());
(shopIds.isEmpty()) {
Result.ok(Collections.emptyList());
}
StringUtil.join(shopIds, );
List<Shop> shopList = query().in(, shopIds).last(( + shopIdstr + )).list();
( ; i < pageGeoList.size(); i++) {
GeoResult<RedisGeoCommands.GeoLocation<String>> geoResult = pageGeoList.get(i);
shopList.get(i);
geoResult.getDistance().getValue();
shop.setDistance(distValue);
}
Result.ok(shopList);
}


