|
|
package com.yf.exam.modules.user.book.service.impl;
|
|
|
|
|
|
import com.alibaba.fastjson.JSON;
|
|
|
import com.alibaba.fastjson.TypeReference;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
|
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
import com.yf.exam.core.api.dto.PagingReqDTO;
|
|
|
import com.yf.exam.modules.qu.entity.Qu;
|
|
|
import com.yf.exam.modules.qu.service.QuService;
|
|
|
import com.yf.exam.modules.user.UserUtils;
|
|
|
import com.yf.exam.modules.user.book.dto.UserBookDTO;
|
|
|
import com.yf.exam.modules.user.book.entity.UserBook;
|
|
|
import com.yf.exam.modules.user.book.mapper.UserBookMapper;
|
|
|
import com.yf.exam.modules.user.book.service.UserBookService;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.util.StringUtils;
|
|
|
|
|
|
/**
|
|
|
* <p>
|
|
|
* 错题本服务实现类,实现了错题本相关的业务逻辑。
|
|
|
* </p>
|
|
|
*
|
|
|
* @author 聪明笨狗
|
|
|
* @since 2020-05-27 17:56
|
|
|
*/
|
|
|
@Service
|
|
|
public class UserBookServiceImpl extends ServiceImpl<UserBookMapper, UserBook> implements UserBookService {
|
|
|
|
|
|
/**
|
|
|
* 注入题目服务类,用于获取题目相关信息
|
|
|
*/
|
|
|
@Autowired
|
|
|
private QuService quService;
|
|
|
|
|
|
/**
|
|
|
* 分页查询用户错题本记录
|
|
|
* @param reqDTO 包含分页信息和查询条件的请求对象
|
|
|
* @return 包含分页结果的错题本记录 DTO 对象
|
|
|
*/
|
|
|
@Override
|
|
|
public IPage<UserBookDTO> paging(PagingReqDTO<UserBookDTO> reqDTO) {
|
|
|
|
|
|
// 创建分页对象,指定当前页码和每页显示数量
|
|
|
Page query = new Page<>(reqDTO.getCurrent(), reqDTO.getSize());
|
|
|
|
|
|
// 构建查询条件包装器
|
|
|
QueryWrapper<UserBook> wrapper = new QueryWrapper<>();
|
|
|
// 只查询当前用户的错题记录
|
|
|
wrapper.lambda().eq(UserBook::getUserId, UserUtils.getUserId(true));
|
|
|
|
|
|
// 获取查询参数
|
|
|
UserBookDTO params = reqDTO.getParams();
|
|
|
if (params != null) {
|
|
|
// 如果标题参数不为空,添加模糊查询条件
|
|
|
if (!StringUtils.isEmpty(params.getTitle())) {
|
|
|
wrapper.lambda().like(UserBook::getTitle, params.getTitle());
|
|
|
}
|
|
|
|
|
|
// 如果考试 ID 参数不为空,添加精确查询条件
|
|
|
if (!StringUtils.isEmpty(params.getExamId())) {
|
|
|
wrapper.lambda().eq(UserBook::getExamId, params.getExamId());
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 执行分页查询,获取错题本实体分页数据
|
|
|
IPage<UserBook> page = this.page(query, wrapper);
|
|
|
// 将实体分页数据转换为 DTO 分页数据
|
|
|
IPage<UserBookDTO> pageData = JSON.parseObject(JSON.toJSONString(page), new TypeReference<Page<UserBookDTO>>(){});
|
|
|
return pageData;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 将错题添加到用户错题本中
|
|
|
* @param examId 考试 ID
|
|
|
* @param quId 题目 ID
|
|
|
*/
|
|
|
@Override
|
|
|
public void addBook(String examId, String quId) {
|
|
|
|
|
|
// 构建查询条件,查找该用户在本次考试中该题目的错题记录
|
|
|
QueryWrapper<UserBook> wrapper = new QueryWrapper<>();
|
|
|
wrapper.lambda()
|
|
|
.eq(UserBook::getUserId, UserUtils.getUserId())
|
|
|
.eq(UserBook::getExamId, examId)
|
|
|
.eq(UserBook::getQuId, quId);
|
|
|
|
|
|
// 查找已有的错题信息
|
|
|
UserBook book = this.getOne(wrapper, false);
|
|
|
|
|
|
// 获取题目信息
|
|
|
Qu qu = quService.getById(quId);
|
|
|
|
|
|
if (book == null) {
|
|
|
// 如果该错题记录不存在,则创建新的错题记录
|
|
|
book = new UserBook();
|
|
|
book.setExamId(examId);
|
|
|
book.setUserId(UserUtils.getUserId());
|
|
|
book.setTitle(qu.getContent());
|
|
|
book.setQuId(quId);
|
|
|
book.setWrongCount(1);
|
|
|
// 获取当前考试中用户错题的最大排序值,并加 1 作为新记录的排序值
|
|
|
Integer maxSort = this.findMaxSort(examId, UserUtils.getUserId());
|
|
|
book.setSort(maxSort + 1);
|
|
|
|
|
|
// 保存新的错题记录
|
|
|
this.save(book);
|
|
|
} else {
|
|
|
// 如果该错题记录已存在,错误次数加 1
|
|
|
book.setWrongCount(book.getWrongCount() + 1);
|
|
|
// 更新错题记录
|
|
|
this.updateById(book);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 查找当前错题的下一个错题的题目 ID
|
|
|
* @param examId 考试 ID
|
|
|
* @param quId 当前错题的题目 ID
|
|
|
* @return 下一个错题的题目 ID,如果不存在则返回 null
|
|
|
*/
|
|
|
@Override
|
|
|
public String findNext(String examId, String quId) {
|
|
|
|
|
|
// 初始化排序值为一个较大值
|
|
|
Integer sort = 999999;
|
|
|
|
|
|
if (!StringUtils.isEmpty(quId)) {
|
|
|
// 构建查询条件,查找当前错题记录
|
|
|
QueryWrapper<UserBook> wrapper = new QueryWrapper<>();
|
|
|
wrapper.lambda()
|
|
|
.eq(UserBook::getUserId, UserUtils.getUserId())
|
|
|
.eq(UserBook::getExamId, examId)
|
|
|
.eq(UserBook::getQuId, quId);
|
|
|
// 按排序值降序排序
|
|
|
wrapper.last(" ORDER BY `sort` DESC");
|
|
|
|
|
|
// 获取当前错题记录
|
|
|
UserBook last = this.getOne(wrapper, false);
|
|
|
if (last != null) {
|
|
|
// 如果找到当前错题记录,获取其排序值
|
|
|
sort = last.getSort();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 构建查询条件,查找排序值小于当前错题的下一个错题记录
|
|
|
QueryWrapper<UserBook> wrapper = new QueryWrapper<>();
|
|
|
wrapper.lambda()
|
|
|
.eq(UserBook::getUserId, UserUtils.getUserId())
|
|
|
.eq(UserBook::getExamId, examId)
|
|
|
.lt(UserBook::getSort, sort);
|
|
|
// 按排序值降序排序
|
|
|
wrapper.last(" ORDER BY `sort` DESC");
|
|
|
|
|
|
// 获取下一个错题记录
|
|
|
UserBook next = this.getOne(wrapper, false);
|
|
|
if (next != null) {
|
|
|
// 如果找到下一个错题记录,返回其题目 ID
|
|
|
return next.getQuId();
|
|
|
}
|
|
|
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 查找指定考试中用户错题的最大排序值
|
|
|
* @param examId 考试 ID
|
|
|
* @param userId 用户 ID
|
|
|
* @return 最大排序值,如果没有记录则返回 0
|
|
|
*/
|
|
|
private Integer findMaxSort(String examId, String userId) {
|
|
|
|
|
|
// 构建查询条件,查找指定考试中用户的错题记录
|
|
|
QueryWrapper<UserBook> wrapper = new QueryWrapper<>();
|
|
|
wrapper.lambda()
|
|
|
.eq(UserBook::getExamId, examId)
|
|
|
.eq(UserBook::getUserId, userId);
|
|
|
// 按排序值降序排序
|
|
|
wrapper.last(" ORDER BY `sort` DESC");
|
|
|
|
|
|
// 获取排序值最大的错题记录
|
|
|
UserBook book = this.getOne(wrapper, false);
|
|
|
if (book == null) {
|
|
|
// 如果没有记录,返回 0
|
|
|
return 0;
|
|
|
}
|
|
|
// 返回最大排序值
|
|
|
return book.getSort();
|
|
|
}
|
|
|
}
|