【修改】 增加试题判分明细至学生端

This commit is contained in:
DESKTOP-932OMT8\REN
2025-06-12 23:44:55 +08:00
parent 1d730c955c
commit e7ec911905
19 changed files with 292 additions and 78 deletions

View File

@@ -40,4 +40,9 @@ public class StuPaperFileDO extends TenantBaseDO {
* 类型0:zip文件1:选择题文件)
*/
private int type;
/**
* 判分详情,富文本格式
*/
private String content;
}

View File

@@ -10,11 +10,13 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import pc.exam.pp.framework.common.pojo.CommonResult;
import pc.exam.pp.module.exam.dal.dataobject.ExamQuestion;
import pc.exam.pp.module.exam.dal.dataobject.student.StuPaperFileDO;
import pc.exam.pp.module.exam.dal.mysql.paper.EducationPaperQuMapper;
import pc.exam.pp.module.exam.dal.mysql.question.ExamQuestionMapper;
import pc.exam.pp.module.exam.dal.mysql.student.StuScoreVo;
import pc.exam.pp.module.exam.service.question.IExamQuestionService;
import pc.exam.pp.module.exam.service.stuPaperScore.StuPaperScoreService;
import pc.exam.pp.module.exam.service.stu_paper_file.StuPaperFileService;
import pc.exam.pp.module.judgement.controller.admin.autoTools.vo.StuPaperReqVo;
import pc.exam.pp.module.judgement.controller.admin.autoTools.vo.StuPaperScoreInfoVo;
import pc.exam.pp.module.judgement.service.auto_tools.AutoToolsService;
@@ -52,16 +54,18 @@ public class AutoToolsController {
private JudgementService judgementService;
@Resource
IExamQuestionService examQuestionService;
@Resource
StuPaperFileService stuPaperFileService;
@GetMapping("/get")
public CommonResult<BigDecimal> get(StuPaperReqVo stuPaperReqVo) throws Exception {
return autoToolsService.judgementScore(stuPaperReqVo.getStuId(),stuPaperReqVo.getPaperId());
}
@GetMapping("/getTest")
public double gets(StuPaperReqVo stuPaperReqVo) throws Exception {
ExamQuestion examQuestion = examQuestionService.selectExamQuestionByQuId(stuPaperReqVo.getPaperId());
return judgementWpsWordService.judgementWpsWord(15.0, "D:\\", "D:\\stu\\wps_word\\1\\47effcb38c696564bef41e3927ff1f5535e068b580c6726f13296ae3230f4271.docx", examQuestion);
}
// @GetMapping("/getTest")
// public double gets(StuPaperReqVo stuPaperReqVo) throws Exception {
// ExamQuestion examQuestion = examQuestionService.selectExamQuestionByQuId(stuPaperReqVo.getPaperId());
// return judgementWpsWordService.judgementWpsWord(15.0, "D:\\", "D:\\stu\\wps_word\\1\\47effcb38c696564bef41e3927ff1f5535e068b580c6726f13296ae3230f4271.docx", examQuestion);
// }
// @GetMapping("/getTests")
// public double getss(StuPaperReqVo stuPaperReqVo) throws Exception {
// ExamQuestion examQuestion = examQuestionService.selectExamQuestionByQuId(stuPaperReqVo.getPaperId());
@@ -91,6 +95,17 @@ public class AutoToolsController {
List<String> quIds = educationPaperQuMapper.selectPaperQuByPaperId(stuPaperReqVo.getPaperId());
List<ExamQuestion> examQuestionList = examQuestionMapper.selectExamQuestionListByQuIds(quIds);
stuPaperScoreInfoVos.setExamQuestionList(examQuestionList);
// 5、查询学生试卷分析
List<StuPaperFileDO> stuPaperFileDOList = stuPaperFileService.findByStuIDAndPaperId(stuPaperReqVo.getStuId(), stuPaperReqVo.getPaperId());
String judgementStr = " ";
for (StuPaperFileDO stuPaperFileDOs : stuPaperFileDOList) {
if (stuPaperFileDOs.getType() == 1) {
if (stuPaperFileDOs.getContent() != null) {
judgementStr = stuPaperFileDOs.getContent();
}
}
}
stuPaperScoreInfoVos.setPaperAnalysis(judgementStr);
return CommonResult.success(stuPaperScoreInfoVos);
}
}

View File

@@ -8,6 +8,8 @@ import pc.exam.pp.module.exam.dal.mysql.question.ExamQuestionAnswerMapper;
import pc.exam.pp.module.judgement.controller.utils.brower.BookmarkChecker;
import pc.exam.pp.module.judgement.controller.utils.brower.BookmarkDeleter;
import pc.exam.pp.module.exam.utils.file.GetDifferencesBetweenFolders;
import pc.exam.pp.module.judgement.service.auto_tools.vo.SourceAndText;
import pc.exam.pp.module.judgement.utils.HtmlAppender;
import java.io.BufferedWriter;
import java.io.File;
@@ -33,8 +35,8 @@ public class BrowserServericeImpl implements IBrowserServerice {
//谷歌浏览器
String chromeBookmarkPath = System.getenv("LOCALAPPDATA") + "\\Google\\Chrome\\User Data\\Default\\Bookmarks";
@Override
public double Judgement(double score, File file, ExamQuestion question) throws IOException {
//根据题目,查找考点
public SourceAndText Judgement(double score, File file, ExamQuestion question, String judgementStr) throws IOException {
//根据题目,查找考点
//得到该试题的得分点
//Net得分点 文件类型 文件名 考点权值
@@ -44,7 +46,7 @@ public class BrowserServericeImpl implements IBrowserServerice {
// answerList.add(new ExamQuestionAnswer("","","","","人民大学", "添加到文件夹 ", "1", "1"));
// answerList.add(new ExamQuestionAnswer("","","","","校情", "添加到文件夹", "1", "2"));
// answerList.add(new ExamQuestionAnswer("","","","","机构", "添加到文件夹", "1", "3"));
SourceAndText sourceAndText = new SourceAndText();
List<ExamQuestionAnswer> answerList = examQuestionAnswerMapper.selectExamQuestionAnswerByQuId(question.getQuId());
//判断如果类型为1为添加到文件夹的html后缀加 .html
@@ -74,13 +76,15 @@ public class BrowserServericeImpl implements IBrowserServerice {
//
// stuFiles.forEach((key, value) -> appendToFile(answerLogPath,key + " -> " + value));
appendToFile(answerLogPath,"=== 学生提交内容得分点 ===");
judgementStr = HtmlAppender.appendHtmlLine(judgementStr,"=== 学生提交内容得分点 ===");
// 计算试题总分
int totalScore = answerList.stream()
.mapToInt(a -> Integer.parseInt(a.getScoreRate()))
.sum();
//这里指挥判断存在文件夹的得分点
Integer studentScore = compareStuAndTestFiles(answerList, stuFiles,score,totalScore);
SourceAndText studentScorePojo = compareStuAndTestFiles(answerList, stuFiles,score,totalScore,judgementStr);
double studentScore = studentScorePojo.getScore();
judgementStr = studentScorePojo.getText();
//判断收藏夹得分点
for (ExamQuestionAnswer examQuestionAnswer : answerList) {
int currentScore = Integer.parseInt(examQuestionAnswer.getScoreRate()); // 当前得分
@@ -99,11 +103,14 @@ public class BrowserServericeImpl implements IBrowserServerice {
String formattedWeightScore = String.format("%.1f", weightScore);
appendToFile(answerLogPath,"✅考点"+bookmarkNameToDelete + " -> 得分权值:" + currentScore+"-> 得分:"+formattedWeightScore);
judgementStr = HtmlAppender.appendHtmlLine(judgementStr,"✅考点"+bookmarkNameToDelete + " -> 得分权值:" + currentScore+"-> 得分:"+formattedWeightScore);
//删除此书签
BookmarkDeleter.deleteBookmarkByName(chromeBookmarkPath, bookmarkNameToDelete);
}
else {
appendToFile(answerLogPath,"❌考点"+bookmarkNameToDelete + " -> 得分权值:" + currentScore+"-> 得分0");
judgementStr = HtmlAppender.appendHtmlLine(judgementStr,"❌考点"+bookmarkNameToDelete + " -> 得分权值:" + currentScore+"-> 得分0");
}
}
@@ -114,13 +121,16 @@ public class BrowserServericeImpl implements IBrowserServerice {
double roundedScoreRatio = Math.round(scoreRatio * 100.0) / 100.0; // 四舍五入到2位小数
appendToFile(answerLogPath," 得分:"+roundedScoreRatio*score);
return roundedScoreRatio*score;
sourceAndText.setScore(roundedScoreRatio*score);
return sourceAndText;
}
// 对比学生提交内容与试题得分点
static Integer compareStuAndTestFiles(List<ExamQuestionAnswer> answerList, Map<String, String> stuFiles,double score,int total) {
static SourceAndText compareStuAndTestFiles(List<ExamQuestionAnswer> answerList, Map<String, String> stuFiles,double score,int total, String judgementStr) {
int totalScore = 0; // 记录总得分
SourceAndText sourceAndText = new SourceAndText();
for (ExamQuestionAnswer answer : answerList) {
if ("添加到文件夹".equals(answer.getContentIn())) {
String filePath = answer.getContent(); // 试题文件路径
@@ -135,15 +145,17 @@ public class BrowserServericeImpl implements IBrowserServerice {
double weightScore = ((double) currentScore / total) * score;
String formattedWeightScore = String.format("%.1f", weightScore);
appendToFile(answerLogPath,"✅考点"+answer.getContent() + " -> 得分权值:" + answer.getScoreRate()+"-> 得分:"+formattedWeightScore);
judgementStr = HtmlAppender.appendHtmlLine(judgementStr,"✅考点"+answer.getContent() + " -> 得分权值:" + answer.getScoreRate()+"-> 得分:"+formattedWeightScore);
}else {
appendToFile(answerLogPath,"❌考点"+answer.getContent() + " -> 得分权值:" + answer.getScoreRate()+"-> 得分0");
judgementStr = HtmlAppender.appendHtmlLine(judgementStr,"❌考点"+answer.getContent() + " -> 得分权值:" + answer.getScoreRate()+"-> 得分0");
}
}
}
//返回累加的得分点
return totalScore;
sourceAndText.setScore(totalScore);
sourceAndText.setText(judgementStr);
return sourceAndText;
}
/**
* 将指定内容追加写入到指定文件中。

View File

@@ -1,12 +1,13 @@
package pc.exam.pp.module.judgement.controller.service.browser;
import pc.exam.pp.module.exam.dal.dataobject.ExamQuestion;
import pc.exam.pp.module.judgement.service.auto_tools.vo.SourceAndText;
import java.io.File;
import java.io.IOException;
public interface IBrowserServerice {
double Judgement(double score, File file, ExamQuestion question) throws IOException;
SourceAndText Judgement(double score, File file, ExamQuestion question, String judgementStr) throws IOException;
}

View File

@@ -6,6 +6,8 @@ import pc.exam.pp.module.exam.dal.dataobject.ExamQuestion;
import pc.exam.pp.module.exam.dal.dataobject.ExamQuestionAnswer;
import pc.exam.pp.module.exam.dal.mysql.question.ExamQuestionAnswerMapper;
import pc.exam.pp.module.exam.utils.file.GetDifferencesBetweenFolders;
import pc.exam.pp.module.judgement.service.auto_tools.vo.SourceAndText;
import pc.exam.pp.module.judgement.utils.HtmlAppender;
import java.io.BufferedWriter;
import java.io.File;
@@ -28,8 +30,8 @@ public class FileServericeImpl implements IFileServerice {
private static final DateTimeFormatter formatter =
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
@Override
public double run_file_point(double score,File file, ExamQuestion question) throws IOException {
public SourceAndText run_file_point(double score, File file, ExamQuestion question, String judgementStr) throws IOException {
SourceAndText sourceAndText = new SourceAndText();
List<ExamQuestionAnswer> answerList = examQuestionAnswerMapper.selectExamQuestionAnswerByQuId(question.getQuId());
//todo 得到学生的考题答案
@@ -60,22 +62,28 @@ public class FileServericeImpl implements IFileServerice {
.mapToInt(a -> Integer.parseInt(a.getScoreRate()))
.sum();
appendToFile(answerLogPath,"=== 学生提交内容得分点 ===");
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "=== 学生提交内容得分点 ===");
// 对比学生提交内容与试题得分点
Integer studentScore = compareStuAndTestFiles(answerList, stuFiles,score,totalScore);
SourceAndText studentScorePojo = compareStuAndTestFiles(answerList, stuFiles,score,totalScore,judgementStr);
double studentScore = studentScorePojo.getScore();
judgementStr = studentScorePojo.getText();
//获取answerList里的所有sorcerate,和integer相除得到一个小于等于1的数
// 计算最终得分比例(保留两位小数)
double scoreRatio = totalScore == 0 ? 0 : (double) studentScore / totalScore;
double roundedScoreRatio = Math.round(scoreRatio * 100.0) / 100.0; // 四舍五入到2位小数
appendToFile(answerLogPath,"得分:"+roundedScoreRatio*score);
return roundedScoreRatio*score;
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "得分:"+roundedScoreRatio*score);
sourceAndText.setScore(roundedScoreRatio*score);
sourceAndText.setText(judgementStr);
return sourceAndText;
}
// 对比学生提交内容与试题得分点
static Integer compareStuAndTestFiles(List<ExamQuestionAnswer> answerList, Map<String, String> stuFiles,double score,int total) {
int totalScore = 0; // 记录总得分
static SourceAndText compareStuAndTestFiles(List<ExamQuestionAnswer> answerList, Map<String, String> stuFiles,double score,int total, String judgementStr) {
SourceAndText sourceAndText = new SourceAndText();
int totalScore = 0; // 记录总得分
for (ExamQuestionAnswer answer : answerList) {
String filePath = answer.getContent(); // 试题文件路径
String checkType = answer.getContentIn(); // 考察类型(考察删除 / 考察名称 / 考察属性)
@@ -103,13 +111,16 @@ public class FileServericeImpl implements IFileServerice {
double weightScore = ((double) currentScore / total) * score;
String formattedWeightScore = String.format("%.1f", weightScore);
appendToFile(answerLogPath,""+answer.getContent() + " -> " + answer.getContentIn() + " -> 得分权值:" + answer.getScoreRate()+"-> 得分:"+formattedWeightScore);
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "" + answer.getContent() + " -> " + answer.getContentIn() + " -> 得分权值:" + answer.getScoreRate()+"-> 得分:"+formattedWeightScore);
}else {
appendToFile(answerLogPath,""+answer.getContent() + " -> " + answer.getContentIn() + " -> 得分权值:" + answer.getScoreRate()+"-> 得分0");
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "" + answer.getContent() + " -> " + answer.getContentIn() + " -> 得分权值:" + answer.getScoreRate()+"-> 得分0");
}
}
sourceAndText.setText(judgementStr);
sourceAndText.setScore(totalScore);
//返回累加的总分
return totalScore;
return sourceAndText;
}
/**

View File

@@ -3,6 +3,7 @@ package pc.exam.pp.module.judgement.controller.service.file;
import pc.exam.pp.module.exam.dal.dataobject.ExamQuestion;
import pc.exam.pp.module.exam.dal.dataobject.ExamQuestionAnswer;
import pc.exam.pp.module.judgement.service.auto_tools.vo.SourceAndText;
import java.io.File;
import java.io.IOException;
@@ -13,7 +14,7 @@ public interface IFileServerice {
double run_file_point(double score,File file, ExamQuestion question) throws IOException;
SourceAndText run_file_point(double score, File file, ExamQuestion question, String judgementStr) throws IOException;
}

View File

@@ -3,6 +3,7 @@ package pc.exam.pp.module.judgement.controller.service.mysql;
import pc.exam.pp.module.exam.dal.dataobject.ExamQuestion;
import pc.exam.pp.module.exam.dal.dataobject.ExamQuestionAnswer;
import pc.exam.pp.module.judgement.service.auto_tools.vo.SourceAndText;
import java.io.File;
import java.io.IOException;
@@ -11,7 +12,7 @@ import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
public interface IMysqlServerice {
double Judgement(double sorce, File file, ExamQuestion examQuestion) throws IOException, SQLException;
SourceAndText Judgement(double sorce, File file, ExamQuestion examQuestion, String judgementStr) throws IOException, SQLException;

View File

@@ -16,7 +16,9 @@ import pc.exam.pp.module.judgement.controller.utils.Mysql.SQLComparatorUtil;
import pc.exam.pp.module.judgement.controller.utils.Mysql.SqlFileProcessor;
import pc.exam.pp.module.judgement.controller.utils.zip.ZipUtil;
import pc.exam.pp.module.judgement.domain.SqlExecutionResult;
import pc.exam.pp.module.judgement.service.auto_tools.vo.SourceAndText;
import pc.exam.pp.module.judgement.utils.EndStuMonitorUtils;
import pc.exam.pp.module.judgement.utils.HtmlAppender;
import java.awt.*;
import java.io.*;
@@ -53,7 +55,8 @@ public class MysqlServericeImpl implements IMysqlServerice {
private ExamQuestionAnswerMapper examQuestionAnswerMapper;
@Override
public double Judgement(double score,File filepath, ExamQuestion examQuestion) throws IOException, SQLException {
public SourceAndText Judgement(double score, File filepath, ExamQuestion examQuestion, String judgementStr) throws IOException, SQLException {
SourceAndText sourceAndText = new SourceAndText();
double scoreTotal =0.0;
String fileUrl= examQuestionAnswerMapper.selectAnswerFile(examQuestion.getQuId());
String path = ZipUtil.downloadStudentFile(fileUrl, "data");
@@ -188,11 +191,10 @@ public class MysqlServericeImpl implements IMysqlServerice {
String createTableSqlExport = rs.getString("Create Table");
// 替换 result 中的值
entry.setValue(createTableSqlExport);
}
} catch (SQLException e) {
appendToFile(answerLogPath, "执行验证 SQL 出错!");
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "执行验证 SQL 出错!");
e.printStackTrace();
}
}
@@ -244,6 +246,7 @@ public class MysqlServericeImpl implements IMysqlServerice {
if (entry.getValue().trim().toUpperCase().startsWith("CREATE TABLE")) {
List<ExamMysqlKeyword> examMysqlKeywordList =new ArrayList<>();
appendToFile(answerLogPath, "==================建表语句==================");
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "==================建表语句==================");
String answerId = null;
for (ExamQuestionAnswer examQuestionAnswer : examQuestionAnswers) {
if (normalize(examQuestionAnswer.getContent()).equals(normalize(entry.getValue()))) {
@@ -285,6 +288,7 @@ public class MysqlServericeImpl implements IMysqlServerice {
}
appendToFile(answerLogPath, "标准答案建表键值对:"+table1Columns);
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "标准答案建表键值对:"+table1Columns);
}
@@ -303,6 +307,7 @@ public class MysqlServericeImpl implements IMysqlServerice {
table2Columns.add(column);
}
appendToFile(answerLogPath, "学生答案建表键值对:"+table2Columns);
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "学生答案建表键值对:"+table2Columns);
}
}
@@ -321,6 +326,7 @@ public class MysqlServericeImpl implements IMysqlServerice {
if (entry.getValue().trim().toUpperCase().startsWith("INSERT")) {
appendToFile(answerLogPath, "==================插入语句==================");
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "==================插入语句==================");
List<ExamMysqlKeyword> examMysqlKeywordList =new ArrayList<>();
// 正则表达式匹配表名
Pattern pattern = Pattern.compile("INSERT INTO\\s+`?(\\w+)`?\\s*\\(");
@@ -362,9 +368,11 @@ public class MysqlServericeImpl implements IMysqlServerice {
if (entry.getValue().trim().toUpperCase().startsWith("DELETE")) {
appendToFile(answerLogPath, "==================删除语句==================");
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "==================删除语句==================");
List<ExamMysqlKeyword> examMysqlKeywordList =new ArrayList<>();
String delStatement = entry.getValue();
appendToFile(answerLogPath, "正确语句: " + delStatement);
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "正确语句: " + delStatement);
delStatement = delStatement.trim().replaceAll(";+\\s*$", "");
String answerId =null;
String sql2 = resultStu.get(entry.getKey());
@@ -404,7 +412,7 @@ public class MysqlServericeImpl implements IMysqlServerice {
if (countstu == 0) {
//累加删除语句的所有权值 examQuestionKeywords累加scorerate
appendToFile(answerLogPath, "验证通过:符合 DELETE 条件的记录已删除。");
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "验证通过:符合 DELETE 条件的记录已删除。");
double sr= accumulateScoreAndLog(examMysqlKeywordList,total,answerLogPath,sql2,totalKeyScore,score,answerId,scoreTotal);
scoreTotal+=sr;
} else {
@@ -414,6 +422,7 @@ public class MysqlServericeImpl implements IMysqlServerice {
}
}catch (SQLException e) {
appendToFile(answerLogPath, "验证学生库失败,"+"得分0 ❌");
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "验证学生库失败,"+"得分0 ❌");
}
}
@@ -421,11 +430,13 @@ public class MysqlServericeImpl implements IMysqlServerice {
} else {
appendToFile(answerLogPath, "验证答案库失败:还有 " + count + " 条记录符合 DELETE 条件,未被删除。"+"得分0 ❌");
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "验证答案库失败:还有 " + count + "条记录符合 DELETE 条件未被删除。得分0 ❌");
}
}
} catch (SQLException e) {
appendToFile(answerLogPath, "执行验证 SQL 出错!");
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "执行验证 SQL 出错!");
e.printStackTrace();
}
@@ -435,9 +446,11 @@ public class MysqlServericeImpl implements IMysqlServerice {
if (entry.getValue().trim().toUpperCase().startsWith("UPDATE")) {
appendToFile(answerLogPath, "==================更新语句==================");
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "==================更新语句==================");
List<ExamMysqlKeyword> examMysqlKeywordList =new ArrayList<>();
String sql1 = entry.getValue();
appendToFile(answerLogPath, "正确语句: " + sql1);
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "正确语句: " + sql1);
String answerId=null;
for (ExamQuestionAnswer examQuestionAnswer : examQuestionAnswers) {
if (normalize(examQuestionAnswer.getContent()).equals(normalize(entry.getValue()))) {
@@ -470,6 +483,7 @@ public class MysqlServericeImpl implements IMysqlServerice {
}
if (entry.getValue().trim().toUpperCase().startsWith("SELECT")) {
appendToFile(answerLogPath, "==================查找语句==================");
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "==================查找语句==================");
List<ExamMysqlKeyword> examMysqlKeywordList =new ArrayList<>();
String answerId =null;
for (ExamQuestionAnswer examQuestionAnswer : examQuestionAnswers) {
@@ -483,6 +497,7 @@ public class MysqlServericeImpl implements IMysqlServerice {
}
String sql1 = entry.getValue();
appendToFile(answerLogPath, "正确语句: " + sql1);
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "正确语句: " + sql1);
String sql2 = resultStu.get(entry.getKey());
@@ -493,9 +508,11 @@ public class MysqlServericeImpl implements IMysqlServerice {
try (ResultSet answer = stmtan.executeQuery(sql1)) {
answerList = getAnswerList(answer);
appendToFile(answerLogPath, "查找语句标准答案");
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "查找语句标准答案");
printResult(answerList);
}catch (SQLException e) {
appendToFile(answerLogPath, "执行验证语句"+sql1+"时发生错误: " + e.getMessage());
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "执行验证语句"+sql1+"时发生错误: " + e.getMessage());
e.printStackTrace();
}
}
@@ -504,9 +521,11 @@ public class MysqlServericeImpl implements IMysqlServerice {
try (ResultSet answer = stmtstu.executeQuery(sql2)) {
answerListStu = getAnswerList(answer);
appendToFile(answerLogPath, "学生语句答案");
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "学生语句答案");
printResult(answerListStu);
} catch (SQLException e) {
appendToFile(answerLogPath, "执行学生库语句"+sql2+"时发生错误: " + e.getMessage());
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "执行学生库语句"+sql2+"时发生错误: " + e.getMessage());
}
@@ -534,6 +553,7 @@ public class MysqlServericeImpl implements IMysqlServerice {
if (entry.getValue().trim().replaceAll("\\s+", " ").matches("(?i)^CREATE( OR REPLACE)?( ALGORITHM\\s*=\\s*\\w+)?( DEFINER\\s*=\\s*[`\"'\\w@%\\.]+)?( SQL SECURITY \\w+)? VIEW\\b.*")) {
appendToFile(answerLogPath, "==================视图语句==================");
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "==================视图语句==================");
List<ExamMysqlKeyword> examMysqlKeywordList =new ArrayList<>();
String answerId=null;
for (ExamQuestionAnswer examQuestionAnswer : examQuestionAnswers) {
@@ -547,6 +567,7 @@ public class MysqlServericeImpl implements IMysqlServerice {
}
String sql1 = entry.getValue();
appendToFile(answerLogPath, "正确语句: " + sql1);
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "正确语句: " + sql1);
String sql2 = resultStu.get(entry.getKey());
// 正则表达式,用于匹配 "VIEW" 后面的视图名称
String regex = "(?<=VIEW\\s)([\\w`_]+)";
@@ -581,16 +602,19 @@ public class MysqlServericeImpl implements IMysqlServerice {
} catch (SQLException e) {
appendToFile(answerLogPath, "执行学生库语句"+createView2+"时发生错误: " + e.getMessage());
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "执行学生库语句"+createView2+"时发生错误: " + e.getMessage());
hasError = true; // 发生异常,设为 true
}
// 执行查询获取视图1的结果
appendToFile(answerLogPath, "执行正确答案视图语句的查询结果:");
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "执行正确答案视图语句的查询结果:");
String sql3 = "SELECT * FROM " + viewName1;
List<List<String>> result1 = executeQuery(stmt, sql3);
printResult(result1);
// 执行查询获取视图2的结果
appendToFile(answerLogPath, "执行考生视图语句的查询结果:");
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "执行考生视图语句的查询结果:");
String sql4 = "SELECT * FROM " + viewName2;
List<List<String>> result2 = executeQuery(stmt, sql4);
printResult(result2);
@@ -598,6 +622,7 @@ public class MysqlServericeImpl implements IMysqlServerice {
// 比较两个视图的结果
boolean isEquivalent = !hasError &&compareResults(result1, result2);
appendToFile(answerLogPath, "\n是否结果等价: " + isEquivalent);
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "\n是否结果等价: " + isEquivalent);
// 删除视图
System.out.println("\n删除视图 " + viewName1 + "" + viewName2 + "...");
@@ -630,8 +655,10 @@ public class MysqlServericeImpl implements IMysqlServerice {
}
appendToFile(answerLogPath, "==================储存过程==================");
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "==================储存过程==================");
String sql1 = entry.getValue();
appendToFile(answerLogPath, "正确语句: " + sql1);
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "正确语句: " + sql1);
String sql2 = resultStu.get(entry.getKey());
//提取call语句
List<String> extractCallStatements = extractCallStatements(sql1);
@@ -643,7 +670,7 @@ public class MysqlServericeImpl implements IMysqlServerice {
boolean hasError = false; // 添加标志变量
for (String extractCallStatement : extractCallStatements) {
appendToFile(answerLogPath, "测试 call 语句:" + extractCallStatement);
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "测试 call 语句:" + extractCallStatement);
try {
// try (Connection conn = DriverManager.getConnection(newDbUrl, user, password);
@@ -653,6 +680,7 @@ public class MysqlServericeImpl implements IMysqlServerice {
// }
} catch (SQLException e) {
appendToFile(answerLogPath, "执行标准库 SQL CALL 语句时发生错误: " + e.getMessage());
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "执行标准库 SQL CALL 语句时发生错误: " + e.getMessage());
}
@@ -667,6 +695,7 @@ public class MysqlServericeImpl implements IMysqlServerice {
stuResults.addAll(extractResults(oldResult));
} catch (SQLException e) {
appendToFile(answerLogPath, "执行学生库 SQL CALL 语句时发生错误: " + e.getMessage());
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "执行学生库 SQL CALL 语句时发生错误: " + e.getMessage());
hasError = true; // 发生异常,设为 true
}
@@ -675,6 +704,7 @@ public class MysqlServericeImpl implements IMysqlServerice {
} catch (SQLException e) {
appendToFile(answerLogPath, "执行学生库语句"+sql2+"时发生错误: " + e.getMessage());
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "执行学生库语句"+sql2+"时发生错误: " + e.getMessage());
hasError = true; // 发生异常,设为 true
}
@@ -694,10 +724,12 @@ public class MysqlServericeImpl implements IMysqlServerice {
}
} else {
appendToFile(answerLogPath, "此存储过程无 CALL 语句");
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "此存储过程无 CALL 语句");
}
}
if (entry.getValue().trim().toUpperCase().toUpperCase().contains("TRIGGER")) {
appendToFile(answerLogPath, "==================触发器==================");
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "==================触发器==================");
List<ExamMysqlKeyword> examMysqlKeywordList =new ArrayList<>();
String answerId=null;
for (ExamQuestionAnswer examQuestionAnswer : examQuestionAnswers) {
@@ -711,6 +743,7 @@ public class MysqlServericeImpl implements IMysqlServerice {
}
String sql1 = entry.getValue();
appendToFile(answerLogPath, "正确语句: " + sql1);
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "正确语句: " + sql1);
String sql2 = resultStu.get(entry.getKey());
// 清洗触发器语句(去除注释等)
@@ -756,9 +789,12 @@ public class MysqlServericeImpl implements IMysqlServerice {
double roundedResult =0.0;
appendToFile(answerLogPath, "共得分:" + String.format("%.2f", scoreTotal));
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "共得分:" + String.format("%.2f", scoreTotal));
folderzip.delete();
deleteFolder(folder);
return scoreTotal;
sourceAndText.setScore(scoreTotal);
sourceAndText.setText(judgementStr);
return sourceAndText;
}

View File

@@ -31,6 +31,7 @@ import pc.exam.pp.module.judgement.controller.service.browser.IBrowserServerice;
import pc.exam.pp.module.judgement.controller.service.file.IFileServerice;
import pc.exam.pp.module.judgement.controller.service.mysql.IMysqlServerice;
import pc.exam.pp.module.judgement.controller.utils.zip.ZipUtil;
import pc.exam.pp.module.judgement.service.auto_tools.vo.SourceAndText;
import pc.exam.pp.module.judgement.service.c_programming.JudgementService;
import pc.exam.pp.module.judgement.service.choice.JudgementChoiceService;
import pc.exam.pp.module.judgement.service.wps_excel.JudgementWpsExcelService;
@@ -192,14 +193,19 @@ public class AutoToolsServiceImpl implements AutoToolsService{
List<StuPaperFileDO> stuPaperFileDOList = stuPaperFileService.findByStuIDAndPaperId(stuId, paperId);
StuPaperFileDO stuPaperFileDO = null;
StuPaperFileDO noZipFileDO = null;
String judgementStr = " ";
for (StuPaperFileDO stuPaperFileDOs : stuPaperFileDOList) {
if (stuPaperFileDOs.getType() == 1) {
noZipFileDO = stuPaperFileDOs;
if (stuPaperFileDOs.getContent() != null) {
judgementStr = stuPaperFileDOs.getContent();
}
}
if (stuPaperFileDOs.getType() == 0) {
stuPaperFileDO = stuPaperFileDOs;
}
}
List<ExamQuestion> quList = new ArrayList<>();
List<String> quIds = educationPaperQuMapper.selectPaperQuByPaperId(paperId);
List<ExamQuestion> examQuestionList = examQuestionMapper.selectExamQuestionListByQuIds(quIds);
@@ -330,7 +336,9 @@ public class AutoToolsServiceImpl implements AutoToolsService{
isNull = true;
}
if ("编程题".equals(one_file.getName().split("\\.")[0])) {
double c_score = judgementService.ProgrammingC(Double.parseDouble(quScore), one_file.getPath(), file_one.getName(), examQuestion);
SourceAndText cpojo = judgementService.ProgrammingC(Double.parseDouble(quScore), one_file.getPath(), file_one.getName(), examQuestion, judgementStr);
double c_score = cpojo.getScore();
judgementStr = cpojo.getText();
score += c_score;
stuPaperScoreDO.setScore(new BigDecimal(c_score));
// 原始正确分数
@@ -356,7 +364,9 @@ public class AutoToolsServiceImpl implements AutoToolsService{
}
// wps 类型存在多级文文件夹,需要个性化设置
if ("文字".equals(one_file.getName().split("\\.")[0])) {
double wps_word_score = judgementWpsWordService.judgementWpsWord(Double.parseDouble(quScore), one_file.getPath(), file_one.getPath(), examQuestion);
SourceAndText wordpojo = judgementWpsWordService.judgementWpsWord(Double.parseDouble(quScore), one_file.getPath(), file_one.getPath(), examQuestion, judgementStr);
double wps_word_score = wordpojo.getScore();
judgementStr = wordpojo.getText();
score += wps_word_score;
stuPaperScoreDO.setScore(new BigDecimal(wps_word_score));
// 原始正确分数
@@ -381,7 +391,9 @@ public class AutoToolsServiceImpl implements AutoToolsService{
break;
}
if ("演示".equals(one_file.getName().split("\\.")[0])) {
double wps_pptx_score = judgementWpsPptxService.judgementWpsPptx(Double.parseDouble(quScore), one_file.getPath(), file_one.getPath(), examQuestion);
SourceAndText pptxpojo = judgementWpsPptxService.judgementWpsPptx(Double.parseDouble(quScore), one_file.getPath(), file_one.getPath(), examQuestion, judgementStr);
double wps_pptx_score = pptxpojo.getScore();
judgementStr = pptxpojo.getText();
score += wps_pptx_score;
stuPaperScoreDO.setScore(new BigDecimal(wps_pptx_score));
// 原始正确分数
@@ -433,7 +445,9 @@ public class AutoToolsServiceImpl implements AutoToolsService{
//windows文件处理
if ("文件处理".equals(one_file.getName().split("\\.")[0])) {
File win_file = new File(one_file.getPath());
double win_file_score = fileServerice.run_file_point(Double.parseDouble(quScore),win_file, examQuestion);
SourceAndText winfilepojo = fileServerice.run_file_point(Double.parseDouble(quScore),win_file, examQuestion, judgementStr);
double win_file_score = winfilepojo.getScore();
judgementStr = winfilepojo.getText();
score += win_file_score;
stuPaperScoreDO.setScore(new BigDecimal(win_file_score));
// 原始正确分数
@@ -462,7 +476,9 @@ public class AutoToolsServiceImpl implements AutoToolsService{
if ("网络题".equals(one_file.getName().split("\\.")[0])) {
System.out.println(one_file);
File edge_file = new File(one_file.getPath());
double browse_score= browserServerice.Judgement(Double.parseDouble(quScore),edge_file,examQuestion);
SourceAndText browsepojo= browserServerice.Judgement(Double.parseDouble(quScore),edge_file,examQuestion, judgementStr);
double browse_score = browsepojo.getScore();
judgementStr = browsepojo.getText();
score += browse_score;
stuPaperScoreDO.setScore(new BigDecimal(browse_score));
// 原始正确分数
@@ -490,7 +506,9 @@ public class AutoToolsServiceImpl implements AutoToolsService{
if ("程序设计".equals(one_file.getName().split("\\.")[0])) {
System.out.println(one_file);
File mysql_file = new File(one_file.getPath());
double judgement = mysqlServerice.Judgement(Double.parseDouble(quScore),mysql_file, examQuestion);
SourceAndText judgementpojo = mysqlServerice.Judgement(Double.parseDouble(quScore),mysql_file, examQuestion, judgementStr);
double judgement = judgementpojo.getScore();
judgementStr = judgementpojo.getText();
score+=judgement;
stuPaperScoreDO.setScore(new BigDecimal(judgement));
// 原始正确分数
@@ -526,6 +544,10 @@ public class AutoToolsServiceImpl implements AutoToolsService{
// 9、上传文件
MultipartFile file = new CustomMultipartFile(zipPath);
String path = null;
if (noZipFileDO != null) {
noZipFileDO.setContent(judgementStr);
stuPaperFileService.updateStuPaperFile(noZipFileDO);
}
fileService.createStuFile(stuId, paperId, file.getOriginalFilename(), path, IoUtil.readBytes(file.getInputStream()));
// 更新学生分数
endStuMonitorUtils.endStuMonitor(String.valueOf(stuId),paperId,score);

View File

@@ -0,0 +1,20 @@
package pc.exam.pp.module.judgement.service.auto_tools.vo;
import lombok.Data;
/**
* @author REN
*/
@Data
public class SourceAndText {
/**
* 分数
*/
private double score;
/**
* 文本
*/
private String text;
}

View File

@@ -1,6 +1,7 @@
package pc.exam.pp.module.judgement.service.c_programming;
import pc.exam.pp.module.exam.dal.dataobject.ExamQuestion;
import pc.exam.pp.module.judgement.service.auto_tools.vo.SourceAndText;
/**
* 判分逻辑集合
@@ -17,7 +18,7 @@ public interface JudgementService {
* @param score 分数
* @return 返回判分
*/
public double ProgrammingC(double score, String pathC, String fileName, ExamQuestion examQuestion);
public SourceAndText ProgrammingC(double score, String pathC, String fileName, ExamQuestion examQuestion, String judgementStr);
/**

View File

@@ -5,6 +5,8 @@ import pc.exam.pp.module.exam.dal.dataobject.ExamQuestion;
import pc.exam.pp.module.exam.dal.dataobject.ExamQuestionAnswer;
import pc.exam.pp.module.exam.dal.dataobject.ExamQuestionKeyword;
import pc.exam.pp.module.exam.utils.file.LogFileUtils;
import pc.exam.pp.module.judgement.service.auto_tools.vo.SourceAndText;
import pc.exam.pp.module.judgement.utils.HtmlAppender;
import pc.exam.pp.module.judgement.utils.JudgementCUtils;
import java.util.*;
@@ -25,8 +27,8 @@ public class JudgementServiceImpl implements JudgementService
* @param score 分数
* @return 返回判分
*/
public double ProgrammingC(double score, String pathC, String fileName, ExamQuestion examQuestion) {
public SourceAndText ProgrammingC(double score, String pathC, String fileName, ExamQuestion examQuestion, String judgementStr) {
SourceAndText sourceAndText = new SourceAndText();
// 关键字比对,超过权重-测试用例/运行(测试用例全对,直接满分-不全对)-结果,不超过权重只给关键字几个的分
// 获取该题有多少分
// TODO 测试分数15该程序设计题为15分
@@ -65,12 +67,17 @@ public class JudgementServiceImpl implements JudgementService
LogFileUtils.createFile(pathC + "/log.txt");
String code = JudgementCUtils.readFile(pathC, fileName);
LogFileUtils.writeLine("✅ 系统开始读取文件:" + code);
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "✅ 系统开始读取文件:" + code);
if (code == "") {
// 如果没有读到源码
LogFileUtils.writeLine("❌ 系统没有读取到文件。");
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "❌ 系统没有读取到文件。");
LogFileUtils.close();
// 该题不得分直接算成0分
return 0;
sourceAndText.setScore(0);
sourceAndText.setText(judgementStr);
return sourceAndText;
}
int true_number = 0;
// 关键字分数
@@ -87,6 +94,7 @@ public class JudgementServiceImpl implements JudgementService
item.put("success", keyword_run);
item.put("score_rate", examQuestionKeyword.getScoreRate());
LogFileUtils.writeLine("✅ 关键字比对:" + examQuestionKeyword.getKeyword() + "--" + keyword_run);
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "✅ 关键字比对:" + examQuestionKeyword.getKeyword() + "--" + keyword_run);
weight += Integer.parseInt(examQuestionKeyword.getScoreRate());
key_list.add(item);
}
@@ -101,6 +109,8 @@ public class JudgementServiceImpl implements JudgementService
true_number += 1;
key_score += one_keyword_score * Integer.parseInt((String) item.get("score_rate"));
LogFileUtils.writeLine("✅ 关键字得分:" + key_score);
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "✅ 关键字得分:" + key_score);
}
}
}
@@ -112,14 +122,19 @@ public class JudgementServiceImpl implements JudgementService
if (is_pass) {
// 如果使用程序编译,进行程序编译
LogFileUtils.writeLine("✅ 正在使用-std=c99进行编译...");
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "✅ 正在使用-std=c99进行编译...");
// 使用C99 运行并得出结果
String code_return = JudgementCUtils.run_code(pathC,code,null,"-std=c99", "编译通过运行");
if (!code_return.contains("error")) {
// 编译没有报错,加上编译分数
totalScore += pass_score;
LogFileUtils.writeLine("✅ 编译通过得分:" + pass_score);
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "✅ 编译通过得分:" + pass_score);
} else {
LogFileUtils.writeLine("❌ 编译未通过。");
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "❌ 编译未通过。");
}
}
// 进行判断测试用例
@@ -131,6 +146,7 @@ public class JudgementServiceImpl implements JudgementService
boolean run_code = false;
List<Boolean> runList = new ArrayList<>();
LogFileUtils.writeLine("✅ 使用测试用例进行判分...");
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "✅ 使用测试用例进行判分...");
for (ExamQuestionAnswer examQuestionAnswer : examQuestion.getAnswerList()) {
// 使用C99 运行并得出结果
String code_return = JudgementCUtils.run_code(pathC,code, examQuestionAnswer.getContentIn(),"-std=c99",null);
@@ -159,13 +175,17 @@ public class JudgementServiceImpl implements JudgementService
if (test_case_number == true_test_case_number) {
// 满分,该题多少分就是多少分
LogFileUtils.writeLine("✅ 测试用例全部正确:"+ score);
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "✅ 测试用例全部正确:"+ score);
LogFileUtils.close();
return score;
sourceAndText.setScore(score);
return sourceAndText;
} else if (test_case_number > true_test_case_number) {
// 2、测试用例没有完全正确对多少个就是多少分
// 公式:测试用例总分数 / 测试用例数量 * 正确测试用例数量
compile_score += (double) ((score * is_compile_score) / test_case_number) * true_test_case_number;
LogFileUtils.writeLine("✅ 测试用例数量:"+ test_case_number + ",正确数量:" + true_test_case_number + ",得分:" + compile_score);
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "✅ 测试用例数量:"+ test_case_number + ",正确数量:" + true_test_case_number + ",得分:" + compile_score);
}
}
@@ -178,17 +198,23 @@ public class JudgementServiceImpl implements JudgementService
// 总分 = 总分 + 结果得分
totalScore += result_score;
LogFileUtils.writeLine("✅ 结果得分:" + result_score);
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "✅ 结果得分:" + result_score);
}
}
totalScore += key_score;
LogFileUtils.close();
return totalScore;
sourceAndText.setScore(totalScore);
sourceAndText.setText(judgementStr);
return sourceAndText;
} else {
// 关键字对几个给几分,没有达到临界值的情况下
totalScore += key_score;
LogFileUtils.writeLine("❌ 关键字没有达到临界值,正确数量:"+ true_number);
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "❌ 关键字没有达到临界值,正确数量:"+ true_number);
LogFileUtils.close();
return totalScore;
sourceAndText.setScore(totalScore);
sourceAndText.setText(judgementStr);
return sourceAndText;
}
}

View File

@@ -2,6 +2,7 @@ package pc.exam.pp.module.judgement.service.wps_pptx;
import pc.exam.pp.module.exam.dal.dataobject.ExamQuestion;
import pc.exam.pp.module.judgement.controller.admin.Wps.dto.WpsPptxJudgementDto;
import pc.exam.pp.module.judgement.service.auto_tools.vo.SourceAndText;
import pc.exam.pp.module.judgement.utils.wps_pptx.vo.PptxInfoPointsVo;
import pc.exam.pp.module.judgement.utils.wps_pptx.vo.PptxInfoReqVo;
import pc.exam.pp.module.judgement.utils.wps_pptx.vo.PptxVO;
@@ -16,7 +17,7 @@ public interface JudgementWpsPptxService {
List<PptxInfoReqVo> programmingWpsPptx(String path) throws Exception;
double judgementWpsPptx(double sorce, String pathC, String path, ExamQuestion examQuestion) throws Exception;
SourceAndText judgementWpsPptx(double sorce, String pathC, String path, ExamQuestion examQuestion, String judgementStr) throws Exception;
List<WpsPptxJudgementDto> getWpsPptxInfo(List<PptxInfoPointsVo> pptxInfoPointsVos) throws IOException;
}

View File

@@ -14,6 +14,8 @@ import pc.exam.pp.module.judgement.dal.dataobject.wpspptx.WpsPptxLinkDO;
import pc.exam.pp.module.judgement.dal.dataobject.wpsword.WpsWordLinkDO;
import pc.exam.pp.module.judgement.dal.mysql.wpspptx.WpsPptxLinkMapper;
import pc.exam.pp.module.judgement.service.auto_tools.AutoToolsService;
import pc.exam.pp.module.judgement.service.auto_tools.vo.SourceAndText;
import pc.exam.pp.module.judgement.utils.HtmlAppender;
import pc.exam.pp.module.judgement.utils.wps_pptx.WpsPptxUtils;
import pc.exam.pp.module.judgement.utils.wps_pptx.vo.PptxInfoPointsVo;
import pc.exam.pp.module.judgement.utils.wps_pptx.vo.PptxInfoReqVo;
@@ -81,11 +83,12 @@ public class JudgementWpsPptxServiceImpl implements JudgementWpsPptxService {
}
@Override
public double judgementWpsPptx(double sorce, String pathC, String path, ExamQuestion examQuestion) throws Exception {
public SourceAndText judgementWpsPptx(double sorce, String pathC, String path, ExamQuestion examQuestion, String judgementStr) throws Exception {
SourceAndText sourceAndText = new SourceAndText();
// 创建log文件txt用于记录
LogFileUtils.createFile(pathC + "/WPS_Word判分过程.txt");
LogFileUtils.writeLine("✅ 开始WPS_Pptx判分");
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "✅ 开始WPS_Pptx判分");
double wpsPptScore = 0;
List<PptxInfoPointsVo> pptxInfoPointsVos = new ArrayList<>();
// 3、获取答案得组成
@@ -127,14 +130,18 @@ public class JudgementWpsPptxServiceImpl implements JudgementWpsPptxService {
wpsPptScore += one_sorce;
if (flag) {
LogFileUtils.writeLine("" + examQuestionAnswer.getContentIn() + " 得分成功,得分:" + one_sorce);
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "" + examQuestionAnswer.getContentIn() + " 得分成功,得分:" + one_sorce);
} else {
LogFileUtils.writeLine("" + examQuestionAnswer.getContentIn() + " 得分失败");
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "" + examQuestionAnswer.getContentIn() + " 得分失败");
}
}
LogFileUtils.writeLine("✅ 结束WPS_Pptx判分试题得分" + wpsPptScore);
// 关闭已经打开得文件
LogFileUtils.close();
return wpsPptScore;
sourceAndText.setScore(wpsPptScore);
sourceAndText.setText(judgementStr);
return sourceAndText;
}
}

View File

@@ -5,6 +5,7 @@ package pc.exam.pp.module.judgement.service.wps_word;
import pc.exam.pp.module.exam.dal.dataobject.ExamQuestion;
import pc.exam.pp.module.judgement.controller.admin.Wps.dto.WpsWordJudgementDto;
import pc.exam.pp.module.judgement.controller.admin.Wps.dto.WpsWordReqDto;
import pc.exam.pp.module.judgement.service.auto_tools.vo.SourceAndText;
import pc.exam.pp.module.judgement.utils.wps_word.vo.WordInfoReqVo;
import pc.exam.pp.module.judgement.utils.wps_word.vo.WordVO;
@@ -37,5 +38,5 @@ public interface JudgementWpsWordService {
* @return 得分
* @throws Exception 异常
*/
double judgementWpsWord(double sorce, String pathC, String path, ExamQuestion examQuestion) throws Exception;
SourceAndText judgementWpsWord(double sorce, String pathC, String path, ExamQuestion examQuestion, String judgementStr) throws Exception;
}

View File

@@ -16,6 +16,8 @@ import pc.exam.pp.module.judgement.controller.admin.Wps.vo.WordListReqVO;
import pc.exam.pp.module.judgement.dal.dataobject.wpsword.WpsWordLinkDO;
import pc.exam.pp.module.judgement.dal.mysql.wpsword.WpsWordLinkMapper;
import pc.exam.pp.module.judgement.service.auto_tools.AutoToolsService;
import pc.exam.pp.module.judgement.service.auto_tools.vo.SourceAndText;
import pc.exam.pp.module.judgement.utils.HtmlAppender;
import pc.exam.pp.module.judgement.utils.wps_word.WpsWordUtils;
import pc.exam.pp.module.judgement.utils.wps_word.vo.WordInfoReqVo;
import pc.exam.pp.module.judgement.utils.wps_word.vo.WordVO;
@@ -82,10 +84,12 @@ public class JudgementWpsWordServiceImpl implements JudgementWpsWordService {
}
@Override
public double judgementWpsWord(double sorce, String pathC, String path, ExamQuestion examQuestion) throws Exception {
public SourceAndText judgementWpsWord(double sorce, String pathC, String path, ExamQuestion examQuestion, String judgementStr) throws Exception {
SourceAndText sourceAndText = new SourceAndText();
// 创建log文件txt用于记录
LogFileUtils.createFile(pathC + "/WPS_Word判分过程.txt");
LogFileUtils.writeLine("✅ 开始WPS_Word判分");
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "✅ 开始WPS_Word判分");
double wps_word_sorce = 0;
// 2、docx文件读取并返回考点及说明信息
// List<WordVO> margins = WpsWordUtils.wps_word(path);
@@ -121,7 +125,6 @@ public class JudgementWpsWordServiceImpl implements JudgementWpsWordService {
int index = 0;
if (wordJudgementDto.getContent().equals(examQuestionAnswer.getContent())) {
flag = true;
// 得分 根据权重进行得分 每个选项分值 = 总分 / 总权重
if (examQuestionAnswer.getScoreRate().equals("1")) {
// 说明权重相等,直接平分分数
@@ -137,14 +140,21 @@ public class JudgementWpsWordServiceImpl implements JudgementWpsWordService {
wps_word_sorce += one_sorce;
if (flag) {
LogFileUtils.writeLine("" + examQuestionAnswer.getContentIn() + " 得分成功,得分:" + one_sorce);
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "" + examQuestionAnswer.getContentIn() + " 得分成功,得分:" + one_sorce);
} else {
LogFileUtils.writeLine("" + examQuestionAnswer.getContentIn() + " 得分失败");
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "" + examQuestionAnswer.getContentIn() + " 得分失败");
}
}
LogFileUtils.writeLine("✅ 结束WPS_Word判分试题得分" + wps_word_sorce);
// 关闭已经打开得文件
LogFileUtils.close();
return wps_word_sorce;
sourceAndText.setScore(wps_word_sorce);
sourceAndText.setText(judgementStr);
return sourceAndText;
}
}

View File

@@ -0,0 +1,41 @@
package pc.exam.pp.module.judgement.utils;
public class HtmlAppender {
/**
* 向原始HTML文本中追加一行内容每行使用<p>标签包裹并换行。
*
* @param originalText 原始HTML内容
* @param newLine 要追加的新行文本
* @return 新的HTML文本
*/
public static String appendHtmlLine(String originalText, String newLine) {
StringBuilder result = new StringBuilder(originalText == null ? "" : originalText);
if (newLine != null && !newLine.isEmpty()) {
result.append("<p>")
.append(escapeHtml(newLine))
.append("</p>\n");
}
return result.toString();
}
// 简单HTML转义防止注入攻击
private static String escapeHtml(String text) {
return text.replace("&", "&amp;")
.replace("<", "&lt;")
.replace(">", "&gt;")
.replace("\"", "&quot;")
.replace("'", "&#39;");
}
// 示例用法
public static void main(String[] args) {
String original = "";
original = appendHtmlLine(original, "Line 1");
original = appendHtmlLine(original, "Line 2");
original = appendHtmlLine(original, "<script>alert('XSS')</script>");
System.out.println(original);
}
}

View File

@@ -186,30 +186,33 @@ public class WpsPptxUtils {
judgementDto.setScoreRate("1");
judgementList.add(judgementDto);
}
} else if (slideCursor.toNextSelection()) {
WpsPptxJudgementDto judgementDto = new WpsPptxJudgementDto();
// 判断是值还是类型
if ("1".equals(pptxInfoPointsVo.getIsboo())) {
judgementDto.setContentIn(getStringName(pptxInfoPointsVo.getEnglishName()) + pptxInfoPointsVo.getName()+"true");
judgementDto.setContent(pptxInfoPointsVo.getEnglishName()+"?"+pptxInfoPointsVo.getFunction()+"?"+"true");
} else {
String value = slideCursor.getTextValue();
value = getValueType(pptxInfoPointsVo, value);
judgementDto.setContentIn(getStringName(pptxInfoPointsVo.getEnglishName()) + pptxInfoPointsVo.getName()+value);
judgementDto.setContent(pptxInfoPointsVo.getEnglishName()+"?"+pptxInfoPointsVo.getFunction()+"?"+value);
}
judgementDto.setImage(pptxInfoPointsVo.getType()+"-"+pptxInfoPointsVo.getBelongTo()+"-"+pptxInfoPointsVo.getIsboo()+"-"+pptxInfoPointsVo.getUnit());
judgementDto.setScoreRate("1");
judgementList.add(judgementDto);
} else {
if ("1".equals(pptxInfoPointsVo.getIsboo())) {
WpsPptxJudgementDto judgementDto = new WpsPptxJudgementDto();
judgementDto.setContentIn(getStringName(pptxInfoPointsVo.getEnglishName()) + pptxInfoPointsVo.getName()+"false");
judgementDto.setContent(pptxInfoPointsVo.getEnglishName()+"?"+pptxInfoPointsVo.getFunction()+"?"+"false");
judgementDto.setImage(pptxInfoPointsVo.getType()+"-"+pptxInfoPointsVo.getBelongTo()+"-"+pptxInfoPointsVo.getIsboo()+"-"+pptxInfoPointsVo.getUnit());
slideCursor.selectPath(namespace + pptxInfoPointsVo.getFunction().replace("-", ""));
if (slideCursor.toNextSelection()) {
WpsPptxJudgementDto judgementDto = new WpsPptxJudgementDto();
// 判断是值还是类型
if ("1".equals(pptxInfoPointsVo.getIsboo())) {
judgementDto.setContentIn(getStringName(pptxInfoPointsVo.getEnglishName()) + pptxInfoPointsVo.getName() + "");
judgementDto.setContent(pptxInfoPointsVo.getEnglishName() + "?" + pptxInfoPointsVo.getFunction() + "?" + "true");
} else {
String value = slideCursor.getTextValue();
value = getValueType(pptxInfoPointsVo, value);
judgementDto.setContentIn(getStringName(pptxInfoPointsVo.getEnglishName()) + pptxInfoPointsVo.getName() + value);
judgementDto.setContent(pptxInfoPointsVo.getEnglishName() + "?" + pptxInfoPointsVo.getFunction() + "?" + value);
}
judgementDto.setImage(pptxInfoPointsVo.getType() + "-" + pptxInfoPointsVo.getBelongTo() + "-" + pptxInfoPointsVo.getIsboo() + "-" + pptxInfoPointsVo.getUnit());
judgementDto.setScoreRate("1");
judgementList.add(judgementDto);
} else {
if ("1".equals(pptxInfoPointsVo.getIsboo())) {
WpsPptxJudgementDto judgementDto = new WpsPptxJudgementDto();
judgementDto.setContentIn(getStringName(pptxInfoPointsVo.getEnglishName()) + pptxInfoPointsVo.getName() + "");
judgementDto.setContent(pptxInfoPointsVo.getEnglishName() + "?" + pptxInfoPointsVo.getFunction() + "?" + "false");
judgementDto.setImage(pptxInfoPointsVo.getType() + "-" + pptxInfoPointsVo.getBelongTo() + "-" + pptxInfoPointsVo.getIsboo() + "-" + pptxInfoPointsVo.getUnit());
judgementDto.setScoreRate("1");
judgementList.add(judgementDto);
}
}
}
}

View File

@@ -64,15 +64,15 @@ public class PageSizeDetector {
heightTwip = Integer.parseInt(matchers.group(1));
}
// 转换为 cm1 twip = 1/1440 英寸 = 2.54 / 1440 cm
double widthCm = widthTwip * 2.54 / 1440;
double heightCm = heightTwip * 2.54 / 1440;
double widthCm = widthTwip / 360000;
double heightCm = heightTwip / 360000;
// 四舍五入保留一位小数
widthCm = Math.round(widthCm * 10) / 10.0;
heightCm = Math.round(heightCm * 10) / 10.0;
// 判断标准纸型(以 cm 为单位进行匹配)
String paperType = "Unknown";
String paperType = "自定义";
if (approx(widthCm, 21.0) && approx(heightCm, 29.7)) {
paperType = "A4";
} else if (approx(widthCm, 29.7) && approx(heightCm, 42.0)) {