From 436cc83033124793e692ab7313ba16e7ba94084c Mon Sep 17 00:00:00 2001 From: luotaiqian <1147642922@qq.com> Date: Thu, 20 Aug 2026 09:37:54 +0800 Subject: [PATCH] PaperBasicInfo --- ...60820_paper_add_paper_type_config_rule.sql | 11 ++++ .../cedu/controller/PaperController.java | 9 +++ .../qinan/cedu/convertor/PaperConvertor.java | 9 +++ .../org/qinan/cedu/enums/PaperTypeEnum.java | 46 +++++++++++++++ .../org/qinan/cedu/mapper/QuestionMapper.java | 8 +++ .../cedu/model/dto/PaperConfigRuleDTO.java | 9 +++ .../cedu/model/dto/PaperPageQueryDTO.java | 4 ++ .../qinan/cedu/model/dto/PaperUpdateDTO.java | 7 +++ .../org/qinan/cedu/model/entity/PaperDO.java | 6 ++ .../qinan/cedu/model/vo/PaperBasicInfoVO.java | 45 ++++++++++++++ .../qinan/cedu/model/vo/PaperExamInfoVO.java | 21 +++++++ .../org/qinan/cedu/model/vo/PaperPageVO.java | 6 ++ .../org/qinan/cedu/service/PaperService.java | 11 +++- .../cedu/service/impl/PaperServiceImpl.java | 58 +++++++++++++++++++ .../main/resources/mapper/QuestionMapper.xml | 13 +++++ 15 files changed, 261 insertions(+), 2 deletions(-) create mode 100644 docs/sql/20260820_paper_add_paper_type_config_rule.sql create mode 100644 safety-cedu-service/src/main/java/org/qinan/cedu/enums/PaperTypeEnum.java create mode 100644 safety-cedu-service/src/main/java/org/qinan/cedu/model/dto/PaperConfigRuleDTO.java create mode 100644 safety-cedu-service/src/main/java/org/qinan/cedu/model/vo/PaperBasicInfoVO.java create mode 100644 safety-cedu-service/src/main/java/org/qinan/cedu/model/vo/PaperExamInfoVO.java diff --git a/docs/sql/20260820_paper_add_paper_type_config_rule.sql b/docs/sql/20260820_paper_add_paper_type_config_rule.sql new file mode 100644 index 00000000..0ab5ca67 --- /dev/null +++ b/docs/sql/20260820_paper_add_paper_type_config_rule.sql @@ -0,0 +1,11 @@ +-- ===================================================================== +-- 变更说明: +-- 1. paper 表新增 paper_type(试卷类型, varchar(36), 非空, 默认fixed: +-- fixed平台试卷,config_rule规则试卷) +-- 2. paper 表新增 config_rule(配置规则, text, 可空) +-- 变更时间: 2026-08-20 +-- ===================================================================== + +ALTER TABLE `paper` + ADD COLUMN `paper_type` varchar(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'fixed' COMMENT '试卷类型 fixed平台试卷,config_rule规则试卷' AFTER `status`, + ADD COLUMN `config_rule` text COLLATE utf8mb4_general_ci COMMENT '配置规则' AFTER `paper_type`; diff --git a/safety-cedu-service/src/main/java/org/qinan/cedu/controller/PaperController.java b/safety-cedu-service/src/main/java/org/qinan/cedu/controller/PaperController.java index 12cd819b..087687da 100644 --- a/safety-cedu-service/src/main/java/org/qinan/cedu/controller/PaperController.java +++ b/safety-cedu-service/src/main/java/org/qinan/cedu/controller/PaperController.java @@ -3,9 +3,11 @@ package org.qinan.cedu.controller; import com.baomidou.mybatisplus.core.metadata.IPage; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; import lombok.RequiredArgsConstructor; import org.qinan.cedu.model.dto.*; import org.qinan.cedu.model.vo.PaperImportVO; +import org.qinan.cedu.model.vo.PaperExamInfoVO; import org.qinan.cedu.model.vo.PaperPageVO; import org.qinan.cedu.model.vo.PaperQuestionVO; import org.qinan.cedu.service.PaperService; @@ -73,4 +75,11 @@ public class PaperController { IPage page = questionService.pagePaperQuestions(query); return PageResponse.of(page.getRecords(), page.getTotal()); } + + @ApiOperation("试卷考试信息查询") + @GetMapping("/paper/exam/info") + public SingleResponse paperExamInfo(@RequestParam("paperId") @ApiParam(value = "试卷id", required = true) Long paperId) { + PaperExamInfoVO pageInfo = paperService.paperExamInfo(paperId); + return SingleResponse.success(pageInfo); + } } diff --git a/safety-cedu-service/src/main/java/org/qinan/cedu/convertor/PaperConvertor.java b/safety-cedu-service/src/main/java/org/qinan/cedu/convertor/PaperConvertor.java index 6f1c01c0..7f078a48 100644 --- a/safety-cedu-service/src/main/java/org/qinan/cedu/convertor/PaperConvertor.java +++ b/safety-cedu-service/src/main/java/org/qinan/cedu/convertor/PaperConvertor.java @@ -2,6 +2,7 @@ package org.qinan.cedu.convertor; import org.mapstruct.Mapper; import org.qinan.cedu.model.entity.PaperDO; +import org.qinan.cedu.model.vo.PaperBasicInfoVO; import org.qinan.cedu.model.vo.PaperPageVO; import java.util.List; @@ -12,4 +13,12 @@ public interface PaperConvertor { PaperPageVO convertEToVo(PaperDO entity); List convertEListToVoList(List list); + + /** + * 试卷实体转试卷基础信息VO + * + * @param entity 试卷实体 + * @return 试卷基础信息VO + */ + PaperBasicInfoVO convertEToBasicVo(PaperDO entity); } diff --git a/safety-cedu-service/src/main/java/org/qinan/cedu/enums/PaperTypeEnum.java b/safety-cedu-service/src/main/java/org/qinan/cedu/enums/PaperTypeEnum.java new file mode 100644 index 00000000..5aeedefb --- /dev/null +++ b/safety-cedu-service/src/main/java/org/qinan/cedu/enums/PaperTypeEnum.java @@ -0,0 +1,46 @@ +package org.qinan.cedu.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 试卷类型枚举 + */ +@Getter +@AllArgsConstructor +public enum PaperTypeEnum { + + /** + * 平台试卷 + */ + FIXED("fixed", "平台试卷"), + + /** + * 规则试卷 + */ + CONFIG_RULE("config_rule", "规则试卷"); + + /** + * 编码 + */ + private final String value; + + /** + * 描述 + */ + private final String label; + + public static final String REMARKS = "试卷类型 fixed平台试卷,config_rule规则试卷"; + + /** + * 根据编码获取枚举 + */ + public static PaperTypeEnum fromCode(String code) { + for (PaperTypeEnum type : values()) { + if (type.value.equals(code)) { + return type; + } + } + return null; + } +} diff --git a/safety-cedu-service/src/main/java/org/qinan/cedu/mapper/QuestionMapper.java b/safety-cedu-service/src/main/java/org/qinan/cedu/mapper/QuestionMapper.java index da22a20a..0e57c26b 100644 --- a/safety-cedu-service/src/main/java/org/qinan/cedu/mapper/QuestionMapper.java +++ b/safety-cedu-service/src/main/java/org/qinan/cedu/mapper/QuestionMapper.java @@ -36,6 +36,14 @@ public interface QuestionMapper extends BaseMapper { */ QuestionVO findQuestion(@Param("questionId") Long questionId); + /** + * 查询试卷下的试题列表(关联课件名称) + * + * @param paperId 试卷id + * @return 试题VO列表 + */ + List listPaperQuestions(@Param("paperId") Long paperId); + /** * 按题型统计试题数量(按关联课件过滤,一条SQL聚合) * diff --git a/safety-cedu-service/src/main/java/org/qinan/cedu/model/dto/PaperConfigRuleDTO.java b/safety-cedu-service/src/main/java/org/qinan/cedu/model/dto/PaperConfigRuleDTO.java new file mode 100644 index 00000000..39b13d39 --- /dev/null +++ b/safety-cedu-service/src/main/java/org/qinan/cedu/model/dto/PaperConfigRuleDTO.java @@ -0,0 +1,9 @@ +package org.qinan.cedu.model.dto; + +import lombok.Data; + +@Data +public class PaperConfigRuleDTO { + +// private +} diff --git a/safety-cedu-service/src/main/java/org/qinan/cedu/model/dto/PaperPageQueryDTO.java b/safety-cedu-service/src/main/java/org/qinan/cedu/model/dto/PaperPageQueryDTO.java index 93f766f1..c36057b2 100644 --- a/safety-cedu-service/src/main/java/org/qinan/cedu/model/dto/PaperPageQueryDTO.java +++ b/safety-cedu-service/src/main/java/org/qinan/cedu/model/dto/PaperPageQueryDTO.java @@ -4,6 +4,7 @@ import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.EqualsAndHashCode; +import org.qinan.cedu.enums.PaperTypeEnum; import org.qinan.cedu.model.query.BasePageQuery; import org.springframework.format.annotation.DateTimeFormat; @@ -20,6 +21,9 @@ public class PaperPageQueryDTO extends BasePageQuery { @ApiModelProperty("试卷名称(模糊)") private String paperName; + @ApiModelProperty(PaperTypeEnum.REMARKS) + private String paperType; + @ApiModelProperty("创建时间-开始(yyyy-MM-dd,含当天)") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) private LocalDate createTimeStart; diff --git a/safety-cedu-service/src/main/java/org/qinan/cedu/model/dto/PaperUpdateDTO.java b/safety-cedu-service/src/main/java/org/qinan/cedu/model/dto/PaperUpdateDTO.java index edc8a3cc..2fd7e84e 100644 --- a/safety-cedu-service/src/main/java/org/qinan/cedu/model/dto/PaperUpdateDTO.java +++ b/safety-cedu-service/src/main/java/org/qinan/cedu/model/dto/PaperUpdateDTO.java @@ -38,4 +38,11 @@ public class PaperUpdateDTO { @DecimalMin(value = "0", message = "合格分数不能小于0") @DecimalMax(value = "9999.99", message = "合格分数不能超过9999.99") private BigDecimal paperPassScore; + + @ApiModelProperty("试卷类型 fixed平台试卷,config_rule规则试卷") + @Size(max = 36, message = "试卷类型长度不能超过36个字符") + private String paperType; + + @ApiModelProperty("配置规则") + private String configRule; } diff --git a/safety-cedu-service/src/main/java/org/qinan/cedu/model/entity/PaperDO.java b/safety-cedu-service/src/main/java/org/qinan/cedu/model/entity/PaperDO.java index 54f449b3..c58ff766 100644 --- a/safety-cedu-service/src/main/java/org/qinan/cedu/model/entity/PaperDO.java +++ b/safety-cedu-service/src/main/java/org/qinan/cedu/model/entity/PaperDO.java @@ -36,4 +36,10 @@ public class PaperDO extends BaseEntity { @ApiModelProperty("试卷状态 normal 正常") private String status; + + @ApiModelProperty("试卷类型 fixed平台试卷,config_rule规则试卷") + private String paperType; + + @ApiModelProperty("配置规则") + private String configRule; } diff --git a/safety-cedu-service/src/main/java/org/qinan/cedu/model/vo/PaperBasicInfoVO.java b/safety-cedu-service/src/main/java/org/qinan/cedu/model/vo/PaperBasicInfoVO.java new file mode 100644 index 00000000..c9cc984a --- /dev/null +++ b/safety-cedu-service/src/main/java/org/qinan/cedu/model/vo/PaperBasicInfoVO.java @@ -0,0 +1,45 @@ +package org.qinan.cedu.model.vo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +/** + * 试卷 + */ +@Data +@ApiModel(value = "PaperBasicInfoVO", description = "试卷基础信息") +public class PaperBasicInfoVO { + + @ApiModelProperty("id") + @JsonSerialize(using = ToStringSerializer.class) + private Long id; + + @ApiModelProperty("创建时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime createTime; + + @ApiModelProperty("试卷名称") + private String paperName; + + @ApiModelProperty("试卷总分") + private BigDecimal paperTotalScore; + + @ApiModelProperty("合格分数") + private BigDecimal paperPassScore; + + @ApiModelProperty("试卷状态 normal 正常") + private String status; + + @ApiModelProperty("试卷类型 fixed平台试卷,config_rule规则试卷") + private String paperType; + + @ApiModelProperty("配置规则") + private String configRule; +} diff --git a/safety-cedu-service/src/main/java/org/qinan/cedu/model/vo/PaperExamInfoVO.java b/safety-cedu-service/src/main/java/org/qinan/cedu/model/vo/PaperExamInfoVO.java new file mode 100644 index 00000000..c0c77c95 --- /dev/null +++ b/safety-cedu-service/src/main/java/org/qinan/cedu/model/vo/PaperExamInfoVO.java @@ -0,0 +1,21 @@ +package org.qinan.cedu.model.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +/** + * 试卷试题分页返回 + */ +@Data +@ApiModel(value = "PaperExamInfoVO", description = "试卷考试信息") +public class PaperExamInfoVO { + + @ApiModelProperty("试卷基本信息") + private PaperBasicInfoVO paperBasicInfoVO; + + @ApiModelProperty("试题信息") + private List questionVOList; +} diff --git a/safety-cedu-service/src/main/java/org/qinan/cedu/model/vo/PaperPageVO.java b/safety-cedu-service/src/main/java/org/qinan/cedu/model/vo/PaperPageVO.java index e05af615..bb9b7d09 100644 --- a/safety-cedu-service/src/main/java/org/qinan/cedu/model/vo/PaperPageVO.java +++ b/safety-cedu-service/src/main/java/org/qinan/cedu/model/vo/PaperPageVO.java @@ -33,6 +33,12 @@ public class PaperPageVO { @ApiModelProperty("试卷状态 normal 正常") private String status; + @ApiModelProperty("试卷类型 fixed平台试卷,config_rule规则试卷") + private String paperType; + + @ApiModelProperty("配置规则") + private String configRule; + @ApiModelProperty("创建时间") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime createTime; diff --git a/safety-cedu-service/src/main/java/org/qinan/cedu/service/PaperService.java b/safety-cedu-service/src/main/java/org/qinan/cedu/service/PaperService.java index 964bd7e4..42110b03 100644 --- a/safety-cedu-service/src/main/java/org/qinan/cedu/service/PaperService.java +++ b/safety-cedu-service/src/main/java/org/qinan/cedu/service/PaperService.java @@ -8,6 +8,7 @@ import org.qinan.cedu.model.dto.PaperPageQueryDTO; import org.qinan.cedu.model.dto.PaperUpdateDTO; import org.qinan.cedu.model.entity.PaperDO; import org.qinan.cedu.model.vo.PaperImportVO; +import org.qinan.cedu.model.vo.PaperExamInfoVO; import org.qinan.cedu.model.vo.PaperPageVO; import java.util.List; @@ -20,7 +21,7 @@ public interface PaperService extends IService { /** * 分页查询试卷 * - * @param query 查询条件(试卷名称、创建时间范围) + * @param query 查询条件(试卷名称、试卷类型、创建时间范围) * @return 分页结果 */ IPage pageQuery(PaperPageQueryDTO query); @@ -88,5 +89,11 @@ public interface PaperService extends IService { */ String importQuestionsTemplate(); - + /** + * 查询试卷考试信息(试卷基础信息+试题列表含选项) + * + * @param paperId 试卷id + * @return 试卷考试信息 + */ + PaperExamInfoVO paperExamInfo(Long paperId); } diff --git a/safety-cedu-service/src/main/java/org/qinan/cedu/service/impl/PaperServiceImpl.java b/safety-cedu-service/src/main/java/org/qinan/cedu/service/impl/PaperServiceImpl.java index c7811fa2..fa632bc1 100644 --- a/safety-cedu-service/src/main/java/org/qinan/cedu/service/impl/PaperServiceImpl.java +++ b/safety-cedu-service/src/main/java/org/qinan/cedu/service/impl/PaperServiceImpl.java @@ -10,10 +10,13 @@ import com.baomidou.mybatisplus.extension.toolkit.Db; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.qinan.cedu.convertor.PaperConvertor; +import org.qinan.cedu.convertor.QuestionConvertor; import org.qinan.cedu.enums.DeleteEnum; import org.qinan.cedu.enums.PaperStatusEnum; +import org.qinan.cedu.enums.PaperTypeEnum; import org.qinan.cedu.mapper.PaperMapper; import org.qinan.cedu.mapper.PaperQuestionRelMapper; +import org.qinan.cedu.mapper.QuestionMapper; import org.qinan.cedu.mapper.QuestionOptionMapper; import org.qinan.cedu.model.dto.PaperCopyDTO; import org.qinan.cedu.model.dto.PaperImportDTO; @@ -23,8 +26,11 @@ import org.qinan.cedu.model.entity.PaperDO; import org.qinan.cedu.model.entity.PaperQuestionRelDO; import org.qinan.cedu.model.entity.QuestionDO; import org.qinan.cedu.model.entity.QuestionOptionDO; +import org.qinan.cedu.model.vo.PaperExamInfoVO; import org.qinan.cedu.model.vo.PaperImportVO; import org.qinan.cedu.model.vo.PaperPageVO; +import org.qinan.cedu.model.vo.QuestionOptionVO; +import org.qinan.cedu.model.vo.QuestionVO; import org.qinan.cedu.service.PaperService; import org.qinan.cedu.service.support.QuestionExcelImporter; import org.qinan.safetyeval.infrastructure.support.InsertFieldDefaults; @@ -49,9 +55,11 @@ import java.util.stream.Collectors; public class PaperServiceImpl extends ServiceImpl implements PaperService { private final PaperQuestionRelMapper paperQuestionRelMapper; + private final QuestionMapper questionMapper; private final QuestionOptionMapper questionOptionMapper; private final QuestionExcelImporter questionExcelImporter; private final PaperConvertor paperConvertor; + private final QuestionConvertor questionConvertor; @Value("${template.paper.importUrl:}") private String paperImportUrl; @@ -131,6 +139,8 @@ public class PaperServiceImpl extends ServiceImpl implemen target.setPaperTotalScore(copyDTO.getPaperTotalScore()); target.setPaperPassScore(copyDTO.getPaperPassScore()); target.setStatus(source.getStatus()); + target.setPaperType(source.getPaperType()); + target.setConfigRule(source.getConfigRule()); this.savePaper(target); // 复制试题+选项+试卷试题关系(id全部换新雪花id) @@ -266,4 +276,52 @@ public class PaperServiceImpl extends ServiceImpl implemen public String importQuestionsTemplate() { return paperImportUrl; } + + @Override + public PaperExamInfoVO paperExamInfo(Long paperId) { + // 1. 查询试卷基础信息 + PaperDO paper = this.lambdaQuery() + .eq(PaperDO::getId, paperId) + .eq(PaperDO::getDeleteEnum, DeleteEnum.FALSE.getCode()) + .one(); + if (paper == null) { + throw new IllegalArgumentException("试卷不存在"); + } + PaperExamInfoVO examInfoVO = new PaperExamInfoVO(); + examInfoVO.setPaperBasicInfoVO(paperConvertor.convertEToBasicVo(paper)); + + // 2. 查询试卷下试题(关联课件名称)并填充选项 + List questionVOList = questionMapper.listPaperQuestions(paperId); + fillQuestionOptions(questionVOList); + examInfoVO.setQuestionVOList(questionVOList); + return examInfoVO; + } + + /** + * 批量填充试题选项:一次查询所有试题的选项后按试题id分组回填 + * + * @param questionVOList 试题VO列表 + */ + private void fillQuestionOptions(List questionVOList) { + if (CollectionUtils.isEmpty(questionVOList)) { + return; + } + List questionIds = questionVOList.stream() + .map(question -> Long.valueOf(question.getId())) + .collect(Collectors.toList()); + // 查询选项信息(仅查询VO需要的字段,按显示顺序排序) + List optionList = questionOptionMapper.selectList(new LambdaQueryWrapper() + .select(QuestionOptionDO::getId, QuestionOptionDO::getQuestionId, + QuestionOptionDO::getOptionKey, QuestionOptionDO::getOptionName, + QuestionOptionDO::getOptionText, QuestionOptionDO::getIsCorrect, + QuestionOptionDO::getSortOrder) + .in(QuestionOptionDO::getQuestionId, questionIds) + .eq(QuestionOptionDO::getDeleteEnum, DeleteEnum.FALSE.getCode()) + .orderByAsc(QuestionOptionDO::getSortOrder)); + Map> optionMap = questionConvertor.convertOptionEListToVoList(optionList) + .stream() + .collect(Collectors.groupingBy(QuestionOptionVO::getQuestionId)); + questionVOList.forEach(question -> question.setQuestionOptionVOList( + optionMap.getOrDefault(Long.valueOf(question.getId()), new ArrayList<>()))); + } } diff --git a/safety-cedu-service/src/main/resources/mapper/QuestionMapper.xml b/safety-cedu-service/src/main/resources/mapper/QuestionMapper.xml index 5d03b871..01313eae 100644 --- a/safety-cedu-service/src/main/resources/mapper/QuestionMapper.xml +++ b/safety-cedu-service/src/main/resources/mapper/QuestionMapper.xml @@ -32,6 +32,19 @@ AND q.delete_enum = 'false' + +