Files
lpt-be/src/main/java/com/guo/learningprogresstracker/service/impl/StudySessionsServiceImpl.java
T
cat-shark a64daacc71 feat: 结束会话时返回有效时间不足的提示信息
- StudySessionsServiceImpl: 检测 effectiveTime 被清零时返回提示消息
- StudySessionController: 将提示消息通过 CommonResult.success(message) 传给前端
2026-05-30 17:36:56 +08:00

162 lines
8.6 KiB
Java

package com.guo.learningprogresstracker.service.impl;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.protobuf.ServiceException;
import com.guo.learningprogresstracker.dto.StudySessionsDto;
import com.guo.learningprogresstracker.dto.response.StudySessionResponse;
import com.guo.learningprogresstracker.entity.StudyReportFragmentsEntity;
import com.guo.learningprogresstracker.entity.StudyReportsEntity;
import com.guo.learningprogresstracker.entity.StudySessionsEntity;
import com.guo.learningprogresstracker.entity.TaskEntity;
import com.guo.learningprogresstracker.enums.StudySessionStateEnum;
import com.guo.learningprogresstracker.exception.ErrorParameterException;
import com.guo.learningprogresstracker.exception.NotFindEntitiesException;
import com.guo.learningprogresstracker.mapStruct.StudySessionConvert;
import com.guo.learningprogresstracker.mapper.StudyReportFragmentsMapper;
import com.guo.learningprogresstracker.mapper.StudyReportsMapper;
import com.guo.learningprogresstracker.mapper.StudySessionsMapper;
import com.guo.learningprogresstracker.service.StudySessionsService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Optional;
import java.util.stream.Collectors;
/**
* 针对表【study_sessions(记录每次学习会话的具体数据)】的数据库操作Service实现
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class StudySessionsServiceImpl extends ServiceImpl<StudySessionsMapper, StudySessionsEntity>
implements StudySessionsService {
public static final int WORK_DURATION = 25;
private final TasksServiceImpl tasksServiceImpl;
private final StudyReportFragmentsServiceImpl studyReportFragmentsServiceImpl;
private final StudyReportFragmentsMapper studyReportFragmentsMapper;
private final StudyReportsMapper studyReportsMapper;
public StudySessionResponse startOrContinueStudySession(String taskNum) throws NotFindEntitiesException, ServiceException {
TaskEntity taskEntity = tasksServiceImpl.getOneOpt(
Wrappers.lambdaQuery(TaskEntity.class).eq(TaskEntity::getTaskNum, taskNum))
.orElseThrow(() -> new NotFindEntitiesException(String.format("[%s]不存在", taskNum)));
StudySessionsEntity session = this.getOneOpt(Wrappers.<StudySessionsEntity>lambdaQuery()
.eq(StudySessionsEntity::getTaskNum, taskNum)
.ne(StudySessionsEntity::getSessionState, StudySessionStateEnum.ENDED.name()))
.orElseGet(() -> {
// 如果没有则创建新会话
StudySessionsEntity newSession = StudySessionsEntity.initNewSession();
newSession.setTaskNum(taskNum);
newSession.setLastStartTime(LocalDateTime.now());
this.save(newSession);
return newSession;
});
session.calculatePointerPosition();
if (session.isOverTime()) {
session.pausedStudySession(session.getLastStartTime().plusMinutes(WORK_DURATION));
this.updateById(session);
}
StudySessionResponse response = StudySessionConvert.MAPPER.toStudySessionResponse(session);
response.setTaskName(taskEntity.getTaskName());
if (session.isOverTime()) {
response.setSystemMessage("上段学习任务已经超时25分钟,将仅计算为25分钟的有效学习时间,请注意休息!");
}
return response;
}
@Override
public void pauseStudySession(String sessionNum, LocalDateTime endTime) throws ErrorParameterException, ServiceException {
StudySessionsEntity studySessionsEntity = this.getOneOpt(Wrappers.lambdaQuery(StudySessionsEntity.class)
.eq(StudySessionsEntity::getSessionNum, sessionNum))
.orElseThrow(() -> new ErrorParameterException("会话[" + sessionNum + "]不存在"));
if (StudySessionStateEnum.PAUSED.name().equals(studySessionsEntity.getSessionState())) {
log.error("会话[" + studySessionsEntity.getSessionNum() + "]重复暂停");
throw new ErrorParameterException("会话[" + sessionNum + "]已经暂停,请勿重复暂停!");
}
studySessionsEntity.calculatePointerPosition();
studySessionsEntity.pausedStudySession(endTime);
this.updateById(studySessionsEntity);
}
@Override
public String endedStudySession(String sessionNum, String content) throws ErrorParameterException {
StudySessionsEntity studySessionsEntity = this.getOneOpt(Wrappers.lambdaQuery(StudySessionsEntity.class)
.eq(StudySessionsEntity::getSessionNum, sessionNum))
.orElseThrow(() -> new ErrorParameterException("会话[" + sessionNum + "]不存在"));
boolean wasOngoing = StudySessionStateEnum.ONGOING.name().equals(studySessionsEntity.getSessionState());
studySessionsEntity.endedStudySession();
this.updateById(studySessionsEntity);
StudyReportsEntity studyReportsEntity = new StudyReportsEntity();
studyReportsEntity.setSessionNum(sessionNum);
studyReportsEntity.setContent(content);
studyReportsMapper.insert(studyReportsEntity);
if (wasOngoing && studySessionsEntity.getEffectiveTime() == 0) {
return "本次有效学习时间不足10分钟,不计入总学习时间";
}
return null;
}
@Override
public StudySessionResponse getNotEndedStudySessionByTaskNum(String taskNum) throws ErrorParameterException {
TaskEntity task = tasksServiceImpl.getOneOpt(Wrappers.lambdaQuery(TaskEntity.class)
.eq(TaskEntity::getTaskNum, taskNum))
.orElseThrow(() -> new ErrorParameterException("任务[" + taskNum + "]不存在"));
StudySessionsDto dto = Optional.ofNullable(studyReportsMapper.getNotEndedStudySessionDtoByTaskNum(taskNum))
.orElseThrow(() -> new ErrorParameterException("任务[" + taskNum + "]不存在进行中或暂停中的会话"));
return StudySessionConvert.MAPPER.toStudySessionResponse(dto);
}
@Override
public ArrayList<String> getAllFragments(String sessionNum) throws ErrorParameterException {
if (this.exists(Wrappers.lambdaQuery(StudySessionsEntity.class)
.eq(StudySessionsEntity::getSessionNum, sessionNum))) {
return studyReportFragmentsMapper.selectList(Wrappers.lambdaQuery(StudyReportFragmentsEntity.class)
.eq(StudyReportFragmentsEntity::getSessionNum, sessionNum))
.stream().map(StudyReportFragmentsEntity::getContent).collect(Collectors.toCollection(ArrayList::new));
} else {
throw new ErrorParameterException("会话[" + sessionNum + "]不存在");
}
}
@Override
public void continueStudySession(String sessionNum) throws ErrorParameterException, ServiceException {
StudySessionsEntity studySessionsEntity = this.getOneOpt(Wrappers.lambdaQuery(StudySessionsEntity.class)
.eq(StudySessionsEntity::getSessionNum, sessionNum))
.orElseThrow(() -> new ErrorParameterException("会话[" + sessionNum + "]不存在"));
if (StudySessionStateEnum.ONGOING.name().equals(studySessionsEntity.getSessionState())) {
log.error("会话[" + studySessionsEntity.getSessionNum() + "]重复开始");
throw new ErrorParameterException("会话[" + sessionNum + "]已经开始,请勿重复开始!");
} else if (StudySessionStateEnum.ENDED.name().equals(studySessionsEntity.getSessionState())) {
log.error("会话[" + studySessionsEntity.getSessionNum() + "]处于结束状态,不可开始该会话!");
throw new ErrorParameterException("会话[" + sessionNum + "]处于结束状态,不可开始该会话!");
}
studySessionsEntity.continueStudySession();
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);
}
}