refactor: 优化其他 Service 实现和 Controller 代码

This commit is contained in:
2026-05-27 21:23:50 +08:00
parent 950c91791f
commit 24d871b430
4 changed files with 55 additions and 47 deletions
@@ -1,13 +1,10 @@
package com.guo.learningprogresstracker.controller; package com.guo.learningprogresstracker.controller;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.protobuf.ServiceException; import com.google.protobuf.ServiceException;
import com.guo.learningprogresstracker.dto.request.EndedStudySessionRequest; import com.guo.learningprogresstracker.dto.request.EndedStudySessionRequest;
import com.guo.learningprogresstracker.dto.response.StudySessionResponse; import com.guo.learningprogresstracker.dto.response.StudySessionResponse;
import com.guo.learningprogresstracker.entity.CommonResult; import com.guo.learningprogresstracker.entity.CommonResult;
import com.guo.learningprogresstracker.entity.StudySessionsEntity;
import com.guo.learningprogresstracker.exception.ErrorParameterException; import com.guo.learningprogresstracker.exception.ErrorParameterException;
import com.guo.learningprogresstracker.mapStruct.StudySessionConvert;
import com.guo.learningprogresstracker.service.impl.StudySessionsServiceImpl; import com.guo.learningprogresstracker.service.impl.StudySessionsServiceImpl;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotEmpty;
@@ -15,8 +12,8 @@ import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
import java.util.ArrayList; import java.util.ArrayList;
import java.time.LocalDateTime;
/** /**
* 学习会话控制层 * 学习会话控制层
@@ -39,11 +36,9 @@ public class StudySessionController {
*/ */
@GetMapping("/{sessionNum}") @GetMapping("/{sessionNum}")
public CommonResult<StudySessionResponse> getStudySessionBySessionNum(@NotEmpty(message = "sessionNum不可为空") @PathVariable String sessionNum) throws ErrorParameterException { public CommonResult<StudySessionResponse> getStudySessionBySessionNum(@NotEmpty(message = "sessionNum不可为空") @PathVariable String sessionNum) throws ErrorParameterException {
StudySessionsEntity studySessionsEntity = studySessionsServiceImpl.getOneOpt(Wrappers.lambdaQuery(StudySessionsEntity.class) // 通过 service 层获取,包含归属校验
.eq(StudySessionsEntity::getSessionNum, sessionNum)) StudySessionResponse response = studySessionsServiceImpl.getStudySessionBySessionNum(sessionNum);
.orElseThrow(() -> new ErrorParameterException("会话[" + sessionNum + "]不存在")); return CommonResult.success(response);
StudySessionResponse studySessionResponse = StudySessionConvert.MAPPER.toStudySessionResponse(studySessionsEntity);
return CommonResult.success(studySessionResponse);
} }
/** /**
@@ -21,22 +21,21 @@ import org.springframework.stereotype.Service;
@Service @Service
@RequiredArgsConstructor @RequiredArgsConstructor
public class StudyReportFragmentsServiceImpl extends ServiceImpl<StudyReportFragmentsMapper, StudyReportFragmentsEntity> public class StudyReportFragmentsServiceImpl extends ServiceImpl<StudyReportFragmentsMapper, StudyReportFragmentsEntity>
implements StudyReportFragmentsService{ implements StudyReportFragmentsService {
private final StudySessionsMapper studySessionsMapper; private final StudySessionsMapper studySessionsMapper;
@Override @Override
public void createFragments(CreateFragmentsRequest request) throws NotFindEntitiesException { public void createFragments(CreateFragmentsRequest request) throws NotFindEntitiesException {
StudyReportFragmentsEntity entity = FragmentsConvert.MAPPER.toFragmentsEntity(request); StudyReportFragmentsEntity entity = FragmentsConvert.MAPPER.toFragmentsEntity(request);
if (studySessionsMapper.exists(Wrappers.lambdaQuery(StudySessionsEntity.class) // 拦截器自动注入 created_by 条件,会话归属校验已内置
.eq(StudySessionsEntity::getSessionNum,entity.getSessionNum()))) { StudySessionsEntity session = studySessionsMapper.selectOne(
this.save(entity); Wrappers.lambdaQuery(StudySessionsEntity.class)
}else { .eq(StudySessionsEntity::getSessionNum, entity.getSessionNum()));
throw new NotFindEntitiesException(String.format("未能找到学习会话sessionNum[%s]",entity.getSessionNum())); if (session == null) {
throw new NotFindEntitiesException(String.format("未能找到学习会话sessionNum[%s]", entity.getSessionNum()));
} }
// created_by 由 MetaObjectHandler 在 insert 时自动填充
this.save(entity);
} }
} }
@@ -38,12 +38,14 @@ public class StudySessionsServiceImpl extends ServiceImpl<StudySessionsMapper, S
implements StudySessionsService { implements StudySessionsService {
public static final int WORK_DURATION = 25; public static final int WORK_DURATION = 25;
private final TasksServiceImpl tasksServiceImpl; private final TasksServiceImpl tasksServiceImpl;
private final StudyReportFragmentsServiceImpl studyReportFragmentsServiceImpl; private final StudyReportFragmentsServiceImpl studyReportFragmentsServiceImpl;
private final StudyReportFragmentsMapper studyReportFragmentsMapper; private final StudyReportFragmentsMapper studyReportFragmentsMapper;
private final StudyReportsMapper studyReportsMapper; private final StudyReportsMapper studyReportsMapper;
public StudySessionResponse startOrContinueStudySession(String taskNum) throws NotFindEntitiesException, ServiceException { public StudySessionResponse startOrContinueStudySession(String taskNum) throws NotFindEntitiesException, ServiceException {
// 拦截器已自动注入 created_by 条件,只有当前用户的 task 才能查到
TaskEntity taskEntity = tasksServiceImpl.getOneOpt( TaskEntity taskEntity = tasksServiceImpl.getOneOpt(
Wrappers.lambdaQuery(TaskEntity.class).eq(TaskEntity::getTaskNum, taskNum)) Wrappers.lambdaQuery(TaskEntity.class).eq(TaskEntity::getTaskNum, taskNum))
.orElseThrow(() -> new NotFindEntitiesException(String.format("[%s]不存在", taskNum))); .orElseThrow(() -> new NotFindEntitiesException(String.format("[%s]不存在", taskNum)));
@@ -80,6 +82,7 @@ public class StudySessionsServiceImpl extends ServiceImpl<StudySessionsMapper, S
@Override @Override
public void pauseStudySession(String sessionNum, LocalDateTime endTime) throws ErrorParameterException, ServiceException { public void pauseStudySession(String sessionNum, LocalDateTime endTime) throws ErrorParameterException, ServiceException {
// 拦截器自动校验归属,查不到即说明无权访问
StudySessionsEntity studySessionsEntity = this.getOneOpt(Wrappers.lambdaQuery(StudySessionsEntity.class) StudySessionsEntity studySessionsEntity = this.getOneOpt(Wrappers.lambdaQuery(StudySessionsEntity.class)
.eq(StudySessionsEntity::getSessionNum, sessionNum)) .eq(StudySessionsEntity::getSessionNum, sessionNum))
.orElseThrow(() -> new ErrorParameterException("会话[" + sessionNum + "]不存在")); .orElseThrow(() -> new ErrorParameterException("会话[" + sessionNum + "]不存在"));
@@ -95,12 +98,13 @@ public class StudySessionsServiceImpl extends ServiceImpl<StudySessionsMapper, S
@Override @Override
public void endedStudySession(String sessionNum, String content) throws ErrorParameterException { public void endedStudySession(String sessionNum, String content) throws ErrorParameterException {
// 拦截器自动校验归属
StudySessionsEntity studySessionsEntity = this.getOneOpt(Wrappers.lambdaQuery(StudySessionsEntity.class) StudySessionsEntity studySessionsEntity = this.getOneOpt(Wrappers.lambdaQuery(StudySessionsEntity.class)
.eq(StudySessionsEntity::getSessionNum, sessionNum)) .eq(StudySessionsEntity::getSessionNum, sessionNum))
.orElseThrow(() -> new ErrorParameterException("会话[" + sessionNum + "]不存在")); .orElseThrow(() -> new ErrorParameterException("会话[" + sessionNum + "]不存在"));
studySessionsEntity.endedStudySession(); studySessionsEntity.endedStudySession();
this.updateById(studySessionsEntity); this.updateById(studySessionsEntity);
// 创建学习报告 // 创建学习报告created_by 由 MetaObjectHandler 自动填充)
StudyReportsEntity studyReportsEntity = new StudyReportsEntity(); StudyReportsEntity studyReportsEntity = new StudyReportsEntity();
studyReportsEntity.setSessionNum(sessionNum); studyReportsEntity.setSessionNum(sessionNum);
studyReportsEntity.setContent(content); studyReportsEntity.setContent(content);
@@ -109,6 +113,10 @@ public class StudySessionsServiceImpl extends ServiceImpl<StudySessionsMapper, S
@Override @Override
public StudySessionResponse getNotEndedStudySessionByTaskNum(String taskNum) throws ErrorParameterException { public StudySessionResponse getNotEndedStudySessionByTaskNum(String taskNum) throws ErrorParameterException {
// 拦截器自动注入 created_by,task 归属校验已内置
TaskEntity task = tasksServiceImpl.getOneOpt(Wrappers.lambdaQuery(TaskEntity.class)
.eq(TaskEntity::getTaskNum, taskNum))
.orElseThrow(() -> new ErrorParameterException("任务[" + taskNum + "]不存在"));
StudySessionsDto dto = Optional.ofNullable(studyReportsMapper.getNotEndedStudySessionDtoByTaskNum(taskNum)) StudySessionsDto dto = Optional.ofNullable(studyReportsMapper.getNotEndedStudySessionDtoByTaskNum(taskNum))
.orElseThrow(() -> new ErrorParameterException("任务[" + taskNum + "]不存在进行中或暂停中的会话")); .orElseThrow(() -> new ErrorParameterException("任务[" + taskNum + "]不存在进行中或暂停中的会话"));
return StudySessionConvert.MAPPER.toStudySessionResponse(dto); return StudySessionConvert.MAPPER.toStudySessionResponse(dto);
@@ -116,9 +124,9 @@ public class StudySessionsServiceImpl extends ServiceImpl<StudySessionsMapper, S
@Override @Override
public ArrayList<String> getAllFragments(String sessionNum) throws ErrorParameterException { public ArrayList<String> getAllFragments(String sessionNum) throws ErrorParameterException {
// 拦截器自动校验归属
if (this.exists(Wrappers.lambdaQuery(StudySessionsEntity.class) if (this.exists(Wrappers.lambdaQuery(StudySessionsEntity.class)
.eq(StudySessionsEntity::getSessionNum, sessionNum))) { .eq(StudySessionsEntity::getSessionNum, sessionNum))) {
// todo guo 后续可在此补充更高级的整理方式
return studyReportFragmentsMapper.selectList(Wrappers.lambdaQuery(StudyReportFragmentsEntity.class) return studyReportFragmentsMapper.selectList(Wrappers.lambdaQuery(StudyReportFragmentsEntity.class)
.eq(StudyReportFragmentsEntity::getSessionNum, sessionNum)) .eq(StudyReportFragmentsEntity::getSessionNum, sessionNum))
.stream().map(StudyReportFragmentsEntity::getContent).collect(Collectors.toCollection(ArrayList::new)); .stream().map(StudyReportFragmentsEntity::getContent).collect(Collectors.toCollection(ArrayList::new));
@@ -129,6 +137,7 @@ public class StudySessionsServiceImpl extends ServiceImpl<StudySessionsMapper, S
@Override @Override
public void continueStudySession(String sessionNum) throws ErrorParameterException, ServiceException { public void continueStudySession(String sessionNum) throws ErrorParameterException, ServiceException {
// 拦截器自动校验归属
StudySessionsEntity studySessionsEntity = this.getOneOpt(Wrappers.lambdaQuery(StudySessionsEntity.class) StudySessionsEntity studySessionsEntity = this.getOneOpt(Wrappers.lambdaQuery(StudySessionsEntity.class)
.eq(StudySessionsEntity::getSessionNum, sessionNum)) .eq(StudySessionsEntity::getSessionNum, sessionNum))
.orElseThrow(() -> new ErrorParameterException("会话[" + sessionNum + "]不存在")); .orElseThrow(() -> new ErrorParameterException("会话[" + sessionNum + "]不存在"));
@@ -142,8 +151,15 @@ public class StudySessionsServiceImpl extends ServiceImpl<StudySessionsMapper, S
studySessionsEntity.continueStudySession(); studySessionsEntity.continueStudySession();
this.updateById(studySessionsEntity); this.updateById(studySessionsEntity);
} }
/**
* 通过 sessionNum 获取学习会话(归属由拦截器自动校验)
*/
public StudySessionResponse getStudySessionBySessionNum(String sessionNum) throws ErrorParameterException {
StudySessionsEntity session = this.getOneOpt(Wrappers.lambdaQuery(StudySessionsEntity.class)
.eq(StudySessionsEntity::getSessionNum, sessionNum))
.orElseThrow(() -> new ErrorParameterException("会话[" + sessionNum + "]不存在"));
return StudySessionConvert.MAPPER.toStudySessionResponse(session);
}
} }
@@ -19,8 +19,6 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.rmi.ServerException;
/** /**
* @author guo * @author guo
* @description 针对表【tasks(存储学习任务的基本信息,包括优先级的多维度计算)】的数据库操作Service实现 * @description 针对表【tasks(存储学习任务的基本信息,包括优先级的多维度计算)】的数据库操作Service实现
@@ -30,24 +28,25 @@ import java.rmi.ServerException;
@RequiredArgsConstructor @RequiredArgsConstructor
@Slf4j @Slf4j
public class TasksServiceImpl extends ServiceImpl<TasksMapper, TaskEntity> public class TasksServiceImpl extends ServiceImpl<TasksMapper, TaskEntity>
implements TasksService{ implements TasksService {
private final TasksMapper tasksMapper; private final TasksMapper tasksMapper;
@Override @Override
public Page<TaskInfo> taskList(Integer pageNum, Integer pageSize) { public Page<TaskInfo> taskList(Integer pageNum, Integer pageSize) {
// 拦截器自动注入 created_by 条件,只返回当前用户的任务
Page<TaskEntity> page = tasksMapper.selectPage(new Page<TaskEntity>(pageNum, pageSize), Page<TaskEntity> page = tasksMapper.selectPage(new Page<TaskEntity>(pageNum, pageSize),
Wrappers.lambdaQuery(TaskEntity.class).orderByDesc(TaskEntity::getCalculatedPriority)); Wrappers.lambdaQuery(TaskEntity.class)
.orderByDesc(TaskEntity::getCalculatedPriority));
Page<TaskInfo> response = TaskConvert.MAPPER.toTaskInfoPage(page); Page<TaskInfo> response = TaskConvert.MAPPER.toTaskInfoPage(page);
// todo 需要补充TaskInfo中的lastLearningStatus字段信息
return response; return response;
} }
@Override @Override
public String addTask(TaskRequest taskRequest) throws ErrorParameterException { public String addTask(TaskRequest taskRequest) throws ErrorParameterException {
TaskEntity task= TaskConvert.MAPPER.taskRequestToTaskEntity(taskRequest); TaskEntity task = TaskConvert.MAPPER.taskRequestToTaskEntity(taskRequest);
// 拦截器自动注入 created_by,重复校验仅限当前用户
if (this.exists(Wrappers.lambdaQuery(TaskEntity.class) if (this.exists(Wrappers.lambdaQuery(TaskEntity.class)
.eq(TaskEntity::getTaskName, task.getTaskName()))) { .eq(TaskEntity::getTaskName, task.getTaskName()))) {
throw new ErrorParameterException(String.format("任务名[%s]重复", task.getTaskName())); throw new ErrorParameterException(String.format("任务名[%s]重复", task.getTaskName()));
@@ -62,14 +61,18 @@ public class TasksServiceImpl extends ServiceImpl<TasksMapper, TaskEntity>
@Override @Override
public TaskInfoResponse getTask(String taskId) { public TaskInfoResponse getTask(String taskId) {
// 拦截器自动校验归属,查到的一定是当前用户的任务
TaskEntity taskEntity = this.getById(taskId); TaskEntity taskEntity = this.getById(taskId);
TaskInfoResponse taskInfoResponse = TaskConvert.MAPPER.taskEntityToTaskInfoResponse(taskEntity); return TaskConvert.MAPPER.taskEntityToTaskInfoResponse(taskEntity);
return taskInfoResponse;
} }
@Override @Override
public void updateTask(String taskId, TaskRequest updatedTask) { public void updateTask(String taskId, TaskRequest updatedTask) {
// getById 已被拦截器保护,其他用户的任务查不到
TaskEntity existingTask = this.getById(taskId);
if (existingTask == null) {
throw new IllegalArgumentException("任务不存在: " + taskId);
}
TaskEntity taskEntity = TaskConvert.MAPPER.taskRequestToTaskEntity(updatedTask); TaskEntity taskEntity = TaskConvert.MAPPER.taskRequestToTaskEntity(updatedTask);
int id; int id;
try { try {
@@ -78,21 +81,16 @@ public class TasksServiceImpl extends ServiceImpl<TasksMapper, TaskEntity>
throw new IllegalArgumentException("任务ID格式错误: " + taskId); throw new IllegalArgumentException("任务ID格式错误: " + taskId);
} }
taskEntity.setId(id); taskEntity.setId(id);
boolean updated = this.updateById(taskEntity); this.updateById(taskEntity);
if (!updated) {
throw new IllegalArgumentException("任务不存在或更新失败: " + taskId);
}
} }
@Override @Override
public void deleteTask(String taskId) throws ServerException { public void deleteTask(String taskId) {
boolean b = this.removeById(taskId); // getById 已被拦截器保护,其他用户的任务查不到
if(!b){ TaskEntity existingTask = this.getById(taskId);
throw new ServerException("未能正常删除任务"); if (existingTask == null) {
throw new IllegalArgumentException("任务不存在: " + taskId);
} }
this.removeById(taskId);
} }
} }