feat(预期):学习预期后端闭环——实体/服务/端点

- 迁移:study_expectations.session_num 改为 varchar 对齐会话编码
- StudyExpectationsEntity / Mapper / Service:每会话一条预期,重复创建覆盖
- StudySessionController:PUT/GET /{sessionNum}/expectation
- 移除空的 studySessionList 占位方法
This commit is contained in:
2026-07-03 23:38:52 +08:00
parent 090d03e251
commit b67cf238c2
7 changed files with 150 additions and 2 deletions
@@ -2,9 +2,12 @@ package com.guo.learningprogresstracker.controller;
import com.google.protobuf.ServiceException;
import com.guo.learningprogresstracker.dto.request.EndedStudySessionRequest;
import com.guo.learningprogresstracker.dto.request.UpsertExpectationRequest;
import com.guo.learningprogresstracker.dto.response.StudySessionResponse;
import com.guo.learningprogresstracker.entity.CommonResult;
import com.guo.learningprogresstracker.entity.StudyExpectationsEntity;
import com.guo.learningprogresstracker.exception.ErrorParameterException;
import com.guo.learningprogresstracker.service.StudyExpectationsService;
import com.guo.learningprogresstracker.service.impl.StudySessionsServiceImpl;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotEmpty;
@@ -26,9 +29,25 @@ public class StudySessionController {
private final StudySessionsServiceImpl studySessionsServiceImpl;
@PostMapping
public void studySessionList() {
private final StudyExpectationsService studyExpectationsService;
/**
* 创建/更新学习会话的学习预期
*/
@PutMapping("/{sessionNum}/expectation")
public CommonResult<StudyExpectationsEntity> upsertExpectation(
@PathVariable("sessionNum") String sessionNum,
@Valid @RequestBody UpsertExpectationRequest request) throws ErrorParameterException {
return CommonResult.success(studyExpectationsService.upsertExpectation(sessionNum, request.getDescription()));
}
/**
* 获取学习会话的学习预期
*/
@GetMapping("/{sessionNum}/expectation")
public CommonResult<StudyExpectationsEntity> getExpectation(
@PathVariable("sessionNum") String sessionNum) {
return CommonResult.success(studyExpectationsService.getBySessionNum(sessionNum));
}
/**
@@ -0,0 +1,14 @@
package com.guo.learningprogresstracker.dto.request;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
/**
* 创建/更新学习预期请求
*/
@Data
public class UpsertExpectationRequest {
@NotBlank(message = "学习预期不可为空")
private String description;
}
@@ -0,0 +1,32 @@
package com.guo.learningprogresstracker.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
/**
* 存储每次学习开始前的预期
*/
@TableName(value = "study_expectations")
@Data
public class StudyExpectationsEntity extends BaseEntity implements Serializable {
@TableId(value = "expectation_id", type = IdType.AUTO)
private Integer expectationId;
@TableField(value = "session_num")
private String sessionNum;
/**
* 学习预期的详细描述
*/
@TableField(value = "description")
private String description;
@TableField(exist = false)
private static final long serialVersionUID = 1L;
}
@@ -0,0 +1,9 @@
package com.guo.learningprogresstracker.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.guo.learningprogresstracker.entity.StudyExpectationsEntity;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface StudyExpectationsMapper extends BaseMapper<StudyExpectationsEntity> {
}
@@ -0,0 +1,20 @@
package com.guo.learningprogresstracker.service;
import com.guo.learningprogresstracker.entity.StudyExpectationsEntity;
import com.guo.learningprogresstracker.exception.ErrorParameterException;
/**
* 学习预期服务
*/
public interface StudyExpectationsService {
/**
* 为学习会话创建学习预期(每个会话最多一条,重复创建则覆盖)
*/
StudyExpectationsEntity upsertExpectation(String sessionNum, String description) throws ErrorParameterException;
/**
* 查询学习会话的学习预期,不存在时返回 null
*/
StudyExpectationsEntity getBySessionNum(String sessionNum);
}
@@ -0,0 +1,52 @@
package com.guo.learningprogresstracker.service.impl;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.guo.learningprogresstracker.entity.StudyExpectationsEntity;
import com.guo.learningprogresstracker.entity.StudySessionsEntity;
import com.guo.learningprogresstracker.exception.ErrorParameterException;
import com.guo.learningprogresstracker.mapper.StudyExpectationsMapper;
import com.guo.learningprogresstracker.mapper.StudySessionsMapper;
import com.guo.learningprogresstracker.service.StudyExpectationsService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
/**
* 学习预期服务实现
*/
@Service
@RequiredArgsConstructor
public class StudyExpectationsServiceImpl implements StudyExpectationsService {
private final StudyExpectationsMapper studyExpectationsMapper;
private final StudySessionsMapper studySessionsMapper;
@Override
public StudyExpectationsEntity upsertExpectation(String sessionNum, String description) throws ErrorParameterException {
boolean sessionExists = studySessionsMapper.exists(
Wrappers.<StudySessionsEntity>lambdaQuery()
.eq(StudySessionsEntity::getSessionNum, sessionNum));
if (!sessionExists) {
throw new ErrorParameterException("学习会话[" + sessionNum + "]不存在");
}
StudyExpectationsEntity existing = getBySessionNum(sessionNum);
if (existing == null) {
StudyExpectationsEntity entity = new StudyExpectationsEntity();
entity.setSessionNum(sessionNum);
entity.setDescription(description);
studyExpectationsMapper.insert(entity);
return entity;
}
existing.setDescription(description);
studyExpectationsMapper.updateById(existing);
return existing;
}
@Override
public StudyExpectationsEntity getBySessionNum(String sessionNum) {
return studyExpectationsMapper.selectOne(
Wrappers.<StudyExpectationsEntity>lambdaQuery()
.eq(StudyExpectationsEntity::getSessionNum, sessionNum)
.last("LIMIT 1"));
}
}
@@ -0,0 +1,2 @@
alter table study_expectations
modify session_num varchar(255) not null comment '会话编码';