1. 开始或继续一个【学习会话】API 2. 暂停一个【学习会话】API 3.通过sessionId获取一个【学习会话】API
This commit is contained in:
@@ -1,9 +1,54 @@
|
|||||||
package com.guo.learningprogresstracker.controller;
|
package com.guo.learningprogresstracker.controller;
|
||||||
|
|
||||||
|
import com.guo.learningprogresstracker.dto.response.StudySessionResponce;
|
||||||
|
import com.guo.learningprogresstracker.entity.CommonResult;
|
||||||
|
import com.guo.learningprogresstracker.entity.StudySessionsEntity;
|
||||||
|
import com.guo.learningprogresstracker.exception.ErrorParameterException;
|
||||||
|
import com.guo.learningprogresstracker.mapStruct.StudySessionConvert;
|
||||||
|
import com.guo.learningprogresstracker.service.impl.StudySessionsServiceImpl;
|
||||||
|
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.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 学习会话控制层
|
||||||
|
*/
|
||||||
|
@RequestMapping("/study-sessions")
|
||||||
@RestController
|
@RestController
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Validated
|
||||||
public class StudySessionController {
|
public class StudySessionController {
|
||||||
|
|
||||||
|
private final StudySessionsServiceImpl studySessionsServiceImpl;
|
||||||
|
|
||||||
|
@PostMapping
|
||||||
|
public void studySessionList() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过sessionId获取一个【学习会话】
|
||||||
|
*/
|
||||||
|
@GetMapping("/{sessionId}")
|
||||||
|
public CommonResult getStudySession(@NotEmpty(message = "sessionId不可为空") @PathVariable String sessionId) throws ErrorParameterException {
|
||||||
|
StudySessionsEntity studySessionsEntity = studySessionsServiceImpl.getOptById(sessionId)
|
||||||
|
.orElseThrow(() -> new ErrorParameterException("会话[" + sessionId + "]不存在"));
|
||||||
|
StudySessionResponce studySessionResponce = StudySessionConvert.MAPPER.toStudySessionResponce(studySessionsEntity);
|
||||||
|
return CommonResult.success(studySessionResponce);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 暂停一个【学习会话】
|
||||||
|
*/
|
||||||
|
@PostMapping("/{taskId}/studay-sessions/pause")
|
||||||
|
public CommonResult pauseStudySession(@PathVariable("sessionId") String sessionId) throws ErrorParameterException {
|
||||||
|
studySessionsServiceImpl.pauseStudySession(sessionId);
|
||||||
|
return CommonResult.success();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,10 +2,13 @@ package com.guo.learningprogresstracker.controller;
|
|||||||
|
|
||||||
import cn.dev33.satoken.stp.StpUtil;
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
import com.guo.learningprogresstracker.common.Ops;
|
import com.guo.learningprogresstracker.common.Ops;
|
||||||
|
import com.guo.learningprogresstracker.dto.response.StudySessionResponce;
|
||||||
import com.guo.learningprogresstracker.entity.CommonResult;
|
import com.guo.learningprogresstracker.entity.CommonResult;
|
||||||
import com.guo.learningprogresstracker.dto.request.TaskRequest;
|
import com.guo.learningprogresstracker.dto.request.TaskRequest;
|
||||||
import com.guo.learningprogresstracker.service.TasksService;
|
import com.guo.learningprogresstracker.service.TasksService;
|
||||||
|
import com.guo.learningprogresstracker.service.impl.StudySessionsServiceImpl;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import jakarta.validation.constraints.NotEmpty;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||||
@@ -29,6 +32,8 @@ public class TaskController {
|
|||||||
|
|
||||||
private final TasksService tasksService;
|
private final TasksService tasksService;
|
||||||
|
|
||||||
|
private final StudySessionsServiceImpl studySessionsServiceImpl;
|
||||||
|
|
||||||
@PostMapping("/tasks")
|
@PostMapping("/tasks")
|
||||||
@Operation(summary = "添加新任务")
|
@Operation(summary = "添加新任务")
|
||||||
public CommonResult addTask(@RequestBody @Validated({Ops.CreateG.class}) TaskRequest taskRequest) {
|
public CommonResult addTask(@RequestBody @Validated({Ops.CreateG.class}) TaskRequest taskRequest) {
|
||||||
@@ -61,4 +66,17 @@ public class TaskController {
|
|||||||
public CommonResult tasksList() {
|
public CommonResult tasksList() {
|
||||||
return CommonResult.success(tasksService.taskList());
|
return CommonResult.success(tasksService.taskList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开始或继续一个【学习会话】
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@GetMapping("/{taskId}/studay-sessions/start-or-continue")
|
||||||
|
public CommonResult startOrContinueStudySession(@NotEmpty(message = "taskId不可为空")
|
||||||
|
@PathVariable String taskId) {
|
||||||
|
StudySessionResponce responce = studySessionsServiceImpl.startOrContinueStudySession(taskId);
|
||||||
|
return CommonResult.success(responce);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package com.guo.learningprogresstracker.dto.response;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class StudySessionResponce {
|
||||||
|
|
||||||
|
private Integer sessionId;
|
||||||
|
|
||||||
|
private Integer taskId;
|
||||||
|
|
||||||
|
|
||||||
|
@Schema(description = "学习开始时间")
|
||||||
|
private LocalDateTime startTime;
|
||||||
|
|
||||||
|
@Schema(description = "上次本会话开始时间")
|
||||||
|
private LocalDateTime lastStartTime;
|
||||||
|
|
||||||
|
|
||||||
|
@Schema(description = "学习结束时间")
|
||||||
|
private LocalDateTime endTime;
|
||||||
|
|
||||||
|
|
||||||
|
@Schema(description = "实际使用时间(分钟)")
|
||||||
|
private Integer actualTime;
|
||||||
|
|
||||||
|
|
||||||
|
@Schema(description = "有效学习时间(分钟)")
|
||||||
|
private Integer effectiveTime;
|
||||||
|
|
||||||
|
|
||||||
|
@Schema(description = "有效时间比")
|
||||||
|
private Double effectivenessRatio;
|
||||||
|
|
||||||
|
|
||||||
|
@Schema(description = "学习会话的状态(进行中、暂停、已结束)")
|
||||||
|
private String sessionState;
|
||||||
|
}
|
||||||
@@ -4,20 +4,23 @@ import com.baomidou.mybatisplus.annotation.IdType;
|
|||||||
import com.baomidou.mybatisplus.annotation.TableField;
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
import java.io.Serializable;
|
import com.guo.learningprogresstracker.enums.StudySessionStateEnum;
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 记录每次学习会话的具体数据
|
* 记录每次学习会话的具体数据
|
||||||
* @TableName study_sessions
|
* @TableName study_sessions
|
||||||
*/
|
*/
|
||||||
@TableName(value ="study_sessions")
|
@TableName(value ="study_sessions")
|
||||||
|
@Slf4j
|
||||||
@Data
|
@Data
|
||||||
public class StudySessionsEntity extends BaseEntity implements Serializable {
|
public class StudySessionsEntity extends BaseEntity implements Serializable {
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@TableId(value = "session_id", type = IdType.AUTO)
|
@TableId(value = "session_id", type = IdType.AUTO)
|
||||||
private Integer sessionId;
|
private Integer sessionId;
|
||||||
|
|
||||||
@@ -33,6 +36,9 @@ public class StudySessionsEntity extends BaseEntity implements Serializable {
|
|||||||
@TableField(value = "start_time")
|
@TableField(value = "start_time")
|
||||||
private LocalDateTime startTime;
|
private LocalDateTime startTime;
|
||||||
|
|
||||||
|
@TableField(value = "last_start_time")
|
||||||
|
private LocalDateTime lastStartTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 学习结束时间
|
* 学习结束时间
|
||||||
*/
|
*/
|
||||||
@@ -66,4 +72,42 @@ public class StudySessionsEntity extends BaseEntity implements Serializable {
|
|||||||
|
|
||||||
@TableField(exist = false)
|
@TableField(exist = false)
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化新会话
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static StudySessionsEntity initNewSession(){
|
||||||
|
StudySessionsEntity studySessionsEntity = new StudySessionsEntity();
|
||||||
|
studySessionsEntity.setStartTime(LocalDateTime.now());
|
||||||
|
studySessionsEntity.setLastModifiedTime(LocalDateTime.now());
|
||||||
|
studySessionsEntity.setSessionState(StudySessionStateEnum.ONGOING.name());
|
||||||
|
return studySessionsEntity;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 继续会话
|
||||||
|
*/
|
||||||
|
public void continueStudySession(){
|
||||||
|
if (this.getSessionState().equals(StudySessionStateEnum.PAUSED.name())){
|
||||||
|
this.setSessionState(StudySessionStateEnum.ONGOING.name());
|
||||||
|
this.setLastStartTime(LocalDateTime.now());
|
||||||
|
}else{
|
||||||
|
log.warn("不应出现的情况:开始了一个状态为【{}】的学习会话",this.getSessionState());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 暂停会话
|
||||||
|
*/
|
||||||
|
public void pausedStudySession(){
|
||||||
|
if (this.getSessionState().equals(StudySessionStateEnum.PAUSED.name())){
|
||||||
|
//
|
||||||
|
}else {
|
||||||
|
this.setEndTime(LocalDateTime.now());
|
||||||
|
this.setEffectiveTime((int) Duration.between(this.lastStartTime,this.endTime).toMinutes());
|
||||||
|
this.setActualTime((int) Duration.between(this.endTime,this.startTime).toMinutes());
|
||||||
|
this.setSessionState(StudySessionStateEnum.PAUSED.name());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package com.guo.learningprogresstracker.enums;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum StudySessionStateEnum {
|
||||||
|
ONGOING("进行中"),
|
||||||
|
PAUSED("暂停"),
|
||||||
|
ENDED("已结束");
|
||||||
|
|
||||||
|
private final String description;
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return this.description;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+2
-1
@@ -5,7 +5,8 @@ package com.guo.learningprogresstracker.exception;
|
|||||||
*
|
*
|
||||||
* 数据不合法时抛出此错误
|
* 数据不合法时抛出此错误
|
||||||
* 此错误由GlobalExceptionHandler类统一处理
|
* 此错误由GlobalExceptionHandler类统一处理
|
||||||
* */
|
*
|
||||||
|
* @author guo*/
|
||||||
public class ErrorParameterException extends Exception {
|
public class ErrorParameterException extends Exception {
|
||||||
public ErrorParameterException(String message){
|
public ErrorParameterException(String message){
|
||||||
super(message);
|
super(message);
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package com.guo.learningprogresstracker.mapStruct;
|
||||||
|
|
||||||
|
import com.guo.learningprogresstracker.dto.response.StudySessionResponce;
|
||||||
|
import com.guo.learningprogresstracker.entity.StudySessionsEntity;
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.ReportingPolicy;
|
||||||
|
import org.mapstruct.factory.Mappers;
|
||||||
|
|
||||||
|
@Mapper(componentModel = "spring",unmappedTargetPolicy = ReportingPolicy.IGNORE)
|
||||||
|
public interface StudySessionConvert {
|
||||||
|
StudySessionConvert MAPPER = Mappers.getMapper(StudySessionConvert.class);
|
||||||
|
|
||||||
|
|
||||||
|
StudySessionResponce toStudySessionResponce(StudySessionsEntity studySessionsEntity);
|
||||||
|
}
|
||||||
+34
-1
@@ -1,11 +1,18 @@
|
|||||||
package com.guo.learningprogresstracker.service.impl;
|
package com.guo.learningprogresstracker.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import com.guo.learningprogresstracker.dto.response.StudySessionResponce;
|
||||||
import com.guo.learningprogresstracker.entity.StudySessionsEntity;
|
import com.guo.learningprogresstracker.entity.StudySessionsEntity;
|
||||||
import com.guo.learningprogresstracker.service.StudySessionsService;
|
import com.guo.learningprogresstracker.enums.StudySessionStateEnum;
|
||||||
|
import com.guo.learningprogresstracker.exception.ErrorParameterException;
|
||||||
|
import com.guo.learningprogresstracker.mapStruct.StudySessionConvert;
|
||||||
import com.guo.learningprogresstracker.mapper.StudySessionsMapper;
|
import com.guo.learningprogresstracker.mapper.StudySessionsMapper;
|
||||||
|
import com.guo.learningprogresstracker.service.StudySessionsService;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author guo
|
* @author guo
|
||||||
* @description 针对表【study_sessions(记录每次学习会话的具体数据)】的数据库操作Service实现
|
* @description 针对表【study_sessions(记录每次学习会话的具体数据)】的数据库操作Service实现
|
||||||
@@ -15,6 +22,32 @@ import org.springframework.stereotype.Service;
|
|||||||
public class StudySessionsServiceImpl extends ServiceImpl<StudySessionsMapper, StudySessionsEntity>
|
public class StudySessionsServiceImpl extends ServiceImpl<StudySessionsMapper, StudySessionsEntity>
|
||||||
implements StudySessionsService{
|
implements StudySessionsService{
|
||||||
|
|
||||||
|
public StudySessionResponce startOrContinueStudySession(String taskId) {
|
||||||
|
// 任务id下是否存在非”已结束“的学习会话
|
||||||
|
Optional<StudySessionsEntity> oneOpt = this.getOneOpt(Wrappers.<StudySessionsEntity>lambdaQuery()
|
||||||
|
.eq(StudySessionsEntity::getTaskId, taskId)
|
||||||
|
.ne(StudySessionsEntity::getSessionState, StudySessionStateEnum.ENDED.name()));
|
||||||
|
// 有则返回该未完成会话,否则创建新的会话
|
||||||
|
if (oneOpt.isEmpty()) {
|
||||||
|
// 返回一个新的会话
|
||||||
|
StudySessionsEntity studySessionsEntity = StudySessionsEntity.initNewSession();
|
||||||
|
this.save(studySessionsEntity);
|
||||||
|
return StudySessionConvert.MAPPER.toStudySessionResponce(studySessionsEntity);
|
||||||
|
}else {
|
||||||
|
// 返回已经存在的会话
|
||||||
|
StudySessionsEntity studySessionsEntity = oneOpt.get();
|
||||||
|
studySessionsEntity.continueStudySession();
|
||||||
|
this.updateById(studySessionsEntity);
|
||||||
|
return StudySessionConvert.MAPPER.toStudySessionResponce(studySessionsEntity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void pauseStudySession(String sessionId) throws ErrorParameterException {
|
||||||
|
StudySessionsEntity studySessionsEntity = this.getOptById(sessionId)
|
||||||
|
.orElseThrow(() -> new ErrorParameterException("会话[" + sessionId + "]不存在"));
|
||||||
|
studySessionsEntity.pausedStudySession();
|
||||||
|
this.updateById(studySessionsEntity);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user