From e5a2bd740fabaa19d59744c6b9bcb6863ec28f6f Mon Sep 17 00:00:00 2001 From: chenyuan Date: Wed, 14 Oct 2026 18:02:11 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20AI=E8=AF=84=E5=88=86=E5=90=8E=E6=95=99?= =?UTF-8?q?=E5=B8=88=E7=AB=AF=E6=88=90=E7=BB=A9=E5=88=97=E8=A1=A8=E5=BB=B6?= =?UTF-8?q?=E8=BF=9F~24=E5=B0=8F=E6=97=B6=E6=89=8D=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E2=80=94=E2=80=94=E9=87=8D=E8=AF=84claim=E7=9A=84=E5=BF=AB?= =?UTF-8?q?=E7=85=A7BINARY=E9=95=BF=E6=96=87=E6=9C=AC=E6=AF=94=E5=AF=B9?= =?UTF-8?q?=E5=A4=B1=E6=95=88=E5=AF=BC=E8=87=B4=E9=87=8D=E8=AF=84=E8=A2=AB?= =?UTF-8?q?=E9=9D=99=E9=BB=98=E8=B7=B3=E8=BF=87=EF=BC=8C=E7=A7=BB=E9=99=A4?= =?UTF-8?q?=E8=AF=A5=E6=9D=A1=E4=BB=B6=EF=BC=88=E5=BF=AB=E7=85=A7=E5=8F=98?= =?UTF-8?q?=E5=8C=96=E5=B7=B2=E5=9C=A8Java=E4=BE=A7=E5=88=A4=E6=96=AD?= =?UTF-8?q?=EF=BC=89=EF=BC=9BAI=E8=AF=84=E5=88=86=E8=90=BD=E5=BA=93?= =?UTF-8?q?=E5=90=8E=E5=BC=82=E6=AD=A5=E9=87=8D=E5=BB=BA=E6=9C=AC=E6=95=99?= =?UTF-8?q?=E5=AD=A6=E7=8F=ADstu=5Frank=E5=BD=93=E6=97=A5=E5=BF=AB?= =?UTF-8?q?=E7=85=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/AiTrainingEvaluationServiceImpl.java | 30 +++++++++++++++++++ .../mappers/AiTrainingEvaluationMapper.xml | 1 - 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/sztzjy/linkCommerce/service/impl/AiTrainingEvaluationServiceImpl.java b/src/main/java/com/sztzjy/linkCommerce/service/impl/AiTrainingEvaluationServiceImpl.java index 004dd86..1d5b440 100644 --- a/src/main/java/com/sztzjy/linkCommerce/service/impl/AiTrainingEvaluationServiceImpl.java +++ b/src/main/java/com/sztzjy/linkCommerce/service/impl/AiTrainingEvaluationServiceImpl.java @@ -20,6 +20,7 @@ import com.sztzjy.linkCommerce.mapper.TeachingClassStudentMapper; import com.sztzjy.linkCommerce.mapper.TrainingTaskMapper; import com.sztzjy.linkCommerce.mapper.TrainingTaskClassConfigMapper; import com.sztzjy.linkCommerce.service.AiTrainingEvaluationService; +import com.sztzjy.linkCommerce.service.ScoreRankService; import com.sztzjy.linkCommerce.service.TrainingKnowledgeService; import com.sztzjy.linkCommerce.training.knowledge.EffectiveTrainingTaskContent; import lombok.extern.slf4j.Slf4j; @@ -35,6 +36,7 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.UUID; +import java.util.concurrent.CompletableFuture; @Slf4j @Service @@ -63,6 +65,8 @@ public class AiTrainingEvaluationServiceImpl implements AiTrainingEvaluationServ public StudentTrainingAnswerMapper studentTrainingAnswerMapper; @Autowired public TeachingClassStudentMapper teachingClassStudentMapper; + @Autowired + public ScoreRankService scoreRankService; @Autowired(required = false) public TrainingTaskClassConfigMapper trainingTaskClassConfigMapper; @Autowired(required = false) @@ -129,6 +133,7 @@ public class AiTrainingEvaluationServiceImpl implements AiTrainingEvaluationServ EvaluationContext context = resolveContext(taskKey, user, true); AiTrainingEvaluation evaluation = getOrCreate(context, user); if (PROCESSING.equals(evaluation.getAssessmentStatus()) && !isProcessingTimedOut(evaluation)) { + log.info("AI assessment still processing, evaluationId={}", evaluation.getId()); return toView(evaluation); } String answerSnapshot = answerSnapshot(context.answer); @@ -145,6 +150,8 @@ public class AiTrainingEvaluationServiceImpl implements AiTrainingEvaluationServ ? aiTrainingEvaluationMapper.claimReassessment(evaluation.getId(), evaluation.getAssessmentAnswerSnapshot(), new Date()) : aiTrainingEvaluationMapper.claimAssessment(evaluation.getId(), new Date()); if (claimed != 1) { + log.info("AI assessment claim skipped, evaluationId={}, reassessment={}, claimed={}", + evaluation.getId(), reassessment, claimed); return currentView(context, user); } @@ -171,6 +178,9 @@ public class AiTrainingEvaluationServiceImpl implements AiTrainingEvaluationServ completed.setAssessmentCompletedAt(completedAt); completed.setUpdateTime(completedAt); completeAssessmentAndWriteScore(completed, context.answer.getId(), score, completedAt); + // 教师端成绩列表读的是 stu_rank 每日快照(凌晨1点定时重建), + // 不在这里立即刷新本班快照,新 AI 分数要等次日才会出现在教师端。 + refreshScoreRankAfterAssessment(user, context.teachingClassId); completed.setHelpStatus(evaluation.getHelpStatus()); completed.setAssessmentStatus(SUCCEEDED); return toView(completed); @@ -215,6 +225,26 @@ public class AiTrainingEvaluationServiceImpl implements AiTrainingEvaluationServ }); } + /** + * AI 分数落库后立即重建本教学班的 stu_rank 当日快照(与每日凌晨定时重建同一套逻辑), + * 教师端成绩列表马上能看到新分数。异步执行且失败只记日志:排名刷新失败不能影响评分结果。 + */ + private void refreshScoreRankAfterAssessment(JwtUser user, String teachingClassId) { + String schoolId = user == null ? null : user.getSchoolId(); + if (scoreRankService == null || StringUtils.isAnyBlank(schoolId, teachingClassId)) { + return; + } + CompletableFuture.runAsync(() -> { + try { + if (!scoreRankService.doRankTeachingClass(schoolId, teachingClassId)) { + scoreRankService.doRankOne(schoolId); + } + } catch (RuntimeException e) { + log.warn("AI assessment score rank refresh failed, teachingClassId={}", teachingClassId, e); + } + }); + } + private AiTrainingEvaluation getOrCreate(EvaluationContext context, JwtUser user) { AiTrainingEvaluation evaluation = aiTrainingEvaluationMapper.findByStudentClassAndTask( user.getUserId(), context.teachingClassId, context.task.getId()); diff --git a/src/main/resources/mappers/AiTrainingEvaluationMapper.xml b/src/main/resources/mappers/AiTrainingEvaluationMapper.xml index 82fff32..14b188f 100644 --- a/src/main/resources/mappers/AiTrainingEvaluationMapper.xml +++ b/src/main/resources/mappers/AiTrainingEvaluationMapper.xml @@ -78,7 +78,6 @@ SET assessment_status = 'PROCESSING', assessment_error_message = NULL, update_time = #{updateTime,jdbcType=TIMESTAMP} WHERE id = #{id,jdbcType=VARCHAR} AND assessment_status = 'SUCCEEDED' - AND (BINARY assessment_answer_snapshot <=> BINARY #{expectedAnswerSnapshot,jdbcType=LONGVARCHAR})