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; /** *

* 错题本服务实现类,实现了错题本相关的业务逻辑。 *

* * @author 聪明笨狗 * @since 2020-05-27 17:56 */ @Service public class UserBookServiceImpl extends ServiceImpl implements UserBookService { /** * 注入题目服务类,用于获取题目相关信息 */ @Autowired private QuService quService; /** * 分页查询用户错题本记录 * @param reqDTO 包含分页信息和查询条件的请求对象 * @return 包含分页结果的错题本记录 DTO 对象 */ @Override public IPage paging(PagingReqDTO reqDTO) { // 创建分页对象,指定当前页码和每页显示数量 Page query = new Page<>(reqDTO.getCurrent(), reqDTO.getSize()); // 构建查询条件包装器 QueryWrapper 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 page = this.page(query, wrapper); // 将实体分页数据转换为 DTO 分页数据 IPage pageData = JSON.parseObject(JSON.toJSONString(page), new TypeReference>(){}); return pageData; } /** * 将错题添加到用户错题本中 * @param examId 考试 ID * @param quId 题目 ID */ @Override public void addBook(String examId, String quId) { // 构建查询条件,查找该用户在本次考试中该题目的错题记录 QueryWrapper 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 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 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 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(); } }