山东大学软件学院项目实训:基于AI大模型的智能考研助手(二)
前言:
本周我们小组进行了最基本的功能开发,包括用户注册和登录,以及基本错题本部分的开发。我负责设计最基本的数据库表结构和接口。用户的注册和登录使用阿里云OSS存储图片,登录后会生成jwt令牌,让用户端可以访问相关的后端接口;本周错题本的开发包括对于错题本和错题的增删改查。
一.数据库表设计
以上的业务功能涉及到的表结构如下,对于以下的这些表中数据的删除,都采用逻辑删除的形式,即将deleted设为1,以防出现查找的时候产生空指针异常。

用户表,包含用户最基本的信息,包括姓名,头像,密码等内容。

错题本表,用于表示错题本实体,用于存储错题,与用户关联,一个用户可以有多个错题本:

错题表,用于存储错题的基本信息,包含标题,题干和答案

错题本-错题表,错题本和错题设计为多对多的关系,一个错题本可以存储多个错题,一个错题可以在多个错题本中使用:

错题-图片表,用于专门存储错题本中含有的图片,图片为阿里云OSS中的图片路径,type表示此图片是属于答案的图片还是题干的图片,0表示题干图片,1表示答案图片,在代码中专门用TopicConstant类存储:

public class TopicConstant {
public static final Integer TOPIC_PICTURE_STEM = 0 ;
public static final Integer TOPIC_PICTURE_ANSWER =1 ;
}
二.相关接口和代码设计
2.1 相关基础代码设计
创建这些表信息的实体类,与表中字段一一对应,这里以Topic为例,其他表亦有对应的实体类:
@Schema(description = "题目")
public class Topic extends BaseEntity{
@TableId(type = IdType.AUTO)
@Schema(description = "题目id")
private Long id;
@Schema(description = "题目标题")
private String title;
@Schema(description = "题干")
private String questionStem;
@Schema(description = "答案")
private String answer;
}
此外我添加了一些实体类,用于处理特殊的数据:
Result类:用于规范传给前端的格式,其中包括响应码,信息和数据,采用泛型的形式来规范传递给前端的数据类型
BaseRequest类:将id等信息封装成RequestBody形式,用于规范
BaseEntity类:用于存储最基本的信息,包括创建时间,修改时间和是否删除,许多类可以继承这个实体类以进行最基本的三个操作
/*
Result类,用于封装后端传给前端的数据,包括数据本身和响应码等
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Result<T> implements Serializable {
private Integer code;//响应码,1 代表成功; 0 代表失败
private String msg; //响应信息 描述字符串
private T data; //返回的数据
//增删改 成功响应
public static <T> Result<T> success(){
return new Result<>(1,"success",null);
}
//查询 成功响应
public static <T> Result<T> success(T data){
return new Result<>(1,"success",data);
}
//失败响应
public static <T> Result<T> error(String msg){
return new Result<>(0,msg,null);
}
}
/*
BaseRequest类,用于接受前端的基础请求参数,比如id等信息,使用字符串为主体,在后端转换
*/
@Data
@Schema(description = "基础请求参数")
public class BaseRequest {
@Schema(description = "id")
private String id;
}
/*
BaseEntity类,用于整合出多数数据实体的公共数据,这样重复的部分只要继承其就行了
*/
public class BaseEntity {
@Schema(description = "创建时间")
private LocalDateTime createTime;
@Schema(description = "更新时间")
private LocalDateTime updateTime;
@Schema(description = "是否删除")
private Integer deleted;
}
2.2 相关接口的设计:
此为错题部分的相关接口,包含获取题目列表,获取题目详情,添加题目,删除题目和更新题目接口,采用Post形式进行访问。此为基本的增删改查功能
@PostMapping("/list")
@Operation(summary = "获取题目列表")
public Result<List<TopicListVO>> list(@RequestBody TopicQueryDTO topicQueryDTO){
log.info("获取题目列表,参数:{}", topicQueryDTO);
List<TopicListVO> topicList = topicService.listVO(topicQueryDTO);
return Result.success(topicList);
}
@PostMapping("/detail")
@Operation(summary = "获取题目详情")
public Result<TopicVO> detail(@RequestBody BaseRequest baseRequest){
log.info("获取题目详情,参数:{}", baseRequest);
TopicVO topic = topicService.getDetailById(baseRequest);
return Result.success(topic);
}
@PostMapping("/add")
@Operation(summary = "添加题目")
public Result add(@RequestBody TopicDTO topicDTO){
log.info("添加题目参数,{}", topicDTO);
topicService.add(topicDTO);
return Result.success();
}
@PostMapping("/delete")
@Operation(summary = "删除题目")
public Result delete(@RequestBody BaseRequest baseRequest){
log.info("删除题目参数,{}", baseRequest);
topicService.delete(baseRequest);
return Result.success();
}
//
//
@PostMapping("/update")
@Operation(summary = "更新题目")
public Result update(@RequestBody TopicDTO topicDTO){
log.info("更新题目参数,{}", topicDTO);
topicService.updateIt(topicDTO);
return Result.success();
}
此为错题本相关接口,包含对错题本基本的增删改查
public class NoteBookController {
private final INoteBookService notebookService;
@PostMapping("/add")
@Operation(summary = "添加错题本")
public Result add(@RequestBody NoteBookDTO noteBookDTO) {
notebookService.add(noteBookDTO);
return Result.success();
}
@PostMapping("/list")
@Operation(summary = "获取错题本列表")
public Result<List<NoteBookListVO>> list() {
List<NoteBookListVO> noteBookList = notebookService.listVO();
return Result.success(noteBookList);
}
@PostMapping("/delete")
@Operation(summary = "删除错题本")
public Result delete(@RequestBody BaseRequest request) {
notebookService.deleteById(request);
return Result.success();
}
@PostMapping("detail")
@Operation(summary = "获取错题本详情")
public Result<NoteBookVO> detail(@RequestBody BaseRequest request) {
log.info("获取错题本详情,id:{}", request);
NoteBookVO noteBookVO = notebookService.detail(request);
return Result.success(noteBookVO);
}
@PostMapping("/update")
@Operation(summary = "更新错题本基本信息")
public Result update(@RequestBody NoteBookDTO noteBookDTO) {
notebookService.updateIt(noteBookDTO);
return Result.success();
}
}
用户登录与注册相关接口,包含用户登录和注册模块。用户登录模块需要生成令牌,作为用户端每次访问后端端口的凭据。除了访问不需要通过令牌授权,其他接口都需要
public class UserController {
@Autowired
IUserService userService;
@PostMapping("/login")
@Operation(summary = "用户登录")
public Result<LoginVO> login(@RequestBody LoginDTO loginDTO){
User user = userService.login(loginDTO);
if(user == null) {
return Result.error("用户名或密码错误");
}
Map claims = new HashMap<>();
claims.put("userId",user.getId());
//为用户生成令牌
String token = JwtUtils.generateJwt(claims);
BaseContext.setCurrentId(user.getId());
LoginVO userLoginVO = LoginVO.builder()
.id(user.getId())
.name(user.getName())
.password(user.getPassword())
.avatar(user.getAvatar())
.token(token)
.build();
return Result.success(userLoginVO);
}
@PostMapping("/register")
@Operation(summary = "用户注册")
public Result register(@RequestBody RegisterDTO registerDTO) {
log.info("用户注册信息,{}",registerDTO);
userService.register(registerDTO);
return Result.success();
}
@PostMapping("/update")
@Operation(summary = "更新用户信息")
public Result update(@RequestBody UserDTO userDTO) {
log.info("更新用户信息,{}",userDTO);
userService.updateIt(userDTO);
return Result.success();
}
}
同时设置了上传头像接口,后端可以通过此接口将前端传过来的数据传给阿里云OSS,实现云存储功能:
public class UploadController {
@Autowired
private AliOSSUtils aliOSSUtils;
@PostMapping("/upload/avatar")
@Operation(summary = "上传头像")
//获取文件之方法
public Result<String> upload(@RequestParam("file") MultipartFile image) throws IOException {
log.info("文件上传:{}",image.getOriginalFilename());
//调用阿里云工具类进行文件上传
String url = aliOSSUtils.upload(image);
log.info("文件上传完成,url:{}",url);
return Result.success(url);
}
}
2.3 相关DTO和VO的设计
错题模块的DTO主要包含以下部分:
查询错题参数,以开始时间和结束时间为条件,以错题title作为模糊查询
@Data
@Schema(description = "查询错题参数")
public class TopicQueryDTO {
@Schema(description = "错题本id")
private Long noteBookId;
@Schema(description = "题目的title")
private String topicStem;
@Schema(description = "开始时间")
private LocalDateTime startTime;
@Schema(description = "结束时间")
private LocalDateTime endTime;
}
保存错题的参数,即TopicDTO,包含以下内容
@Data
@Builder
@Schema(description = "添加题目")
public class TopicDTO {
@Schema(description = "题目id")
private Long id;
@Schema(description = "题目标题")
private String title;
@Schema(description = "错题本id")
private Long noteBookId;
@Schema(description = "题干")
private String questionStem;
@Schema(description = "题干图片")
private List<String> questionStemPictureList;
@Schema(description = "答案")
private String answer;
@Schema(description = "答案图片")
private List<String> answerPictureList;
@Schema(description = "标签")
private List<String> labels;
}
用于显示错题详情的TopicVO,包含题目标题,题干等信息,对于图片等信息需要后端连表查询:
public class TopicVO implements Serializable {
// 添加 implements Serializable
// 添加 serialVersionUID
private static final long serialVersionUID = 1L;
@Schema(description = "题目id")
private Long id;
@Schema(description = "题目标题")
private String title;
@Schema(description = "题干")
private String questionStem;
@Schema(description = "题干图片")
private List<String> questionStemPictureUrls;
@Schema(description = "答案")
private String answer;
@Schema(description = "答案图片")
private List<String> answerPictureUrls;
@Schema(description = "创建时间")
private LocalDateTime createTime;
@Schema(description = "更新时间")
private LocalDateTime updateTime;
@Schema(description = "题目标签")
private List<Label> labels;
}
TopicListVO,用于展示错题的缩略图形式,包含以下信息:
public class TopicListVO implements Serializable{
// 添加 implements Serializable
@Schema(description = "题目id")
private Long id;
@Schema(description = "题目标题")
private String title;
@Schema(description = "题干")
private String topicStem;
@Schema(description = "图片")
private List<String> pictureUrls;
@Schema(description = "创建时间")
private LocalDateTime createTime;
@Schema(description = "修改时间")
private LocalDateTime updateTime;
@Schema(description = "标签")
private List<Label> labels;
}
错题本相关DTO参数,包含错题本名称,简介等信息:
@Schema(description = "错题本添加信息")
@Data
public class NoteBookDTO {
@Schema(description = "错题本id")
private Long id;
@Schema(description = "错题本名称")
private String name;
@Schema(description = "错题本简介")
private String brief;
}
错题本相关的VO参数,包含错题本的缩略图VO以及错题本的详情VO
public class NoteBookListVO {
@Schema(description = "错题本id")
private Long id;
@Schema(description = "错题本名称")
private String name;
@Schema(description = "错题本简介")
private String brief;
@Schema(description = "创建时间")
private LocalDateTime createTime;
@Schema(description = "更新时间")
private LocalDateTime updateTime;
}
public class NoteBookVO {
@Schema(description = "错题本id")
private Long id;
@Schema(description = "错题本名称")
private String name;
@Schema(description = "错题本简介")
private String brief;
@Schema(description = "创建时间")
private LocalDateTime createTime;
@Schema(description = "更新时间")
private LocalDateTime updateTime;
}
用户模块相关的DTO,包含用户登录DTO和注册DTO,用于接受,来自前端的登录和注册信息:
@Data
@Schema(description = "用户登录信息")
public class LoginDTO {
@Schema(description = "用户名")
private String name;
@Schema(description = "密码")
private String password;
}
@Data
public class RegisterDTO {
private String name;
private String password;
private String avatar;
}
用户模块相关的VO,其中除了基础的id,名字头像,还包含token,作为令牌访问后端
public class LoginVO {
private Long id;
private String name;
private String avatar;
private String token;
}
三.总结
本周小组围绕用户体系与错题本核心功能完成了基础开发工作,我主要负责数据库表结构与接口设计,整体采用逻辑删除机制保障数据安全,通过阿里云OSS实现头像存储、JWT令牌校验用户身份,构建了覆盖用户全生命周期及错题管理的基础架构。在数据库层面,设计了用户表、错题本表、错题表及关联中间表,通过BaseEntity统一封装创建时间、更新时间与删除标记,配合TopicConstant常量类规范图片类型,实现了多对多错题关联与图片分离存储的灵活结构。接口设计上,基于RESTful风格封装了Result统一响应格式与BaseRequest基础参数模型,完成了用户注册登录(含令牌生成)、错题本与错题的增删改查全流程接口,并通过DTO/VO分层隔离前后端数据交互,既保障了数据传输的规范性,也为后续功能扩展预留了清晰的架构边界,为系统后续迭代奠定了稳定可靠的基础。
更多推荐


所有评论(0)