diff --git a/src-源文件/main/java/com/yf/exam/modules/qu/controller/QuController.java b/src-源文件/main/java/com/yf/exam/modules/qu/controller/QuController.java index 07e7d76..99f62b6 100644 --- a/src-源文件/main/java/com/yf/exam/modules/qu/controller/QuController.java +++ b/src-源文件/main/java/com/yf/exam/modules/qu/controller/QuController.java @@ -1,137 +1,129 @@ +// 导入所需的包 package com.yf.exam.modules.qu.controller; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.baomidou.mybatisplus.core.metadata.IPage; -import com.google.common.collect.Lists; -import com.yf.exam.core.api.ApiRest; -import com.yf.exam.core.api.controller.BaseController; -import com.yf.exam.core.api.dto.BaseIdReqDTO; -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.core.exception.ServiceException; -import com.yf.exam.core.utils.BeanMapper; -import com.yf.exam.core.utils.excel.ExportExcel; -import com.yf.exam.core.utils.excel.ImportExcel; -import com.yf.exam.modules.qu.dto.QuDTO; -import com.yf.exam.modules.qu.dto.export.QuExportDTO; -import com.yf.exam.modules.qu.dto.ext.QuDetailDTO; -import com.yf.exam.modules.qu.dto.request.QuQueryReqDTO; -import com.yf.exam.modules.qu.entity.Qu; -import com.yf.exam.modules.qu.service.QuService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import org.apache.commons.lang3.StringUtils; -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; -import org.apache.shiro.authz.annotation.RequiresRoles; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.util.CollectionUtils; -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.RequestParam; -import org.springframework.web.bind.annotation.ResponseBody; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.multipart.MultipartFile; - -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.util.Arrays; -import java.util.List; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; // 用于构建查询条件 +import com.baomidou.mybatisplus.core.metadata.IPage; // 用于分页 +import com.google.common.collect.Lists; // 用于操作列表 +import com.yf.exam.core.api.ApiRest; // API响应封装类 +import com.yf.exam.core.api.controller.BaseController; // 基础控制器类 +import com.yf.exam.core.api.dto.BaseIdReqDTO; // 基础ID请求DTO +import com.yf.exam.core.api.dto.BaseIdRespDTO; // 基础ID响应DTO +import com.yf.exam.core.api.dto.BaseIdsReqDTO; // 基础ID数组请求DTO +import com.yf.exam.core.api.dto.PagingReqDTO; // 分页请求DTO +import com.yf.exam.core.exception.ServiceException; // 自定义服务异常 +import com.yf.exam.core.utils.BeanMapper; // Bean映射工具 +import com.yf.exam.core.utils.excel.ExportExcel; // 导出Excel工具 +import com.yf.exam.core.utils.excel.ImportExcel; // 导入Excel工具 +import com.yf.exam.modules.qu.dto.QuDTO; // 问题DTO +import com.yf.exam.modules.qu.dto.export.QuExportDTO; // 问题导出DTO +import com.yf.exam.modules.qu.dto.ext.QuDetailDTO; // 问题详情DTO +import com.yf.exam.modules.qu.dto.request.QuQueryReqDTO; // 问题查询请求DTO +import com.yf.exam.modules.qu.entity.Qu; // 问题实体类 +import com.yf.exam.modules.qu.service.QuService; // 问题服务类 +import io.swagger.annotations.Api; // Swagger API注释 +import io.swagger.annotations.ApiOperation; // Swagger API操作注释 +import org.apache.commons.lang3.StringUtils; // 字符串操作工具类 +import org.apache.poi.openxml4j.exceptions.InvalidFormatException; // 用于处理Excel格式异常 +import org.apache.shiro.authz.annotation.RequiresRoles; // Shiro权限控制注解 +import org.springframework.beans.factory.annotation.Autowired; // 自动注入依赖 +import org.springframework.util.CollectionUtils; // 集合工具类 +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.RequestParam; // 请求参数注解 +import org.springframework.web.bind.annotation.ResponseBody; // 响应体注解 +import org.springframework.web.bind.annotation.RestController; // REST控制器注解 +import org.springframework.web.multipart.MultipartFile; // 用于处理文件上传 + +import javax.servlet.http.HttpServletResponse; // 用于处理HTTP响应 +import java.io.IOException; // IO异常处理 +import java.util.Arrays; // 数组工具类 +import java.util.List; // 列表工具类 /** *

* 问题题目控制器 *

+* 该控制器类负责管理题目相关的操作,包括添加、修改、删除、查询等 * * @author 聪明笨狗 * @since 2020-05-25 13:25 */ -@Api(tags={"问题题目"}) -@RestController -@RequestMapping("/exam/api/qu/qu") +@Api(tags={"问题题目"}) // Swagger注解,表示该控制器处理"问题题目"相关的请求 +@RestController // Spring注解,表示这是一个RESTful API控制器 +@RequestMapping("/exam/api/qu/qu") // 设置基础路径 public class QuController extends BaseController { @Autowired - private QuService baseService; + private QuService baseService; // 自动注入问题服务类 /** - * 添加或修改 + * 添加或修改问题题目 * - * @param reqDTO - * @return + * @param reqDTO 请求的详细数据,包含问题题目的详细信息 + * @return 返回操作结果 */ - @RequiresRoles("sa") - @ApiOperation(value = "添加或修改") - @RequestMapping(value = "/save", method = {RequestMethod.POST}) + @RequiresRoles("sa") // 限制只有角色为"sa"的用户可以访问此方法 + @ApiOperation(value = "添加或修改") // Swagger注解,描述该方法的功能 + @RequestMapping(value = "/save", method = {RequestMethod.POST}) // POST请求,表示保存操作 public ApiRest save(@RequestBody QuDetailDTO reqDTO) { - baseService.save(reqDTO); - return super.success(); + baseService.save(reqDTO); // 调用服务层保存或更新问题数据 + return super.success(); // 返回成功响应 } /** - * 批量删除 + * 批量删除问题题目 * - * @param reqDTO - * @return + * @param reqDTO 请求的ID数组,包含要删除的题目ID列表 + * @return 返回操作结果 */ - @RequiresRoles("sa") - @ApiOperation(value = "批量删除") - @RequestMapping(value = "/delete", method = {RequestMethod.POST}) + @RequiresRoles("sa") // 限制只有角色为"sa"的用户可以访问此方法 + @ApiOperation(value = "批量删除") // Swagger注解,描述该方法的功能 + @RequestMapping(value = "/delete", method = {RequestMethod.POST}) // POST请求,表示删除操作 public ApiRest edit(@RequestBody BaseIdsReqDTO reqDTO) { - //根据ID删除 - baseService.delete(reqDTO.getIds()); - return super.success(); + baseService.delete(reqDTO.getIds()); // 调用服务层进行批量删除 + return super.success(); // 返回成功响应 } /** - * 查找详情 + * 查找问题题目详情 * - * @param reqDTO - * @return + * @param reqDTO 请求的ID数据,包含要查找的题目ID + * @return 返回问题题目的详细信息 */ - @ApiOperation(value = "查找详情") - @RequestMapping(value = "/detail", method = {RequestMethod.POST}) + @ApiOperation(value = "查找详情") // Swagger注解,描述该方法的功能 + @RequestMapping(value = "/detail", method = {RequestMethod.POST}) // POST请求,表示获取详情操作 public ApiRest detail(@RequestBody BaseIdReqDTO reqDTO) { - QuDetailDTO dto = baseService.detail(reqDTO.getId()); - return super.success(dto); + QuDetailDTO dto = baseService.detail(reqDTO.getId()); // 调用服务层获取问题题目详情 + return super.success(dto); // 返回问题详情 } /** - * 分页查找 + * 分页查询问题题目 * - * @param reqDTO - * @return + * @param reqDTO 分页请求数据,包含查询条件和分页参数 + * @return 返回分页结果 */ - @RequiresRoles("sa") - @ApiOperation(value = "分页查找") - @RequestMapping(value = "/paging", method = {RequestMethod.POST}) + @RequiresRoles("sa") // 限制只有角色为"sa"的用户可以访问此方法 + @ApiOperation(value = "分页查找") // Swagger注解,描述该方法的功能 + @RequestMapping(value = "/paging", method = {RequestMethod.POST}) // POST请求,表示分页查询操作 public ApiRest> paging(@RequestBody PagingReqDTO reqDTO) { - - //分页查询并转换 - IPage page = baseService.paging(reqDTO); - - return super.success(page); + IPage page = baseService.paging(reqDTO); // 调用服务层进行分页查询 + return super.success(page); // 返回分页结果 } - /** - * 导出excel文件 + * 导出问题题目的Excel文件 */ - @RequiresRoles("sa") - @ResponseBody - @RequestMapping(value = "/export") + @RequiresRoles("sa") // 限制只有角色为"sa"的用户可以访问此方法 + @ResponseBody // 标明返回内容直接作为响应体 + @RequestMapping(value = "/export") // 导出请求路径 public ApiRest exportFile(HttpServletResponse response, @RequestBody QuQueryReqDTO reqDTO) { - - - // 导出文件名 - String fileName = "导出的试题-" + System.currentTimeMillis() + ".xlsx"; - + String fileName = "导出的试题-" + System.currentTimeMillis() + ".xlsx"; // 设置导出的文件名 try { - int no = 0; String quId = ""; - List list = baseService.listForExport(reqDTO); + List list = baseService.listForExport(reqDTO); // 获取导出数据 for (QuExportDTO item : list) { if (!quId.equals(item.getQId())) { quId = item.getQId(); @@ -144,135 +136,101 @@ public class QuController extends BaseController { item.setQImage(""); item.setQVideo(""); } - item.setNo(String.valueOf(no)); + item.setNo(String.valueOf(no)); // 设置题目序号 } - new ExportExcel("试题", QuExportDTO.class).setDataList(list).write(response, fileName).dispose(); - return super.success(); + new ExportExcel("试题", QuExportDTO.class).setDataList(list).write(response, fileName).dispose(); // 导出数据到Excel文件 + return super.success(); // 返回成功响应 } catch (Exception e) { - return failure(e.getMessage()); + return failure(e.getMessage()); // 捕获异常并返回失败响应 } } /** - * 导入Excel + * 导入问题题目的Excel文件 * - * @param file - * @return + * @param file 上传的Excel文件 + * @return 返回操作结果 */ - @RequiresRoles("sa") - @ResponseBody - @RequestMapping(value = "/import") + @RequiresRoles("sa") // 限制只有角色为"sa"的用户可以访问此方法 + @ResponseBody // 标明返回内容直接作为响应体 + @RequestMapping(value = "/import") // 导入请求路径 public ApiRest importFile(@RequestParam("file") MultipartFile file) { - try { - - ImportExcel ei = new ImportExcel(file, 1, 0); - List list = ei.getDataList(QuExportDTO.class); - - // 校验数据 - this.checkExcel(list); - - // 导入数据条数 - baseService.importExcel(list); - - // 导入成功 - return super.success(); - - } catch (IOException e) { - - } catch (InvalidFormatException e) { - - } catch (IllegalAccessException e) { - - } catch (InstantiationException e) { - + ImportExcel ei = new ImportExcel(file, 1, 0); // 创建导入Excel对象 + List list = ei.getDataList(QuExportDTO.class); // 获取Excel中的数据列表 + this.checkExcel(list); // 校验数据 + baseService.importExcel(list); // 调用服务层进行导入操作 + return super.success(); // 返回成功响应 + } catch (IOException | InvalidFormatException | IllegalAccessException | InstantiationException e) { + return super.failure(); // 捕获各种异常并返回失败响应 } - - return super.failure(); } /** - * 校验Excel + * 校验Excel文件中的数据 * - * @param list - * @throws Exception + * @param list 导入的题目数据列表 + * @throws ServiceException 可能抛出服务异常 */ private void checkExcel(List list) throws ServiceException { - - // 约定第三行开始导入 + // 校验Excel数据的逻辑,检查每一行数据的有效性 int line = 3; StringBuffer sb = new StringBuffer(); - if (CollectionUtils.isEmpty(list)) { - throw new ServiceException(1, "您导入的数据似乎是一个空表格!"); + throw new ServiceException(1, "您导入的数据似乎是一个空表格!"); // 如果表格为空,抛出异常 } - Integer quNo = null; for (QuExportDTO item : list) { - - System.out.println(item.getNo()); if (StringUtils.isBlank(item.getNo())) { line++; continue; } - - System.out.println(item.getQContent()); Integer no; - try { - no = Integer.parseInt(item.getNo()); + no = Integer.parseInt(item.getNo()); // 转换题目序号 } catch (Exception e) { line++; continue; } - if (no == null) { sb.append("第" + line + "行,题目序号不能为空!
"); } - + // 校验题目内容和其他字段是否为空 if (quNo == null || !quNo.equals(no)) { - if (item.getQuType() == null) { sb.append("第" + line + "行,题目类型不能为空
"); } - if (StringUtils.isBlank(item.getQContent())) { sb.append("第" + line + "行,题目内容不能为空
"); } - if (CollectionUtils.isEmpty(item.getRepoList())) { sb.append("第" + line + "行,题目必须包含一个题库
"); } } - if (StringUtils.isBlank(item.getAIsRight())) { sb.append("第" + line + "行,选项是否正确不能为空
"); } - if (StringUtils.isBlank(item.getAContent()) && StringUtils.isBlank(item.getAImage())) { sb.append("第" + line + "行,选项内容和选项图片必须有一个不为空
"); } - quNo = no; line++; } - - // 存在错误 if (!"".equals(sb.toString())) { - throw new ServiceException(1, sb.toString()); + throw new ServiceException(1, sb.toString()); // 如果有校验错误,抛出异常 } } /** - * 下载导入试题数据模板 + * 下载试题导入模板 */ @ResponseBody - @RequestMapping(value = "import/template") + @RequestMapping(value = "import/template") // 导入模板下载路径 public ApiRest importFileTemplate(HttpServletResponse response) { try { - String fileName = "试题导入模板.xlsx"; - List list = Lists.newArrayList(); - + String fileName = "试题导入模板.xlsx"; // 设置文件名 + List list = Lists.newArrayList(); // 创建模板数据列表 + // 模板数据(包含问题内容、题型、选项等) QuExportDTO l1 = new QuExportDTO(); l1.setNo("正式导入,请删除此说明行:数字,相同的数字表示同一题的序列"); l1.setQContent("问题内容"); @@ -286,39 +244,17 @@ public class QuController extends BaseController { l1.setAIsRight("只能填写0或1,0表示否,1表示是"); l1.setAAnalysis("这个项是正确的"); - - QuExportDTO l2 = new QuExportDTO(); - l2.setQContent("找出以下可以被2整除的数(多选)"); - l2.setQAnalysis("最基本的数学题,不做过多解析"); - l2.setQuType("2"); - l2.setNo("1"); - l2.setAIsRight("1"); - l2.setAContent("数字:2"); - l2.setAAnalysis("2除以2=1,对的"); - - QuExportDTO l3 = new QuExportDTO(); - l3.setNo("1"); - l3.setAIsRight("0"); - l3.setAContent("数字:3"); - l3.setAAnalysis("3除以2=1.5,不能被整除"); - - QuExportDTO l4 = new QuExportDTO(); - l4.setNo("1"); - l4.setAIsRight("1"); - l4.setAContent("数字:6"); - l4.setAAnalysis("6除以2=3,对的"); - - - + // 添加模板示例数据 list.add(l1); list.add(l2); list.add(l3); list.add(l4); + // 导出模板文件 new ExportExcel("试题数据", QuExportDTO.class, 1).setDataList(list).write(response, fileName).dispose(); - return super.success(); + return super.success(); // 返回成功响应 } catch (Exception e) { - return super.failure("导入模板下载失败!失败信息:"+e.getMessage()); + return super.failure("导入模板下载失败!失败信息:"+e.getMessage()); // 返回失败响应 } } } diff --git a/src-源文件/main/java/com/yf/exam/modules/qu/dto/QuAnswerDTO.java b/src-源文件/main/java/com/yf/exam/modules/qu/dto/QuAnswerDTO.java index 3b9c3a1..9a6a160 100644 --- a/src-源文件/main/java/com/yf/exam/modules/qu/dto/QuAnswerDTO.java +++ b/src-源文件/main/java/com/yf/exam/modules/qu/dto/QuAnswerDTO.java @@ -1,42 +1,66 @@ package com.yf.exam.modules.qu.dto; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; +import io.swagger.annotations.ApiModel; // Swagger注解,用于生成API文档 +import io.swagger.annotations.ApiModelProperty; // Swagger注解,用于描述API模型的属性 +import lombok.Data; // Lombok注解,用于自动生成getter、setter等方法 -import java.io.Serializable; +import java.io.Serializable; // 可序列化接口 /** *

* 候选答案请求类 *

* +* 该类用于封装候选答案的请求信息,包含每个答案的具体内容、是否正确、答案分析等信息。 +* * @author 聪明笨狗 * @since 2020-05-25 13:23 */ -@Data +@Data // Lombok注解,自动生成getter、setter等方法 @ApiModel(value="候选答案", description="候选答案") public class QuAnswerDTO implements Serializable { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; // 序列化版本UID + /** + * 答案ID + * 用于唯一标识每个候选答案,通常由数据库自动生成。 + */ + @ApiModelProperty(value = "答案ID", required=true) // Swagger注解,描述字段信息,标明该字段是必填项 + private String id; // 答案ID - @ApiModelProperty(value = "答案ID", required=true) - private String id; + /** + * 题目ID + * 该字段表示该答案对应的题目ID。 + */ + @ApiModelProperty(value = "问题ID", required=true) // Swagger注解,描述字段信息,标明该字段是必填项 + private String quId; // 题目ID - @ApiModelProperty(value = "问题ID", required=true) - private String quId; + /** + * 是否正确 + * 标记该答案是否为正确答案,`true`表示正确,`false`表示错误。 + */ + @ApiModelProperty(value = "是否正确", required=true) // Swagger注解,描述字段信息,标明该字段是必填项 + private Boolean isRight; // 是否正确 - @ApiModelProperty(value = "是否正确", required=true) - private Boolean isRight; + /** + * 选项图片 + * 存储与该答案相关的图片URL,通常用于多媒体题目选项。 + */ + @ApiModelProperty(value = "选项图片", required=true) // Swagger注解,描述字段信息,标明该字段是必填项 + private String image; // 选项图片URL - @ApiModelProperty(value = "选项图片", required=true) - private String image; + /** + * 答案内容 + * 该字段用于存储该答案的文本内容,通常为答案的描述或选项文本。 + */ + @ApiModelProperty(value = "答案内容", required=true) // Swagger注解,描述字段信息,标明该字段是必填项 + private String content; // 答案内容 - @ApiModelProperty(value = "答案内容", required=true) - private String content; - - @ApiModelProperty(value = "答案分析", required=true) - private String analysis; - + /** + * 答案分析 + * 用于对该答案进行详细解析,解释为什么该答案正确或错误。 + */ + @ApiModelProperty(value = "答案分析", required=true) // Swagger注解,描述字段信息,标明该字段是必填项 + private String analysis; // 答案分析 } diff --git a/src-源文件/main/java/com/yf/exam/modules/qu/dto/QuDTO.java b/src-源文件/main/java/com/yf/exam/modules/qu/dto/QuDTO.java index 8f45eec..fe82154 100644 --- a/src-源文件/main/java/com/yf/exam/modules/qu/dto/QuDTO.java +++ b/src-源文件/main/java/com/yf/exam/modules/qu/dto/QuDTO.java @@ -1,53 +1,88 @@ package com.yf.exam.modules.qu.dto; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; +import io.swagger.annotations.ApiModel; // Swagger注解,用于生成API文档 +import io.swagger.annotations.ApiModelProperty; // Swagger注解,用于描述API模型的属性 +import lombok.Data; // Lombok注解,用于自动生成getter、setter等方法 -import java.io.Serializable; -import java.util.Date; +import java.io.Serializable; // 可序列化接口 +import java.util.Date; // 日期类型 /** *

* 问题题目请求类 *

* +* 该类用于封装问题题目的基本信息,包括题目的类型、难度、内容、解析等。 +* * @author 聪明笨狗 * @since 2020-05-25 13:23 */ -@Data +@Data // Lombok注解,自动生成getter、setter等方法 @ApiModel(value="问题题目", description="问题题目") public class QuDTO implements Serializable { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; // 序列化版本UID + /** + * 题目ID + * 每个题目都拥有唯一的ID,用于标识题目。 + */ + @ApiModelProperty(value = "题目ID", required=true) // Swagger注解,描述字段信息,标明该字段是必填项 + private String id; // 题目ID - @ApiModelProperty(value = "题目ID", required=true) - private String id; + /** + * 题目类型 + * 该字段用于标识题目的类型,例如选择题、填空题、判断题等。 + */ + @ApiModelProperty(value = "题目类型", required=true) // Swagger注解,描述字段信息,标明该字段是必填项 + private Integer quType; // 题目类型 - @ApiModelProperty(value = "题目类型", required=true) - private Integer quType; + /** + * 题目难度 + * 用于表示题目的难易程度。1表示普通,2表示较难,可能有更多级别。 + */ + @ApiModelProperty(value = "1普通,2较难", required=true) // Swagger注解,描述字段信息,标明该字段是必填项 + private Integer level; // 题目难度 - @ApiModelProperty(value = "1普通,2较难", required=true) - private Integer level; + /** + * 题目图片 + * 该字段存储与题目相关的图片URL,可以是题目内容的辅助说明。 + */ + @ApiModelProperty(value = "题目图片", required=true) // Swagger注解,描述字段信息,标明该字段是必填项 + private String image; // 题目图片URL - @ApiModelProperty(value = "题目图片", required=true) - private String image; + /** + * 题目内容 + * 存储题目的具体内容,描述问题的文本部分。 + */ + @ApiModelProperty(value = "题目内容", required=true) // Swagger注解,描述字段信息,标明该字段是必填项 + private String content; // 题目内容 - @ApiModelProperty(value = "题目内容", required=true) - private String content; + /** + * 创建时间 + * 标识题目创建的时间,通常由系统自动生成。 + */ + @ApiModelProperty(value = "创建时间", required=true) // Swagger注解,描述字段信息,标明该字段是必填项 + private Date createTime; // 创建时间 + /** + * 更新时间 + * 记录题目最后一次更新时间,通常由系统自动更新。 + */ + @ApiModelProperty(value = "更新时间", required=true) // Swagger注解,描述字段信息,标明该字段是必填项 + private Date updateTime; // 更新时间 - @ApiModelProperty(value = "创建时间", required=true) - private Date createTime; + /** + * 题目备注 + * 可选字段,用于记录关于题目的额外备注信息。 + */ + @ApiModelProperty(value = "题目备注", required=true) // Swagger注解,描述字段信息,标明该字段是必填项 + private String remark; // 题目备注 - @ApiModelProperty(value = "更新时间", required=true) - private Date updateTime; - - @ApiModelProperty(value = "题目备注", required=true) - private String remark; - - @ApiModelProperty(value = "整题解析", required=true) - private String analysis; - + /** + * 整题解析 + * 提供该题目的完整解析,帮助用户理解解题思路及过程。 + */ + @ApiModelProperty(value = "整题解析", required=true) // Swagger注解,描述字段信息,标明该字段是必填项 + private String analysis; // 整题解析 } diff --git a/src-源文件/main/java/com/yf/exam/modules/qu/dto/QuRepoDTO.java b/src-源文件/main/java/com/yf/exam/modules/qu/dto/QuRepoDTO.java index 6e689b8..0fa058e 100644 --- a/src-源文件/main/java/com/yf/exam/modules/qu/dto/QuRepoDTO.java +++ b/src-源文件/main/java/com/yf/exam/modules/qu/dto/QuRepoDTO.java @@ -1,38 +1,58 @@ package com.yf.exam.modules.qu.dto; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; +import io.swagger.annotations.ApiModel; // Swagger注解,用于生成API文档 +import io.swagger.annotations.ApiModelProperty; // Swagger注解,用于描述API模型的属性 +import lombok.Data; // Lombok注解,用于自动生成getter、setter等方法 -import java.io.Serializable; +import java.io.Serializable; // 可序列化接口 /** *

* 试题题库请求类 *

* +* 该类用于封装题库与题目之间的关联信息,包含题目的ID、题库ID、题目类型等信息。 +* * @author 聪明笨狗 * @since 2020-05-25 13:23 */ -@Data +@Data // Lombok注解,自动生成getter、setter等方法 @ApiModel(value="试题题库", description="试题题库") public class QuRepoDTO implements Serializable { - private static final long serialVersionUID = 1L; - - - private String id; - - @ApiModelProperty(value = "试题", required=true) - private String quId; - - @ApiModelProperty(value = "归属题库", required=true) - private String repoId; - - @ApiModelProperty(value = "题目类型", required=true) - private Integer quType; - - @ApiModelProperty(value = "排序", required=true) - private Integer sort; - -} \ No newline at end of file + private static final long serialVersionUID = 1L; // 序列化版本UID + + /** + * 试题ID + * 唯一标识一道试题。 + */ + private String id; // 试题ID + + /** + * 题目ID + * 与题目ID进行关联,表示该试题属于某个具体题目。 + */ + @ApiModelProperty(value = "试题", required=true) // Swagger注解,描述字段信息,标明该字段是必填项 + private String quId; // 题目ID + + /** + * 题库ID + * 标识该题目所属的题库。 + */ + @ApiModelProperty(value = "归属题库", required=true) // Swagger注解,描述字段信息,标明该字段是必填项 + private String repoId; // 题库ID + + /** + * 题目类型 + * 表示该题目在题库中的类型,例如选择题、填空题等。 + */ + @ApiModelProperty(value = "题目类型", required=true) // Swagger注解,描述字段信息,标明该字段是必填项 + private Integer quType; // 题目类型 + + /** + * 排序 + * 表示该题目在题库中的显示顺序,数字越小,顺序越靠前。 + */ + @ApiModelProperty(value = "排序", required=true) // Swagger注解,描述字段信息,标明该字段是必填项 + private Integer sort; // 排序 +} diff --git a/src-源文件/main/java/com/yf/exam/modules/qu/dto/export/QuExportDTO.java b/src-源文件/main/java/com/yf/exam/modules/qu/dto/export/QuExportDTO.java index fe94dac..fff01c5 100644 --- a/src-源文件/main/java/com/yf/exam/modules/qu/dto/export/QuExportDTO.java +++ b/src-源文件/main/java/com/yf/exam/modules/qu/dto/export/QuExportDTO.java @@ -1,45 +1,59 @@ package com.yf.exam.modules.qu.dto.export; -import com.yf.exam.core.utils.excel.annotation.ExcelField; -import com.yf.exam.core.utils.excel.fieldtype.ListType; -import lombok.Data; +import com.yf.exam.core.utils.excel.annotation.ExcelField; // Excel导出注解 +import com.yf.exam.core.utils.excel.fieldtype.ListType; // 用于处理List类型字段的特殊注解 +import lombok.Data; // Lombok注解,用于自动生成getter、setter、toString等方法 -import java.util.List; +import java.util.List; // 用于表示列表类型的字段 /** * 用于导出的数据结构 + * + * 该类是导出试题相关数据时所使用的DTO(数据传输对象),包含了题目序号、题目内容、题目解析、选项内容等信息。 + * 主要用于Excel导出时的数据映射。 + * * @author bool */ -@Data +@Data // Lombok注解,自动生成getter、setter等方法 public class QuExportDTO { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; // 序列化版本UID /** - * + * 题目ID */ - private String qId; - - @ExcelField(title="题目序号", align=2, sort=1) - private String no; - @ExcelField(title="题目类型", align=2, sort=2) - private String quType; - @ExcelField(title="题目内容", align=2, sort=3) - private String qContent; - @ExcelField(title="整体解析", align=2, sort=4) - private String qAnalysis; - @ExcelField(title="题目图片", align=2, sort=5) - private String qImage; - @ExcelField(title="题目视频", align=2, sort=6) - private String qVideo; - @ExcelField(title="所属题库", align=2, sort=7, fieldType = ListType.class) - private List repoList; - @ExcelField(title="是否正确项", align=2, sort=8) - private String aIsRight; - @ExcelField(title="选项内容", align=2, sort=9) - private String aContent; - @ExcelField(title="选项解析", align=2, sort=10) - private String aAnalysis; - @ExcelField(title="选项图片", align=2, sort=11) - private String aImage; + private String qId; // 题目的唯一标识符 + + @ExcelField(title="题目序号", align=2, sort=1) // 导出Excel时的列标题和排序,align为居中对齐,sort为排序位置 + private String no; // 题目序号,表示题目的编号 + + @ExcelField(title="题目类型", align=2, sort=2) // Excel导出列的标题和排序 + private String quType; // 题目类型,可能是单选题、多选题等 + + @ExcelField(title="题目内容", align=2, sort=3) // Excel导出列的标题和排序 + private String qContent; // 题目内容,包含问题的具体描述 + + @ExcelField(title="整体解析", align=2, sort=4) // Excel导出列的标题和排序 + private String qAnalysis; // 整个题目的解析说明 + + @ExcelField(title="题目图片", align=2, sort=5) // Excel导出列的标题和排序 + private String qImage; // 题目图片,存储图片URL或路径 + + @ExcelField(title="题目视频", align=2, sort=6) // Excel导出列的标题和排序 + private String qVideo; // 题目视频,存储视频URL或路径 + + @ExcelField(title="所属题库", align=2, sort=7, fieldType = ListType.class) // 题库列表,支持导出多个题库 + private List repoList; // 题目所属的题库列表 + + @ExcelField(title="是否正确项", align=2, sort=8) // Excel导出列的标题和排序 + private String aIsRight; // 是否为正确选项(0或1) + + @ExcelField(title="选项内容", align=2, sort=9) // Excel导出列的标题和排序 + private String aContent; // 选项内容,表示答案的具体内容 + + @ExcelField(title="选项解析", align=2, sort=10) // Excel导出列的标题和排序 + private String aAnalysis; // 选项解析,说明该选项的正确性或相关分析 + + @ExcelField(title="选项图片", align=2, sort=11) // Excel导出列的标题和排序 + private String aImage; // 选项图片,存储图片URL或路径 } diff --git a/src-源文件/main/java/com/yf/exam/modules/qu/dto/export/QuImportDTO.java b/src-源文件/main/java/com/yf/exam/modules/qu/dto/export/QuImportDTO.java index 4ac03c0..79aa0fe 100644 --- a/src-源文件/main/java/com/yf/exam/modules/qu/dto/export/QuImportDTO.java +++ b/src-源文件/main/java/com/yf/exam/modules/qu/dto/export/QuImportDTO.java @@ -1,23 +1,56 @@ package com.yf.exam.modules.qu.dto.export; -import com.yf.exam.modules.qu.dto.QuAnswerDTO; -import lombok.Data; +import com.yf.exam.modules.qu.dto.QuAnswerDTO; // 导入的选项答案DTO +import lombok.Data; // Lombok注解,用于自动生成getter、setter、toString等方法 -import java.util.List; +import java.util.List; // 用于表示列表类型的字段 /** * 用于导出的数据结构 + * + * 该类用于导入试题数据时的DTO(数据传输对象),包含了题目类型、题目内容、解析、题目图片等信息。 + * 同时还包含了该题目的多个答案选项。 + * * @author bool */ -@Data +@Data // Lombok注解,自动生成getter、setter等方法 public class QuImportDTO { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; // 序列化版本UID - private String quType; - private String qContent; - private String qAnalysis; - private String qImage; - private String repoName; - private List answerList; + /** + * 题目类型 + * 例如:1代表单选题,2代表多选题,3代表判断题,4代表主观题等 + */ + private String quType; // 题目类型,表示题目的类别 + + /** + * 题目内容 + * 例如:问题的具体描述 + */ + private String qContent; // 题目内容,表示题目的实际问题 + + /** + * 题目解析 + * 例如:题目解析或解释说明 + */ + private String qAnalysis; // 题目解析,解释题目的答案或相关说明 + + /** + * 题目图片 + * 例如:题目相关的图片URL + */ + private String qImage; // 题目图片,存储图片URL或路径 + + /** + * 题库名称 + * 例如:题目所属的题库名称 + */ + private String repoName; // 题目所属的题库名称 + + /** + * 答案选项列表 + * 该字段存储了该题目的多个答案选项及其相关信息。 + */ + private List answerList; // 答案选项列表,包含该题目的所有答案选项 } diff --git a/src-源文件/main/java/com/yf/exam/modules/qu/dto/ext/QuDetailDTO.java b/src-源文件/main/java/com/yf/exam/modules/qu/dto/ext/QuDetailDTO.java index b36a4e8..0035a89 100644 --- a/src-源文件/main/java/com/yf/exam/modules/qu/dto/ext/QuDetailDTO.java +++ b/src-源文件/main/java/com/yf/exam/modules/qu/dto/ext/QuDetailDTO.java @@ -1,33 +1,43 @@ package com.yf.exam.modules.qu.dto.ext; -import com.yf.exam.modules.qu.dto.QuAnswerDTO; -import com.yf.exam.modules.qu.dto.QuDTO; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; +import com.yf.exam.modules.qu.dto.QuAnswerDTO; // 引入选项答案DTO +import com.yf.exam.modules.qu.dto.QuDTO; // 引入问题题目DTO +import io.swagger.annotations.ApiModel; // Swagger注解,用于生成API文档 +import io.swagger.annotations.ApiModelProperty; // Swagger注解,用于描述API模型的属性 +import lombok.Data; // Lombok注解,用于自动生成getter、setter等方法 -import java.util.List; +import java.util.List; // 用于表示列表类型的字段 /** *

* 问题题目请求类 *

* +* 该类用于表示问题的详细信息,继承自 `QuDTO`,包括题目的详细信息如备选项、题库列表等。 +* 主要用于在前后端交互时,传递包含问题详细信息的请求或响应数据。 +* * @author 聪明笨狗 * @since 2020-05-25 13:23 */ -@Data +@Data // Lombok注解,自动生成getter、setter等方法 @ApiModel(value="问题题目详情", description="问题题目详情") public class QuDetailDTO extends QuDTO { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; // 序列化版本UID - - @ApiModelProperty(value = "备选项列表", required=true) - private List answerList; - - @ApiModelProperty(value = "题库列表", required=true) - private List repoIds; + /** + * 备选项列表 + * 该字段包含了该题目的所有答案选项列表。 + * 每个选项都包含了选项内容、是否为正确答案、解析等信息。 + */ + @ApiModelProperty(value = "备选项列表", required=true) // Swagger注解,用于生成文档 + private List answerList; // 备选项列表,包含该题目的所有答案选项 - + /** + * 题库列表 + * 该字段包含了该题目所属的多个题库ID。 + * 用于标识该题目属于哪些题库,可能有多个题库关联。 + */ + @ApiModelProperty(value = "题库列表", required=true) // Swagger注解,用于生成文档 + private List repoIds; // 题库列表,存储题库ID的列表 } diff --git a/src-源文件/main/java/com/yf/exam/modules/qu/dto/request/QuQueryReqDTO.java b/src-源文件/main/java/com/yf/exam/modules/qu/dto/request/QuQueryReqDTO.java index a927e9e..989cb8e 100644 --- a/src-源文件/main/java/com/yf/exam/modules/qu/dto/request/QuQueryReqDTO.java +++ b/src-源文件/main/java/com/yf/exam/modules/qu/dto/request/QuQueryReqDTO.java @@ -1,38 +1,54 @@ package com.yf.exam.modules.qu.dto.request; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; +import io.swagger.annotations.ApiModel; // Swagger注解,用于生成API文档 +import io.swagger.annotations.ApiModelProperty; // Swagger注解,用于描述API模型的属性 +import lombok.Data; // Lombok注解,用于自动生成getter、setter等方法 -import java.io.Serializable; -import java.util.List; +import java.io.Serializable; // 可序列化接口 +import java.util.List; // 用于表示列表类型的字段 /** *

* 问题题目请求类 *

* +* 该类用于封装前端请求查询题目的参数。通过该请求类,前端可以传递多个查询条件, +* 如题目类型、题库ID、题目内容等,以便进行题目的筛选和查询。 +* * @author 聪明笨狗 * @since 2020-05-25 13:23 */ -@Data +@Data // Lombok注解,自动生成getter、setter等方法 @ApiModel(value="题目查询请求类", description="题目查询请求类") public class QuQueryReqDTO implements Serializable { - private static final long serialVersionUID = 1L; - - - @ApiModelProperty(value = "题目类型") - private Integer quType; - - @ApiModelProperty(value = "归属题库") - private List repoIds; - - @ApiModelProperty(value = "题目内容") - private String content; - - @ApiModelProperty(value = "排除ID列表") - private List excludes; - - + private static final long serialVersionUID = 1L; // 序列化版本UID + + /** + * 题目类型 + * 用于指定查询的题目类型。例如,单选题、多选题、判断题等。 + */ + @ApiModelProperty(value = "题目类型") // Swagger注解,描述字段信息 + private Integer quType; // 题目类型,通常是数字表示不同题型 + + /** + * 归属题库 + * 用于指定题目所属的题库ID列表。如果该字段不为空,查询会限制在指定的题库中。 + */ + @ApiModelProperty(value = "归属题库") // Swagger注解,描述字段信息 + private List repoIds; // 题库ID列表,题目可以归属于多个题库 + + /** + * 题目内容 + * 用于进行模糊查询,匹配包含特定内容的题目。 + */ + @ApiModelProperty(value = "题目内容") // Swagger注解,描述字段信息 + private String content; // 题目内容,支持模糊查询 + + /** + * 排除ID列表 + * 用于指定在查询中排除的题目ID列表,这些ID的题目不会出现在查询结果中。 + */ + @ApiModelProperty(value = "排除ID列表") // Swagger注解,描述字段信息 + private List excludes; // 排除的题目ID列表 } diff --git a/src-源文件/main/java/com/yf/exam/modules/qu/dto/request/QuRepoBatchReqDTO.java b/src-源文件/main/java/com/yf/exam/modules/qu/dto/request/QuRepoBatchReqDTO.java index 3ca148d..0628495 100644 --- a/src-源文件/main/java/com/yf/exam/modules/qu/dto/request/QuRepoBatchReqDTO.java +++ b/src-源文件/main/java/com/yf/exam/modules/qu/dto/request/QuRepoBatchReqDTO.java @@ -1,34 +1,47 @@ package com.yf.exam.modules.qu.dto.request; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; +import io.swagger.annotations.ApiModel; // Swagger注解,用于生成API文档 +import io.swagger.annotations.ApiModelProperty; // Swagger注解,用于描述API模型的属性 +import lombok.Data; // Lombok注解,用于自动生成getter、setter等方法 -import java.io.Serializable; -import java.util.List; +import java.io.Serializable; // 可序列化接口 +import java.util.List; // 用于表示列表类型的字段 /** *

-* 问题题目请求类 +* 试题题库批量操作请求类 *

* +* 该类用于封装前端请求批量操作题目和题库关联的参数。 +* 通过该请求类,前端可以执行批量新增或移除题目与题库的关联操作。 +* * @author 聪明笨狗 * @since 2020-05-25 13:23 */ -@Data +@Data // Lombok注解,自动生成getter、setter等方法 @ApiModel(value="试题题库批量操作类", description="试题题库批量操作类") public class QuRepoBatchReqDTO implements Serializable { - private static final long serialVersionUID = 1L; - - - @ApiModelProperty(value = "题目ID", required=true) - private List quIds; - - @ApiModelProperty(value = "题目类型", required=true) - private List repoIds; - - @ApiModelProperty(value = "是否移除,否就新增;是就移除", required=true) - private Boolean remove; - + private static final long serialVersionUID = 1L; // 序列化版本UID + + /** + * 题目ID列表 + * 用于指定要操作的题目ID集合,可以是多个题目。 + */ + @ApiModelProperty(value = "题目ID", required=true) // Swagger注解,描述字段信息,标明该字段是必填项 + private List quIds; // 要操作的题目ID列表 + + /** + * 题库ID列表 + * 用于指定题目与之关联的题库ID集合,可以是多个题库。 + */ + @ApiModelProperty(value = "题目类型", required=true) // Swagger注解,描述字段信息,标明该字段是必填项 + private List repoIds; // 题库ID列表 + + /** + * 是否移除标志 + * 如果为 `true`,表示从题库中移除题目;如果为 `false`,表示新增题目到题库中。 + */ + @ApiModelProperty(value = "是否移除,否就新增;是就移除", required=true) // Swagger注解,描述字段信息,标明该字段是必填项 + private Boolean remove; // `true`表示移除,`false`表示新增 } diff --git a/src-源文件/main/java/com/yf/exam/modules/qu/entity/Qu.java b/src-源文件/main/java/com/yf/exam/modules/qu/entity/Qu.java index 2380cdc..ccb4579 100644 --- a/src-源文件/main/java/com/yf/exam/modules/qu/entity/Qu.java +++ b/src-源文件/main/java/com/yf/exam/modules/qu/entity/Qu.java @@ -1,75 +1,85 @@ package com.yf.exam.modules.qu.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 com.baomidou.mybatisplus.annotation.IdType; // MyBatis Plus注解,指定ID生成策略 +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; // MyBatis Plus扩展的活动记录模式类 +import lombok.Data; // Lombok注解,用于自动生成getter、setter等方法 -import java.util.Date; +import java.util.Date; // 日期类型 /** *

* 问题题目实体类 *

* +* 该类用于映射问题题目的数据结构,通过MyBatis-Plus框架进行数据库操作。 +* * @author 聪明笨狗 * @since 2020-05-25 13:23 */ -@Data -@TableName("el_qu") +@Data // Lombok注解,自动生成getter、setter等方法 +@TableName("el_qu") // MyBatis Plus注解,指定与数据库表的映射关系 public class Qu extends Model { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; // 序列化版本UID /** * 题目ID + * 主键,唯一标识一道题目。 */ - @TableId(value = "id", type = IdType.ASSIGN_ID) - private String id; + @TableId(value = "id", type = IdType.ASSIGN_ID) // MyBatis Plus注解,指定主键生成策略为自定义ID + private String id; // 题目ID /** * 题目类型 + * 表示该题目是选择题、判断题等类型。 */ - @TableField("qu_type") - private Integer quType; + @TableField("qu_type") // MyBatis Plus注解,指定字段名与数据库表字段名映射 + private Integer quType; // 题目类型 /** - * 1普通,2较难 + * 题目难度 + * 1表示普通,2表示较难。 */ - private Integer level; + private Integer level; // 题目难度,1普通,2较难 /** * 题目图片 + * 题目相关的图片资源,存储图片URL或路径。 */ - private String image; + private String image; // 题目图片 /** * 题目内容 + * 存储题目的实际内容,例如选择题或填空题的文本。 */ - private String content; + private String content; // 题目内容 /** * 创建时间 + * 记录该题目创建的时间戳。 */ - @TableField("create_time") - private Date createTime; + @TableField("create_time") // MyBatis Plus注解,映射数据库中的字段 + private Date createTime; // 创建时间 /** * 更新时间 + * 记录该题目最后更新时间戳。 */ - @TableField("update_time") - private Date updateTime; + @TableField("update_time") // MyBatis Plus注解,映射数据库中的字段 + private Date updateTime; // 更新时间 /** * 题目备注 + * 对题目附加的说明或备注。 */ - private String remark; + private String remark; // 题目备注 /** * 整题解析 + * 对该题目的详细解析,包括答案解析、解题思路等。 */ - private String analysis; - + private String analysis; // 整题解析 } diff --git a/src-源文件/main/java/com/yf/exam/modules/qu/entity/QuAnswer.java b/src-源文件/main/java/com/yf/exam/modules/qu/entity/QuAnswer.java index 45e9bf4..6c01005 100644 --- a/src-源文件/main/java/com/yf/exam/modules/qu/entity/QuAnswer.java +++ b/src-源文件/main/java/com/yf/exam/modules/qu/entity/QuAnswer.java @@ -1,58 +1,64 @@ package com.yf.exam.modules.qu.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 com.baomidou.mybatisplus.annotation.IdType; // MyBatis Plus注解,指定ID生成策略 +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; // MyBatis Plus扩展的活动记录模式类 +import lombok.Data; // Lombok注解,用于自动生成getter、setter等方法 /** *

* 候选答案实体类 *

* +* 该类用于映射候选答案的数据结构,通过MyBatis-Plus框架进行数据库操作。 +* * @author 聪明笨狗 * @since 2020-05-25 13:23 */ -@Data -@TableName("el_qu_answer") +@Data // Lombok注解,自动生成getter、setter等方法 +@TableName("el_qu_answer") // MyBatis Plus注解,指定与数据库表的映射关系 public class QuAnswer extends Model { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; // 序列化版本UID /** * 答案ID + * 主键,唯一标识一个答案。 */ - @TableId(value = "id", type = IdType.ASSIGN_ID) - private String id; + @TableId(value = "id", type = IdType.ASSIGN_ID) // MyBatis Plus注解,指定主键生成策略为自定义ID + private String id; // 答案ID /** * 问题ID + * 关联的题目ID,表示这个答案是属于哪道题目的。 */ - @TableField("qu_id") - private String quId; + @TableField("qu_id") // MyBatis Plus注解,指定字段名与数据库表字段名映射 + private String quId; // 问题ID /** * 是否正确 + * 该答案是否为正确答案,true表示正确,false表示错误。 */ - @TableField("is_right") - private Boolean isRight; + @TableField("is_right") // MyBatis Plus注解,映射数据库中的字段 + private Boolean isRight; // 是否正确 /** * 选项图片 + * 答案相关的图片资源,存储图片URL或路径。 */ - private String image; + private String image; // 选项图片 /** * 答案内容 + * 存储该选项的文本内容。 */ - private String content; - + private String content; // 答案内容 /** * 答案分析 + * 对该答案的详细分析,包括为什么是正确或错误的解析。 */ - private String analysis; - + private String analysis; // 答案分析 } diff --git a/src-源文件/main/java/com/yf/exam/modules/qu/entity/QuRepo.java b/src-源文件/main/java/com/yf/exam/modules/qu/entity/QuRepo.java index baade9a..aa26d34 100644 --- a/src-源文件/main/java/com/yf/exam/modules/qu/entity/QuRepo.java +++ b/src-源文件/main/java/com/yf/exam/modules/qu/entity/QuRepo.java @@ -1,50 +1,59 @@ package com.yf.exam.modules.qu.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 com.baomidou.mybatisplus.annotation.IdType; // MyBatis Plus注解,指定ID生成策略 +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; // MyBatis Plus扩展的活动记录模式类 +import lombok.Data; // Lombok注解,用于自动生成getter、setter等方法 /** *

* 试题题库实体类 *

* +* 该类用于映射试题和题库之间的关系,表示一道题目属于某个题库,并可能具有排序。 +* * @author 聪明笨狗 * @since 2020-05-25 13:23 */ -@Data -@TableName("el_qu_repo") +@Data // Lombok注解,自动生成getter、setter等方法 +@TableName("el_qu_repo") // MyBatis Plus注解,指定与数据库表的映射关系 public class QuRepo extends Model { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; // 序列化版本UID - @TableId(value = "id", type = IdType.ASSIGN_ID) - private String id; + /** + * 试题题库关系ID + * 主键,唯一标识一条题目与题库的关联记录。 + */ + @TableId(value = "id", type = IdType.ASSIGN_ID) // MyBatis Plus注解,指定主键生成策略为自定义ID + private String id; // 试题题库关系ID /** - * 试题 + * 试题ID + * 关联的题目ID,表示某道题目属于哪个题库。 */ - @TableField("qu_id") - private String quId; + @TableField("qu_id") // MyBatis Plus注解,指定字段名与数据库表字段名映射 + private String quId; // 试题ID /** - * 归属题库 + * 题库ID + * 关联的题库ID,表示该题目属于哪个题库。 */ - @TableField("repo_id") - private String repoId; + @TableField("repo_id") // MyBatis Plus注解,指定字段名与数据库表字段名映射 + private String repoId; // 题库ID /** * 题目类型 + * 用于描述该题目所属的类型(例如:选择题、填空题等)。 */ - @TableField("qu_type") - private Integer quType; + @TableField("qu_type") // MyBatis Plus注解,映射数据库中的字段 + private Integer quType; // 题目类型 /** * 排序 + * 用于对题库中的题目进行排序。 */ - private Integer sort; - + private Integer sort; // 排序 } diff --git a/src-源文件/main/java/com/yf/exam/modules/qu/enums/QuType.java b/src-源文件/main/java/com/yf/exam/modules/qu/enums/QuType.java index 70e2ee1..4e5f342 100644 --- a/src-源文件/main/java/com/yf/exam/modules/qu/enums/QuType.java +++ b/src-源文件/main/java/com/yf/exam/modules/qu/enums/QuType.java @@ -1,8 +1,10 @@ package com.yf.exam.modules.qu.enums; - /** - * 题目类型 + * 题目类型接口 + * + * 该接口定义了不同类型的题目标识常量,适用于题库系统中对题目类型的区分。 + * * @author bool * @date 2019-10-30 13:11 */ @@ -10,16 +12,19 @@ public interface QuType { /** * 单选题 + * 表示一道题目是单选题,用户只能选择一个答案。 */ Integer RADIO = 1; /** * 多选题 + * 表示一道题目是多选题,用户可以选择多个答案。 */ Integer MULTI = 2; /** * 判断题 + * 表示一道题目是判断题,通常是选择“正确”或“错误”两种答案。 */ Integer JUDGE = 3; diff --git a/src-源文件/main/java/com/yf/exam/modules/qu/mapper/QuAnswerMapper.java b/src-源文件/main/java/com/yf/exam/modules/qu/mapper/QuAnswerMapper.java index 23699ce..5fb575e 100644 --- a/src-源文件/main/java/com/yf/exam/modules/qu/mapper/QuAnswerMapper.java +++ b/src-源文件/main/java/com/yf/exam/modules/qu/mapper/QuAnswerMapper.java @@ -4,13 +4,13 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.yf.exam.modules.qu.entity.QuAnswer; /** -*

-* 候选答案Mapper -*

-* -* @author 聪明笨狗 -* @since 2020-05-25 13:23 -*/ + *

+ * 候选答案Mapper + *

+ * + * @author 聪明笨狗 + * @since 2020-05-25 13:23 + */ public interface QuAnswerMapper extends BaseMapper { } diff --git a/src-源文件/main/java/com/yf/exam/modules/qu/mapper/QuMapper.java b/src-源文件/main/java/com/yf/exam/modules/qu/mapper/QuMapper.java index 14069a2..2ab579e 100644 --- a/src-源文件/main/java/com/yf/exam/modules/qu/mapper/QuMapper.java +++ b/src-源文件/main/java/com/yf/exam/modules/qu/mapper/QuMapper.java @@ -1,15 +1,15 @@ -package com.yf.exam.modules.qu.mapper; +package com.yf.exam.modules.qu.mapper; // 定义包名,用于存放与问题题目相关的 Mapper 类 -import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import com.baomidou.mybatisplus.core.metadata.IPage; -import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.yf.exam.modules.qu.dto.QuDTO; -import com.yf.exam.modules.qu.dto.export.QuExportDTO; -import com.yf.exam.modules.qu.dto.request.QuQueryReqDTO; -import com.yf.exam.modules.qu.entity.Qu; -import org.apache.ibatis.annotations.Param; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; // 导入 MyBatis-Plus 的 BaseMapper,用于提供通用的 CRUD 方法 +import com.baomidou.mybatisplus.core.metadata.IPage; // 导入分页接口 IPage,用于处理分页结果 +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; // 导入分页插件的 Page 类,用于分页查询 +import com.yf.exam.modules.qu.dto.QuDTO; // 导入 QuDTO 数据传输对象,用于封装题目数据 +import com.yf.exam.modules.qu.dto.export.QuExportDTO; // 导入 QuExportDTO 用于题目导出的数据结构 +import com.yf.exam.modules.qu.dto.request.QuQueryReqDTO; // 导入 QuQueryReqDTO 用于封装查询条件 +import com.yf.exam.modules.qu.entity.Qu; // 导入 Qu 实体类,表示题目表的对应数据 +import org.apache.ibatis.annotations.Param; // 导入 MyBatis 的 Param 注解,用于 SQL 查询中的参数传递 -import java.util.List; +import java.util.List; // 导入 List,用于返回多个对象的集合 /** *

@@ -19,38 +19,34 @@ import java.util.List; * @author 聪明笨狗 * @since 2020-05-25 13:23 */ -public interface QuMapper extends BaseMapper { - - +public interface QuMapper extends BaseMapper { // QuMapper 继承自 BaseMapper,提供基本的 CRUD 操作 /** * 随机抽取题库的数据 - * @param repoId - * @param quType - * @param level + * @param repoId 题库ID + * @param quType 题目类型 + * @param level 题目难度 * @param excludes 要排除的ID列表 - * @param size - * @return + * @param size 抽取题目的数量 + * @return 随机抽取的题目列表 */ - List listByRandom(@Param("repoId") String repoId, - @Param("quType") Integer quType, - @Param("excludes") List excludes, - @Param("size") Integer size); + List listByRandom(@Param("repoId") String repoId, // 题库ID + @Param("quType") Integer quType, // 题目类型 + @Param("excludes") List excludes, // 要排除的题目ID列表 + @Param("size") Integer size); // 抽取的题目数量 /** * 查找导出列表 - * @param query - * @return + * @param query 查询条件对象 + * @return 返回符合条件的题目列表,用于导出 */ - List listForExport(@Param("query") QuQueryReqDTO query); + List listForExport(@Param("query") QuQueryReqDTO query); // 根据查询条件查找导出数据 /** * 分页查找 - * @param page - * @param query - * @return + * @param page 分页参数,包含当前页和每页大小 + * @param query 查询条件对象 + * @return 返回分页的题目数据 */ - IPage paging(Page page, @Param("query") QuQueryReqDTO query); - - + IPage paging(Page page, @Param("query") QuQueryReqDTO query); // 分页查询题目数据,返回 QuDTO 类型的数据 } diff --git a/src-源文件/main/java/com/yf/exam/modules/qu/mapper/QuRepoMapper.java b/src-源文件/main/java/com/yf/exam/modules/qu/mapper/QuRepoMapper.java index 1015448..84fa2cb 100644 --- a/src-源文件/main/java/com/yf/exam/modules/qu/mapper/QuRepoMapper.java +++ b/src-源文件/main/java/com/yf/exam/modules/qu/mapper/QuRepoMapper.java @@ -1,7 +1,7 @@ -package com.yf.exam.modules.qu.mapper; +package com.yf.exam.modules.qu.mapper; // 定义包名,用于存放与试题题库相关的 Mapper 类 -import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import com.yf.exam.modules.qu.entity.QuRepo; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; // 导入 MyBatis-Plus 的 BaseMapper,用于提供通用的 CRUD 方法 +import com.yf.exam.modules.qu.entity.QuRepo; // 导入 QuRepo 实体类,表示试题题库表的数据 /** *

@@ -11,6 +11,5 @@ import com.yf.exam.modules.qu.entity.QuRepo; * @author 聪明笨狗 * @since 2020-05-25 13:23 */ -public interface QuRepoMapper extends BaseMapper { - +public interface QuRepoMapper extends BaseMapper { // QuRepoMapper 继承自 BaseMapper,提供基本的 CRUD 操作 } diff --git a/src-源文件/main/java/com/yf/exam/modules/qu/service/QuAnswerService.java b/src-源文件/main/java/com/yf/exam/modules/qu/service/QuAnswerService.java index 4062e95..f6329f5 100644 --- a/src-源文件/main/java/com/yf/exam/modules/qu/service/QuAnswerService.java +++ b/src-源文件/main/java/com/yf/exam/modules/qu/service/QuAnswerService.java @@ -10,7 +10,7 @@ import java.util.List; /** *

-* 候选答案业务类 +* 候选答案业务类接口,定义了与试题答案相关的业务操作 *

* * @author 聪明笨狗 @@ -19,30 +19,30 @@ import java.util.List; public interface QuAnswerService extends IService { /** - * 分页查询数据 - * @param reqDTO - * @return + * 分页查询答案数据 + * @param reqDTO 请求的分页和查询参数 + * @return 分页的答案数据 */ IPage paging(PagingReqDTO reqDTO); /** - * 根据题目ID查询答案并随机 - * @param quId - * @return + * 根据题目ID查询答案,并进行随机排序 + * @param quId 题目ID + * @return 随机排序后的答案列表 */ List listAnswerByRandom(String quId); /** - * 根据问题查找答案 - * @param quId - * @return + * 根据题目ID查询所有的答案 + * @param quId 题目ID + * @return 该题目的答案列表 */ List listByQu(String quId); /** - * 保存试题 - * @param quId - * @param list + * 保存所有选项数据 + * @param quId 题目ID + * @param list 题目的所有答案选项 */ void saveAll(String quId, List list); } diff --git a/src-源文件/main/java/com/yf/exam/modules/qu/service/QuRepoService.java b/src-源文件/main/java/com/yf/exam/modules/qu/service/QuRepoService.java index f528759..a53ebb1 100644 --- a/src-源文件/main/java/com/yf/exam/modules/qu/service/QuRepoService.java +++ b/src-源文件/main/java/com/yf/exam/modules/qu/service/QuRepoService.java @@ -1,59 +1,66 @@ +// 定义包名,表示该接口属于com.yf.exam.modules.qu.service包下 package com.yf.exam.modules.qu.service; +// 导入MyBatis Plus框架的分页功能相关类 import com.baomidou.mybatisplus.core.metadata.IPage; +// 导入MyBatis Plus框架的服务接口 import com.baomidou.mybatisplus.extension.service.IService; +// 导入项目中定义的分页请求DTO类 import com.yf.exam.core.api.dto.PagingReqDTO; +// 导入项目中定义的题库DTO类 import com.yf.exam.modules.qu.dto.QuRepoDTO; +// 导入项目中定义的批量请求DTO类 import com.yf.exam.modules.qu.dto.request.QuRepoBatchReqDTO; +// 导入项目中定义的题库实体类 import com.yf.exam.modules.qu.entity.QuRepo; - +// 导入Java.util包下的List接口,用于操作列表 import java.util.List; /** -*

-* 试题题库业务类 -*

-* -* @author 聪明笨狗 -* @since 2020-05-25 13:23 -*/ + *

+ * 试题题库业务接口,定义了题库相关的业务操作 + *

+ * + * @author 聪明笨狗 + * @since 2020-05-25 13:23 + */ public interface QuRepoService extends IService { /** - * 分页查询数据 - * @param reqDTO - * @return - */ + * 分页查询题库数据的方法 + * @param reqDTO 分页请求DTO,包含分页信息和查询条件 + * @return 返回分页响应,包含题库数据和分页信息 + */ IPage paging(PagingReqDTO reqDTO); /** - * 保存全部列表 - * @param quId - * @param quType - * @param ids + * 保存全部列表的方法,用于保存题目与题库的关系 + * @param quId 题目ID + * @param quType 题目类型 + * @param ids 题库ID列表 */ void saveAll(String quId, Integer quType, List ids); /** - * 根据问题查找题库 - * @param quId - * @return + * 根据题目查找题库的方法 + * @param quId 题目ID + * @return 返回与题目关联的题库ID列表 */ List listByQu(String quId); /** - * 根据题库查找题目ID列表 - * @param repoId - * @param quType - * @param rand - * @return + * 根据题库查找题目ID列表的方法 + * @param repoId 题库ID + * @param quType 题目类型 + * @param rand 是否随机选择 + * @return 返回题目ID列表 */ List listByRepo(String repoId, Integer quType, boolean rand); /** - * 批量操作 - * @param reqDTO + * 批量操作的方法,用于执行批量业务操作 + * @param reqDTO 批量请求DTO,包含批量操作信息 */ void batchAction(QuRepoBatchReqDTO reqDTO); -} +} \ No newline at end of file diff --git a/src-源文件/main/java/com/yf/exam/modules/qu/service/QuService.java b/src-源文件/main/java/com/yf/exam/modules/qu/service/QuService.java index 81f43b0..51fe835 100644 --- a/src-源文件/main/java/com/yf/exam/modules/qu/service/QuService.java +++ b/src-源文件/main/java/com/yf/exam/modules/qu/service/QuService.java @@ -1,46 +1,55 @@ +// 定义包名,表示该接口属于com.yf.exam.modules.qu.service包下 package com.yf.exam.modules.qu.service; +// 导入MyBatis Plus框架的分页功能相关类 import com.baomidou.mybatisplus.core.metadata.IPage; +// 导入MyBatis Plus框架的服务接口 import com.baomidou.mybatisplus.extension.service.IService; +// 导入项目中定义的分页请求DTO类 import com.yf.exam.core.api.dto.PagingReqDTO; +// 导入项目中定义的题目DTO类 import com.yf.exam.modules.qu.dto.QuDTO; +// 导入项目中定义的题目导出DTO类 import com.yf.exam.modules.qu.dto.export.QuExportDTO; +// 导入项目中定义的扩展题目详情DTO类 import com.yf.exam.modules.qu.dto.ext.QuDetailDTO; +// 导入项目中定义的题目查询请求DTO类 import com.yf.exam.modules.qu.dto.request.QuQueryReqDTO; +// 导入项目中定义的题目实体类 import com.yf.exam.modules.qu.entity.Qu; - +// 导入Java.util包下的List接口,用于操作列表 import java.util.List; /** -*

-* 问题题目业务类 -*

-* -* @author 聪明笨狗 -* @since 2020-05-25 13:23 -*/ + *

+ * 问题题目业务接口,定义了题目相关的业务操作 + *

+ * + * @author 聪明笨狗 + * @since 2020-05-25 13:23 + */ public interface QuService extends IService { /** - * 分页查询数据 - * @param reqDTO - * @return + * 分页查询题目数据的方法 + * @param reqDTO 分页请求DTO,包含分页信息和查询条件 + * @return 返回分页响应,包含题目数据和分页信息 */ IPage paging(PagingReqDTO reqDTO); /** - * 删除试题 - * @param ids + * 删除题目的方法 + * @param ids 题目ID列表 */ void delete(List ids); /** - * 随机抽取题库的数据 - * @param repoId - * @param quType + * 随机抽取题库中的数据的方法 + * @param repoId 题库ID + * @param quType 题目类型 * @param excludes 要排除的ID列表 - * @param size - * @return + * @param size 抽取的数量 + * @return 返回随机抽取的题目列表 */ List listByRandom(String repoId, Integer quType, @@ -48,29 +57,29 @@ public interface QuService extends IService { Integer size); /** - * 问题详情 - * @param id - * @return + * 查询题目详情的方法 + * @param id 题目ID + * @return 返回题目详情DTO */ QuDetailDTO detail(String id); /** - * 保存试题 - * @param reqDTO + * 保存题目的方法 + * @param reqDTO 题目详情DTO */ void save(QuDetailDTO reqDTO); /** - * 查找导出列表 - * @param query - * @return + * 查找导出列表的方法 + * @param query 题目查询请求DTO + * @return 返回题目导出列表 */ List listForExport(QuQueryReqDTO query); /** - * 导入Excel - * @param dtoList - * @return + * 导入Excel数据的方法 + * @param dtoList 题目导出DTO列表 + * @return 返回导入的结果,影响的行数 */ int importExcel(List dtoList); -} +} \ No newline at end of file diff --git a/src-源文件/main/java/com/yf/exam/modules/qu/service/impl/QuAnswerServiceImpl.java b/src-源文件/main/java/com/yf/exam/modules/qu/service/impl/QuAnswerServiceImpl.java index 2fd66cf..1c31577 100644 --- a/src-源文件/main/java/com/yf/exam/modules/qu/service/impl/QuAnswerServiceImpl.java +++ b/src-源文件/main/java/com/yf/exam/modules/qu/service/impl/QuAnswerServiceImpl.java @@ -1,24 +1,24 @@ -package com.yf.exam.modules.qu.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.core.utils.BeanMapper; -import com.yf.exam.modules.qu.dto.QuAnswerDTO; -import com.yf.exam.modules.qu.entity.QuAnswer; -import com.yf.exam.modules.qu.mapper.QuAnswerMapper; -import com.yf.exam.modules.qu.service.QuAnswerService; -import com.yf.exam.modules.qu.utils.ImageCheckUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.util.CollectionUtils; - -import java.util.ArrayList; -import java.util.List; +package com.yf.exam.modules.qu.service.impl; // 定义包名,表示这是实现类部分,专注于处理与试题答案相关的逻辑 + +import com.alibaba.fastjson.JSON; // 导入 fastjson 库,用于 JSON 序列化和反序列化 +import com.alibaba.fastjson.TypeReference; // 导入 fastjson 库的 TypeReference,用于处理泛型类型 +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; // 导入 MyBatis-Plus 的 QueryWrapper,用于构造查询条件 +import com.baomidou.mybatisplus.core.metadata.IPage; // 导入 MyBatis-Plus 的 IPage 接口,用于分页查询 +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; // 导入 MyBatis-Plus 的分页 Page 类 +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; // 导入 MyBatis-Plus 的 ServiceImpl 基类 +import com.yf.exam.core.api.dto.PagingReqDTO; // 导入分页请求数据传输对象类 +import com.yf.exam.core.utils.BeanMapper; // 导入 BeanMapper 工具类,用于对象之间的映射 +import com.yf.exam.modules.qu.dto.QuAnswerDTO; // 导入试题答案的 DTO 类 +import com.yf.exam.modules.qu.entity.QuAnswer; // 导入试题答案的实体类 +import com.yf.exam.modules.qu.mapper.QuAnswerMapper; // 导入试题答案的 Mapper 接口 +import com.yf.exam.modules.qu.service.QuAnswerService; // 导入试题答案的服务接口 +import com.yf.exam.modules.qu.utils.ImageCheckUtils; // 导入图片校验工具类 +import org.springframework.beans.factory.annotation.Autowired; // 导入 Spring 的注解,自动注入依赖 +import org.springframework.stereotype.Service; // 导入 Spring 的服务注解,标识这是一个服务类 +import org.springframework.util.CollectionUtils; // 导入 Spring 的集合工具类,用于检查集合是否为空 + +import java.util.ArrayList; // 导入 ArrayList,用于动态数组 +import java.util.List; // 导入 List 接口,作为列表类型 /** *

@@ -28,65 +28,77 @@ import java.util.List; * @author 聪明笨狗 * @since 2020-05-25 13:23 */ -@Service +@Service // 表示这是一个服务类,Spring 会自动扫描并管理该类 public class QuAnswerServiceImpl extends ServiceImpl implements QuAnswerService { @Autowired - private ImageCheckUtils imageCheckUtils; + private ImageCheckUtils imageCheckUtils; // 自动注入图片校验工具类,用于校验图片地址是否合法 @Override public IPage paging(PagingReqDTO reqDTO) { - - //创建分页对象 + // 创建分页对象,传入当前页和每页大小 IPage query = new Page<>(reqDTO.getCurrent(), reqDTO.getSize()); - //查询条件 + // 创建查询条件包装器 QueryWrapper wrapper = new QueryWrapper<>(); - //获得数据 + // 执行分页查询,获取分页结果 IPage page = this.page(query, wrapper); - //转换结果 + + // 将查询结果转换为 QuAnswerDTO 类型的分页结果 IPage pageData = JSON.parseObject(JSON.toJSONString(page), new TypeReference>(){}); return pageData; - } + } @Override public List listAnswerByRandom(String quId) { + // 创建查询条件包装器 QueryWrapper wrapper = new QueryWrapper<>(); + // 设置查询条件,过滤出与 quId 相同的记录 wrapper.lambda().eq(QuAnswer::getQuId, quId); + // 使用 SQL 的随机排序来随机获取答案 wrapper.last(" ORDER BY RAND() "); + // 执行查询并返回结果 return this.list(wrapper); } @Override public List listByQu(String quId) { + // 创建查询条件包装器 QueryWrapper wrapper = new QueryWrapper<>(); + // 设置查询条件,过滤出与 quId 相同的记录 wrapper.lambda().eq(QuAnswer::getQuId, quId); + // 执行查询,获取答案列表 List list = this.list(wrapper); if(!CollectionUtils.isEmpty(list)){ + // 将 QuAnswer 实体对象列表转换为 QuAnswerDTO 对象列表 return BeanMapper.mapList(list, QuAnswerDTO.class); } + // 如果没有找到记录,返回 null return null; } - /** * 查找已存在的列表 - * @param quId - * @return + * @param quId 试题ID + * @return 已存在答案的 ID 列表 */ public List findExistsList(String quId) { - //返回结果 + // 创建空的结果列表 List ids = new ArrayList<>(); + // 创建查询条件包装器 QueryWrapper wrapper = new QueryWrapper(); + // 设置查询条件,过滤出与 quId 相同的记录 wrapper.lambda().eq(QuAnswer::getQuId, quId); + // 执行查询,获取答案列表 List list = this.list(wrapper); if (!CollectionUtils.isEmpty(list)) { + // 将已有的答案 ID 添加到结果列表 for (QuAnswer item : list) { ids.add(item.getId()); } @@ -96,49 +108,49 @@ public class QuAnswerServiceImpl extends ServiceImpl i @Override public void saveAll(String quId, List list) { - - //最终要保存的列表 + // 创建保存的答案列表 List saveList = new ArrayList<>(); - //已存在的标签列表 + // 获取已有的答案 ID 列表 List ids = this.findExistsList(quId); + // 如果答案列表不为空,则进行处理 if(!CollectionUtils.isEmpty(list)){ for(QuAnswerDTO item: list){ - // 校验图片地址 + // 校验选项图片地址是否合法 imageCheckUtils.checkImage(item.getImage(), "选项图片地址错误!"); - //标签ID + // 获取答案 ID String id = item.getId(); QuAnswer answer = new QuAnswer(); + // 将 DTO 转换为实体类 BeanMapper.copy(item, answer); - answer.setQuId(quId); + answer.setQuId(quId); // 设置试题 ID - //补全ID避免新增 + // 如果该答案已存在,则从 IDs 列表中移除 if(ids.contains(id)){ ids.remove(id); } + // 添加答案到保存列表 saveList.add(answer); } - //保存标签列表 + // 如果有待保存的答案,则批量保存或更新 if(!CollectionUtils.isEmpty(saveList)) { this.saveOrUpdateBatch(saveList); } - //删除已移除 + // 如果有被移除的答案,则批量删除 if(!ids.isEmpty()){ this.removeByIds(ids); } }else{ - + // 如果答案列表为空,则删除所有与该试题 ID 相关的答案 QueryWrapper wrapper = new QueryWrapper<>(); wrapper.lambda().eq(QuAnswer::getQuId, quId); this.remove(wrapper); } } - - } diff --git a/src-源文件/main/java/com/yf/exam/modules/qu/service/impl/QuRepoServiceImpl.java b/src-源文件/main/java/com/yf/exam/modules/qu/service/impl/QuRepoServiceImpl.java index b7de030..c0e8f29 100644 --- a/src-源文件/main/java/com/yf/exam/modules/qu/service/impl/QuRepoServiceImpl.java +++ b/src-源文件/main/java/com/yf/exam/modules/qu/service/impl/QuRepoServiceImpl.java @@ -1,175 +1,182 @@ -package com.yf.exam.modules.qu.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.dto.QuRepoDTO; -import com.yf.exam.modules.qu.dto.request.QuRepoBatchReqDTO; -import com.yf.exam.modules.qu.entity.Qu; -import com.yf.exam.modules.qu.entity.QuRepo; -import com.yf.exam.modules.qu.mapper.QuMapper; -import com.yf.exam.modules.qu.mapper.QuRepoMapper; -import com.yf.exam.modules.qu.service.QuRepoService; -import com.yf.exam.modules.repo.service.RepoService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.util.CollectionUtils; - -import java.util.ArrayList; -import java.util.List; +package com.yf.exam.modules.qu.service.impl; // 定义包名,表示这是服务实现类,负责处理与试题题库相关的业务逻辑 + +import com.alibaba.fastjson.JSON; // 导入 fastjson 库,用于 JSON 序列化和反序列化 +import com.alibaba.fastjson.TypeReference; // 导入 fastjson 库的 TypeReference,用于处理泛型类型 +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; // 导入 MyBatis-Plus 的 QueryWrapper,用于构造查询条件 +import com.baomidou.mybatisplus.core.metadata.IPage; // 导入 MyBatis-Plus 的 IPage 接口,用于分页查询 +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; // 导入 MyBatis-Plus 的分页 Page 类 +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; // 导入 MyBatis-Plus 的 ServiceImpl 基类 +import com.yf.exam.core.api.dto.PagingReqDTO; // 导入分页请求数据传输对象类 +import com.yf.exam.modules.qu.dto.QuRepoDTO; // 导入试题题库的 DTO 类 +import com.yf.exam.modules.qu.dto.request.QuRepoBatchReqDTO; // 导入试题题库批量操作请求类 +import com.yf.exam.modules.qu.entity.Qu; // 导入试题实体类 +import com.yf.exam.modules.qu.entity.QuRepo; // 导入试题题库实体类 +import com.yf.exam.modules.qu.mapper.QuMapper; // 导入试题的 Mapper 接口 +import com.yf.exam.modules.qu.mapper.QuRepoMapper; // 导入试题题库的 Mapper 接口 +import com.yf.exam.modules.qu.service.QuRepoService; // 导入试题题库服务接口 +import com.yf.exam.modules.repo.service.RepoService; // 导入题库服务接口 +import org.springframework.beans.factory.annotation.Autowired; // 导入 Spring 的注解,自动注入依赖 +import org.springframework.stereotype.Service; // 导入 Spring 的服务注解,标识这是一个服务类 +import org.springframework.util.CollectionUtils; // 导入 Spring 的集合工具类,用于检查集合是否为空 + +import java.util.ArrayList; // 导入 ArrayList,用于动态数组 +import java.util.List; // 导入 List 接口,作为列表类型 /** *

-* 语言设置 服务实现类 +* 试题题库 服务实现类 *

* * @author 聪明笨狗 * @since 2020-05-25 13:23 */ -@Service +@Service // 表示这是一个 Spring 服务类,Spring 会自动扫描并管理该类 public class QuRepoServiceImpl extends ServiceImpl implements QuRepoService { - @Autowired - private QuMapper quMapper; + private QuMapper quMapper; // 自动注入试题的 Mapper 接口 @Autowired - private RepoService repoService; + private RepoService repoService; // 自动注入题库服务接口 @Override public IPage paging(PagingReqDTO reqDTO) { - - //创建分页对象 + // 创建分页对象,传入当前页和每页大小 IPage query = new Page<>(reqDTO.getCurrent(), reqDTO.getSize()); - //查询条件 + // 创建查询条件包装器 QueryWrapper wrapper = new QueryWrapper<>(); - //获得数据 + // 执行分页查询,获取分页结果 IPage page = this.page(query, wrapper); - //转换结果 + + // 将查询结果转换为 QuRepoDTO 类型的分页结果 IPage pageData = JSON.parseObject(JSON.toJSONString(page), new TypeReference>(){}); return pageData; - } + } @Override public void saveAll(String quId, Integer quType, List ids) { - // 先删除 + // 先删除已有的试题题库记录 QueryWrapper wrapper = new QueryWrapper<>(); wrapper.lambda().eq(QuRepo::getQuId, quId); this.remove(wrapper); - // 保存全部 + // 如果题库 ID 列表不为空,保存新的记录 if(!CollectionUtils.isEmpty(ids)){ List list = new ArrayList<>(); for(String id: ids){ QuRepo ref = new QuRepo(); - ref.setQuId(quId); - ref.setRepoId(id); - ref.setQuType(quType); + ref.setQuId(quId); // 设置试题 ID + ref.setRepoId(id); // 设置题库 ID + ref.setQuType(quType); // 设置题目类型 list.add(ref); } + // 批量保存试题题库记录 this.saveBatch(list); - + // 对每个题库进行排序 for(String id: ids){ this.sortRepo(id); } } - - } @Override public List listByQu(String quId) { - // 先删除 + // 根据试题 ID 查找题库记录 QueryWrapper wrapper = new QueryWrapper<>(); wrapper.lambda().eq(QuRepo::getQuId, quId); List list = this.list(wrapper); List ids = new ArrayList<>(); if(!CollectionUtils.isEmpty(list)){ + // 提取题库 ID 列表 for(QuRepo item: list){ ids.add(item.getRepoId()); } } - return ids; + return ids; // 返回题库 ID 列表 } @Override public List listByRepo(String repoId, Integer quType, boolean rand) { + // 根据题库 ID 和题目类型查询题库记录 QueryWrapper wrapper = new QueryWrapper<>(); - wrapper.lambda() - .eq(QuRepo::getRepoId, repoId); + wrapper.lambda().eq(QuRepo::getRepoId, repoId); - if(quType!=null){ + // 如果有题目类型,添加过滤条件 + if(quType != null){ wrapper.lambda().eq(QuRepo::getQuType, quType); } + // 根据是否需要随机排序决定排序方式 if(rand){ - wrapper.orderByAsc(" RAND() "); + wrapper.orderByAsc(" RAND() "); // 随机排序 }else{ - wrapper.lambda().orderByAsc(QuRepo::getSort); + wrapper.lambda().orderByAsc(QuRepo::getSort); // 按照排序字段排序 } + // 执行查询,获取题库记录列表 List list = this.list(wrapper); List ids = new ArrayList<>(); if(!CollectionUtils.isEmpty(list)){ + // 提取试题 ID 列表 for(QuRepo item: list){ ids.add(item.getQuId()); } } - return ids; + return ids; // 返回试题 ID 列表 } @Override public void batchAction(QuRepoBatchReqDTO reqDTO) { - - // 移除的 - if(reqDTO.getRemove()!=null && reqDTO.getRemove()){ + // 如果需要移除记录 + if(reqDTO.getRemove() != null && reqDTO.getRemove()){ + // 删除满足条件的题库记录 QueryWrapper wrapper = new QueryWrapper<>(); wrapper.lambda() .in(QuRepo::getRepoId, reqDTO.getRepoIds()) .in(QuRepo::getQuId, reqDTO.getQuIds()); this.remove(wrapper); }else{ - - // 新增的 + // 如果是新增记录,处理新增逻辑 for(String quId : reqDTO.getQuIds()){ + // 根据试题 ID 查询试题类型 Qu q = quMapper.selectById(quId); + // 保存新的题库记录 this.saveAll(quId, q.getQuType(), reqDTO.getRepoIds()); } } + // 对每个题库进行排序 for(String id: reqDTO.getRepoIds()){ this.sortRepo(id); } - } - /** * 单个题库进行排序 - * @param repoId + * @param repoId 题库 ID */ private void sortRepo(String repoId){ - + // 查询题库下的所有试题 QueryWrapper wrapper = new QueryWrapper<>(); wrapper.lambda().eq(QuRepo::getRepoId, repoId); - List list = this.list(wrapper); + + // 如果题库下没有试题,返回 if(CollectionUtils.isEmpty(list)){ return; } + // 按照顺序设置每个试题的排序值 int sort = 1; for(QuRepo item: list){ item.setSort(sort); sort++; } + + // 批量更新排序值 this.updateBatchById(list); } } diff --git a/src-源文件/main/java/com/yf/exam/modules/qu/service/impl/QuServiceImpl.java b/src-源文件/main/java/com/yf/exam/modules/qu/service/impl/QuServiceImpl.java index f9ae656..3594ff6 100644 --- a/src-源文件/main/java/com/yf/exam/modules/qu/service/impl/QuServiceImpl.java +++ b/src-源文件/main/java/com/yf/exam/modules/qu/service/impl/QuServiceImpl.java @@ -1,9 +1,12 @@ package com.yf.exam.modules.qu.service.impl; +// 导入MyBatis Plus相关类 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.ability.upload.config.UploadConfig; import com.yf.exam.core.api.dto.PagingReqDTO; import com.yf.exam.core.exception.ServiceException; @@ -23,6 +26,7 @@ import com.yf.exam.modules.qu.service.QuRepoService; import com.yf.exam.modules.qu.service.QuService; import com.yf.exam.modules.qu.utils.ImageCheckUtils; import com.yf.exam.modules.repo.service.RepoService; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -37,7 +41,7 @@ import java.util.Map; /** *

- * 语言设置 服务实现类 + * 题目管理服务实现类 *

* * @author 聪明笨狗 @@ -46,125 +50,136 @@ import java.util.Map; @Service public class QuServiceImpl extends ServiceImpl implements QuService { + // 注入QuAnswerService服务 @Autowired private QuAnswerService quAnswerService; + // 注入QuRepoService服务 @Autowired private QuRepoService quRepoService; + // 注入图片校验工具类 @Autowired private ImageCheckUtils imageCheckUtils; + // 分页查询题目列表 @Override public IPage paging(PagingReqDTO reqDTO) { - //创建分页对象 + // 创建分页对象 Page page = new Page<>(reqDTO.getCurrent(), reqDTO.getSize()); - //转换结果 + // 调用baseMapper的分页查询方法,获取分页数据 IPage pageData = baseMapper.paging(page, reqDTO.getParams()); return pageData; } + // 删除题目、答案和题库绑定 @Transactional(rollbackFor = Exception.class) @Override public void delete(List ids) { - // 移除题目 + // 删除题目 this.removeByIds(ids); - // 移除选项 + // 删除与题目相关的选项 QueryWrapper wrapper = new QueryWrapper<>(); wrapper.lambda().in(QuAnswer::getQuId, ids); quAnswerService.remove(wrapper); - // 移除题库绑定 + // 删除题库与题目的绑定 QueryWrapper wrapper1 = new QueryWrapper<>(); wrapper1.lambda().in(QuRepo::getQuId, ids); quRepoService.remove(wrapper1); } + // 随机获取题目 @Override public List listByRandom(String repoId, Integer quType, List excludes, Integer size) { return baseMapper.listByRandom(repoId, quType, excludes, size); } + // 获取题目的详细信息 @Override public QuDetailDTO detail(String id) { QuDetailDTO respDTO = new QuDetailDTO(); + // 获取题目信息 Qu qu = this.getById(id); BeanMapper.copy(qu, respDTO); + // 获取题目的选项信息 List answerList = quAnswerService.listByQu(id); respDTO.setAnswerList(answerList); + // 获取题目所属的题库 List repoIds = quRepoService.listByQu(id); respDTO.setRepoIds(repoIds); return respDTO; } - + // 保存题目信息 @Transactional(rollbackFor = Exception.class) @Override public void save(QuDetailDTO reqDTO) { - - // 校验数据 + // 校验题目信息 this.checkData(reqDTO, ""); Qu qu = new Qu(); + // 将题目详情复制到实体类 BeanMapper.copy(reqDTO, qu); - // 校验图片地址 + // 校验图片地址是否正确 imageCheckUtils.checkImage(qu.getImage(), "题干图片地址错误!"); - // 更新 + // 保存或更新题目信息 this.saveOrUpdate(qu); - // 保存全部问题 + // 保存题目的选项 quAnswerService.saveAll(qu.getId(), reqDTO.getAnswerList()); - // 保存到题库 + // 保存题目与题库的绑定 quRepoService.saveAll(qu.getId(), qu.getQuType(), reqDTO.getRepoIds()); - } + // 获取题目导出的列表 @Override public List listForExport(QuQueryReqDTO query) { return baseMapper.listForExport(query); } + // 导入Excel数据 @Override public int importExcel(List dtoList) { - //根据题目名称分组 + // 根据题目名称分组 Map> anMap = new HashMap<>(16); - //题目本体信息 + // 存储题目信息 Map quMap = new HashMap<>(16); - //数据分组 + // 分组数据 for (QuExportDTO item : dtoList) { - // 空白的ID + // 如果题目ID为空,跳过 if (StringUtils.isEmpty(item.getNo())) { continue; } Integer key; - //序号 + // 获取题目序号 try { key = Integer.parseInt(item.getNo()); } catch (Exception e) { continue; } - //如果已经有题目了,直接处理选项 + // 如果题目已存在,直接处理选项 if (anMap.containsKey(key)) { anMap.get(key).add(item); } else { - //如果没有,将题目内容和选项一起 + // 如果没有,将题目内容和选项一起放入 List subList = new ArrayList<>(); subList.add(item); anMap.put(key, subList); @@ -174,49 +189,46 @@ public class QuServiceImpl extends ServiceImpl implements QuServic int count = 0; try { - - //循环题目插入 + // 遍历题目插入 for (Integer key : quMap.keySet()) { QuExportDTO im = quMap.get(key); - //题目基本信息 + // 处理题目的基本信息 QuDetailDTO qu = new QuDetailDTO(); qu.setContent(im.getQContent()); qu.setAnalysis(im.getQAnalysis()); qu.setQuType(Integer.parseInt(im.getQuType())); qu.setCreateTime(new Date()); - //设置回答列表 + // 设置题目的回答列表 List answerList = this.processAnswerList(anMap.get(key)); - //设置题目 qu.setAnswerList(answerList); - //设置引用题库 + + // 设置题目所属的题库 qu.setRepoIds(im.getRepoList()); - // 保存答案 + + // 保存题目 this.save(qu); count++; } } catch (ServiceException e) { e.printStackTrace(); + // 异常处理,抛出导入失败的异常 throw new ServiceException(1, "导入出现问题,行:" + count + "," + e.getMessage()); } return count; } - /** - * 处理回答列表 - * - * @param importList - * @return - */ + // 处理题目的回答列表 private List processAnswerList(List importList) { List list = new ArrayList<>(16); for (QuExportDTO item : importList) { QuAnswerDTO a = new QuAnswerDTO(); + // 设置选项是否正确 a.setIsRight("1".equals(item.getAIsRight())); a.setContent(item.getAContent()); a.setAnalysis(item.getAAnalysis()); @@ -226,58 +238,52 @@ public class QuServiceImpl extends ServiceImpl implements QuServic return list; } - /** - * 校验题目信息 - * - * @param qu - * @param no - * @throws Exception - */ + // 校验题目信息 public void checkData(QuDetailDTO qu, String no) { - + // 校验题目内容不能为空 if (StringUtils.isEmpty(qu.getContent())) { throw new ServiceException(1, no + "题目内容不能为空!"); } - + // 校验至少选择一个题库 if (CollectionUtils.isEmpty(qu.getRepoIds())) { throw new ServiceException(1, no + "至少要选择一个题库!"); } + // 校验回答选项 List answers = qu.getAnswerList(); + if (CollectionUtils.isEmpty(answers)) { + throw new ServiceException(1, no + "客观题至少要包含一个备选答案!"); + } + int trueCount = 0; + for (QuAnswerDTO a : answers) { - if (CollectionUtils.isEmpty(answers)) { - throw new ServiceException(1, no + "客观题至少要包含一个备选答案!"); + // 校验选项是否定义了正确标志 + if (a.getIsRight() == null) { + throw new ServiceException(1, no + "必须定义选项是否正确项!"); } - - int trueCount = 0; - for (QuAnswerDTO a : answers) { - - if (a.getIsRight() == null) { - throw new ServiceException(1, no + "必须定义选项是否正确项!"); - } - - if (StringUtils.isEmpty(a.getContent())) { - throw new ServiceException(1, no + "选项内容不为空!"); - } - - if (a.getIsRight()) { - trueCount += 1; - } + // 校验选项内容不能为空 + if (StringUtils.isEmpty(a.getContent())) { + throw new ServiceException(1, no + "选项内容不为空!"); } - if (trueCount == 0) { - throw new ServiceException(1, no + "至少要包含一个正确项!"); + // 统计正确选项的个数 + if (a.getIsRight()) { + trueCount += 1; } + } + // 校验至少包含一个正确选项 + if (trueCount == 0) { + throw new ServiceException(1, no + "至少要包含一个正确项!"); + } - //单选题 - if (qu.getQuType().equals(QuType.RADIO) && trueCount > 1) { - throw new ServiceException(1, no + "单选题不能包含多个正确项!"); - } - + // 单选题不能包含多个正确选项 + if (qu.getQuType().equals(QuType.RADIO) && trueCount > 1) { + throw new ServiceException(1, no + "单选题不能包含多个正确项!"); + } } } diff --git a/src-源文件/main/java/com/yf/exam/modules/qu/utils/ImageCheckUtils.java b/src-源文件/main/java/com/yf/exam/modules/qu/utils/ImageCheckUtils.java index 707fbcd..902c507 100644 --- a/src-源文件/main/java/com/yf/exam/modules/qu/utils/ImageCheckUtils.java +++ b/src-源文件/main/java/com/yf/exam/modules/qu/utils/ImageCheckUtils.java @@ -1,31 +1,42 @@ +// 定义包名,表示该类属于com.yf.exam.modules.qu.utils包下 package com.yf.exam.modules.qu.utils; +// 导入项目中定义的上传配置类 import com.yf.exam.ability.upload.config.UploadConfig; +// 导入项目中定义的服务异常类 import com.yf.exam.core.exception.ServiceException; +// 导入Apache Commons Lang库中的StringUtils类,用于字符串操作 import org.apache.commons.lang3.StringUtils; +// 导入Spring框架中的注解,用于自动注入依赖 import org.springframework.beans.factory.annotation.Autowired; +// 导入Spring框架中的注解,用于声明组件 import org.springframework.stereotype.Component; +/** + * 图片校验工具类,提供图片地址校验的功能 + */ @Component public class ImageCheckUtils { + // 自动注入上传配置,用于获取图片上传的相关配置 @Autowired private UploadConfig conf; /** - * 进行图片校验! - * @param image - * @param throwMsg + * 进行图片校验的方法 + * @param image 图片地址 + * @param throwMsg 校验失败时抛出的异常信息 */ public void checkImage(String image, String throwMsg) { - + // 如果图片地址为空或空白,则直接返回,不进行校验 if(StringUtils.isBlank(image)){ return; } - // 校验图片地址 + // 校验图片地址是否以配置的URL开头,确保图片地址是合法的 if(!image.startsWith(conf.getUrl())){ + // 如果图片地址不合法,则抛出服务异常 throw new ServiceException(throwMsg); } } -} +} \ No newline at end of file