refactor: ReviewServiceImpl 改用 MyBatis-Plus Java API 实现复盘功能

This commit is contained in:
2026-05-27 21:23:44 +08:00
parent f797a712db
commit 950c91791f
@@ -1,49 +1,164 @@
package com.guo.learningprogresstracker.service.impl; package com.guo.learningprogresstracker.service.impl;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.guo.learningprogresstracker.dto.ReviewFeedItem; import com.guo.learningprogresstracker.dto.ReviewFeedItem;
import com.guo.learningprogresstracker.entity.StudyReportFragmentsEntity; import com.guo.learningprogresstracker.entity.StudyReportFragmentsEntity;
import com.guo.learningprogresstracker.entity.StudyReportsEntity; import com.guo.learningprogresstracker.entity.StudyReportsEntity;
import com.guo.learningprogresstracker.entity.StudySessionsEntity;
import com.guo.learningprogresstracker.entity.TaskEntity;
import com.guo.learningprogresstracker.exception.NotFindEntitiesException; import com.guo.learningprogresstracker.exception.NotFindEntitiesException;
import com.guo.learningprogresstracker.mapper.ReviewMapper;
import com.guo.learningprogresstracker.mapper.StudyReportFragmentsMapper; import com.guo.learningprogresstracker.mapper.StudyReportFragmentsMapper;
import com.guo.learningprogresstracker.mapper.StudyReportsMapper; import com.guo.learningprogresstracker.mapper.StudyReportsMapper;
import com.guo.learningprogresstracker.mapper.StudySessionsMapper;
import com.guo.learningprogresstracker.mapper.TasksMapper;
import com.guo.learningprogresstracker.service.ReviewService; import com.guo.learningprogresstracker.service.ReviewService;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.List; import java.util.*;
import java.util.Optional; import java.util.stream.Collectors;
import java.util.stream.Stream;
/** /**
* 复习模块 Service 实现 * 复习模块 Service 实现(纯 MyBatis-Plus Java API
*/ */
@Service @Service
@RequiredArgsConstructor @RequiredArgsConstructor
public class ReviewServiceImpl implements ReviewService { public class ReviewServiceImpl implements ReviewService {
private final ReviewMapper reviewMapper;
private final StudyReportsMapper studyReportsMapper; private final StudyReportsMapper studyReportsMapper;
private final StudyReportFragmentsMapper studyReportFragmentsMapper; private final StudyReportFragmentsMapper studyReportFragmentsMapper;
private final StudySessionsMapper studySessionsMapper;
private final TasksMapper tasksMapper;
@Override @Override
public List<ReviewFeedItem> getReviewFeed(int limit) { public List<ReviewFeedItem> getReviewFeed(int limit) {
return reviewMapper.selectReviewFeed(limit); // created_by 条件由 TenantLineInnerInterceptor 自动注入
List<StudyReportsEntity> reports = studyReportsMapper.selectList(
Wrappers.<StudyReportsEntity>lambdaQuery()
.orderByDesc(StudyReportsEntity::getCreatedTime)
.last("LIMIT " + limit));
List<StudyReportFragmentsEntity> fragments = studyReportFragmentsMapper.selectList(
Wrappers.<StudyReportFragmentsEntity>lambdaQuery()
.orderByDesc(StudyReportFragmentsEntity::getCreatedTime)
.last("LIMIT " + limit));
return mergeAndConvert(reports, fragments);
} }
@Override @Override
public List<ReviewFeedItem> getTaskReview(String taskNum) { public List<ReviewFeedItem> getTaskReview(String taskNum) {
return reviewMapper.selectTaskReview(taskNum); // 先查该任务下的所有 sessionNum
List<String> sessionNums = studySessionsMapper.selectList(
Wrappers.<StudySessionsEntity>lambdaQuery()
.eq(StudySessionsEntity::getTaskNum, taskNum)
.select(StudySessionsEntity::getSessionNum))
.stream()
.map(StudySessionsEntity::getSessionNum)
.collect(Collectors.toList());
if (sessionNums.isEmpty()) {
return Collections.emptyList();
}
List<StudyReportsEntity> reports = studyReportsMapper.selectList(
Wrappers.<StudyReportsEntity>lambdaQuery()
.in(StudyReportsEntity::getSessionNum, sessionNums)
.orderByDesc(StudyReportsEntity::getCreatedTime));
List<StudyReportFragmentsEntity> fragments = studyReportFragmentsMapper.selectList(
Wrappers.<StudyReportFragmentsEntity>lambdaQuery()
.in(StudyReportFragmentsEntity::getSessionNum, sessionNums)
.orderByDesc(StudyReportFragmentsEntity::getCreatedTime));
return mergeAndConvert(reports, fragments);
} }
@Override @Override
public StudyReportsEntity getReportDetail(int id) throws NotFindEntitiesException { public StudyReportsEntity getReportDetail(int id) throws NotFindEntitiesException {
// 拦截器自动校验归属
return Optional.ofNullable(studyReportsMapper.selectById(id)) return Optional.ofNullable(studyReportsMapper.selectById(id))
.orElseThrow(() -> new NotFindEntitiesException("学习报告[" + id + "]不存在")); .orElseThrow(() -> new NotFindEntitiesException("学习报告[" + id + "]不存在"));
} }
@Override @Override
public StudyReportFragmentsEntity getFragmentDetail(int id) throws NotFindEntitiesException { public StudyReportFragmentsEntity getFragmentDetail(int id) throws NotFindEntitiesException {
// 拦截器自动校验归属
return Optional.ofNullable(studyReportFragmentsMapper.selectById(id)) return Optional.ofNullable(studyReportFragmentsMapper.selectById(id))
.orElseThrow(() -> new NotFindEntitiesException("学习残片[" + id + "]不存在")); .orElseThrow(() -> new NotFindEntitiesException("学习残片[" + id + "]不存在"));
} }
/**
* 将报告和残片合并转换为 ReviewFeedItem 列表,按创建时间倒序排列
*/
private List<ReviewFeedItem> mergeAndConvert(List<StudyReportsEntity> reports,
List<StudyReportFragmentsEntity> fragments) {
// 收集所有 sessionNum,批量查询 session 和 task
Set<String> allSessionNums = Stream.concat(
reports.stream().map(StudyReportsEntity::getSessionNum),
fragments.stream().map(StudyReportFragmentsEntity::getSessionNum)
).collect(Collectors.toSet());
if (allSessionNums.isEmpty()) {
return Collections.emptyList();
}
// 批量查询 sessions,构建 sessionNum -> taskNum 映射
Map<String, String> sessionToTaskMap = studySessionsMapper.selectList(
Wrappers.<StudySessionsEntity>lambdaQuery()
.in(StudySessionsEntity::getSessionNum, allSessionNums)
.select(StudySessionsEntity::getSessionNum, StudySessionsEntity::getTaskNum))
.stream()
.collect(Collectors.toMap(
StudySessionsEntity::getSessionNum,
StudySessionsEntity::getTaskNum,
(a, b) -> a));
// 批量查询 tasks,构建 taskNum -> taskName 映射
Set<String> taskNums = new HashSet<>(sessionToTaskMap.values());
Map<String, String> taskNameMap = tasksMapper.selectList(
Wrappers.<TaskEntity>lambdaQuery()
.in(TaskEntity::getTaskNum, taskNums)
.select(TaskEntity::getTaskNum, TaskEntity::getTaskName))
.stream()
.collect(Collectors.toMap(
TaskEntity::getTaskNum,
TaskEntity::getTaskName,
(a, b) -> a));
// 转换报告
List<ReviewFeedItem> reportItems = reports.stream().map(r -> {
ReviewFeedItem item = new ReviewFeedItem();
item.setId(r.getId());
item.setSessionNum(r.getSessionNum());
item.setSourceType("REPORT");
item.setContent(r.getContent());
item.setCreatedTime(r.getCreatedTime());
String taskNum = sessionToTaskMap.get(r.getSessionNum());
item.setTaskNum(taskNum);
item.setTaskName(taskNum != null ? taskNameMap.get(taskNum) : null);
return item;
}).collect(Collectors.toList());
// 转换残片
List<ReviewFeedItem> fragmentItems = fragments.stream().map(f -> {
ReviewFeedItem item = new ReviewFeedItem();
item.setId(f.getId());
item.setSessionNum(f.getSessionNum());
item.setSourceType("FRAGMENT");
item.setContent(f.getContent());
item.setCreatedTime(f.getCreatedTime());
String taskNum = sessionToTaskMap.get(f.getSessionNum());
item.setTaskNum(taskNum);
item.setTaskName(taskNum != null ? taskNameMap.get(taskNum) : null);
return item;
}).collect(Collectors.toList());
// 合并并按创建时间倒序
return Stream.concat(reportItems.stream(), fragmentItems.stream())
.sorted(Comparator.comparing(ReviewFeedItem::getCreatedTime,
Comparator.nullsLast(Comparator.reverseOrder())))
.collect(Collectors.toList());
}
} }