【修改】mysql根据出题界面,考点加引号

This commit is contained in:
huababa1
2025-07-15 04:28:33 +08:00
parent a69cfac1bd
commit 3f4c7b6fa5
4 changed files with 147 additions and 76 deletions

View File

@@ -0,0 +1,24 @@
package com.example.exam.exam.dal;
import lombok.Data;
/**
* @author REN
*/
@Data
public class SourceAndTextAndTotal {
/**
* 分数
*/
private double score;
/**
* 文本
*/
private String text;
/**
* 考点正确数量
*/
private int total;
}

View File

@@ -3,6 +3,7 @@ package com.example.exam.exam.service.brower;
import com.example.exam.exam.dal.ExamQuestion; import com.example.exam.exam.dal.ExamQuestion;
import com.example.exam.exam.dal.ExamQuestionAnswer; import com.example.exam.exam.dal.ExamQuestionAnswer;
import com.example.exam.exam.dal.SourceAndText; import com.example.exam.exam.dal.SourceAndText;
import com.example.exam.exam.dal.SourceAndTextAndTotal;
import com.example.exam.exam.mapper.ExamQuestionAnswerMapper; import com.example.exam.exam.mapper.ExamQuestionAnswerMapper;
import com.example.exam.exam.utils.HtmlAppender; import com.example.exam.exam.utils.HtmlAppender;
import com.example.exam.exam.utils.brower.BookmarkChecker; import com.example.exam.exam.utils.brower.BookmarkChecker;
@@ -53,7 +54,8 @@ public class JudgementBrowerServiceImpl implements JudgementBrowerService {
// } // }
// } // }
// } // }
int correctCount = 0; // 完全正确的题目数量
int totalQuestions = answerList.size(); // 总题目数量// 总题目数量
//分为两点1文件夹-- 去考生文件夹去找 文件名 //分为两点1文件夹-- 去考生文件夹去找 文件名
@@ -77,8 +79,9 @@ public class JudgementBrowerServiceImpl implements JudgementBrowerService {
.mapToInt(a -> Integer.parseInt(a.getScoreRate())) .mapToInt(a -> Integer.parseInt(a.getScoreRate()))
.sum(); .sum();
//这里指挥判断存在文件夹的得分点 //这里指挥判断存在文件夹的得分点
SourceAndText studentScorePojo = compareStuAndTestFiles(answerList, stuFiles,score,totalScore,judgementStr); SourceAndTextAndTotal studentScorePojo = compareStuAndTestFiles(answerList, stuFiles,score,totalScore,judgementStr);
double studentScore = studentScorePojo.getScore(); double studentScore = studentScorePojo.getScore();
correctCount= studentScorePojo.getTotal();
judgementStr = studentScorePojo.getText(); judgementStr = studentScorePojo.getText();
//判断收藏夹得分点 //判断收藏夹得分点
for (ExamQuestionAnswer examQuestionAnswer : answerList) { for (ExamQuestionAnswer examQuestionAnswer : answerList) {
@@ -91,7 +94,7 @@ public class JudgementBrowerServiceImpl implements JudgementBrowerService {
if (isCorrect) { if (isCorrect) {
//如果有 +权值 //如果有 +权值
studentScore += currentScore; studentScore += currentScore;
correctCount++;
// 计算该考点的权重得分并保留一位小数 // 计算该考点的权重得分并保留一位小数
double weightScore = ((double) currentScore / totalScore) * score; double weightScore = ((double) currentScore / totalScore) * score;
@@ -114,18 +117,22 @@ public class JudgementBrowerServiceImpl implements JudgementBrowerService {
// 计算最终得分比例(保留两位小数) // 计算最终得分比例(保留两位小数)
double scoreRatio = totalScore == 0 ? 0 : (double) studentScore / totalScore; double scoreRatio = totalScore == 0 ? 0 : (double) studentScore / totalScore;
double roundedScoreRatio = Math.round(scoreRatio * 100.0) / 100.0; // 四舍五入到2位小数 double roundedScoreRatio = Math.round(scoreRatio*score * 100.0) / 100.0; // 四舍五入到2位小数
appendToFile(answerLogPath," 得分:"+roundedScoreRatio*score); if (correctCount == totalQuestions) {
sourceAndText.setScore(roundedScoreRatio*score); roundedScoreRatio = score; // 全对,直接给满分
}
appendToFile(answerLogPath," 得分:"+roundedScoreRatio);
sourceAndText.setScore(roundedScoreRatio);
sourceAndText.setText(judgementStr); sourceAndText.setText(judgementStr);
return sourceAndText; return sourceAndText;
} }
// 对比学生提交内容与试题得分点 // 对比学生提交内容与试题得分点
static SourceAndText compareStuAndTestFiles(List<ExamQuestionAnswer> answerList, Map<String, String> stuFiles,double score,int total, String judgementStr) { static SourceAndTextAndTotal compareStuAndTestFiles(List<ExamQuestionAnswer> answerList, Map<String, String> stuFiles,double score,int total, String judgementStr) {
int totalScore = 0; // 记录总得分 int totalScore = 0; // 记录总得分
SourceAndText sourceAndText = new SourceAndText(); int correctCount = 0; // 完全正确的题目数量
SourceAndTextAndTotal sourceAndText = new SourceAndTextAndTotal();
for (ExamQuestionAnswer answer : answerList) { for (ExamQuestionAnswer answer : answerList) {
if ("添加到文件夹".equals(answer.getContentIn())) { if ("添加到文件夹".equals(answer.getContentIn())) {
String filePath = answer.getContent(); // 试题文件路径 String filePath = answer.getContent(); // 试题文件路径
@@ -136,6 +143,7 @@ public class JudgementBrowerServiceImpl implements JudgementBrowerService {
// 如果正确,则累加总分 // 如果正确,则累加总分
if (isCorrect) { if (isCorrect) {
totalScore += currentScore; totalScore += currentScore;
correctCount++;
// 计算该考点的权重得分并保留一位小数 // 计算该考点的权重得分并保留一位小数
double weightScore = ((double) currentScore / total) * score; double weightScore = ((double) currentScore / total) * score;
String formattedWeightScore = String.format("%.1f", weightScore); String formattedWeightScore = String.format("%.1f", weightScore);
@@ -150,6 +158,7 @@ public class JudgementBrowerServiceImpl implements JudgementBrowerService {
//返回累加的得分点 //返回累加的得分点
sourceAndText.setScore(totalScore); sourceAndText.setScore(totalScore);
sourceAndText.setText(judgementStr); sourceAndText.setText(judgementStr);
sourceAndText.setTotal(correctCount);
return sourceAndText; return sourceAndText;
} }
/** /**

View File

@@ -67,6 +67,8 @@ public class IMysqlLocalServiceImpl implements IMysqlLocalService {
// 5.2、查询试题ID // 5.2、查询试题ID
List<ExamQuestionAnswer> examQuestionAnswers = examQuestionAnswerMapper.selectExamQuestionAnswerByQuId(examQuestion.getQuId()); List<ExamQuestionAnswer> examQuestionAnswers = examQuestionAnswerMapper.selectExamQuestionAnswerByQuId(examQuestion.getQuId());
int correctCount = 0; // 完全正确的题目数量
int totalQuestions = examQuestionAnswers.size(); // 总题目数量// 总题目数量
String totalKeyScore ="0"; String totalKeyScore ="0";
//得出 这个题总共的权值点 //得出 这个题总共的权值点
totalKeyScore=examQuestionAnswerMapper.selectCountPointByQuId(examQuestion.getQuId()); totalKeyScore=examQuestionAnswerMapper.selectCountPointByQuId(examQuestion.getQuId());
@@ -243,6 +245,7 @@ public class IMysqlLocalServiceImpl implements IMysqlLocalService {
if (table1Columns.equals(table2Columns)) { if (table1Columns.equals(table2Columns)) {
correctCount++; // 完全正确
appendToFile(answerLogPath, "【执行】"+""+showCreateTableSql+"】【验证】【表】【"+tableName+"】【√】"); appendToFile(answerLogPath, "【执行】"+""+showCreateTableSql+"】【验证】【表】【"+tableName+"】【√】");
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "【执行】"+""+showCreateTableSql+"】【验证】【表】【"+tableName+"】【✅】"); judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "【执行】"+""+showCreateTableSql+"】【验证】【表】【"+tableName+"】【✅】");
SourceAndText studentScorePojo = accumulateScoreAndLog(examMysqlKeywordList,total,answerLogPath,stuSQL,totalKeyScore,score,answerId,scoreTotal,judgementStr); SourceAndText studentScorePojo = accumulateScoreAndLog(examMysqlKeywordList,total,answerLogPath,stuSQL,totalKeyScore,score,answerId,scoreTotal,judgementStr);
@@ -259,83 +262,93 @@ public class IMysqlLocalServiceImpl implements IMysqlLocalService {
} }
if (sql.trim().toUpperCase().startsWith("INSERT")) { // 匹配成功
appendToFile(answerLogPath, "==================插入语句=================="); if (sql.trim().toUpperCase().startsWith("INSERT")) {
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "==================插入语句=================="); appendToFile(answerLogPath, "==================插入语句==================");
// 正则表达式匹配表名 judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "==================插入语句==================");
Pattern pattern = Pattern.compile("INSERT INTO\\s+`?(\\w+)`?\\s*\\("); // 正则表达式匹配表名
Matcher matcher = pattern.matcher(sql); Pattern pattern = Pattern.compile(
"INSERT\\s+INTO\\s+`?(\\w+)`?",
Pattern.CASE_INSENSITIVE
);
Matcher matcher = pattern.matcher(sql);
// appendToFile(answerLogPath, "答案语句: " + sql); // appendToFile(answerLogPath, "答案语句: " + sql);
// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "答案语句: "); // judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "答案语句: ");
// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, sql); // judgementStr = HtmlAppender.appendHtmlLine(judgementStr, sql);
if (matcher.find()) { if (matcher.find()) {
String tableName = matcher.group(1).replace("`", ""); // 获取表名 String tableName = matcher.group(1);
// 匹配成功
String answerId= examQuestionAnswer.getAnswerId(); String answerId= examQuestionAnswer.getAnswerId();
List<ExamMysqlKeyword> examMysqlKeywordList = examMysqlKeywordMapper.selectListByAnswerId(answerId); List<ExamMysqlKeyword> examMysqlKeywordList = examMysqlKeywordMapper.selectListByAnswerId(answerId);
// 传入 INSERT SQL 和主键字段 // 传入 INSERT SQL 和主键字段
String yanzheng = convertInsertToSelect(sql); String yanzheng = null;
try {
String stuSql=null; yanzheng = convertInsertToSelect(sql);
List<List<String>> answerList= new ArrayList<>(); String stuSql=null;
List<List<String>> answerListStu = new ArrayList<>(); List<List<String>> answerList= new ArrayList<>();
try (Connection connanswer = DriverManager.getConnection(newDbUrl, user, password); List<List<String>> answerListStu = new ArrayList<>();
Statement stmtan = connanswer.createStatement()) { try (Connection connanswer = DriverManager.getConnection(newDbUrl, user, password);
try (ResultSet answer = stmtan.executeQuery(yanzheng)) { Statement stmtan = connanswer.createStatement()) {
answerList = getAnswerList(answer); try (ResultSet answer = stmtan.executeQuery(yanzheng)) {
answerList = getAnswerList(answer);
// appendToFile(answerLogPath, "查找语句标准答案"); // appendToFile(answerLogPath, "查找语句标准答案");
// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "查找语句标准答案"); // judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "查找语句标准答案");
// printResult(answerList,judgementStr); // printResult(answerList,judgementStr);
}catch (SQLException e) { }catch (SQLException e) {
// appendToFile(answerLogPath, "答案表执行验证语句"+yanzheng+"时发生错误: " + e.getMessage()); // appendToFile(answerLogPath, "答案表执行验证语句"+yanzheng+"时发生错误: " + e.getMessage());
// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "答案表执行验证语句"+yanzheng+"时发生错误: " + e.getMessage()); // judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "答案表执行验证语句"+yanzheng+"时发生错误: " + e.getMessage());
e.printStackTrace(); e.printStackTrace();
}
} }
} try (Connection connstu = DriverManager.getConnection(stuDbUrl, user, password);
try (Connection connstu = DriverManager.getConnection(stuDbUrl, user, password); Statement stmtstu = connstu.createStatement()) {
Statement stmtstu = connstu.createStatement()) { try (ResultSet answer = stmtstu.executeQuery(yanzheng)) {
try (ResultSet answer = stmtstu.executeQuery(yanzheng)) { answerListStu = getAnswerList(answer);
answerListStu = getAnswerList(answer); //这里根据answerListStu 还原学生的sql语句
//这里根据answerListStu 还原学生的sql语句 List<String> columnNames = getColumnNames(answer); // ← 获取字段名
List<String> columnNames = getColumnNames(answer); // ← 获取字段名
String tName = extractTableNameFromInsert(sql); String tName = extractTableNameFromInsert(sql);
//构建还原 SQL你可以自定义表名比如传 "student_table" //构建还原 SQL你可以自定义表名比如传 "student_table"
stuSql = generateInsertSQL(tName, columnNames, answerListStu); stuSql = generateInsertSQL(tName, columnNames, answerListStu);
// appendToFile(answerLogPath, "学生对"+tName+"插入的SQL:\n" + stuSql); // appendToFile(answerLogPath, "学生对"+tName+"插入的SQL:\n" + stuSql);
// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "学生对"+tName+"+插入的SQL:" ); // judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "学生对"+tName+"+插入的SQL:" );
// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, stuSql); // judgementStr = HtmlAppender.appendHtmlLine(judgementStr, stuSql);
// appendToFile(answerLogPath, "学生语句答案"); // appendToFile(answerLogPath, "学生语句答案");
// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "学生语句答案"); // judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "学生语句答案");
// printResult(answerListStu,judgementStr); // printResult(answerListStu,judgementStr);
} catch (SQLException e) { } catch (SQLException e) {
// appendToFile(answerLogPath, "学生表执行验证语句"+yanzheng+"时发生错误: " + e.getMessage()); // appendToFile(answerLogPath, "学生表执行验证语句"+yanzheng+"时发生错误: " + e.getMessage());
// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "学生表执行验证语句"+yanzheng+"时发生错误: " + e.getMessage()); // judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "学生表执行验证语句"+yanzheng+"时发生错误: " + e.getMessage());
}
} }
} boolean isEquivalent =false;
boolean isEquivalent =false;
if (answerListStu!=null&&answerListStu.size()>0){
isEquivalent = compareResultsSelect(answerList, answerListStu);
}
if (isEquivalent) {
correctCount++; // 完全正确
appendToFile(answerLogPath, "【执行】"+""+yanzheng+"】【验证】【表】【"+tableName+"】【√】");
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "【执行】 "+""+yanzheng+"】【验证】【表】【"+tableName+"】【✅】");
SourceAndText studentScorePojo = accumulateScoreAndLog(examMysqlKeywordList,total,answerLogPath,stuSql,totalKeyScore,score,answerId,scoreTotal,judgementStr);
scoreTotal += studentScorePojo.getScore();
judgementStr = studentScorePojo.getText();
} else {
appendToFile(answerLogPath, "【执行】"+""+yanzheng+"】【验证】【表】【"+tableName+"】【×】");
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "【执行】 "+""+yanzheng+"】【验证】【表】【"+tableName+"】【❌】");
SourceAndText studentScorePojo= calculateTotalScoreRate(stuSql, examMysqlKeywordList,totalKeyScore,score,answerId,scoreTotal,judgementStr);
scoreTotal += studentScorePojo.getScore();
judgementStr = studentScorePojo.getText();
}
} catch (Exception e) {
if (answerListStu!=null&&answerListStu.size()>0){
isEquivalent = compareResultsSelect(answerList, answerListStu);
} }
if (isEquivalent) {
appendToFile(answerLogPath, "【执行】"+""+yanzheng+"】【验证】【表】【"+tableName+"】【√】");
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "【执行】 "+""+yanzheng+"】【验证】【表】【"+tableName+"】【✅】");
SourceAndText studentScorePojo = accumulateScoreAndLog(examMysqlKeywordList,total,answerLogPath,stuSql,totalKeyScore,score,answerId,scoreTotal,judgementStr);
scoreTotal += studentScorePojo.getScore();
judgementStr = studentScorePojo.getText();
} else {
appendToFile(answerLogPath, "【执行】"+""+yanzheng+"】【验证】【表】【"+tableName+"】【×】");
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "【执行】 "+""+yanzheng+"】【验证】【表】【"+tableName+"】【❌】");
SourceAndText studentScorePojo= calculateTotalScoreRate(stuSql, examMysqlKeywordList,totalKeyScore,score,answerId,scoreTotal,judgementStr);
scoreTotal += studentScorePojo.getScore();
judgementStr = studentScorePojo.getText();
}
} }
} }
@@ -347,7 +360,11 @@ public class IMysqlLocalServiceImpl implements IMysqlLocalService {
// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, sql); // judgementStr = HtmlAppender.appendHtmlLine(judgementStr, sql);
sql = sql.trim().replaceAll(";+\\s*$", ""); sql = sql.trim().replaceAll(";+\\s*$", "");
// 正则提取表名和 WHERE 条件 // 正则提取表名和 WHERE 条件
Pattern pattern = Pattern.compile("DELETE\\s+FROM\\s+(\\w+)\\s+WHERE\\s+(.+)", Pattern.CASE_INSENSITIVE); Pattern pattern = Pattern.compile(
"DELETE\\s+FROM\\s+`?(\\w+)`?\\s+WHERE\\s+([^;]+);?",
Pattern.CASE_INSENSITIVE | Pattern.DOTALL
);
Matcher matcher = pattern.matcher(sql); Matcher matcher = pattern.matcher(sql);
// 匹配成功 // 匹配成功
String answerId = examQuestionAnswer.getAnswerId(); String answerId = examQuestionAnswer.getAnswerId();
@@ -375,6 +392,7 @@ public class IMysqlLocalServiceImpl implements IMysqlLocalService {
if (rsstu.next()) { if (rsstu.next()) {
int countstu = rsstu.getInt(1); int countstu = rsstu.getInt(1);
if (countstu == 0) { if (countstu == 0) {
correctCount++; // 完全正确
//累加删除语句的所有权值 examQuestionKeywords累加scorerate //累加删除语句的所有权值 examQuestionKeywords累加scorerate
// appendToFile(answerLogPath, "验证通过:符合 DELETE 条件的记录已删除。"); // appendToFile(answerLogPath, "验证通过:符合 DELETE 条件的记录已删除。");
// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "验证通过:符合 DELETE 条件的记录已删除。"); // judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "验证通过:符合 DELETE 条件的记录已删除。");
@@ -430,9 +448,10 @@ public class IMysqlLocalServiceImpl implements IMysqlLocalService {
String selectSql = convertUpdateToSelectWhere(sql); String selectSql = convertUpdateToSelectWhere(sql);
// 提取表名和 WHERE 子句 // 提取表名和 WHERE 子句
Pattern pattern = Pattern.compile( Pattern pattern = Pattern.compile(
"UPDATE\\s+`?(\\w+)`?\\s+SET\\s+.+?\\s+WHERE\\s+(.+);?", "UPDATE\\s+`?(\\w+)`?\\s+SET\\s+(.+?)\\s+WHERE\\s+(.+?);?$",
Pattern.CASE_INSENSITIVE | Pattern.DOTALL Pattern.CASE_INSENSITIVE | Pattern.DOTALL
); );
Matcher matcher = pattern.matcher(sql); Matcher matcher = pattern.matcher(sql);
if (matcher.find()) { if (matcher.find()) {
@@ -486,6 +505,7 @@ public class IMysqlLocalServiceImpl implements IMysqlLocalService {
} }
// //
if (isEquivalent) { if (isEquivalent) {
correctCount++; // 完全正确
appendToFile(answerLogPath, "【执行】 "+""+selectSql+"】【验证】【表】【"+tableName+"】【√】"); appendToFile(answerLogPath, "【执行】 "+""+selectSql+"】【验证】【表】【"+tableName+"】【√】");
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "【执行】 "+""+selectSql+"】【验证】【表】【"+tableName+"】【✅】"); judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "【执行】 "+""+selectSql+"】【验证】【表】【"+tableName+"】【✅】");
SourceAndText studentScorePojo = accumulateScoreAndLog(examMysqlKeywordList,total,answerLogPath,stuSql,totalKeyScore,score,answerId,scoreTotal,judgementStr); SourceAndText studentScorePojo = accumulateScoreAndLog(examMysqlKeywordList,total,answerLogPath,stuSql,totalKeyScore,score,answerId,scoreTotal,judgementStr);
@@ -591,6 +611,7 @@ public class IMysqlLocalServiceImpl implements IMysqlLocalService {
} }
if (isEquivalent) { if (isEquivalent) {
correctCount++; // 完全正确
appendToFile(answerLogPath, "执行"+sql+"验证文件【"+fileName.get()+"】【√】"); appendToFile(answerLogPath, "执行"+sql+"验证文件【"+fileName.get()+"】【√】");
judgementStr = HtmlAppender.appendHtmlLine(judgementStr,"执行"+sql+"验证文件【"+fileName.get()+"】【✅】"); judgementStr = HtmlAppender.appendHtmlLine(judgementStr,"执行"+sql+"验证文件【"+fileName.get()+"】【✅】");
//todo 得分 //todo 得分
@@ -684,6 +705,7 @@ public class IMysqlLocalServiceImpl implements IMysqlLocalService {
if (isEquivalent) { if (isEquivalent) {
correctCount++; // 完全正确
appendToFile(answerLogPath, "【执行】"+""+showCreateViewSql+"】【验证】【视图】【"+viewNam1+"】 【√】"); appendToFile(answerLogPath, "【执行】"+""+showCreateViewSql+"】【验证】【视图】【"+viewNam1+"】 【√】");
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "【执行】"+""+showCreateViewSql+"】【验证】【视图】【"+viewNam1+"】【✅】"); judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "【执行】"+""+showCreateViewSql+"】【验证】【视图】【"+viewNam1+"】【✅】");
SourceAndText studentScorePojo = accumulateScoreAndLog(examMysqlKeywordList,total,answerLogPath,stuSQL,totalKeyScore,score,answerId,scoreTotal,judgementStr); SourceAndText studentScorePojo = accumulateScoreAndLog(examMysqlKeywordList,total,answerLogPath,stuSQL,totalKeyScore,score,answerId,scoreTotal,judgementStr);
@@ -798,7 +820,7 @@ public class IMysqlLocalServiceImpl implements IMysqlLocalService {
boolean flag= !hasError &&mysqlBooleanVo.isFlag(); boolean flag= !hasError &&mysqlBooleanVo.isFlag();
if (flag) { if (flag) {
//todo 得分 correctCount++; // 完全正确
appendToFile(answerLogPath, "【执行】"+extractCallStatements+"【验证】【文件】【"+fileName.get()+"】【√】"); appendToFile(answerLogPath, "【执行】"+extractCallStatements+"【验证】【文件】【"+fileName.get()+"】【√】");
judgementStr = HtmlAppender.appendHtmlLine(judgementStr,"【执行】"+extractCallStatements+"【验证】【文件】 【"+fileName.get()+"】【✅】"); judgementStr = HtmlAppender.appendHtmlLine(judgementStr,"【执行】"+extractCallStatements+"【验证】【文件】 【"+fileName.get()+"】【✅】");
SourceAndText studentScorePojo = accumulateScoreAndLog(examMysqlKeywordList,total,answerLogPath,stuAnswer.get(),totalKeyScore,score,answerId,scoreTotal,judgementStr); SourceAndText studentScorePojo = accumulateScoreAndLog(examMysqlKeywordList,total,answerLogPath,stuAnswer.get(),totalKeyScore,score,answerId,scoreTotal,judgementStr);
@@ -937,6 +959,7 @@ public class IMysqlLocalServiceImpl implements IMysqlLocalService {
boolean equals = normalizedTriggerSql1.equals(normalizedTriggerSql2); boolean equals = normalizedTriggerSql1.equals(normalizedTriggerSql2);
if (equals) { if (equals) {
correctCount++; // 完全正确
appendToFile(answerLogPath, "【文件】 【"+fileName.get()+"】【√】"); appendToFile(answerLogPath, "【文件】 【"+fileName.get()+"】【√】");
judgementStr = HtmlAppender.appendHtmlLine(judgementStr,"【文件】 【"+fileName.get()+"】【✅】"); judgementStr = HtmlAppender.appendHtmlLine(judgementStr,"【文件】 【"+fileName.get()+"】【✅】");
//todo 得分 //todo 得分
@@ -1025,7 +1048,7 @@ public class IMysqlLocalServiceImpl implements IMysqlLocalService {
} }
// //
if (isEquivalent) { if (isEquivalent) {
correctCount++; // 完全正确
appendToFile(answerLogPath, "【执行】 "+""+selectSql+"】 【验证】 【表】 【"+tableName+"】【√】"); appendToFile(answerLogPath, "【执行】 "+""+selectSql+"】 【验证】 【表】 【"+tableName+"】【√】");
@@ -1084,6 +1107,10 @@ public class IMysqlLocalServiceImpl implements IMysqlLocalService {
// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "共得分:" + String.format("%.2f", scoreTotal)); // judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "共得分:" + String.format("%.2f", scoreTotal));
folderzip.delete(); folderzip.delete();
deleteFolder(folder); deleteFolder(folder);
// 全部题目处理完成后
if (correctCount == totalQuestions) {
scoreTotal = score; // 全对,直接给满分
}
//todo 删除学生答题的数据库连接 单独写一个接口 //todo 删除学生答题的数据库连接 单独写一个接口
// deleteRegistryKey(); // deleteRegistryKey();
sourceAndText.setScore(scoreTotal); sourceAndText.setScore(scoreTotal);
@@ -1361,21 +1388,23 @@ public class IMysqlLocalServiceImpl implements IMysqlLocalService {
// 清理语句 // 清理语句
updateSQL = updateSQL.trim().replaceAll(";\\s*$", ""); updateSQL = updateSQL.trim().replaceAll(";\\s*$", "");
// 正则提取表名和 WHERE 条件 // 正则提取表名和 WHERE 条件(支持反引号)
Pattern pattern = Pattern.compile( Pattern pattern = Pattern.compile(
"UPDATE\\s+(\\w+)\\s+SET\\s+.+?\\s+WHERE\\s+(.+)", "UPDATE\\s+`?(\\w+)`?\\s+SET\\s+.+?\\s+WHERE\\s+(.+)",
Pattern.CASE_INSENSITIVE | Pattern.DOTALL Pattern.CASE_INSENSITIVE | Pattern.DOTALL
); );
Matcher matcher = pattern.matcher(updateSQL); Matcher matcher = pattern.matcher(updateSQL);
if (matcher.find()) { if (matcher.find()) {
String tableName = matcher.group(1).trim(); String tableName = matcher.group(1).trim();
String whereClause = matcher.group(2).trim(); String whereClause = matcher.group(2).trim();
return "SELECT * FROM " + tableName + " WHERE " + whereClause + ";"; return "SELECT * FROM `" + tableName + "` WHERE " + whereClause + ";";
} else { } else {
return "-- 无法识别的 UPDATE 语句"; return "-- 无法识别的 UPDATE 语句";
} }
} }
public static String extractTableNameFromInsert(String sql) { public static String extractTableNameFromInsert(String sql) {
Pattern pattern = Pattern.compile("INSERT\\s+INTO\\s+(\\w+)\\s*\\(", Pattern.CASE_INSENSITIVE); Pattern pattern = Pattern.compile("INSERT\\s+INTO\\s+(\\w+)\\s*\\(", Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(sql); Matcher matcher = pattern.matcher(sql);
@@ -1747,7 +1776,7 @@ public class IMysqlLocalServiceImpl implements IMysqlLocalService {
System.out.println("========================================================= " ); System.out.println("========================================================= " );
Pattern p = Pattern.compile("UPDATE\\s+(\\w+)\\s+SET\\s+(.+?)\\s+WHERE\\s+(.+);?", Pattern.CASE_INSENSITIVE | Pattern.DOTALL); Pattern p = Pattern.compile("UPDATE\\s+`?(\\w+)`?\\s+SET\\s+(.+?)\\s+WHERE\\s+(.+);?", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
Matcher m = p.matcher(originalUpdateSql); Matcher m = p.matcher(originalUpdateSql);
if (!m.find()) { if (!m.find()) {
throw new IllegalArgumentException("无法解析原始 UPDATE 语句"); throw new IllegalArgumentException("无法解析原始 UPDATE 语句");
@@ -1794,6 +1823,9 @@ public class IMysqlLocalServiceImpl implements IMysqlLocalService {
return callStatements; return callStatements;
} }
public static String convertInsertToSelect(String insertSql) { public static String convertInsertToSelect(String insertSql) {
Pattern pattern = Pattern.compile( Pattern pattern = Pattern.compile(
"INSERT INTO\\s+`?(\\w+)`?\\s*\\((.*?)\\)\\s*VALUES\\s*\\((.*?)\\)", "INSERT INTO\\s+`?(\\w+)`?\\s*\\((.*?)\\)\\s*VALUES\\s*\\((.*?)\\)",
@@ -1842,8 +1874,6 @@ public class IMysqlLocalServiceImpl implements IMysqlLocalService {
/** /**
* 比较两个查询的结果 * 比较两个查询的结果
*/ */

View File

@@ -3,6 +3,7 @@ package com.example.exam.exam.service.winfile;
import com.example.exam.exam.dal.ExamQuestion; import com.example.exam.exam.dal.ExamQuestion;
import com.example.exam.exam.dal.ExamQuestionAnswer; import com.example.exam.exam.dal.ExamQuestionAnswer;
import com.example.exam.exam.dal.SourceAndText; import com.example.exam.exam.dal.SourceAndText;
import com.example.exam.exam.dal.SourceAndTextAndTotal;
import com.example.exam.exam.mapper.ExamQuestionAnswerMapper; import com.example.exam.exam.mapper.ExamQuestionAnswerMapper;
import com.example.exam.exam.utils.HtmlAppender; import com.example.exam.exam.utils.HtmlAppender;
import com.example.exam.exam.utils.file.GetDifferencesBetweenFolders; import com.example.exam.exam.utils.file.GetDifferencesBetweenFolders;
@@ -40,8 +41,8 @@ public class FileServericeImpl implements IFileServerice {
// answerList.add(new ExamQuestionAnswer("","","","","EDZK\\RONGHE.COM", "考察名称", "1", "4")); // answerList.add(new ExamQuestionAnswer("","","","","EDZK\\RONGHE.COM", "考察名称", "1", "4"));
// answerList.add(new ExamQuestionAnswer("","","","","HGACYL\\PLAY.MEM", "考察名称", "1", "5")); // answerList.add(new ExamQuestionAnswer("","","","","HGACYL\\PLAY.MEM", "考察名称", "1", "5"));
// answerList.add(new ExamQuestionAnswer("","","","","WUE\\PB6.txt", "考察名称", "1", "6")); // answerList.add(new ExamQuestionAnswer("","","","","WUE\\PB6.txt", "考察名称", "1", "6"));
int correctCount = 0; // 完全正确的题目数量
int totalQuestions = answerList.size(); // 总题目数量// 总题目数量
File stuPath = file; File stuPath = file;
// 设置日志文件路径为file所在目录下的answerLogFile.txt // 设置日志文件路径为file所在目录下的answerLogFile.txt
@@ -62,26 +63,31 @@ public class FileServericeImpl implements IFileServerice {
appendToFile(answerLogPath,"=== 学生提交内容得分点 ==="); appendToFile(answerLogPath,"=== 学生提交内容得分点 ===");
judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "=== 学生提交内容得分点 ==="); judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "=== 学生提交内容得分点 ===");
// 对比学生提交内容与试题得分点 // 对比学生提交内容与试题得分点
SourceAndText studentScorePojo = compareStuAndTestFiles(answerList, stuFiles,score,totalScore,judgementStr); SourceAndTextAndTotal studentScorePojo = compareStuAndTestFiles(answerList, stuFiles,score,totalScore,judgementStr);
double studentScore = studentScorePojo.getScore(); double studentScore = studentScorePojo.getScore();
judgementStr = studentScorePojo.getText(); judgementStr = studentScorePojo.getText();
//获取answerList里的所有sorcerate,和integer相除得到一个小于等于1的数 //获取answerList里的所有sorcerate,和integer相除得到一个小于等于1的数
// 计算最终得分比例(保留两位小数) // 计算最终得分比例(保留两位小数)
double scoreRatio = totalScore == 0 ? 0 : (double) studentScore / totalScore; double scoreRatio = totalScore == 0 ? 0 : (double) studentScore / totalScore;
double roundedScoreRatio = Math.round(scoreRatio * 100.0) / 100.0; // 四舍五入到2位小数 double roundedScoreRatio = Math.round(scoreRatio * 100.0*score) / 100.0; // 四舍五入到2位小数
appendToFile(answerLogPath,"得分:"+roundedScoreRatio*score); if (correctCount == totalQuestions) {
roundedScoreRatio = score; // 全对,直接给满分
}
appendToFile(answerLogPath,"得分:"+roundedScoreRatio);
// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "得分:"+roundedScoreRatio*score); // judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "得分:"+roundedScoreRatio*score);
sourceAndText.setScore(roundedScoreRatio*score); sourceAndText.setScore(roundedScoreRatio);
sourceAndText.setText(judgementStr); sourceAndText.setText(judgementStr);
return sourceAndText; return sourceAndText;
} }
// 对比学生提交内容与试题得分点 // 对比学生提交内容与试题得分点
static SourceAndText compareStuAndTestFiles(List<ExamQuestionAnswer> answerList, Map<String, String> stuFiles,double score,int total, String judgementStr) { static SourceAndTextAndTotal compareStuAndTestFiles(List<ExamQuestionAnswer> answerList, Map<String, String> stuFiles, double score, int total, String judgementStr) {
SourceAndText sourceAndText = new SourceAndText(); SourceAndTextAndTotal sourceAndText = new SourceAndTextAndTotal();
int totalScore = 0; // 记录总得分 int correctCount = 0; // 完全正确的题目数量
int totalQuestions = answerList.size(); // 总题目数量// 总题目数量
double totalScore = 0; // 记录总得分
for (ExamQuestionAnswer answer : answerList) { for (ExamQuestionAnswer answer : answerList) {
String filePath = answer.getContent(); // 试题文件路径 String filePath = answer.getContent(); // 试题文件路径
String checkType = answer.getContentIn(); // 考察类型(考察删除 / 考察名称 / 考察属性) String checkType = answer.getContentIn(); // 考察类型(考察删除 / 考察名称 / 考察属性)
@@ -105,6 +111,7 @@ public class FileServericeImpl implements IFileServerice {
// 如果正确,则累加总分 // 如果正确,则累加总分
if (isCorrect) { if (isCorrect) {
totalScore += currentScore; totalScore += currentScore;
correctCount++; // 完全正确
// 计算该考点的权重得分并保留一位小数 // 计算该考点的权重得分并保留一位小数
double weightScore = ((double) currentScore / total) * score; double weightScore = ((double) currentScore / total) * score;
String formattedWeightScore = String.format("%.1f", weightScore); String formattedWeightScore = String.format("%.1f", weightScore);
@@ -117,6 +124,7 @@ public class FileServericeImpl implements IFileServerice {
} }
sourceAndText.setText(judgementStr); sourceAndText.setText(judgementStr);
sourceAndText.setScore(totalScore); sourceAndText.setScore(totalScore);
sourceAndText.setTotal(correctCount);
//返回累加的总分 //返回累加的总分
return sourceAndText; return sourceAndText;
} }