merge: 观看历史统一分页契约并移除 limit

This commit is contained in:
Zhou Weidong authored and trae-solo-agent committed 2026-10-22 13:21:35 +08:00
commit cd51aabe7e
5 files changed
+19 -34

No files matched your search

+2 -7
View File
@@ -291,7 +291,6 @@ app.register.max-per-device-per-day
| POST | `/app/watch/progress` | 上报进度(建议每 10s 一次,切集时补一次) |
| GET | `/app/watch/progress?dramaId=` | 某剧续看位置 |
| GET | `/app/watch/recent` | 最近观看分页;`pageIndex` 默认 1,`pageSize` 默认 20、上限 100 |
| GET | `/app/watch/recent?limit=20` | 旧版最近观看 List 响应,仅保留一版兼容 |
| DELETE | `/app/watch/progress/{dramaId}` | 删除某剧记录 |
| DELETE | `/app/watch/progress` | 清空记录 |
| POST | `/app/favorites/toggle` | 收藏/取消收藏,返回切换后状态 |
@@ -341,7 +340,6 @@ app.register.max-per-device-per-day
| --- | --- | --- | --- | --- |
| `pageIndex` | int | 否 | 1 | 页码,小于 1 按 1 处理 |
| `pageSize` | int | 否 | 20 | 每页数量,上限 100,小于 1 按 1 处理 |
| `limit` | int | 否 | 无 | 兼容旧版;只要传该参数就返回 List,不再返回 PageResult |
分页响应 `data` 为 `PageResult<ProgressRespVO>`:
@@ -366,8 +364,8 @@ app.register.max-per-device-per-day
}
```
排序固定为 `updated_at DESC, drama_id DESC`。每页记录通过批量 IN 查询装配短剧和分集,
不逐条访问数据库。
排序固定为 `updated_at DESC, id DESC`。每页记录通过批量 IN 查询装配短剧和分集,
不逐条访问数据库。越界页返回空 `list` 且 `total` 保持正确。
`ProgressRespVO` 展示字段:
@@ -378,9 +376,6 @@ app.register.max-per-device-per-day
| `episodeNumber` | int / null | 当前续看集号 `ep_no` |
| `totalEpisodes` | int / null | 短剧总集数 |
旧兼容请求 `GET /app/watch/recent?limit=20` 的 `data` 仍为 `List<ProgressRespVO>`,
行为在本版本保留;新客户端应使用分页响应。
### 1.6 离线下载(已实现)
服务端只发**授权**与**短时效地址**,分片由客户端直接向 CDN 拉取 ——
@@ -44,19 +44,14 @@ public class AppWatchController {
return Result.ok(progressService.ofDrama(SecurityUtils.getAppUserId(), dramaId));
}
@Operation(summary = "最近观看列表")
/** 最近观看分页,契约与 /app/favorites 一致:pageIndex/pageSize。 */
@Operation(summary = "最近观看分页")
@GetMapping("/recent")
public Result<?> recent(
@RequestParam(required = false) Integer limit,
public Result<PageResult<ProgressRespVO>> recent(
@RequestParam(defaultValue = "1") int pageIndex,
@RequestParam(defaultValue = "20") int pageSize) {
Long userId = SecurityUtils.getAppUserId();
if (limit != null) {
return Result.ok(progressService.recent(userId, limit));
}
PageResult<ProgressRespVO> page = progressService.recentPage(
userId, pageIndex, pageSize);
return Result.ok(page);
return Result.ok(progressService.recentPage(
SecurityUtils.getAppUserId(), pageIndex, pageSize));
}
@Operation(summary = "删除某部剧的观看记录")
@@ -138,17 +138,19 @@ class AppLibraryPagingContractTest {
}
@Test
void should_return_legacy_list_when_recent_limit_is_present() throws Exception {
given(progressService.recent(USER_ID, 5))
.willReturn(List.of(progress(12L, 88L, 6, "剧名一", 68)));
void should_ignore_removed_limit_and_still_return_page_result() throws Exception {
// limit 已从契约移除:即使客户端误传,也应走分页并返回 PageResult。
given(progressService.recentPage(USER_ID, 1, 20))
.willReturn(new PageResult<>(3L, List.of(progress(12L, 88L, 6, "剧名一", 68))));
watchMvc.perform(get("/app/watch/recent").param("limit", "5"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.data").isArray())
.andExpect(jsonPath("$.data[0].dramaTitle").value("剧名一"))
.andExpect(jsonPath("$.data[0].episodeNumber").value(6));
.andExpect(jsonPath("$.data.total").value("3"))
.andExpect(jsonPath("$.data.list").isArray())
.andExpect(jsonPath("$.data.list.length()").value(1))
.andExpect(jsonPath("$.data.list[0].dramaTitle").value("剧名一"));
verify(progressService).recent(USER_ID, 5);
verify(progressService).recentPage(USER_ID, 1, 20);
}
private Drama drama(Long id, String title) {
@@ -90,7 +90,7 @@ class WatchProgressServiceTest {
assertThat(pageCaptor.getValue().getSize()).isEqualTo(20);
assertThat(wrapperCaptor.getValue().getSqlSegment())
.contains("updated_at DESC")
.contains("drama_id DESC");
.contains("id DESC");
verify(dramaService, times(1)).listByIds(List.of(12L, 13L));
verify(episodeService, times(1)).listByIds(List.of(88L, 99L));
}
@@ -42,7 +42,6 @@ import java.util.Objects;
public class WatchProgressService {
private static final long FINISH_THRESHOLD_MS = 1000L;
private static final int DEFAULT_PAGE_SIZE = 20;
private static final int MAX_PAGE_SIZE = 100;
private final WatchProgressMapper progressMapper;
@@ -116,13 +115,7 @@ public class WatchProgressService {
return progress == null ? null : toResp(progress);
}
/** 最近观看列表("我的-观看记录")。 */
public List<ProgressRespVO> recent(Long userId, int limit) {
int safeLimit = limit <= 0 || limit > MAX_PAGE_SIZE ? DEFAULT_PAGE_SIZE : limit;
return recentPage(userId, 1, safeLimit).getList();
}
/** 分页查询最近观看,按更新时间与 dramaId 稳定倒序。 */
/** 分页查询最近观看,按更新时间倒序并以 id 兜底保证稳定。 */
public PageResult<ProgressRespVO> recentPage(Long userId, int pageIndex, int pageSize) {
int safeIndex = Math.max(pageIndex, 1);
int safeSize = Math.min(Math.max(pageSize, 1), MAX_PAGE_SIZE);
@@ -131,7 +124,7 @@ public class WatchProgressService {
Wrappers.<WatchProgress>lambdaQuery()
.eq(WatchProgress::getUserId, userId)
.orderByDesc(WatchProgress::getUpdatedAt)
.orderByDesc(WatchProgress::getDramaId));
.orderByDesc(WatchProgress::getId));
return new PageResult<>(result.getTotal(), enrichDisplay(result.getRecords()));
}