From 868e0bb7bdfb483453353d0d9289ba99e01b24f2 Mon Sep 17 00:00:00 2001 From: lbw <1192299468@qq.com> Date: Wed, 31 Dec 2025 15:41:53 +0800 Subject: [PATCH] =?UTF-8?q?feat(plan):=20=E6=94=AF=E6=8C=81=E5=AD=A6?= =?UTF-8?q?=E6=A1=88=E7=94=9F=E6=88=90=E7=8A=B6=E6=80=81=E8=BD=AE=E8=AF=A2?= =?UTF-8?q?=E4=B8=8E=E8=BF=9B=E5=BA=A6=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增接口检查学案是否正在生成,防止重复生成任务 - 使用 Redis 缓存标识学案生成状态,设置 12 分钟过期时间 - 生成学案时记录状态至 Redis,生成完成后自动清除 - Vue 学案列表新增学案生成进度条显示与已生成标签 - 新增组件事件监听生成成功,触发轮询检测学案状态 - 轮询间隔 10 秒,动态更新学案生成进度,最高至 95% - 路由离开与组件卸载时停止所有轮询,防止内存泄漏 - 优化学案生成逻辑,新增小测试卷自动关联及数据入库 - 更新配置文件模板路径,提高文档管理一致性 --- .../service/constant/LessonPlanConstant.java | 19 +++-- .../controller/LessonPlanController.java | 21 +++++ .../vo/plan/FindIsGeneratePlanReqVO.java | 15 ++++ .../service/plan/LessonPlansServiceImpl.java | 43 ++++++++++- .../main/resources/config/application-dev.yml | 2 +- .../templates/study_plan_review_v2.docx | Bin 0 -> 24798 bytes enlish-vue/src/api/plan.js | 6 ++ .../layouts/components/LessonPlanDialog.vue | 3 +- enlish-vue/src/pages/LearningPlan.vue | 2 - enlish-vue/src/pages/class.vue | 72 +++++++++++++++++- 10 files changed, 167 insertions(+), 16 deletions(-) create mode 100644 enlish-service/src/main/java/com/yinlihupo/enlish/service/model/vo/plan/FindIsGeneratePlanReqVO.java create mode 100644 enlish-service/src/main/resources/templates/study_plan_review_v2.docx diff --git a/enlish-service/src/main/java/com/yinlihupo/enlish/service/constant/LessonPlanConstant.java b/enlish-service/src/main/java/com/yinlihupo/enlish/service/constant/LessonPlanConstant.java index 5addc7f..557df22 100644 --- a/enlish-service/src/main/java/com/yinlihupo/enlish/service/constant/LessonPlanConstant.java +++ b/enlish-service/src/main/java/com/yinlihupo/enlish/service/constant/LessonPlanConstant.java @@ -1,10 +1,17 @@ package com.yinlihupo.enlish.service.constant; -public interface LessonPlanConstant { +public class LessonPlanConstant { - String TITLE = "Title"; - String PASSAGE = "ThePassage"; - String QUIZ = "Quiz"; - String ANSWER_KEY_EXPLANATION = "AnswerKey&Explanation"; - String FULL_TRANSLATION = "FullTranslation"; + public static final String TITLE = "Title"; + public static final String PASSAGE = "ThePassage"; + public static final String QUIZ = "Quiz"; + public static final String ANSWER_KEY_EXPLANATION = "AnswerKey&Explanation"; + public static final String FULL_TRANSLATION = "FullTranslation"; + + // 正在生成学案标识 + public static final String GENERATING_PLAN = "GeneratingPlan"; + + public static String buildGeneratePlanContent(Integer studentId) { + return GENERATING_PLAN + ":" + studentId; + } } diff --git a/enlish-service/src/main/java/com/yinlihupo/enlish/service/controller/LessonPlanController.java b/enlish-service/src/main/java/com/yinlihupo/enlish/service/controller/LessonPlanController.java index c2249c3..ca0f0fa 100644 --- a/enlish-service/src/main/java/com/yinlihupo/enlish/service/controller/LessonPlanController.java +++ b/enlish-service/src/main/java/com/yinlihupo/enlish/service/controller/LessonPlanController.java @@ -1,5 +1,6 @@ package com.yinlihupo.enlish.service.controller; +import com.yinlihupo.enlish.service.constant.LessonPlanConstant; import com.yinlihupo.enlish.service.domain.dataobject.LessonPlansDO; import com.yinlihupo.enlish.service.domain.dataobject.VocabularyBankDO; import com.yinlihupo.enlish.service.model.vo.plan.*; @@ -13,6 +14,7 @@ import jakarta.annotation.Resource; import jakarta.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.redis.core.RedisTemplate; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; @@ -30,6 +32,9 @@ public class LessonPlanController { @Resource private LessonPlansService lessonPlanService; + @Resource + private RedisTemplate redisTemplate; + @Resource(name = "taskExecutor") private Executor taskExecutor; @Resource @@ -47,6 +52,9 @@ public class LessonPlanController { Integer unitId = addLessonPlanReqVO.getUnitId(); Integer wordSize = addLessonPlanReqVO.getWordSize(); try { + if (redisTemplate.opsForValue().get(LessonPlanConstant.buildGeneratePlanContent(studentId)) != null) { + throw new RuntimeException("学案正常生成中"); + } taskExecutor.execute(() -> lessonPlanService.generateLessonPlans(studentId, unitId, wordSize)); return Response.success("生成学案成功,请等待 10 分钟"); } catch (Exception e) { @@ -96,4 +104,17 @@ public class LessonPlanController { public void findPlanWordVoiceTTS(@RequestBody FindWordTTSVoiceReqVO findWordVoiceReqVO, HttpServletResponse response) { ttsUtil.generateWordVoice(findWordVoiceReqVO.getText(), response); } + + @PostMapping("check") + @ApiOperationLog(description = "检测学案是否在生成") + public Response checkLessonPlan(@RequestBody FindIsGeneratePlanReqVO findIsGeneratePlanReqVO) { + Integer studentId = findIsGeneratePlanReqVO.getStudentId(); + String key = LessonPlanConstant.buildGeneratePlanContent(studentId); + if (redisTemplate.opsForValue().get(key) != null) { + return Response.fail(); + } + return Response.success("学案生成完成"); + } + + } diff --git a/enlish-service/src/main/java/com/yinlihupo/enlish/service/model/vo/plan/FindIsGeneratePlanReqVO.java b/enlish-service/src/main/java/com/yinlihupo/enlish/service/model/vo/plan/FindIsGeneratePlanReqVO.java new file mode 100644 index 0000000..3c167c8 --- /dev/null +++ b/enlish-service/src/main/java/com/yinlihupo/enlish/service/model/vo/plan/FindIsGeneratePlanReqVO.java @@ -0,0 +1,15 @@ +package com.yinlihupo.enlish.service.model.vo.plan; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@AllArgsConstructor +@NoArgsConstructor +@Data +@Builder +public class FindIsGeneratePlanReqVO { + + private Integer studentId; +} diff --git a/enlish-service/src/main/java/com/yinlihupo/enlish/service/service/plan/LessonPlansServiceImpl.java b/enlish-service/src/main/java/com/yinlihupo/enlish/service/service/plan/LessonPlansServiceImpl.java index 7ff086d..675ff05 100644 --- a/enlish-service/src/main/java/com/yinlihupo/enlish/service/service/plan/LessonPlansServiceImpl.java +++ b/enlish-service/src/main/java/com/yinlihupo/enlish/service/service/plan/LessonPlansServiceImpl.java @@ -12,12 +12,14 @@ import com.yinlihupo.framework.common.util.JsonUtils; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.checkerframework.checker.nullness.qual.NonNull; +import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.io.IOException; import java.time.LocalDateTime; import java.util.*; +import java.util.concurrent.TimeUnit; @Service @Slf4j @@ -45,10 +47,17 @@ public class LessonPlansServiceImpl implements LessonPlansService { private StudentDOMapper studentDOMapper; @Resource private PlanExamDOMapper planExamDOMapper; + @Resource + private RedisTemplate redisTemplate; @Override public void generateLessonPlans(Integer studentId, Integer unitId, Integer wordSize) { + String key = LessonPlanConstant.buildGeneratePlanContent(studentId); + redisTemplate.opsForValue().set(key, studentId); + redisTemplate.expire( key, 12, TimeUnit.MINUTES); + + log.info("开始生成计划"); List vocabularyBankDOS = vocabularyBankDOMapper.selectVocabularyBankDOAllByUnitId(unitId); UnitDO unitDO = unitDOMapper.selectByPrimaryKey(unitId); GradeUnitDO gradeUnitDO = gradeUnitDOMapper.selectByUnitId(unitId); @@ -146,7 +155,7 @@ public class LessonPlansServiceImpl implements LessonPlansService { Map map = generateWeekendPlans(checkList, i + 6, gradeDO, unitDO, studentId); LessonPlansDO lessonPlansDO = LessonPlansDO.builder() - .title(map.get("title").toString()) + .title(map.get("examStr").toString() + "复习") .gradeId(gradeDO.getId().toString()) .unitId(unitDO.getId()) .createdAt(LocalDateTime.now()) @@ -154,6 +163,13 @@ public class LessonPlansServiceImpl implements LessonPlansService { .build(); lessonPlansDOMapper.insert(lessonPlansDO); + Integer examId = (Integer) map.get("examId"); + PlanExamDO planExamDO = PlanExamDO.builder() + .planId(lessonPlansDO.getId()) + .examId(examId) + .build(); + planExamDOMapper.insert(planExamDO); + StudentLessonPlansDO studentLessonPlansDO = StudentLessonPlansDO.builder() .studentId(studentId) .planId(lessonPlansDO.getId()) @@ -177,13 +193,32 @@ public class LessonPlansServiceImpl implements LessonPlansService { } - private Map generateWeekendPlans(List checkList, + private Map generateWeekendPlans(List words, int day, GradeDO gradeDO, UnitDO unitDO, Integer studentId) throws IOException { Map data = new HashMap<>(); - data.put("title", "第" + day + "天" + "复习" + gradeDO.getTitle() + unitDO.getTitle() + studentId); - data.put("checkList", checkList); + words.forEach(word -> word.setDefinition(word.getDefinition().length() > 5 ? word.getDefinition().substring(0, 5) : word.getDefinition())); + List wordIds = words.stream().map(VocabularyBankDO::getId).toList(); + StudentDO studentDO = studentDOMapper.selectStudentById(studentId); + + String ExamTitle = gradeDO.getTitle() + unitDO.getTitle() + "教案小测第" + ExamWordsConstant.day2Chinese(day) + "天" + studentDO.getName(); + ExamWordsDO examWordsDO = ExamWordsDO.builder() + .gradeId(gradeDO.getId()) + .level(1) + .wordIds(wordIds) + .type(ExamWordsConstant.EXAM_TYPE_TEST) + .title(ExamTitle) + .createdAt(LocalDateTime.now()) + .build(); + examWordsDOMapper.insert(examWordsDO); + studentExamWordsDOMapper.insertStudentsExam(studentId, examWordsDO.getId()); + + data.put("examId", examWordsDO.getId()); + data.put("studentId", studentId); + data.put("studentStr", studentDO.getName()); + data.put("examStr", ExamTitle); + data.put("words", words); // LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy(); // Configure config = Configure.builder() // .bind("checkList", policy) diff --git a/enlish-service/src/main/resources/config/application-dev.yml b/enlish-service/src/main/resources/config/application-dev.yml index cda3cad..4582eb4 100644 --- a/enlish-service/src/main/resources/config/application-dev.yml +++ b/enlish-service/src/main/resources/config/application-dev.yml @@ -36,7 +36,7 @@ templates: data: C:\project\tess plan: weekday: C:\project\java\enlish_edu\enlish\enlish-service\src\main\resources\templates\tem_study_plan_v5.docx - weekend: C:\project\java\enlish_edu\enlish\enlish-service\src\main\resources\templates\study_plan_review_v1.docx + weekend: C:\project\java\enlish_edu\enlish\enlish-service\src\main\resources\templates\study_plan_review_v2.docx plan_day: 7 tmp: png: C:\project\java\enlish_edu\enlish\enlish-service\src\main\resources\tmp\png\ diff --git a/enlish-service/src/main/resources/templates/study_plan_review_v2.docx b/enlish-service/src/main/resources/templates/study_plan_review_v2.docx new file mode 100644 index 0000000000000000000000000000000000000000..0da2b03c98c6836a0d38355aa5110a11092f54cc GIT binary patch literal 24798 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 q)sMdaR<`F`ki literal 0 HcmV?d00001 diff --git a/enlish-vue/src/api/plan.js b/enlish-vue/src/api/plan.js index c0f6e65..00fcb63 100644 --- a/enlish-vue/src/api/plan.js +++ b/enlish-vue/src/api/plan.js @@ -51,6 +51,12 @@ export function getLessonPlanWords(planId) { }) } +export function checkIsGenerated(studentId) { + return axios.post('plan/check', { + studentId: studentId + }) +} + const resolveBlob = (res, fileName) => { // 创建 Blob 对象,可以指定 type,也可以让浏览器自动推断 const blob = new Blob([res], { type: 'application/octet-stream' }); diff --git a/enlish-vue/src/layouts/components/LessonPlanDialog.vue b/enlish-vue/src/layouts/components/LessonPlanDialog.vue index 3932be0..6ebf2ac 100644 --- a/enlish-vue/src/layouts/components/LessonPlanDialog.vue +++ b/enlish-vue/src/layouts/components/LessonPlanDialog.vue @@ -39,7 +39,7 @@ const props = defineProps({ modelValue: { type: Boolean, default: false }, studentId: { type: [Number, String], required: true } }) -const emit = defineEmits(['update:modelValue']) +const emit = defineEmits(['update:modelValue', 'success']) const visible = computed({ get: () => props.modelValue, @@ -71,6 +71,7 @@ async function handleGenerate() { const d = res?.data if (d.success) { ElMessage.success('生成学案任务已提交,请等待十分钟') + emit('success', { studentId: Number(props.studentId) }) visible.value = false } else { showMessage(d.message || '生成学案失败,请联系管理员', 'error') diff --git a/enlish-vue/src/pages/LearningPlan.vue b/enlish-vue/src/pages/LearningPlan.vue index 4f625dc..b80825c 100644 --- a/enlish-vue/src/pages/LearningPlan.vue +++ b/enlish-vue/src/pages/LearningPlan.vue @@ -19,7 +19,6 @@
学案
- - diff --git a/enlish-vue/src/pages/class.vue b/enlish-vue/src/pages/class.vue index 59fb2c4..8ea48b6 100644 --- a/enlish-vue/src/pages/class.vue +++ b/enlish-vue/src/pages/class.vue @@ -59,6 +59,18 @@ + + +