22 changed files with 1092 additions and 0 deletions
@ -0,0 +1,42 @@ |
|||
package com.project.classicpaper.application; |
|||
|
|||
import com.project.base.domain.result.PageResult; |
|||
import com.project.base.domain.result.Result; |
|||
import com.project.classicpaper.domain.dto.ClassicPaperDTO; |
|||
import com.project.classicpaper.domain.dto.ClassicPaperQuestionDTO; |
|||
import com.project.classicpaper.domain.dto.GenerateClassicPaperRequestDTO; |
|||
|
|||
import java.util.List; |
|||
|
|||
public interface ClassicPaperApplicationService { |
|||
|
|||
/** |
|||
* 批量生成经典套题(N个版本) |
|||
*/ |
|||
Result<List<ClassicPaperDTO>> generate(GenerateClassicPaperRequestDTO request) throws Exception; |
|||
|
|||
/** |
|||
* 单题重抽 |
|||
*/ |
|||
Result<ClassicPaperQuestionDTO> regenerateQuestion(Long paperId, Long questionId) throws Exception; |
|||
|
|||
/** |
|||
* 套卷列表 |
|||
*/ |
|||
Result<PageResult<ClassicPaperDTO>> list(Long subLineId, Long classicCategoryId, Integer status, Integer pageNum, Integer pageSize); |
|||
|
|||
/** |
|||
* 套卷详情(含题目列表) |
|||
*/ |
|||
Result<ClassicPaperDTO> getDetail(Long id); |
|||
|
|||
/** |
|||
* 套题组详情(查一组N个版本) |
|||
*/ |
|||
Result<List<ClassicPaperDTO>> getGroupDetail(Long paperGroupId); |
|||
|
|||
/** |
|||
* 废弃套卷 |
|||
*/ |
|||
Result<String> delete(Long id) throws Exception; |
|||
} |
|||
@ -0,0 +1,157 @@ |
|||
package com.project.classicpaper.application.impl; |
|||
|
|||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
|||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
|||
import com.project.base.domain.exception.BusinessErrorException; |
|||
import com.project.base.domain.result.PageResult; |
|||
import com.project.base.domain.result.Result; |
|||
import com.project.base.domain.result.ResultCodeEnum; |
|||
import com.project.classicpaper.application.ClassicPaperApplicationService; |
|||
import com.project.classicpaper.domain.dto.ClassicPaperDTO; |
|||
import com.project.classicpaper.domain.dto.ClassicPaperQuestionDTO; |
|||
import com.project.classicpaper.domain.dto.GenerateClassicPaperRequestDTO; |
|||
import com.project.classicpaper.domain.entity.ClassicPaperEntity; |
|||
import com.project.classicpaper.domain.entity.ClassicPaperQuestionEntity; |
|||
import com.project.classicpaper.domain.enums.ClassicPaperStatusEnum; |
|||
import com.project.classicpaper.domain.service.*; |
|||
import com.project.question.domain.entity.QuestionEntity; |
|||
import com.project.question.domain.service.QuestionBaseService; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.stereotype.Service; |
|||
|
|||
import java.util.ArrayList; |
|||
import java.util.List; |
|||
import java.util.stream.Collectors; |
|||
|
|||
@Service |
|||
public class ClassicPaperApplicationServiceImpl implements ClassicPaperApplicationService { |
|||
|
|||
@Autowired |
|||
private GenerateClassicPaperDomainService generateClassicPaperDomainService; |
|||
|
|||
@Autowired |
|||
private RegenerateQuestionDomainService regenerateQuestionDomainService; |
|||
|
|||
@Autowired |
|||
private ClassicPaperBaseService classicPaperBaseService; |
|||
|
|||
@Autowired |
|||
private ClassicPaperQuestionBaseService classicPaperQuestionBaseService; |
|||
|
|||
@Autowired |
|||
private QuestionBaseService questionBaseService; |
|||
|
|||
@Override |
|||
public Result<List<ClassicPaperDTO>> generate(GenerateClassicPaperRequestDTO request) throws Exception { |
|||
return generateClassicPaperDomainService.generate(request); |
|||
} |
|||
|
|||
@Override |
|||
public Result<ClassicPaperQuestionDTO> regenerateQuestion(Long paperId, Long questionId) throws Exception { |
|||
return regenerateQuestionDomainService.regenerate(paperId, questionId); |
|||
} |
|||
|
|||
@Override |
|||
public Result<PageResult<ClassicPaperDTO>> list(Long subLineId, Long classicCategoryId, |
|||
Integer status, Integer pageNum, Integer pageSize) { |
|||
Page<ClassicPaperEntity> page = new Page<>(pageNum == null ? 1 : pageNum, pageSize == null ? 10 : pageSize); |
|||
|
|||
LambdaQueryWrapper<ClassicPaperEntity> wrapper = new LambdaQueryWrapper<>(); |
|||
if (subLineId != null) { |
|||
wrapper.eq(ClassicPaperEntity::getSubLineId, subLineId); |
|||
} |
|||
if (classicCategoryId != null) { |
|||
wrapper.eq(ClassicPaperEntity::getClassicCategoryId, classicCategoryId); |
|||
} |
|||
if (status != null) { |
|||
wrapper.eq(ClassicPaperEntity::getStatus, status); |
|||
} |
|||
wrapper.orderByDesc(ClassicPaperEntity::getCreateTime); |
|||
|
|||
classicPaperBaseService.page(page, wrapper); |
|||
|
|||
PageResult<ClassicPaperDTO> pageResult = new PageResult<>(page.convert(entity -> { |
|||
ClassicPaperDTO dto = entity.toDTO(ClassicPaperDTO::new); |
|||
dto.setStatusText(ClassicPaperStatusEnum.findByValue(entity.getStatus())); |
|||
return dto; |
|||
})); |
|||
return Result.success(pageResult); |
|||
} |
|||
|
|||
@Override |
|||
public Result<ClassicPaperDTO> getDetail(Long id) { |
|||
ClassicPaperEntity paper = classicPaperBaseService.getById(id); |
|||
if (paper == null) { |
|||
return Result.fail(ResultCodeEnum.RESOURCE_NOT_EXIST, "套卷不存在"); |
|||
} |
|||
|
|||
ClassicPaperDTO dto = paper.toDTO(ClassicPaperDTO::new); |
|||
dto.setStatusText(ClassicPaperStatusEnum.findByValue(paper.getStatus())); |
|||
|
|||
// 查询关联题目
|
|||
List<ClassicPaperQuestionEntity> paperQuestions = classicPaperQuestionBaseService.list( |
|||
new LambdaQueryWrapper<ClassicPaperQuestionEntity>() |
|||
.eq(ClassicPaperQuestionEntity::getPaperId, id) |
|||
.orderByAsc(ClassicPaperQuestionEntity::getSortOrder) |
|||
); |
|||
|
|||
if (!paperQuestions.isEmpty()) { |
|||
List<Long> questionIds = paperQuestions.stream() |
|||
.map(ClassicPaperQuestionEntity::getQuestionId).collect(Collectors.toList()); |
|||
List<QuestionEntity> questions = questionBaseService.listByIds(questionIds); |
|||
|
|||
List<ClassicPaperQuestionDTO> questionDTOs = new ArrayList<>(); |
|||
for (ClassicPaperQuestionEntity pq : paperQuestions) { |
|||
ClassicPaperQuestionDTO qDto = new ClassicPaperQuestionDTO(); |
|||
qDto.setId(pq.getId()); |
|||
qDto.setPaperId(pq.getPaperId()); |
|||
qDto.setQuestionId(pq.getQuestionId()); |
|||
qDto.setSortOrder(pq.getSortOrder()); |
|||
qDto.setQuestionType(pq.getQuestionType()); |
|||
questions.stream() |
|||
.filter(q -> q.getId().equals(pq.getQuestionId())) |
|||
.findFirst() |
|||
.ifPresent(q -> qDto.setQuestionDetail(q.getQuestionDetail())); |
|||
questionDTOs.add(qDto); |
|||
} |
|||
dto.setQuestionList(questionDTOs); |
|||
} |
|||
|
|||
return Result.success(dto); |
|||
} |
|||
|
|||
@Override |
|||
public Result<List<ClassicPaperDTO>> getGroupDetail(Long paperGroupId) { |
|||
List<ClassicPaperEntity> papers = classicPaperBaseService.list( |
|||
new LambdaQueryWrapper<ClassicPaperEntity>() |
|||
.eq(ClassicPaperEntity::getPaperGroupId, paperGroupId) |
|||
.orderByAsc(ClassicPaperEntity::getSetIndex) |
|||
); |
|||
if (papers.isEmpty()) { |
|||
return Result.fail(ResultCodeEnum.RESOURCE_NOT_EXIST, "套题组不存在"); |
|||
} |
|||
|
|||
List<ClassicPaperDTO> dtoList = papers.stream() |
|||
.map(entity -> { |
|||
ClassicPaperDTO dto = entity.toDTO(ClassicPaperDTO::new); |
|||
dto.setStatusText(ClassicPaperStatusEnum.findByValue(entity.getStatus())); |
|||
return dto; |
|||
}) |
|||
.collect(Collectors.toList()); |
|||
return Result.success(dtoList); |
|||
} |
|||
|
|||
@Override |
|||
public Result<String> delete(Long id) throws Exception { |
|||
ClassicPaperEntity paper = classicPaperBaseService.getById(id); |
|||
if (paper == null) { |
|||
throw new BusinessErrorException("套卷不存在"); |
|||
} |
|||
if (ClassicPaperStatusEnum.CONFIRMED.getValue().equals(paper.getStatus())) { |
|||
throw new BusinessErrorException("已固化的套卷不能废弃"); |
|||
} |
|||
paper.setStatus(ClassicPaperStatusEnum.DISCARDED.getValue()); |
|||
classicPaperBaseService.updateById(paper); |
|||
return Result.success("废弃成功"); |
|||
} |
|||
} |
|||
@ -0,0 +1,57 @@ |
|||
package com.project.classicpaper.controller; |
|||
|
|||
import com.project.base.domain.result.PageResult; |
|||
import com.project.base.domain.result.Result; |
|||
import com.project.classicpaper.application.ClassicPaperApplicationService; |
|||
import com.project.classicpaper.domain.dto.ClassicPaperDTO; |
|||
import com.project.classicpaper.domain.dto.ClassicPaperQuestionDTO; |
|||
import com.project.classicpaper.domain.dto.GenerateClassicPaperRequestDTO; |
|||
import com.project.operation.annotation.OperationLog; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.web.bind.annotation.*; |
|||
|
|||
import java.util.List; |
|||
|
|||
@RestController |
|||
@Slf4j |
|||
@RequestMapping("/api/admin/classicPaper") |
|||
public class ClassicPaperController { |
|||
|
|||
@Autowired |
|||
private ClassicPaperApplicationService classicPaperApplicationService; |
|||
|
|||
@PostMapping("/generate") |
|||
@OperationLog(module = "经典套题") |
|||
public Result<List<ClassicPaperDTO>> generate(@RequestBody GenerateClassicPaperRequestDTO request) throws Exception { |
|||
return classicPaperApplicationService.generate(request); |
|||
} |
|||
|
|||
@PostMapping("/regenerateQuestion") |
|||
@OperationLog(module = "经典套题") |
|||
public Result<ClassicPaperQuestionDTO> regenerateQuestion(Long paperId, Long questionId) throws Exception { |
|||
return classicPaperApplicationService.regenerateQuestion(paperId, questionId); |
|||
} |
|||
|
|||
@GetMapping("/list") |
|||
public Result<PageResult<ClassicPaperDTO>> list(Long subLineId, Long classicCategoryId, |
|||
Integer status, Integer pageNum, Integer pageSize) { |
|||
return classicPaperApplicationService.list(subLineId, classicCategoryId, status, pageNum, pageSize); |
|||
} |
|||
|
|||
@GetMapping("/detail") |
|||
public Result<ClassicPaperDTO> detail(Long id) { |
|||
return classicPaperApplicationService.getDetail(id); |
|||
} |
|||
|
|||
@GetMapping("/groupDetail") |
|||
public Result<List<ClassicPaperDTO>> groupDetail(Long paperGroupId) { |
|||
return classicPaperApplicationService.getGroupDetail(paperGroupId); |
|||
} |
|||
|
|||
@PostMapping("/delete") |
|||
@OperationLog(module = "经典套题") |
|||
public Result<String> delete(Long id) throws Exception { |
|||
return classicPaperApplicationService.delete(id); |
|||
} |
|||
} |
|||
@ -0,0 +1,39 @@ |
|||
package com.project.classicpaper.domain.dto; |
|||
|
|||
import com.project.base.domain.dto.BaseDTO; |
|||
import lombok.Data; |
|||
|
|||
import java.util.List; |
|||
|
|||
@Data |
|||
public class ClassicPaperDTO extends BaseDTO { |
|||
private Long id; |
|||
|
|||
private String name; |
|||
|
|||
private String description; |
|||
|
|||
private Integer sourceType; |
|||
|
|||
private Long subLineId; |
|||
|
|||
private String subLineName; |
|||
|
|||
private Long classicCategoryId; |
|||
|
|||
private String classicCategoryName; |
|||
|
|||
private Long informationId; |
|||
|
|||
private Integer status; |
|||
|
|||
private String statusText; |
|||
|
|||
private Integer questionCount; |
|||
|
|||
private Long paperGroupId; |
|||
|
|||
private Integer setIndex; |
|||
|
|||
private List<ClassicPaperQuestionDTO> questionList; |
|||
} |
|||
@ -0,0 +1,22 @@ |
|||
package com.project.classicpaper.domain.dto; |
|||
|
|||
import com.project.question.domain.entity.QuestionEntity; |
|||
import lombok.Data; |
|||
|
|||
@Data |
|||
public class ClassicPaperQuestionDTO { |
|||
private Long id; |
|||
|
|||
private Long paperId; |
|||
|
|||
private Long questionId; |
|||
|
|||
private Integer sortOrder; |
|||
|
|||
private Integer questionType; |
|||
|
|||
/** |
|||
* 题目详情(从 QuestionEntity 关联查询) |
|||
*/ |
|||
private QuestionEntity.QuestionDetail questionDetail; |
|||
} |
|||
@ -0,0 +1,52 @@ |
|||
package com.project.classicpaper.domain.dto; |
|||
|
|||
import lombok.Data; |
|||
|
|||
@Data |
|||
public class GenerateClassicPaperRequestDTO { |
|||
|
|||
/** |
|||
* 子产品线ID(必填) |
|||
*/ |
|||
private Long subLineId; |
|||
|
|||
/** |
|||
* 经典分类ID(必填) |
|||
*/ |
|||
private Long classicCategoryId; |
|||
|
|||
/** |
|||
* 生成版本数 N,1~5(必填) |
|||
*/ |
|||
private Integer setCount; |
|||
|
|||
/** |
|||
* 套卷名称前缀(必填) |
|||
*/ |
|||
private String namePrefix; |
|||
|
|||
/** |
|||
* 套卷描述(可选) |
|||
*/ |
|||
private String description; |
|||
|
|||
/** |
|||
* 单选题数量 |
|||
*/ |
|||
private Integer singleChoiceNum; |
|||
|
|||
/** |
|||
* 多选题数量 |
|||
*/ |
|||
private Integer multipleChoiceNum; |
|||
|
|||
/** |
|||
* 判断题数量 |
|||
*/ |
|||
private Integer trueFalseNum; |
|||
|
|||
/** |
|||
* 简答题数量 |
|||
*/ |
|||
private Integer shortAnswerNum; |
|||
} |
|||
@ -0,0 +1,73 @@ |
|||
package com.project.classicpaper.domain.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.project.base.domain.entity.BaseEntity; |
|||
import jakarta.persistence.*; |
|||
import lombok.Data; |
|||
import lombok.EqualsAndHashCode; |
|||
import org.hibernate.annotations.Comment; |
|||
|
|||
@Data |
|||
@Table(name = "evaluator_classic_paper", |
|||
indexes = {@Index(name = "Idx_sub_line_id", columnList = "sub_line_id"), |
|||
@Index(name = "Idx_status", columnList = "status"), |
|||
@Index(name = "Idx_paper_group_id", columnList = "paper_group_id")}) |
|||
@Entity |
|||
@TableName(value = "evaluator_classic_paper") |
|||
@EqualsAndHashCode(callSuper = true) |
|||
public class ClassicPaperEntity extends BaseEntity { |
|||
@TableId(value = "id", type = IdType.ASSIGN_ID) |
|||
@Id |
|||
private Long id; |
|||
|
|||
@Column(name = "name", columnDefinition = "varchar(200) comment '套卷名称'") |
|||
@Comment("套卷名称") |
|||
private String name; |
|||
|
|||
@Column(name = "description", columnDefinition = "TEXT comment '套卷描述'") |
|||
@Comment("套卷描述") |
|||
private String description; |
|||
|
|||
@Column(name = "source_type") |
|||
@TableField("source_type") |
|||
@Comment("来源:0-Word导入,1-AI生成") |
|||
private Integer sourceType; |
|||
|
|||
@Column(name = "sub_line_id") |
|||
@TableField("sub_line_id") |
|||
@Comment("来源子产品线ID") |
|||
private Long subLineId; |
|||
|
|||
@Column(name = "information_id") |
|||
@TableField("information_id") |
|||
@Comment("关联资料ID") |
|||
private Long informationId; |
|||
|
|||
@Column(name = "status") |
|||
@TableField("status") |
|||
@Comment("状态:0-生成中,1-草稿,2-已固化,3-已废弃") |
|||
private Integer status; |
|||
|
|||
@Column(name = "question_count") |
|||
@TableField("question_count") |
|||
@Comment("题目总数") |
|||
private Integer questionCount; |
|||
|
|||
@Column(name = "paper_group_id") |
|||
@TableField("paper_group_id") |
|||
@Comment("套题组ID,N个版本共享") |
|||
private Long paperGroupId; |
|||
|
|||
@Column(name = "set_index") |
|||
@TableField("set_index") |
|||
@Comment("组内序号(1~N)") |
|||
private Integer setIndex; |
|||
|
|||
@Column(name = "classic_category_id") |
|||
@TableField("classic_category_id") |
|||
@Comment("经典分类ID") |
|||
private Long classicCategoryId; |
|||
} |
|||
@ -0,0 +1,44 @@ |
|||
package com.project.classicpaper.domain.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.project.base.domain.entity.BaseEntity; |
|||
import jakarta.persistence.*; |
|||
import lombok.Data; |
|||
import lombok.EqualsAndHashCode; |
|||
import org.hibernate.annotations.Comment; |
|||
|
|||
@Data |
|||
@Table(name = "evaluator_classic_paper_question", |
|||
indexes = {@Index(name = "Idx_paper_id", columnList = "paper_id"), |
|||
@Index(name = "Idx_question_id", columnList = "question_id")}) |
|||
@Entity |
|||
@TableName(value = "evaluator_classic_paper_question") |
|||
@EqualsAndHashCode(callSuper = true) |
|||
public class ClassicPaperQuestionEntity extends BaseEntity { |
|||
@TableId(value = "id", type = IdType.ASSIGN_ID) |
|||
@Id |
|||
private Long id; |
|||
|
|||
@Column(name = "paper_id") |
|||
@TableField("paper_id") |
|||
@Comment("套卷ID") |
|||
private Long paperId; |
|||
|
|||
@Column(name = "question_id") |
|||
@TableField("question_id") |
|||
@Comment("题目ID") |
|||
private Long questionId; |
|||
|
|||
@Column(name = "sort_order") |
|||
@TableField("sort_order") |
|||
@Comment("排序序号") |
|||
private Integer sortOrder; |
|||
|
|||
@Column(name = "question_type") |
|||
@TableField("question_type") |
|||
@Comment("题型") |
|||
private Integer questionType; |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
package com.project.classicpaper.domain.enums; |
|||
|
|||
import com.project.base.domain.enums.HasValueEnum; |
|||
import lombok.Getter; |
|||
import lombok.RequiredArgsConstructor; |
|||
|
|||
@RequiredArgsConstructor |
|||
@Getter |
|||
public enum ClassicPaperSourceTypeEnum implements HasValueEnum<Integer> { |
|||
WORD_IMPORT(0, "Word导入"), |
|||
AI_GENERATED(1, "AI生成"); |
|||
|
|||
private final Integer value; |
|||
private final String desc; |
|||
} |
|||
@ -0,0 +1,26 @@ |
|||
package com.project.classicpaper.domain.enums; |
|||
|
|||
import com.project.base.domain.enums.HasValueEnum; |
|||
import lombok.Getter; |
|||
import lombok.RequiredArgsConstructor; |
|||
|
|||
@RequiredArgsConstructor |
|||
@Getter |
|||
public enum ClassicPaperStatusEnum implements HasValueEnum<Integer> { |
|||
GENERATING(0, "生成中"), |
|||
DRAFT(1, "草稿"), |
|||
CONFIRMED(2, "已固化"), |
|||
DISCARDED(3, "已废弃"); |
|||
|
|||
private final Integer value; |
|||
private final String desc; |
|||
|
|||
public static String findByValue(Integer value) { |
|||
for (ClassicPaperStatusEnum e : values()) { |
|||
if (e.value.equals(value)) { |
|||
return e.desc; |
|||
} |
|||
} |
|||
return ""; |
|||
} |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
package com.project.classicpaper.domain.service; |
|||
|
|||
import com.baomidou.mybatisplus.extension.service.IService; |
|||
import com.project.classicpaper.domain.entity.ClassicPaperEntity; |
|||
|
|||
public interface ClassicPaperBaseService extends IService<ClassicPaperEntity> { |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
package com.project.classicpaper.domain.service; |
|||
|
|||
import com.baomidou.mybatisplus.extension.service.IService; |
|||
import com.project.classicpaper.domain.entity.ClassicPaperQuestionEntity; |
|||
|
|||
public interface ClassicPaperQuestionBaseService extends IService<ClassicPaperQuestionEntity> { |
|||
} |
|||
@ -0,0 +1,25 @@ |
|||
package com.project.classicpaper.domain.service; |
|||
|
|||
import com.project.information.domain.entity.KnowledgePointEntity; |
|||
import com.project.question.domain.entity.QuestionEntity; |
|||
import com.project.task.domain.enums.QuestionTypeEnum; |
|||
|
|||
import java.util.List; |
|||
|
|||
/** |
|||
* 经典套卷题目生成器接口 |
|||
* 当前使用降级实现,后续替换为算法服务新接口实现 |
|||
*/ |
|||
public interface ClassicPaperQuestionGenerator { |
|||
|
|||
/** |
|||
* 为经典套卷生成题目 |
|||
* |
|||
* @param knowledgePoints 知识点列表(素材) |
|||
* @param questionType 题型 |
|||
* @param count 生成数量 |
|||
* @return 生成的题目实体列表(已保存到数据库) |
|||
*/ |
|||
List<QuestionEntity> generate(List<KnowledgePointEntity> knowledgePoints, |
|||
QuestionTypeEnum questionType, int count) throws Exception; |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
package com.project.classicpaper.domain.service; |
|||
|
|||
import com.project.base.domain.result.Result; |
|||
import com.project.classicpaper.domain.dto.ClassicPaperDTO; |
|||
import com.project.classicpaper.domain.dto.GenerateClassicPaperRequestDTO; |
|||
|
|||
import java.util.List; |
|||
|
|||
public interface GenerateClassicPaperDomainService { |
|||
|
|||
/** |
|||
* 批量生成经典套题(N个版本) |
|||
*/ |
|||
Result<List<ClassicPaperDTO>> generate(GenerateClassicPaperRequestDTO request) throws Exception; |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
package com.project.classicpaper.domain.service; |
|||
|
|||
import com.project.base.domain.result.Result; |
|||
import com.project.classicpaper.domain.dto.ClassicPaperQuestionDTO; |
|||
|
|||
public interface RegenerateQuestionDomainService { |
|||
|
|||
/** |
|||
* 单题重抽:替换套卷中的某道题 |
|||
* |
|||
* @param paperId 套卷ID |
|||
* @param questionId 原题目ID |
|||
* @return 新题目信息 |
|||
*/ |
|||
Result<ClassicPaperQuestionDTO> regenerate(Long paperId, Long questionId) throws Exception; |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
package com.project.classicpaper.domain.service.impl; |
|||
|
|||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
|||
import com.project.classicpaper.domain.entity.ClassicPaperEntity; |
|||
import com.project.classicpaper.domain.service.ClassicPaperBaseService; |
|||
import com.project.classicpaper.mapper.ClassicPaperMapper; |
|||
import org.springframework.stereotype.Service; |
|||
|
|||
@Service |
|||
public class ClassicPaperBaseServiceImpl extends ServiceImpl<ClassicPaperMapper, ClassicPaperEntity> implements ClassicPaperBaseService { |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
package com.project.classicpaper.domain.service.impl; |
|||
|
|||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
|||
import com.project.classicpaper.domain.entity.ClassicPaperQuestionEntity; |
|||
import com.project.classicpaper.domain.service.ClassicPaperQuestionBaseService; |
|||
import com.project.classicpaper.mapper.ClassicPaperQuestionMapper; |
|||
import org.springframework.stereotype.Service; |
|||
|
|||
@Service |
|||
public class ClassicPaperQuestionBaseServiceImpl extends ServiceImpl<ClassicPaperQuestionMapper, ClassicPaperQuestionEntity> implements ClassicPaperQuestionBaseService { |
|||
} |
|||
@ -0,0 +1,109 @@ |
|||
package com.project.classicpaper.domain.service.impl; |
|||
|
|||
import cn.hutool.core.util.RandomUtil; |
|||
import com.project.base.domain.result.Result; |
|||
import com.project.information.domain.entity.KnowledgePointEntity; |
|||
import com.project.question.domain.dto.QuestionDTO; |
|||
import com.project.question.domain.entity.QuestionEntity; |
|||
import com.project.question.domain.service.SaveQuestionDomainService; |
|||
import com.project.task.domain.enums.QuestionTypeEnum; |
|||
import com.project.classicpaper.domain.service.ClassicPaperQuestionGenerator; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
import java.util.*; |
|||
import java.util.stream.Collectors; |
|||
|
|||
/** |
|||
* 降级实现:生成占位题目 |
|||
* 当算法服务新接口未就绪时使用,后续替换为真正的算法调用 |
|||
*/ |
|||
@Component |
|||
@Slf4j |
|||
public class FallbackClassicPaperQuestionGenerator implements ClassicPaperQuestionGenerator { |
|||
|
|||
@Autowired |
|||
private SaveQuestionDomainService saveQuestionDomainService; |
|||
|
|||
private final String[] optionListStr = {"A", "B", "C", "D"}; |
|||
private final String[] trueFalseListStr = {"A", "B"}; |
|||
private final List<Integer> list = Arrays.asList(0, 1, 2, 3); |
|||
|
|||
@Override |
|||
public List<QuestionEntity> generate(List<KnowledgePointEntity> knowledgePoints, |
|||
QuestionTypeEnum questionType, int count) throws Exception { |
|||
log.info(">>> [经典套题-降级] 开始生成占位题目, 题型: {}, 数量: {}, 知识点数: {}", |
|||
questionType, count, knowledgePoints.size()); |
|||
|
|||
List<QuestionEntity> result = new ArrayList<>(); |
|||
for (int i = 0; i < count; i++) { |
|||
KnowledgePointEntity kp = knowledgePoints.get(i % knowledgePoints.size()); |
|||
|
|||
QuestionDTO questionDTO = new QuestionDTO(); |
|||
questionDTO.setKpIdList(Collections.singletonList(kp.getId())); |
|||
questionDTO.setQuestionType(questionType.getValue()); |
|||
questionDTO.setSourceType(0); |
|||
|
|||
QuestionDTO.QuestionDetailDTO detailDTO = new QuestionDTO.QuestionDetailDTO(); |
|||
questionDTO.setQuestionDetailDTO(detailDTO); |
|||
detailDTO.setQuestionContent(String.format("【经典套题】%s - 第%d题(%s)", |
|||
kp.getParseName(), i + 1, questionType.getDescription())); |
|||
detailDTO.setType(questionType.getValue()); |
|||
|
|||
if (QuestionTypeEnum.SINGLE_CHOICE.equals(questionType)) { |
|||
int rightAnswerNo = RandomUtil.randomInt(0, 4); |
|||
TreeMap<String, String> optionList = new TreeMap<>(); |
|||
for (int j = 0; j < optionListStr.length; j++) { |
|||
optionList.put(optionListStr[j], String.format("选项%s", optionListStr[j])); |
|||
if (j == rightAnswerNo) { |
|||
detailDTO.setRightAnswer(optionListStr[j]); |
|||
detailDTO.setAnalysis(String.format("正确答案是%s", optionListStr[j])); |
|||
} |
|||
} |
|||
detailDTO.setOptions(optionList); |
|||
} else if (QuestionTypeEnum.MULTIPLE_CHOICE.equals(questionType)) { |
|||
Collections.shuffle(list); |
|||
Set<Integer> resultIdx = list.subList(0, 2).stream().collect(Collectors.toSet()); |
|||
TreeMap<String, String> optionList = new TreeMap<>(); |
|||
List<String> rightAnswerList = new ArrayList<>(); |
|||
for (int j = 0; j < optionListStr.length; j++) { |
|||
optionList.put(optionListStr[j], String.format("选项%s", optionListStr[j])); |
|||
if (resultIdx.contains(j)) { |
|||
rightAnswerList.add(optionListStr[j]); |
|||
} |
|||
} |
|||
detailDTO.setRightAnswer(String.join(",", rightAnswerList)); |
|||
detailDTO.setAnalysis(String.format("正确答案是%s", detailDTO.getRightAnswer())); |
|||
detailDTO.setOptions(optionList); |
|||
} else if (QuestionTypeEnum.TRUE_FALSE.equals(questionType)) { |
|||
int rightAnswerNo = RandomUtil.randomInt(0, 2); |
|||
TreeMap<String, String> optionList = new TreeMap<>(); |
|||
for (int j = 0; j < trueFalseListStr.length; j++) { |
|||
optionList.put(trueFalseListStr[j], j == 0 ? "对" : "错"); |
|||
if (j == rightAnswerNo) { |
|||
detailDTO.setRightAnswer(trueFalseListStr[j]); |
|||
detailDTO.setAnalysis(String.format("正确答案是%s", trueFalseListStr[j])); |
|||
} |
|||
} |
|||
detailDTO.setOptions(optionList); |
|||
} else { |
|||
// 简答题
|
|||
detailDTO.setRightAnswer("参考答案"); |
|||
detailDTO.setAnalysis("解析"); |
|||
} |
|||
|
|||
Result<QuestionDTO> saveResult = saveQuestionDomainService.save(questionDTO); |
|||
QuestionDTO saved = saveResult.getData(); |
|||
|
|||
QuestionEntity savedEntity = new QuestionEntity(); |
|||
savedEntity.setId(saved.getId()); |
|||
savedEntity.setQuestionType(questionType.getValue()); |
|||
savedEntity.setKpIdList(saved.getKpIdList()); |
|||
result.add(savedEntity); |
|||
} |
|||
|
|||
log.info(">>> [经典套题-降级] 生成完成, 共{}题", result.size()); |
|||
return result; |
|||
} |
|||
} |
|||
@ -0,0 +1,222 @@ |
|||
package com.project.classicpaper.domain.service.impl; |
|||
|
|||
import cn.hutool.core.collection.CollUtil; |
|||
import cn.hutool.core.util.StrUtil; |
|||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
|||
import com.project.base.config.SnowflakeIdWorker; |
|||
import com.project.base.domain.exception.BusinessErrorException; |
|||
import com.project.base.domain.result.Result; |
|||
import com.project.classicpaper.domain.dto.ClassicPaperDTO; |
|||
import com.project.classicpaper.domain.dto.ClassicPaperQuestionDTO; |
|||
import com.project.classicpaper.domain.dto.GenerateClassicPaperRequestDTO; |
|||
import com.project.classicpaper.domain.entity.ClassicPaperEntity; |
|||
import com.project.classicpaper.domain.entity.ClassicPaperQuestionEntity; |
|||
import com.project.classicpaper.domain.enums.ClassicPaperSourceTypeEnum; |
|||
import com.project.classicpaper.domain.enums.ClassicPaperStatusEnum; |
|||
import com.project.classicpaper.domain.service.*; |
|||
import com.project.information.domain.entity.InformationEntity; |
|||
import com.project.information.domain.entity.KnowledgePointEntity; |
|||
import com.project.information.domain.enums.InformationParseStatusEnum; |
|||
import com.project.information.domain.service.InformationBaseService; |
|||
import com.project.information.domain.service.KnowledgePointBaseService; |
|||
import com.project.question.domain.entity.QuestionEntity; |
|||
import com.project.task.domain.enums.QuestionTypeEnum; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.stereotype.Service; |
|||
import org.springframework.transaction.annotation.Transactional; |
|||
|
|||
import java.util.*; |
|||
import java.util.stream.Collectors; |
|||
|
|||
@Service |
|||
@Slf4j |
|||
public class GenerateClassicPaperDomainServiceImpl implements GenerateClassicPaperDomainService { |
|||
|
|||
@Autowired |
|||
private InformationBaseService informationBaseService; |
|||
|
|||
@Autowired |
|||
private KnowledgePointBaseService knowledgePointBaseService; |
|||
|
|||
@Autowired |
|||
private ClassicPaperBaseService classicPaperBaseService; |
|||
|
|||
@Autowired |
|||
private ClassicPaperQuestionBaseService classicPaperQuestionBaseService; |
|||
|
|||
@Autowired |
|||
private ClassicPaperQuestionGenerator classicPaperQuestionGenerator; |
|||
|
|||
private final SnowflakeIdWorker snowflakeIdWorker = new SnowflakeIdWorker(0, 0); |
|||
|
|||
@Override |
|||
@Transactional(rollbackFor = Exception.class) |
|||
public Result<List<ClassicPaperDTO>> generate(GenerateClassicPaperRequestDTO request) throws Exception { |
|||
// 1. 校验参数
|
|||
validateRequest(request); |
|||
|
|||
// 2. 查询子产品线下已解析成功的资料
|
|||
List<InformationEntity> informations = informationBaseService.list( |
|||
new LambdaQueryWrapper<InformationEntity>() |
|||
.eq(InformationEntity::getSubLineId, request.getSubLineId()) |
|||
.eq(InformationEntity::getParseStatus, InformationParseStatusEnum.Success.getValue()) |
|||
); |
|||
if (CollUtil.isEmpty(informations)) { |
|||
throw new BusinessErrorException("该子产品线下没有已解析成功的资料"); |
|||
} |
|||
|
|||
// 3. 查询这些资料的所有知识点
|
|||
List<Long> informationIds = informations.stream() |
|||
.map(InformationEntity::getId).collect(Collectors.toList()); |
|||
List<KnowledgePointEntity> allKps = knowledgePointBaseService.list( |
|||
new LambdaQueryWrapper<KnowledgePointEntity>() |
|||
.in(KnowledgePointEntity::getInformationId, informationIds) |
|||
); |
|||
if (CollUtil.isEmpty(allKps)) { |
|||
throw new BusinessErrorException("该子产品线下没有知识点数据"); |
|||
} |
|||
|
|||
// 4. 计算总题目数并校验知识点数量
|
|||
int totalPerSet = Optional.ofNullable(request.getSingleChoiceNum()).orElse(0) |
|||
+ Optional.ofNullable(request.getMultipleChoiceNum()).orElse(0) |
|||
+ Optional.ofNullable(request.getTrueFalseNum()).orElse(0) |
|||
+ Optional.ofNullable(request.getShortAnswerNum()).orElse(0); |
|||
if (totalPerSet <= 0) { |
|||
throw new BusinessErrorException("至少需要一种题型的数量大于0"); |
|||
} |
|||
int setCount = request.getSetCount(); |
|||
if (allKps.size() < totalPerSet) { |
|||
throw new BusinessErrorException("知识点数量(" + allKps.size() + ")不足以生成每套 " + totalPerSet + " 道题"); |
|||
} |
|||
|
|||
// 5. 创建 paperGroupId
|
|||
Long paperGroupId = snowflakeIdWorker.nextId(); |
|||
|
|||
// 6. 构建题型配置列表
|
|||
List<QuestionTypeConfig> typeConfigs = buildTypeConfigs(request); |
|||
|
|||
// 7. 循环生成 N 个版本
|
|||
List<ClassicPaperDTO> paperDTOs = new ArrayList<>(); |
|||
for (int i = 1; i <= setCount; i++) { |
|||
ClassicPaperDTO paperDTO = generateOnePaper(paperGroupId, i, request, allKps, typeConfigs); |
|||
paperDTOs.add(paperDTO); |
|||
} |
|||
|
|||
log.info(">>> [经典套题] 批量生成完成, paperGroupId={}, 版本数={}, 每套题数={}", |
|||
paperGroupId, setCount, totalPerSet); |
|||
return Result.success(paperDTOs); |
|||
} |
|||
|
|||
private void validateRequest(GenerateClassicPaperRequestDTO request) { |
|||
if (request.getSubLineId() == null) { |
|||
throw new BusinessErrorException("子产品线ID不能为空"); |
|||
} |
|||
if (request.getClassicCategoryId() == null) { |
|||
throw new BusinessErrorException("经典分类不能为空"); |
|||
} |
|||
if (request.getSetCount() == null || request.getSetCount() < 1 || request.getSetCount() > 5) { |
|||
throw new BusinessErrorException("版本数必须在1~5之间"); |
|||
} |
|||
if (StrUtil.isBlank(request.getNamePrefix())) { |
|||
throw new BusinessErrorException("套卷名称前缀不能为空"); |
|||
} |
|||
} |
|||
|
|||
private List<QuestionTypeConfig> buildTypeConfigs(GenerateClassicPaperRequestDTO request) { |
|||
List<QuestionTypeConfig> configs = new ArrayList<>(); |
|||
if (Optional.ofNullable(request.getSingleChoiceNum()).orElse(0) > 0) { |
|||
configs.add(new QuestionTypeConfig(QuestionTypeEnum.SINGLE_CHOICE, request.getSingleChoiceNum())); |
|||
} |
|||
if (Optional.ofNullable(request.getMultipleChoiceNum()).orElse(0) > 0) { |
|||
configs.add(new QuestionTypeConfig(QuestionTypeEnum.MULTIPLE_CHOICE, request.getMultipleChoiceNum())); |
|||
} |
|||
if (Optional.ofNullable(request.getTrueFalseNum()).orElse(0) > 0) { |
|||
configs.add(new QuestionTypeConfig(QuestionTypeEnum.TRUE_FALSE, request.getTrueFalseNum())); |
|||
} |
|||
if (Optional.ofNullable(request.getShortAnswerNum()).orElse(0) > 0) { |
|||
configs.add(new QuestionTypeConfig(QuestionTypeEnum.SHORT_ANSWER, request.getShortAnswerNum())); |
|||
} |
|||
return configs; |
|||
} |
|||
|
|||
/** |
|||
* 生成一个版本的套卷 |
|||
*/ |
|||
private ClassicPaperDTO generateOnePaper(Long paperGroupId, int setIndex, |
|||
GenerateClassicPaperRequestDTO request, |
|||
List<KnowledgePointEntity> allKps, |
|||
List<QuestionTypeConfig> typeConfigs) throws Exception { |
|||
// 创建套卷实体
|
|||
ClassicPaperEntity paper = new ClassicPaperEntity(); |
|||
paper.setName(request.getNamePrefix() + "-V" + setIndex); |
|||
paper.setDescription(request.getDescription()); |
|||
paper.setSourceType(ClassicPaperSourceTypeEnum.AI_GENERATED.getValue()); |
|||
paper.setSubLineId(request.getSubLineId()); |
|||
paper.setClassicCategoryId(request.getClassicCategoryId()); |
|||
paper.setStatus(ClassicPaperStatusEnum.DRAFT.getValue()); |
|||
paper.setPaperGroupId(paperGroupId); |
|||
paper.setSetIndex(setIndex); |
|||
paper.setQuestionCount(0); |
|||
classicPaperBaseService.save(paper); |
|||
|
|||
// 打乱知识点顺序,每个版本用不同的排列
|
|||
List<KnowledgePointEntity> shuffledKps = new ArrayList<>(allKps); |
|||
Collections.shuffle(shuffledKps); |
|||
|
|||
int totalQuestions = 0; |
|||
int sortOrder = 1; |
|||
List<ClassicPaperQuestionEntity> paperQuestionEntities = new ArrayList<>(); |
|||
|
|||
// 对每种题型生成题目
|
|||
for (QuestionTypeConfig config : typeConfigs) { |
|||
// 从知识点池中采样(不同版本使用不同组合)
|
|||
List<KnowledgePointEntity> sampledKps = sampleKps(shuffledKps, config.count); |
|||
|
|||
List<QuestionEntity> questions = classicPaperQuestionGenerator.generate( |
|||
sampledKps, config.questionType, config.count); |
|||
|
|||
for (QuestionEntity question : questions) { |
|||
ClassicPaperQuestionEntity pq = new ClassicPaperQuestionEntity(); |
|||
pq.setPaperId(paper.getId()); |
|||
pq.setQuestionId(question.getId()); |
|||
pq.setSortOrder(sortOrder++); |
|||
pq.setQuestionType(config.questionType.getValue()); |
|||
paperQuestionEntities.add(pq); |
|||
totalQuestions++; |
|||
} |
|||
} |
|||
|
|||
// 批量保存关联关系
|
|||
classicPaperQuestionBaseService.saveBatch(paperQuestionEntities); |
|||
|
|||
// 更新题目总数
|
|||
paper.setQuestionCount(totalQuestions); |
|||
classicPaperBaseService.updateById(paper); |
|||
|
|||
// 构建返回 DTO
|
|||
ClassicPaperDTO dto = paper.toDTO(ClassicPaperDTO::new); |
|||
dto.setStatusText(ClassicPaperStatusEnum.DRAFT.getDesc()); |
|||
return dto; |
|||
} |
|||
|
|||
/** |
|||
* 从知识点池中采样指定数量的知识点 |
|||
*/ |
|||
private List<KnowledgePointEntity> sampleKps(List<KnowledgePointEntity> pool, int count) { |
|||
if (pool.size() <= count) { |
|||
return new ArrayList<>(pool); |
|||
} |
|||
return new ArrayList<>(pool.subList(0, count)); |
|||
} |
|||
|
|||
private static class QuestionTypeConfig { |
|||
final QuestionTypeEnum questionType; |
|||
final int count; |
|||
|
|||
QuestionTypeConfig(QuestionTypeEnum questionType, int count) { |
|||
this.questionType = questionType; |
|||
this.count = count; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,124 @@ |
|||
package com.project.classicpaper.domain.service.impl; |
|||
|
|||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
|||
import com.project.base.domain.exception.BusinessErrorException; |
|||
import com.project.base.domain.result.Result; |
|||
import com.project.classicpaper.domain.dto.ClassicPaperQuestionDTO; |
|||
import com.project.classicpaper.domain.entity.ClassicPaperEntity; |
|||
import com.project.classicpaper.domain.entity.ClassicPaperQuestionEntity; |
|||
import com.project.classicpaper.domain.enums.ClassicPaperStatusEnum; |
|||
import com.project.classicpaper.domain.service.ClassicPaperBaseService; |
|||
import com.project.classicpaper.domain.service.ClassicPaperQuestionBaseService; |
|||
import com.project.classicpaper.domain.service.ClassicPaperQuestionGenerator; |
|||
import com.project.classicpaper.domain.service.RegenerateQuestionDomainService; |
|||
import com.project.information.domain.entity.KnowledgePointEntity; |
|||
import com.project.information.domain.service.KnowledgePointBaseService; |
|||
import com.project.question.domain.entity.QuestionEntity; |
|||
import com.project.question.domain.entity.QuestionKpRelEntity; |
|||
import com.project.question.domain.service.QuestionBaseService; |
|||
import com.project.question.domain.service.QuestionKpRelBaseService; |
|||
import com.project.task.domain.enums.QuestionTypeEnum; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.stereotype.Service; |
|||
import org.springframework.transaction.annotation.Transactional; |
|||
|
|||
import java.util.Collections; |
|||
import java.util.List; |
|||
import java.util.stream.Collectors; |
|||
|
|||
@Service |
|||
@Slf4j |
|||
public class RegenerateQuestionDomainServiceImpl implements RegenerateQuestionDomainService { |
|||
|
|||
@Autowired |
|||
private ClassicPaperBaseService classicPaperBaseService; |
|||
|
|||
@Autowired |
|||
private ClassicPaperQuestionBaseService classicPaperQuestionBaseService; |
|||
|
|||
@Autowired |
|||
private QuestionBaseService questionBaseService; |
|||
|
|||
@Autowired |
|||
private QuestionKpRelBaseService questionKpRelBaseService; |
|||
|
|||
@Autowired |
|||
private KnowledgePointBaseService knowledgePointBaseService; |
|||
|
|||
@Autowired |
|||
private ClassicPaperQuestionGenerator classicPaperQuestionGenerator; |
|||
|
|||
@Override |
|||
@Transactional(rollbackFor = Exception.class) |
|||
public Result<ClassicPaperQuestionDTO> regenerate(Long paperId, Long questionId) throws Exception { |
|||
// 1. 校验套卷存在且为草稿状态
|
|||
ClassicPaperEntity paper = classicPaperBaseService.getById(paperId); |
|||
if (paper == null) { |
|||
throw new BusinessErrorException("套卷不存在"); |
|||
} |
|||
if (!ClassicPaperStatusEnum.DRAFT.getValue().equals(paper.getStatus())) { |
|||
throw new BusinessErrorException("只有草稿状态的套卷才能重抽题目"); |
|||
} |
|||
|
|||
// 2. 校验题目属于该套卷
|
|||
ClassicPaperQuestionEntity paperQuestion = classicPaperQuestionBaseService.getOne( |
|||
new LambdaQueryWrapper<ClassicPaperQuestionEntity>() |
|||
.eq(ClassicPaperQuestionEntity::getPaperId, paperId) |
|||
.eq(ClassicPaperQuestionEntity::getQuestionId, questionId) |
|||
); |
|||
if (paperQuestion == null) { |
|||
throw new BusinessErrorException("该题目不属于此套卷"); |
|||
} |
|||
|
|||
// 3. 查询原题目信息
|
|||
QuestionEntity originalQuestion = questionBaseService.getById(questionId); |
|||
if (originalQuestion == null) { |
|||
throw new BusinessErrorException("原题目不存在"); |
|||
} |
|||
|
|||
// 4. 查询原题目的知识点关联
|
|||
List<QuestionKpRelEntity> kpRels = questionKpRelBaseService.list( |
|||
new LambdaQueryWrapper<QuestionKpRelEntity>() |
|||
.eq(QuestionKpRelEntity::getQuestionId, questionId) |
|||
); |
|||
if (kpRels.isEmpty()) { |
|||
throw new BusinessErrorException("原题目没有关联知识点,无法重抽"); |
|||
} |
|||
List<Long> kpIds = kpRels.stream() |
|||
.map(QuestionKpRelEntity::getKpId).collect(Collectors.toList()); |
|||
|
|||
// 5. 查询知识点详情
|
|||
List<KnowledgePointEntity> knowledgePoints = knowledgePointBaseService.listByIds(kpIds); |
|||
if (knowledgePoints.isEmpty()) { |
|||
throw new BusinessErrorException("关联知识点数据不存在"); |
|||
} |
|||
|
|||
// 6. 调用生成器生成新题
|
|||
QuestionTypeEnum questionType = QuestionTypeEnum.findByValue(originalQuestion.getQuestionType()); |
|||
List<QuestionEntity> newQuestions = classicPaperQuestionGenerator.generate( |
|||
knowledgePoints, questionType, 1); |
|||
if (newQuestions.isEmpty()) { |
|||
throw new BusinessErrorException("生成新题失败"); |
|||
} |
|||
QuestionEntity newQuestion = newQuestions.get(0); |
|||
|
|||
// 7. 更新关联关系,指向新题
|
|||
paperQuestion.setQuestionId(newQuestion.getId()); |
|||
classicPaperQuestionBaseService.updateById(paperQuestion); |
|||
|
|||
log.info(">>> [经典套题-重抽] 套卷{} 题目{} -> 新题目{}", paperId, questionId, newQuestion.getId()); |
|||
|
|||
// 8. 构建返回
|
|||
ClassicPaperQuestionDTO dto = new ClassicPaperQuestionDTO(); |
|||
dto.setId(paperQuestion.getId()); |
|||
dto.setPaperId(paperId); |
|||
dto.setQuestionId(newQuestion.getId()); |
|||
dto.setSortOrder(paperQuestion.getSortOrder()); |
|||
dto.setQuestionType(paperQuestion.getQuestionType()); |
|||
if (newQuestion.getQuestionDetail() != null) { |
|||
dto.setQuestionDetail(newQuestion.getQuestionDetail()); |
|||
} |
|||
return Result.success(dto); |
|||
} |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
package com.project.classicpaper.mapper; |
|||
|
|||
import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
|||
import com.project.classicpaper.domain.entity.ClassicPaperEntity; |
|||
import org.apache.ibatis.annotations.Mapper; |
|||
|
|||
@Mapper |
|||
public interface ClassicPaperMapper extends BaseMapper<ClassicPaperEntity> { |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
package com.project.classicpaper.mapper; |
|||
|
|||
import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
|||
import com.project.classicpaper.domain.entity.ClassicPaperQuestionEntity; |
|||
import org.apache.ibatis.annotations.Mapper; |
|||
|
|||
@Mapper |
|||
public interface ClassicPaperQuestionMapper extends BaseMapper<ClassicPaperQuestionEntity> { |
|||
} |
|||
Loading…
Reference in new issue