refactor: ReviewServiceImpl 改用 MyBatis-Plus Java API 实现复盘功能
This commit is contained in:
@@ -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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user