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 EXAM_TYPE_BASELINE = 1;
// 中期
public static final int EXAM_TYPE_MIDTERM = 2;
// 期末
public static final int EXAM_TYPE_FINAL = 3;
// 小测
public static final int EXAM_TYPE_TEST = 4;
public static int getZoneA(int gradeId) {
return switch (gradeId) {
@@ -131,4 +137,17 @@ public class ExamWordsConstant {
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()
.id(examWordsJudgeResultDO.getId())
.studentId(examWordsJudgeResultDO.getStudentId())
.studentName(studentService.getStudentById(examWordsJudgeResultDO.getStudentId()).getName())
.examWordsTitle(examWordsService.getExamWordsDOById(examWordsJudgeResultDO.getExamWordsId()).getTitle())
.studentName(examWordsJudgeResultDO.getStudentId() != null ? studentService.getStudentById(examWordsJudgeResultDO.getStudentId()).getName() : "")
.examWordsTitle(examWordsJudgeResultDO.getExamWordsId() != null ? examWordsService.getExamWordsDOById(examWordsJudgeResultDO.getExamWordsId()).getTitle() : "")
.examWordsId(examWordsJudgeResultDO.getExamWordsId())
.startDate(examWordsJudgeResultDO.getStartDate())
.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.ZoneStats;
import com.yinlihupo.enlish.service.service.ExamWordsJudgeService;
import com.yinlihupo.enlish.service.service.StudentLessonPlansService;
import com.yinlihupo.enlish.service.utils.PngUtil;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
@@ -40,6 +41,10 @@ public class ExamWordsJudgeServiceImpl implements ExamWordsJudgeService {
private GradeUnitDOMapper gradeUnitDOMapper;
@Resource
private StudentDOMapper studentDOMapper;
@Resource
private PlanExamDOMapper planExamDOMapper;
@Resource
private StudentLessonPlansService studentLessonPlansService;
@Value("${templates.data}")
private String tessdataPath;
@@ -56,6 +61,7 @@ public class ExamWordsJudgeServiceImpl implements ExamWordsJudgeService {
StudentExamId studentExamId = PngUtil.analyzeExamWordsIdAndStudentId(ansSheetPath, tessdataPath, coordinatesXIES);
Integer examWordsJudgeResultDOId = examWordsJudgeResultDO.getId();
if (studentExamId == null) {
log.info("未找到学生 id 和考试 id");
examWordsJudgeResultDOMapper.updateMsg(examWordsJudgeResultDOId, "未识别学生 id 和考试 id");
continue;
}
@@ -93,9 +99,13 @@ public class ExamWordsJudgeServiceImpl implements ExamWordsJudgeService {
.wrongWordCount(unmemorizedWordIds.size())
.isFinished(1)
.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);
if (updated != 1) {
examWordsJudgeResultDOMapper.updateMsg(examWordsJudgeResultDOId, "更新考试记录失败");
@@ -103,6 +113,12 @@ public class ExamWordsJudgeServiceImpl implements ExamWordsJudgeService {
}
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()
.wordId(wordId)
.studentId(studentId)

View File

@@ -1,5 +1,6 @@
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.domain.dataobject.*;
import com.yinlihupo.enlish.service.domain.mapper.*;
@@ -36,6 +37,14 @@ public class LessonPlansServiceImpl implements LessonPlansService {
private GradeDOMapper gradeDOMapper;
@Resource
private DifyClient difyClient;
@Resource
private ExamWordsDOMapper examWordsDOMapper;
@Resource
private StudentExamWordsDOMapper studentExamWordsDOMapper;
@Resource
private StudentDOMapper studentDOMapper;
@Resource
private PlanExamDOMapper planExamDOMapper;
@Override
@@ -116,6 +125,13 @@ public class LessonPlansServiceImpl implements LessonPlansService {
.build();
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) {
log.info("生成第{}天计划失败,失败原因 {}", i + 1, e.getMessage());
}
@@ -244,6 +260,40 @@ public class LessonPlansServiceImpl implements LessonPlansService {
data.put("sentences", sentences);
data.put("sentencesAns", sentences);
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();
// Configure config = Configure.builder()
// .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 jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
@Component
@Slf4j
public class AutoJudgeExamWordsTask {
@Resource
@@ -15,7 +15,9 @@ public class AutoJudgeExamWordsTask {
@Scheduled(fixedRate = 5000)
public void autoJudgeExamWords() {
System.out.println("【固定频率】开始自动判卷,时间:" + LocalDateTime.now());
examWordsJudgeService.judgeExamWords(5);
if (examWordsJudgeService.getExamWordsJudgeResultCount() != 0) {
log.info("有试卷待检测,开始检测");
examWordsJudgeService.judgeExamWords(5);
}
}
}

View File

@@ -52,6 +52,7 @@ public class WordExportUtil {
.bind("checkListAns", policyLessonPlanWeekday)
.bind("sentences", policyLessonPlanWeekday)
.bind("sentencesAns", policyLessonPlanWeekday)
.bind("words", policyLessonPlanWeekday)
.build();
LoopRowTableRenderPolicy policyLessonPlan = new LoopRowTableRenderPolicy();
@@ -96,7 +97,7 @@ public class WordExportUtil {
} else {
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());
OutputStream out = response.getOutputStream();
template.render(map);

View File

@@ -35,7 +35,7 @@ templates:
count: 100
data: C:\project\tess
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
plan_day: 7
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"/>
<!-- 需要生成的表-实体类 -->
<table tableName="student_stage_learning_remark" domainObjectName="StudentStageLearningRemarkDO"
<table tableName="plan_exam" domainObjectName="PlanExamDO"
enableCountByExample="false"
enableUpdateByExample="false"
enableDeleteByExample="false"

View File

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

View File

@@ -61,7 +61,9 @@
<select id="selectCount" resultType="java.lang.Integer">
select count(1)
from exam_words_judge_result
where is_finished = 0
</select>
<select id="selectDetailById" resultMap="ResultMapWithBLOBs">
select *
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 {
List<VocabularyBankDO> vocabularyBankDOS = vocabularyBankDOMapper.selectVocabularyBankDOAllByUnitId(269);
List<Sentence> sentences = client.sendSentenceAnalyze(vocabularyBankDOS, "小学4年级");
} catch (Exception e) {
e.printStackTrace();

View File

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

View File

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

View File

@@ -24,25 +24,25 @@ public class TestOmr {
public void testOmr(){
OpenCV.loadLocally();
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,
3206, 3208, 3209, 3210, 3211, 3212, 3507, 3508, 3509, 3510,
3511, 3512, 3513, 3514, 3515, 3516, 3517, 3519, 3521, 3522,
3523, 3524, 3525, 3526, 3527, 3528, 3529, 3530, 3531, 3532,
3533, 3535, 3536, 3537, 3538, 3539);
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";
List<CoordinatesXY> coordinatesXIES = PngUtil.analysisXY(path);
// 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,
// 3206, 3208, 3209, 3210, 3211, 3212, 3507, 3508, 3509, 3510,
// 3511, 3512, 3513, 3514, 3515, 3516, 3517, 3519, 3521, 3522,
// 3523, 3524, 3525, 3526, 3527, 3528, 3529, 3530, 3531, 3532,
// 3533, 3535, 3536, 3537, 3538, 3539);
//
// 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";
// List<CoordinatesXY> coordinatesXIES = PngUtil.analysisXY(path);
}
@Test
public void testInteger(){
String filePath = "C:\\project\\java\\enlish_edu\\enlish\\enlish-service\\src\\main\\resources\\templates\\p3.png";
List<CoordinatesXY> coordinatesXIES = PngUtil.analysisXY(filePath);
StudentExamId studentExamId = PngUtil.analyzeExamWordsIdAndStudentId(filePath, tessdataPath, coordinatesXIES);
log.info("studentExamId:{}",studentExamId);
// String filePath = "C:\\project\\java\\enlish_edu\\enlish\\enlish-service\\src\\main\\resources\\templates\\p3.png";
// List<CoordinatesXY> coordinatesXIES = PngUtil.analysisXY(filePath);
// StudentExamId studentExamId = PngUtil.analyzeExamWordsIdAndStudentId(filePath, tessdataPath, coordinatesXIES);
// log.info("studentExamId:{}",studentExamId);
}
}

View File

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

View File

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