diff --git a/src/main/java/com/youlai/boot/mini/controller/StrayAnimalController.java b/src/main/java/com/youlai/boot/mini/controller/StrayAnimalController.java index 438099c..0059228 100644 --- a/src/main/java/com/youlai/boot/mini/controller/StrayAnimalController.java +++ b/src/main/java/com/youlai/boot/mini/controller/StrayAnimalController.java @@ -14,6 +14,8 @@ import com.youlai.boot.mini.model.form.NoteCollectForm; import com.youlai.boot.mini.model.form.NoteLikeForm; import com.youlai.boot.mini.model.form.StrayAnimalForm; import com.youlai.boot.mini.model.query.OwnStrayAnimalQuery; +import com.youlai.boot.mini.model.query.WaterfallQuery; +import com.youlai.boot.mini.model.vo.WaterfallResult; import com.youlai.boot.mini.model.vo.SaveStrayAnimalVO; import com.youlai.boot.mini.model.vo.StrayAnimalDetailsVO; import com.youlai.boot.mini.model.vo.StrayAnimalShortVO; @@ -175,7 +177,15 @@ public class StrayAnimalController { return Result.success(result); } - //获取流浪动物笔记瀑布流 + @Operation(summary = "获取流浪动物笔记瀑布流") + @GetMapping(value = "/note/waterfall") + public Result> getWaterfall( + @Valid WaterfallQuery query + ) { + Long userId = SecurityUtils.getUserId(); + WaterfallResult result = strayAnimalService.getWaterfall(query, userId); + return Result.success(result); + } //增加浏览量 diff --git a/src/main/java/com/youlai/boot/mini/mapper/MiniStrayAnimalMapper.java b/src/main/java/com/youlai/boot/mini/mapper/MiniStrayAnimalMapper.java index 65440d5..f3e211a 100644 --- a/src/main/java/com/youlai/boot/mini/mapper/MiniStrayAnimalMapper.java +++ b/src/main/java/com/youlai/boot/mini/mapper/MiniStrayAnimalMapper.java @@ -30,4 +30,6 @@ public interface MiniStrayAnimalMapper extends BaseMapper { StrayAnimalDetailsVO getStrayAnimalDetails(@Param("animalUuid") String animalUuid, @Param("miniUserId") Long miniUserId); List listByMapBounds(MapSearchDTO mapSearch); + + List getWaterfall(@Param("cursor") Long cursor, @Param("pageSize") Integer pageSize, @Param("animalType") String animalType, @Param("miniUserId") Long miniUserId); } diff --git a/src/main/java/com/youlai/boot/mini/model/query/WaterfallQuery.java b/src/main/java/com/youlai/boot/mini/model/query/WaterfallQuery.java new file mode 100644 index 0000000..d43b5d1 --- /dev/null +++ b/src/main/java/com/youlai/boot/mini/model/query/WaterfallQuery.java @@ -0,0 +1,19 @@ +package com.youlai.boot.mini.model.query; + +import com.youlai.boot.common.base.BaseQuery; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import lombok.Data; + +@Data +@Schema(description = "瀑布流查询参数") +public class WaterfallQuery extends BaseQuery { + + @Schema(description = "游标(上一页最后一条的ID,首次请求不传)", example = "100") + private Long cursor; + + @Schema(description = "动物类型筛选(cat-猫 dog-狗 other-其他)", example = "cat") + private String animalType; + +} diff --git a/src/main/java/com/youlai/boot/mini/model/vo/StrayAnimalShortVO.java b/src/main/java/com/youlai/boot/mini/model/vo/StrayAnimalShortVO.java index b07deab..7184f69 100644 --- a/src/main/java/com/youlai/boot/mini/model/vo/StrayAnimalShortVO.java +++ b/src/main/java/com/youlai/boot/mini/model/vo/StrayAnimalShortVO.java @@ -7,6 +7,9 @@ import lombok.Data; @Data public class StrayAnimalShortVO { + @Schema(description = "笔记ID(仅用于瀑布流游标,前端不需要展示)", hidden = true) + private Long id; + @Schema(description = "作者uuid", example = "true") private String authorUuid; diff --git a/src/main/java/com/youlai/boot/mini/model/vo/WaterfallResult.java b/src/main/java/com/youlai/boot/mini/model/vo/WaterfallResult.java new file mode 100644 index 0000000..7e86135 --- /dev/null +++ b/src/main/java/com/youlai/boot/mini/model/vo/WaterfallResult.java @@ -0,0 +1,28 @@ +package com.youlai.boot.mini.model.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.List; + +@Data +@Schema(description = "瀑布流返回结果") +public class WaterfallResult { + + @Schema(description = "数据列表") + private List list; + + @Schema(description = "下一页游标(传null表示没有更多了)", example = "100") + private Long nextCursor; + + @Schema(description = "是否最后一页", example = "false") + private Boolean isLastPage; + + public static WaterfallResult of(List list, Long nextCursor, boolean isLastPage) { + WaterfallResult result = new WaterfallResult<>(); + result.setList(list); + result.setNextCursor(nextCursor); + result.setIsLastPage(isLastPage); + return result; + } +} diff --git a/src/main/java/com/youlai/boot/mini/service/StrayAnimalService.java b/src/main/java/com/youlai/boot/mini/service/StrayAnimalService.java index 8d205bb..e2e2c25 100644 --- a/src/main/java/com/youlai/boot/mini/service/StrayAnimalService.java +++ b/src/main/java/com/youlai/boot/mini/service/StrayAnimalService.java @@ -9,8 +9,11 @@ import com.youlai.boot.mini.model.dto.MapSearchDTO; import com.youlai.boot.mini.model.entity.MiniStrayAnimal; import com.youlai.boot.mini.model.form.NoteCollectForm; import com.youlai.boot.mini.model.form.NoteLikeForm; +import com.youlai.boot.mini.model.form.NoteCollectForm; import com.youlai.boot.mini.model.form.StrayAnimalForm; import com.youlai.boot.mini.model.query.OwnStrayAnimalQuery; +import com.youlai.boot.mini.model.query.WaterfallQuery; +import com.youlai.boot.mini.model.vo.WaterfallResult; import com.youlai.boot.mini.model.vo.SaveStrayAnimalVO; import com.youlai.boot.mini.model.vo.StrayAnimalDetailsVO; import com.youlai.boot.mini.model.vo.StrayAnimalNearbyVO; @@ -48,5 +51,7 @@ public interface StrayAnimalService extends IService { Map toggleNoteLike(NoteLikeForm form, Long userId); Map toggleNoteCollect(NoteCollectForm form, Long userId); + + WaterfallResult getWaterfall(WaterfallQuery query, Long userId); } diff --git a/src/main/java/com/youlai/boot/mini/service/impl/StrayAnimalServiceImpl.java b/src/main/java/com/youlai/boot/mini/service/impl/StrayAnimalServiceImpl.java index 5863078..3c6cfb8 100644 --- a/src/main/java/com/youlai/boot/mini/service/impl/StrayAnimalServiceImpl.java +++ b/src/main/java/com/youlai/boot/mini/service/impl/StrayAnimalServiceImpl.java @@ -38,6 +38,7 @@ import com.youlai.boot.mini.model.entity.MiniStrayAnimalNote; import com.youlai.boot.mini.model.entity.MiniStrayAnimalNoteMedia; import com.youlai.boot.mini.model.form.StrayAnimalForm; import com.youlai.boot.mini.model.query.OwnStrayAnimalQuery; +import com.youlai.boot.mini.model.query.WaterfallQuery; import com.youlai.boot.mini.model.vo.*; import com.youlai.boot.mini.service.MiniPointRecordService; import com.youlai.boot.mini.service.StrayAnimalService; @@ -774,4 +775,55 @@ public class StrayAnimalServiceImpl extends ServiceImpl getWaterfall(WaterfallQuery query, Long userId) { + // 1. 设置默认值,查 N+1 条 + int pageSize = query.getPageSize(); + int querySize = pageSize + 1; + + // 2. 从DB查询 N+1 条数据 + List list = miniStrayAnimalMapper.getWaterfall( + query.getCursor(), + querySize, + query.getAnimalType(), + userId + ); + + // 3. 设置默认图片(如果没有封面图) + if (list != null && !list.isEmpty()) { + list.forEach(item -> { + if (StrUtil.isBlank(item.getFirstImageUrl())) { + switch (item.getAnimalType()) { + case "cat": + item.setFirstImageUrl(getDefaultCatCoverHost() + "/default_cat.png"); + break; + case "dog": + item.setFirstImageUrl(getDefaultCatCoverHost() + "/default_dog.png"); + break; + default: + item.setFirstImageUrl(getDefaultCatCoverHost() + "/default_other.png"); + break; + } + } + }); + } + + // 4. 计算下一页游标(N+1 方案:如果返回数量 > pageSize 说明有下一页,取前 pageSize 条) + Long nextCursor = null; + boolean isLastPage = true; + List resultList = list; + + if (list != null && !list.isEmpty()) { + if (list.size() > pageSize) { + // 取前 pageSize 条 + resultList = list.subList(0, pageSize); + // 用第 pageSize 条的 id 作为游标 + nextCursor = list.get(pageSize - 1).getId(); + isLastPage = false; + } + } + + return WaterfallResult.of(resultList, nextCursor, isLastPage); + } + } diff --git a/src/main/resources/mapper/mini/MiniStrayAnimalMapper.xml b/src/main/resources/mapper/mini/MiniStrayAnimalMapper.xml index e4f96ae..4b7569c 100644 --- a/src/main/resources/mapper/mini/MiniStrayAnimalMapper.xml +++ b/src/main/resources/mapper/mini/MiniStrayAnimalMapper.xml @@ -291,5 +291,69 @@ + +