From d68b60e96ceee848ecd4e83a96192103b36d8d7f Mon Sep 17 00:00:00 2001 From: luoweijian <1329394916@qq.com> Date: Wed, 8 Jul 2026 14:57:41 +0800 Subject: [PATCH] =?UTF-8?q?bug=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RegenerateQuestionDomainServiceImpl.java | 90 ++++++++++++------- 1 file changed, 59 insertions(+), 31 deletions(-) diff --git a/src/main/java/com/project/classicpaper/domain/service/impl/RegenerateQuestionDomainServiceImpl.java b/src/main/java/com/project/classicpaper/domain/service/impl/RegenerateQuestionDomainServiceImpl.java index 8ded339..003f67b 100644 --- a/src/main/java/com/project/classicpaper/domain/service/impl/RegenerateQuestionDomainServiceImpl.java +++ b/src/main/java/com/project/classicpaper/domain/service/impl/RegenerateQuestionDomainServiceImpl.java @@ -79,6 +79,9 @@ public class RegenerateQuestionDomainServiceImpl implements RegenerateQuestionDo @Value("${classicpaper.spare.replenish-delay-ms:10000}") private long replenishDelayMs; + @Value("${classicpaper.regenerate.timeout-minutes:20}") + private int regenerateTimeoutMinutes; + @Override @Transactional(rollbackFor = Exception.class) public Result regenerate(Long paperId, Long paperQuestionId) throws Exception { @@ -206,13 +209,52 @@ public class RegenerateQuestionDomainServiceImpl implements RegenerateQuestionDo .eq(RegenerateQuestionTaskEntity::getPaperQuestionId, paperQuestionId) .eq(RegenerateQuestionTaskEntity::getStatus, 0)); if (existingTask != null) { - // 已有任务正在生题中,先把 questionId 置空,避免前端看到旧题 - paperQuestion.setQuestionId(null); - classicPaperQuestionBaseService.updateById(paperQuestion); - throw new BusinessErrorException("该题目正在重新生题中,请稍后再试"); + // 先把 questionId 置空,避免前端看到旧题(MyBatis-Plus updateById 忽略 null,需用 lambdaUpdate) + classicPaperQuestionBaseService.lambdaUpdate() + .set(ClassicPaperQuestionEntity::getQuestionId, null) + .eq(ClassicPaperQuestionEntity::getId, paperQuestionId) + .update(); + + // 检查是否超时,超时则重新发 + long elapsed = System.currentTimeMillis() - existingTask.getCreateTime().getTime(); + if (elapsed > regenerateTimeoutMinutes * 60 * 1000L) { + log.info(">>> [经典套题-重新生题-异步] 旧任务超时,重新发起, paperQuestionId={}, 已耗时={}ms", + paperQuestionId, elapsed); + // 标记旧任务为失败 + existingTask.setStatus(2); + existingTask.setErrorMessage("超时重发"); + regenerateQuestionTaskBaseService.updateById(existingTask); + // 不返回,继续往下走创建新任务 + } else { + throw new BusinessErrorException("该题目正在重新生题中,请稍后再试"); + } + } + + // 3. 在置空前先查好原题数据 + Long originalQuestionId = paperQuestion.getQuestionId(); + if (originalQuestionId == null) { + throw new BusinessErrorException("原题目不存在"); + } + QuestionEntity originalQuestion = questionBaseService.getById(originalQuestionId); + if (originalQuestion == null) { + throw new BusinessErrorException("原题目不存在"); + } + + List kpRels = questionKpRelBaseService.list( + new LambdaQueryWrapper() + .eq(QuestionKpRelEntity::getQuestionId, originalQuestionId)); + if (kpRels.isEmpty()) { + throw new BusinessErrorException("原题目没有关联知识点,无法重新生题"); } + List kpIds = kpRels.stream() + .map(QuestionKpRelEntity::getKpId).collect(Collectors.toList()); + List knowledgePoints = knowledgePointBaseService.listByIds(kpIds); + if (knowledgePoints.isEmpty()) { + throw new BusinessErrorException("关联知识点数据不存在"); + } + QuestionTypeEnum questionType = QuestionTypeEnum.findByValue(originalQuestion.getQuestionType()); - // 3. 创建任务记录 + // 4. 创建任务记录 String taskId = UUID.randomUUID().toString().replace("-", ""); RegenerateQuestionTaskEntity taskEntity = new RegenerateQuestionTaskEntity(); taskEntity.setTaskId(taskId); @@ -221,39 +263,25 @@ public class RegenerateQuestionDomainServiceImpl implements RegenerateQuestionDo taskEntity.setStatus(0); // 进行中 regenerateQuestionTaskBaseService.save(taskEntity); - // 4. 清空 questionId,让回调走提拔分支 - paperQuestion.setQuestionId(null); - classicPaperQuestionBaseService.updateById(paperQuestion); + // 5. 清空 questionId,让回调走提拔分支(MyBatis-Plus updateById 忽略 null,需用 lambdaUpdate) + classicPaperQuestionBaseService.lambdaUpdate() + .set(ClassicPaperQuestionEntity::getQuestionId, null) + .eq(ClassicPaperQuestionEntity::getId, paperQuestionId) + .update(); - // 5. 异步执行重新生题逻辑(回调会提拔新题 + 更新 task 状态) - CompletableFuture.runAsync(() -> doRegenerateAsync(taskId, paperQuestionId), regenerateExecutor); + // 6. 异步执行重新生题逻辑(回调会提拔新题 + 更新 task 状态) + Long clusterId = knowledgePoints.get(0).getClusterId(); + CompletableFuture.runAsync(() -> doRegenerateAsync(taskId, paperQuestionId, knowledgePoints, questionType, clusterId), regenerateExecutor); log.info(">>> [经典套题-重新生题-异步] 任务已提交, taskId={}, paperId={}, paperQuestionId={}", taskId, paperId, paperQuestionId); } - private void doRegenerateAsync(String taskId, Long paperQuestionId) { + private void doRegenerateAsync(String taskId, Long paperQuestionId, + List knowledgePoints, + QuestionTypeEnum questionType, Long clusterId) { try { - // 1. 查询关联记录和原题 - ClassicPaperQuestionEntity paperQuestion = classicPaperQuestionBaseService.getById(paperQuestionId); - Long questionId = paperQuestion.getQuestionId(); - QuestionEntity originalQuestion = questionBaseService.getById(questionId); - - // 2. 查询知识点 - List kpRels = questionKpRelBaseService.list( - new LambdaQueryWrapper() - .eq(QuestionKpRelEntity::getQuestionId, questionId)); - List kpIds = kpRels.stream() - .map(QuestionKpRelEntity::getKpId).collect(Collectors.toList()); - List knowledgePoints = knowledgePointBaseService.listByIds(kpIds); - if (knowledgePoints.isEmpty()) { - throw new BusinessErrorException("关联知识点数据不存在"); - } - - // 异步提交生题任务(回调会提拔新题 + 更新 task 状态) - QuestionTypeEnum questionType = QuestionTypeEnum.findByValue(originalQuestion.getQuestionType()); - Long clusterId = knowledgePoints.get(0).getClusterId(); classicPaperQuestionGenerator.generateAsync( - paperQuestionId, knowledgePoints, questionType, 1, clusterId); + paperQuestionId, knowledgePoints, questionType, replenishCount, clusterId); log.info(">>> [经典套题-重新生题-异步] 已提交算法, taskId={}, paperQuestionId={}, 题型={}", taskId, paperQuestionId, questionType);