From 5df805cca7809656f68dd5e588e9c52f1e8ea24e Mon Sep 17 00:00:00 2001 From: cat_shark <1716967236@qq.com> Date: Tue, 8 Jul 2025 09:20:31 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BB=BB=E5=8A=A1=E5=BC=80=E5=A7=8B?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=EF=BC=8C=E7=9B=B8=E5=85=B3=E9=80=BB=E8=BE=91?= =?UTF-8?q?=E8=A1=A5=E5=85=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 7 +++++ .../config/JacksonConfig.java | 12 +++++++-- .../serializer/LocalDateTimeSerializer.java | 7 +++-- .../controller/StudySessionController.java | 21 +++++++++------ .../entity/StudySessionsEntity.java | 21 ++++++++------- .../service/StudySessionsService.java | 5 +++- .../impl/StudySessionsServiceImpl.java | 26 ++++++++++++++++--- 7 files changed, 71 insertions(+), 28 deletions(-) diff --git a/pom.xml b/pom.xml index 097a6da..b07765d 100644 --- a/pom.xml +++ b/pom.xml @@ -116,6 +116,13 @@ 3.5.5 + + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + 2.15.4 + + diff --git a/src/main/java/com/guo/learningprogresstracker/config/JacksonConfig.java b/src/main/java/com/guo/learningprogresstracker/config/JacksonConfig.java index c1c0b4b..7ec42bc 100644 --- a/src/main/java/com/guo/learningprogresstracker/config/JacksonConfig.java +++ b/src/main/java/com/guo/learningprogresstracker/config/JacksonConfig.java @@ -1,10 +1,12 @@ package com.guo.learningprogresstracker.config; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.module.SimpleModule; import com.guo.learningprogresstracker.config.serializer.LocalDateTimeSerializer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; import java.time.LocalDateTime; @@ -14,11 +16,17 @@ import java.time.LocalDateTime; @Configuration public class JacksonConfig { @Bean - public ObjectMapper objectMapper() { - ObjectMapper mapper = new ObjectMapper(); + public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) { + ObjectMapper mapper = builder.build(); + + // 注册自定义序列化器 SimpleModule module = new SimpleModule(); module.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer()); mapper.registerModule(module); + + // 关闭序列化为时间戳(使用字符串格式) + mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + return mapper; } } diff --git a/src/main/java/com/guo/learningprogresstracker/config/serializer/LocalDateTimeSerializer.java b/src/main/java/com/guo/learningprogresstracker/config/serializer/LocalDateTimeSerializer.java index 9ad47b0..f0a743c 100644 --- a/src/main/java/com/guo/learningprogresstracker/config/serializer/LocalDateTimeSerializer.java +++ b/src/main/java/com/guo/learningprogresstracker/config/serializer/LocalDateTimeSerializer.java @@ -10,8 +10,8 @@ import java.time.format.DateTimeFormatter; public class LocalDateTimeSerializer extends StdSerializer { - // 定义你希望使用的日期时间格式 - private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");; + // 修改为ISO 8601格式,末尾带Z,表示UTC时区 + private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'"); public LocalDateTimeSerializer() { super(LocalDateTime.class); @@ -22,9 +22,8 @@ public class LocalDateTimeSerializer extends StdSerializer { if (value == null) { gen.writeNull(); } else { - // 格式化LocalDateTime为字符串 + // 这里假设LocalDateTime是UTC时间,直接格式化并加Z String formattedDate = value.format(formatter); - // 将格式化后的字符串写入JSON流作为一个值 gen.writeString(formattedDate); } } diff --git a/src/main/java/com/guo/learningprogresstracker/controller/StudySessionController.java b/src/main/java/com/guo/learningprogresstracker/controller/StudySessionController.java index bbae24e..f6ea0a8 100644 --- a/src/main/java/com/guo/learningprogresstracker/controller/StudySessionController.java +++ b/src/main/java/com/guo/learningprogresstracker/controller/StudySessionController.java @@ -12,13 +12,9 @@ import jakarta.validation.Valid; import jakarta.validation.constraints.NotEmpty; import lombok.RequiredArgsConstructor; import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; +import java.time.LocalDateTime; import java.util.ArrayList; /** @@ -49,12 +45,21 @@ public class StudySessionController { return CommonResult.success(studySessionResponse); } + /** + * 开始一个【学习会话】 + */ + @PostMapping("/{sessionNum}/study-sessions/continue") + public CommonResult startStudySession(@PathVariable("sessionNum") String sessionNum) throws ErrorParameterException { + studySessionsServiceImpl.continueStudySession(sessionNum); + return CommonResult.success(); + } + /** * 暂停一个【学习会话】 */ @PostMapping("/{sessionNum}/study-sessions/pause") - public CommonResult pauseStudySession(@PathVariable("sessionNum") String sessionNum) throws ErrorParameterException { - studySessionsServiceImpl.pauseStudySession(sessionNum); + public CommonResult pauseStudySession(@PathVariable("sessionNum") String sessionNum, @RequestParam(value = "endTime",required = false) LocalDateTime endTime) throws ErrorParameterException { + studySessionsServiceImpl.pauseStudySession(sessionNum,endTime); return CommonResult.success(); } diff --git a/src/main/java/com/guo/learningprogresstracker/entity/StudySessionsEntity.java b/src/main/java/com/guo/learningprogresstracker/entity/StudySessionsEntity.java index 3cd034f..83aba96 100644 --- a/src/main/java/com/guo/learningprogresstracker/entity/StudySessionsEntity.java +++ b/src/main/java/com/guo/learningprogresstracker/entity/StudySessionsEntity.java @@ -8,6 +8,7 @@ import com.guo.learningprogresstracker.enums.StudySessionStateEnum; import com.guo.learningprogresstracker.utils.GenerateNumTool; import lombok.Data; import lombok.extern.slf4j.Slf4j; +import org.springframework.util.ObjectUtils; import java.io.Serializable; import java.time.Duration; @@ -98,7 +99,7 @@ public class StudySessionsEntity extends BaseEntity implements Serializable { this.setSessionState(StudySessionStateEnum.ONGOING.name()); this.setLastStartTime(LocalDateTime.now()); } else if (this.getSessionState().equals(StudySessionStateEnum.ONGOING.name())) { - log.info("进行中的学习会话({})被重新获取",this.getSessionNum()); + log.info("进行中的学习会话({})被重新开始",this.getSessionNum()); } else{ log.warn("不应出现的情况:开始了一个状态为【{}】的学习会话({})",this.getSessionState(),this.getSessionNum()); } @@ -107,15 +108,15 @@ public class StudySessionsEntity extends BaseEntity implements Serializable { /** * 暂停会话 */ - public void pausedStudySession(){ - if (this.getSessionState().equals(StudySessionStateEnum.PAUSED.name())){ - log.warn("不应出现的情况:暂停了一个状态为【{}】的学习会话",this.getSessionState()); + public void pausedStudySession(LocalDateTime endTime){ + if (this.getSessionState().equals(StudySessionStateEnum.PAUSED.name())) { + log.warn("不应出现的情况:暂停了一个状态为【{}】的学习会话({})", this.getSessionState(), this.getSessionNum()); // - }else { - this.setEndTime(LocalDateTime.now()); - this.setActualTime(Duration.between(this.startTime,this.endTime).toSeconds()); - this.setEffectiveTime(this.getEffectiveTime()+Duration.between(this.lastStartTime,this.endTime).toSeconds()); - this.setEffectivenessRatio(this.effectiveTime/this.actualTime); + } else { + this.setEndTime(ObjectUtils.isEmpty(endTime) ? LocalDateTime.now() : endTime); + this.setActualTime(Duration.between(this.startTime, this.endTime).toSeconds()); + this.setEffectiveTime(this.getEffectiveTime() + Duration.between(this.lastStartTime, this.endTime).toSeconds()); + this.setEffectivenessRatio(this.effectiveTime / this.actualTime); this.setSessionState(StudySessionStateEnum.PAUSED.name()); } } @@ -128,7 +129,7 @@ public class StudySessionsEntity extends BaseEntity implements Serializable { log.warn("不应出现的情况:结束了一个状态为【{}】的学习会话",this.getSessionState()); }else { if (this.getSessionState().equals(StudySessionStateEnum.ONGOING.name())) { - this.pausedStudySession(); + this.pausedStudySession(endTime); } this.setSessionState(StudySessionStateEnum.ENDED.name()); } diff --git a/src/main/java/com/guo/learningprogresstracker/service/StudySessionsService.java b/src/main/java/com/guo/learningprogresstracker/service/StudySessionsService.java index b27bd49..e170252 100644 --- a/src/main/java/com/guo/learningprogresstracker/service/StudySessionsService.java +++ b/src/main/java/com/guo/learningprogresstracker/service/StudySessionsService.java @@ -5,6 +5,7 @@ import com.guo.learningprogresstracker.entity.StudySessionsEntity; import com.baomidou.mybatisplus.extension.service.IService; import com.guo.learningprogresstracker.exception.ErrorParameterException; +import java.time.LocalDateTime; import java.util.ArrayList; /** @@ -20,5 +21,7 @@ public interface StudySessionsService extends IService { void endedStudySession(String sessionNum, String content) throws ErrorParameterException; - void pauseStudySession(String sessionNum) throws ErrorParameterException; + void pauseStudySession(String sessionNum, LocalDateTime endTime) throws ErrorParameterException; + + void continueStudySession(String sessionNum) throws ErrorParameterException; } diff --git a/src/main/java/com/guo/learningprogresstracker/service/impl/StudySessionsServiceImpl.java b/src/main/java/com/guo/learningprogresstracker/service/impl/StudySessionsServiceImpl.java index 0ff868b..6421f29 100644 --- a/src/main/java/com/guo/learningprogresstracker/service/impl/StudySessionsServiceImpl.java +++ b/src/main/java/com/guo/learningprogresstracker/service/impl/StudySessionsServiceImpl.java @@ -58,7 +58,8 @@ public class StudySessionsServiceImpl extends ServiceImpl new ErrorParameterException("会话[" + sessionNum + "]不存在")); - studySessionsEntity.pausedStudySession(); + if (StudySessionStateEnum.PAUSED.name().equals(studySessionsEntity.getSessionState())) { + log.error("会话[" + studySessionsEntity.getSessionNum() + "]重复暂停"); + throw new ErrorParameterException("会话[" + sessionNum + "]已经暂停,请勿重复暂停!"); + } + studySessionsEntity.pausedStudySession(endTime); this.updateById(studySessionsEntity); } @@ -110,6 +115,21 @@ public class StudySessionsServiceImpl extends ServiceImpl 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); + } }