From 770173ad54c591691506468f908357619ee0bfc2 Mon Sep 17 00:00:00 2001 From: "MSI\\letre" Date: Mon, 7 Jul 2025 16:02:11 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90=E6=96=B0=E5=A2=9E=E3=80=91=20windows?= =?UTF-8?q?=E7=BD=91=E7=BB=9C=E8=AE=BE=E7=BD=AE1=E3=80=81=E7=94=9F?= =?UTF-8?q?=E6=88=90=E6=96=87=E4=BB=B62=E3=80=81=E5=88=A4=E5=88=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AutoForWinEdgeSettingService.java | 17 + .../AutoForWinEdgeSettingServiceImpl.java | 311 ++++++++++++++++++ 2 files changed, 328 insertions(+) create mode 100644 src/main/java/com/example/exam/exam/service/autoForWinEdgeSetting/AutoForWinEdgeSettingService.java create mode 100644 src/main/java/com/example/exam/exam/service/autoForWinEdgeSetting/AutoForWinEdgeSettingServiceImpl.java diff --git a/src/main/java/com/example/exam/exam/service/autoForWinEdgeSetting/AutoForWinEdgeSettingService.java b/src/main/java/com/example/exam/exam/service/autoForWinEdgeSetting/AutoForWinEdgeSettingService.java new file mode 100644 index 0000000..6d9e055 --- /dev/null +++ b/src/main/java/com/example/exam/exam/service/autoForWinEdgeSetting/AutoForWinEdgeSettingService.java @@ -0,0 +1,17 @@ +package com.example.exam.exam.service.autoForWinEdgeSetting; + +import com.example.exam.exam.controller.auto.vo.StuInfoVo; + +import java.io.IOException; +import java.math.BigDecimal; +import java.util.List; + +/** + * @author REN + */ +public interface AutoForWinEdgeSettingService { + + String autoForEdgeToJson(List stuInfoVo); + + BigDecimal autoForEdge(StuInfoVo stuInfoVo) throws IOException; +} diff --git a/src/main/java/com/example/exam/exam/service/autoForWinEdgeSetting/AutoForWinEdgeSettingServiceImpl.java b/src/main/java/com/example/exam/exam/service/autoForWinEdgeSetting/AutoForWinEdgeSettingServiceImpl.java new file mode 100644 index 0000000..5eb544a --- /dev/null +++ b/src/main/java/com/example/exam/exam/service/autoForWinEdgeSetting/AutoForWinEdgeSettingServiceImpl.java @@ -0,0 +1,311 @@ +package com.example.exam.exam.service.autoForWinEdgeSetting; + +import com.example.exam.exam.controller.auto.vo.StuInfoVo; +import com.example.exam.exam.dal.*; +import com.example.exam.exam.mapper.EducationPaperMapper; +import com.example.exam.exam.mapper.EducationPaperQuMapper; +import com.example.exam.exam.mapper.EducationPaperSchemeMapper; +import com.example.exam.exam.service.autoforchoice.AutoForChoiceService; +import com.example.exam.exam.service.c.JudgementService; +import com.example.exam.exam.service.question.IExamQuestionService; +import com.example.exam.exam.service.stupaperscore.StuPaperScoreService; +import com.example.exam.exam.service.tenant.SystemTenantService; +import com.example.exam.exam.service.wpspptx.WpsPptxJudgementDto; +import com.example.exam.exam.utils.HtmlAppender; +import com.example.exam.exam.utils.c.LogFileUtils; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import jakarta.annotation.Resource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.math.BigDecimal; +import java.util.*; + +@Service +public class AutoForWinEdgeSettingServiceImpl implements AutoForWinEdgeSettingService { + + @Resource + JudgementService judgementService; + @Resource + EducationPaperSchemeMapper educationPaperSchemeMapper; + @Resource + IExamQuestionService examQuestionService; + @Resource + EducationPaperQuMapper educationPaperQuMapper; + @Resource + StuPaperScoreService stuPaperScoreService; + @Resource + SystemTenantService systemTenantService; + @Autowired + private EducationPaperMapper educationPaperMapper; + /** + * 自动判题选择题 + * @param stuInfoVo 学生考试信息 + * @return 是否通过 + */ + @Override + public String autoForEdgeToJson(List stuInfoVo) { + // 写入到文件夹 + for (StuInfoVo infoVo : stuInfoVo) { + // 试题ID + String quId = infoVo.getQuestionId(); + String edgeAnswerKey = infoVo.getEdgeAnswerKeys(); + String edgeAnswerValue = infoVo.getEdgeAnswerValues(); + // 保存ID路径 + String filePath = infoVo.getFilePath(); + File file = new File(filePath + "/"+ quId +"@EdgeDummy.json"); + if (!file.exists()) { + LogFileUtils.createFile(filePath + "/"+ quId +"@EdgeDummy.json"); + } + Map map = new HashMap<>(); + map.put(edgeAnswerKey, edgeAnswerValue); + writeMapToJson(map, filePath + "/"+ quId +"@EdgeDummy.json"); + } + + return "成功"; + } + + @Override + public BigDecimal autoForEdge(StuInfoVo stuInfoVo) throws IOException { + SystemTenant systemTenant = systemTenantService.getId(stuInfoVo.getSchoolName()); + BigDecimal score = new BigDecimal(0); + // 获取Paper下的所有windows网络设置ID + List examQuestions = educationPaperMapper.selectPaperQuByPaperId(stuInfoVo.getPaperId()); + List edgeList = new ArrayList<>(); + for (ExamQuestion examQuestion : examQuestions) { + if ("windows网络设置".equals(examQuestion.getSubjectName())) { + edgeList.add(examQuestion); + } + } + // 获取所有json文件,并取出试题ID + List resultFile = new ArrayList<>(); + File dir = new File(stuInfoVo.getFilePath()); + File[] files = dir.listFiles(); + if (files == null) return null; + for (File file : files) { + if (file.isFile() + && file.getName().contains("@EdgeDummy") + && file.getName().toLowerCase().endsWith(".json")) { + resultFile.add(file); + } + } + if (resultFile.size() == 0) return null; + List trueFileQuid = new ArrayList<>(); + List noFileQuid = new ArrayList<>(); + // 开始读取文件并进行拆分 + for (ExamQuestion examQuestion : edgeList) { + boolean fileIsTrue = false; + for (File file : resultFile) { + String quId = file.getName().split("@")[0]; + if (quId.equals(examQuestion.getQuId())) { + fileIsTrue = true; + trueFileQuid.add(quId); + break; + } + } + if (!fileIsTrue) { + noFileQuid.add(examQuestion.getQuId()); + } + } + // 查询哪些文件已经进行获取到学生作答文件了 + for (String str: trueFileQuid) { + // 查询到学生文件 + Optional fileResult = resultFile.stream().filter(resultFiles -> resultFiles.getName().contains(str)).findFirst(); + if (fileResult.isPresent()) { + File file = fileResult.get(); + // 创建 ObjectMapper 实例 + File jsonFile = new File(file.getPath()); + ObjectMapper objectMapper = new ObjectMapper(); + if (jsonFile.exists()) { + Double oneScore = 0.0; + String quId = file.getName().split("@")[0]; + List educationPaperQus = educationPaperQuMapper.selectPaperQuListByPaperId(stuInfoVo.getPaperId()); + Optional resultss = educationPaperQus.stream().filter(entry -> entry.getQuId().equals(quId)) + .findFirst(); + // 获取排序 + EducationPaperQu educationPaperQu = resultss.get(); + + // 试题分数 + List educationPaperSchemeList = educationPaperSchemeMapper.selectEducationPaperTaskByPaperId(stuInfoVo.getPaperId()); + Optional result = educationPaperSchemeList.stream().filter(quLists -> quLists.getSpName().equals("windows网络设置")).findFirst(); + String quScore = result.get().getQuScores(); + // 根据ID查询试题 + ExamQuestion examQuestion = examQuestionService.selectExamQuestionByQuId(quId); + + // 读取学生文件 + try (FileInputStream fileInputStream = new FileInputStream(jsonFile)) { + // 读取文件并转换为 JsonNode + JsonNode rootNode = objectMapper.readTree(fileInputStream); + String jsonText = objectMapper.writeValueAsString(rootNode); + // 从 JSON 文件读取并转换为 Person 对象 + Map map = objectMapper.readValue(jsonText, Map.class); + + String judgementStr = "

-----------------------------------------------------------

"; + judgementStr += "

试题序号:" + educationPaperQu.getSort() + "

"; + judgementStr += "

试题编号:" + examQuestion.getQuNum() + "

"; + judgementStr += "

试题分数:" + Double.parseDouble(quScore) + "

"; + judgementStr += "

试题名称: windows网络设置

"; + + // 考试进行比对 + for (ExamQuestionAnswer questionAnswer : examQuestion.getAnswerList()) { + boolean flag = false; + double one_sorce = 0; + for (Map.Entry entry : map.entrySet()) { + String key = entry.getKey(); + String value = entry.getValue(); + // 使用map组合成考点 + String point = key + "@" + value; + if (questionAnswer.getContent().equals(point)) { + // 说明正确 + flag = true; + // 得分 根据权重进行得分 每个选项分值 = 总分 / 总权重 + if (questionAnswer.getScoreRate().equals("1")) { + // 说明权重相等,直接平分分数 + one_sorce = Double.parseDouble(quScore) / examQuestion.getAnswerList().size(); + } else { + one_sorce = Double.parseDouble(quScore) * Double.parseDouble(questionAnswer.getScoreRate()); + } + break; + } + } + oneScore += one_sorce; + score = score.add(new BigDecimal(one_sorce)); + if (flag) { + judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "✅ " + questionAnswer.getContentIn() + " 得分成功,得分:" + one_sorce); + } else { + judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "❌ " + questionAnswer.getContentIn() + " 得分失败"); + } + } + judgementStr += "

试题得分: " + oneScore + "

"; + StuPaperScoreDO stuPaperScoreDO = stuPaperScoreService.getStuScoreByPaperIdAndQuid(stuInfoVo.getStuId(), stuInfoVo.getPaperId(), quId); + if (stuPaperScoreDO != null) { + // 说明已经是做过该题,需要更新数据 + stuPaperScoreDO.setScore(new BigDecimal(oneScore)); + stuPaperScoreDO.setContent(judgementStr); + stuPaperScoreDO.setSort(educationPaperQu.getSort()); + stuPaperScoreDO.setSubjectName("windows网络设置"); + stuPaperScoreDO.setIsTrue(oneScore == 0 ? 1 : oneScore == Double.parseDouble(quScore) ? 0 : 2); + stuPaperScoreDO.setTrueScore(new BigDecimal(quScore)); + stuPaperScoreDO.setTenantId(systemTenant.getId()); + stuPaperScoreService.updateStuPaperScore(stuPaperScoreDO); + } else { + StuPaperScoreDO insertInfo = new StuPaperScoreDO(); + insertInfo.setStuId(stuInfoVo.getStuId()); + insertInfo.setPaperId(stuInfoVo.getPaperId()); + insertInfo.setQuId(quId); + insertInfo.setScore(new BigDecimal(oneScore)); + insertInfo.setContent(judgementStr); + insertInfo.setSort(educationPaperQu.getSort()); + insertInfo.setSubjectName("windows网络设置"); + stuPaperScoreDO.setIsTrue(oneScore == 0 ? 1 : oneScore == Double.parseDouble(quScore) ? 0 : 2); + insertInfo.setTenantId(systemTenant.getId()); + insertInfo.setTrueScore(new BigDecimal(quScore)); + stuPaperScoreService.insertStuPaperScore(insertInfo); + } + if (fileInputStream != null) { + try { + fileInputStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + // 没有作答的题目直接0分 + for (String str: noFileQuid) { + String quId = str; + List educationPaperQus = educationPaperQuMapper.selectPaperQuListByPaperId(stuInfoVo.getPaperId()); + Optional resultss = educationPaperQus.stream().filter(entry -> entry.getQuId().equals(quId)) + .findFirst(); + // 获取排序 + EducationPaperQu educationPaperQu = resultss.get(); + + // 试题分数 + List educationPaperSchemeList = educationPaperSchemeMapper.selectEducationPaperTaskByPaperId(stuInfoVo.getPaperId()); + Optional result = educationPaperSchemeList.stream().filter(quLists -> quLists.getSpName().equals("windows网络设置")).findFirst(); + String quScore = result.get().getQuScores(); + // 根据ID查询试题 + ExamQuestion examQuestion = examQuestionService.selectExamQuestionByQuId(quId); + String judgementStr = "

-----------------------------------------------------------

"; + judgementStr += "

试题序号:" + educationPaperQu.getSort() + "

"; + judgementStr += "

试题编号:" + examQuestion.getQuNum() + "

"; + judgementStr += "

试题分数:" + Double.parseDouble(quScore) + "

"; + judgementStr += "

试题名称: windows网络设置

"; + judgementStr += "

❌ 未成功检测到作答情况

"; + judgementStr += "

试题得分: 0分

"; + StuPaperScoreDO stuPaperScoreDO = stuPaperScoreService.getStuScoreByPaperIdAndQuid(stuInfoVo.getStuId(), stuInfoVo.getPaperId(), quId); + if (stuPaperScoreDO != null) { + // 说明已经是做过该题,需要更新数据 + stuPaperScoreDO.setScore(new BigDecimal(0)); + stuPaperScoreDO.setContent(judgementStr); + stuPaperScoreDO.setSort(educationPaperQu.getSort()); + stuPaperScoreDO.setSubjectName("windows网络设置"); + stuPaperScoreDO.setIsTrue(1); + stuPaperScoreDO.setTrueScore(new BigDecimal(quScore)); + stuPaperScoreDO.setTenantId(systemTenant.getId()); + stuPaperScoreService.updateStuPaperScore(stuPaperScoreDO); + } else { + StuPaperScoreDO insertInfo = new StuPaperScoreDO(); + insertInfo.setStuId(stuInfoVo.getStuId()); + insertInfo.setPaperId(stuInfoVo.getPaperId()); + insertInfo.setQuId(quId); + insertInfo.setScore(new BigDecimal(0)); + insertInfo.setContent(judgementStr); + insertInfo.setSort(educationPaperQu.getSort()); + insertInfo.setSubjectName("windows网络设置"); + stuPaperScoreDO.setIsTrue(1); + insertInfo.setTenantId(systemTenant.getId()); + insertInfo.setTrueScore(new BigDecimal(quScore)); + stuPaperScoreService.insertStuPaperScore(insertInfo); + } + } + return score.setScale(1, BigDecimal.ROUND_HALF_UP); + } + + // 将Map写入JSON文件 + // 将Map追加到JSON文件 + public static String writeMapToJson(Map map, String filePath) { + ObjectMapper objectMapper = new ObjectMapper(); + File file = new File(filePath); + + try { + // 如果文件存在且文件不为空,尝试读取现有内容 + Map existingMap = null; + if (file.exists() && file.length() > 0) { + existingMap = objectMapper.readValue(file, Map.class); + } + + // 如果文件为空或无法读取,初始化为空的Map + if (existingMap == null) { + existingMap = new HashMap<>(); + } + + // 合并新的Map数据 + existingMap.putAll(map); + + // 将合并后的Map写入到文件 + objectMapper.writeValue(file, existingMap); + } catch (IOException e) { + e.printStackTrace(); + } + return "学生答案已经写入到 " + filePath; + } + + + public static String convertToLetter(int number) { + // 判断是否在 1 到 26 的范围内 + if (number >= 1 && number <= 26) { + return String.valueOf((char) ('A' + number - 1)); // 转换为对应的字母 + } else { + return "Invalid"; // 如果不在 1-26 范围内,返回 "Invalid" + } + } +}