diff --git a/enlish-service/src/main/java/com/yinlihupo/enlish/service/config/ListWordIdTypeHandler.java b/enlish-service/src/main/java/com/yinlihupo/enlish/service/config/ListWordIdTypeHandler.java new file mode 100644 index 0000000..2cc2ecf --- /dev/null +++ b/enlish-service/src/main/java/com/yinlihupo/enlish/service/config/ListWordIdTypeHandler.java @@ -0,0 +1,59 @@ +package com.yinlihupo.enlish.service.config; + +import com.yinlihupo.framework.common.util.JsonUtils; +import org.apache.ibatis.type.BaseTypeHandler; +import org.apache.ibatis.type.JdbcType; + +import java.sql.CallableStatement; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; + +public class ListWordIdTypeHandler extends BaseTypeHandler> { + + @Override + public void setNonNullParameter(PreparedStatement ps, int i, List parameter, JdbcType jdbcType) throws SQLException { + try { + String json = JsonUtils.toJsonString(parameter); + ps.setString(i, json); + } catch (SQLException e) { + throw new SQLException("转换List为JSON字符串失败", e); + } + } + + /** + * 获取结果(从ResultSet中按列名获取):将JSON字符串转换为List + */ + @Override + public List getNullableResult(ResultSet rs, String columnName) throws SQLException { + return parseJson(rs.getString(columnName)); + } + + /** + * 获取结果(从ResultSet中按列索引获取) + */ + @Override + public List getNullableResult(ResultSet rs, int columnIndex) throws SQLException { + return parseJson(rs.getString(columnIndex)); + } + + /** + * 获取结果(从CallableStatement中获取) + */ + @Override + public List getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { + return parseJson(cs.getString(columnIndex)); + } + + private List parseJson(String json) { + if (json == null || json.isEmpty()) { + return null; + } + try { + return JsonUtils.parseList(json, Integer.class); + } catch (Exception e) { + throw new RuntimeException("转换JSON字符串为List失败", e); + } + } +} diff --git a/enlish-service/src/main/java/com/yinlihupo/enlish/service/constant/AssessmentConstant.java b/enlish-service/src/main/java/com/yinlihupo/enlish/service/constant/ExamWordsConstant.java similarity index 54% rename from enlish-service/src/main/java/com/yinlihupo/enlish/service/constant/AssessmentConstant.java rename to enlish-service/src/main/java/com/yinlihupo/enlish/service/constant/ExamWordsConstant.java index a0ef877..368f19c 100644 --- a/enlish-service/src/main/java/com/yinlihupo/enlish/service/constant/AssessmentConstant.java +++ b/enlish-service/src/main/java/com/yinlihupo/enlish/service/constant/ExamWordsConstant.java @@ -1,8 +1,8 @@ package com.yinlihupo.enlish.service.constant; -public interface AssessmentConstant { +public interface ExamWordsConstant { int PGN_COL = 53; // 文件暂存目录 linux - String ASSESSMENT_FELT = "enlish/assessment/"; + String ASSESSMENT_FELT = "enlish/exam_words/"; } diff --git a/enlish-service/src/main/java/com/yinlihupo/enlish/service/controller/AssessmentController.java b/enlish-service/src/main/java/com/yinlihupo/enlish/service/controller/AssessmentController.java deleted file mode 100644 index e769b4a..0000000 --- a/enlish-service/src/main/java/com/yinlihupo/enlish/service/controller/AssessmentController.java +++ /dev/null @@ -1,91 +0,0 @@ -package com.yinlihupo.enlish.service.controller; - - -import com.deepoove.poi.XWPFTemplate; -import com.deepoove.poi.config.Configure; -import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy; -import com.yinlihupo.enlish.service.constant.AssessmentConstant; -import com.yinlihupo.enlish.service.enums.AssessmentsType; -import com.yinlihupo.enlish.service.model.bo.CoordinatesXY; -import com.yinlihupo.enlish.service.model.bo.Word; -import com.yinlihupo.enlish.service.model.vo.assessment.AssessmentStudentReqVO; -import com.yinlihupo.enlish.service.service.AssessmentService; -import com.yinlihupo.enlish.service.utils.PngUtil; -import jakarta.annotation.Resource; -import jakarta.servlet.http.HttpServletResponse; -import lombok.extern.slf4j.Slf4j; -import org.springframework.web.bind.annotation.*; -import org.springframework.web.multipart.MultipartFile; - -import java.io.File; -import java.io.OutputStream; -import java.net.URLEncoder; -import java.nio.charset.StandardCharsets; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -@RequestMapping("/assessment/") -@RestController -@Slf4j -public class AssessmentController { - - @Resource - private AssessmentService assessmentService; - - @PatchMapping("felt") - public void generateAssessmentDocxStudent(@RequestBody AssessmentStudentReqVO assessmentStudentReqVO, HttpServletResponse response) { - Integer studentId = assessmentStudentReqVO.getStudentId(); - HashMap unitIdAndWordCount = assessmentStudentReqVO.getUnitIdAndWordCount(); - - int assessmentDocxId = assessmentService.getAssessmentDocxId(studentId, AssessmentsType.ASSESSMENT_FELT); - List assessmentWords; - if (assessmentDocxId == 0) { - assessmentWords = assessmentService.genAssessmentWords(studentId, unitIdAndWordCount); - assessmentDocxId = assessmentService.getAssessmentDocxId(studentId, AssessmentsType.ASSESSMENT_FELT); - } else { - assessmentWords = assessmentService.getAssessmentWordsById(assessmentDocxId); - } - - LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy(); - Configure config = Configure.builder() - .bind("words", policy) - .bind("answer", policy) - .build(); - - Map data = new HashMap<>(); - data.put("assessment_id", assessmentDocxId); - 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_v3.docx", config)) { - template.render(data); - String fileName = URLEncoder.encode( assessmentDocxId + "摸底测试.docx", StandardCharsets.UTF_8).replaceAll("\\+", "%20"); - response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document"); - response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + fileName); - - OutputStream out = response.getOutputStream(); - template.write(out); - - out.flush(); - out.close(); - } catch (Exception e) { - throw new RuntimeException(e); - } - - } - - @PostMapping("analyze") - public void generateAssessmentDocxAnalyze(@RequestParam("file") MultipartFile file, @RequestParam("id") Integer assessmentId) { - // 把文件暂存在本地 - String filePath = AssessmentConstant.ASSESSMENT_FELT + assessmentId + ".png"; - try { - file.transferTo(new File(filePath)); - } catch (Exception e) { - throw new RuntimeException(e); - } - - List coordinatesXIES = PngUtil.analysisXY(filePath); - } -} diff --git a/enlish-service/src/main/java/com/yinlihupo/enlish/service/controller/ExamWordsController.java b/enlish-service/src/main/java/com/yinlihupo/enlish/service/controller/ExamWordsController.java new file mode 100644 index 0000000..45effe8 --- /dev/null +++ b/enlish-service/src/main/java/com/yinlihupo/enlish/service/controller/ExamWordsController.java @@ -0,0 +1,102 @@ +package com.yinlihupo.enlish.service.controller; + + +import com.deepoove.poi.XWPFTemplate; +import com.deepoove.poi.config.Configure; +import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy; +import com.yinlihupo.enlish.service.domain.dataobject.ExamWordsDO; +import com.yinlihupo.enlish.service.domain.dataobject.VocabularyBankDO; +import com.yinlihupo.enlish.service.model.bo.Word; +import com.yinlihupo.enlish.service.model.vo.exam.GenerateExamWordsReqVO; +import com.yinlihupo.enlish.service.service.ExamWordsService; +import com.yinlihupo.enlish.service.service.VocabularyService; +import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletResponse; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.io.FileInputStream; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@RequestMapping("/exam/words/") +@RestController +@Slf4j +public class ExamWordsController { + + @Resource + private ExamWordsService examWordsService; + @Resource + private VocabularyService vocabularyService; + @Value("${templates.word}") + private String templateWordPath; + + @PostMapping("submit") + public void generateFeltExamWords(@RequestBody GenerateExamWordsReqVO generateExamWordsReqVO, HttpServletResponse response) { + Integer gradeId = generateExamWordsReqVO.getGradeId(); + Integer level = generateExamWordsReqVO.getLevel(); + List studentIds = generateExamWordsReqVO.getStudentIds(); + if (studentIds == null || studentIds.isEmpty() || gradeId == null || level == null) { + throw new RuntimeException("参数错误"); + } + try { + ExamWordsDO examWordsDO = examWordsService.generateExamWords(gradeId, level, studentIds); + List vocabularyBankDOS = vocabularyService.findVocabularyBankDOListById(examWordsDO.getWordIds()); + + List assessmentWords = vocabularyBankDOS.stream().map(vocabularyBankDO -> Word.builder() + .id(vocabularyBankDO.getId()) + .title(vocabularyBankDO.getWord()) + .definition(vocabularyBankDO.getDefinition()) + .build()).toList(); + + // 配置 POI-TL + LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy(); + Configure config = Configure.builder() + .bind("words", policy) + .bind("answer", policy) + .build(); + + Map data = new HashMap<>(); + data.put("assessment_id", examWordsDO.getId()); + data.put("words", assessmentWords); + data.put("answer", assessmentWords); + + // 2. 设置文件名编码 + String fileName = URLEncoder.encode(examWordsDO.getId() + "摸底测试.docx", StandardCharsets.UTF_8).replaceAll("\\+", "%20"); + + // 3. 设置响应头 + response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document"); + response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + fileName); + + try (InputStream inputStream = new FileInputStream(this.templateWordPath); + XWPFTemplate template = XWPFTemplate.compile(inputStream, config); + OutputStream out = response.getOutputStream()) { + + template.render(data); + template.write(out); + out.flush(); + } + + } catch (Exception e) { + + if (!response.isCommitted()) { + response.reset(); + response.setContentType("application/json;charset=UTF-8"); + throw new RuntimeException("生成试卷失败: " + e.getMessage()); + } else { + throw new RuntimeException("生成试卷导出中断", e); + } + } + } + + +} diff --git a/enlish-service/src/main/java/com/yinlihupo/enlish/service/domain/dataobject/AssessmentsDO.java b/enlish-service/src/main/java/com/yinlihupo/enlish/service/domain/dataobject/ExamWordsDO.java similarity index 54% rename from enlish-service/src/main/java/com/yinlihupo/enlish/service/domain/dataobject/AssessmentsDO.java rename to enlish-service/src/main/java/com/yinlihupo/enlish/service/domain/dataobject/ExamWordsDO.java index ddfa26b..a417953 100644 --- a/enlish-service/src/main/java/com/yinlihupo/enlish/service/domain/dataobject/AssessmentsDO.java +++ b/enlish-service/src/main/java/com/yinlihupo/enlish/service/domain/dataobject/ExamWordsDO.java @@ -5,28 +5,24 @@ import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; -import java.math.BigDecimal; import java.time.LocalDateTime; -import java.util.Date; +import java.util.List; @AllArgsConstructor @NoArgsConstructor @Data @Builder -public class AssessmentsDO { - +public class ExamWordsDO { private Integer id; - private Integer studentId; - - private LocalDateTime testDate; - - private Integer testType; + private Integer gradeId; private Integer level; - private Integer estimatedVocabSize; + private String title; - private String contentDetailsJson; + private LocalDateTime createdAt; + + private List wordIds; } \ No newline at end of file diff --git a/enlish-service/src/main/java/com/yinlihupo/enlish/service/domain/dataobject/GradeUnitDO.java b/enlish-service/src/main/java/com/yinlihupo/enlish/service/domain/dataobject/GradeUnitDO.java new file mode 100644 index 0000000..8cd07a0 --- /dev/null +++ b/enlish-service/src/main/java/com/yinlihupo/enlish/service/domain/dataobject/GradeUnitDO.java @@ -0,0 +1,20 @@ +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 GradeUnitDO { + private Integer id; + + private Integer gradeId; + + private Integer unitId; + + +} \ No newline at end of file diff --git a/enlish-service/src/main/java/com/yinlihupo/enlish/service/domain/dataobject/StudentExamWordsDO.java b/enlish-service/src/main/java/com/yinlihupo/enlish/service/domain/dataobject/StudentExamWordsDO.java new file mode 100644 index 0000000..4e0ba27 --- /dev/null +++ b/enlish-service/src/main/java/com/yinlihupo/enlish/service/domain/dataobject/StudentExamWordsDO.java @@ -0,0 +1,25 @@ +package com.yinlihupo.enlish.service.domain.dataobject; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Date; + +@AllArgsConstructor +@NoArgsConstructor +@Data +@Builder +public class StudentExamWordsDO { + private Integer id; + + private Integer studentId; + + private Integer examWordsId; + + private Integer isCompleted; + + private Date startData; + +} \ No newline at end of file diff --git a/enlish-service/src/main/java/com/yinlihupo/enlish/service/domain/mapper/AssessmentsDOMapper.java b/enlish-service/src/main/java/com/yinlihupo/enlish/service/domain/mapper/AssessmentsDOMapper.java deleted file mode 100644 index 5db630e..0000000 --- a/enlish-service/src/main/java/com/yinlihupo/enlish/service/domain/mapper/AssessmentsDOMapper.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.yinlihupo.enlish.service.domain.mapper; - -import com.yinlihupo.enlish.service.domain.dataobject.AssessmentsDO; -import org.apache.ibatis.annotations.Param; - -public interface AssessmentsDOMapper { - int deleteByPrimaryKey(Integer id); - - int insert(AssessmentsDO record); - - int insertSelective(AssessmentsDO record); - - AssessmentsDO selectByPrimaryKey(Integer id); - - int updateByPrimaryKeySelective(AssessmentsDO record); - - int updateByPrimaryKeyWithBLOBs(AssessmentsDO record); - - int updateByPrimaryKey(AssessmentsDO record); - - Integer selectAssessmentsIdByStudentIdAndTestType(@Param("studentId") Integer studentId, @Param("testType") Integer testType); - - String selectContentDetailsJsonByAssessmentsId(@Param("assessmentsId") Integer assessmentsId); -} \ No newline at end of file diff --git a/enlish-service/src/main/java/com/yinlihupo/enlish/service/domain/mapper/ExamWordsDOMapper.java b/enlish-service/src/main/java/com/yinlihupo/enlish/service/domain/mapper/ExamWordsDOMapper.java new file mode 100644 index 0000000..2250ab3 --- /dev/null +++ b/enlish-service/src/main/java/com/yinlihupo/enlish/service/domain/mapper/ExamWordsDOMapper.java @@ -0,0 +1,8 @@ +package com.yinlihupo.enlish.service.domain.mapper; + +import com.yinlihupo.enlish.service.domain.dataobject.ExamWordsDO; + +public interface ExamWordsDOMapper { + + int insert(ExamWordsDO record); +} \ No newline at end of file diff --git a/enlish-service/src/main/java/com/yinlihupo/enlish/service/domain/mapper/GradeUnitDOMapper.java b/enlish-service/src/main/java/com/yinlihupo/enlish/service/domain/mapper/GradeUnitDOMapper.java new file mode 100644 index 0000000..6ed5767 --- /dev/null +++ b/enlish-service/src/main/java/com/yinlihupo/enlish/service/domain/mapper/GradeUnitDOMapper.java @@ -0,0 +1,10 @@ +package com.yinlihupo.enlish.service.domain.mapper; + +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +public interface GradeUnitDOMapper { + + List selectUnitIdsByGradeId(@Param("gradeId") Integer gradeId); +} \ No newline at end of file diff --git a/enlish-service/src/main/java/com/yinlihupo/enlish/service/domain/mapper/StudentExamWordsDOMapper.java b/enlish-service/src/main/java/com/yinlihupo/enlish/service/domain/mapper/StudentExamWordsDOMapper.java new file mode 100644 index 0000000..ab6f816 --- /dev/null +++ b/enlish-service/src/main/java/com/yinlihupo/enlish/service/domain/mapper/StudentExamWordsDOMapper.java @@ -0,0 +1,11 @@ +package com.yinlihupo.enlish.service.domain.mapper; + + +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +public interface StudentExamWordsDOMapper { + + int insertStudentsExam(@Param("studentIds") List studentIds, @Param("examWordsId") Integer examWordsId); +} \ No newline at end of file diff --git a/enlish-service/src/main/java/com/yinlihupo/enlish/service/domain/mapper/VocabularyBankDOMapper.java b/enlish-service/src/main/java/com/yinlihupo/enlish/service/domain/mapper/VocabularyBankDOMapper.java index 4418c3f..896783c 100644 --- a/enlish-service/src/main/java/com/yinlihupo/enlish/service/domain/mapper/VocabularyBankDOMapper.java +++ b/enlish-service/src/main/java/com/yinlihupo/enlish/service/domain/mapper/VocabularyBankDOMapper.java @@ -6,17 +6,10 @@ import org.apache.ibatis.annotations.Param; import java.util.List; public interface VocabularyBankDOMapper { - int deleteByPrimaryKey(Integer id); - - int insert(VocabularyBankDO record); int insertSelective(VocabularyBankDO record); - VocabularyBankDO selectByPrimaryKey(Integer id); - - int updateByPrimaryKeySelective(VocabularyBankDO record); - - int updateByPrimaryKey(VocabularyBankDO record); - List selectVocabularyBankDOListByUnitId(@Param("unitId") Integer unitId, @Param("wordCount") Integer wordCount); + + List selectVocabularyBankDOListByIds(@Param("ids") List ids); } \ No newline at end of file diff --git a/enlish-service/src/main/java/com/yinlihupo/enlish/service/model/vo/assessment/AssessmentStudentReqVO.java b/enlish-service/src/main/java/com/yinlihupo/enlish/service/model/vo/assessment/AssessmentStudentReqVO.java deleted file mode 100644 index 00f4460..0000000 --- a/enlish-service/src/main/java/com/yinlihupo/enlish/service/model/vo/assessment/AssessmentStudentReqVO.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.yinlihupo.enlish.service.model.vo.assessment; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -import java.util.HashMap; - -// 进行摸底测试 -@AllArgsConstructor -@NoArgsConstructor -@Data -@Builder -public class AssessmentStudentReqVO { - - /** - * 学生 id - */ - private Integer studentId; - - - /** - * 单元 id 和词数 - */ - private HashMap unitIdAndWordCount; -} diff --git a/enlish-service/src/main/java/com/yinlihupo/enlish/service/model/vo/exam/GenerateExamWordsReqVO.java b/enlish-service/src/main/java/com/yinlihupo/enlish/service/model/vo/exam/GenerateExamWordsReqVO.java new file mode 100644 index 0000000..da093ba --- /dev/null +++ b/enlish-service/src/main/java/com/yinlihupo/enlish/service/model/vo/exam/GenerateExamWordsReqVO.java @@ -0,0 +1,20 @@ +package com.yinlihupo.enlish.service.model.vo.exam; + + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +@AllArgsConstructor +@NoArgsConstructor +@Data +@Builder +public class GenerateExamWordsReqVO { + + private Integer gradeId; + private Integer level; + private List studentIds; +} diff --git a/enlish-service/src/main/java/com/yinlihupo/enlish/service/service/AssessmentService.java b/enlish-service/src/main/java/com/yinlihupo/enlish/service/service/AssessmentService.java deleted file mode 100644 index abae1df..0000000 --- a/enlish-service/src/main/java/com/yinlihupo/enlish/service/service/AssessmentService.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.yinlihupo.enlish.service.service; - - -import com.yinlihupo.enlish.service.enums.AssessmentsType; -import com.yinlihupo.enlish.service.model.bo.Word; - -import java.util.HashMap; -import java.util.List; - -public interface AssessmentService { - - List genAssessmentWords(Integer studentId, HashMap unitIdAndWordCount); - - Integer getAssessmentDocxId(Integer studentId, AssessmentsType assessmentsType); - - List getAssessmentWordsById(Integer id); -} diff --git a/enlish-service/src/main/java/com/yinlihupo/enlish/service/service/ExamWordsService.java b/enlish-service/src/main/java/com/yinlihupo/enlish/service/service/ExamWordsService.java new file mode 100644 index 0000000..f85c174 --- /dev/null +++ b/enlish-service/src/main/java/com/yinlihupo/enlish/service/service/ExamWordsService.java @@ -0,0 +1,13 @@ +package com.yinlihupo.enlish.service.service; + + +import com.yinlihupo.enlish.service.domain.dataobject.ExamWordsDO; + +import java.util.List; + +public interface ExamWordsService { + + ExamWordsDO generateExamWords(Integer gradeId, Integer level, List studentIds); + + +} diff --git a/enlish-service/src/main/java/com/yinlihupo/enlish/service/service/VocabularyService.java b/enlish-service/src/main/java/com/yinlihupo/enlish/service/service/VocabularyService.java new file mode 100644 index 0000000..41f1a23 --- /dev/null +++ b/enlish-service/src/main/java/com/yinlihupo/enlish/service/service/VocabularyService.java @@ -0,0 +1,11 @@ +package com.yinlihupo.enlish.service.service; + + +import com.yinlihupo.enlish.service.domain.dataobject.VocabularyBankDO; + +import java.util.List; + +public interface VocabularyService { + + List findVocabularyBankDOListById(List ids); +} diff --git a/enlish-service/src/main/java/com/yinlihupo/enlish/service/service/assessment/AssessmentServiceImpl.java b/enlish-service/src/main/java/com/yinlihupo/enlish/service/service/assessment/AssessmentServiceImpl.java deleted file mode 100644 index 2950db4..0000000 --- a/enlish-service/src/main/java/com/yinlihupo/enlish/service/service/assessment/AssessmentServiceImpl.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.yinlihupo.enlish.service.service.assessment; - -import com.yinlihupo.enlish.service.domain.dataobject.AssessmentsDO; -import com.yinlihupo.enlish.service.domain.dataobject.VocabularyBankDO; -import com.yinlihupo.enlish.service.domain.mapper.AssessmentsDOMapper; -import com.yinlihupo.enlish.service.domain.mapper.VocabularyBankDOMapper; -import com.yinlihupo.enlish.service.domain.mapper.WordMasteryLogDOMapper; -import com.yinlihupo.enlish.service.enums.AssessmentsType; -import com.yinlihupo.enlish.service.model.bo.Word; -import com.yinlihupo.enlish.service.service.AssessmentService; -import com.yinlihupo.framework.common.util.JsonUtils; -import jakarta.annotation.Resource; -import org.springframework.stereotype.Service; - -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -@Service -public class AssessmentServiceImpl implements AssessmentService { - - @Resource - private VocabularyBankDOMapper vocabularyBankDOMapper; - @Resource - private WordMasteryLogDOMapper wordMasteryLogDOMapper; - @Resource - private AssessmentsDOMapper assessmentsDOMapper; - - @Override - public List genAssessmentWords(Integer studentId, HashMap unitIdAndWordCount) { - - List words = new ArrayList<>(); - for (Map.Entry entry : unitIdAndWordCount.entrySet()) { - Integer unitId = entry.getKey(); - Integer wordCount = entry.getValue(); - - List vocabularyBankDOS = vocabularyBankDOMapper.selectVocabularyBankDOListByUnitId(unitId, wordCount); - words.addAll( - vocabularyBankDOS.stream() - .map(vocabularyBankDO -> Word.builder() - .id(vocabularyBankDO.getId()) - .title(vocabularyBankDO.getWord()) - .definition(vocabularyBankDO.getDefinition()) - .build()) - .toList() - ); - } - - assessmentsDOMapper.insertSelective( - AssessmentsDO.builder() - .studentId(studentId) - .level(0) - .testType(AssessmentsType.ASSESSMENT_FELT.getId()) - .testDate(LocalDateTime.now()) - .estimatedVocabSize(0) - .contentDetailsJson(JsonUtils.toJsonString(words)) - .build() - ); - - return words; - } - - @Override - public Integer getAssessmentDocxId(Integer studentId, AssessmentsType assessmentsType) { - return assessmentsDOMapper.selectAssessmentsIdByStudentIdAndTestType(studentId, assessmentsType.getId()); - } - - @Override - public List getAssessmentWordsById(Integer id) { - String contentJson = assessmentsDOMapper.selectContentDetailsJsonByAssessmentsId(id); - try { - return JsonUtils.parseList(contentJson, Word.class); - } catch (Exception e) { - throw new RuntimeException(e); - } - - } - - -} diff --git a/enlish-service/src/main/java/com/yinlihupo/enlish/service/service/exam/ExamWordsServiceImpl.java b/enlish-service/src/main/java/com/yinlihupo/enlish/service/service/exam/ExamWordsServiceImpl.java new file mode 100644 index 0000000..6e94ad7 --- /dev/null +++ b/enlish-service/src/main/java/com/yinlihupo/enlish/service/service/exam/ExamWordsServiceImpl.java @@ -0,0 +1,78 @@ +package com.yinlihupo.enlish.service.service.exam; + +import com.yinlihupo.enlish.service.domain.dataobject.ExamWordsDO; +import com.yinlihupo.enlish.service.domain.dataobject.VocabularyBankDO; +import com.yinlihupo.enlish.service.domain.mapper.ExamWordsDOMapper; +import com.yinlihupo.enlish.service.domain.mapper.GradeUnitDOMapper; +import com.yinlihupo.enlish.service.domain.mapper.StudentExamWordsDOMapper; +import com.yinlihupo.enlish.service.domain.mapper.VocabularyBankDOMapper; +import com.yinlihupo.enlish.service.service.ExamWordsService; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.multipart.MultipartFile; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +@Service +@Slf4j +public class ExamWordsServiceImpl implements ExamWordsService { + + @Resource + private GradeUnitDOMapper gradeUnitDOMapper; + @Resource + private VocabularyBankDOMapper vocabularyBankDOMapper; + @Value("${templates.count}") + private Integer wordCount; + @Resource + private ExamWordsDOMapper examWordsDOMapper; + @Resource + private StudentExamWordsDOMapper studentExamWordsDOMapper; + + @Override + @Transactional(rollbackFor = RuntimeException.class) + public ExamWordsDO generateExamWords(Integer gradeId, Integer level, List studentIds) { + + List unitIds = gradeUnitDOMapper.selectUnitIdsByGradeId(gradeId); + List vocabularyBankDOS = new ArrayList<>(); + int count = wordCount; + for (Integer unitId : unitIds) { + List words = vocabularyBankDOMapper.selectVocabularyBankDOListByUnitId(unitId, 20); + vocabularyBankDOS.addAll(words); + count -= 20; + if (count <= 0) { + break; + } + } + ExamWordsDO examWordsDO = ExamWordsDO.builder() + .gradeId(gradeId) + .level(level) + .title("测试") + .createdAt(LocalDateTime.now()) + .wordIds(vocabularyBankDOS.stream().map(VocabularyBankDO::getId).toList()) + .build(); + + int insert = examWordsDOMapper.insert(examWordsDO); + if (insert <= 0) { + throw new RuntimeException("插入考试失败"); + } + + int insertStudentsExam = studentExamWordsDOMapper.insertStudentsExam(studentIds, examWordsDO.getId()); + if (insertStudentsExam <= 0) { + throw new RuntimeException("插入学生关联考试失败"); + } + + return examWordsDO; + } + + @PostMapping("analyze") + public void generateAssessmentDocxAnalyze(@RequestParam("file") MultipartFile file, @RequestParam("id") Integer id) { + + } +} diff --git a/enlish-service/src/main/java/com/yinlihupo/enlish/service/service/vocabulary/VocabularyServiceImpl.java b/enlish-service/src/main/java/com/yinlihupo/enlish/service/service/vocabulary/VocabularyServiceImpl.java new file mode 100644 index 0000000..7e52bb5 --- /dev/null +++ b/enlish-service/src/main/java/com/yinlihupo/enlish/service/service/vocabulary/VocabularyServiceImpl.java @@ -0,0 +1,22 @@ +package com.yinlihupo.enlish.service.service.vocabulary; + +import com.yinlihupo.enlish.service.domain.dataobject.VocabularyBankDO; +import com.yinlihupo.enlish.service.domain.mapper.VocabularyBankDOMapper; +import com.yinlihupo.enlish.service.service.VocabularyService; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.util.List; +@Service +@Slf4j +public class VocabularyServiceImpl implements VocabularyService { + + @Resource + private VocabularyBankDOMapper vocabularyBankDOMapper; + + @Override + public List findVocabularyBankDOListById(List ids) { + return vocabularyBankDOMapper.selectVocabularyBankDOListByIds(ids); + } +} diff --git a/enlish-service/src/main/java/com/yinlihupo/enlish/service/utils/PngUtil.java b/enlish-service/src/main/java/com/yinlihupo/enlish/service/utils/PngUtil.java index 56d844d..42a4b69 100644 --- a/enlish-service/src/main/java/com/yinlihupo/enlish/service/utils/PngUtil.java +++ b/enlish-service/src/main/java/com/yinlihupo/enlish/service/utils/PngUtil.java @@ -1,6 +1,6 @@ package com.yinlihupo.enlish.service.utils; -import com.yinlihupo.enlish.service.constant.AssessmentConstant; +import com.yinlihupo.enlish.service.constant.ExamWordsConstant; import com.yinlihupo.enlish.service.model.bo.CoordinatesXY; import com.yinlihupo.enlish.service.model.bo.Word; import lombok.extern.slf4j.Slf4j; @@ -91,7 +91,7 @@ public class PngUtil { // 获取每一列的宽度 list.sort(Comparator.comparingInt(CoordinatesXY::getHeight)); - int height = list.get(list.size() - 1).getHeight() / AssessmentConstant.PGN_COL; + int height = list.get(list.size() - 1).getHeight() / ExamWordsConstant.PGN_COL; // 删除两列答题卡区块 list.sort(Comparator.comparingInt(CoordinatesXY::getWidth)); @@ -139,7 +139,7 @@ public class PngUtil { int currentX = coordinatesXY.getX(); int currentY = coordinatesXY.getY(); - int count = i == 0 ? AssessmentConstant.PGN_COL - 1 : AssessmentConstant.PGN_COL; + int count = i == 0 ? ExamWordsConstant.PGN_COL - 1 : ExamWordsConstant.PGN_COL; // 内层循环:遍历这一列的每一行 for (int j = 0; j < count; j++) { diff --git a/enlish-service/src/main/resources/config/application-dev.yml b/enlish-service/src/main/resources/config/application-dev.yml index dfbd476..b8b351a 100644 --- a/enlish-service/src/main/resources/config/application-dev.yml +++ b/enlish-service/src/main/resources/config/application-dev.yml @@ -19,3 +19,10 @@ spring: max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制) min-idle: 0 # 连接池中的最小空闲连接 max-idle: 10 # 连接池中的最大空闲连接 + + +templates: + word: C:\project\java\enlish_edu\enlish\enlish-service\src\main\resources\templates\assessment_v5.docx + count: 100 +tmp: + png: C:\project\java\enlish_edu\enlish\enlish-service\src\main\resources\tmp\png \ No newline at end of file diff --git a/enlish-service/src/main/resources/generatorConfig.xml b/enlish-service/src/main/resources/generatorConfig.xml index cec6772..8a856d9 100644 --- a/enlish-service/src/main/resources/generatorConfig.xml +++ b/enlish-service/src/main/resources/generatorConfig.xml @@ -45,7 +45,7 @@ targetProject="src/main/java"/> - - - - - - - - - - - - - - - - - id, student_id, test_date, test_type, level, estimated_vocab_size - - - - content_details_json - - - - - - delete from assessments - where id = #{id,jdbcType=INTEGER} - - - - insert into assessments (id, student_id, test_date, - test_type, level, estimated_vocab_size, - content_details_json) - values (#{id,jdbcType=INTEGER}, #{studentId,jdbcType=INTEGER}, #{testDate,jdbcType=TIMESTAMP}, - #{testType,jdbcType=INTEGER}, #{level,jdbcType=INTEGER}, #{estimatedVocabSize,jdbcType=INTEGER}, - #{contentDetailsJson,jdbcType=LONGVARCHAR}) - - - - insert into assessments - - - id, - - - student_id, - - - test_date, - - - test_type, - - - level, - - - estimated_vocab_size, - - - content_details_json, - - - - - #{id,jdbcType=INTEGER}, - - - #{studentId,jdbcType=INTEGER}, - - - #{testDate,jdbcType=TIMESTAMP}, - - - #{testType,jdbcType=INTEGER}, - - - #{level,jdbcType=INTEGER}, - - - #{estimatedVocabSize,jdbcType=INTEGER}, - - - #{contentDetailsJson,jdbcType=LONGVARCHAR}, - - - - - - update assessments - - - student_id = #{studentId,jdbcType=INTEGER}, - - - test_date = #{testDate,jdbcType=TIMESTAMP}, - - - test_type = #{testType,jdbcType=INTEGER}, - - - level = #{level,jdbcType=INTEGER}, - - - estimated_vocab_size = #{estimatedVocabSize,jdbcType=INTEGER}, - - - content_details_json = #{contentDetailsJson,jdbcType=LONGVARCHAR}, - - - where id = #{id,jdbcType=INTEGER} - - - - update assessments - set student_id = #{studentId,jdbcType=INTEGER}, - test_date = #{testDate,jdbcType=TIMESTAMP}, - test_type = #{testType,jdbcType=INTEGER}, - level = #{level,jdbcType=INTEGER}, - estimated_vocab_size = #{estimatedVocabSize,jdbcType=INTEGER}, - content_details_json = #{contentDetailsJson,jdbcType=LONGVARCHAR} - where id = #{id,jdbcType=INTEGER} - - - - update assessments - set student_id = #{studentId,jdbcType=INTEGER}, - test_date = #{testDate,jdbcType=TIMESTAMP}, - test_type = #{testType,jdbcType=INTEGER}, - level = #{level,jdbcType=INTEGER}, - estimated_vocab_size = #{estimatedVocabSize,jdbcType=INTEGER} - where id = #{id,jdbcType=INTEGER} - - - - - - - \ No newline at end of file diff --git a/enlish-service/src/main/resources/mapper/ExamWordsDOMapper.xml b/enlish-service/src/main/resources/mapper/ExamWordsDOMapper.xml new file mode 100644 index 0000000..a20075e --- /dev/null +++ b/enlish-service/src/main/resources/mapper/ExamWordsDOMapper.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + 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}) + + + + \ No newline at end of file diff --git a/enlish-service/src/main/resources/mapper/GradeUnitDOMapper.xml b/enlish-service/src/main/resources/mapper/GradeUnitDOMapper.xml new file mode 100644 index 0000000..3f87644 --- /dev/null +++ b/enlish-service/src/main/resources/mapper/GradeUnitDOMapper.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/enlish-service/src/main/resources/mapper/StudentExamWordsDOMapper.xml b/enlish-service/src/main/resources/mapper/StudentExamWordsDOMapper.xml new file mode 100644 index 0000000..c4e802a --- /dev/null +++ b/enlish-service/src/main/resources/mapper/StudentExamWordsDOMapper.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + insert into student_exam_words + (student_id, exam_words_id, is_completed, start_data) + values + + (#{studentId}, #{examWordsId}, 0, now()) + + + + + \ No newline at end of file diff --git a/enlish-service/src/main/resources/mapper/VocabularyBankDOMapper.xml b/enlish-service/src/main/resources/mapper/VocabularyBankDOMapper.xml index 4616f99..0588f87 100644 --- a/enlish-service/src/main/resources/mapper/VocabularyBankDOMapper.xml +++ b/enlish-service/src/main/resources/mapper/VocabularyBankDOMapper.xml @@ -9,27 +9,6 @@ - - id, word, `definition`, pronunciation, unit_id - - - - - - delete from vocabulary_bank - where id = #{id,jdbcType=INTEGER} - - - - insert into vocabulary_bank (id, word, `definition`, pronunciation, unit_id) - values (#{id,jdbcType=INTEGER}, #{word,jdbcType=VARCHAR}, #{definition,jdbcType=VARCHAR}, - #{pronunciation,jdbcType=VARCHAR}, #{unitId,jdbcType=INTEGER}) - insert into vocabulary_bank @@ -69,39 +48,19 @@ - - update vocabulary_bank - - - word = #{word,jdbcType=VARCHAR}, - - - `definition` = #{definition,jdbcType=VARCHAR}, - - - pronunciation = #{pronunciation,jdbcType=VARCHAR}, - - - unit_id = #{unitId,jdbcType=INTEGER}, - - - where id = #{id,jdbcType=INTEGER} - - - - update vocabulary_bank - set word = #{word,jdbcType=VARCHAR}, - `definition` = #{definition,jdbcType=VARCHAR}, - pronunciation = #{pronunciation,jdbcType=VARCHAR}, - unit_id = #{unitId,jdbcType=INTEGER} - where id = #{id,jdbcType=INTEGER} - - + \ No newline at end of file diff --git a/enlish-service/src/main/resources/templates/assessment_v5.docx b/enlish-service/src/main/resources/templates/assessment_v5.docx new file mode 100644 index 0000000..ce38579 Binary files /dev/null and b/enlish-service/src/main/resources/templates/assessment_v5.docx differ diff --git a/enlish-service/src/test/java/com/yinlihupo/enlish/service/omr/TestOmr.java b/enlish-service/src/test/java/com/yinlihupo/enlish/service/omr/TestOmr.java index 700a7ac..f075525 100644 --- a/enlish-service/src/test/java/com/yinlihupo/enlish/service/omr/TestOmr.java +++ b/enlish-service/src/test/java/com/yinlihupo/enlish/service/omr/TestOmr.java @@ -1,28 +1,20 @@ package com.yinlihupo.enlish.service.omr; -import com.yinlihupo.enlish.service.enums.AssessmentsType; import com.yinlihupo.enlish.service.model.bo.CoordinatesXY; -import com.yinlihupo.enlish.service.model.bo.Word; -import com.yinlihupo.enlish.service.service.AssessmentService; import com.yinlihupo.enlish.service.utils.PngUtil; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import nu.pattern.OpenCV; import org.junit.jupiter.api.Test; -import org.opencv.core.*; import org.springframework.boot.test.context.SpringBootTest; import java.util.Arrays; -import java.util.HashMap; import java.util.List; @SpringBootTest @Slf4j public class TestOmr { - @Resource - private AssessmentService assessmentService; - @Test public void testOmr(){ OpenCV.loadLocally(); @@ -38,28 +30,7 @@ public class TestOmr { String path = "C:\\project\\java\\enlish_edu\\enlish\\enlish-service\\src\\main\\resources\\templates\\p3.png"; List coordinatesXIES = PngUtil.analysisXY(path); - for (CoordinatesXY coordinatesXY : coordinatesXIES) { - log.info("坐标: {}", coordinatesXY); - } - Integer studentId = 1; - HashMap unitIdAndWordCount = new HashMap<>(); - unitIdAndWordCount.put(142, 30); - unitIdAndWordCount.put(132, 40); - - Integer assessmentDocxId = assessmentService.getAssessmentDocxId(studentId, AssessmentsType.ASSESSMENT_FELT); - List assessmentWords; - if (assessmentDocxId == null || assessmentDocxId == 0) { - assessmentWords = assessmentService.genAssessmentWords(studentId, unitIdAndWordCount); - } else { - assessmentWords = assessmentService.getAssessmentWordsById(assessmentDocxId); - } - - List integers = PngUtil.analyzePngForUnmemorizedWordIds(path, assessmentWords, coordinatesXIES); - - for (Integer integer : integers) { - log.info("未背熟的单词ID: {}", integer); - } } diff --git a/enlish-service/src/test/java/com/yinlihupo/enlish/service/service/assessmentTest.java b/enlish-service/src/test/java/com/yinlihupo/enlish/service/service/assessmentTest.java deleted file mode 100644 index 609fac6..0000000 --- a/enlish-service/src/test/java/com/yinlihupo/enlish/service/service/assessmentTest.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.yinlihupo.enlish.service.service; - -import com.deepoove.poi.XWPFTemplate; -import com.deepoove.poi.config.Configure; -import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy; -import com.yinlihupo.enlish.service.enums.AssessmentsType; -import com.yinlihupo.enlish.service.model.bo.Word; -import jakarta.annotation.Resource; -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.SpringBootTest; - -import java.io.FileOutputStream; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -@SpringBootTest -public class assessmentTest { - - @Resource - private AssessmentService assessmentService; - - @Test - public void generateAssessmentDocxStudent() { - - Integer studentId = 1; - HashMap unitIdAndWordCount = new HashMap<>(); - unitIdAndWordCount.put(142, 30); - unitIdAndWordCount.put(132, 40); - - Integer assessmentDocxId = assessmentService.getAssessmentDocxId(studentId, AssessmentsType.ASSESSMENT_FELT); - List assessmentWords; - if (assessmentDocxId == null || assessmentDocxId == 0) { - assessmentWords = assessmentService.genAssessmentWords(studentId, unitIdAndWordCount); - assessmentDocxId = assessmentService.getAssessmentDocxId(studentId, AssessmentsType.ASSESSMENT_FELT); - } else { - assessmentWords = assessmentService.getAssessmentWordsById(assessmentDocxId); - } - - LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy(); - Configure config = Configure.builder() - .bind("words", policy) - .build(); - - Map data = new HashMap<>(); - data.put("assessment_id", assessmentDocxId); - data.put("words", assessmentWords); - - // 4. 渲染并输出 - try (XWPFTemplate template = XWPFTemplate.compile("C:\\project\\java\\enlish_edu\\enlish\\enlish-service\\src\\main\\resources\\templates\\assessment_v4.docx", config)) { - template.render(data); - template.write(new FileOutputStream("学生单词测试卷.docx")); - System.out.println("文档生成成功!"); - } catch (Exception e) { - e.printStackTrace(); - } - } -} diff --git a/enlish-service/src/test/java/com/yinlihupo/enlish/service/service/exam/ExamTest.java b/enlish-service/src/test/java/com/yinlihupo/enlish/service/service/exam/ExamTest.java new file mode 100644 index 0000000..bc97766 --- /dev/null +++ b/enlish-service/src/test/java/com/yinlihupo/enlish/service/service/exam/ExamTest.java @@ -0,0 +1,57 @@ +package com.yinlihupo.enlish.service.service.exam; + +import com.deepoove.poi.XWPFTemplate; +import com.deepoove.poi.config.Configure; +import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy; +import com.yinlihupo.enlish.service.domain.dataobject.ExamWordsDO; +import com.yinlihupo.enlish.service.domain.dataobject.VocabularyBankDO; +import com.yinlihupo.enlish.service.model.bo.Word; +import com.yinlihupo.enlish.service.service.ExamWordsService; +import com.yinlihupo.enlish.service.service.VocabularyService; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +import java.io.FileOutputStream; +import java.util.*; + +@SpringBootTest +@Slf4j +public class ExamTest { + + @Resource + private ExamWordsService examWordsService; + @Resource + private VocabularyService vocabularyService; + @Test + public void test() { + ExamWordsDO examWordsDO = examWordsService.generateExamWords(5, 0, List.of(1)); + log.info("{}", examWordsDO); + List vocabularyBankDOS = vocabularyService.findVocabularyBankDOListById(examWordsDO.getWordIds()); + List 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 data = new HashMap<>(); + data.put("id", examWordsDO.getId()); + data.put("words", 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(); + } + } +}