diff --git a/src/main/java/com/guo/learningprogresstracker/controller/ReviewController.java b/src/main/java/com/guo/learningprogresstracker/controller/ReviewController.java index fd97df8..189eb02 100644 --- a/src/main/java/com/guo/learningprogresstracker/controller/ReviewController.java +++ b/src/main/java/com/guo/learningprogresstracker/controller/ReviewController.java @@ -35,7 +35,7 @@ public class ReviewController { private final StandardMindMapService standardMindMapService; /** - * 获取复习 feed,合并报告和残片按时间倒序 + * 获取复习 feed,仅返回学习残片(首页滚动条使用) */ @GetMapping("/feed") public CommonResult> getReviewFeed( diff --git a/src/main/java/com/guo/learningprogresstracker/dto/ReviewFeedItem.java b/src/main/java/com/guo/learningprogresstracker/dto/ReviewFeedItem.java index e21bfbe..8d5dfd8 100644 --- a/src/main/java/com/guo/learningprogresstracker/dto/ReviewFeedItem.java +++ b/src/main/java/com/guo/learningprogresstracker/dto/ReviewFeedItem.java @@ -5,7 +5,7 @@ import lombok.Data; import java.time.LocalDateTime; /** - * 复习滚动 feed 条目,合并展示学习报告和残片 + * 复习滚动 feed 条目;首页仅使用残片,任务详情仍可同时包含报告和残片 */ @Data public class ReviewFeedItem { diff --git a/src/main/java/com/guo/learningprogresstracker/service/ReviewService.java b/src/main/java/com/guo/learningprogresstracker/service/ReviewService.java index bef4704..0059254 100644 --- a/src/main/java/com/guo/learningprogresstracker/service/ReviewService.java +++ b/src/main/java/com/guo/learningprogresstracker/service/ReviewService.java @@ -14,7 +14,7 @@ import java.util.List; public interface ReviewService { /** - * 获取复习 feed 列表,合并报告和残片按时间倒序 + * 获取复习 feed 列表,仅返回学习残片并按时间倒序 */ List getReviewFeed(int limit, String mode); diff --git a/src/main/java/com/guo/learningprogresstracker/service/impl/ReviewServiceImpl.java b/src/main/java/com/guo/learningprogresstracker/service/impl/ReviewServiceImpl.java index 9f574db..4240174 100644 --- a/src/main/java/com/guo/learningprogresstracker/service/impl/ReviewServiceImpl.java +++ b/src/main/java/com/guo/learningprogresstracker/service/impl/ReviewServiceImpl.java @@ -16,6 +16,7 @@ import com.guo.learningprogresstracker.mapper.StudySessionsMapper; import com.guo.learningprogresstracker.mapper.TasksMapper; import com.guo.learningprogresstracker.service.ReviewService; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; @@ -29,6 +30,7 @@ import java.util.stream.Stream; /** * 复习模块 Service 实现 */ +@Slf4j @Service @RequiredArgsConstructor public class ReviewServiceImpl implements ReviewService { @@ -53,13 +55,6 @@ public class ReviewServiceImpl implements ReviewService { } boolean random = RANDOM_MODE.equalsIgnoreCase(mode); - List reports = random - ? studyReportsMapper.selectList(Wrappers.lambdaQuery() - .last("ORDER BY RAND() LIMIT " + safeLimit)) - : studyReportsMapper.selectList(Wrappers.lambdaQuery() - .orderByDesc(StudyReportsEntity::getCreatedTime) - .last("LIMIT " + safeLimit)); - List fragments = random ? studyReportFragmentsMapper.selectList(Wrappers.lambdaQuery() .last("ORDER BY RAND() LIMIT " + safeLimit)) @@ -67,7 +62,7 @@ public class ReviewServiceImpl implements ReviewService { .orderByDesc(StudyReportFragmentsEntity::getCreatedTime) .last("LIMIT " + safeLimit)); - List items = mergeAndConvert(reports, fragments); + List items = mergeAndConvert(List.of(), fragments); if (random) { Collections.shuffle(items); } @@ -82,14 +77,11 @@ public class ReviewServiceImpl implements ReviewService { private List getSmartFeed(int safeLimit) { int candidateLimit = Math.min(safeLimit * SMART_CANDIDATE_MULTIPLIER, 500); - List reports = studyReportsMapper.selectList( - Wrappers.lambdaQuery() - .last("ORDER BY RAND() LIMIT " + candidateLimit)); List fragments = studyReportFragmentsMapper.selectList( Wrappers.lambdaQuery() .last("ORDER BY RAND() LIMIT " + candidateLimit)); - List candidates = mergeAndConvert(reports, fragments); + List candidates = mergeAndConvert(List.of(), fragments); if (candidates.size() <= safeLimit) { Collections.shuffle(candidates); return candidates; @@ -224,13 +216,19 @@ public class ReviewServiceImpl implements ReviewService { @Override public StudyReportsEntity getReportDetail(int id) throws NotFindEntitiesException { return Optional.ofNullable(studyReportsMapper.selectById(id)) - .orElseThrow(() -> new NotFindEntitiesException("学习报告[" + id + "]不存在")); + .orElseThrow(() -> { + log.warn("学习报告[{}]不存在", id); + return new NotFindEntitiesException("这份学习报告不存在或已被删除"); + }); } @Override public StudyReportFragmentsEntity getFragmentDetail(int id) throws NotFindEntitiesException { return Optional.ofNullable(studyReportFragmentsMapper.selectById(id)) - .orElseThrow(() -> new NotFindEntitiesException("学习残片[" + id + "]不存在")); + .orElseThrow(() -> { + log.warn("学习残片[{}]不存在", id); + return new NotFindEntitiesException("这条学习残片不存在或已被删除"); + }); } /** @@ -321,7 +319,8 @@ public class ReviewServiceImpl implements ReviewService { private void ensureTaskExists(String taskNum) throws NotFindEntitiesException { if (!StringUtils.hasText(taskNum) || !tasksMapper.exists( Wrappers.lambdaQuery().eq(TaskEntity::getTaskNum, taskNum))) { - throw new NotFindEntitiesException("任务[" + taskNum + "]不存在"); + log.warn("任务[{}]不存在", taskNum); + throw new NotFindEntitiesException("这个任务不存在或已被删除"); } } diff --git a/src/test/java/com/guo/learningprogresstracker/service/impl/ReviewServiceImplTest.java b/src/test/java/com/guo/learningprogresstracker/service/impl/ReviewServiceImplTest.java index c2fed13..bf5573d 100644 --- a/src/test/java/com/guo/learningprogresstracker/service/impl/ReviewServiceImplTest.java +++ b/src/test/java/com/guo/learningprogresstracker/service/impl/ReviewServiceImplTest.java @@ -62,13 +62,13 @@ class ReviewServiceImplTest { void getReviewFeed_smartMode_prefersLowRecallRatioContent() { LocalDateTime now = LocalDateTime.now(); - StudyReportsEntity oldLowMastery = new StudyReportsEntity(); + StudyReportFragmentsEntity oldLowMastery = new StudyReportFragmentsEntity(); oldLowMastery.setId(1); oldLowMastery.setSessionNum("S_LOW"); oldLowMastery.setContent("很久没复习且掌握度低"); oldLowMastery.setCreatedTime(now.minusDays(60)); - StudyReportsEntity freshHighMastery = new StudyReportsEntity(); + StudyReportFragmentsEntity freshHighMastery = new StudyReportFragmentsEntity(); freshHighMastery.setId(2); freshHighMastery.setSessionNum("S_HIGH"); freshHighMastery.setContent("刚学完且掌握度高"); @@ -93,8 +93,7 @@ class ReviewServiceImplTest { highRatioRecord.setRecallRatio(1.0); highRatioRecord.setCreatedTime(now); - when(studyReportsMapper.selectList(any())).thenReturn(List.of(oldLowMastery, freshHighMastery)); - when(studyReportFragmentsMapper.selectList(any())).thenReturn(List.of()); + when(studyReportFragmentsMapper.selectList(any())).thenReturn(List.of(oldLowMastery, freshHighMastery)); when(studySessionsMapper.selectList(any())).thenReturn(List.of(sessionLow, sessionHigh)); when(tasksMapper.selectList(any())).thenReturn(List.of(taskLow, taskHigh)); when(reviewRecallRecordMapper.selectList(any())).thenReturn(List.of(highRatioRecord)); @@ -116,15 +115,9 @@ class ReviewServiceImplTest { } @Test - void getReviewFeed_shouldApplyFinalLimitAfterMerge() { - StudyReportsEntity report = new StudyReportsEntity(); - report.setId(1); - report.setSessionNum("S1"); - report.setContent("report"); - report.setCreatedTime(LocalDateTime.now()); - + void getReviewFeed_shouldReturnFragmentsOnly() { StudyReportFragmentsEntity fragment = new StudyReportFragmentsEntity(); - fragment.setId(2); + fragment.setId(1); fragment.setSessionNum("S1"); fragment.setContent("fragment"); fragment.setCreatedTime(LocalDateTime.now().minusMinutes(1)); @@ -137,7 +130,6 @@ class ReviewServiceImplTest { task.setTaskNum("T1"); task.setTaskName("Task"); - when(studyReportsMapper.selectList(any())).thenReturn(List.of(report)); when(studyReportFragmentsMapper.selectList(any())).thenReturn(List.of(fragment)); when(studySessionsMapper.selectList(any())).thenReturn(List.of(session)); when(tasksMapper.selectList(any())).thenReturn(List.of(task)); @@ -145,7 +137,7 @@ class ReviewServiceImplTest { List items = reviewService.getReviewFeed(1, "recent"); assertEquals(1, items.size()); - assertEquals("REPORT", items.get(0).getSourceType()); + assertEquals("FRAGMENT", items.get(0).getSourceType()); assertEquals("Task", items.get(0).getTaskName()); }