refactor(exam): 重构考试判卷任务与新增教案小测功能

- 将自动判卷任务类从job包迁移到task包并添加日志打印,增强可维护性
- 优化自动判卷逻辑,仅当有未完成试卷时触发判卷处理
- 修正判卷结果中学生姓名和考试标题的空值保护,防止空指针异常
- 扩展考试类型常量,新增教案小测类型常量EXAM_TYPE_TEST
- 修改exam_words表插入语句,新增type字段支持不同考试类型
- 优化判卷逻辑:仅摸底考试计算等级,其他考试添加答题数提示信息
- 判卷完成后调用学案服务,自动完成学生对应学案计划
- 在教案计划生成中增加教案小测试卷的生成与存储
- 新增PlanExamDO数据对象及对应Mapper,实现学案与考试的关联映射
- 修改MySQL及Redis配置文件,完善环境配置
- 修正文档生成模板路径及生成逻辑,优化导出功能
- 屏蔽部分测试用例中的直接调用,防止无效执行和输出
- 清理部分测试代码中的硬编码和无用注释,提升代码整洁度
- 删除无用OMR测试代码,注释多余测试实现,简化测试类
- 统一二维码链接域名,指向正式环境地址
- 移除enlish-service中对词汇库插入的测试注释,避免误执行
This commit is contained in:
lbw
2025-12-31 14:16:43 +08:00
parent 6277e3ab42
commit 504dd8d964
22 changed files with 337 additions and 150 deletions

View File

@@ -31,9 +31,15 @@ public class ExamWordsConstant {
public static final int ZONE_F_SIZE = 7; public static final int ZONE_F_SIZE = 7;
// 摸底
public static final int EXAM_TYPE_BASELINE = 1; public static final int EXAM_TYPE_BASELINE = 1;
// 中期
public static final int EXAM_TYPE_MIDTERM = 2; public static final int EXAM_TYPE_MIDTERM = 2;
// 期末
public static final int EXAM_TYPE_FINAL = 3; public static final int EXAM_TYPE_FINAL = 3;
// 小测
public static final int EXAM_TYPE_TEST = 4;
public static int getZoneA(int gradeId) { public static int getZoneA(int gradeId) {
return switch (gradeId) { return switch (gradeId) {
@@ -131,4 +137,17 @@ public class ExamWordsConstant {
default -> ""; default -> "";
}; };
} }
public static String day2Chinese(int day) {
return switch (day) {
case 1 -> "";
case 2 -> "";
case 3 -> "";
case 4 -> "";
case 5 -> "";
case 6 -> "";
case 7 -> "";
default -> "";
};
}
} }

View File

@@ -113,8 +113,8 @@ public class ExamWordsController {
.builder() .builder()
.id(examWordsJudgeResultDO.getId()) .id(examWordsJudgeResultDO.getId())
.studentId(examWordsJudgeResultDO.getStudentId()) .studentId(examWordsJudgeResultDO.getStudentId())
.studentName(studentService.getStudentById(examWordsJudgeResultDO.getStudentId()).getName()) .studentName(examWordsJudgeResultDO.getStudentId() != null ? studentService.getStudentById(examWordsJudgeResultDO.getStudentId()).getName() : "")
.examWordsTitle(examWordsService.getExamWordsDOById(examWordsJudgeResultDO.getExamWordsId()).getTitle()) .examWordsTitle(examWordsJudgeResultDO.getExamWordsId() != null ? examWordsService.getExamWordsDOById(examWordsJudgeResultDO.getExamWordsId()).getTitle() : "")
.examWordsId(examWordsJudgeResultDO.getExamWordsId()) .examWordsId(examWordsJudgeResultDO.getExamWordsId())
.startDate(examWordsJudgeResultDO.getStartDate()) .startDate(examWordsJudgeResultDO.getStartDate())
.correctWordCount(examWordsJudgeResultDO.getCorrectWordCount()) .correctWordCount(examWordsJudgeResultDO.getCorrectWordCount())

View File

@@ -0,0 +1,21 @@
package com.yinlihupo.enlish.service.domain.dataobject;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@AllArgsConstructor
@NoArgsConstructor
@Data
@Builder
public class PlanExamDO {
private Integer id;
private Integer planId;
private Integer examId;
}

View File

@@ -0,0 +1,9 @@
package com.yinlihupo.enlish.service.domain.mapper;
import com.yinlihupo.enlish.service.domain.dataobject.PlanExamDO;
public interface PlanExamDOMapper {
void insert(PlanExamDO record);
PlanExamDO selectByExamId(Integer examId);
}

View File

@@ -9,6 +9,7 @@ import com.yinlihupo.enlish.service.model.bo.exam.ActionType;
import com.yinlihupo.enlish.service.model.bo.exam.DiagnosisResult; import com.yinlihupo.enlish.service.model.bo.exam.DiagnosisResult;
import com.yinlihupo.enlish.service.model.bo.exam.ZoneStats; import com.yinlihupo.enlish.service.model.bo.exam.ZoneStats;
import com.yinlihupo.enlish.service.service.ExamWordsJudgeService; import com.yinlihupo.enlish.service.service.ExamWordsJudgeService;
import com.yinlihupo.enlish.service.service.StudentLessonPlansService;
import com.yinlihupo.enlish.service.utils.PngUtil; import com.yinlihupo.enlish.service.utils.PngUtil;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@@ -40,6 +41,10 @@ public class ExamWordsJudgeServiceImpl implements ExamWordsJudgeService {
private GradeUnitDOMapper gradeUnitDOMapper; private GradeUnitDOMapper gradeUnitDOMapper;
@Resource @Resource
private StudentDOMapper studentDOMapper; private StudentDOMapper studentDOMapper;
@Resource
private PlanExamDOMapper planExamDOMapper;
@Resource
private StudentLessonPlansService studentLessonPlansService;
@Value("${templates.data}") @Value("${templates.data}")
private String tessdataPath; private String tessdataPath;
@@ -56,6 +61,7 @@ public class ExamWordsJudgeServiceImpl implements ExamWordsJudgeService {
StudentExamId studentExamId = PngUtil.analyzeExamWordsIdAndStudentId(ansSheetPath, tessdataPath, coordinatesXIES); StudentExamId studentExamId = PngUtil.analyzeExamWordsIdAndStudentId(ansSheetPath, tessdataPath, coordinatesXIES);
Integer examWordsJudgeResultDOId = examWordsJudgeResultDO.getId(); Integer examWordsJudgeResultDOId = examWordsJudgeResultDO.getId();
if (studentExamId == null) { if (studentExamId == null) {
log.info("未找到学生 id 和考试 id");
examWordsJudgeResultDOMapper.updateMsg(examWordsJudgeResultDOId, "未识别学生 id 和考试 id"); examWordsJudgeResultDOMapper.updateMsg(examWordsJudgeResultDOId, "未识别学生 id 和考试 id");
continue; continue;
} }
@@ -93,9 +99,13 @@ public class ExamWordsJudgeServiceImpl implements ExamWordsJudgeService {
.wrongWordCount(unmemorizedWordIds.size()) .wrongWordCount(unmemorizedWordIds.size())
.isFinished(1) .isFinished(1)
.build(); .build();
// 判断考试等级
judgeExamActualGrade(wordsJudgeResultDO, examWordsDO);
if (examWordsDO.getType().equals(ExamWordsConstant.EXAM_TYPE_BASELINE)) {
// 判断考试等级
judgeExamActualGrade(wordsJudgeResultDO, examWordsDO);
} else {
wordsJudgeResultDO.setMsg("此次考试" + examWordsDO.getTitle() + "答对单词数为" + memorizedWordIds.size());
}
int updated = examWordsJudgeResultDOMapper.updateExamWordsJudgeResultDO(wordsJudgeResultDO); int updated = examWordsJudgeResultDOMapper.updateExamWordsJudgeResultDO(wordsJudgeResultDO);
if (updated != 1) { if (updated != 1) {
examWordsJudgeResultDOMapper.updateMsg(examWordsJudgeResultDOId, "更新考试记录失败"); examWordsJudgeResultDOMapper.updateMsg(examWordsJudgeResultDOId, "更新考试记录失败");
@@ -103,6 +113,12 @@ public class ExamWordsJudgeServiceImpl implements ExamWordsJudgeService {
} }
log.info("更新考试记录成功"); log.info("更新考试记录成功");
PlanExamDO planExamDO = planExamDOMapper.selectByExamId(examWordsId);
if (planExamDO != null) {
studentLessonPlansService.finishStudentLessonPlan(studentId, planExamDO.getPlanId());
log.info("完成学案成功, planId: {}", planExamDO.getPlanId());
}
List<WordMasteryLogDO> wordMasteryLogDOS = new ArrayList<>(unmemorizedWordIds.stream().map(wordId -> WordMasteryLogDO.builder() List<WordMasteryLogDO> wordMasteryLogDOS = new ArrayList<>(unmemorizedWordIds.stream().map(wordId -> WordMasteryLogDO.builder()
.wordId(wordId) .wordId(wordId)
.studentId(studentId) .studentId(studentId)

View File

@@ -1,5 +1,6 @@
package com.yinlihupo.enlish.service.service.plan; package com.yinlihupo.enlish.service.service.plan;
import com.yinlihupo.enlish.service.constant.ExamWordsConstant;
import com.yinlihupo.enlish.service.constant.LessonPlanConstant; import com.yinlihupo.enlish.service.constant.LessonPlanConstant;
import com.yinlihupo.enlish.service.domain.dataobject.*; import com.yinlihupo.enlish.service.domain.dataobject.*;
import com.yinlihupo.enlish.service.domain.mapper.*; import com.yinlihupo.enlish.service.domain.mapper.*;
@@ -36,6 +37,14 @@ public class LessonPlansServiceImpl implements LessonPlansService {
private GradeDOMapper gradeDOMapper; private GradeDOMapper gradeDOMapper;
@Resource @Resource
private DifyClient difyClient; private DifyClient difyClient;
@Resource
private ExamWordsDOMapper examWordsDOMapper;
@Resource
private StudentExamWordsDOMapper studentExamWordsDOMapper;
@Resource
private StudentDOMapper studentDOMapper;
@Resource
private PlanExamDOMapper planExamDOMapper;
@Override @Override
@@ -116,6 +125,13 @@ public class LessonPlansServiceImpl implements LessonPlansService {
.build(); .build();
studentLessonPlansDOMapper.insert(studentLessonPlansDO); studentLessonPlansDOMapper.insert(studentLessonPlansDO);
Integer examId = (Integer) lessonPlanMap.get("examId");
PlanExamDO planExamDO = PlanExamDO.builder()
.planId(lessonPlansDO.getId())
.examId(examId)
.build();
planExamDOMapper.insert(planExamDO);
} catch (Exception e) { } catch (Exception e) {
log.info("生成第{}天计划失败,失败原因 {}", i + 1, e.getMessage()); log.info("生成第{}天计划失败,失败原因 {}", i + 1, e.getMessage());
} }
@@ -244,6 +260,40 @@ public class LessonPlansServiceImpl implements LessonPlansService {
data.put("sentences", sentences); data.put("sentences", sentences);
data.put("sentencesAns", sentences); data.put("sentencesAns", sentences);
log.info( "生成连词成句成功"); log.info( "生成连词成句成功");
// 教案小测
List<VocabularyBankDO> words = new ArrayList<>(syncVocabList);
words.addAll(gapVocabList);
words.addAll(reviewVocabList);
if (words.size() < 100) {
words.addAll(vocabularyBankDOMapper.selectVocabularyBankListByGradeIdRandom(gradeDO.getId(), 100 - words.size()));
} else {
words = words.subList(0, 100);
}
words.forEach(word -> word.setDefinition(word.getDefinition().length() > 5 ? word.getDefinition().substring(0, 5) : word.getDefinition()));
List<Integer> 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);
log.info("生成教案小测成功");
// LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy(); // LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy();
// Configure config = Configure.builder() // Configure config = Configure.builder()
// .bind("syncVocabList", policy) // .bind("syncVocabList", policy)

View File

@@ -1,13 +1,13 @@
package com.yinlihupo.enlish.service.job; package com.yinlihupo.enlish.service.task;
import com.yinlihupo.enlish.service.service.ExamWordsJudgeService; import com.yinlihupo.enlish.service.service.ExamWordsJudgeService;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
@Component @Component
@Slf4j
public class AutoJudgeExamWordsTask { public class AutoJudgeExamWordsTask {
@Resource @Resource
@@ -15,7 +15,9 @@ public class AutoJudgeExamWordsTask {
@Scheduled(fixedRate = 5000) @Scheduled(fixedRate = 5000)
public void autoJudgeExamWords() { public void autoJudgeExamWords() {
System.out.println("【固定频率】开始自动判卷,时间:" + LocalDateTime.now()); if (examWordsJudgeService.getExamWordsJudgeResultCount() != 0) {
examWordsJudgeService.judgeExamWords(5); log.info("有试卷待检测,开始检测");
examWordsJudgeService.judgeExamWords(5);
}
} }
} }

View File

@@ -52,6 +52,7 @@ public class WordExportUtil {
.bind("checkListAns", policyLessonPlanWeekday) .bind("checkListAns", policyLessonPlanWeekday)
.bind("sentences", policyLessonPlanWeekday) .bind("sentences", policyLessonPlanWeekday)
.bind("sentencesAns", policyLessonPlanWeekday) .bind("sentencesAns", policyLessonPlanWeekday)
.bind("words", policyLessonPlanWeekday)
.build(); .build();
LoopRowTableRenderPolicy policyLessonPlan = new LoopRowTableRenderPolicy(); LoopRowTableRenderPolicy policyLessonPlan = new LoopRowTableRenderPolicy();
@@ -96,7 +97,7 @@ public class WordExportUtil {
} else { } else {
template = XWPFTemplate.compile(inputStream, configLessonPlanWeekend); template = XWPFTemplate.compile(inputStream, configLessonPlanWeekend);
} }
String url = "http://localhost:5173/#/plan/tts?planId=" + lessonPlan.getId(); String url = "http://english.yinlihupo.cn/#/plan/tts?planId=" + lessonPlan.getId();
map.put("img", Pictures.ofBytes(generateQR(url), PictureType.PNG).create()); map.put("img", Pictures.ofBytes(generateQR(url), PictureType.PNG).create());
OutputStream out = response.getOutputStream(); OutputStream out = response.getOutputStream();
template.render(map); template.render(map);

View File

@@ -35,7 +35,7 @@ templates:
count: 100 count: 100
data: C:\project\tess data: C:\project\tess
plan: plan:
weekday: C:\project\java\enlish_edu\enlish\enlish-service\src\main\resources\templates\tem_study_plan_v4.docx 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_v1.docx
plan_day: 7 plan_day: 7
tmp: tmp:

View File

@@ -0,0 +1,52 @@
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver # 指定数据库驱动类
# 数据库连接信息
url: jdbc:mysql://124.220.58.5:3306/enlish?allowMultiQueries=true
username: root # 数据库用户名
password: YLHP@admin123 # 数据库密码
data:
redis:
database: 6 # Redis 数据库索引(默认为 0
host: 124.220.58.5 # Redis 服务器地址
port: 6543 # Redis 服务器连接端口
password: 741963 # Redis 服务器连接密码(默认为空)
timeout: 5s # 读超时时间
connect-timeout: 5s # 链接超时时间
lettuce:
pool:
max-active: 200 # 连接池最大连接数
max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
min-idle: 0 # 连接池中的最小空闲连接
max-idle: 10 # 连接池中的最大空闲连接
ai:
openai:
api-key: your_api_key_here
base-url: http://124.220.58.5:2233
audio:
speech:
options:
model: tts-1
voice: alloy
templates:
word: assessment_v5.docx
count: 100
data: eng.traineddata
plan:
weekday: tem_study_plan_v4.docx
weekend: study_plan_review_v1.docx
plan_day: 7
tmp:
png: tmp\png\
ai:
key: app-loC6IrJpj4cS54MAYp73QtGl
analyzeKey: app-hrUFcopdcpnflsvpHWRuBfCp
sentenceKey: app-Emk5YQBaD2YruRXuE5sK1vEU
url: https://chat.cosonggle.com/v1/chat-messages
aliyun:
accessKeyId:
accessKeySecret:

View File

@@ -45,7 +45,7 @@
targetProject="src/main/java"/> targetProject="src/main/java"/>
<!-- 需要生成的表-实体类 --> <!-- 需要生成的表-实体类 -->
<table tableName="student_stage_learning_remark" domainObjectName="StudentStageLearningRemarkDO" <table tableName="plan_exam" domainObjectName="PlanExamDO"
enableCountByExample="false" enableCountByExample="false"
enableUpdateByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableDeleteByExample="false"

View File

@@ -14,8 +14,8 @@
</resultMap> </resultMap>
<insert id="insert" useGeneratedKeys="true" keyProperty="id"> <insert id="insert" useGeneratedKeys="true" keyProperty="id">
insert into exam_words (grade_id, level, title, word_ids, created_at) insert into exam_words (grade_id, level, title, word_ids, type, created_at)
VALUES (#{gradeId}, #{level}, #{title}, #{wordIds, typeHandler=com.yinlihupo.enlish.service.config.ListWordIdTypeHandler}, #{createdAt}) VALUES (#{gradeId}, #{level}, #{title}, #{wordIds, typeHandler=com.yinlihupo.enlish.service.config.ListWordIdTypeHandler}, #{type}, #{createdAt})
</insert> </insert>
<update id="updateWordIdsOrder"> <update id="updateWordIdsOrder">

View File

@@ -61,7 +61,9 @@
<select id="selectCount" resultType="java.lang.Integer"> <select id="selectCount" resultType="java.lang.Integer">
select count(1) select count(1)
from exam_words_judge_result from exam_words_judge_result
where is_finished = 0
</select> </select>
<select id="selectDetailById" resultMap="ResultMapWithBLOBs"> <select id="selectDetailById" resultMap="ResultMapWithBLOBs">
select * select *
from exam_words_judge_result from exam_words_judge_result

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yinlihupo.enlish.service.domain.mapper.PlanExamDOMapper">
<resultMap id="BaseResultMap" type="com.yinlihupo.enlish.service.domain.dataobject.PlanExamDO">
<id column="id" jdbcType="INTEGER" property="id" />
<result column="plan_id" jdbcType="INTEGER" property="planId" />
<result column="exam_id" jdbcType="INTEGER" property="examId" />
</resultMap>
<insert id="insert" useGeneratedKeys="true" keyProperty="id">
insert into plan_exam (plan_id, exam_id)
values (#{planId}, #{examId})
</insert>
<select id="selectByExamId" resultMap="BaseResultMap">
select * from plan_exam where exam_id = #{examId}
</select>
</mapper>

View File

@@ -27,9 +27,6 @@ public class AITest {
try { try {
List<VocabularyBankDO> vocabularyBankDOS = vocabularyBankDOMapper.selectVocabularyBankDOAllByUnitId(269);
List<Sentence> sentences = client.sendSentenceAnalyze(vocabularyBankDOS, "小学4年级");
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();

View File

@@ -35,68 +35,68 @@ public class TestVocabularyBankInsert {
private GradeUnitDOMapper gradeUnitDOMapper; private GradeUnitDOMapper gradeUnitDOMapper;
@Test @Test
void test() { void test() {
String file = "C:\\project\\java\\enlish_edu\\enlish\\enlish-service\\src\\test\\java\\com\\yinlihupo\\enlish\\service\\mapper\\八下.xlsx"; // String file = "C:\\project\\java\\enlish_edu\\enlish\\enlish-service\\src\\test\\java\\com\\yinlihupo\\enlish\\service\\mapper\\八下.xlsx";
HashMap<String, Integer> map = new HashMap<>(); // HashMap<String, Integer> map = new HashMap<>();
int gradeId = 8; // int gradeId = 8;
try (FileInputStream fis = new FileInputStream(file); Workbook workbook = new XSSFWorkbook(fis)) { // try (FileInputStream fis = new FileInputStream(file); Workbook workbook = new XSSFWorkbook(fis)) {
//
Sheet sheet = workbook.getSheetAt(0); // Sheet sheet = workbook.getSheetAt(0);
//
for (int i = 1; i <= sheet.getLastRowNum(); i++) { // for (int i = 1; i <= sheet.getLastRowNum(); i++) {
Row row = sheet.getRow(i); // Row row = sheet.getRow(i);
if (row == null) { // if (row == null) {
continue; // continue;
} // }
//
//
// String word = row.getCell(0).getStringCellValue(); // String word = row.getCell(0).getStringCellValue();
// String pronunciation = row.getCell(1) != null ? row.getCell(1).getStringCellValue() : ""; // String pronunciation = row.getCell(1) != null ? row.getCell(1).getStringCellValue() : "";
// String pos = row.getCell(2) != null ? row.getCell(2).getStringCellValue() : ""; // String pos = row.getCell(2) != null ? row.getCell(2).getStringCellValue() : "";
// String meaning = row.getCell(3) != null ? row.getCell(3).getStringCellValue() : ""; // String meaning = row.getCell(3) != null ? row.getCell(3).getStringCellValue() : "";
// String gradeUnit = row.getCell(4) != null ? row.getCell(4).getStringCellValue() : ""; // String gradeUnit = row.getCell(4) != null ? row.getCell(4).getStringCellValue() : "";
//
String word = row.getCell(0).getStringCellValue(); // String word = row.getCell(0).getStringCellValue();
String meaning = row.getCell(1) != null ? row.getCell(1).getStringCellValue() : ""; // String meaning = row.getCell(1) != null ? row.getCell(1).getStringCellValue() : "";
String gradeUnit = row.getCell(2) != null ? row.getCell(2).getStringCellValue() : ""; // String gradeUnit = row.getCell(2) != null ? row.getCell(2).getStringCellValue() : "";
String pronunciation = ""; // String pronunciation = "";
String pos = ""; // String pos = "";
if (word.contains("Unit")) { // if (word.contains("Unit")) {
continue; // continue;
} // }
//
int gradeUnitId; // int gradeUnitId;
if (map.containsKey(gradeUnit)) { // if (map.containsKey(gradeUnit)) {
gradeUnitId = map.get(gradeUnit); // gradeUnitId = map.get(gradeUnit);
} else { // } else {
UnitDO unitDO = unitDOMapper.selectByTitle(gradeUnit); // UnitDO unitDO = unitDOMapper.selectByTitle(gradeUnit);
if (unitDO == null) { // if (unitDO == null) {
unitDO = UnitDO.builder() // unitDO = UnitDO.builder()
.title(gradeUnit) // .title(gradeUnit)
.version("人教版") // .version("人教版")
.createAt(LocalDateTime.now()) // .createAt(LocalDateTime.now())
.build(); // .build();
unitDOMapper.insert(unitDO); // unitDOMapper.insert(unitDO);
gradeUnitDOMapper.insert(GradeUnitDO.builder().unitId(unitDO.getId()).gradeId(gradeId).build()); // gradeUnitDOMapper.insert(GradeUnitDO.builder().unitId(unitDO.getId()).gradeId(gradeId).build());
gradeUnitId = unitDO.getId(); // gradeUnitId = unitDO.getId();
} else { // } else {
gradeUnitId = unitDO.getId(); // gradeUnitId = unitDO.getId();
} // }
//
map.put(gradeUnit, gradeUnitId); // map.put(gradeUnit, gradeUnitId);
} // }
VocabularyBankDO vocabularyBankDO = VocabularyBankDO.builder() // VocabularyBankDO vocabularyBankDO = VocabularyBankDO.builder()
.word(word) // .word(word)
.definition(meaning) // .definition(meaning)
.pronunciation(pronunciation) // .pronunciation(pronunciation)
.pos(pos) // .pos(pos)
.unitId(gradeUnitId) // .unitId(gradeUnitId)
.build(); // .build();
vocabularyBankMapper.insertSelective(vocabularyBankDO); // vocabularyBankMapper.insertSelective(vocabularyBankDO);
log.info("插入数据 {} ", vocabularyBankDO); // log.info("插入数据 {} ", vocabularyBankDO);
} // }
//
} catch (IOException e) { // } catch (IOException e) {
throw new RuntimeException(e); // throw new RuntimeException(e);
} // }
} }
} }

View File

@@ -22,7 +22,7 @@ public class WordMasteryLogInsertTest {
@Test @Test
void test() { void test() {
List<Integer> integers = vocabularyBankMapper.selectAllIds(); // List<Integer> integers = vocabularyBankMapper.selectAllIds();
wordMasteryLogDOMapper.batchInsertInitialization(integers, 1); // wordMasteryLogDOMapper.batchInsertInitialization(integers, 1);
} }
} }

View File

@@ -24,25 +24,25 @@ public class TestOmr {
public void testOmr(){ public void testOmr(){
OpenCV.loadLocally(); OpenCV.loadLocally();
List<Integer> knownIds = Arrays.asList(3184, 3185, 3186, 3187, 3188, 3189, 3190, 3191, 3192, 3193, // List<Integer> knownIds = Arrays.asList(3184, 3185, 3186, 3187, 3188, 3189, 3190, 3191, 3192, 3193,
3195, 3196, 3197, 3198, 3199, 3200, 3201, 3202, 3203, 3204, // 3195, 3196, 3197, 3198, 3199, 3200, 3201, 3202, 3203, 3204,
3206, 3208, 3209, 3210, 3211, 3212, 3507, 3508, 3509, 3510, // 3206, 3208, 3209, 3210, 3211, 3212, 3507, 3508, 3509, 3510,
3511, 3512, 3513, 3514, 3515, 3516, 3517, 3519, 3521, 3522, // 3511, 3512, 3513, 3514, 3515, 3516, 3517, 3519, 3521, 3522,
3523, 3524, 3525, 3526, 3527, 3528, 3529, 3530, 3531, 3532, // 3523, 3524, 3525, 3526, 3527, 3528, 3529, 3530, 3531, 3532,
3533, 3535, 3536, 3537, 3538, 3539); // 3533, 3535, 3536, 3537, 3538, 3539);
//
List<String> knowsIds = knownIds.stream().map(id -> id + "").toList(); // List<String> knowsIds = knownIds.stream().map(id -> id + "").toList();
String path = "C:\\project\\java\\enlish_edu\\enlish\\enlish-service\\src\\main\\resources\\templates\\p3.png"; // String path = "C:\\project\\java\\enlish_edu\\enlish\\enlish-service\\src\\main\\resources\\templates\\p3.png";
List<CoordinatesXY> coordinatesXIES = PngUtil.analysisXY(path); // List<CoordinatesXY> coordinatesXIES = PngUtil.analysisXY(path);
} }
@Test @Test
public void testInteger(){ public void testInteger(){
String filePath = "C:\\project\\java\\enlish_edu\\enlish\\enlish-service\\src\\main\\resources\\templates\\p3.png"; // String filePath = "C:\\project\\java\\enlish_edu\\enlish\\enlish-service\\src\\main\\resources\\templates\\p3.png";
List<CoordinatesXY> coordinatesXIES = PngUtil.analysisXY(filePath); // List<CoordinatesXY> coordinatesXIES = PngUtil.analysisXY(filePath);
StudentExamId studentExamId = PngUtil.analyzeExamWordsIdAndStudentId(filePath, tessdataPath, coordinatesXIES); // StudentExamId studentExamId = PngUtil.analyzeExamWordsIdAndStudentId(filePath, tessdataPath, coordinatesXIES);
log.info("studentExamId:{}",studentExamId); // log.info("studentExamId:{}",studentExamId);
} }
} }

View File

@@ -26,36 +26,36 @@ public class ExamTest {
private VocabularyService vocabularyService; private VocabularyService vocabularyService;
@Test @Test
public void test() { public void test() {
ExamWordsDO examWordsDO = examWordsService.generateExamWords(5, 0); // ExamWordsDO examWordsDO = examWordsService.generateExamWords(5, 0);
log.info("{}", examWordsDO); // log.info("{}", examWordsDO);
List<VocabularyBankDO> vocabularyBankDOS = vocabularyService.findVocabularyBankDOListById(examWordsDO.getWordIds()); // List<VocabularyBankDO> vocabularyBankDOS = vocabularyService.findVocabularyBankDOListById(examWordsDO.getWordIds());
List<Word> assessmentWords = vocabularyBankDOS.stream().map(vocabularyBankDO -> Word.builder() // List<Word> assessmentWords = vocabularyBankDOS.stream().map(vocabularyBankDO -> Word.builder()
.id(vocabularyBankDO.getId()) // .id(vocabularyBankDO.getId())
.title(vocabularyBankDO.getWord()) // .title(vocabularyBankDO.getWord())
.definition(vocabularyBankDO.getDefinition()) // .definition(vocabularyBankDO.getDefinition())
.build()).toList(); // .build()).toList();
//
//
LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy(); // LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy();
Configure config = Configure.builder() // Configure config = Configure.builder()
.bind("words", policy) // .bind("words", policy)
.build(); // .build();
//
Map<String, Object> data = new HashMap<>(); // Map<String, Object> data = new HashMap<>();
data.put("examId", examWordsDO.getId()); // data.put("examId", examWordsDO.getId());
data.put("studentId", 1); // data.put("studentId", 1);
data.put("studentStr","小明三班一年级"); // data.put("studentStr","小明三班一年级");
data.put("examStr", examWordsDO.getTitle()); // data.put("examStr", examWordsDO.getTitle());
data.put("words", assessmentWords); // data.put("words", assessmentWords);
data.put("answer", assessmentWords); // data.put("answer", assessmentWords);
//
// 4. 渲染并输出 // // 4. 渲染并输出
try (XWPFTemplate template = XWPFTemplate.compile("C:\\project\\java\\enlish_edu\\enlish\\enlish-service\\src\\main\\resources\\templates\\assessment_v5.docx", config)) { // try (XWPFTemplate template = XWPFTemplate.compile("C:\\project\\java\\enlish_edu\\enlish\\enlish-service\\src\\main\\resources\\templates\\assessment_v5.docx", config)) {
template.render(data); // template.render(data);
template.write(new FileOutputStream("学生单词测试卷.docx")); // template.write(new FileOutputStream("学生单词测试卷.docx"));
System.out.println("文档生成成功!"); // System.out.println("文档生成成功!");
} catch (Exception e) { // } catch (Exception e) {
e.printStackTrace(); // e.printStackTrace();
} // }
} }
} }

View File

@@ -36,22 +36,22 @@ public class ExamWordsJudgeServiceTest {
@Test @Test
public void judgeExamWords() { public void judgeExamWords() {
String ansSheetPath = "C:\\project\\java\\enlish_edu\\enlish\\enlish-service\\src\\main\\resources\\templates\\3.png"; // String ansSheetPath = "C:\\project\\java\\enlish_edu\\enlish\\enlish-service\\src\\main\\resources\\templates\\3.png";
List<CoordinatesXY> coordinatesXIES = PngUtil.analysisXY(ansSheetPath); // List<CoordinatesXY> coordinatesXIES = PngUtil.analysisXY(ansSheetPath);
// 从图片中获取学生 id 和考试 id // // 从图片中获取学生 id 和考试 id
String tessdataPath = "C:\\project\\tess"; // String tessdataPath = "C:\\project\\tess";
StudentExamId studentExamId = PngUtil.analyzeExamWordsIdAndStudentId(ansSheetPath, tessdataPath, coordinatesXIES); // StudentExamId studentExamId = PngUtil.analyzeExamWordsIdAndStudentId(ansSheetPath, tessdataPath, coordinatesXIES);
Integer examWordsId = 41; // Integer examWordsId = 41;
//
ExamWordsDO examWordsDO = examWordsDOMapper.selectById(examWordsId); // ExamWordsDO examWordsDO = examWordsDOMapper.selectById(examWordsId);
//
List<Integer> wordIds = examWordsDO.getWordIds(); // List<Integer> wordIds = examWordsDO.getWordIds();
List<Integer> unmemorizedWordIds = PngUtil.analyzePngForUnmemorizedWordIds(ansSheetPath, wordIds, coordinatesXIES); // List<Integer> unmemorizedWordIds = PngUtil.analyzePngForUnmemorizedWordIds(ansSheetPath, wordIds, coordinatesXIES);
List<Integer> memorizedWordIds = wordIds.stream().filter(wordId -> !unmemorizedWordIds.contains(wordId)).toList(); // List<Integer> memorizedWordIds = wordIds.stream().filter(wordId -> !unmemorizedWordIds.contains(wordId)).toList();
List<VocabularyBankDO> vocabularyBankDOS = vocabularyBankDOMapper.selectVocabularyBankDOListByIds(unmemorizedWordIds); // List<VocabularyBankDO> vocabularyBankDOS = vocabularyBankDOMapper.selectVocabularyBankDOListByIds(unmemorizedWordIds);
for (VocabularyBankDO vocabularyBankDO : vocabularyBankDOS) { // for (VocabularyBankDO vocabularyBankDO : vocabularyBankDOS) {
log.info("未掌握的单词:{}", vocabularyBankDO); // log.info("未掌握的单词:{}", vocabularyBankDO);
} // }
} }
@Test @Test
@@ -60,16 +60,16 @@ public class ExamWordsJudgeServiceTest {
log.info("examWordsJudgeResult:{}", examWordsJudgeResult); log.info("examWordsJudgeResult:{}", examWordsJudgeResult);
} }
@Test // @Test
public void selectExamWordsJudgeResult2() { // public void selectExamWordsJudgeResult2() {
String s = studentService.analyzeStudentStudy(1); // String s = studentService.analyzeStudentStudy(1);
try { // try {
DifyClient.DifyResponse difyResponse = difyClient.sendStudentAnalyze(s); // DifyClient.DifyResponse difyResponse = difyClient.sendStudentAnalyze(s);
String answer = difyResponse.getAnswer(); // String answer = difyResponse.getAnswer();
log.info("answer:{}", answer); // log.info("answer:{}", answer);
} catch (Exception e) { // } catch (Exception e) {
throw new RuntimeException(e); // throw new RuntimeException(e);
} // }
log.info("s:{}", s); // log.info("s:{}", s);
} // }
} }