yutao 10 months ago
parent 4b21fc9d32
commit 36d1edbed4

@ -0,0 +1,75 @@
package com.yf.exam.modules.user;
// 导入自定义的 API 错误信息类
import com.yf.exam.core.api.ApiError;
// 导入自定义的服务异常类
import com.yf.exam.core.exception.ServiceException;
// 导入系统用户登录信息响应数据传输对象
import com.yf.exam.modules.sys.user.dto.response.SysUserLoginDTO;
// 导入 Shiro 安全工具类
import org.apache.shiro.SecurityUtils;
/**
*
* @author bool
*/
public class UserUtils {
/**
* ID
*
* @param throwable ID
* true ServiceException
* false null
* @return ID throwable false null
*/
public static String getUserId(boolean throwable){
try {
// 从 Shiro 的 Subject 中获取当前用户的主身份信息,并转换为 SysUserLoginDTO 对象,然后获取用户 ID
return ((SysUserLoginDTO) SecurityUtils.getSubject().getPrincipal()).getId();
}catch (Exception e){
if(throwable){
// 若 throwable 为 true获取用户 ID 失败时抛出服务异常
throw new ServiceException(ApiError.ERROR_10010002);
}
// 若 throwable 为 false获取用户 ID 失败时返回 null
return null;
}
}
/**
*
*
* @param throwable
* true ServiceException
* false false
* @return "sa" true false
* throwable false false
*/
public static boolean isAdmin(boolean throwable){
try {
// 从 Shiro 的 Subject 中获取当前用户的主身份信息,并转换为 SysUserLoginDTO 对象
SysUserLoginDTO dto = ((SysUserLoginDTO) SecurityUtils.getSubject().getPrincipal());
// 判断用户的角色列表是否包含 "sa"
return dto.getRoles().contains("sa");
}catch (Exception e){
if(throwable){
// 若 throwable 为 true获取用户信息失败时抛出服务异常
throw new ServiceException(ApiError.ERROR_10010002);
}
}
// 若获取用户信息失败且 throwable 为 false返回 false
return false;
}
/**
* ID
* getUserId(boolean throwable) throwable true
*
* @return ID ServiceException
*/
public static String getUserId(){
return getUserId(true);
}
}

@ -0,0 +1,79 @@
package com.yf.exam.modules.user.book.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yf.exam.core.api.ApiRest;
import com.yf.exam.core.api.controller.BaseController;
import com.yf.exam.core.api.dto.BaseIdRespDTO;
import com.yf.exam.core.api.dto.BaseIdsReqDTO;
import com.yf.exam.core.api.dto.PagingReqDTO;
import com.yf.exam.modules.user.book.dto.UserBookDTO;
import com.yf.exam.modules.user.book.service.UserBookService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
/**
* <p>
* HTTP
* </p>
*
* @author
* @since 2020-05-27 17:56
*/
@Api(tags={"错题本"})
@RestController
@RequestMapping("/exam/api/user/wrong-book")
public class UserBookController extends BaseController {
/**
*
*/
@Autowired
private UserBookService baseService;
/**
*
* @param reqDTO ID
* @return
*/
@ApiOperation(value = "批量删除")
@RequestMapping(value = "/delete", method = { RequestMethod.POST})
public ApiRest delete(@RequestBody BaseIdsReqDTO reqDTO) {
// 根据传入的ID列表删除对应的错题本记录
baseService.removeByIds(reqDTO.getIds());
// 返回操作成功的响应
return super.success();
}
/**
*
* @param reqDTO
* @return
*/
@ApiOperation(value = "分页查找")
@RequestMapping(value = "/paging", method = { RequestMethod.POST})
public ApiRest<IPage<UserBookDTO>> paging(@RequestBody PagingReqDTO<UserBookDTO> reqDTO) {
// 调用服务层方法进行分页查询并将结果转换为UserBookDTO对象
IPage<UserBookDTO> page = baseService.paging(reqDTO);
// 返回包含分页结果的成功响应
return super.success(page);
}
/**
* 200
* @param reqDTO IDID
* @return ID
*/
@ApiOperation(value = "查找列表")
@RequestMapping(value = "/next", method = { RequestMethod.POST})
public ApiRest<BaseIdRespDTO> nextQu(@RequestBody UserBookDTO reqDTO) {
// 调用服务层方法查找下一个错题的题目ID
String quId = baseService.findNext(reqDTO.getExamId(), reqDTO.getQuId());
// 将下一个题目ID封装到响应对象中并返回成功响应
return super.success(new BaseIdRespDTO(quId));
}
}

@ -0,0 +1,79 @@
package com.yf.exam.modules.user.book.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* <p>
*
* IDIDID
* </p>
*
* @author
* @since 2020-05-27 17:56
*/
@Data
@ApiModel(value="错题本", description="错题本")
public class UserBookDTO implements Serializable {
// 序列化版本号,用于保证序列化和反序列化过程中类的版本一致性
private static final long serialVersionUID = 1L;
/**
* ID
*/
@ApiModelProperty(value = "ID", required=true)
private String id;
/**
* ID
*/
@ApiModelProperty(value = "考试ID", required=true)
private String examId;
/**
* ID
*/
@ApiModelProperty(value = "用户ID", required=true)
private String userId;
/**
* ID
*/
@ApiModelProperty(value = "题目ID", required=true)
private String quId;
/**
*
*/
@ApiModelProperty(value = "加入时间", required=true)
private Date createTime;
/**
*
*/
@ApiModelProperty(value = "最近错误时间", required=true)
private Date updateTime;
/**
*
*/
@ApiModelProperty(value = "错误时间", required=true)
private Integer wrongCount;
/**
*
*/
@ApiModelProperty(value = "题目标题", required=true)
private String title;
/**
*
*/
@ApiModelProperty(value = "错题序号", required=true)
private Integer sort;
}

@ -0,0 +1,80 @@
package com.yf.exam.modules.user.book.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 com.baomidou.mybatisplus.extension.activerecord.Model;
import lombok.Data;
import java.util.Date;
/**
* <p>
* `el_user_book`
* MyBatis-Plus `Model` 使 ActiveRecord
* </p>
*
* @author
* @since 2020-05-27 17:56
*/
@Data
@TableName("el_user_book")
public class UserBook extends Model<UserBook> {
// 序列化版本号,确保序列化和反序列化过程中类版本的一致性
private static final long serialVersionUID = 1L;
/**
* ID
*/
@TableId(value = "id", type = IdType.ASSIGN_ID)
private String id;
/**
* ID
*/
@TableField("exam_id")
private String examId;
/**
* ID
*/
@TableField("user_id")
private String userId;
/**
* ID
*/
@TableField("qu_id")
private String quId;
/**
*
*/
@TableField("create_time")
private Date createTime;
/**
*
*/
@TableField("update_time")
private Date updateTime;
/**
*
*/
@TableField("wrong_count")
private Integer wrongCount;
/**
* 便
*/
private String title;
/**
*
*/
private Integer sort;
}

@ -0,0 +1,18 @@
package com.yf.exam.modules.user.book.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yf.exam.modules.user.book.entity.UserBook;
/**
* <p>
* Mapper
* MyBatis-PlusBaseMapper使BaseMapperCRUD
* </p>
*
* @author
* @since 2020-05-27 17:56
*/
public interface UserBookMapper extends BaseMapper<UserBook> {
// 若需要自定义数据库操作方法,可在此处添加接口方法声明
// 对应的SQL语句可以在XML文件中实现或者使用@Select、@Insert等注解
}

@ -0,0 +1,41 @@
package com.yf.exam.modules.user.book.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yf.exam.core.api.dto.PagingReqDTO;
import com.yf.exam.modules.user.book.dto.UserBookDTO;
import com.yf.exam.modules.user.book.entity.UserBook;
/**
* <p>
*
* MyBatis-Plus IService 使
* </p>
*
* @author
* @since 2020-05-27 17:56
*/
public interface UserBookService extends IService<UserBook> {
/**
*
* @param reqDTO UserBookDTO
* @return UserBookDTO IPage
*/
IPage<UserBookDTO> paging(PagingReqDTO<UserBookDTO> reqDTO);
/**
*
* @param examId ID
* @param quId ID
*/
void addBook(String examId, String quId);
/**
*
* @param examId ID
* @param quId ID
* @return ID null
*/
String findNext(String examId, String quId);
}

@ -0,0 +1,192 @@
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();
}
}

@ -0,0 +1,65 @@
package com.yf.exam.modules.user.exam.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yf.exam.core.api.ApiRest;
import com.yf.exam.core.api.controller.BaseController;
import com.yf.exam.core.api.dto.PagingReqDTO;
import com.yf.exam.modules.user.exam.dto.request.UserExamReqDTO;
import com.yf.exam.modules.user.exam.dto.response.UserExamRespDTO;
import com.yf.exam.modules.user.exam.service.UserExamService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
/**
* <p>
* HTTP
*
* </p>
*
* @author
* @since 2020-09-21 15:13
*/
@Api(tags={"考试记录"})
@RestController
@RequestMapping("/exam/api/user/exam")
public class UserExamController extends BaseController {
/**
*
*/
@Autowired
private UserExamService baseService;
/**
*
* @param reqDTO UserExamReqDTO
* @return UserExamRespDTO
*/
@ApiOperation(value = "分页查找")
@RequestMapping(value = "/paging", method = { RequestMethod.POST})
public ApiRest<IPage<UserExamRespDTO>> paging(@RequestBody PagingReqDTO<UserExamReqDTO> reqDTO) {
// 调用服务层的分页查询方法,获取分页后的考试记录
IPage<UserExamRespDTO> page = baseService.paging(reqDTO);
// 返回包含分页结果的成功响应
return super.success(page);
}
/**
*
* @param reqDTO UserExamReqDTO
* @return UserExamRespDTO
*/
@ApiOperation(value = "分页查找")
@RequestMapping(value = "/my-paging", method = { RequestMethod.POST})
public ApiRest<IPage<UserExamRespDTO>> myPaging(@RequestBody PagingReqDTO<UserExamReqDTO> reqDTO) {
// 调用服务层的分页查询方法,获取当前用户分页后的考试记录
IPage<UserExamRespDTO> page = baseService.myPaging(reqDTO);
// 返回包含分页结果的成功响应
return super.success(page);
}
}

@ -0,0 +1,84 @@
// 声明该类所在的包,此包用于存放用户考试相关的数据传输对象
package com.yf.exam.modules.user.exam.dto;
// 导入自定义的字典注解,用于处理数据字典映射
import com.yf.exam.core.annon.Dict;
// 导入 Swagger 相关注解,用于生成 API 文档
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
// 导入 Lombok 的 Data 注解,自动生成 getter、setter、equals、hashCode 和 toString 方法
import lombok.Data;
// 导入日期类,用于表示时间相关的属性
import java.util.Date;
// 导入序列化接口,使该类的对象可以被序列化和反序列化
import java.io.Serializable;
/**
* <p>
* 访
* IDID
* </p>
*
* @author
* @since 2020-09-21 15:13
*/
// 使用 Lombok 的 Data 注解,简化代码,自动生成常用方法
@Data
// 使用 Swagger 的 ApiModel 注解,为 API 文档提供该类的描述信息
@ApiModel(value="考试记录", description="考试记录")
public class UserExamDTO implements Serializable {
// 序列化版本号,用于保证序列化和反序列化过程中类的版本一致性,避免版本不一致导致的错误
private static final long serialVersionUID = 1L;
/**
* ID
*/
private String id;
/**
* ID
*/
@ApiModelProperty(value = "用户ID", required=true)
private String userId;
/**
* ID
* @Dict `el_exam` `id` `title`
* 便
*/
@Dict(dictTable = "el_exam", dicText = "title", dicCode = "id")
@ApiModelProperty(value = "考试ID", required=true)
private String examId;
/**
*
*/
@ApiModelProperty(value = "考试次数", required=true)
private Integer tryCount;
/**
*
*/
@ApiModelProperty(value = "最高分数", required=true)
private Integer maxScore;
/**
*
*/
@ApiModelProperty(value = "是否通过", required=true)
private Boolean passed;
/**
*
*/
@ApiModelProperty(value = "创建时间")
private Date createTime;
/**
*
*/
@ApiModelProperty(value = "更新时间")
private Date updateTime;
}

@ -0,0 +1,42 @@
package com.yf.exam.modules.user.exam.dto.request;
// 导入 UserExamDTO 类,作为当前类的父类
import com.yf.exam.modules.user.exam.dto.UserExamDTO;
// 导入 Swagger 注解,用于 API 文档生成
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
// 导入 Lombok 的 Data 注解,自动生成 getter、setter、toString 等方法
import lombok.Data;
/**
* <p>
*
* UserExamDTO
* </p>
*
* @author
* @since 2020-09-21 15:13
*/
// 使用 Lombok 的 Data 注解,自动生成常用方法
@Data
// 使用 Swagger 的 ApiModel 注解,为 API 文档提供模型描述
@ApiModel(value="考试记录", description="考试记录")
public class UserExamReqDTO extends UserExamDTO {
// 序列化版本号,用于保证序列化和反序列化过程中类的版本一致性
private static final long serialVersionUID = 1L;
/**
*
*/
// 使用 Swagger 的 ApiModelProperty 注解,为 API 文档描述该属性
@ApiModelProperty(value = "考试名称", required=true)
private String title;
/**
*
*/
// 使用 Swagger 的 ApiModelProperty 注解,为 API 文档描述该属性
@ApiModelProperty(value = "人员名称", required=true)
private String realName;
}

@ -0,0 +1,36 @@
package com.yf.exam.modules.user.exam.dto.response;
import com.yf.exam.modules.user.exam.dto.UserExamDTO;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* <p>
*
* UserExamDTO
* </p>
*
* @author
* @since 2020-09-21 15:13
*/
@Data
@ApiModel(value="考试记录", description="考试记录")
public class UserExamRespDTO extends UserExamDTO {
// 序列化版本号,用于保证序列化和反序列化过程中类的版本一致性
private static final long serialVersionUID = 1L;
/**
*
*/
@ApiModelProperty(value = "考试名称", required=true)
private String title;
/**
*
*/
@ApiModelProperty(value = "人员名称", required=true)
private String realName;
}

@ -0,0 +1,85 @@
package com.yf.exam.modules.user.exam.entity;
// 导入 MyBatis-Plus 主键类型注解,用于指定主键生成策略
import com.baomidou.mybatisplus.annotation.IdType;
// 导入 MyBatis-Plus 表字段注解,用于指定实体类属性与数据库表字段的映射关系
import com.baomidou.mybatisplus.annotation.TableField;
// 导入 MyBatis-Plus 表主键注解,用于指定实体类的主键属性
import com.baomidou.mybatisplus.annotation.TableId;
// 导入 MyBatis-Plus 表名注解,用于指定实体类对应的数据库表名
import com.baomidou.mybatisplus.annotation.TableName;
// 导入 MyBatis-Plus 活动记录模型类,实体类继承该类可使用活动记录模式操作数据库
import com.baomidou.mybatisplus.extension.activerecord.Model;
// 导入 Lombok 的 Data 注解,自动生成 getter、setter、equals、hashCode 和 toString 方法
import lombok.Data;
// 导入日期类,用于表示时间相关的属性
import java.util.Date;
/**
* <p>
* `el_user_exam`
* MyBatis-Plus Model 使
* </p>
*
* @author
* @since 2020-09-21 15:13
*/
// 使用 Lombok 的 Data 注解,简化代码,自动生成常用方法
@Data
// 使用 MyBatis-Plus 的 TableName 注解,指定该实体类对应的数据库表名为 `el_user_exam`
@TableName("el_user_exam")
public class UserExam extends Model<UserExam> {
// 序列化版本号,用于保证序列化和反序列化过程中类的版本一致性
private static final long serialVersionUID = 1L;
/**
* ID `id`
* 使 MyBatis-Plus TableId ASSIGN_ID ID
*/
@TableId(value = "id", type = IdType.ASSIGN_ID)
private String id;
/**
* ID `user_id`
*/
@TableField("user_id")
private String userId;
/**
* ID `exam_id`
*/
@TableField("exam_id")
private String examId;
/**
* `try_count`
*/
@TableField("try_count")
private Integer tryCount;
/**
* `max_score`
*/
@TableField("max_score")
private Integer maxScore;
/**
*
*
*/
private Boolean passed;
/**
* `create_time`
*/
@TableField("create_time")
private Date createTime;
/**
* `update_time`
*/
@TableField("update_time")
private Date updateTime;
}

@ -0,0 +1,37 @@
package com.yf.exam.modules.user.exam.mapper;
// 导入 MyBatis-Plus 基础 Mapper 接口,提供基本的数据库 CRUD 操作
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
// 导入 MyBatis-Plus 分页查询结果接口,用于封装分页查询结果
import com.baomidou.mybatisplus.core.metadata.IPage;
// 导入 MyBatis-Plus 分页对象,用于设置分页查询的参数
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
// 导入考试记录请求数据传输对象,用于封装查询条件
import com.yf.exam.modules.user.exam.dto.request.UserExamReqDTO;
// 导入考试记录响应数据传输对象,用于封装查询结果
import com.yf.exam.modules.user.exam.dto.response.UserExamRespDTO;
// 导入考试记录实体类,对应数据库中的考试记录表
import com.yf.exam.modules.user.exam.entity.UserExam;
// 导入 MyBatis 参数注解,用于在 SQL 语句中引用方法参数
import org.apache.ibatis.annotations.Param;
/**
* <p>
* Mapper
* MyBatis-Plus BaseMapper 使
* </p>
*
* @author
* @since 2020-09-21 15:13
*/
public interface UserExamMapper extends BaseMapper<UserExam> {
/**
*
* @param page
* @param query
* @return IPage
*/
IPage<UserExamRespDTO> paging(Page page, @Param("query") UserExamReqDTO query);
}

@ -0,0 +1,50 @@
package com.yf.exam.modules.user.exam.service;
// 导入 MyBatis-Plus 分页元数据接口,用于封装分页查询结果
import com.baomidou.mybatisplus.core.metadata.IPage;
// 导入 MyBatis-Plus 扩展服务接口,提供基础的 CRUD 操作
import com.baomidou.mybatisplus.extension.service.IService;
// 导入自定义的分页请求数据传输对象,用于封装分页查询的请求参数
import com.yf.exam.core.api.dto.PagingReqDTO;
// 导入考试记录请求数据传输对象,用于封装考试记录查询的具体条件
import com.yf.exam.modules.user.exam.dto.request.UserExamReqDTO;
// 导入考试记录响应数据传输对象,用于封装考试记录查询的返回结果
import com.yf.exam.modules.user.exam.dto.response.UserExamRespDTO;
// 导入考试记录实体类,对应数据库中的考试记录数据
import com.yf.exam.modules.user.exam.entity.UserExam;
/**
* <p>
*
* MyBatis-Plus IService 使
* </p>
*
* @author
* @since 2020-09-21 15:13
*/
public interface UserExamService extends IService<UserExam> {
/**
*
* @param reqDTO UserExamReqDTO
* @return IPage
*/
IPage<UserExamRespDTO> paging(PagingReqDTO<UserExamReqDTO> reqDTO);
/**
*
* @param reqDTO UserExamReqDTO
* @return IPage
*/
IPage<UserExamRespDTO> myPaging(PagingReqDTO<UserExamReqDTO> reqDTO);
/**
*
*
* @param userId ID
* @param examId ID
* @param score
* @param passed
*/
void joinResult(String userId, String examId, Integer score, boolean passed);
}

@ -0,0 +1,116 @@
package com.yf.exam.modules.user.exam.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yf.exam.core.api.dto.PagingReqDTO;
import com.yf.exam.modules.user.UserUtils;
import com.yf.exam.modules.user.exam.dto.request.UserExamReqDTO;
import com.yf.exam.modules.user.exam.dto.response.UserExamRespDTO;
import com.yf.exam.modules.user.exam.entity.UserExam;
import com.yf.exam.modules.user.exam.mapper.UserExamMapper;
import com.yf.exam.modules.user.exam.service.UserExamService;
import org.springframework.stereotype.Service;
import java.util.Date;
/**
* <p>
* UserExamService
* MyBatis-Plus ServiceImpl 使
* </p>
*
* @author
* @since 2020-09-21 15:13
*/
@Service
public class UserExamServiceImpl extends ServiceImpl<UserExamMapper, UserExam> implements UserExamService {
/**
*
* @param reqDTO UserExamReqDTO
* @return UserExamRespDTO IPage
*/
@Override
public IPage<UserExamRespDTO> paging(PagingReqDTO<UserExamReqDTO> reqDTO) {
// 调用 Mapper 层的分页查询方法,将请求的分页信息和查询参数传入
// 并将查询结果转换为包含 UserExamRespDTO 的分页数据
IPage<UserExamRespDTO> pageData = baseMapper.paging(reqDTO.toPage(), reqDTO.getParams());
return pageData;
}
/**
*
* @param reqDTO UserExamReqDTO
* @return UserExamRespDTO IPage
*/
@Override
public IPage<UserExamRespDTO> myPaging(PagingReqDTO<UserExamReqDTO> reqDTO) {
// 获取请求中的查询参数
UserExamReqDTO params = reqDTO.getParams();
// 若查询参数为空,则创建一个新的 UserExamReqDTO 对象
if(params == null){
params = new UserExamReqDTO();
}
// 设置当前用户的 ID 到查询参数中
params.setUserId(UserUtils.getUserId());
// 调用 Mapper 层的分页查询方法,将请求的分页信息和更新后的查询参数传入
// 并将查询结果转换为包含 UserExamRespDTO 的分页数据
IPage<UserExamRespDTO> pageData = baseMapper.paging(reqDTO.toPage(), params);
return pageData;
}
/**
*
* @param userId ID
* @param examId ID
* @param score
* @param passed
*/
@Override
public void joinResult(String userId, String examId, Integer score, boolean passed) {
// 构建查询条件,根据用户 ID 和考试 ID 查询考试记录
QueryWrapper<UserExam> wrapper = new QueryWrapper<>();
wrapper.lambda().eq(UserExam::getUserId, userId)
.eq(UserExam::getExamId, examId);
// 根据查询条件获取一条考试记录
UserExam record = this.getOne(wrapper, false);
if(record == null){
// 若记录不存在,则创建一条新的考试记录
record = new UserExam();
// 设置记录创建时间
record.setCreateTime(new Date());
// 设置记录更新时间
record.setUpdateTime(new Date());
// 设置用户 ID
record.setUserId(userId);
// 设置考试 ID
record.setExamId(examId);
// 设置最高分数为本次考试得分
record.setMaxScore(score);
// 设置是否通过考试
record.setPassed(passed);
// 保存新的考试记录
this.save(record);
return;
}
// 修复低分数不加入统计问题,增加考试次数
record.setTryCount(record.getTryCount() + 1);
// 更新记录更新时间
record.setUpdateTime(new Date());
// 若本次考试得分高于之前的最高分数,则更新最高分数和是否通过考试状态
if(record.getMaxScore() < score){
record.setMaxScore(score);
record.setPassed(passed);
}
// 根据记录 ID 更新考试记录
this.updateById(record);
}
}
Loading…
Cancel
Save