From f4c54bd0123d60bee946451bc86f6ebedcf96519 Mon Sep 17 00:00:00 2001 From: dlaren Date: Wed, 30 Jul 2025 10:39:44 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90=E4=BF=AE=E6=94=B9=E3=80=91=20?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=97=A0=E7=94=A8=E4=BB=A3=E7=A0=81=EF=BC=8C?= =?UTF-8?q?=E6=96=B0=E5=A2=9Edocx4j=E4=BB=A3=E7=A0=81=E8=AF=BB=E5=8F=96doc?= =?UTF-8?q?x=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/wps/vo/docx/DocxListReqVO.java | 2 +- .../admin/wps/vo/docx/DocxRespVO.java | 14 +- .../admin/wps/vo/docx/DocxSaveReqVO.java | 14 +- .../exam/dal/dataobject/wps/ExamWpsDocx.java | 8 +- .../admin/AutoWps/AutoWpsController.java | 27 +- .../admin/AutoWps/vo/WpsDocxInfoVo.java | 5 +- .../admin/Browser/BrowserController.java | 50 +- .../admin/Mysql/MysqlController.java | 88 +- .../controller/admin/Mysql/TestControler.java | 54 +- .../controller/admin/Ps/PsController.java | 1 - .../WindowFile/WindowsFileController.java | 74 +- .../controller/admin/Wps/WpsController.java | 23 +- .../admin/autoTools/AutoToolsController.java | 20 - .../service/browser/BrowserServericeImpl.java | 212 +- .../service/browser/IBrowserServerice.java | 23 +- .../service/file/FileServericeImpl.java | 158 +- .../service/file/IFileServerice.java | 27 +- .../service/mysql/IMysqlLocalService.java | 32 +- .../service/mysql/IMysqlLocalServiceImpl.java | 3772 ++++++++--------- .../service/mysql/IMysqlServerice.java | 40 +- .../service/mysql/MysqlServericeImpl.java | 3073 +++++++------- .../service/mysql/testServiceImpl.java | 44 +- .../controller/service/mysql/testservice.java | 14 +- .../wps_excel/JudgementWpsExcelService.java | 9 - .../JudgementWpsExcelServiceImpl.java | 11 - .../wps_pptx/JudgementWpsPptxServiceImpl.java | 7 - .../wps_word/JudgementWpsWordService.java | 23 +- .../wps_word/JudgementWpsWordServiceImpl.java | 73 +- .../utils/wps_excel/WpsExcelUtils.java | 2 - .../utils/wps_word/docx4j/DocxConversion.java | 10 +- .../utils/wps_word/docx4j/DocxMaster.java | 55 +- .../wps_word/docx4j/paragraph/Paragraphs.java | 440 +- .../wps_word/utils/WpsWordNameSpaces.java | 7 +- .../utils/wps_word/utils/XmlUtil.java | 2 +- 34 files changed, 4161 insertions(+), 4253 deletions(-) diff --git a/exam-module-exam/exam-module-exam-biz/src/main/java/pc/exam/pp/module/exam/controller/admin/wps/vo/docx/DocxListReqVO.java b/exam-module-exam/exam-module-exam-biz/src/main/java/pc/exam/pp/module/exam/controller/admin/wps/vo/docx/DocxListReqVO.java index 731e8b51..49ef4aa2 100644 --- a/exam-module-exam/exam-module-exam-biz/src/main/java/pc/exam/pp/module/exam/controller/admin/wps/vo/docx/DocxListReqVO.java +++ b/exam-module-exam/exam-module-exam-biz/src/main/java/pc/exam/pp/module/exam/controller/admin/wps/vo/docx/DocxListReqVO.java @@ -3,7 +3,7 @@ package pc.exam.pp.module.exam.controller.admin.wps.vo.docx; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@Schema(description = "考试模块 - PPT考点列表 Request VO") +@Schema(description = "考试模块 - Word考点列表 Request VO") @Data public class DocxListReqVO { diff --git a/exam-module-exam/exam-module-exam-biz/src/main/java/pc/exam/pp/module/exam/controller/admin/wps/vo/docx/DocxRespVO.java b/exam-module-exam/exam-module-exam-biz/src/main/java/pc/exam/pp/module/exam/controller/admin/wps/vo/docx/DocxRespVO.java index 0e590b03..79e7d34b 100644 --- a/exam-module-exam/exam-module-exam-biz/src/main/java/pc/exam/pp/module/exam/controller/admin/wps/vo/docx/DocxRespVO.java +++ b/exam-module-exam/exam-module-exam-biz/src/main/java/pc/exam/pp/module/exam/controller/admin/wps/vo/docx/DocxRespVO.java @@ -5,7 +5,7 @@ import lombok.Data; import java.time.LocalDateTime; -@Schema(description = "考试模块 - PPT考点信息 Response VO") +@Schema(description = "考试模块 - Word考点信息 Response VO") @Data public class DocxRespVO { @@ -23,17 +23,9 @@ public class DocxRespVO { private String chineseName; - private String dataType; + private String functions; - private Integer isText; - - private String valueList; - - private Integer isTrue; - - private Integer titleType; - - private Integer isParameter; + private String parameter; private LocalDateTime createTime; diff --git a/exam-module-exam/exam-module-exam-biz/src/main/java/pc/exam/pp/module/exam/controller/admin/wps/vo/docx/DocxSaveReqVO.java b/exam-module-exam/exam-module-exam-biz/src/main/java/pc/exam/pp/module/exam/controller/admin/wps/vo/docx/DocxSaveReqVO.java index 57afeb3f..dfcd8d1d 100644 --- a/exam-module-exam/exam-module-exam-biz/src/main/java/pc/exam/pp/module/exam/controller/admin/wps/vo/docx/DocxSaveReqVO.java +++ b/exam-module-exam/exam-module-exam-biz/src/main/java/pc/exam/pp/module/exam/controller/admin/wps/vo/docx/DocxSaveReqVO.java @@ -3,7 +3,7 @@ package pc.exam.pp.module.exam.controller.admin.wps.vo.docx; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -@Schema(description = "考试模块 - PPT考点创建/修改 Request VO") +@Schema(description = "考试模块 - Word考点创建/修改 Request VO") @Data public class DocxSaveReqVO { @@ -21,16 +21,8 @@ public class DocxSaveReqVO { private String chineseName; - private String dataType; + private String parameter; - private Integer isText; - - private String valueList; - - private Integer isTrue; - - private Integer titleType; - - private Integer isParameter; + private String functions; } diff --git a/exam-module-exam/exam-module-exam-biz/src/main/java/pc/exam/pp/module/exam/dal/dataobject/wps/ExamWpsDocx.java b/exam-module-exam/exam-module-exam-biz/src/main/java/pc/exam/pp/module/exam/dal/dataobject/wps/ExamWpsDocx.java index 48e88724..2da5675c 100644 --- a/exam-module-exam/exam-module-exam-biz/src/main/java/pc/exam/pp/module/exam/dal/dataobject/wps/ExamWpsDocx.java +++ b/exam-module-exam/exam-module-exam-biz/src/main/java/pc/exam/pp/module/exam/dal/dataobject/wps/ExamWpsDocx.java @@ -29,13 +29,9 @@ public class ExamWpsDocx extends TenantBaseDO { private String title; private Integer sort; private String chineseName; - private String dataType; + private String functions; + private String parameter; private Integer status; - private String valueList; - private Integer isTrue; - private Integer isText; - private Integer titleType; - private Integer isParameter; @TableField(exist = false) private List children = new ArrayList<>(); } diff --git a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/admin/AutoWps/AutoWpsController.java b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/admin/AutoWps/AutoWpsController.java index 22eec29a..5c55cb76 100644 --- a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/admin/AutoWps/AutoWpsController.java +++ b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/admin/AutoWps/AutoWpsController.java @@ -1,24 +1,24 @@ package pc.exam.pp.module.judgement.controller.admin.AutoWps; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.Resource; +import org.springframework.http.MediaType; import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestPart; +import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import pc.exam.pp.framework.common.pojo.CommonResult; import pc.exam.pp.module.infra.controller.admin.file.vo.file.FileUploadReqVO; import pc.exam.pp.module.judgement.controller.admin.AutoWps.vo.WpsDocxInfoVo; -import pc.exam.pp.module.judgement.controller.admin.Wps.dto.WpsPptxJudgementDto; -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.wps_excel.JudgementWpsExcelService; import pc.exam.pp.module.judgement.service.wps_pptx.JudgementWpsPptxService; import pc.exam.pp.module.judgement.service.wps_word.JudgementWpsWordService; -import pc.exam.pp.module.judgement.utils.wps_pptx.judgementVO.JudgementReqVo; -import pc.exam.pp.module.judgement.utils.wps_pptx.vo.PptxInfoReqVo; import pc.exam.pp.module.judgement.utils.wps_word.docx4j.vo.DocxDataInfoVO; import pc.exam.pp.module.judgement.utils.wps_word.docx4j.vo.JudgementWordsVO; -import pc.exam.pp.module.judgement.utils.wps_word.vo.WordInfoReqVo; import java.util.List; @@ -44,13 +44,18 @@ public class AutoWpsController { /** * 获取指定考点的数据 - * @param wpsDocxInfoVos * @return * @throws Exception */ - @PostMapping("/docxMaster") - public CommonResult> docxMaster(@RequestBody List wpsDocxInfoVos) throws Exception { - return CommonResult.success(judgementWpsWordService.docxMaster(wpsDocxInfoVos)); + @PostMapping(value = "/docxMaster", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + public CommonResult> docxMaster(@RequestPart("data") String jsonData, @RequestPart("file") MultipartFile file) throws Exception { + // 手动解析JSON数组 + ObjectMapper objectMapper = new ObjectMapper(); + List wpsDocxInfoVos = objectMapper.readValue( + jsonData, + new TypeReference>() {} + ); + return CommonResult.success(judgementWpsWordService.docxMaster(wpsDocxInfoVos, file)); } /** diff --git a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/admin/AutoWps/vo/WpsDocxInfoVo.java b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/admin/AutoWps/vo/WpsDocxInfoVo.java index 5967e596..6349e85a 100644 --- a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/admin/AutoWps/vo/WpsDocxInfoVo.java +++ b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/admin/AutoWps/vo/WpsDocxInfoVo.java @@ -1,6 +1,7 @@ package pc.exam.pp.module.judgement.controller.admin.AutoWps.vo; import lombok.Data; +import org.springframework.web.multipart.MultipartFile; @Data public class WpsDocxInfoVo { @@ -20,6 +21,6 @@ public class WpsDocxInfoVo { // 考点代码 private String examCode; - // 文件路径 理论上都是一样的 - private String filePath; + // 方式方法 + private String method; } diff --git a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/admin/Browser/BrowserController.java b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/admin/Browser/BrowserController.java index af9241d8..e95f2e66 100644 --- a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/admin/Browser/BrowserController.java +++ b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/admin/Browser/BrowserController.java @@ -1,25 +1,25 @@ -package pc.exam.pp.module.judgement.controller.admin.Browser; - - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; -import pc.exam.pp.module.judgement.controller.service.browser.IBrowserServerice; - -@RestController -@RequestMapping("/tool/Browser") - -public class BrowserController { - - @Autowired - private IBrowserServerice browserServerice; - /** - * 浏览器判分 - * @return 得分 - */ -// @PostMapping("/run_judgement") -// public CommonResult run_C_code() throws IOException { -// return CommonResult.success(browserServerice.Judgement()); -// } - -} +//package pc.exam.pp.module.judgement.controller.admin.Browser; +// +// +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.web.bind.annotation.RequestMapping; +//import org.springframework.web.bind.annotation.RestController; +//import pc.exam.pp.module.judgement.controller.service.browser.IBrowserServerice; +// +//@RestController +//@RequestMapping("/tool/Browser") +// +//public class BrowserController { +// +// @Autowired +// private IBrowserServerice browserServerice; +// /** +// * 浏览器判分 +// * @return 得分 +// */ +//// @PostMapping("/run_judgement") +//// public CommonResult run_C_code() throws IOException { +//// return CommonResult.success(browserServerice.Judgement()); +//// } +// +//} diff --git a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/admin/Mysql/MysqlController.java b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/admin/Mysql/MysqlController.java index 68b5a69c..82a680b1 100644 --- a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/admin/Mysql/MysqlController.java +++ b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/admin/Mysql/MysqlController.java @@ -1,45 +1,45 @@ -package pc.exam.pp.module.judgement.controller.admin.Mysql; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.*; -import pc.exam.pp.framework.common.pojo.CommonResult; -import pc.exam.pp.module.judgement.controller.admin.autoTools.vo.StuPaperReqVo; -import pc.exam.pp.module.judgement.controller.service.mysql.IMysqlLocalService; -import pc.exam.pp.module.judgement.controller.service.mysql.IMysqlServerice; - -import java.io.IOException; -import java.math.BigDecimal; -import java.sql.SQLException; - -@RestController -@RequestMapping("/tool/Mysql") -public class MysqlController { - - - - @Autowired - private IMysqlServerice mysqlServerice; - @Autowired - private IMysqlLocalService mysqlLocalService; - - /** - * 删除 本地学生的连接和库 - * @param tName - * @throws Exception - */ - @GetMapping("/delMysqlConnect") - public void get(@RequestParam("tName") String tName) throws Exception { - mysqlLocalService.delMysqlConnect(tName); - } - - /** - * Mysql判分 - * @return 得分 - */ -// @PostMapping("/run_judgement") -// public CommonResult run_C_code() throws SQLException, IOException { -// return CommonResult.success(mysqlServerice.Judgement( )); +//package pc.exam.pp.module.judgement.controller.admin.Mysql; +// +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.web.bind.annotation.*; +//import pc.exam.pp.framework.common.pojo.CommonResult; +//import pc.exam.pp.module.judgement.controller.admin.autoTools.vo.StuPaperReqVo; +//import pc.exam.pp.module.judgement.controller.service.mysql.IMysqlLocalService; +//import pc.exam.pp.module.judgement.controller.service.mysql.IMysqlServerice; +// +//import java.io.IOException; +//import java.math.BigDecimal; +//import java.sql.SQLException; +// +//@RestController +//@RequestMapping("/tool/Mysql") +//public class MysqlController { +// +// +// +// @Autowired +// private IMysqlServerice mysqlServerice; +// @Autowired +// private IMysqlLocalService mysqlLocalService; +// +// /** +// * 删除 本地学生的连接和库 +// * @param tName +// * @throws Exception +// */ +// @GetMapping("/delMysqlConnect") +// public void get(@RequestParam("tName") String tName) throws Exception { +// mysqlLocalService.delMysqlConnect(tName); // } - - -} +// +// /** +// * Mysql判分 +// * @return 得分 +// */ +//// @PostMapping("/run_judgement") +//// public CommonResult run_C_code() throws SQLException, IOException { +//// return CommonResult.success(mysqlServerice.Judgement( )); +//// } +// +// +//} diff --git a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/admin/Mysql/TestControler.java b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/admin/Mysql/TestControler.java index fa857395..a69ca59a 100644 --- a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/admin/Mysql/TestControler.java +++ b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/admin/Mysql/TestControler.java @@ -1,27 +1,27 @@ -package pc.exam.pp.module.judgement.controller.admin.Mysql; - -import jakarta.annotation.Resource; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.PostMapping; -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.judgement.controller.service.mysql.IMysqlServerice; -import pc.exam.pp.module.judgement.controller.service.mysql.testservice; - -import java.io.IOException; -import java.sql.SQLException; - -@RestController -@RequestMapping("/tool/Test") -public class TestControler { - - @Autowired - private testservice testservice; - - @PostMapping("/test") - public CommonResult run_C_code() { - return CommonResult.success(testservice.test()); - } - -} +//package pc.exam.pp.module.judgement.controller.admin.Mysql; +// +//import jakarta.annotation.Resource; +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.web.bind.annotation.PostMapping; +//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.judgement.controller.service.mysql.IMysqlServerice; +//import pc.exam.pp.module.judgement.controller.service.mysql.testservice; +// +//import java.io.IOException; +//import java.sql.SQLException; +// +//@RestController +//@RequestMapping("/tool/Test") +//public class TestControler { +// +// @Autowired +// private testservice testservice; +// +// @PostMapping("/test") +// public CommonResult run_C_code() { +// return CommonResult.success(testservice.test()); +// } +// +//} diff --git a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/admin/Ps/PsController.java b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/admin/Ps/PsController.java index d76ad1ba..182cf05b 100644 --- a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/admin/Ps/PsController.java +++ b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/admin/Ps/PsController.java @@ -3,7 +3,6 @@ package pc.exam.pp.module.judgement.controller.admin.Ps; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import pc.exam.pp.module.judgement.controller.service.mysql.IMysqlServerice; import pc.exam.pp.module.judgement.controller.service.ps.IPsService; @RestController diff --git a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/admin/WindowFile/WindowsFileController.java b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/admin/WindowFile/WindowsFileController.java index 6717f73d..6905cbd2 100644 --- a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/admin/WindowFile/WindowsFileController.java +++ b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/admin/WindowFile/WindowsFileController.java @@ -1,37 +1,37 @@ -package pc.exam.pp.module.judgement.controller.admin.WindowFile; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.PostMapping; -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.judgement.controller.service.file.IFileServerice; -import pc.exam.pp.module.judgement.utils.EndStuMonitorUtils; - -import java.io.IOException; - -/** - * 文件操作题判分 - * rwb - */ - -@RestController -@RequestMapping("/tool/File") -public class WindowsFileController { - - @Autowired - private IFileServerice fileServerice; - - - - /** - * 文件操作题判分 - * @return 判分 - */ -// @PostMapping("/run_judgement") -// public CommonResult run_file_point() throws IOException { -// //"权值得分比重" -// return CommonResult.success(fileServerice.run_file_point()); -// } - -} +//package pc.exam.pp.module.judgement.controller.admin.WindowFile; +// +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.web.bind.annotation.PostMapping; +//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.judgement.controller.service.file.IFileServerice; +//import pc.exam.pp.module.judgement.utils.EndStuMonitorUtils; +// +//import java.io.IOException; +// +///** +// * 文件操作题判分 +// * rwb +// */ +// +//@RestController +//@RequestMapping("/tool/File") +//public class WindowsFileController { +// +// @Autowired +// private IFileServerice fileServerice; +// +// +// +// /** +// * 文件操作题判分 +// * @return 判分 +// */ +//// @PostMapping("/run_judgement") +//// public CommonResult run_file_point() throws IOException { +//// //"权值得分比重" +//// return CommonResult.success(fileServerice.run_file_point()); +//// } +// +//} diff --git a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/admin/Wps/WpsController.java b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/admin/Wps/WpsController.java index 1a39e7af..3823acdc 100644 --- a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/admin/Wps/WpsController.java +++ b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/admin/Wps/WpsController.java @@ -2,30 +2,15 @@ package pc.exam.pp.module.judgement.controller.admin.Wps; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.Resource; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import pc.exam.pp.framework.common.pojo.CommonResult; -import pc.exam.pp.module.judgement.controller.admin.AutoWps.vo.WpsDocxInfoVo; import pc.exam.pp.module.judgement.controller.admin.Wps.dto.WpsPptxJudgementDto; -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.wps_excel.JudgementWpsExcelService; import pc.exam.pp.module.judgement.service.wps_pptx.JudgementWpsPptxService; import pc.exam.pp.module.judgement.service.wps_word.JudgementWpsWordService; -//import pc.exam.pp.module.judgement.utils.wps_excel.vo.ExcelInfoReqVo; -import pc.exam.pp.module.judgement.utils.wps_excel.vo.ExcelInfoReqVo; -import pc.exam.pp.module.judgement.utils.wps_excel.vo.XlsxVO; -import pc.exam.pp.module.judgement.utils.wps_excel.vo.xlsx_all.XlsxAllDataReqVo; -import pc.exam.pp.module.judgement.utils.wps_excel.vo.xlsx_drawing.XlsxInfoVo; -import pc.exam.pp.module.judgement.utils.wps_excel.vo.xlsx_style.XlsxStyleVO; import pc.exam.pp.module.judgement.utils.wps_pptx.judgementVO.JudgementReqVo; -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; -import pc.exam.pp.module.judgement.utils.wps_word.docx4j.vo.JudgementWordsVO; -import pc.exam.pp.module.judgement.utils.wps_word.vo.WordInfoReqVo; -import pc.exam.pp.module.judgement.utils.wps_word.vo.WordVO; import java.util.List; @@ -49,10 +34,10 @@ public class WpsController { JudgementWpsExcelService judgementWpsExcelService; - @PostMapping("/docxMaster") - public CommonResult> docxMaster(@RequestBody List wpsDocxInfoVos) throws Exception { - return CommonResult.success(judgementWpsWordService.docxMaster(wpsDocxInfoVos)); - } +// @PostMapping("/docxMaster") +// public CommonResult> docxMaster(@RequestBody List wpsDocxInfoVos) throws Exception { +// return CommonResult.success(judgementWpsWordService.docxMaster(wpsDocxInfoVos)); +// } // /** // * wps word // * @return 判分 diff --git a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/admin/autoTools/AutoToolsController.java b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/admin/autoTools/AutoToolsController.java index 20445788..d7bd9907 100644 --- a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/admin/autoTools/AutoToolsController.java +++ b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/admin/autoTools/AutoToolsController.java @@ -10,26 +10,14 @@ 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.dataobject.student.StuPaperInfoDO; import pc.exam.pp.module.exam.dal.dataobject.student.StuPaperScoreDO; 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.stuPaperInfo.StuPaperInfoService; 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; -import pc.exam.pp.module.judgement.service.c_programming.JudgementService; -import pc.exam.pp.module.judgement.service.wps_excel.JudgementWpsExcelService; -import pc.exam.pp.module.judgement.service.wps_pptx.JudgementWpsPptxService; -import pc.exam.pp.module.judgement.service.wps_word.JudgementWpsWordService; -import java.math.BigDecimal; -import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Objects; @@ -51,11 +39,6 @@ public class AutoToolsController { @Resource ExamQuestionMapper examQuestionMapper; -// @GetMapping("/get") -// public CommonResult get(StuPaperReqVo stuPaperReqVo) throws Exception { -// return autoToolsService.judgementScore(stuPaperReqVo.getStuId(),stuPaperReqVo.getPaperId()); -// } - @GetMapping("/getStuScoreInfo") @Operation(summary = "通过学生ID、试卷ID获取") public CommonResult getStuScore(StuPaperReqVo stuPaperReqVo){ @@ -76,9 +59,6 @@ public class AutoToolsController { .filter(Objects::nonNull) .collect(Collectors.toList()); // 一条一条进行查询试题,防止顺序错乱 -// for (String quId : quIds) { -// examQuestionList.add(examQuestionMapper.selectExamQuestionByQuId(quId)); -// } stuPaperScoreInfoVos.setExamQuestionList(examQuestionList); // 5、查询学生试卷分析 List scoreDOS = stuPaperScoreService.findByStuIDAndPaperId(stuPaperReqVo.getStuId(),stuPaperReqVo.getPaperId()); diff --git a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/service/browser/BrowserServericeImpl.java b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/service/browser/BrowserServericeImpl.java index 1a16c245..b16d2e8a 100644 --- a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/service/browser/BrowserServericeImpl.java +++ b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/service/browser/BrowserServericeImpl.java @@ -1,176 +1,40 @@ -package pc.exam.pp.module.judgement.controller.service.browser; - -import jakarta.annotation.Resource; -import org.springframework.stereotype.Service; -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.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; -import java.io.FileWriter; -import java.io.IOException; -import java.nio.file.Paths; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -@Service -public class BrowserServericeImpl implements IBrowserServerice { - static String answerLogPath ; // 文件路径 - @Resource - private ExamQuestionAnswerMapper examQuestionAnswerMapper; - private static final DateTimeFormatter formatter = - DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); - //考生试题文件夹 -// static final String BASE_DIR = "D:/exam/4/"; - //谷歌浏览器 - String chromeBookmarkPath = System.getenv("LOCALAPPDATA") + "\\Google\\Chrome\\User Data\\Default\\Bookmarks"; - @Override - public SourceAndText Judgement(double score, File file, ExamQuestion question, String judgementStr) throws IOException { - //根据题目,查找考点 - - //得到该试题的得分点 - //Net得分点 文件类型 文件名 考点权值 - // 添加到文件夹 1 - // 添加到收藏夹 2 -// List answerList=new ArrayList<>(); -// answerList.add(new ExamQuestionAnswer("","","","","人民大学", "添加到文件夹 ", "1", "1")); -// answerList.add(new ExamQuestionAnswer("","","","","校情", "添加到文件夹", "1", "2")); -// answerList.add(new ExamQuestionAnswer("","","","","机构", "添加到文件夹", "1", "3")); - SourceAndText sourceAndText = new SourceAndText(); - List answerList = examQuestionAnswerMapper.selectExamQuestionAnswerByQuId(question.getQuId()); - - //判断如果类型为1,为添加到文件夹的html,后缀加 .html -// for (ExamQuestionAnswer answer : answerList) { -// if ("添加到文件夹".equals(answer.getContentIn())) { -// String fileName = answer.getContent(); -// if (!fileName.endsWith(".html")) { -// answer.setContent(fileName + ".html"); -// } +//package pc.exam.pp.module.judgement.controller.service.browser; +// +//import jakarta.annotation.Resource; +//import org.springframework.stereotype.Service; +//import pc.exam.pp.module.exam.dal.mysql.question.ExamQuestionAnswerMapper; +// +//import java.io.BufferedWriter; +//import java.io.FileWriter; +//import java.io.IOException; +//import java.time.LocalDateTime; +//import java.time.format.DateTimeFormatter; +// +//@Service +//public class BrowserServericeImpl implements IBrowserServerice { +// static String answerLogPath ; // 文件路径 +// @Resource +// private ExamQuestionAnswerMapper examQuestionAnswerMapper; +// private static final DateTimeFormatter formatter = +// DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); +// //考生试题文件夹 +//// static final String BASE_DIR = "D:/exam/4/"; +// //谷歌浏览器 +// String chromeBookmarkPath = System.getenv("LOCALAPPDATA") + "\\Google\\Chrome\\User Data\\Default\\Bookmarks"; +// /** +// * 将指定内容追加写入到指定文件中。 +// * +// * @param filePath 文件路径 +// * @param content 要写入的内容 +// */ +// public static void appendToFile(String filePath, String content) { +// try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath, true))) { +// String timestamp = LocalDateTime.now().format(formatter); +// String logLine = String.format("[%s] %s", timestamp, content); +// writer.write(logLine); +// writer.newLine(); // 可选:添加换行符 +// } catch (IOException e) { +// e.printStackTrace(); // } // } - - - - //分为两点,1:文件夹-- 去考生文件夹去找 文件名 - // 2:收藏夹--去浏览器去找 根据值 文件名 查找 - // 找到后 —————— +权值 ,根据文件名删除 - - answerLogPath = file.getParent() + File.separator + "log.txt"; - - //根据路径,得到考生答题文件集合 - Map stuFiles = GetDifferencesBetweenFolders.listFilesAndFoldersWithAttributes(file.toPath()); - - - // 输出学生提交的内容 -// appendToFile(answerLogPath,"=== 学生提交内容(stu 目录) ==="); -// -// 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(); - //这里指挥判断存在文件夹的得分点 - 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()); // 当前得分 - - if ( "添加到收藏夹".equals(examQuestionAnswer.getContentIn())){ - String bookmarkNameToDelete = examQuestionAnswer.getContent(); - //检查收藏夹是否有书签 - boolean isCorrect = BookmarkChecker.bookmarkExists(chromeBookmarkPath, bookmarkNameToDelete); - if (isCorrect) { - //如果有 +权值 - studentScore += currentScore; - - - // 计算该考点的权重得分并保留一位小数 - double weightScore = ((double) currentScore / totalScore) * score; - 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"); - - } - } - - } - - // 计算最终得分比例(保留两位小数) - double scoreRatio = totalScore == 0 ? 0 : (double) studentScore / totalScore; - - double roundedScoreRatio = Math.round(scoreRatio * 100.0) / 100.0; // 四舍五入到2位小数 - appendToFile(answerLogPath," 得分:"+roundedScoreRatio*score); - sourceAndText.setScore(roundedScoreRatio*score); - sourceAndText.setText(judgementStr); - return sourceAndText; - } - - - // 对比学生提交内容与试题得分点 - static SourceAndText compareStuAndTestFiles(List answerList, Map 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(); // 试题文件路径 - int currentScore = Integer.parseInt(answer.getScoreRate()); // 当前得分 - boolean isCorrect = false; - // 如果学生提交中存在该文件,则得分 - isCorrect = stuFiles.containsKey(filePath); - // 如果正确,则累加总分 - if (isCorrect) { - totalScore += currentScore; - // 计算该考点的权重得分并保留一位小数 - 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"); - } - } - } - //返回累加的得分点 - sourceAndText.setScore(totalScore); - sourceAndText.setText(judgementStr); - return sourceAndText; - } - /** - * 将指定内容追加写入到指定文件中。 - * - * @param filePath 文件路径 - * @param content 要写入的内容 - */ - public static void appendToFile(String filePath, String content) { - try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath, true))) { - String timestamp = LocalDateTime.now().format(formatter); - String logLine = String.format("[%s] %s", timestamp, content); - writer.write(logLine); - writer.newLine(); // 可选:添加换行符 - } catch (IOException e) { - e.printStackTrace(); - } - } -} +//} diff --git a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/service/browser/IBrowserServerice.java b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/service/browser/IBrowserServerice.java index 93c42403..8a7e24f5 100644 --- a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/service/browser/IBrowserServerice.java +++ b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/service/browser/IBrowserServerice.java @@ -1,13 +1,10 @@ -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 { - SourceAndText Judgement(double score, File file, ExamQuestion question, String judgementStr) throws IOException; - - -} +//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 { +//} diff --git a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/service/file/FileServericeImpl.java b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/service/file/FileServericeImpl.java index 744f288b..0f3daf69 100644 --- a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/service/file/FileServericeImpl.java +++ b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/service/file/FileServericeImpl.java @@ -1,142 +1,18 @@ -package pc.exam.pp.module.judgement.controller.service.file; - -import jakarta.annotation.Resource; -import org.springframework.stereotype.Service; -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; -import java.io.FileWriter; -import java.io.IOException; -import java.nio.file.Paths; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; -import java.util.Map; - - -@Service -public class FileServericeImpl implements IFileServerice { - static String answerLogPath ; // 文件路径 - @Resource - private ExamQuestionAnswerMapper examQuestionAnswerMapper; - private static final DateTimeFormatter formatter = - DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); - @Override - public SourceAndText run_file_point(double score, File file, ExamQuestion question, String judgementStr) throws IOException { - SourceAndText sourceAndText = new SourceAndText(); - List answerList = examQuestionAnswerMapper.selectExamQuestionAnswerByQuId(question.getQuId()); - - //todo 得到学生的考题答案 -// List answerList=new ArrayList<>(); -// answerList.add(new ExamQuestionAnswer("","","","","HGACYL\\RLQM.MEM", "考察删除", "1", "1")); -// answerList.add(new ExamQuestionAnswer("","","","","TING\\XYU\\AUTOE.BAT", "考察删除", "1", "2")); -// answerList.add(new ExamQuestionAnswer("","","","","AHEWL\\KMENS", "考察名称", "1", "3")); -// answerList.add(new ExamQuestionAnswer("","","","","EDZK\\RONGHE.COM", "考察名称", "1", "4")); -// answerList.add(new ExamQuestionAnswer("","","","","HGACYL\\PLAY.MEM", "考察名称", "1", "5")); -// answerList.add(new ExamQuestionAnswer("","","","","WUE\\PB6.txt", "考察名称", "1", "6")); - - - File stuPath = file; - - // 设置日志文件路径为file所在目录下的answerLogFile.txt - answerLogPath = file.getParent() + File.separator + "log.txt"; - System.out.println(answerLogPath); - // 获取 stu 文件夹的内容 - Map stuFiles = GetDifferencesBetweenFolders.listFilesAndFoldersWithAttributes(stuPath.toPath()); - - // 输出学生提交的内容 -// appendToFile(answerLogPath,"=== 学生提交内容(stu 目录) ==="); +//package pc.exam.pp.module.judgement.controller.service.file; // -// stuFiles.forEach((key, value) -> appendToFile(answerLogPath,key + " -> " + value)); - -// 计算试题总分 - int totalScore = answerList.stream() - .mapToInt(a -> Integer.parseInt(a.getScoreRate())) - .sum(); - appendToFile(answerLogPath,"=== 学生提交内容得分点 ==="); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "=== 学生提交内容得分点 ==="); - // 对比学生提交内容与试题得分点 - 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); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "得分:"+roundedScoreRatio*score); - sourceAndText.setScore(roundedScoreRatio*score); - sourceAndText.setText(judgementStr); - return sourceAndText; - } - - - // 对比学生提交内容与试题得分点 - static SourceAndText compareStuAndTestFiles(List answerList, Map 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(); // 考察类型(考察删除 / 考察名称 / 考察属性) - int currentScore = Integer.parseInt(answer.getScoreRate()); // 当前得分 - boolean isCorrect = false; - - if ("考察删除".equals(checkType)) { - // 如果学生提交中不存在该文件,则得分 - isCorrect = !stuFiles.containsKey(filePath); - } else if ("考察名称".equals(checkType)) { - // 如果学生提交中存在该文件,则得分 - isCorrect = stuFiles.containsKey(filePath); - } else if ("考察属性".equals(checkType)) { - // 如果学生提交中存在该文件,且属性匹配,则得分 - if (stuFiles.containsKey(filePath)) { - String studentAttrs = stuFiles.get(filePath); // 学生提交的属性 - String expectedAttrs = answer.getAttribute(); // 试题中期望的属性 - isCorrect = studentAttrs.equals(expectedAttrs); - } - } - // 如果正确,则累加总分 - if (isCorrect) { - totalScore += currentScore; - // 计算该考点的权重得分并保留一位小数 - 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 sourceAndText; - } - - /** - * 将指定内容追加写入到指定文件中。 - * - * @param filePath 文件路径 - * @param content 要写入的内容 - */ - public static void appendToFile(String filePath, String content) { - try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath, true))) { - String timestamp = LocalDateTime.now().format(formatter); - String logLine = String.format("[%s] %s", timestamp, content); - writer.write(logLine); - writer.newLine(); // 可选:添加换行符 - } catch (IOException e) { - e.printStackTrace(); - } - } -} +//import jakarta.annotation.Resource; +//import org.springframework.stereotype.Service; +//import pc.exam.pp.module.exam.dal.mysql.question.ExamQuestionAnswerMapper; +// +//import java.time.format.DateTimeFormatter; +// +// +//@Service +//public class FileServericeImpl implements IFileServerice { +// static String answerLogPath ; // 文件路径 +// @Resource +// private ExamQuestionAnswerMapper examQuestionAnswerMapper; +// private static final DateTimeFormatter formatter = +// DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); +// +//} diff --git a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/service/file/IFileServerice.java b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/service/file/IFileServerice.java index 13c8981d..e979e052 100644 --- a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/service/file/IFileServerice.java +++ b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/service/file/IFileServerice.java @@ -1,20 +1,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; -import java.util.List; - -public interface IFileServerice { - - - - - SourceAndText run_file_point(double score, File file, ExamQuestion question, String judgementStr) throws IOException; - - -} +//package pc.exam.pp.module.judgement.controller.service.file; +// +// +//public interface IFileServerice { +// +// +//} diff --git a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/service/mysql/IMysqlLocalService.java b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/service/mysql/IMysqlLocalService.java index d65e6728..60c1630f 100644 --- a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/service/mysql/IMysqlLocalService.java +++ b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/service/mysql/IMysqlLocalService.java @@ -1,16 +1,16 @@ -package pc.exam.pp.module.judgement.controller.service.mysql; - -import pc.exam.pp.framework.common.pojo.CommonResult; -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; -import java.sql.SQLException; - -public interface IMysqlLocalService { - SourceAndText Judgement(double sorce, File file, ExamQuestion examQuestion, String judgementStr) throws IOException, SQLException; - - void delMysqlConnect(String tName); - -} +//package pc.exam.pp.module.judgement.controller.service.mysql; +// +//import pc.exam.pp.framework.common.pojo.CommonResult; +//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; +//import java.sql.SQLException; +// +//public interface IMysqlLocalService { +// SourceAndText Judgement(double sorce, File file, ExamQuestion examQuestion, String judgementStr) throws IOException, SQLException; +// +// void delMysqlConnect(String tName); +// +//} diff --git a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/service/mysql/IMysqlLocalServiceImpl.java b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/service/mysql/IMysqlLocalServiceImpl.java index 4421a9c1..aaab77da 100644 --- a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/service/mysql/IMysqlLocalServiceImpl.java +++ b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/service/mysql/IMysqlLocalServiceImpl.java @@ -1,1892 +1,1890 @@ -package pc.exam.pp.module.judgement.controller.service.mysql; - -import jakarta.annotation.Resource; -import org.apache.commons.lang3.StringEscapeUtils; -import org.apache.commons.lang3.StringUtils; -import org.springframework.stereotype.Service; -import pc.exam.pp.framework.common.pojo.CommonResult; -import pc.exam.pp.module.exam.dal.dataobject.ExamMysqlKeyword; -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.ExamMysqlKeywordMapper; -import pc.exam.pp.module.exam.dal.mysql.question.ExamQuestionAnswerMapper; -import pc.exam.pp.module.judgement.controller.service.mysql.vo.MysqlBooleanVo; -import pc.exam.pp.module.judgement.controller.service.mysql.vo.MysqlVo; -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.utils.HtmlAppender; - -import java.io.*; -import java.math.BigDecimal; -import java.math.RoundingMode; -import java.nio.charset.StandardCharsets; -import java.nio.file.DirectoryStream; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.sql.*; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.util.*; -import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicReference; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -@Service -public class IMysqlLocalServiceImpl implements IMysqlLocalService{ - - static String databaseName; - static String databaseNameStu; - static String answerLogPath; // 文件路径 - private static final DateTimeFormatter formatter = - DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); - @Resource - private ExamMysqlKeywordMapper examMysqlKeywordMapper; - @Resource - private ExamQuestionAnswerMapper examQuestionAnswerMapper; - - @Override - public SourceAndText Judgement(double score, File filepath, ExamQuestion examQuestion, String judgementStr) throws IOException, SQLException { - String stuDataName=examQuestion.getTname(); - SourceAndText sourceAndText = new SourceAndText(); - double scoreTotal =0.0; - String fileUrl= examQuestionAnswerMapper.selectAnswerFile(examQuestion.getQuId()); - String path = ZipUtil.downloadStudentFile(fileUrl, "data"); - // 4、获取到得是zip文件,需要解压 - String stuFilePath = ZipUtil.unzipToNamedFolder(path); - File folderzip = new File(path); - File folder = new File(stuFilePath); - // 5、解压之后得文件获取文件夹和文件 - String stu_files = null; - - // 5.2、查询试题ID - - List examQuestionAnswers = examQuestionAnswerMapper.selectExamQuestionAnswerByQuId(examQuestion.getQuId()); - String totalKeyScore ="0"; - //得出 这个题总共的权值点 - totalKeyScore=examQuestionAnswerMapper.selectCountPointByQuId(examQuestion.getQuId()); - - answerLogPath = filepath.getParent() + File.separator + "log.txt"; - - AtomicInteger total = new AtomicInteger(); - // 文件路径 - -// String file = "D:\\Desktop\\202504211120_mysql\\71\\MYS_010_122\\结果素材\\结果素材\\Teacher"; -// String file = new File(filepath, "结果").getAbsolutePath(); -// String filePath = "D:\\Desktop\\202504211120_mysql\\71\\MYS_010_122\\结果素材\\结果素材\\Teacher\\answer.txt"; // 答案文件路径 - String filePath = new File(stuFilePath).getAbsolutePath(); // 结果/answer.txt - -// String answerPath = "D:\\Desktop\\202504211120_mysql\\71\\MYS_010_122\\结果素材\\结果素材\\Teacher\\db\\db_escape.myd"; // 原始 SQL 文件路径 - File dbDir = new File(stuFilePath, "db"); - String answerPath = null; - if (dbDir.exists() && dbDir.isDirectory()) { - File[] mydFiles = dbDir.listFiles((dir, name) -> name.toLowerCase().endsWith(".myd")); - if (mydFiles != null && mydFiles.length > 0) { - answerPath = mydFiles[0].getAbsolutePath(); // 默认取第一个 .myd 文件 - } - } - - -// String fileStu = "D:\\Desktop\\202504211120_mysql\\71\\MYS_010_122\\考试素材\\考试素材\\Student"; - String fileStu = filepath.getAbsolutePath(); - -// String stuAnswerPath = "D:\\Desktop\\202504211120_mysql\\71\\MYS_010_122\\考试素材\\考试素材\\Student\\db\\db_escape.myd"; - File stuDbDir = new File(fileStu, "db"); - String stuAnswerPath = null; - if (stuDbDir.exists() && stuDbDir.isDirectory()) { - File[] stuMydFiles = stuDbDir.listFiles((dir, name) -> name.toLowerCase().endsWith(".myd")); - if (stuMydFiles != null && stuMydFiles.length > 0) { - stuAnswerPath = stuMydFiles[0].getAbsolutePath(); // 默认取第一个 .myd 文件 - } - } - - // 生成随机数据库名,临时使用 - databaseName = "db_" + UUID.randomUUID().toString().replace("-", "").substring(0, 8); - -// databaseName = "db_6f80867f"; -// databaseNameStu= "db_6f80867e"; - // 连接到 MySQL 默认数据库 - String url = "jdbc:mysql://localhost:6033/"+stuDataName+"?useSSL=false&serverTimezone=Asia/Shanghai"; - String user = "root"; - String password = ""; - try { - // **连接到 MySQL 默认数据库,创建新的数据库** - try (Connection conn = DriverManager.getConnection(url, user, password); - Statement stmt = conn.createStatement()) { - String createDbSql = "CREATE DATABASE IF NOT EXISTS " + databaseName + - " CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci"; -// String createDbSql = "CREATE DATABASE " + databaseName; - stmt.executeUpdate(createDbSql); - System.out.println("已创建数据库:" + databaseName); - - - - } - - - } catch (SQLException e) { - e.printStackTrace(); - } - -// // **建立连接到新创建的数据库** - String newDbUrl = "jdbc:mysql://localhost:6033/" + databaseName + "?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=UTF-8"; - String stuDbUrl = "jdbc:mysql://localhost:6033/" + stuDataName + "?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=UTF-8"; - // **通过命令行执行 SQL 文件** 建立 完整正确数据库 - boolean sqlFileExecuted = executeSqlFileUsingCommandLine(answerPath, databaseName, user, password); - //建立考生答题数据库 -// boolean sqlFileExecutedstu = executeSqlFileUsingCommandLine(stuAnswerPath, databaseNameStu, user, password); - - if (sqlFileExecuted ) { - - - Map result = readFilesAsMap(stuFilePath); - Map resultStu = readFilesAsMap(fileStu); - - try (Connection conn = DriverManager.getConnection(newDbUrl, user, password); - Statement stmt = conn.createStatement()) { - for (ExamQuestionAnswer examQuestionAnswer : examQuestionAnswers) { - String sql=examQuestionAnswer.getContent(); - if(sql.trim().toUpperCase().startsWith("CREATE TABLE")) { - appendToFile(answerLogPath, "==================建表语句=================="); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "==================建表语句=================="); - // 匹配成功 - String answerId = examQuestionAnswer.getAnswerId(); - List examMysqlKeywordList= examMysqlKeywordMapper.selectListByAnswerId(answerId); - - // 正则表达式匹配表名 - Pattern pattern = Pattern.compile("CREATE TABLE\\s+`?(\\w+)`?\\s*\\("); - Matcher matcher = pattern.matcher(sql); - - if (matcher.find()) { - String tableName = matcher.group(1).replace("`", ""); // 获取表名 - - - // 查询建表语句 - String showCreateTableSql = "SHOW CREATE TABLE " + tableName; - - String sql1 = "SELECT COLUMN_NAME, COLUMN_TYPE, IS_NULLABLE, COLUMN_KEY, EXTRA " + - "FROM INFORMATION_SCHEMA.COLUMNS " + - "WHERE TABLE_NAME = '" + tableName + "' AND TABLE_SCHEMA = '" + databaseName + "'"; - String sql2 = "SELECT COLUMN_NAME, COLUMN_TYPE, IS_NULLABLE, COLUMN_KEY, EXTRA " + - "FROM INFORMATION_SCHEMA.COLUMNS " + - "WHERE TABLE_NAME = '" + tableName + "' AND TABLE_SCHEMA = '" + stuDataName + "'"; - - // 获取主库字段信息 - Set> table1Columns = new HashSet<>(); - try (ResultSet rs = stmt.executeQuery(sql1)) { - while (rs.next()) { - Map column = new HashMap<>(); - column.put("COLUMN_NAME", rs.getString("COLUMN_NAME")); - column.put("COLUMN_TYPE", rs.getString("COLUMN_TYPE")); - column.put("IS_NULLABLE", rs.getString("IS_NULLABLE")); - column.put("COLUMN_KEY", rs.getString("COLUMN_KEY")); - column.put("EXTRA", rs.getString("EXTRA")); - table1Columns.add(column); - - } -// appendToFile(answerLogPath, "标准答案建表键值对:"+table1Columns); -// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "标准答案建表键值对:"+table1Columns); - - - } - // 获取学生库字段信息 - Set> table2Columns = new HashSet<>(); - boolean tableExists = false; - //学生语句 - String stuSQL=null; - try (Connection connstu = DriverManager.getConnection(stuDbUrl, user, password); - Statement stmtstu = connstu.createStatement()) { - try (ResultSet rsstu = stmtstu.executeQuery(sql2)) { - // 检查是否有数据返回 - tableExists = rsstu.next(); // 第一次调用next()判断是否有数据 - if (tableExists) { - try (ResultSet rs = stmt.executeQuery(showCreateTableSql)) { - if (rs.next()) { - String createTableSqlExport = rs.getString("Create Table"); - // 替换 result 中的值 - stuSQL=createTableSqlExport; - } - } - - // 如果有数据,处理第一行(因为上面已经调用了next()) - do { - Map column = new HashMap<>(); - column.put("COLUMN_NAME", rsstu.getString("COLUMN_NAME")); - column.put("COLUMN_TYPE", rsstu.getString("COLUMN_TYPE")); - column.put("IS_NULLABLE", rsstu.getString("IS_NULLABLE")); - column.put("COLUMN_KEY", rsstu.getString("COLUMN_KEY")); - column.put("EXTRA", rsstu.getString("EXTRA")); - table2Columns.add(column); - } while (rsstu.next()); - - } else { - // 表不存在时的处理逻辑 - System.out.println("表 " + tableName + " 在学生数据库中不存在"); - // 或者 throw new RuntimeException("表不存在"); - String yuju= compareTables(table1Columns, table2Columns, stuDataName,tableName, "",judgementStr); - judgementStr=yuju; - - - } - - - } - } - - String yuju= compareTables(table1Columns, table2Columns, stuDataName,tableName, tableName,judgementStr); - judgementStr=yuju; - - - - if (table1Columns.equals(table2Columns)) { - // - SourceAndText studentScorePojo = accumulateScoreAndLog(examMysqlKeywordList,total,answerLogPath,stuSQL,totalKeyScore,score,answerId,scoreTotal,judgementStr); - scoreTotal += studentScorePojo.getScore(); - judgementStr = studentScorePojo.getText(); - } else { - SourceAndText studentScorePojo= calculateTotalScoreRate(stuSQL, examMysqlKeywordList,totalKeyScore,score,answerId,scoreTotal,judgementStr); - scoreTotal += studentScorePojo.getScore(); - judgementStr = studentScorePojo.getText(); - } - } - - } - - if (sql.trim().toUpperCase().startsWith("INSERT")) { - appendToFile(answerLogPath, "==================插入语句=================="); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "==================插入语句=================="); - // 正则表达式匹配表名 - Pattern pattern = Pattern.compile("INSERT INTO\\s+`?(\\w+)`?\\s*\\("); - Matcher matcher = pattern.matcher(sql); - appendToFile(answerLogPath, "答案语句: " + sql); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "答案语句: "); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, sql); - if (matcher.find()) { - String tableName = matcher.group(1).replace("`", ""); // 获取表名 - // 匹配成功 - String answerId= examQuestionAnswer.getAnswerId(); - List examMysqlKeywordList = examMysqlKeywordMapper.selectListByAnswerId(answerId); - - - //把select语句 转化成验证语句sql - String yanzheng = convertInsertToSelect(sql); - String stuSql=null; - List> answerList= new ArrayList<>(); - List> answerListStu = new ArrayList<>(); - try (Connection connanswer = DriverManager.getConnection(newDbUrl, user, password); - Statement stmtan = connanswer.createStatement()) { - try (ResultSet answer = stmtan.executeQuery(yanzheng)) { - answerList = getAnswerList(answer); -// appendToFile(answerLogPath, "查找语句标准答案"); -// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "查找语句标准答案"); -// printResult(answerList,judgementStr); - }catch (SQLException e) { - appendToFile(answerLogPath, "答案表执行验证语句"+yanzheng+"时发生错误: " + e.getMessage()); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "答案表执行验证语句"+yanzheng+"时发生错误: " + e.getMessage()); - e.printStackTrace(); - } - } - try (Connection connstu = DriverManager.getConnection(stuDbUrl, user, password); - Statement stmtstu = connstu.createStatement()) { - try (ResultSet answer = stmtstu.executeQuery(yanzheng)) { - answerListStu = getAnswerList(answer); - //这里根据answerListStu ,还原学生的sql语句 - List columnNames = getColumnNames(answer); // ← 获取字段名 - - String tName = extractTableNameFromInsert(sql); - - //构建还原 SQL(你可以自定义表名,比如传 "student_table") - stuSql = generateInsertSQL(tName, columnNames, answerListStu); -// appendToFile(answerLogPath, "学生对"+tName+"插入的SQL:\n" + stuSql); -// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "学生对"+tName+"+插入的SQL:" ); -// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, stuSql); -// appendToFile(answerLogPath, "学生语句答案"); -// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "学生语句答案"); -// printResult(answerListStu,judgementStr); - } catch (SQLException e) { - appendToFile(answerLogPath, "学生表执行验证语句"+yanzheng+"时发生错误: " + e.getMessage()); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "学生表执行验证语句"+yanzheng+"时发生错误: " + e.getMessage()); - } - } - boolean isEquivalent =false; - - if (answerListStu!=null&&answerListStu.size()>0){ - isEquivalent = compareResultsSelect(answerList, answerListStu); - } - - if (isEquivalent) { - SourceAndText studentScorePojo = accumulateScoreAndLog(examMysqlKeywordList,total,answerLogPath,stuSql,totalKeyScore,score,answerId,scoreTotal,judgementStr); - scoreTotal += studentScorePojo.getScore(); - judgementStr = studentScorePojo.getText(); - } else { - SourceAndText studentScorePojo= calculateTotalScoreRate(stuSql, examMysqlKeywordList,totalKeyScore,score,answerId,scoreTotal,judgementStr); - scoreTotal += studentScorePojo.getScore(); - judgementStr = studentScorePojo.getText(); - } - } - - } - if (sql.trim().toUpperCase().startsWith("DELETE")) { - appendToFile(answerLogPath, "==================删除语句=================="); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "==================删除语句=================="); - - appendToFile(answerLogPath, "答案语句: " + sql); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "答案语句: "); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, sql); - sql = sql.trim().replaceAll(";+\\s*$", ""); - // 正则提取表名和 WHERE 条件 - Pattern pattern = Pattern.compile("DELETE\\s+FROM\\s+(\\w+)\\s+WHERE\\s+(.+)", Pattern.CASE_INSENSITIVE); - Matcher matcher = pattern.matcher(sql); - // 匹配成功 - String answerId = examQuestionAnswer.getAnswerId(); - List examMysqlKeywordList = examMysqlKeywordMapper.selectListByAnswerId(answerId); - - if (matcher.find()) { - String tableName = matcher.group(1).trim(); - String whereClause = matcher.group(2).trim(); - pc.exam.pp.module.judgement.controller.service.mysql.MysqlServericeImpl.DeleteInfo deleteInfo = new pc.exam.pp.module.judgement.controller.service.mysql.MysqlServericeImpl.DeleteInfo(tableName, whereClause); -// appendToFile(answerLogPath, "提取出的表名: " + deleteInfo.tableName); -// appendToFile(answerLogPath, "提取出的条件: " + deleteInfo.whereClause); - // 构造验证 SQL - String verifySql = "SELECT COUNT(*) FROM " + deleteInfo.tableName + " WHERE " + deleteInfo.whereClause; -// appendToFile(answerLogPath, "验证 SQL: " + verifySql); - //查找正确答案的 -// try (Connection conn = DriverManager.getConnection(newDbUrl, user, password); -// Statement stmt = conn.createStatement()) { - try (ResultSet rs = stmt.executeQuery(verifySql)) { - if (rs.next()) { - int count = rs.getInt(1); - if (count == 0) { - try (Connection connstu = DriverManager.getConnection(stuDbUrl, user, password); - Statement stmtstu = connstu.createStatement()) { - try (ResultSet rsstu = stmtstu.executeQuery(verifySql)) { - if (rsstu.next()) { - int countstu = rsstu.getInt(1); - if (countstu == 0) { - //累加删除语句的所有权值 examQuestionKeywords累加scorerate - appendToFile(answerLogPath, "验证通过:符合 DELETE 条件的记录已删除。"); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "验证通过:符合 DELETE 条件的记录已删除。"); - SourceAndText studentScorePojo = accumulateScoreAndLog(examMysqlKeywordList,total,answerLogPath,sql,totalKeyScore,score,answerId,scoreTotal,judgementStr); - scoreTotal += studentScorePojo.getScore(); - judgementStr = studentScorePojo.getText(); - - } else { - SourceAndText studentScorePojo= calculateTotalScoreRate(null, examMysqlKeywordList,totalKeyScore,score,answerId,scoreTotal,judgementStr); - scoreTotal += studentScorePojo.getScore(); - judgementStr = studentScorePojo.getText(); - } - } - }catch (SQLException e) { - appendToFile(answerLogPath, "验证学生库失败,"+"得分:0 ❌"); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "验证学生库失败,"+"得分:0 ❌"); - } - - } - - - } 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(); - } - - } - - } - - if (sql.trim().toUpperCase().startsWith("UPDATE")) { - appendToFile(answerLogPath, "==================更新语句=================="); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "==================更新语句=================="); - appendToFile(answerLogPath, "答案语句: " + sql); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "答案语句: "); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, sql); - // 匹配成功 - String answerId = examQuestionAnswer.getAnswerId(); - List examMysqlKeywordList= examMysqlKeywordMapper.selectListByAnswerId(answerId); - //转换成select语句 - String selectSql = convertUpdateToSelectWhere(sql); - - List> answerList= new ArrayList<>(); - List> answerListStu = new ArrayList<>(); - try (Connection connanswer = DriverManager.getConnection(newDbUrl, user, password); - Statement stmtan = connanswer.createStatement()) { - try (ResultSet answer = stmtan.executeQuery(selectSql)) { - answerList = getAnswerList(answer); -// appendToFile(answerLogPath, "查找语句标准答案"); -// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "查找语句标准答案"); -// printResult(answerList,judgementStr); - }catch (SQLException e) { - appendToFile(answerLogPath, "答案表执行验证语句"+selectSql+"时发生错误: " + e.getMessage()); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "答案表执行验证语句"+selectSql+"时发生错误: " + e.getMessage()); - e.printStackTrace(); - } - } - String stuSql =null; - try (Connection connstu = DriverManager.getConnection(stuDbUrl, user, password); - Statement stmtstu = connstu.createStatement()) { - try (ResultSet answer = stmtstu.executeQuery(selectSql)) { - answerListStu = getAnswerList(answer); - //还原 sql - ResultSetMetaData meta = answer.getMetaData(); - List columns = new ArrayList<>(); - for (int i = 1; i <= meta.getColumnCount(); i++) { - columns.add(meta.getColumnLabel(i)); - } - - stuSql = restoreUpdateFromResult(sql, columns, answerListStu); -// appendToFile(answerLogPath, "还原学生 UPDATE 语句:" + stuSql); -// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "还原学生 UPDATE 语句:" + stuSql); -// appendToFile(answerLogPath, "学生语句答案:"); -// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "学生语句答案:"); -// printResult(answerListStu,judgementStr); - } catch (SQLException e) { - appendToFile(answerLogPath, "学生表执行验证语句"+selectSql+"时发生错误:" + e.getMessage()); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "学生表执行验证语句"+selectSql+"时发生错误: " + e.getMessage()); - } - - - } - boolean isEquivalent =false; - - if (answerListStu!=null&&answerListStu.size()>0){ - isEquivalent = compareResultsSelect(answerList, answerListStu); - } - // - if (isEquivalent) { - SourceAndText studentScorePojo = accumulateScoreAndLog(examMysqlKeywordList,total,answerLogPath,stuSql,totalKeyScore,score,answerId,scoreTotal,judgementStr); - scoreTotal += studentScorePojo.getScore(); - judgementStr = studentScorePojo.getText(); - - } else { - SourceAndText studentScorePojo= calculateTotalScoreRate(stuSql, examMysqlKeywordList,totalKeyScore,score,answerId,scoreTotal,judgementStr); - scoreTotal += studentScorePojo.getScore(); - judgementStr = studentScorePojo.getText(); - - } - - } - if (sql.trim().toUpperCase().startsWith("SELECT")) { - appendToFile(answerLogPath, "==================查找语句=================="); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "==================查找语句=================="); - // 匹配成功 - String answerId = examQuestionAnswer.getAnswerId(); - List examMysqlKeywordList= examMysqlKeywordMapper.selectListByAnswerId(answerId); - - appendToFile(answerLogPath, "答案语句: " + sql); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "答案语句: "); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, sql); - - AtomicReference stuAnswer = new AtomicReference<>(); - - // 根据sql 的内容查询结果文件夹语句的文件名,再根据文件名 查找 考生 - try { - String finalSql = sql; - Files.walk(Paths.get(filePath)) - .filter(Files::isRegularFile) - .forEach(filePaths -> { - try { - String fileContent = Files.readString(filePaths, StandardCharsets.UTF_8); - String normalizedFileContent = fileContent.trim().replaceAll("\\s+", "").toLowerCase(); - String normalizedFinalSql = finalSql.trim().replaceAll("\\s+", "").toLowerCase(); - if (normalizedFinalSql.equals(normalizedFileContent)) { - - String stuPath=fileStu+"\\"+filePaths.getFileName(); - stuAnswer.set(readSQLFromFile(stuPath)); - System.out.println("考生语句"+stuAnswer); - } - } catch (Exception e) { - appendToFile(answerLogPath,"读取文件失败:" + filePaths); - e.printStackTrace(); - } - } - ); - } catch (IOException e) { - appendToFile(answerLogPath,"遍历目录出错!"); - e.printStackTrace(); - } - - List> answerList= new ArrayList<>(); - List> answerListStu = new ArrayList<>(); - try (Connection connanswer = DriverManager.getConnection(newDbUrl, user, password); - Statement stmtan = connanswer.createStatement()) { - try (ResultSet answer = stmtan.executeQuery(sql)) { - answerList = getAnswerList(answer); - appendToFile(answerLogPath, "运行标准答案语句的查询结果:"); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "运行标准答案语句的查询结果:"); - judgementStr = printResult(answerList,judgementStr); - }catch (SQLException e) { - appendToFile(answerLogPath, "执行验证语句"+sql+"时发生错误: " + e.getMessage()); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "执行验证语句"+sql+"时发生错误: " + e.getMessage()); - e.printStackTrace(); - } - } - try (Connection connstu = DriverManager.getConnection(stuDbUrl, user, password); - Statement stmtstu = connstu.createStatement()) { - if (StringUtils.isBlank(stuAnswer.get())) { - SourceAndText sourceAndTextError = new SourceAndText(); - appendToFile(answerLogPath, "❌考生SQL文件丢失或未作答,无法评分,得分:0.0"); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "❌考生SQL文件丢失或未作答,无法评分,得分:0.0"); - sourceAndTextError.setText(judgementStr); - sourceAndTextError.setScore(0.0); - continue; - } - try (ResultSet answer = stmtstu.executeQuery(String.valueOf(stuAnswer))) { - answerListStu = getAnswerList(answer); - appendToFile(answerLogPath, "运行学生语句的查询结果:"); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "运行学生语句的查询结果:"); - judgementStr= printResult(answerListStu,judgementStr); - } catch (SQLException e) { - appendToFile(answerLogPath, "执行学生库语句"+String.valueOf(stuAnswer)+"时发生错误: " + e.getMessage()); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "执行学生库语句"+String.valueOf(stuAnswer)+"时发生错误: " + e.getMessage()); - } - - } - boolean isEquivalent =false; - - if (answerListStu!=null&&answerListStu.size()>0){ - isEquivalent = compareResultsSelect(answerList, answerListStu); - } - - if (isEquivalent) { - //todo 得分 - SourceAndText studentScorePojo = accumulateScoreAndLog(examMysqlKeywordList,total,answerLogPath,String.valueOf(stuAnswer),totalKeyScore,score,answerId,scoreTotal,judgementStr); - scoreTotal += studentScorePojo.getScore(); - judgementStr = studentScorePojo.getText(); - - } else { - SourceAndText studentScorePojo= calculateTotalScoreRate(String.valueOf(stuAnswer), examMysqlKeywordList,totalKeyScore,score,answerId,scoreTotal,judgementStr); - scoreTotal += studentScorePojo.getScore(); - judgementStr = studentScorePojo.getText(); - - } - - } - - - if (sql.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, "==================视图语句=================="); - // 匹配成功 - String answerId = examQuestionAnswer.getAnswerId(); - List examMysqlKeywordList= examMysqlKeywordMapper.selectListByAnswerId(answerId); - appendToFile(answerLogPath, "答案语句: " + sql); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "答案语句: "); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, sql); - - // 正则表达式,用于匹配 "VIEW" 后面的视图名称 - String regex = "(?<=VIEW\\s)([\\w`_]+)"; - String sqlviewAnswer = removeComments(sql); - String viewNam1 = extractViewName(sqlviewAnswer, regex); - - String showCreateViewSql = "SHOW CREATE VIEW " + viewNam1; - - // 执行查询,获取答案 视图的结果 - appendToFile(answerLogPath, "执行正确答案视图语句的查询结果:"); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "执行正确答案视图语句的查询结果:"); - String sql3 = "SELECT * FROM " + viewNam1; - List> result1 = executeQuery(stmt, sql3); - judgementStr= printResult(result1,judgementStr); - - List> result2 =new ArrayList<>(); - String stuSQL =null; - boolean hasError = false; // 添加标志变量 - try (Connection connstu = DriverManager.getConnection(stuDbUrl, user, password); - Statement stmtstu = connstu.createStatement()) { - - try (ResultSet rs = stmtstu.executeQuery(showCreateViewSql)) { - if (rs.next()) { - String createViewSqlExport = rs.getString("Create View"); - // 替换 result 中的值 - stuSQL=createViewSqlExport; - } - }catch (SQLException e) { - appendToFile(answerLogPath, "执行学生库语句"+showCreateViewSql+"时发生错误: " + e.getMessage()); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "执行学生库语句"+showCreateViewSql+"时发生错误: " + e.getMessage()); - hasError = true; // 发生异常,设为 true - } - - // 执行查询,获取考生 视图的结果 - appendToFile(answerLogPath, "执行考生视图语句的查询结果:"); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "执行考生视图语句的查询结果:"); - - try { - result2 = executeQuery(stmtstu, sql3); - - } catch (SQLException e) { - appendToFile(answerLogPath, "执行学生库语句"+sql3+"时发生错误: " + e.getMessage()); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "执行学生库语句"+sql3+"时发生错误: " + e.getMessage()); - hasError = true; // 发生异常,设为 true - } - - - judgementStr= printResult(result2,judgementStr); - } - - // 比较两个视图的结果 - boolean isEquivalent =!hasError &&compareResults(result1, result2); - appendToFile(answerLogPath, "\n是否结果等价: " + isEquivalent); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "\n是否结果等价: " + isEquivalent); - - - if (isEquivalent) { - SourceAndText studentScorePojo = accumulateScoreAndLog(examMysqlKeywordList,total,answerLogPath,stuSQL,totalKeyScore,score,answerId,scoreTotal,judgementStr); - scoreTotal += studentScorePojo.getScore(); - judgementStr = studentScorePojo.getText(); - - } else { - SourceAndText studentScorePojo= calculateTotalScoreRate(stuSQL, examMysqlKeywordList,totalKeyScore,score,answerId,scoreTotal,judgementStr); - scoreTotal += studentScorePojo.getScore(); - judgementStr = studentScorePojo.getText(); - } -// } - - } - - //存储过程 - if (sql.trim().toUpperCase().toUpperCase().contains("PROCEDURE")) { - // 匹配成功 - String answerId = examQuestionAnswer.getAnswerId(); - List examMysqlKeywordList= examMysqlKeywordMapper.selectListByAnswerId(answerId); - - appendToFile(answerLogPath, "==================储存过程=================="); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "==================储存过程=================="); - appendToFile(answerLogPath, "答案语句: " + sql); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "答案语句: "); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, sql); - - - AtomicReference stuAnswer = new AtomicReference<>(); - - // 根据sql 的内容查询结果文件夹语句的文件名,再根据文件名 查找 考生 - try { - String finalSql = sql; - Files.walk(Paths.get(filePath)) - .filter(Files::isRegularFile) - .forEach(filePaths -> { - try { - String fileContent = Files.readString(filePaths, StandardCharsets.UTF_8); - String normalizedFileContent = fileContent.trim().replaceAll("\\s+", "").toLowerCase(); - String normalizedFinalSql = finalSql.trim().replaceAll("\\s+", "").toLowerCase(); - if (normalizedFinalSql.equals(normalizedFileContent)) { - - String stuPath=fileStu+"\\"+filePaths.getFileName(); - stuAnswer.set(readSQLFromFile(stuPath)); - System.out.println("考生语句"+stuAnswer); - } - } catch (Exception e) { - appendToFile(answerLogPath,"读取文件失败:" + filePaths); - e.printStackTrace(); - } - } - - - ); - } catch (IOException e) { - appendToFile(answerLogPath,"遍历目录出错!"); - e.printStackTrace(); - } - - //提取call语句 - List extractCallStatements = extractCallStatements(sql); - //标准答案 集合 - List> anwerResults = new ArrayList<>(); - //考生答案 集合 - List> stuResults = new ArrayList<>(); - if (extractCallStatements != null && extractCallStatements.size() > 0) { - boolean hasError = false; // 添加标志变量 - for (String extractCallStatement : extractCallStatements) { - appendToFile(answerLogPath, "测试 call 语句:" + extractCallStatement); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "测试 call 语句:" + extractCallStatement); - - try { - - ResultSet newResult = stmt.executeQuery(extractCallStatement); - anwerResults.addAll(extractResults(newResult)); - } catch (SQLException e) { - appendToFile(answerLogPath, "执行标准库 SQL CALL 语句时发生错误: " + e.getMessage()); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "执行标准库 SQL CALL 语句时发生错误: " + e.getMessage()); - } - try (Connection connstu = DriverManager.getConnection(stuDbUrl, user, password); - Statement stmtstu = connstu.createStatement()) { - if (StringUtils.isBlank(stuAnswer.get())) { - SourceAndText sourceAndTextError = new SourceAndText(); - appendToFile(answerLogPath, "❌考生SQL文件丢失或未作答,无法评分,得分:0.0"); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "❌考生SQL文件丢失或未作答,无法评分,得分:0.0"); - sourceAndTextError.setText(judgementStr); - sourceAndTextError.setScore(0.0); - continue; - } - - - try { - ResultSet oldResult = stmtstu.executeQuery(extractCallStatement); - stuResults.addAll(extractResults(oldResult)); - } catch (SQLException e) { - appendToFile(answerLogPath, "执行学生库 SQL CALL 语句时发生错误: " + e.getMessage()); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "执行学生库 SQL CALL 语句时发生错误: " + e.getMessage()); - hasError = true; // 发生异常,设为 true - } - } - - } - // 比较结果(如果发生异常,可以认为比较失败) - MysqlBooleanVo mysqlBooleanVo = compareExtractResults(anwerResults, stuResults,judgementStr); - judgementStr=mysqlBooleanVo.getText(); - boolean flag= !hasError &&mysqlBooleanVo.isFlag(); - - if (flag) { - //todo 得分 - SourceAndText studentScorePojo = accumulateScoreAndLog(examMysqlKeywordList,total,answerLogPath,stuAnswer.get(),totalKeyScore,score,answerId,scoreTotal,judgementStr); - scoreTotal += studentScorePojo.getScore(); - judgementStr = studentScorePojo.getText(); - - } else { - //得分 - SourceAndText studentScorePojo = calculateTotalScoreRate(stuAnswer.get(), examMysqlKeywordList, totalKeyScore, score, answerId, scoreTotal,judgementStr); - scoreTotal += studentScorePojo.getScore(); - judgementStr = studentScorePojo.getText(); - - } - } else { - appendToFile(answerLogPath, "此存储过程无 CALL 语句"); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "此存储过程无 CALL 语句"); - } - } - if (sql.trim().toUpperCase().toUpperCase().contains("TRIGGER")) { - appendToFile(answerLogPath, "==================触发器=================="); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "==================触发器=================="); - // 匹配成功 - String answerId = examQuestionAnswer.getAnswerId(); - List examMysqlKeywordList= examMysqlKeywordMapper.selectListByAnswerId(answerId); - - appendToFile(answerLogPath, "答案语句: " + sql); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "答案语句: "); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, sql); - - - AtomicReference stuAnswer = new AtomicReference<>(); - - // 根据sql 的内容查询结果文件夹语句的文件名,再根据文件名 查找 考生 - try { - String finalSql = sql; - Files.walk(Paths.get(filePath)) - .filter(Files::isRegularFile) - .forEach(filePaths -> { - try { - String fileContent = Files.readString(filePaths, StandardCharsets.UTF_8); - String normalizedFileContent = fileContent.trim().replaceAll("\\s+", "").toLowerCase(); - String normalizedFinalSql = finalSql.trim().replaceAll("\\s+", "").toLowerCase(); - if (normalizedFinalSql.equals(normalizedFileContent)) { - - String stuPath=fileStu+"\\"+filePaths.getFileName(); - stuAnswer.set(readSQLFromFile(stuPath)); - System.out.println("考生语句"+stuAnswer); - } - } catch (Exception e) { - appendToFile(answerLogPath,"读取文件失败:" + filePaths); - e.printStackTrace(); - } - } - - - ); - } catch (IOException e) { - appendToFile(answerLogPath,"遍历目录出错!"); - e.printStackTrace(); - } - - - String regex = "(?i)(?<=CREATE\\s+TRIGGER\\s)([`\\w_]+)"; - String cleanSql = removeComments(sql); - String triggerName = extractViewName(cleanSql, regex); - String stuSQL =null; - String answerSQL =null; - boolean hasError = false; // 添加标志变量 - if (triggerName != null && !triggerName.isEmpty()) { - // 去除反引号 - triggerName = triggerName.replace("`", ""); - String showCreateTriggerSql = "SHOW CREATE TRIGGER " + triggerName + ";"; - - - try (ResultSet rs = stmt.executeQuery(showCreateTriggerSql)) { - if (rs.next()) { - String createTriggerSqlExport = rs.getString("SQL Original Statement"); - answerSQL = createTriggerSqlExport; - } - } catch (SQLException e) { - appendToFile(answerLogPath, "执行答案语句" + showCreateTriggerSql + "时发生错误: " + e.getMessage()); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "执行答案语句" + showCreateTriggerSql + "时发生错误: " + e.getMessage()); - } - - - - try (Connection connstu = DriverManager.getConnection(stuDbUrl, user, password); - Statement stmtstu = connstu.createStatement()) { - if (StringUtils.isBlank(stuAnswer.get())) { - SourceAndText sourceAndTextError = new SourceAndText(); - appendToFile(answerLogPath, "❌考生SQL文件丢失或未作答,无法评分,得分:0.0"); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "❌考生SQL文件丢失或未作答,无法评分,得分:0.0"); - sourceAndTextError.setText(judgementStr); - sourceAndTextError.setScore(0.0); - continue; - } - try (ResultSet rs = stmtstu.executeQuery(showCreateTriggerSql)) { - if (rs.next()) { - String createTriggerSqlExport = rs.getString("SQL Original Statement"); - stuSQL = createTriggerSqlExport; - } - } catch (SQLException e) { - appendToFile(answerLogPath, "执行学生库语句" + showCreateTriggerSql + "时发生错误: " + e.getMessage()); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "执行学生库语句" + showCreateTriggerSql + "时发生错误: " + e.getMessage()); - hasError = true; // 发生异常,设为 true - } - } - - - } else { - appendToFile(answerLogPath, "⚠ 无法提取触发器名"); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "⚠ 无法提取触发器名"); - } - - - - - if (!hasError){ - - // 清洗触发器语句(去除注释等) - String triggerStatementCleanSql1 = cleanProcedureSQL(answerSQL); - - // 标准化触发器内容(去空格、换行、小写) - String normalizedTriggerSql1 = triggerStatementCleanSql1.trim().replaceAll("\\s+", "").toLowerCase(); - - - // 清洗触发器语句(去除注释等) - String triggerStatementCleanSql2 = cleanProcedureSQL(stuSQL); - - // 标准化触发器内容(去空格、换行、小写) - String normalizedTriggerSql2 = triggerStatementCleanSql2.trim().replaceAll("\\s+", "").toLowerCase(); - - boolean equals = normalizedTriggerSql1.equals(normalizedTriggerSql2); - if (equals) { - //todo 得分 - SourceAndText studentScorePojo = accumulateScoreAndLog(examMysqlKeywordList, total, answerLogPath, stuAnswer.get(), totalKeyScore, score, answerId, scoreTotal,judgementStr); - scoreTotal += studentScorePojo.getScore(); - judgementStr = studentScorePojo.getText(); - - } - else { - SourceAndText studentScorePojo = calculateTotalScoreRate(stuAnswer.get(), examMysqlKeywordList, totalKeyScore, score, answerId, scoreTotal,judgementStr); - scoreTotal += studentScorePojo.getScore(); - judgementStr = studentScorePojo.getText(); - } - } - - else { - SourceAndText studentScorePojo = calculateTotalScoreRate(stuAnswer.get(), examMysqlKeywordList, totalKeyScore, score, answerId, scoreTotal,judgementStr); - scoreTotal += studentScorePojo.getScore(); - judgementStr = studentScorePojo.getText(); - } - } - } - - //删除临时创建的数据库databaseName - String dropDbSql = "DROP DATABASE " + databaseName; - stmt.executeUpdate(dropDbSql); - - //todo 删除学生答题的数据库 单独写一个接口 -// String dropDbSql2 = "DROP DATABASE " + stuDataName; -// stmt.executeUpdate(dropDbSql2); - - - } - } - appendToFile(answerLogPath, "共得分:" + String.format("%.2f", scoreTotal)); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "共得分:" + String.format("%.2f", scoreTotal)); - folderzip.delete(); - deleteFolder(folder); - //todo 删除学生答题的数据库连接 单独写一个接口 -// deleteRegistryKey(); - sourceAndText.setScore(scoreTotal); - sourceAndText.setText(judgementStr); - return sourceAndText; - } - - @Override - public void delMysqlConnect(String tName) { - String stuDbUrl = "jdbc:mysql://localhost:6033/" + tName + "?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=UTF-8"; - String user = "root"; - String password = ""; - try (Connection connstu = DriverManager.getConnection(stuDbUrl, user, password); - Statement stmtstu = connstu.createStatement()) { - String dropDbSql2 = "DROP DATABASE " + tName; - stmtstu.executeUpdate(dropDbSql2); - deleteRegistryKey(); - } catch (SQLException e) { - throw new RuntimeException(e); - } - - } - - private static String compareTables(Set> standardSet, Set> studentSet, String dbTable, String tableName,String tableNameStu,String judgementStr) { - int index = 1; - // 判断表名是否一致 - String tableNameCheck = tableName.equalsIgnoreCase(tableNameStu) ? "✔" : "x"; - // 输出 - System.out.printf("%02d.【数据表】【%s】【名称】【%s】【%s】\n", index, dbTable, tableName, tableNameCheck); - appendToFile(answerLogPath, "%02d.【数据表】【%s】【名称】【%s】【%s】\n", index, dbTable, tableName, tableNameCheck); - judgementStr = HtmlAppender.appendHtmlLineMysql(judgementStr, "%02d.【数据表】【%s】【名称】【%s】【%s】\n", index, dbTable, tableName, tableNameCheck); - // 把Set转成Map,方便通过字段名快速取值 - Map> standardMap = convertSetToMap(standardSet); - Map> studentMap = convertSetToMap(studentSet); - - for (String columnName : standardMap.keySet()) { - Map stdCol = standardMap.get(columnName); - Map stuCol = studentMap.get(columnName); - - String fullName = dbTable + "." + columnName; - - String nameCheck = stuCol != null ? "✔" : "x"; - System.out.printf("%02d.【字段】【%s】【名称】【%s】【%s】\n", ++index, fullName, columnName, nameCheck); - judgementStr = HtmlAppender.appendHtmlLineMysql(judgementStr, "%02d.【字段】【%s】【名称】【%s】【%s】\n", index, fullName, columnName, nameCheck); - appendToFile(answerLogPath, "%02d.【字段】【%s】【名称】【%s】【%s】\n", index, fullName, columnName, nameCheck); - - if (stuCol != null) { - MysqlVo mysqlVo1 = compareField(index, fullName, "类型", stdCol.get("COLUMN_TYPE"), stuCol.get("COLUMN_TYPE"),judgementStr); - index=mysqlVo1.getIndex(); - judgementStr=mysqlVo1.getText(); - MysqlVo mysqlVo2 = compareField(index, fullName, "允许为空", stdCol.get("IS_NULLABLE"), stuCol.get("IS_NULLABLE"),judgementStr); - index=mysqlVo2.getIndex(); - judgementStr=mysqlVo2.getText(); - MysqlVo mysqlVo3 = compareField(index, fullName, "扩展", stdCol.get("EXTRA"), stuCol.get("EXTRA"),judgementStr); - index=mysqlVo3.getIndex(); - judgementStr=mysqlVo3.getText(); - MysqlVo mysqlVo4 = compareField(index, fullName, "键类型", stdCol.get("COLUMN_KEY"), stuCol.get("COLUMN_KEY"),judgementStr); - index=mysqlVo4.getIndex(); - judgementStr=mysqlVo4.getText(); - } else { - // 缺失字段,直接输出所有属性错误 - MysqlVo mysqlVo1 = printMissing(index, fullName, "类型", stdCol.get("COLUMN_TYPE"),judgementStr); - index=mysqlVo1.getIndex(); - judgementStr=mysqlVo1.getText(); - MysqlVo mysqlVo2 = printMissing(index, fullName, "允许为空", stdCol.get("IS_NULLABLE"),judgementStr); - index=mysqlVo2.getIndex(); - judgementStr=mysqlVo2.getText(); - MysqlVo mysqlVo3 = printMissing(index, fullName, "扩展", stdCol.get("EXTRA"),judgementStr); - index=mysqlVo3.getIndex(); - judgementStr=mysqlVo3.getText(); - MysqlVo mysqlVo4 = printMissing(index, fullName, "键类型", stdCol.get("COLUMN_KEY"),judgementStr); - index=mysqlVo4.getIndex(); - judgementStr=mysqlVo4.getText(); - } - } - return judgementStr; - } - - private static MysqlVo compareField(int index, String fullName, String property, String stdValue, String stuValue, String judgementStr) { - MysqlVo mysqlVo=new MysqlVo(); - String mark = stdValue.equalsIgnoreCase(stuValue) ? "✔" : "x"; - System.out.printf("%02d.【字段】【%s】【%s】【%s】【%s】\n", index + 1, fullName, property, stuValue, mark); - appendToFile(answerLogPath, "%02d.【字段】【%s】【%s】【%s】【%s】\n", index + 1, fullName, property, stuValue, mark); - judgementStr = HtmlAppender.appendHtmlLineMysql(judgementStr, "%02d.【字段】【%s】【%s】【%s】【%s】\n", index + 1, fullName, property, stuValue, mark); - mysqlVo.setText(judgementStr); - mysqlVo.setIndex(index + 1); - return mysqlVo; - } - - private static MysqlVo printMissing(int index, String fullName, String property, String stdValue,String judgementStr) { - MysqlVo mysqlVo=new MysqlVo(); - System.out.printf("%02d.【字段】【%s】【%s】【%s】【x】\n", index + 1, fullName, property, stdValue); - appendToFile(answerLogPath, "%02d.【字段】【%s】【%s】【%s】【x】\n", index + 1, fullName, property, stdValue); - judgementStr = HtmlAppender.appendHtmlLineMysql(judgementStr, "%02d.【字段】【%s】【%s】【%s】【x】\n", index + 1, fullName, property, stdValue); - mysqlVo.setText(judgementStr); - mysqlVo.setIndex(index + 1); - return mysqlVo; - } - - private static Map> convertSetToMap(Set> set) { - Map> map = new LinkedHashMap<>(); - for (Map column : set) { - map.put(column.get("COLUMN_NAME"), column); - } - return map; - } - public static void deleteFolder(File folder) { - if (folder.isDirectory()) { - File[] files = folder.listFiles(); - if (files != null) { - for (File file : files) { - deleteFolder(file); // 递归删除所有子文件/文件夹 - } - } - } - folder.delete(); // 删除空文件夹或文件 - } - //如果这个小题对了,直接累加对应的权值分 - private SourceAndText accumulateScoreAndLog(List examMysqlKeywordList, AtomicInteger total, String answerLogPath, String sql2, String totalKeyScore, double score,String answerId,double scoreTotal,String judgementStr) { - SourceAndText sourceAndText = new SourceAndText(); - if(StringUtils.isBlank(answerId)){ - appendToFile(answerLogPath, "❌该语句找不到试题id,请检查出题内容!" ); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "❌该语句找不到试题id,请检查出题内容!"); - sourceAndText.setText(judgementStr); - sourceAndText.setScore(0.0); - //返回累加的总分 - return sourceAndText; - } - //用answerid查对应答案的权值 。除以总权值 - String scoreRateStr= examQuestionAnswerMapper.selectExamQuestionAnswerScoreByAnswerId(answerId); - - // 解析权值 - double scoreRate = 0.0; - double totalKey = 0.0; - double singleScore = 0.0; - try { - scoreRate = Double.parseDouble(scoreRateStr); - totalKey = Double.parseDouble(totalKeyScore); - // 计算该答案对应的得分 - - if (totalKey > 0) { - singleScore = (scoreRate / totalKey) * score; - singleScore = Math.round(singleScore * 100.0) / 100.0; - } - - String[] lines = sql2.split("\\r?\\n"); - - // 开头:✅学生语句: - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "✅学生语句:"); - // 第一行直接加在后面 - if (lines.length > 0) { - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, StringEscapeUtils.escapeHtml4(lines[0])); - } - - // 后续行添加换行和缩进 - for (int i = 1; i < lines.length; i++) { - judgementStr = HtmlAppender.appendHtmlLine(judgementStr," "+StringEscapeUtils.escapeHtml4(lines[i].trim())); - } - // 最终加入 judgementStr - judgementStr = HtmlAppender.appendHtmlLine(judgementStr,",正确,语句得分权值:"+scoreRateStr + ",得分" + singleScore); -// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "✅学生语句" + sql2 + "正确,语句得分权值:" + scoreRateStr + ",得分" + singleScore); - appendToFile(answerLogPath, "✅学生语句" + sql2 + "正确,语句得分权值:" + scoreRateStr + ",得分" + singleScore); - } catch (NumberFormatException e) { - System.err.println("无效的totalKeyScore值:" + totalKeyScore); - } - sourceAndText.setText(judgementStr); - sourceAndText.setScore(singleScore); - //返回累加的总分 - return sourceAndText; - - } - - - - - public static String convertUpdateToSelectWhere(String updateSQL) { - // 清理语句 - updateSQL = updateSQL.trim().replaceAll(";\\s*$", ""); - - // 正则提取表名和 WHERE 条件 - Pattern pattern = Pattern.compile( - "UPDATE\\s+(\\w+)\\s+SET\\s+.+?\\s+WHERE\\s+(.+)", - Pattern.CASE_INSENSITIVE | Pattern.DOTALL - ); - Matcher matcher = pattern.matcher(updateSQL); - if (matcher.find()) { - String tableName = matcher.group(1).trim(); - String whereClause = matcher.group(2).trim(); - return "SELECT * FROM " + tableName + " WHERE " + whereClause + ";"; - } else { - return "-- 无法识别的 UPDATE 语句"; - } - } - - public static String extractTableNameFromInsert(String sql) { - Pattern pattern = Pattern.compile("INSERT\\s+INTO\\s+(\\w+)\\s*\\(", Pattern.CASE_INSENSITIVE); - Matcher matcher = pattern.matcher(sql); - if (matcher.find()) { - return matcher.group(1); - } else { - return "unknown_table"; - } - } - - - private List getColumnNames(ResultSet rs) throws SQLException { - List columnNames = new ArrayList<>(); - ResultSetMetaData metaData = rs.getMetaData(); - int columnCount = metaData.getColumnCount(); - for (int i = 1; i <= columnCount; i++) { - columnNames.add(metaData.getColumnName(i)); - } - return columnNames; - } - - public static String generateInsertSQL(String tableName, List columns, List> rows) { - StringBuilder sb = new StringBuilder(); - sb.append("INSERT INTO ").append(tableName).append(" ("); - sb.append(String.join(", ", columns)); - sb.append(") VALUES\n"); - - List valueLines = new ArrayList<>(); - for (List row : rows) { - List formattedValues = new ArrayList<>(); - for (String value : row) { - if (value == null) { - formattedValues.add("NULL"); - } else if (value.matches("-?\\d+(\\.\\d+)?")) { - formattedValues.add(value); // 数字不加引号 - } else { - formattedValues.add("'" + value.replace("'", "''") + "'"); // 字符串加引号并转义 - } - } - valueLines.add("(" + String.join(", ", formattedValues) + ")"); - } - - sb.append(String.join(",\n", valueLines)).append(";"); - return sb.toString(); - } - - public SourceAndText calculateTotalScoreRate(String sql, List examQuestionKeywords, String totalKeyScore, double score,String answerId,double scoreTotal,String judgementStr) { - SourceAndText sourceAndText = new SourceAndText(); - if(StringUtils.isBlank(answerId)){ - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "❌该语句找不到试题id,请检查出题内容!"); - appendToFile(answerLogPath, "❌该语句找不到试题id,请检查出题内容!" ); - sourceAndText.setText(judgementStr); - sourceAndText.setScore(0.0); - //返回累加的总分 - return sourceAndText; - } - //用answerid查对应答案的权值 。除以总权值 - String scoreRateStr= examQuestionAnswerMapper.selectExamQuestionAnswerScoreByAnswerId(answerId); - - - - // 解析权值 - double scoreRate = 0.0; - double totalKey = 0.0; - // 计算该答案对应的得分 - double singleScore = 0.0; - try { - scoreRate = Double.parseDouble(scoreRateStr); - totalKey = Double.parseDouble(totalKeyScore); - - if (totalKey > 0) { - singleScore = (scoreRate / totalKey) * score; - singleScore = Math.round(singleScore * 100.0) / 100.0; - } - - - - } catch (NumberFormatException e) { - System.err.println("无效的totalKeyScore值:" + totalKeyScore); - } - - - int totalScoreRate = 0; - Set matchedKeywords = new HashSet<>(); - for (ExamMysqlKeyword keyword : examQuestionKeywords) { - String keywordValue = keyword.getKeyword(); - if (keywordValue != null && !keywordValue.isEmpty() && !matchedKeywords.contains(keywordValue)) { - // 使用正则,确保是完整单词(字段)匹配 - String regex = keywordValue; - if (sql.contains(regex)) { - try { - totalScoreRate += Integer.parseInt(keyword.getScoreRate()); - - matchedKeywords.add(keywordValue); - } catch (NumberFormatException e) { - System.err.println("Invalid scoreRate format for keyword: " + keywordValue); - } - } - } - } - //累加答案关键字的所有权值 - int totalKeyScoreInt = examQuestionKeywords.stream() - .map(ExamMysqlKeyword::getScoreRate) - .filter(s -> s != null && !s.isEmpty()) - .mapToInt(Integer::parseInt) - .sum(); - - //乘以 对了多少个 关键字 权值 - double finalRoundedScore; - if (totalKeyScoreInt == 0) { - // 如果总键值为0,可以设置为0或其他默认值 - finalRoundedScore = 0.0; - } else { - finalRoundedScore = new BigDecimal( - ((double) totalScoreRate / totalKeyScoreInt) * singleScore - ).setScale(2, RoundingMode.HALF_UP).doubleValue(); - } - - String[] lines = sql.split("\\r?\\n"); - - // 开头:✅学生语句: - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "❌学生语句:"); - // 第一行直接加在后面 - if (lines.length > 0) { - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, StringEscapeUtils.escapeHtml4(lines[0])); - } - - // 后续行添加换行和缩进 - for (int i = 1; i < lines.length; i++) { - judgementStr = HtmlAppender.appendHtmlLine(judgementStr," "+StringEscapeUtils.escapeHtml4(lines[i].trim())); - } - // 最终加入 judgementStr - judgementStr = HtmlAppender.appendHtmlLine(judgementStr,",不正确,语句权值:"+scoreRateStr+",关键权值:"+totalKeyScoreInt+",答对得分点为:"+matchedKeywords+",答对关键得分权值"+ totalScoreRate+ ",得分" + finalRoundedScore); -// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "❌语句"+sql+"不正确,语句权值:"+scoreRateStr+",关键权值:"+totalKeyScoreInt+",答对得分点为:"+matchedKeywords+",答对关键得分权值"+ totalScoreRate+ ",得分" + finalRoundedScore); - - appendToFile(answerLogPath,"❌语句"+sql+"不正确,语句权值:"+scoreRateStr+",关键权值:"+totalKeyScoreInt+",答对得分点为:"+matchedKeywords+",答对关键得分权值"+ totalScoreRate+ ",得分" + finalRoundedScore); - sourceAndText.setText(judgementStr); - sourceAndText.setScore(finalRoundedScore); - //返回累加的总分 - return sourceAndText; - } - - // 预处理函数:去除空格和换行并转为大写 - private static String normalize(String str) { - return str.replaceAll("\\s+", "").toUpperCase(); - } - - // 删除 数据库连接 - public static void deleteRegistryKey() { - try { - // 1. 通过命令获取当前用户 SID - Process sidProcess = Runtime.getRuntime().exec(new String[]{"whoami", "/user"}); - BufferedReader reader = new BufferedReader(new InputStreamReader(sidProcess.getInputStream())); - - String sid = null; - String line; - while ((line = reader.readLine()) != null) { - if (line.contains("\\")) continue; // 跳过表头行 - String[] parts = line.trim().split("\\s+"); - if (parts.length >= 2) { - sid = parts[1]; // 第二列是 SID - break; - } - } - reader.close(); - - int sidExitCode = sidProcess.waitFor(); - if (sid == null || sidExitCode != 0) { - System.out.println("❌ 无法获取当前用户 SID"); - return; - } - - // 2. 构造完整注册表路径 - String regKey = "HKEY_USERS\\" + sid + "\\Software\\PremiumSoft\\Navicat\\Servers\\答题专用"; - - // 3. 执行删除命令 - String[] cmd = {"reg", "delete", regKey, "/f"}; - Process process = Runtime.getRuntime().exec(cmd); - int exitCode = process.waitFor(); - - if (exitCode == 0) { - System.out.println("✅ 注册表项删除成功"); - } else { - System.out.println("❌ 注册表项删除失败,退出码:" + exitCode); - } - - } catch (Exception e) { - e.printStackTrace(); - } - } - - - - - public static String cleanProcedureSQL(String sql) { - // 删除 DELIMITER 和 $$ 标记 - sql = sql.replaceAll("(?i)DELIMITER\\s+\\$\\$", ""); // 删除 DELIMITER $$ - sql = sql.replaceAll("(?i)DELIMITER\\s+;", ""); // 删除 DELIMITER ; - sql = sql.replaceAll("\\$\\$", ""); // 删除结尾 $$ - - // 删除 CALL 语句(例如 CALL pro_xxx(...);) - sql = sql.replaceAll("(?i)CALL\\s+[^;]+;", ""); // 删除 CALL 语句(不区分大小写) - - - // 删除 -- 行内注释(从 -- 到行尾) - sql = sql.replaceAll("(?m)--.*?$", ""); // (?m) 多行模式,$ 表示行尾 - - // 删除 /**/ 多行注释 - sql = sql.replaceAll("(?s)/\\*.*?\\*/", ""); // (?s) 单行模式,.*? 非贪婪匹配 - - // 去掉多余空白字符 - return sql.trim(); - } - public static class DeleteInfo { - public String tableName; - public String whereClause; - - public DeleteInfo(String tableName, String whereClause) { - this.tableName = tableName; - this.whereClause = whereClause; - } - } - // 标准化 SQL 字符串 - public static String convertInsertToSelect(String sql) { - sql = sql.trim().replaceAll(";+\\s*$", ""); // 去掉末尾分号 - - // 匹配字段名和 VALUES 部分 - Pattern pattern = Pattern.compile( - "INSERT INTO\\s+\\w+\\s*\\(([^)]+)\\)\\s*VALUES\\s*(.+)", - Pattern.CASE_INSENSITIVE | Pattern.DOTALL - ); - Matcher matcher = pattern.matcher(sql); - if (!matcher.find()) { - return "不合法的 INSERT 语句"; - } - - String fieldPart = matcher.group(1).trim(); - String valuesPart = matcher.group(2).trim(); - - String[] fields = fieldPart.split("\\s*,\\s*"); - - // 提取所有 () 中的值 - List valueGroups = new ArrayList<>(); - Matcher valueMatcher = Pattern.compile("\\(([^()]*)\\)").matcher(valuesPart); - while (valueMatcher.find()) { - valueGroups.add(valueMatcher.group(1)); - } - - // 构造 SELECT ... UNION ALL - List selects = new ArrayList<>(); - for (int i = 0; i < valueGroups.size(); i++) { - String[] values = valueGroups.get(i).split("\\s*,\\s*", -1); - if (values.length != fields.length) { - return "字段数与值数不匹配,请检查第 " + (i + 1) + " 行"; - } - - StringBuilder sb = new StringBuilder("SELECT "); - for (int j = 0; j < fields.length; j++) { - if (i == 0) { - sb.append(values[j]).append(" AS ").append(fields[j]); - } else { - sb.append(values[j]); - } - if (j < fields.length - 1) sb.append(", "); - } - selects.add(sb.toString()); - } - - return String.join("\nUNION ALL\n", selects) + ";"; - } - - - - // 比较两个结果集 - private static MysqlBooleanVo compareExtractResults(List> newResults, List> oldResults, String judgementStr) { - MysqlBooleanVo mysqlBooleanVo=new MysqlBooleanVo(); - appendToFile(answerLogPath,"==== 标准答案 ===="); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "==== 标准答案 ===="); - for (Map row : newResults) { - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, row.toString()); - appendToFile(answerLogPath,row.toString()); - } - appendToFile(answerLogPath,"==== 考生答案 ===="); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "==== 考生答案 ===="); - for (Map row : oldResults) { - appendToFile(answerLogPath,row.toString()); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, row.toString()); - } - - if (newResults.size() != oldResults.size()) { - appendToFile(answerLogPath,"❌考生答案与标准答案个数不对"); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "❌考生答案与标准答案个数不对"); - mysqlBooleanVo.setText(judgementStr); - mysqlBooleanVo.setFlag(false); - return mysqlBooleanVo; - } - - // 不比较顺序,直接判断两个列表内容是否一样(将其转换为 Set) - Set> newSet = new HashSet<>(newResults); - Set> oldSet = new HashSet<>(oldResults); - - if (!newSet.equals(oldSet)) { - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "❌ 内容相同但顺序不同,或存在差异:"); - appendToFile(answerLogPath,"❌ 内容相同但顺序不同,或存在差异:"); - Set> onlyInNew = new HashSet<>(newSet); - onlyInNew.removeAll(oldSet); - - Set> onlyInOld = new HashSet<>(oldSet); - onlyInOld.removeAll(newSet); - - for (Map row : onlyInNew) { - appendToFile(answerLogPath,"⚠️ 标准答案中有但考生答案中没有: " + row); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "⚠️ 标准答案中有但考生答案中没有: " + row); - } - - for (Map row : onlyInOld) { - appendToFile(answerLogPath,"⚠️ 考生答案中有但标准答案中没有: " + row); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "⚠️ 考生答案中有但标准答案中没有: " + row); - } - mysqlBooleanVo.setText(judgementStr); - mysqlBooleanVo.setFlag(false); - return mysqlBooleanVo; - } - appendToFile(answerLogPath,"两个结果集内容一致(不考虑顺序)!"); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "两个结果集内容一致(不考虑顺序)!"); - mysqlBooleanVo.setText(judgementStr); - mysqlBooleanVo.setFlag(true); - return mysqlBooleanVo; - } - - - // 提取ResultSet中的结果到一个列表中 - private static List> extractResults(ResultSet resultSet) throws SQLException { - List> results = new ArrayList<>(); - - // 获取列数 - ResultSetMetaData metaData = resultSet.getMetaData(); - int columnCount = metaData.getColumnCount(); - - while (resultSet.next()) { - Map row = new HashMap<>(); - for (int i = 1; i <= columnCount; i++) { - String columnName = metaData.getColumnLabel(i); - Object value = resultSet.getObject(i); - row.put(columnName, value); - } - results.add(row); - } - - return results; - } - - - public static String restoreUpdateFromResult( - String originalUpdateSql, - List columns, - List> answerListStu - ) { - - System.out.println("========================================================= " ); - System.out.println("originalUpdateSql = " + originalUpdateSql); - System.out.println("columns = " + columns); - System.out.println("answerListStu = " + answerListStu); - System.out.println("========================================================= " ); - - - Pattern p = Pattern.compile("UPDATE\\s+(\\w+)\\s+SET\\s+(.+?)\\s+WHERE\\s+(.+);?", Pattern.CASE_INSENSITIVE | Pattern.DOTALL); - Matcher m = p.matcher(originalUpdateSql); - if (!m.find()) { - throw new IllegalArgumentException("无法解析原始 UPDATE 语句"); - } - String tableName = m.group(1); - String wherePart = m.group(3); - - if (answerListStu.isEmpty()) { - throw new IllegalArgumentException("查询结果为空,无法还原"); - } - - List firstRow = answerListStu.get(0); - List answerRow = answerListStu.get(1); - List setClauses = new ArrayList<>(); - - for (int i = 0; i < columns.size(); i++) { - String col = columns.get(i); - String val = answerRow.get(i); - - String valStr; - if (val == null || val.equalsIgnoreCase("null")) { - valStr = "NULL"; - } else if (val.matches("-?\\d+(\\.\\d+)?")) { - valStr = val; - } else { - valStr = "'" + val.replace("'", "''") + "'"; - } - setClauses.add(col + " = " + valStr); - } - - String setPart = String.join(", ", setClauses); - return "UPDATE " + tableName + " SET " + setPart + " WHERE " + wherePart ; - } - - public static List extractCallStatements(String sql) { - List callStatements = new ArrayList<>(); - Pattern callPattern = Pattern.compile("CALL\\s+\\w+\\s*\\([^;]*?\\);", Pattern.CASE_INSENSITIVE); - Matcher matcher = callPattern.matcher(sql); - - while (matcher.find()) { - callStatements.add(matcher.group()); - } - - return callStatements; - } - - - /** - * 比较两个查询的结果 - */ - private static boolean compareResults(List> result1, List> result2) { - // 获取列名并比较(顺序无关) - List columnNames1 = result1.get(0); - List columnNames2 = result2.get(0); - - // 检查列名是否一致(顺序无关) - Set columnSet1 = new HashSet<>(columnNames1); - Set columnSet2 = new HashSet<>(columnNames2); - if (!columnSet1.equals(columnSet2)) { - return false; - } - - // 获取数据行(去除列名) - List> rows1 = result1.subList(1, result1.size()); - List> rows2 = result2.subList(1, result2.size()); - - // 使用 Set 存储每行数据并比较 - Set> rowSet1 = new HashSet<>(); - for (List row : rows1) { - rowSet1.add(new HashSet<>(row)); - } - - Set> rowSet2 = new HashSet<>(); - for (List row : rows2) { - rowSet2.add(new HashSet<>(row)); - } - - // 比较行数据(无顺序) - return rowSet1.equals(rowSet2); - } - /** - * 执行 SQL 查询并返回结果 - */ - private static List> executeQuery(Statement stmt, String sql) throws SQLException { - List> result = new ArrayList<>(); - - - try { - - ResultSet rs = stmt.executeQuery(sql); - // 获取列数和列名 - ResultSetMetaData metaData = rs.getMetaData(); - int columnCount = metaData.getColumnCount(); - - // 获取列名 - List columnNames = new ArrayList<>(); - for (int i = 1; i <= columnCount; i++) { - columnNames.add(metaData.getColumnLabel(i)); - } - result.add(columnNames); // 将列名添加为结果的第一行 - - // 遍历结果集 - while (rs.next()) { - List row = new ArrayList<>(); - for (int i = 1; i <= columnCount; i++) { - row.add(rs.getString(i)); - } - result.add(row); - } - } catch (SQLException e) { - appendToFile(answerLogPath, "执行学生库 SQL CALL 语句时发生错误: " + e.getMessage()); - } - - - return result; - } - /** - * 从文件读取 SQL 语句 - */ - private static String readSQLFromFile(String filePath) throws IOException { - File file = new File(filePath); - if (!file.exists()) { - throw new FileNotFoundException("❌ 找不到SQL文件:" + filePath); - } - - StringBuilder sql = new StringBuilder(); - try (BufferedReader reader = new BufferedReader(new FileReader(file))) { - String line; - while ((line = reader.readLine()) != null) { - sql.append(line).append(" "); - } - } - return sql.toString().trim(); - } - - // 去除 SQL 中的注释部分 - private static String removeComments(String sql) { - // 正则表达式匹配 SQL 中以 -- 开头的注释 - return sql.replaceAll("(?m)^[\\s]*--.*$", ""); - } - /** - * 比较两个查询的结果 - */ - private static boolean compareResultsSelect(List> result1, List> result2) { - // 获取列名并比较(顺序无关) - List columnNames1 = result1.get(0); - List columnNames2 = result2.get(0); - - // 检查列名是否一致(顺序无关) - Set columnSet1 = new HashSet<>(columnNames1); - Set columnSet2 = new HashSet<>(columnNames2); - if (!columnSet1.equals(columnSet2)) { - return false; - } - - // 获取数据行(去除列名) - List> rows1 = result1.subList(1, result1.size()); - List> rows2 = result2.subList(1, result2.size()); - - // 使用 Set 存储每行数据并比较 - Set> rowSet1 = new HashSet<>(); - for (List row : rows1) { - rowSet1.add(new HashSet<>(row)); - } - - Set> rowSet2 = new HashSet<>(); - for (List row : rows2) { - rowSet2.add(new HashSet<>(row)); - } - - // 比较行数据(无顺序) - return rowSet1.equals(rowSet2); - } - /** - * 打印查询结果 - */ - private static String printResult(List> result,String judgementStr) { - if (result.isEmpty()) { - appendToFile(answerLogPath, "查询结果为空"); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "查询结果为空"); - return judgementStr; - } else { - for (int i = 0; i < result.size(); i++) { - List row = result.get(i); - StringBuilder sb = new StringBuilder(); - for (String value : row) { - sb.append(value).append("\t"); - } - - // 输出整行 - appendToFile(answerLogPath, sb.toString()); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, sb.toString()); - } - } - return judgementStr; - } - - /** - * 使用提供的正则表达式模式从给定的 SQL 语句中提取视图名称。 - */ - private static String extractViewName(String sql, String regex) { - Pattern pattern = Pattern.compile(regex); - Matcher matcher = pattern.matcher(sql); - - // 如果找到匹配项,返回匹配到的视图名称 - if (matcher.find()) { - return matcher.group(1).replace("`", ""); // 如果有反引号(`),则移除 - } else { - return "未找到视图名称"; - } - } - - private static List> getAnswerList(ResultSet answer) throws SQLException { - List> result = new ArrayList<>(); - // 获取列数和列名 - ResultSetMetaData metaData = answer.getMetaData(); - int columnCount = metaData.getColumnCount(); - - // 获取列名 - List columnNames = new ArrayList<>(); - for (int i = 1; i <= columnCount; i++) { - columnNames.add(metaData.getColumnLabel(i)); - } - result.add(columnNames); // 将列名添加为结果的第一行 - - // 遍历结果集 - while (answer.next()) { - List row = new ArrayList<>(); - for (int i = 1; i <= columnCount; i++) { - row.add(answer.getString(i)); - } - result.add(row); - } - - return result; - - } - - - - public static void generateInsertStatements(String tableName, Map.Entry entry, String newDbUrl, String user, String password) { - // 确保 entry 里包含的是 INSERT 语句 - if (entry.getValue().trim().toUpperCase().startsWith("INSERT")) { - System.out.println("==================插入语句=================="); - // 创建一个列表来存储所有的 INSERT INTO 语句 - List insertQueries = new ArrayList<>(); - try (Connection conn = DriverManager.getConnection(newDbUrl, user, password); - Statement stmt = conn.createStatement()) { - - // 查询表的所有列 - String columnsQuery = "DESCRIBE " + tableName; - - try (ResultSet columnsRs = stmt.executeQuery(columnsQuery)) { - List columnNames = new ArrayList<>(); - while (columnsRs.next()) { - String columnName = columnsRs.getString("Field"); - columnNames.add(columnName); - } - - // 获取表的数据并生成 INSERT INTO 语句 - String selectQuery = "SELECT * FROM " + tableName; - try (ResultSet dataRs = stmt.executeQuery(selectQuery)) { - - while (dataRs.next()) { - StringBuilder insertQuery = new StringBuilder("INSERT INTO `" + tableName + "` ("); - - // 构建列名部分 - for (int i = 0; i < columnNames.size(); i++) { - insertQuery.append("`").append(columnNames.get(i)).append("`"); - if (i < columnNames.size() - 1) { - insertQuery.append(", "); - } - } - insertQuery.append(") VALUES ("); - - // 构建值部分 - for (int i = 0; i < columnNames.size(); i++) { - Object value = dataRs.getObject(columnNames.get(i)); - if (value == null) { - insertQuery.append("NULL"); - } else if (value instanceof String) { - insertQuery.append("'").append(value.toString().replace("'", "''")).append("'"); - } else { - insertQuery.append(value); - } - - if (i < columnNames.size() - 1) { - insertQuery.append(", "); - } - } - insertQuery.append(");"); - // 将生成的 INSERT INTO 语句添加到列表中 - insertQueries.add(insertQuery.toString()); - // 输出生成的 INSERT INTO 语句 - System.out.println(insertQuery.toString()); - } - - } - catch (SQLException e) { - System.err.println("生成插入语句失败,表名:" + tableName); - e.printStackTrace(); - } - } - } catch (SQLException e) { - System.err.println("生成插入语句失败,表名:" + tableName); - e.printStackTrace(); - } - // 将列表赋值给 entry 的值 - entry.setValue(insertQueries.toString()); - System.out.println(entry.getValue()); - } - } - - /** - * 读取指定目录下所有文件,返回一个文件名到文件内容的键值对Map - * @param directoryPath 文件夹路径 - * @return Map<文件名, 文件内容> - * @throws IOException 读取文件异常 - */ - public static Map readFilesAsMap(String directoryPath) throws IOException { - Map fileContentMap = new HashMap<>(); - - Path dirPath = Paths.get(directoryPath); - if (!Files.isDirectory(dirPath)) { - throw new IllegalArgumentException("路径不是一个有效的目录: " + directoryPath); - } - - try (DirectoryStream stream = Files.newDirectoryStream(dirPath)) { - for (Path path : stream) { - if (Files.isRegularFile(path)) { - String fileName = path.getFileName().toString(); - String content = new String(Files.readAllBytes(path)); - fileContentMap.put(fileName, content); - } - } - } - - return fileContentMap; - } - - - /** - * 通过命令行执行 SQL 文件 - */ - public static boolean executeSqlFileUsingCommandLine(String sqlFilePath, String dbName, String user, String password) { - try { - // 拼接命令 - String[] command = { - "mysql", - "-u" + user, - "-P", "6033", - dbName, - "-e", "source " + sqlFilePath - }; - - // 启动进程 - Process process = Runtime.getRuntime().exec(command); - int exitCode = process.waitFor(); - - return exitCode == 0; - } catch (Exception e) { - e.printStackTrace(); - return false; - } - } -// private static boolean executeSqlFileUsingCommandLine(String filePath, String databaseName, String user, String password) throws IOException { -// // 构建 MySQL 命令 -// String command = String.format("mysql -u %s -p%s %s < %s", user, password, databaseName, filePath); +//package pc.exam.pp.module.judgement.controller.service.mysql; // -// // 使用 ProcessBuilder 执行命令 -// ProcessBuilder processBuilder = new ProcessBuilder("cmd.exe", "/c", command); -// processBuilder.inheritIO(); // 将输入输出重定向到当前控制台 -// Process process = processBuilder.start(); +//import jakarta.annotation.Resource; +//import org.apache.commons.lang3.StringEscapeUtils; +//import org.apache.commons.lang3.StringUtils; +//import org.springframework.stereotype.Service; +//import pc.exam.pp.module.exam.dal.dataobject.ExamMysqlKeyword; +//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.ExamMysqlKeywordMapper; +//import pc.exam.pp.module.exam.dal.mysql.question.ExamQuestionAnswerMapper; +//import pc.exam.pp.module.judgement.controller.service.mysql.vo.MysqlBooleanVo; +//import pc.exam.pp.module.judgement.controller.service.mysql.vo.MysqlVo; +//import pc.exam.pp.module.judgement.controller.utils.zip.ZipUtil; +//import pc.exam.pp.module.judgement.service.auto_tools.vo.SourceAndText; // -// try { -// // 等待命令执行完成 -// int exitCode = process.waitFor(); -// if (exitCode == 0) { -// System.out.println("SQL 文件执行成功:" + filePath); -// return true; // 返回 true 表示执行成功 -// } else { -// System.err.println("SQL 文件执行失败:" + filePath); -// return false; // 返回 false 表示执行失败 +//import java.io.*; +//import java.math.BigDecimal; +//import java.math.RoundingMode; +//import java.nio.charset.StandardCharsets; +//import java.nio.file.DirectoryStream; +//import java.nio.file.Files; +//import java.nio.file.Path; +//import java.nio.file.Paths; +//import java.sql.*; +//import java.time.LocalDateTime; +//import java.time.format.DateTimeFormatter; +//import java.util.*; +//import java.util.List; +//import java.util.concurrent.atomic.AtomicInteger; +//import java.util.concurrent.atomic.AtomicReference; +//import java.util.regex.Matcher; +//import java.util.regex.Pattern; +//@Service +//public class IMysqlLocalServiceImpl implements IMysqlLocalService{ +// +// static String databaseName; +// static String databaseNameStu; +// static String answerLogPath; // 文件路径 +// private static final DateTimeFormatter formatter = +// DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); +// @Resource +// private ExamMysqlKeywordMapper examMysqlKeywordMapper; +// @Resource +// private ExamQuestionAnswerMapper examQuestionAnswerMapper; +// +// @Override +// public SourceAndText Judgement(double score, File filepath, ExamQuestion examQuestion, String judgementStr) throws IOException, SQLException { +// String stuDataName=examQuestion.getTname(); +// SourceAndText sourceAndText = new SourceAndText(); +// double scoreTotal =0.0; +// String fileUrl= examQuestionAnswerMapper.selectAnswerFile(examQuestion.getQuId()); +// String path = ZipUtil.downloadStudentFile(fileUrl, "data"); +// // 4、获取到得是zip文件,需要解压 +// String stuFilePath = ZipUtil.unzipToNamedFolder(path); +// File folderzip = new File(path); +// File folder = new File(stuFilePath); +// // 5、解压之后得文件获取文件夹和文件 +// String stu_files = null; +// +// // 5.2、查询试题ID +// +// List examQuestionAnswers = examQuestionAnswerMapper.selectExamQuestionAnswerByQuId(examQuestion.getQuId()); +// String totalKeyScore ="0"; +// //得出 这个题总共的权值点 +// totalKeyScore=examQuestionAnswerMapper.selectCountPointByQuId(examQuestion.getQuId()); +// +// answerLogPath = filepath.getParent() + File.separator + "log.txt"; +// +// AtomicInteger total = new AtomicInteger(); +// // 文件路径 +// +//// String file = "D:\\Desktop\\202504211120_mysql\\71\\MYS_010_122\\结果素材\\结果素材\\Teacher"; +//// String file = new File(filepath, "结果").getAbsolutePath(); +//// String filePath = "D:\\Desktop\\202504211120_mysql\\71\\MYS_010_122\\结果素材\\结果素材\\Teacher\\answer.txt"; // 答案文件路径 +// String filePath = new File(stuFilePath).getAbsolutePath(); // 结果/answer.txt +// +//// String answerPath = "D:\\Desktop\\202504211120_mysql\\71\\MYS_010_122\\结果素材\\结果素材\\Teacher\\db\\db_escape.myd"; // 原始 SQL 文件路径 +// File dbDir = new File(stuFilePath, "db"); +// String answerPath = null; +// if (dbDir.exists() && dbDir.isDirectory()) { +// File[] mydFiles = dbDir.listFiles((dir, name) -> name.toLowerCase().endsWith(".myd")); +// if (mydFiles != null && mydFiles.length > 0) { +// answerPath = mydFiles[0].getAbsolutePath(); // 默认取第一个 .myd 文件 +// } // } -// } catch (InterruptedException e) { -// e.printStackTrace(); -// return false; +// +// +//// String fileStu = "D:\\Desktop\\202504211120_mysql\\71\\MYS_010_122\\考试素材\\考试素材\\Student"; +// String fileStu = filepath.getAbsolutePath(); +// +//// String stuAnswerPath = "D:\\Desktop\\202504211120_mysql\\71\\MYS_010_122\\考试素材\\考试素材\\Student\\db\\db_escape.myd"; +// File stuDbDir = new File(fileStu, "db"); +// String stuAnswerPath = null; +// if (stuDbDir.exists() && stuDbDir.isDirectory()) { +// File[] stuMydFiles = stuDbDir.listFiles((dir, name) -> name.toLowerCase().endsWith(".myd")); +// if (stuMydFiles != null && stuMydFiles.length > 0) { +// stuAnswerPath = stuMydFiles[0].getAbsolutePath(); // 默认取第一个 .myd 文件 +// } +// } +// +// // 生成随机数据库名,临时使用 +// databaseName = "db_" + UUID.randomUUID().toString().replace("-", "").substring(0, 8); +// +//// databaseName = "db_6f80867f"; +//// databaseNameStu= "db_6f80867e"; +// // 连接到 MySQL 默认数据库 +// String url = "jdbc:mysql://localhost:6033/"+stuDataName+"?useSSL=false&serverTimezone=Asia/Shanghai"; +// String user = "root"; +// String password = ""; +// try { +// // **连接到 MySQL 默认数据库,创建新的数据库** +// try (Connection conn = DriverManager.getConnection(url, user, password); +// Statement stmt = conn.createStatement()) { +// String createDbSql = "CREATE DATABASE IF NOT EXISTS " + databaseName + +// " CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci"; +//// String createDbSql = "CREATE DATABASE " + databaseName; +// stmt.executeUpdate(createDbSql); +// System.out.println("已创建数据库:" + databaseName); +// +// +// +// } +// +// +// } catch (SQLException e) { +// e.printStackTrace(); +// } +// +//// // **建立连接到新创建的数据库** +// String newDbUrl = "jdbc:mysql://localhost:6033/" + databaseName + "?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=UTF-8"; +// String stuDbUrl = "jdbc:mysql://localhost:6033/" + stuDataName + "?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=UTF-8"; +// // **通过命令行执行 SQL 文件** 建立 完整正确数据库 +// boolean sqlFileExecuted = executeSqlFileUsingCommandLine(answerPath, databaseName, user, password); +// //建立考生答题数据库 +//// boolean sqlFileExecutedstu = executeSqlFileUsingCommandLine(stuAnswerPath, databaseNameStu, user, password); +// +// if (sqlFileExecuted ) { +// +// +// Map result = readFilesAsMap(stuFilePath); +// Map resultStu = readFilesAsMap(fileStu); +// +// try (Connection conn = DriverManager.getConnection(newDbUrl, user, password); +// Statement stmt = conn.createStatement()) { +// for (ExamQuestionAnswer examQuestionAnswer : examQuestionAnswers) { +// String sql=examQuestionAnswer.getContent(); +// if(sql.trim().toUpperCase().startsWith("CREATE TABLE")) { +// appendToFile(answerLogPath, "==================建表语句=================="); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "==================建表语句=================="); +// // 匹配成功 +// String answerId = examQuestionAnswer.getAnswerId(); +// List examMysqlKeywordList= examMysqlKeywordMapper.selectListByAnswerId(answerId); +// +// // 正则表达式匹配表名 +// Pattern pattern = Pattern.compile("CREATE TABLE\\s+`?(\\w+)`?\\s*\\("); +// Matcher matcher = pattern.matcher(sql); +// +// if (matcher.find()) { +// String tableName = matcher.group(1).replace("`", ""); // 获取表名 +// +// +// // 查询建表语句 +// String showCreateTableSql = "SHOW CREATE TABLE " + tableName; +// +// String sql1 = "SELECT COLUMN_NAME, COLUMN_TYPE, IS_NULLABLE, COLUMN_KEY, EXTRA " + +// "FROM INFORMATION_SCHEMA.COLUMNS " + +// "WHERE TABLE_NAME = '" + tableName + "' AND TABLE_SCHEMA = '" + databaseName + "'"; +// String sql2 = "SELECT COLUMN_NAME, COLUMN_TYPE, IS_NULLABLE, COLUMN_KEY, EXTRA " + +// "FROM INFORMATION_SCHEMA.COLUMNS " + +// "WHERE TABLE_NAME = '" + tableName + "' AND TABLE_SCHEMA = '" + stuDataName + "'"; +// +// // 获取主库字段信息 +// Set> table1Columns = new HashSet<>(); +// try (ResultSet rs = stmt.executeQuery(sql1)) { +// while (rs.next()) { +// Map column = new HashMap<>(); +// column.put("COLUMN_NAME", rs.getString("COLUMN_NAME")); +// column.put("COLUMN_TYPE", rs.getString("COLUMN_TYPE")); +// column.put("IS_NULLABLE", rs.getString("IS_NULLABLE")); +// column.put("COLUMN_KEY", rs.getString("COLUMN_KEY")); +// column.put("EXTRA", rs.getString("EXTRA")); +// table1Columns.add(column); +// +// } +//// appendToFile(answerLogPath, "标准答案建表键值对:"+table1Columns); +//// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "标准答案建表键值对:"+table1Columns); +// +// +// } +// // 获取学生库字段信息 +// Set> table2Columns = new HashSet<>(); +// boolean tableExists = false; +// //学生语句 +// String stuSQL=null; +// try (Connection connstu = DriverManager.getConnection(stuDbUrl, user, password); +// Statement stmtstu = connstu.createStatement()) { +// try (ResultSet rsstu = stmtstu.executeQuery(sql2)) { +// // 检查是否有数据返回 +// tableExists = rsstu.next(); // 第一次调用next()判断是否有数据 +// if (tableExists) { +// try (ResultSet rs = stmt.executeQuery(showCreateTableSql)) { +// if (rs.next()) { +// String createTableSqlExport = rs.getString("Create Table"); +// // 替换 result 中的值 +// stuSQL=createTableSqlExport; +// } +// } +// +// // 如果有数据,处理第一行(因为上面已经调用了next()) +// do { +// Map column = new HashMap<>(); +// column.put("COLUMN_NAME", rsstu.getString("COLUMN_NAME")); +// column.put("COLUMN_TYPE", rsstu.getString("COLUMN_TYPE")); +// column.put("IS_NULLABLE", rsstu.getString("IS_NULLABLE")); +// column.put("COLUMN_KEY", rsstu.getString("COLUMN_KEY")); +// column.put("EXTRA", rsstu.getString("EXTRA")); +// table2Columns.add(column); +// } while (rsstu.next()); +// +// } else { +// // 表不存在时的处理逻辑 +// System.out.println("表 " + tableName + " 在学生数据库中不存在"); +// // 或者 throw new RuntimeException("表不存在"); +// String yuju= compareTables(table1Columns, table2Columns, stuDataName,tableName, "",judgementStr); +// judgementStr=yuju; +// +// +// } +// +// +// } +// } +// +// String yuju= compareTables(table1Columns, table2Columns, stuDataName,tableName, tableName,judgementStr); +// judgementStr=yuju; +// +// +// +// if (table1Columns.equals(table2Columns)) { +// // +// SourceAndText studentScorePojo = accumulateScoreAndLog(examMysqlKeywordList,total,answerLogPath,stuSQL,totalKeyScore,score,answerId,scoreTotal,judgementStr); +// scoreTotal += studentScorePojo.getScore(); +// judgementStr = studentScorePojo.getText(); +// } else { +// SourceAndText studentScorePojo= calculateTotalScoreRate(stuSQL, examMysqlKeywordList,totalKeyScore,score,answerId,scoreTotal,judgementStr); +// scoreTotal += studentScorePojo.getScore(); +// judgementStr = studentScorePojo.getText(); +// } +// } +// +// } +// +// if (sql.trim().toUpperCase().startsWith("INSERT")) { +// appendToFile(answerLogPath, "==================插入语句=================="); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "==================插入语句=================="); +// // 正则表达式匹配表名 +// Pattern pattern = Pattern.compile("INSERT INTO\\s+`?(\\w+)`?\\s*\\("); +// Matcher matcher = pattern.matcher(sql); +// appendToFile(answerLogPath, "答案语句: " + sql); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "答案语句: "); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, sql); +// if (matcher.find()) { +// String tableName = matcher.group(1).replace("`", ""); // 获取表名 +// // 匹配成功 +// String answerId= examQuestionAnswer.getAnswerId(); +// List examMysqlKeywordList = examMysqlKeywordMapper.selectListByAnswerId(answerId); +// +// +// //把select语句 转化成验证语句sql +// String yanzheng = convertInsertToSelect(sql); +// String stuSql=null; +// List> answerList= new ArrayList<>(); +// List> answerListStu = new ArrayList<>(); +// try (Connection connanswer = DriverManager.getConnection(newDbUrl, user, password); +// Statement stmtan = connanswer.createStatement()) { +// try (ResultSet answer = stmtan.executeQuery(yanzheng)) { +// answerList = getAnswerList(answer); +//// appendToFile(answerLogPath, "查找语句标准答案"); +//// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "查找语句标准答案"); +//// printResult(answerList,judgementStr); +// }catch (SQLException e) { +// appendToFile(answerLogPath, "答案表执行验证语句"+yanzheng+"时发生错误: " + e.getMessage()); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "答案表执行验证语句"+yanzheng+"时发生错误: " + e.getMessage()); +// e.printStackTrace(); +// } +// } +// try (Connection connstu = DriverManager.getConnection(stuDbUrl, user, password); +// Statement stmtstu = connstu.createStatement()) { +// try (ResultSet answer = stmtstu.executeQuery(yanzheng)) { +// answerListStu = getAnswerList(answer); +// //这里根据answerListStu ,还原学生的sql语句 +// List columnNames = getColumnNames(answer); // ← 获取字段名 +// +// String tName = extractTableNameFromInsert(sql); +// +// //构建还原 SQL(你可以自定义表名,比如传 "student_table") +// stuSql = generateInsertSQL(tName, columnNames, answerListStu); +//// appendToFile(answerLogPath, "学生对"+tName+"插入的SQL:\n" + stuSql); +//// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "学生对"+tName+"+插入的SQL:" ); +//// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, stuSql); +//// appendToFile(answerLogPath, "学生语句答案"); +//// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "学生语句答案"); +//// printResult(answerListStu,judgementStr); +// } catch (SQLException e) { +// appendToFile(answerLogPath, "学生表执行验证语句"+yanzheng+"时发生错误: " + e.getMessage()); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "学生表执行验证语句"+yanzheng+"时发生错误: " + e.getMessage()); +// } +// } +// boolean isEquivalent =false; +// +// if (answerListStu!=null&&answerListStu.size()>0){ +// isEquivalent = compareResultsSelect(answerList, answerListStu); +// } +// +// if (isEquivalent) { +// SourceAndText studentScorePojo = accumulateScoreAndLog(examMysqlKeywordList,total,answerLogPath,stuSql,totalKeyScore,score,answerId,scoreTotal,judgementStr); +// scoreTotal += studentScorePojo.getScore(); +// judgementStr = studentScorePojo.getText(); +// } else { +// SourceAndText studentScorePojo= calculateTotalScoreRate(stuSql, examMysqlKeywordList,totalKeyScore,score,answerId,scoreTotal,judgementStr); +// scoreTotal += studentScorePojo.getScore(); +// judgementStr = studentScorePojo.getText(); +// } +// } +// +// } +// if (sql.trim().toUpperCase().startsWith("DELETE")) { +// appendToFile(answerLogPath, "==================删除语句=================="); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "==================删除语句=================="); +// +// appendToFile(answerLogPath, "答案语句: " + sql); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "答案语句: "); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, sql); +// sql = sql.trim().replaceAll(";+\\s*$", ""); +// // 正则提取表名和 WHERE 条件 +// Pattern pattern = Pattern.compile("DELETE\\s+FROM\\s+(\\w+)\\s+WHERE\\s+(.+)", Pattern.CASE_INSENSITIVE); +// Matcher matcher = pattern.matcher(sql); +// // 匹配成功 +// String answerId = examQuestionAnswer.getAnswerId(); +// List examMysqlKeywordList = examMysqlKeywordMapper.selectListByAnswerId(answerId); +// +// if (matcher.find()) { +// String tableName = matcher.group(1).trim(); +// String whereClause = matcher.group(2).trim(); +// pc.exam.pp.module.judgement.controller.service.mysql.MysqlServericeImpl.DeleteInfo deleteInfo = new pc.exam.pp.module.judgement.controller.service.mysql.MysqlServericeImpl.DeleteInfo(tableName, whereClause); +//// appendToFile(answerLogPath, "提取出的表名: " + deleteInfo.tableName); +//// appendToFile(answerLogPath, "提取出的条件: " + deleteInfo.whereClause); +// // 构造验证 SQL +// String verifySql = "SELECT COUNT(*) FROM " + deleteInfo.tableName + " WHERE " + deleteInfo.whereClause; +//// appendToFile(answerLogPath, "验证 SQL: " + verifySql); +// //查找正确答案的 +//// try (Connection conn = DriverManager.getConnection(newDbUrl, user, password); +//// Statement stmt = conn.createStatement()) { +// try (ResultSet rs = stmt.executeQuery(verifySql)) { +// if (rs.next()) { +// int count = rs.getInt(1); +// if (count == 0) { +// try (Connection connstu = DriverManager.getConnection(stuDbUrl, user, password); +// Statement stmtstu = connstu.createStatement()) { +// try (ResultSet rsstu = stmtstu.executeQuery(verifySql)) { +// if (rsstu.next()) { +// int countstu = rsstu.getInt(1); +// if (countstu == 0) { +// //累加删除语句的所有权值 examQuestionKeywords累加scorerate +// appendToFile(answerLogPath, "验证通过:符合 DELETE 条件的记录已删除。"); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "验证通过:符合 DELETE 条件的记录已删除。"); +// SourceAndText studentScorePojo = accumulateScoreAndLog(examMysqlKeywordList,total,answerLogPath,sql,totalKeyScore,score,answerId,scoreTotal,judgementStr); +// scoreTotal += studentScorePojo.getScore(); +// judgementStr = studentScorePojo.getText(); +// +// } else { +// SourceAndText studentScorePojo= calculateTotalScoreRate(null, examMysqlKeywordList,totalKeyScore,score,answerId,scoreTotal,judgementStr); +// scoreTotal += studentScorePojo.getScore(); +// judgementStr = studentScorePojo.getText(); +// } +// } +// }catch (SQLException e) { +// appendToFile(answerLogPath, "验证学生库失败,"+"得分:0 ❌"); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "验证学生库失败,"+"得分:0 ❌"); +// } +// +// } +// +// +// } 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(); +// } +// +// } +// +// } +// +// if (sql.trim().toUpperCase().startsWith("UPDATE")) { +// appendToFile(answerLogPath, "==================更新语句=================="); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "==================更新语句=================="); +// appendToFile(answerLogPath, "答案语句: " + sql); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "答案语句: "); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, sql); +// // 匹配成功 +// String answerId = examQuestionAnswer.getAnswerId(); +// List examMysqlKeywordList= examMysqlKeywordMapper.selectListByAnswerId(answerId); +// //转换成select语句 +// String selectSql = convertUpdateToSelectWhere(sql); +// +// List> answerList= new ArrayList<>(); +// List> answerListStu = new ArrayList<>(); +// try (Connection connanswer = DriverManager.getConnection(newDbUrl, user, password); +// Statement stmtan = connanswer.createStatement()) { +// try (ResultSet answer = stmtan.executeQuery(selectSql)) { +// answerList = getAnswerList(answer); +//// appendToFile(answerLogPath, "查找语句标准答案"); +//// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "查找语句标准答案"); +//// printResult(answerList,judgementStr); +// }catch (SQLException e) { +// appendToFile(answerLogPath, "答案表执行验证语句"+selectSql+"时发生错误: " + e.getMessage()); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "答案表执行验证语句"+selectSql+"时发生错误: " + e.getMessage()); +// e.printStackTrace(); +// } +// } +// String stuSql =null; +// try (Connection connstu = DriverManager.getConnection(stuDbUrl, user, password); +// Statement stmtstu = connstu.createStatement()) { +// try (ResultSet answer = stmtstu.executeQuery(selectSql)) { +// answerListStu = getAnswerList(answer); +// //还原 sql +// ResultSetMetaData meta = answer.getMetaData(); +// List columns = new ArrayList<>(); +// for (int i = 1; i <= meta.getColumnCount(); i++) { +// columns.add(meta.getColumnLabel(i)); +// } +// +// stuSql = restoreUpdateFromResult(sql, columns, answerListStu); +//// appendToFile(answerLogPath, "还原学生 UPDATE 语句:" + stuSql); +//// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "还原学生 UPDATE 语句:" + stuSql); +//// appendToFile(answerLogPath, "学生语句答案:"); +//// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "学生语句答案:"); +//// printResult(answerListStu,judgementStr); +// } catch (SQLException e) { +// appendToFile(answerLogPath, "学生表执行验证语句"+selectSql+"时发生错误:" + e.getMessage()); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "学生表执行验证语句"+selectSql+"时发生错误: " + e.getMessage()); +// } +// +// +// } +// boolean isEquivalent =false; +// +// if (answerListStu!=null&&answerListStu.size()>0){ +// isEquivalent = compareResultsSelect(answerList, answerListStu); +// } +// // +// if (isEquivalent) { +// SourceAndText studentScorePojo = accumulateScoreAndLog(examMysqlKeywordList,total,answerLogPath,stuSql,totalKeyScore,score,answerId,scoreTotal,judgementStr); +// scoreTotal += studentScorePojo.getScore(); +// judgementStr = studentScorePojo.getText(); +// +// } else { +// SourceAndText studentScorePojo= calculateTotalScoreRate(stuSql, examMysqlKeywordList,totalKeyScore,score,answerId,scoreTotal,judgementStr); +// scoreTotal += studentScorePojo.getScore(); +// judgementStr = studentScorePojo.getText(); +// +// } +// +// } +// if (sql.trim().toUpperCase().startsWith("SELECT")) { +// appendToFile(answerLogPath, "==================查找语句=================="); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "==================查找语句=================="); +// // 匹配成功 +// String answerId = examQuestionAnswer.getAnswerId(); +// List examMysqlKeywordList= examMysqlKeywordMapper.selectListByAnswerId(answerId); +// +// appendToFile(answerLogPath, "答案语句: " + sql); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "答案语句: "); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, sql); +// +// AtomicReference stuAnswer = new AtomicReference<>(); +// +// // 根据sql 的内容查询结果文件夹语句的文件名,再根据文件名 查找 考生 +// try { +// String finalSql = sql; +// Files.walk(Paths.get(filePath)) +// .filter(Files::isRegularFile) +// .forEach(filePaths -> { +// try { +// String fileContent = Files.readString(filePaths, StandardCharsets.UTF_8); +// String normalizedFileContent = fileContent.trim().replaceAll("\\s+", "").toLowerCase(); +// String normalizedFinalSql = finalSql.trim().replaceAll("\\s+", "").toLowerCase(); +// if (normalizedFinalSql.equals(normalizedFileContent)) { +// +// String stuPath=fileStu+"\\"+filePaths.getFileName(); +// stuAnswer.set(readSQLFromFile(stuPath)); +// System.out.println("考生语句"+stuAnswer); +// } +// } catch (Exception e) { +// appendToFile(answerLogPath,"读取文件失败:" + filePaths); +// e.printStackTrace(); +// } +// } +// ); +// } catch (IOException e) { +// appendToFile(answerLogPath,"遍历目录出错!"); +// e.printStackTrace(); +// } +// +// List> answerList= new ArrayList<>(); +// List> answerListStu = new ArrayList<>(); +// try (Connection connanswer = DriverManager.getConnection(newDbUrl, user, password); +// Statement stmtan = connanswer.createStatement()) { +// try (ResultSet answer = stmtan.executeQuery(sql)) { +// answerList = getAnswerList(answer); +// appendToFile(answerLogPath, "运行标准答案语句的查询结果:"); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "运行标准答案语句的查询结果:"); +// judgementStr = printResult(answerList,judgementStr); +// }catch (SQLException e) { +// appendToFile(answerLogPath, "执行验证语句"+sql+"时发生错误: " + e.getMessage()); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "执行验证语句"+sql+"时发生错误: " + e.getMessage()); +// e.printStackTrace(); +// } +// } +// try (Connection connstu = DriverManager.getConnection(stuDbUrl, user, password); +// Statement stmtstu = connstu.createStatement()) { +// if (StringUtils.isBlank(stuAnswer.get())) { +// SourceAndText sourceAndTextError = new SourceAndText(); +// appendToFile(answerLogPath, "❌考生SQL文件丢失或未作答,无法评分,得分:0.0"); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "❌考生SQL文件丢失或未作答,无法评分,得分:0.0"); +// sourceAndTextError.setText(judgementStr); +// sourceAndTextError.setScore(0.0); +// continue; +// } +// try (ResultSet answer = stmtstu.executeQuery(String.valueOf(stuAnswer))) { +// answerListStu = getAnswerList(answer); +// appendToFile(answerLogPath, "运行学生语句的查询结果:"); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "运行学生语句的查询结果:"); +// judgementStr= printResult(answerListStu,judgementStr); +// } catch (SQLException e) { +// appendToFile(answerLogPath, "执行学生库语句"+String.valueOf(stuAnswer)+"时发生错误: " + e.getMessage()); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "执行学生库语句"+String.valueOf(stuAnswer)+"时发生错误: " + e.getMessage()); +// } +// +// } +// boolean isEquivalent =false; +// +// if (answerListStu!=null&&answerListStu.size()>0){ +// isEquivalent = compareResultsSelect(answerList, answerListStu); +// } +// +// if (isEquivalent) { +// //todo 得分 +// SourceAndText studentScorePojo = accumulateScoreAndLog(examMysqlKeywordList,total,answerLogPath,String.valueOf(stuAnswer),totalKeyScore,score,answerId,scoreTotal,judgementStr); +// scoreTotal += studentScorePojo.getScore(); +// judgementStr = studentScorePojo.getText(); +// +// } else { +// SourceAndText studentScorePojo= calculateTotalScoreRate(String.valueOf(stuAnswer), examMysqlKeywordList,totalKeyScore,score,answerId,scoreTotal,judgementStr); +// scoreTotal += studentScorePojo.getScore(); +// judgementStr = studentScorePojo.getText(); +// +// } +// +// } +// +// +// if (sql.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, "==================视图语句=================="); +// // 匹配成功 +// String answerId = examQuestionAnswer.getAnswerId(); +// List examMysqlKeywordList= examMysqlKeywordMapper.selectListByAnswerId(answerId); +// appendToFile(answerLogPath, "答案语句: " + sql); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "答案语句: "); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, sql); +// +// // 正则表达式,用于匹配 "VIEW" 后面的视图名称 +// String regex = "(?<=VIEW\\s)([\\w`_]+)"; +// String sqlviewAnswer = removeComments(sql); +// String viewNam1 = extractViewName(sqlviewAnswer, regex); +// +// String showCreateViewSql = "SHOW CREATE VIEW " + viewNam1; +// +// // 执行查询,获取答案 视图的结果 +// appendToFile(answerLogPath, "执行正确答案视图语句的查询结果:"); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "执行正确答案视图语句的查询结果:"); +// String sql3 = "SELECT * FROM " + viewNam1; +// List> result1 = executeQuery(stmt, sql3); +// judgementStr= printResult(result1,judgementStr); +// +// List> result2 =new ArrayList<>(); +// String stuSQL =null; +// boolean hasError = false; // 添加标志变量 +// try (Connection connstu = DriverManager.getConnection(stuDbUrl, user, password); +// Statement stmtstu = connstu.createStatement()) { +// +// try (ResultSet rs = stmtstu.executeQuery(showCreateViewSql)) { +// if (rs.next()) { +// String createViewSqlExport = rs.getString("Create View"); +// // 替换 result 中的值 +// stuSQL=createViewSqlExport; +// } +// }catch (SQLException e) { +// appendToFile(answerLogPath, "执行学生库语句"+showCreateViewSql+"时发生错误: " + e.getMessage()); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "执行学生库语句"+showCreateViewSql+"时发生错误: " + e.getMessage()); +// hasError = true; // 发生异常,设为 true +// } +// +// // 执行查询,获取考生 视图的结果 +// appendToFile(answerLogPath, "执行考生视图语句的查询结果:"); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "执行考生视图语句的查询结果:"); +// +// try { +// result2 = executeQuery(stmtstu, sql3); +// +// } catch (SQLException e) { +// appendToFile(answerLogPath, "执行学生库语句"+sql3+"时发生错误: " + e.getMessage()); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "执行学生库语句"+sql3+"时发生错误: " + e.getMessage()); +// hasError = true; // 发生异常,设为 true +// } +// +// +// judgementStr= printResult(result2,judgementStr); +// } +// +// // 比较两个视图的结果 +// boolean isEquivalent =!hasError &&compareResults(result1, result2); +// appendToFile(answerLogPath, "\n是否结果等价: " + isEquivalent); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "\n是否结果等价: " + isEquivalent); +// +// +// if (isEquivalent) { +// SourceAndText studentScorePojo = accumulateScoreAndLog(examMysqlKeywordList,total,answerLogPath,stuSQL,totalKeyScore,score,answerId,scoreTotal,judgementStr); +// scoreTotal += studentScorePojo.getScore(); +// judgementStr = studentScorePojo.getText(); +// +// } else { +// SourceAndText studentScorePojo= calculateTotalScoreRate(stuSQL, examMysqlKeywordList,totalKeyScore,score,answerId,scoreTotal,judgementStr); +// scoreTotal += studentScorePojo.getScore(); +// judgementStr = studentScorePojo.getText(); +// } +//// } +// +// } +// +// //存储过程 +// if (sql.trim().toUpperCase().toUpperCase().contains("PROCEDURE")) { +// // 匹配成功 +// String answerId = examQuestionAnswer.getAnswerId(); +// List examMysqlKeywordList= examMysqlKeywordMapper.selectListByAnswerId(answerId); +// +// appendToFile(answerLogPath, "==================储存过程=================="); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "==================储存过程=================="); +// appendToFile(answerLogPath, "答案语句: " + sql); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "答案语句: "); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, sql); +// +// +// AtomicReference stuAnswer = new AtomicReference<>(); +// +// // 根据sql 的内容查询结果文件夹语句的文件名,再根据文件名 查找 考生 +// try { +// String finalSql = sql; +// Files.walk(Paths.get(filePath)) +// .filter(Files::isRegularFile) +// .forEach(filePaths -> { +// try { +// String fileContent = Files.readString(filePaths, StandardCharsets.UTF_8); +// String normalizedFileContent = fileContent.trim().replaceAll("\\s+", "").toLowerCase(); +// String normalizedFinalSql = finalSql.trim().replaceAll("\\s+", "").toLowerCase(); +// if (normalizedFinalSql.equals(normalizedFileContent)) { +// +// String stuPath=fileStu+"\\"+filePaths.getFileName(); +// stuAnswer.set(readSQLFromFile(stuPath)); +// System.out.println("考生语句"+stuAnswer); +// } +// } catch (Exception e) { +// appendToFile(answerLogPath,"读取文件失败:" + filePaths); +// e.printStackTrace(); +// } +// } +// +// +// ); +// } catch (IOException e) { +// appendToFile(answerLogPath,"遍历目录出错!"); +// e.printStackTrace(); +// } +// +// //提取call语句 +// List extractCallStatements = extractCallStatements(sql); +// //标准答案 集合 +// List> anwerResults = new ArrayList<>(); +// //考生答案 集合 +// List> stuResults = new ArrayList<>(); +// if (extractCallStatements != null && extractCallStatements.size() > 0) { +// boolean hasError = false; // 添加标志变量 +// for (String extractCallStatement : extractCallStatements) { +// appendToFile(answerLogPath, "测试 call 语句:" + extractCallStatement); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "测试 call 语句:" + extractCallStatement); +// +// try { +// +// ResultSet newResult = stmt.executeQuery(extractCallStatement); +// anwerResults.addAll(extractResults(newResult)); +// } catch (SQLException e) { +// appendToFile(answerLogPath, "执行标准库 SQL CALL 语句时发生错误: " + e.getMessage()); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "执行标准库 SQL CALL 语句时发生错误: " + e.getMessage()); +// } +// try (Connection connstu = DriverManager.getConnection(stuDbUrl, user, password); +// Statement stmtstu = connstu.createStatement()) { +// if (StringUtils.isBlank(stuAnswer.get())) { +// SourceAndText sourceAndTextError = new SourceAndText(); +// appendToFile(answerLogPath, "❌考生SQL文件丢失或未作答,无法评分,得分:0.0"); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "❌考生SQL文件丢失或未作答,无法评分,得分:0.0"); +// sourceAndTextError.setText(judgementStr); +// sourceAndTextError.setScore(0.0); +// continue; +// } +// +// +// try { +// ResultSet oldResult = stmtstu.executeQuery(extractCallStatement); +// stuResults.addAll(extractResults(oldResult)); +// } catch (SQLException e) { +// appendToFile(answerLogPath, "执行学生库 SQL CALL 语句时发生错误: " + e.getMessage()); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "执行学生库 SQL CALL 语句时发生错误: " + e.getMessage()); +// hasError = true; // 发生异常,设为 true +// } +// } +// +// } +// // 比较结果(如果发生异常,可以认为比较失败) +// MysqlBooleanVo mysqlBooleanVo = compareExtractResults(anwerResults, stuResults,judgementStr); +// judgementStr=mysqlBooleanVo.getText(); +// boolean flag= !hasError &&mysqlBooleanVo.isFlag(); +// +// if (flag) { +// //todo 得分 +// SourceAndText studentScorePojo = accumulateScoreAndLog(examMysqlKeywordList,total,answerLogPath,stuAnswer.get(),totalKeyScore,score,answerId,scoreTotal,judgementStr); +// scoreTotal += studentScorePojo.getScore(); +// judgementStr = studentScorePojo.getText(); +// +// } else { +// //得分 +// SourceAndText studentScorePojo = calculateTotalScoreRate(stuAnswer.get(), examMysqlKeywordList, totalKeyScore, score, answerId, scoreTotal,judgementStr); +// scoreTotal += studentScorePojo.getScore(); +// judgementStr = studentScorePojo.getText(); +// +// } +// } else { +// appendToFile(answerLogPath, "此存储过程无 CALL 语句"); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "此存储过程无 CALL 语句"); +// } +// } +// if (sql.trim().toUpperCase().toUpperCase().contains("TRIGGER")) { +// appendToFile(answerLogPath, "==================触发器=================="); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "==================触发器=================="); +// // 匹配成功 +// String answerId = examQuestionAnswer.getAnswerId(); +// List examMysqlKeywordList= examMysqlKeywordMapper.selectListByAnswerId(answerId); +// +// appendToFile(answerLogPath, "答案语句: " + sql); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "答案语句: "); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, sql); +// +// +// AtomicReference stuAnswer = new AtomicReference<>(); +// +// // 根据sql 的内容查询结果文件夹语句的文件名,再根据文件名 查找 考生 +// try { +// String finalSql = sql; +// Files.walk(Paths.get(filePath)) +// .filter(Files::isRegularFile) +// .forEach(filePaths -> { +// try { +// String fileContent = Files.readString(filePaths, StandardCharsets.UTF_8); +// String normalizedFileContent = fileContent.trim().replaceAll("\\s+", "").toLowerCase(); +// String normalizedFinalSql = finalSql.trim().replaceAll("\\s+", "").toLowerCase(); +// if (normalizedFinalSql.equals(normalizedFileContent)) { +// +// String stuPath=fileStu+"\\"+filePaths.getFileName(); +// stuAnswer.set(readSQLFromFile(stuPath)); +// System.out.println("考生语句"+stuAnswer); +// } +// } catch (Exception e) { +// appendToFile(answerLogPath,"读取文件失败:" + filePaths); +// e.printStackTrace(); +// } +// } +// +// +// ); +// } catch (IOException e) { +// appendToFile(answerLogPath,"遍历目录出错!"); +// e.printStackTrace(); +// } +// +// +// String regex = "(?i)(?<=CREATE\\s+TRIGGER\\s)([`\\w_]+)"; +// String cleanSql = removeComments(sql); +// String triggerName = extractViewName(cleanSql, regex); +// String stuSQL =null; +// String answerSQL =null; +// boolean hasError = false; // 添加标志变量 +// if (triggerName != null && !triggerName.isEmpty()) { +// // 去除反引号 +// triggerName = triggerName.replace("`", ""); +// String showCreateTriggerSql = "SHOW CREATE TRIGGER " + triggerName + ";"; +// +// +// try (ResultSet rs = stmt.executeQuery(showCreateTriggerSql)) { +// if (rs.next()) { +// String createTriggerSqlExport = rs.getString("SQL Original Statement"); +// answerSQL = createTriggerSqlExport; +// } +// } catch (SQLException e) { +// appendToFile(answerLogPath, "执行答案语句" + showCreateTriggerSql + "时发生错误: " + e.getMessage()); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "执行答案语句" + showCreateTriggerSql + "时发生错误: " + e.getMessage()); +// } +// +// +// +// try (Connection connstu = DriverManager.getConnection(stuDbUrl, user, password); +// Statement stmtstu = connstu.createStatement()) { +// if (StringUtils.isBlank(stuAnswer.get())) { +// SourceAndText sourceAndTextError = new SourceAndText(); +// appendToFile(answerLogPath, "❌考生SQL文件丢失或未作答,无法评分,得分:0.0"); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "❌考生SQL文件丢失或未作答,无法评分,得分:0.0"); +// sourceAndTextError.setText(judgementStr); +// sourceAndTextError.setScore(0.0); +// continue; +// } +// try (ResultSet rs = stmtstu.executeQuery(showCreateTriggerSql)) { +// if (rs.next()) { +// String createTriggerSqlExport = rs.getString("SQL Original Statement"); +// stuSQL = createTriggerSqlExport; +// } +// } catch (SQLException e) { +// appendToFile(answerLogPath, "执行学生库语句" + showCreateTriggerSql + "时发生错误: " + e.getMessage()); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "执行学生库语句" + showCreateTriggerSql + "时发生错误: " + e.getMessage()); +// hasError = true; // 发生异常,设为 true +// } +// } +// +// +// } else { +// appendToFile(answerLogPath, "⚠ 无法提取触发器名"); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "⚠ 无法提取触发器名"); +// } +// +// +// +// +// if (!hasError){ +// +// // 清洗触发器语句(去除注释等) +// String triggerStatementCleanSql1 = cleanProcedureSQL(answerSQL); +// +// // 标准化触发器内容(去空格、换行、小写) +// String normalizedTriggerSql1 = triggerStatementCleanSql1.trim().replaceAll("\\s+", "").toLowerCase(); +// +// +// // 清洗触发器语句(去除注释等) +// String triggerStatementCleanSql2 = cleanProcedureSQL(stuSQL); +// +// // 标准化触发器内容(去空格、换行、小写) +// String normalizedTriggerSql2 = triggerStatementCleanSql2.trim().replaceAll("\\s+", "").toLowerCase(); +// +// boolean equals = normalizedTriggerSql1.equals(normalizedTriggerSql2); +// if (equals) { +// //todo 得分 +// SourceAndText studentScorePojo = accumulateScoreAndLog(examMysqlKeywordList, total, answerLogPath, stuAnswer.get(), totalKeyScore, score, answerId, scoreTotal,judgementStr); +// scoreTotal += studentScorePojo.getScore(); +// judgementStr = studentScorePojo.getText(); +// +// } +// else { +// SourceAndText studentScorePojo = calculateTotalScoreRate(stuAnswer.get(), examMysqlKeywordList, totalKeyScore, score, answerId, scoreTotal,judgementStr); +// scoreTotal += studentScorePojo.getScore(); +// judgementStr = studentScorePojo.getText(); +// } +// } +// +// else { +// SourceAndText studentScorePojo = calculateTotalScoreRate(stuAnswer.get(), examMysqlKeywordList, totalKeyScore, score, answerId, scoreTotal,judgementStr); +// scoreTotal += studentScorePojo.getScore(); +// judgementStr = studentScorePojo.getText(); +// } +// } +// } +// +// //删除临时创建的数据库databaseName +// String dropDbSql = "DROP DATABASE " + databaseName; +// stmt.executeUpdate(dropDbSql); +// +// //todo 删除学生答题的数据库 单独写一个接口 +//// String dropDbSql2 = "DROP DATABASE " + stuDataName; +//// stmt.executeUpdate(dropDbSql2); +// +// +// } +// } +// appendToFile(answerLogPath, "共得分:" + String.format("%.2f", scoreTotal)); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "共得分:" + String.format("%.2f", scoreTotal)); +// folderzip.delete(); +// deleteFolder(folder); +// //todo 删除学生答题的数据库连接 单独写一个接口 +//// deleteRegistryKey(); +// sourceAndText.setScore(scoreTotal); +// sourceAndText.setText(judgementStr); +// return sourceAndText; +// } +// +// @Override +// public void delMysqlConnect(String tName) { +// String stuDbUrl = "jdbc:mysql://localhost:6033/" + tName + "?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=UTF-8"; +// String user = "root"; +// String password = ""; +// try (Connection connstu = DriverManager.getConnection(stuDbUrl, user, password); +// Statement stmtstu = connstu.createStatement()) { +// String dropDbSql2 = "DROP DATABASE " + tName; +// stmtstu.executeUpdate(dropDbSql2); +// deleteRegistryKey(); +// } catch (SQLException e) { +// throw new RuntimeException(e); +// } +// +// } +// +// private static String compareTables(Set> standardSet, Set> studentSet, String dbTable, String tableName,String tableNameStu,String judgementStr) { +// int index = 1; +// // 判断表名是否一致 +// String tableNameCheck = tableName.equalsIgnoreCase(tableNameStu) ? "✔" : "x"; +// // 输出 +// System.out.printf("%02d.【数据表】【%s】【名称】【%s】【%s】\n", index, dbTable, tableName, tableNameCheck); +// appendToFile(answerLogPath, "%02d.【数据表】【%s】【名称】【%s】【%s】\n", index, dbTable, tableName, tableNameCheck); +// judgementStr = HtmlAppender.appendHtmlLineMysql(judgementStr, "%02d.【数据表】【%s】【名称】【%s】【%s】\n", index, dbTable, tableName, tableNameCheck); +// // 把Set转成Map,方便通过字段名快速取值 +// Map> standardMap = convertSetToMap(standardSet); +// Map> studentMap = convertSetToMap(studentSet); +// +// for (String columnName : standardMap.keySet()) { +// Map stdCol = standardMap.get(columnName); +// Map stuCol = studentMap.get(columnName); +// +// String fullName = dbTable + "." + columnName; +// +// String nameCheck = stuCol != null ? "✔" : "x"; +// System.out.printf("%02d.【字段】【%s】【名称】【%s】【%s】\n", ++index, fullName, columnName, nameCheck); +// judgementStr = HtmlAppender.appendHtmlLineMysql(judgementStr, "%02d.【字段】【%s】【名称】【%s】【%s】\n", index, fullName, columnName, nameCheck); +// appendToFile(answerLogPath, "%02d.【字段】【%s】【名称】【%s】【%s】\n", index, fullName, columnName, nameCheck); +// +// if (stuCol != null) { +// MysqlVo mysqlVo1 = compareField(index, fullName, "类型", stdCol.get("COLUMN_TYPE"), stuCol.get("COLUMN_TYPE"),judgementStr); +// index=mysqlVo1.getIndex(); +// judgementStr=mysqlVo1.getText(); +// MysqlVo mysqlVo2 = compareField(index, fullName, "允许为空", stdCol.get("IS_NULLABLE"), stuCol.get("IS_NULLABLE"),judgementStr); +// index=mysqlVo2.getIndex(); +// judgementStr=mysqlVo2.getText(); +// MysqlVo mysqlVo3 = compareField(index, fullName, "扩展", stdCol.get("EXTRA"), stuCol.get("EXTRA"),judgementStr); +// index=mysqlVo3.getIndex(); +// judgementStr=mysqlVo3.getText(); +// MysqlVo mysqlVo4 = compareField(index, fullName, "键类型", stdCol.get("COLUMN_KEY"), stuCol.get("COLUMN_KEY"),judgementStr); +// index=mysqlVo4.getIndex(); +// judgementStr=mysqlVo4.getText(); +// } else { +// // 缺失字段,直接输出所有属性错误 +// MysqlVo mysqlVo1 = printMissing(index, fullName, "类型", stdCol.get("COLUMN_TYPE"),judgementStr); +// index=mysqlVo1.getIndex(); +// judgementStr=mysqlVo1.getText(); +// MysqlVo mysqlVo2 = printMissing(index, fullName, "允许为空", stdCol.get("IS_NULLABLE"),judgementStr); +// index=mysqlVo2.getIndex(); +// judgementStr=mysqlVo2.getText(); +// MysqlVo mysqlVo3 = printMissing(index, fullName, "扩展", stdCol.get("EXTRA"),judgementStr); +// index=mysqlVo3.getIndex(); +// judgementStr=mysqlVo3.getText(); +// MysqlVo mysqlVo4 = printMissing(index, fullName, "键类型", stdCol.get("COLUMN_KEY"),judgementStr); +// index=mysqlVo4.getIndex(); +// judgementStr=mysqlVo4.getText(); +// } +// } +// return judgementStr; +// } +// +// private static MysqlVo compareField(int index, String fullName, String property, String stdValue, String stuValue, String judgementStr) { +// MysqlVo mysqlVo=new MysqlVo(); +// String mark = stdValue.equalsIgnoreCase(stuValue) ? "✔" : "x"; +// System.out.printf("%02d.【字段】【%s】【%s】【%s】【%s】\n", index + 1, fullName, property, stuValue, mark); +// appendToFile(answerLogPath, "%02d.【字段】【%s】【%s】【%s】【%s】\n", index + 1, fullName, property, stuValue, mark); +// judgementStr = HtmlAppender.appendHtmlLineMysql(judgementStr, "%02d.【字段】【%s】【%s】【%s】【%s】\n", index + 1, fullName, property, stuValue, mark); +// mysqlVo.setText(judgementStr); +// mysqlVo.setIndex(index + 1); +// return mysqlVo; +// } +// +// private static MysqlVo printMissing(int index, String fullName, String property, String stdValue,String judgementStr) { +// MysqlVo mysqlVo=new MysqlVo(); +// System.out.printf("%02d.【字段】【%s】【%s】【%s】【x】\n", index + 1, fullName, property, stdValue); +// appendToFile(answerLogPath, "%02d.【字段】【%s】【%s】【%s】【x】\n", index + 1, fullName, property, stdValue); +// judgementStr = HtmlAppender.appendHtmlLineMysql(judgementStr, "%02d.【字段】【%s】【%s】【%s】【x】\n", index + 1, fullName, property, stdValue); +// mysqlVo.setText(judgementStr); +// mysqlVo.setIndex(index + 1); +// return mysqlVo; +// } +// +// private static Map> convertSetToMap(Set> set) { +// Map> map = new LinkedHashMap<>(); +// for (Map column : set) { +// map.put(column.get("COLUMN_NAME"), column); +// } +// return map; +// } +// public static void deleteFolder(File folder) { +// if (folder.isDirectory()) { +// File[] files = folder.listFiles(); +// if (files != null) { +// for (File file : files) { +// deleteFolder(file); // 递归删除所有子文件/文件夹 +// } +// } +// } +// folder.delete(); // 删除空文件夹或文件 +// } +// //如果这个小题对了,直接累加对应的权值分 +// private SourceAndText accumulateScoreAndLog(List examMysqlKeywordList, AtomicInteger total, String answerLogPath, String sql2, String totalKeyScore, double score,String answerId,double scoreTotal,String judgementStr) { +// SourceAndText sourceAndText = new SourceAndText(); +// if(StringUtils.isBlank(answerId)){ +// appendToFile(answerLogPath, "❌该语句找不到试题id,请检查出题内容!" ); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "❌该语句找不到试题id,请检查出题内容!"); +// sourceAndText.setText(judgementStr); +// sourceAndText.setScore(0.0); +// //返回累加的总分 +// return sourceAndText; +// } +// //用answerid查对应答案的权值 。除以总权值 +// String scoreRateStr= examQuestionAnswerMapper.selectExamQuestionAnswerScoreByAnswerId(answerId); +// +// // 解析权值 +// double scoreRate = 0.0; +// double totalKey = 0.0; +// double singleScore = 0.0; +// try { +// scoreRate = Double.parseDouble(scoreRateStr); +// totalKey = Double.parseDouble(totalKeyScore); +// // 计算该答案对应的得分 +// +// if (totalKey > 0) { +// singleScore = (scoreRate / totalKey) * score; +// singleScore = Math.round(singleScore * 100.0) / 100.0; +// } +// +// String[] lines = sql2.split("\\r?\\n"); +// +// // 开头:✅学生语句: +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "✅学生语句:"); +// // 第一行直接加在后面 +// if (lines.length > 0) { +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, StringEscapeUtils.escapeHtml4(lines[0])); +// } +// +// // 后续行添加换行和缩进 +// for (int i = 1; i < lines.length; i++) { +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr," "+StringEscapeUtils.escapeHtml4(lines[i].trim())); +// } +// // 最终加入 judgementStr +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr,",正确,语句得分权值:"+scoreRateStr + ",得分" + singleScore); +//// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "✅学生语句" + sql2 + "正确,语句得分权值:" + scoreRateStr + ",得分" + singleScore); +// appendToFile(answerLogPath, "✅学生语句" + sql2 + "正确,语句得分权值:" + scoreRateStr + ",得分" + singleScore); +// } catch (NumberFormatException e) { +// System.err.println("无效的totalKeyScore值:" + totalKeyScore); +// } +// sourceAndText.setText(judgementStr); +// sourceAndText.setScore(singleScore); +// //返回累加的总分 +// return sourceAndText; +// +// } +// +// +// +// +// public static String convertUpdateToSelectWhere(String updateSQL) { +// // 清理语句 +// updateSQL = updateSQL.trim().replaceAll(";\\s*$", ""); +// +// // 正则提取表名和 WHERE 条件 +// Pattern pattern = Pattern.compile( +// "UPDATE\\s+(\\w+)\\s+SET\\s+.+?\\s+WHERE\\s+(.+)", +// Pattern.CASE_INSENSITIVE | Pattern.DOTALL +// ); +// Matcher matcher = pattern.matcher(updateSQL); +// if (matcher.find()) { +// String tableName = matcher.group(1).trim(); +// String whereClause = matcher.group(2).trim(); +// return "SELECT * FROM " + tableName + " WHERE " + whereClause + ";"; +// } else { +// return "-- 无法识别的 UPDATE 语句"; // } // } - /** - * 将指定内容追加写入到指定文件中。 - * - * @param filePath 文件路径 - * @param content 要写入的内容 - */ - public static void appendToFile(String filePath, String content) { - try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath, true))) { - String timestamp = LocalDateTime.now().format(formatter); - String logLine = String.format("[%s] %s", timestamp, content); - writer.write(logLine); - writer.newLine(); // 可选:添加换行符 - } catch (IOException e) { - e.printStackTrace(); - } - } - public static void appendToFile(String filePath, String format, Object... args) { - try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath, true))) { - String timestamp = LocalDateTime.now().format(formatter); - String content = String.format(format, args); - String logLine = String.format("[%s] %s", timestamp, content); - writer.write(logLine); - writer.newLine(); // 可选:添加换行符 - } catch (IOException e) { - e.printStackTrace(); - } - } - - } +// +// public static String extractTableNameFromInsert(String sql) { +// Pattern pattern = Pattern.compile("INSERT\\s+INTO\\s+(\\w+)\\s*\\(", Pattern.CASE_INSENSITIVE); +// Matcher matcher = pattern.matcher(sql); +// if (matcher.find()) { +// return matcher.group(1); +// } else { +// return "unknown_table"; +// } +// } +// +// +// private List getColumnNames(ResultSet rs) throws SQLException { +// List columnNames = new ArrayList<>(); +// ResultSetMetaData metaData = rs.getMetaData(); +// int columnCount = metaData.getColumnCount(); +// for (int i = 1; i <= columnCount; i++) { +// columnNames.add(metaData.getColumnName(i)); +// } +// return columnNames; +// } +// +// public static String generateInsertSQL(String tableName, List columns, List> rows) { +// StringBuilder sb = new StringBuilder(); +// sb.append("INSERT INTO ").append(tableName).append(" ("); +// sb.append(String.join(", ", columns)); +// sb.append(") VALUES\n"); +// +// List valueLines = new ArrayList<>(); +// for (List row : rows) { +// List formattedValues = new ArrayList<>(); +// for (String value : row) { +// if (value == null) { +// formattedValues.add("NULL"); +// } else if (value.matches("-?\\d+(\\.\\d+)?")) { +// formattedValues.add(value); // 数字不加引号 +// } else { +// formattedValues.add("'" + value.replace("'", "''") + "'"); // 字符串加引号并转义 +// } +// } +// valueLines.add("(" + String.join(", ", formattedValues) + ")"); +// } +// +// sb.append(String.join(",\n", valueLines)).append(";"); +// return sb.toString(); +// } +// +// public SourceAndText calculateTotalScoreRate(String sql, List examQuestionKeywords, String totalKeyScore, double score,String answerId,double scoreTotal,String judgementStr) { +// SourceAndText sourceAndText = new SourceAndText(); +// if(StringUtils.isBlank(answerId)){ +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "❌该语句找不到试题id,请检查出题内容!"); +// appendToFile(answerLogPath, "❌该语句找不到试题id,请检查出题内容!" ); +// sourceAndText.setText(judgementStr); +// sourceAndText.setScore(0.0); +// //返回累加的总分 +// return sourceAndText; +// } +// //用answerid查对应答案的权值 。除以总权值 +// String scoreRateStr= examQuestionAnswerMapper.selectExamQuestionAnswerScoreByAnswerId(answerId); +// +// +// +// // 解析权值 +// double scoreRate = 0.0; +// double totalKey = 0.0; +// // 计算该答案对应的得分 +// double singleScore = 0.0; +// try { +// scoreRate = Double.parseDouble(scoreRateStr); +// totalKey = Double.parseDouble(totalKeyScore); +// +// if (totalKey > 0) { +// singleScore = (scoreRate / totalKey) * score; +// singleScore = Math.round(singleScore * 100.0) / 100.0; +// } +// +// +// +// } catch (NumberFormatException e) { +// System.err.println("无效的totalKeyScore值:" + totalKeyScore); +// } +// +// +// int totalScoreRate = 0; +// Set matchedKeywords = new HashSet<>(); +// for (ExamMysqlKeyword keyword : examQuestionKeywords) { +// String keywordValue = keyword.getKeyword(); +// if (keywordValue != null && !keywordValue.isEmpty() && !matchedKeywords.contains(keywordValue)) { +// // 使用正则,确保是完整单词(字段)匹配 +// String regex = keywordValue; +// if (sql.contains(regex)) { +// try { +// totalScoreRate += Integer.parseInt(keyword.getScoreRate()); +// +// matchedKeywords.add(keywordValue); +// } catch (NumberFormatException e) { +// System.err.println("Invalid scoreRate format for keyword: " + keywordValue); +// } +// } +// } +// } +// //累加答案关键字的所有权值 +// int totalKeyScoreInt = examQuestionKeywords.stream() +// .map(ExamMysqlKeyword::getScoreRate) +// .filter(s -> s != null && !s.isEmpty()) +// .mapToInt(Integer::parseInt) +// .sum(); +// +// //乘以 对了多少个 关键字 权值 +// double finalRoundedScore; +// if (totalKeyScoreInt == 0) { +// // 如果总键值为0,可以设置为0或其他默认值 +// finalRoundedScore = 0.0; +// } else { +// finalRoundedScore = new BigDecimal( +// ((double) totalScoreRate / totalKeyScoreInt) * singleScore +// ).setScale(2, RoundingMode.HALF_UP).doubleValue(); +// } +// +// String[] lines = sql.split("\\r?\\n"); +// +// // 开头:✅学生语句: +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "❌学生语句:"); +// // 第一行直接加在后面 +// if (lines.length > 0) { +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, StringEscapeUtils.escapeHtml4(lines[0])); +// } +// +// // 后续行添加换行和缩进 +// for (int i = 1; i < lines.length; i++) { +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr," "+StringEscapeUtils.escapeHtml4(lines[i].trim())); +// } +// // 最终加入 judgementStr +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr,",不正确,语句权值:"+scoreRateStr+",关键权值:"+totalKeyScoreInt+",答对得分点为:"+matchedKeywords+",答对关键得分权值"+ totalScoreRate+ ",得分" + finalRoundedScore); +//// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "❌语句"+sql+"不正确,语句权值:"+scoreRateStr+",关键权值:"+totalKeyScoreInt+",答对得分点为:"+matchedKeywords+",答对关键得分权值"+ totalScoreRate+ ",得分" + finalRoundedScore); +// +// appendToFile(answerLogPath,"❌语句"+sql+"不正确,语句权值:"+scoreRateStr+",关键权值:"+totalKeyScoreInt+",答对得分点为:"+matchedKeywords+",答对关键得分权值"+ totalScoreRate+ ",得分" + finalRoundedScore); +// sourceAndText.setText(judgementStr); +// sourceAndText.setScore(finalRoundedScore); +// //返回累加的总分 +// return sourceAndText; +// } +// +// // 预处理函数:去除空格和换行并转为大写 +// private static String normalize(String str) { +// return str.replaceAll("\\s+", "").toUpperCase(); +// } +// +// // 删除 数据库连接 +// public static void deleteRegistryKey() { +// try { +// // 1. 通过命令获取当前用户 SID +// Process sidProcess = Runtime.getRuntime().exec(new String[]{"whoami", "/user"}); +// BufferedReader reader = new BufferedReader(new InputStreamReader(sidProcess.getInputStream())); +// +// String sid = null; +// String line; +// while ((line = reader.readLine()) != null) { +// if (line.contains("\\")) continue; // 跳过表头行 +// String[] parts = line.trim().split("\\s+"); +// if (parts.length >= 2) { +// sid = parts[1]; // 第二列是 SID +// break; +// } +// } +// reader.close(); +// +// int sidExitCode = sidProcess.waitFor(); +// if (sid == null || sidExitCode != 0) { +// System.out.println("❌ 无法获取当前用户 SID"); +// return; +// } +// +// // 2. 构造完整注册表路径 +// String regKey = "HKEY_USERS\\" + sid + "\\Software\\PremiumSoft\\Navicat\\Servers\\答题专用"; +// +// // 3. 执行删除命令 +// String[] cmd = {"reg", "delete", regKey, "/f"}; +// Process process = Runtime.getRuntime().exec(cmd); +// int exitCode = process.waitFor(); +// +// if (exitCode == 0) { +// System.out.println("✅ 注册表项删除成功"); +// } else { +// System.out.println("❌ 注册表项删除失败,退出码:" + exitCode); +// } +// +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +// +// +// +// +// public static String cleanProcedureSQL(String sql) { +// // 删除 DELIMITER 和 $$ 标记 +// sql = sql.replaceAll("(?i)DELIMITER\\s+\\$\\$", ""); // 删除 DELIMITER $$ +// sql = sql.replaceAll("(?i)DELIMITER\\s+;", ""); // 删除 DELIMITER ; +// sql = sql.replaceAll("\\$\\$", ""); // 删除结尾 $$ +// +// // 删除 CALL 语句(例如 CALL pro_xxx(...);) +// sql = sql.replaceAll("(?i)CALL\\s+[^;]+;", ""); // 删除 CALL 语句(不区分大小写) +// +// +// // 删除 -- 行内注释(从 -- 到行尾) +// sql = sql.replaceAll("(?m)--.*?$", ""); // (?m) 多行模式,$ 表示行尾 +// +// // 删除 /**/ 多行注释 +// sql = sql.replaceAll("(?s)/\\*.*?\\*/", ""); // (?s) 单行模式,.*? 非贪婪匹配 +// +// // 去掉多余空白字符 +// return sql.trim(); +// } +// public static class DeleteInfo { +// public String tableName; +// public String whereClause; +// +// public DeleteInfo(String tableName, String whereClause) { +// this.tableName = tableName; +// this.whereClause = whereClause; +// } +// } +// // 标准化 SQL 字符串 +// public static String convertInsertToSelect(String sql) { +// sql = sql.trim().replaceAll(";+\\s*$", ""); // 去掉末尾分号 +// +// // 匹配字段名和 VALUES 部分 +// Pattern pattern = Pattern.compile( +// "INSERT INTO\\s+\\w+\\s*\\(([^)]+)\\)\\s*VALUES\\s*(.+)", +// Pattern.CASE_INSENSITIVE | Pattern.DOTALL +// ); +// Matcher matcher = pattern.matcher(sql); +// if (!matcher.find()) { +// return "不合法的 INSERT 语句"; +// } +// +// String fieldPart = matcher.group(1).trim(); +// String valuesPart = matcher.group(2).trim(); +// +// String[] fields = fieldPart.split("\\s*,\\s*"); +// +// // 提取所有 () 中的值 +// List valueGroups = new ArrayList<>(); +// Matcher valueMatcher = Pattern.compile("\\(([^()]*)\\)").matcher(valuesPart); +// while (valueMatcher.find()) { +// valueGroups.add(valueMatcher.group(1)); +// } +// +// // 构造 SELECT ... UNION ALL +// List selects = new ArrayList<>(); +// for (int i = 0; i < valueGroups.size(); i++) { +// String[] values = valueGroups.get(i).split("\\s*,\\s*", -1); +// if (values.length != fields.length) { +// return "字段数与值数不匹配,请检查第 " + (i + 1) + " 行"; +// } +// +// StringBuilder sb = new StringBuilder("SELECT "); +// for (int j = 0; j < fields.length; j++) { +// if (i == 0) { +// sb.append(values[j]).append(" AS ").append(fields[j]); +// } else { +// sb.append(values[j]); +// } +// if (j < fields.length - 1) sb.append(", "); +// } +// selects.add(sb.toString()); +// } +// +// return String.join("\nUNION ALL\n", selects) + ";"; +// } +// +// +// +// // 比较两个结果集 +// private static MysqlBooleanVo compareExtractResults(List> newResults, List> oldResults, String judgementStr) { +// MysqlBooleanVo mysqlBooleanVo=new MysqlBooleanVo(); +// appendToFile(answerLogPath,"==== 标准答案 ===="); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "==== 标准答案 ===="); +// for (Map row : newResults) { +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, row.toString()); +// appendToFile(answerLogPath,row.toString()); +// } +// appendToFile(answerLogPath,"==== 考生答案 ===="); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "==== 考生答案 ===="); +// for (Map row : oldResults) { +// appendToFile(answerLogPath,row.toString()); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, row.toString()); +// } +// +// if (newResults.size() != oldResults.size()) { +// appendToFile(answerLogPath,"❌考生答案与标准答案个数不对"); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "❌考生答案与标准答案个数不对"); +// mysqlBooleanVo.setText(judgementStr); +// mysqlBooleanVo.setFlag(false); +// return mysqlBooleanVo; +// } +// +// // 不比较顺序,直接判断两个列表内容是否一样(将其转换为 Set) +// Set> newSet = new HashSet<>(newResults); +// Set> oldSet = new HashSet<>(oldResults); +// +// if (!newSet.equals(oldSet)) { +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "❌ 内容相同但顺序不同,或存在差异:"); +// appendToFile(answerLogPath,"❌ 内容相同但顺序不同,或存在差异:"); +// Set> onlyInNew = new HashSet<>(newSet); +// onlyInNew.removeAll(oldSet); +// +// Set> onlyInOld = new HashSet<>(oldSet); +// onlyInOld.removeAll(newSet); +// +// for (Map row : onlyInNew) { +// appendToFile(answerLogPath,"⚠️ 标准答案中有但考生答案中没有: " + row); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "⚠️ 标准答案中有但考生答案中没有: " + row); +// } +// +// for (Map row : onlyInOld) { +// appendToFile(answerLogPath,"⚠️ 考生答案中有但标准答案中没有: " + row); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "⚠️ 考生答案中有但标准答案中没有: " + row); +// } +// mysqlBooleanVo.setText(judgementStr); +// mysqlBooleanVo.setFlag(false); +// return mysqlBooleanVo; +// } +// appendToFile(answerLogPath,"两个结果集内容一致(不考虑顺序)!"); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "两个结果集内容一致(不考虑顺序)!"); +// mysqlBooleanVo.setText(judgementStr); +// mysqlBooleanVo.setFlag(true); +// return mysqlBooleanVo; +// } +// +// +// // 提取ResultSet中的结果到一个列表中 +// private static List> extractResults(ResultSet resultSet) throws SQLException { +// List> results = new ArrayList<>(); +// +// // 获取列数 +// ResultSetMetaData metaData = resultSet.getMetaData(); +// int columnCount = metaData.getColumnCount(); +// +// while (resultSet.next()) { +// Map row = new HashMap<>(); +// for (int i = 1; i <= columnCount; i++) { +// String columnName = metaData.getColumnLabel(i); +// Object value = resultSet.getObject(i); +// row.put(columnName, value); +// } +// results.add(row); +// } +// +// return results; +// } +// +// +// public static String restoreUpdateFromResult( +// String originalUpdateSql, +// List columns, +// List> answerListStu +// ) { +// +// System.out.println("========================================================= " ); +// System.out.println("originalUpdateSql = " + originalUpdateSql); +// System.out.println("columns = " + columns); +// System.out.println("answerListStu = " + answerListStu); +// System.out.println("========================================================= " ); +// +// +// Pattern p = Pattern.compile("UPDATE\\s+(\\w+)\\s+SET\\s+(.+?)\\s+WHERE\\s+(.+);?", Pattern.CASE_INSENSITIVE | Pattern.DOTALL); +// Matcher m = p.matcher(originalUpdateSql); +// if (!m.find()) { +// throw new IllegalArgumentException("无法解析原始 UPDATE 语句"); +// } +// String tableName = m.group(1); +// String wherePart = m.group(3); +// +// if (answerListStu.isEmpty()) { +// throw new IllegalArgumentException("查询结果为空,无法还原"); +// } +// +// List firstRow = answerListStu.get(0); +// List answerRow = answerListStu.get(1); +// List setClauses = new ArrayList<>(); +// +// for (int i = 0; i < columns.size(); i++) { +// String col = columns.get(i); +// String val = answerRow.get(i); +// +// String valStr; +// if (val == null || val.equalsIgnoreCase("null")) { +// valStr = "NULL"; +// } else if (val.matches("-?\\d+(\\.\\d+)?")) { +// valStr = val; +// } else { +// valStr = "'" + val.replace("'", "''") + "'"; +// } +// setClauses.add(col + " = " + valStr); +// } +// +// String setPart = String.join(", ", setClauses); +// return "UPDATE " + tableName + " SET " + setPart + " WHERE " + wherePart ; +// } +// +// public static List extractCallStatements(String sql) { +// List callStatements = new ArrayList<>(); +// Pattern callPattern = Pattern.compile("CALL\\s+\\w+\\s*\\([^;]*?\\);", Pattern.CASE_INSENSITIVE); +// Matcher matcher = callPattern.matcher(sql); +// +// while (matcher.find()) { +// callStatements.add(matcher.group()); +// } +// +// return callStatements; +// } +// +// +// /** +// * 比较两个查询的结果 +// */ +// private static boolean compareResults(List> result1, List> result2) { +// // 获取列名并比较(顺序无关) +// List columnNames1 = result1.get(0); +// List columnNames2 = result2.get(0); +// +// // 检查列名是否一致(顺序无关) +// Set columnSet1 = new HashSet<>(columnNames1); +// Set columnSet2 = new HashSet<>(columnNames2); +// if (!columnSet1.equals(columnSet2)) { +// return false; +// } +// +// // 获取数据行(去除列名) +// List> rows1 = result1.subList(1, result1.size()); +// List> rows2 = result2.subList(1, result2.size()); +// +// // 使用 Set 存储每行数据并比较 +// Set> rowSet1 = new HashSet<>(); +// for (List row : rows1) { +// rowSet1.add(new HashSet<>(row)); +// } +// +// Set> rowSet2 = new HashSet<>(); +// for (List row : rows2) { +// rowSet2.add(new HashSet<>(row)); +// } +// +// // 比较行数据(无顺序) +// return rowSet1.equals(rowSet2); +// } +// /** +// * 执行 SQL 查询并返回结果 +// */ +// private static List> executeQuery(Statement stmt, String sql) throws SQLException { +// List> result = new ArrayList<>(); +// +// +// try { +// +// ResultSet rs = stmt.executeQuery(sql); +// // 获取列数和列名 +// ResultSetMetaData metaData = rs.getMetaData(); +// int columnCount = metaData.getColumnCount(); +// +// // 获取列名 +// List columnNames = new ArrayList<>(); +// for (int i = 1; i <= columnCount; i++) { +// columnNames.add(metaData.getColumnLabel(i)); +// } +// result.add(columnNames); // 将列名添加为结果的第一行 +// +// // 遍历结果集 +// while (rs.next()) { +// List row = new ArrayList<>(); +// for (int i = 1; i <= columnCount; i++) { +// row.add(rs.getString(i)); +// } +// result.add(row); +// } +// } catch (SQLException e) { +// appendToFile(answerLogPath, "执行学生库 SQL CALL 语句时发生错误: " + e.getMessage()); +// } +// +// +// return result; +// } +// /** +// * 从文件读取 SQL 语句 +// */ +// private static String readSQLFromFile(String filePath) throws IOException { +// File file = new File(filePath); +// if (!file.exists()) { +// throw new FileNotFoundException("❌ 找不到SQL文件:" + filePath); +// } +// +// StringBuilder sql = new StringBuilder(); +// try (BufferedReader reader = new BufferedReader(new FileReader(file))) { +// String line; +// while ((line = reader.readLine()) != null) { +// sql.append(line).append(" "); +// } +// } +// return sql.toString().trim(); +// } +// +// // 去除 SQL 中的注释部分 +// private static String removeComments(String sql) { +// // 正则表达式匹配 SQL 中以 -- 开头的注释 +// return sql.replaceAll("(?m)^[\\s]*--.*$", ""); +// } +// /** +// * 比较两个查询的结果 +// */ +// private static boolean compareResultsSelect(List> result1, List> result2) { +// // 获取列名并比较(顺序无关) +// List columnNames1 = result1.get(0); +// List columnNames2 = result2.get(0); +// +// // 检查列名是否一致(顺序无关) +// Set columnSet1 = new HashSet<>(columnNames1); +// Set columnSet2 = new HashSet<>(columnNames2); +// if (!columnSet1.equals(columnSet2)) { +// return false; +// } +// +// // 获取数据行(去除列名) +// List> rows1 = result1.subList(1, result1.size()); +// List> rows2 = result2.subList(1, result2.size()); +// +// // 使用 Set 存储每行数据并比较 +// Set> rowSet1 = new HashSet<>(); +// for (List row : rows1) { +// rowSet1.add(new HashSet<>(row)); +// } +// +// Set> rowSet2 = new HashSet<>(); +// for (List row : rows2) { +// rowSet2.add(new HashSet<>(row)); +// } +// +// // 比较行数据(无顺序) +// return rowSet1.equals(rowSet2); +// } +// /** +// * 打印查询结果 +// */ +// private static String printResult(List> result,String judgementStr) { +// if (result.isEmpty()) { +// appendToFile(answerLogPath, "查询结果为空"); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "查询结果为空"); +// return judgementStr; +// } else { +// for (int i = 0; i < result.size(); i++) { +// List row = result.get(i); +// StringBuilder sb = new StringBuilder(); +// for (String value : row) { +// sb.append(value).append("\t"); +// } +// +// // 输出整行 +// appendToFile(answerLogPath, sb.toString()); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, sb.toString()); +// } +// } +// return judgementStr; +// } +// +// /** +// * 使用提供的正则表达式模式从给定的 SQL 语句中提取视图名称。 +// */ +// private static String extractViewName(String sql, String regex) { +// Pattern pattern = Pattern.compile(regex); +// Matcher matcher = pattern.matcher(sql); +// +// // 如果找到匹配项,返回匹配到的视图名称 +// if (matcher.find()) { +// return matcher.group(1).replace("`", ""); // 如果有反引号(`),则移除 +// } else { +// return "未找到视图名称"; +// } +// } +// +// private static List> getAnswerList(ResultSet answer) throws SQLException { +// List> result = new ArrayList<>(); +// // 获取列数和列名 +// ResultSetMetaData metaData = answer.getMetaData(); +// int columnCount = metaData.getColumnCount(); +// +// // 获取列名 +// List columnNames = new ArrayList<>(); +// for (int i = 1; i <= columnCount; i++) { +// columnNames.add(metaData.getColumnLabel(i)); +// } +// result.add(columnNames); // 将列名添加为结果的第一行 +// +// // 遍历结果集 +// while (answer.next()) { +// List row = new ArrayList<>(); +// for (int i = 1; i <= columnCount; i++) { +// row.add(answer.getString(i)); +// } +// result.add(row); +// } +// +// return result; +// +// } +// +// +// +// public static void generateInsertStatements(String tableName, Map.Entry entry, String newDbUrl, String user, String password) { +// // 确保 entry 里包含的是 INSERT 语句 +// if (entry.getValue().trim().toUpperCase().startsWith("INSERT")) { +// System.out.println("==================插入语句=================="); +// // 创建一个列表来存储所有的 INSERT INTO 语句 +// List insertQueries = new ArrayList<>(); +// try (Connection conn = DriverManager.getConnection(newDbUrl, user, password); +// Statement stmt = conn.createStatement()) { +// +// // 查询表的所有列 +// String columnsQuery = "DESCRIBE " + tableName; +// +// try (ResultSet columnsRs = stmt.executeQuery(columnsQuery)) { +// List columnNames = new ArrayList<>(); +// while (columnsRs.next()) { +// String columnName = columnsRs.getString("Field"); +// columnNames.add(columnName); +// } +// +// // 获取表的数据并生成 INSERT INTO 语句 +// String selectQuery = "SELECT * FROM " + tableName; +// try (ResultSet dataRs = stmt.executeQuery(selectQuery)) { +// +// while (dataRs.next()) { +// StringBuilder insertQuery = new StringBuilder("INSERT INTO `" + tableName + "` ("); +// +// // 构建列名部分 +// for (int i = 0; i < columnNames.size(); i++) { +// insertQuery.append("`").append(columnNames.get(i)).append("`"); +// if (i < columnNames.size() - 1) { +// insertQuery.append(", "); +// } +// } +// insertQuery.append(") VALUES ("); +// +// // 构建值部分 +// for (int i = 0; i < columnNames.size(); i++) { +// Object value = dataRs.getObject(columnNames.get(i)); +// if (value == null) { +// insertQuery.append("NULL"); +// } else if (value instanceof String) { +// insertQuery.append("'").append(value.toString().replace("'", "''")).append("'"); +// } else { +// insertQuery.append(value); +// } +// +// if (i < columnNames.size() - 1) { +// insertQuery.append(", "); +// } +// } +// insertQuery.append(");"); +// // 将生成的 INSERT INTO 语句添加到列表中 +// insertQueries.add(insertQuery.toString()); +// // 输出生成的 INSERT INTO 语句 +// System.out.println(insertQuery.toString()); +// } +// +// } +// catch (SQLException e) { +// System.err.println("生成插入语句失败,表名:" + tableName); +// e.printStackTrace(); +// } +// } +// } catch (SQLException e) { +// System.err.println("生成插入语句失败,表名:" + tableName); +// e.printStackTrace(); +// } +// // 将列表赋值给 entry 的值 +// entry.setValue(insertQueries.toString()); +// System.out.println(entry.getValue()); +// } +// } +// +// /** +// * 读取指定目录下所有文件,返回一个文件名到文件内容的键值对Map +// * @param directoryPath 文件夹路径 +// * @return Map<文件名, 文件内容> +// * @throws IOException 读取文件异常 +// */ +// public static Map readFilesAsMap(String directoryPath) throws IOException { +// Map fileContentMap = new HashMap<>(); +// +// Path dirPath = Paths.get(directoryPath); +// if (!Files.isDirectory(dirPath)) { +// throw new IllegalArgumentException("路径不是一个有效的目录: " + directoryPath); +// } +// +// try (DirectoryStream stream = Files.newDirectoryStream(dirPath)) { +// for (Path path : stream) { +// if (Files.isRegularFile(path)) { +// String fileName = path.getFileName().toString(); +// String content = new String(Files.readAllBytes(path)); +// fileContentMap.put(fileName, content); +// } +// } +// } +// +// return fileContentMap; +// } +// +// +// /** +// * 通过命令行执行 SQL 文件 +// */ +// public static boolean executeSqlFileUsingCommandLine(String sqlFilePath, String dbName, String user, String password) { +// try { +// // 拼接命令 +// String[] command = { +// "mysql", +// "-u" + user, +// "-P", "6033", +// dbName, +// "-e", "source " + sqlFilePath +// }; +// +// // 启动进程 +// Process process = Runtime.getRuntime().exec(command); +// int exitCode = process.waitFor(); +// +// return exitCode == 0; +// } catch (Exception e) { +// e.printStackTrace(); +// return false; +// } +// } +//// private static boolean executeSqlFileUsingCommandLine(String filePath, String databaseName, String user, String password) throws IOException { +//// // 构建 MySQL 命令 +//// String command = String.format("mysql -u %s -p%s %s < %s", user, password, databaseName, filePath); +//// +//// // 使用 ProcessBuilder 执行命令 +//// ProcessBuilder processBuilder = new ProcessBuilder("cmd.exe", "/c", command); +//// processBuilder.inheritIO(); // 将输入输出重定向到当前控制台 +//// Process process = processBuilder.start(); +//// +//// try { +//// // 等待命令执行完成 +//// int exitCode = process.waitFor(); +//// if (exitCode == 0) { +//// System.out.println("SQL 文件执行成功:" + filePath); +//// return true; // 返回 true 表示执行成功 +//// } else { +//// System.err.println("SQL 文件执行失败:" + filePath); +//// return false; // 返回 false 表示执行失败 +//// } +//// } catch (InterruptedException e) { +//// e.printStackTrace(); +//// return false; +//// } +//// } +// /** +// * 将指定内容追加写入到指定文件中。 +// * +// * @param filePath 文件路径 +// * @param content 要写入的内容 +// */ +// public static void appendToFile(String filePath, String content) { +// try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath, true))) { +// String timestamp = LocalDateTime.now().format(formatter); +// String logLine = String.format("[%s] %s", timestamp, content); +// writer.write(logLine); +// writer.newLine(); // 可选:添加换行符 +// } catch (IOException e) { +// e.printStackTrace(); +// } +// } +// public static void appendToFile(String filePath, String format, Object... args) { +// try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath, true))) { +// String timestamp = LocalDateTime.now().format(formatter); +// String content = String.format(format, args); +// String logLine = String.format("[%s] %s", timestamp, content); +// writer.write(logLine); +// writer.newLine(); // 可选:添加换行符 +// } catch (IOException e) { +// e.printStackTrace(); +// } +// } +// +// } diff --git a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/service/mysql/IMysqlServerice.java b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/service/mysql/IMysqlServerice.java index ad0330f2..7ea8aa19 100644 --- a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/service/mysql/IMysqlServerice.java +++ b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/service/mysql/IMysqlServerice.java @@ -1,20 +1,20 @@ -package pc.exam.pp.module.judgement.controller.service.mysql; - - -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.ExamQuestionAnswer; -import pc.exam.pp.module.judgement.service.auto_tools.vo.SourceAndText; - -import java.io.File; -import java.io.IOException; -import java.sql.SQLException; -import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; - -public interface IMysqlServerice { - SourceAndText Judgement(double sorce, File file, ExamQuestion examQuestion, String judgementStr) throws IOException, SQLException; - - - -} +//package pc.exam.pp.module.judgement.controller.service.mysql; +// +// +//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.ExamQuestionAnswer; +//import pc.exam.pp.module.judgement.service.auto_tools.vo.SourceAndText; +// +//import java.io.File; +//import java.io.IOException; +//import java.sql.SQLException; +//import java.util.List; +//import java.util.concurrent.atomic.AtomicInteger; +// +//public interface IMysqlServerice { +// SourceAndText Judgement(double sorce, File file, ExamQuestion examQuestion, String judgementStr) throws IOException, SQLException; +// +// +// +////} diff --git a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/service/mysql/MysqlServericeImpl.java b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/service/mysql/MysqlServericeImpl.java index 2fc5a723..7db2a464 100644 --- a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/service/mysql/MysqlServericeImpl.java +++ b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/service/mysql/MysqlServericeImpl.java @@ -1,1553 +1,1540 @@ -package pc.exam.pp.module.judgement.controller.service.mysql; - -import jakarta.annotation.Resource; -import org.apache.commons.lang3.StringUtils; -import org.springframework.stereotype.Service; -import pc.exam.pp.framework.common.pojo.CommonResult; -import pc.exam.pp.module.exam.dal.dataobject.ExamMysqlKeyword; -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.dal.mysql.question.ExamMysqlKeywordMapper; -import pc.exam.pp.module.exam.dal.mysql.question.ExamQuestionAnswerMapper; -import pc.exam.pp.module.exam.dal.mysql.question.ExamQuestionMapper; -import pc.exam.pp.module.judgement.controller.service.mysql.vo.MysqlVo; -import pc.exam.pp.module.judgement.controller.utils.Mysql.MySQLExporterUtil; -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.*; -import java.math.BigDecimal; -import java.math.RoundingMode; -import java.nio.charset.StandardCharsets; -import java.nio.file.DirectoryStream; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.sql.*; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.util.*; -import java.util.List; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.stream.Collectors; - -import static pc.exam.pp.module.judgement.controller.utils.Mysql.SQLComparatorUtil.areUpdateStatementsEqual; - -@Service -public class MysqlServericeImpl implements IMysqlServerice { - static String databaseName; - static String databaseNameStu; - static String answerLogPath; // 文件路径 - private static final DateTimeFormatter formatter = - DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); - @Resource - private ExamMysqlKeywordMapper examMysqlKeywordMapper; - @Resource - private ExamQuestionAnswerMapper examQuestionAnswerMapper; - - @Override - 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"); - // 4、获取到得是zip文件,需要解压 - String stuFilePath = ZipUtil.unzipToNamedFolder(path); - File folderzip = new File(path); - File folder = new File(stuFilePath); - // 5、解压之后得文件获取文件夹和文件 - String stu_files = null; - - // 5.2、查询试题ID - - List examQuestionAnswers = examQuestionAnswerMapper.selectExamQuestionAnswerByQuId(examQuestion.getQuId()); - String totalKeyScore ="0"; - //得出 这个题总共的权值点 - totalKeyScore=examQuestionAnswerMapper.selectCountPointByQuId(examQuestion.getQuId()); - -// if (examQuestionAnswers!=null&&examQuestionAnswers.size()>0){ -// List answerIdList = examQuestionAnswers.stream() -// .map(ExamQuestionAnswer::getAnswerId) // 提取每个对象的 answerId -// .collect(Collectors.toList()); -// //得到总计得分点 -// System.out.println(answerIdList); -// totalKeyScore=examMysqlKeywordMapper.selectByAnswerIds(answerIdList); +//package pc.exam.pp.module.judgement.controller.service.mysql; // +//import jakarta.annotation.Resource; +//import org.apache.commons.lang3.StringUtils; +//import org.springframework.stereotype.Service; +//import pc.exam.pp.module.exam.dal.dataobject.ExamMysqlKeyword; +//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.ExamMysqlKeywordMapper; +//import pc.exam.pp.module.exam.dal.mysql.question.ExamQuestionAnswerMapper; +//import pc.exam.pp.module.judgement.controller.service.mysql.vo.MysqlVo; +//import pc.exam.pp.module.judgement.controller.utils.zip.ZipUtil; +//import pc.exam.pp.module.judgement.service.auto_tools.vo.SourceAndText; +// +//import java.io.*; +//import java.math.BigDecimal; +//import java.math.RoundingMode; +//import java.nio.file.DirectoryStream; +//import java.nio.file.Files; +//import java.nio.file.Path; +//import java.nio.file.Paths; +//import java.sql.*; +//import java.time.LocalDateTime; +//import java.time.format.DateTimeFormatter; +//import java.util.*; +//import java.util.List; +//import java.util.concurrent.atomic.AtomicInteger; +//import java.util.regex.Matcher; +//import java.util.regex.Pattern; +// +//import static pc.exam.pp.module.judgement.controller.utils.Mysql.SQLComparatorUtil.areUpdateStatementsEqual; +// +//@Service +//public class MysqlServericeImpl implements IMysqlServerice { +// static String databaseName; +// static String databaseNameStu; +// static String answerLogPath; // 文件路径 +// private static final DateTimeFormatter formatter = +// DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); +// @Resource +// private ExamMysqlKeywordMapper examMysqlKeywordMapper; +// @Resource +// private ExamQuestionAnswerMapper examQuestionAnswerMapper; +// +// @Override +// 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"); +// // 4、获取到得是zip文件,需要解压 +// String stuFilePath = ZipUtil.unzipToNamedFolder(path); +// File folderzip = new File(path); +// File folder = new File(stuFilePath); +// // 5、解压之后得文件获取文件夹和文件 +// String stu_files = null; +// +// // 5.2、查询试题ID +// +// List examQuestionAnswers = examQuestionAnswerMapper.selectExamQuestionAnswerByQuId(examQuestion.getQuId()); +// String totalKeyScore ="0"; +// //得出 这个题总共的权值点 +// totalKeyScore=examQuestionAnswerMapper.selectCountPointByQuId(examQuestion.getQuId()); +// +//// if (examQuestionAnswers!=null&&examQuestionAnswers.size()>0){ +//// List answerIdList = examQuestionAnswers.stream() +//// .map(ExamQuestionAnswer::getAnswerId) // 提取每个对象的 answerId +//// .collect(Collectors.toList()); +//// //得到总计得分点 +//// System.out.println(answerIdList); +//// totalKeyScore=examMysqlKeywordMapper.selectByAnswerIds(answerIdList); +//// +//// } +// answerLogPath = filepath.getParent() + File.separator + "log.txt"; +// +// AtomicInteger total = new AtomicInteger(); +// // 文件路径 +// +//// String file = "D:\\Desktop\\202504211120_mysql\\71\\MYS_010_122\\结果素材\\结果素材\\Teacher"; +//// String file = new File(filepath, "结果").getAbsolutePath(); +//// String filePath = "D:\\Desktop\\202504211120_mysql\\71\\MYS_010_122\\结果素材\\结果素材\\Teacher\\answer.txt"; // 答案文件路径 +// String filePath = new File(stuFilePath, "answer.txt").getAbsolutePath(); // 结果/answer.txt +// +//// String answerPath = "D:\\Desktop\\202504211120_mysql\\71\\MYS_010_122\\结果素材\\结果素材\\Teacher\\db\\db_escape.myd"; // 原始 SQL 文件路径 +// File dbDir = new File(stuFilePath, "db"); +// String answerPath = null; +// if (dbDir.exists() && dbDir.isDirectory()) { +// File[] mydFiles = dbDir.listFiles((dir, name) -> name.toLowerCase().endsWith(".myd")); +// if (mydFiles != null && mydFiles.length > 0) { +// answerPath = mydFiles[0].getAbsolutePath(); // 默认取第一个 .myd 文件 +// } // } - answerLogPath = filepath.getParent() + File.separator + "log.txt"; - - AtomicInteger total = new AtomicInteger(); - // 文件路径 - -// String file = "D:\\Desktop\\202504211120_mysql\\71\\MYS_010_122\\结果素材\\结果素材\\Teacher"; -// String file = new File(filepath, "结果").getAbsolutePath(); -// String filePath = "D:\\Desktop\\202504211120_mysql\\71\\MYS_010_122\\结果素材\\结果素材\\Teacher\\answer.txt"; // 答案文件路径 - String filePath = new File(stuFilePath, "answer.txt").getAbsolutePath(); // 结果/answer.txt - -// String answerPath = "D:\\Desktop\\202504211120_mysql\\71\\MYS_010_122\\结果素材\\结果素材\\Teacher\\db\\db_escape.myd"; // 原始 SQL 文件路径 - File dbDir = new File(stuFilePath, "db"); - String answerPath = null; - if (dbDir.exists() && dbDir.isDirectory()) { - File[] mydFiles = dbDir.listFiles((dir, name) -> name.toLowerCase().endsWith(".myd")); - if (mydFiles != null && mydFiles.length > 0) { - answerPath = mydFiles[0].getAbsolutePath(); // 默认取第一个 .myd 文件 - } - } - - -// String fileStu = "D:\\Desktop\\202504211120_mysql\\71\\MYS_010_122\\考试素材\\考试素材\\Student"; - String fileStu = filepath.getAbsolutePath(); - -// String stuAnswerPath = "D:\\Desktop\\202504211120_mysql\\71\\MYS_010_122\\考试素材\\考试素材\\Student\\db\\db_escape.myd"; - File stuDbDir = new File(fileStu, "db"); - String stuAnswerPath = null; - if (stuDbDir.exists() && stuDbDir.isDirectory()) { - File[] stuMydFiles = stuDbDir.listFiles((dir, name) -> name.toLowerCase().endsWith(".myd")); - if (stuMydFiles != null && stuMydFiles.length > 0) { - stuAnswerPath = stuMydFiles[0].getAbsolutePath(); // 默认取第一个 .myd 文件 - } - } - - // 生成随机数据库名,临时使用 - databaseName = "db_" + UUID.randomUUID().toString().replace("-", "").substring(0, 8); - databaseNameStu = "db_" + UUID.randomUUID().toString().replace("-", "").substring(0, 8); - -// databaseName = "db_6f80867f"; -// databaseNameStu= "db_6f80867e"; - // 连接到 MySQL 默认数据库 - String url = "jdbc:mysql://rm-bp1a44uap1mm20980mo.mysql.rds.aliyuncs.com:3306/mysql?useSSL=false&serverTimezone=Asia/Shanghai"; - String user = "root"; - String password = "Xiaobing0308"; - try { - // **连接到 MySQL 默认数据库,创建新的数据库** - try (Connection conn = DriverManager.getConnection(url, user, password); - Statement stmt = conn.createStatement()) { - String createDbSql = "CREATE DATABASE IF NOT EXISTS " + databaseName + - " CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci"; -// String createDbSql = "CREATE DATABASE " + databaseName; - stmt.executeUpdate(createDbSql); - System.out.println("已创建数据库:" + databaseName); -// String createDbSql2 = "CREATE DATABASE " + databaseNameStu; - String createDbSql2 = "CREATE DATABASE IF NOT EXISTS " + databaseNameStu + - " CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci"; - stmt.executeUpdate(createDbSql2); - System.out.println("已创建数据库:" + databaseNameStu); - - - } - - - } catch (SQLException e) { - e.printStackTrace(); - } - -// // **建立连接到新创建的数据库** - String newDbUrl = "jdbc:mysql://rm-bp1a44uap1mm20980mo.mysql.rds.aliyuncs.com:3306/" + databaseName + "?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=UTF-8"; - String stuDbUrl = "jdbc:mysql://rm-bp1a44uap1mm20980mo.mysql.rds.aliyuncs.com:3306/" + databaseNameStu + "?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=UTF-8"; - // **通过命令行执行 SQL 文件** 建立 完整正确数据库 - boolean sqlFileExecuted = executeSqlFileUsingCommandLine(answerPath, databaseName, user, password); - //建立考生答题数据库 - boolean sqlFileExecutedstu = executeSqlFileUsingCommandLine(stuAnswerPath, databaseNameStu, user, password); - - if (sqlFileExecuted && sqlFileExecutedstu) { - - - Map result = readFilesAsMap(stuFilePath); - Map resultStu = readFilesAsMap(fileStu); - try (Connection conn = DriverManager.getConnection(stuDbUrl, user, password); - Statement stmt = conn.createStatement()) { - - - System.out.println("已连接学生数据库"); - for (Map.Entry entry : resultStu.entrySet()) { - - if (entry.getValue().trim().toUpperCase().startsWith("CREATE TABLE")) { - // 正则表达式匹配表名 - Pattern pattern = Pattern.compile("CREATE TABLE\\s+`?(\\w+)`?\\s*\\("); - Matcher matcher = pattern.matcher(entry.getValue()); - - if (matcher.find()) { - String tableName = matcher.group(1).replace("`", ""); // 获取表名 - System.out.println("表名:" + tableName); - // 获取表名和 SQL 语句 - String createTableSql = entry.getValue(); - - - // 执行 CREATE TABLE 语句 - stmt.executeUpdate(createTableSql); - // 查询建表语句 - String showCreateTableSql = "SHOW CREATE TABLE " + tableName; - try (ResultSet rs = stmt.executeQuery(showCreateTableSql)) { - if (rs.next()) { - String createTableSqlExport = rs.getString("Create Table"); - // 替换 result 中的值 - entry.setValue(createTableSqlExport); - } - } catch (SQLException e) { - appendToFile(answerLogPath, "执行验证 SQL 出错!"); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "执行验证 SQL 出错!"); - e.printStackTrace(); - } - } - - } - - - if (entry.getValue().trim().toUpperCase().startsWith("DELETE")) { - String delStatement = entry.getValue(); - stmt.executeUpdate(delStatement); - - } - - - } - for (Map.Entry entry : resultStu.entrySet()) { - - if (entry.getValue().trim().toUpperCase().startsWith("INSERT")) { - // 正则表达式匹配表名 - Pattern pattern = Pattern.compile("INSERT INTO\\s+`?(\\w+)`?\\s*(\\(|VALUES)", Pattern.CASE_INSENSITIVE); - Matcher matcher = pattern.matcher(entry.getValue()); - if (matcher.find()) { - String tableName = matcher.group(1).replace("`", ""); // 获取表名 - // 获取 INSERT INTO 语句的表格数据并生成新的插入语句 - - String sqlBlock = entry.getValue(); - String[] sqlStatements = sqlBlock.split(";"); - - for (String sql : sqlStatements) { - sql = sql.trim(); - if (!sql.isEmpty()) { - stmt.executeUpdate(sql); - } - } - - generateInsertStatements(tableName, entry, stuDbUrl, user, password); - - } - } - } - } catch (SQLException e) { - e.printStackTrace(); - } - - try (Connection conn = DriverManager.getConnection(newDbUrl, user, password); - Statement stmt = conn.createStatement()) { - for (Map.Entry entry : result.entrySet()) { - - if (entry.getValue().trim().toUpperCase().startsWith("CREATE TABLE")) { - List examMysqlKeywordList =new ArrayList<>(); - appendToFile(answerLogPath, "==================建表语句=================="); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "==================建表语句=================="); - String answerId = null; - for (ExamQuestionAnswer examQuestionAnswer : examQuestionAnswers) { - if (normalize(examQuestionAnswer.getContent()).equals(normalize(entry.getValue()))) { - // 匹配成功 - answerId = examQuestionAnswer.getAnswerId(); - examMysqlKeywordList= examMysqlKeywordMapper.selectListByAnswerId(answerId); - break; - } - - } - // 正则表达式匹配表名 - Pattern pattern = Pattern.compile("CREATE TABLE\\s+`?(\\w+)`?\\s*\\("); - Matcher matcher = pattern.matcher(entry.getValue()); - - if (matcher.find()) { - String tableName = matcher.group(1).replace("`", ""); // 获取表名 - - - // 查询建表语句 - String showCreateTableSql = "SHOW CREATE TABLE " + tableName; - String sql = "SELECT COLUMN_NAME, COLUMN_TYPE, IS_NULLABLE, COLUMN_KEY, EXTRA " + - "FROM INFORMATION_SCHEMA.COLUMNS " + - "WHERE TABLE_NAME = '" + tableName + "' AND TABLE_SCHEMA = '" + databaseName + "'"; - String sql2 = "SELECT COLUMN_NAME, COLUMN_TYPE, IS_NULLABLE, COLUMN_KEY, EXTRA " + - "FROM INFORMATION_SCHEMA.COLUMNS " + - "WHERE TABLE_NAME = '" + tableName + "' AND TABLE_SCHEMA = '" + databaseNameStu + "'"; - - // 获取主库字段信息 - Set> table1Columns = new HashSet<>(); - try (ResultSet rs = stmt.executeQuery(sql)) { - while (rs.next()) { - Map column = new HashMap<>(); - column.put("COLUMN_NAME", rs.getString("COLUMN_NAME")); - column.put("COLUMN_TYPE", rs.getString("COLUMN_TYPE")); - column.put("IS_NULLABLE", rs.getString("IS_NULLABLE")); - column.put("COLUMN_KEY", rs.getString("COLUMN_KEY")); - column.put("EXTRA", rs.getString("EXTRA")); - table1Columns.add(column); - - } -// appendToFile(answerLogPath, "标准答案建表键值对:"+table1Columns); -// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "标准答案建表键值对:"+table1Columns); - - - } - // 获取学生库字段信息 - Set> table2Columns = new HashSet<>(); - try (Connection connstu = DriverManager.getConnection(stuDbUrl, user, password); - Statement stmtstu = connstu.createStatement()) { - try (ResultSet rsstu = stmtstu.executeQuery(sql2)) { - while (rsstu.next()) { - Map column = new HashMap<>(); - column.put("COLUMN_NAME", rsstu.getString("COLUMN_NAME")); - column.put("COLUMN_TYPE", rsstu.getString("COLUMN_TYPE")); - column.put("IS_NULLABLE", rsstu.getString("IS_NULLABLE")); - column.put("COLUMN_KEY", rsstu.getString("COLUMN_KEY")); - column.put("EXTRA", rsstu.getString("EXTRA")); - table2Columns.add(column); - } -// appendToFile(answerLogPath, "学生答案建表键值对:"+table2Columns); -// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "学生答案建表键值对:"+table2Columns); - - } - } - String sql3 = resultStu.get(entry.getKey()); - Matcher matcherStu = pattern.matcher(sql3); - String tableNameStu =""; - if (matcherStu.find()) { - tableNameStu= matcherStu.group(1).replace("`", ""); // 获取表名 - } - String yuju= compareTables(table1Columns, table2Columns, examQuestion.getTname(),tableName, tableNameStu,judgementStr); - judgementStr=yuju; - - if (table1Columns.equals(table2Columns)) { - // - SourceAndText studentScorePojo = accumulateScoreAndLog(examMysqlKeywordList,total,answerLogPath,sql3,totalKeyScore,score,answerId,scoreTotal,judgementStr); - scoreTotal += studentScorePojo.getScore(); - judgementStr = studentScorePojo.getText(); - } else { - SourceAndText studentScorePojo= calculateTotalScoreRate(sql3, examMysqlKeywordList,totalKeyScore,score,answerId,scoreTotal,judgementStr); - scoreTotal += studentScorePojo.getScore(); - judgementStr = studentScorePojo.getText(); - } - } - - } - - if (entry.getValue().trim().toUpperCase().startsWith("INSERT")) { - appendToFile(answerLogPath, "==================插入语句=================="); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "==================插入语句=================="); - List examMysqlKeywordList =new ArrayList<>(); - // 正则表达式匹配表名 - Pattern pattern = Pattern.compile("INSERT INTO\\s+`?(\\w+)`?\\s*\\("); - Matcher matcher = pattern.matcher(entry.getValue()); - appendToFile(answerLogPath, "正确语句: " + entry.getValue()); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "正确语句: " + entry.getValue()); - if (matcher.find()) { - String tableName = matcher.group(1).replace("`", ""); // 获取表名 - String answerId=null; - for (ExamQuestionAnswer examQuestionAnswer : examQuestionAnswers) { - if (normalize(examQuestionAnswer.getContent()).equals(normalize(entry.getValue()))) { - // 匹配成功 - answerId = examQuestionAnswer.getAnswerId(); - examMysqlKeywordList= examMysqlKeywordMapper.selectListByAnswerId(answerId); - break; - } - - } - // 获取 INSERT INTO 语句的表格数据并生成新的插入语句 - - generateInsertStatements(tableName, entry, newDbUrl, user, password); - String sql1 = result.get(entry.getKey()); - String sql2 = resultStu.get(entry.getKey()); - - - boolean equals = sql1.equals(sql2); - if (equals) { - SourceAndText studentScorePojo = accumulateScoreAndLog(examMysqlKeywordList,total,answerLogPath,sql2,totalKeyScore,score,answerId,scoreTotal,judgementStr); - scoreTotal += studentScorePojo.getScore(); - judgementStr = studentScorePojo.getText(); - } else { - SourceAndText studentScorePojo= calculateTotalScoreRate(sql2, examMysqlKeywordList,totalKeyScore,score,answerId,scoreTotal,judgementStr); - scoreTotal += studentScorePojo.getScore(); - judgementStr = studentScorePojo.getText(); - } - - - } - - - } - - if (entry.getValue().trim().toUpperCase().startsWith("DELETE")) { - appendToFile(answerLogPath, "==================删除语句=================="); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "==================删除语句=================="); - List 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()); - // 正则提取表名和 WHERE 条件 - Pattern pattern = Pattern.compile("DELETE\\s+FROM\\s+(\\w+)\\s+WHERE\\s+(.+)", Pattern.CASE_INSENSITIVE); - Matcher matcher = pattern.matcher(delStatement); - for (ExamQuestionAnswer examQuestionAnswer : examQuestionAnswers) { - if (normalize(examQuestionAnswer.getContent()).equals(normalize(entry.getValue()))) { - // 匹配成功 - answerId = examQuestionAnswer.getAnswerId(); - examMysqlKeywordList= examMysqlKeywordMapper.selectListByAnswerId(answerId); - break; - } - - } - if (matcher.find()) { - String tableName = matcher.group(1).trim(); - String whereClause = matcher.group(2).trim(); - MysqlServericeImpl.DeleteInfo deleteInfo = new MysqlServericeImpl.DeleteInfo(tableName, whereClause); -// appendToFile(answerLogPath, "提取出的表名: " + deleteInfo.tableName); -// appendToFile(answerLogPath, "提取出的条件: " + deleteInfo.whereClause); - // 构造验证 SQL - String verifySql = "SELECT COUNT(*) FROM " + deleteInfo.tableName + " WHERE " + deleteInfo.whereClause; -// appendToFile(answerLogPath, "验证 SQL: " + verifySql); - //查找正确答案的 -// try (Connection conn = DriverManager.getConnection(newDbUrl, user, password); -// Statement stmt = conn.createStatement()) { - try (ResultSet rs = stmt.executeQuery(verifySql)) { - if (rs.next()) { - int count = rs.getInt(1); - if (count == 0) { - try (Connection connstu = DriverManager.getConnection(stuDbUrl, user, password); - Statement stmtstu = connstu.createStatement()) { - try (ResultSet rsstu = stmtstu.executeQuery(verifySql)) { - if (rsstu.next()) { - int countstu = rsstu.getInt(1); - if (countstu == 0) { - //累加删除语句的所有权值 examQuestionKeywords累加scorerate - appendToFile(answerLogPath, "验证通过:符合 DELETE 条件的记录已删除。"); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "验证通过:符合 DELETE 条件的记录已删除。"); - SourceAndText studentScorePojo = accumulateScoreAndLog(examMysqlKeywordList,total,answerLogPath,sql2,totalKeyScore,score,answerId,scoreTotal,judgementStr); - scoreTotal += studentScorePojo.getScore(); - judgementStr = studentScorePojo.getText(); - - } else { - SourceAndText studentScorePojo= calculateTotalScoreRate(sql2, examMysqlKeywordList,totalKeyScore,score,answerId,scoreTotal,judgementStr); - scoreTotal += studentScorePojo.getScore(); - judgementStr = studentScorePojo.getText(); - } - } - }catch (SQLException e) { - appendToFile(answerLogPath, "验证学生库失败,"+"得分:0 ❌"); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "验证学生库失败,"+"得分:0 ❌"); - } - - } - - - } 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(); - } - - } - - } - - if (entry.getValue().trim().toUpperCase().startsWith("UPDATE")) { - appendToFile(answerLogPath, "==================更新语句=================="); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "==================更新语句=================="); - List 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()))) { - // 匹配成功 - answerId = examQuestionAnswer.getAnswerId(); - examMysqlKeywordList= examMysqlKeywordMapper.selectListByAnswerId(answerId); - break; - } - - } - //根据entry的key 获得resultStu 的value - - // 根据 key 获取另一个文件中的 SQL 语句 - String sql2 = resultStu.get(entry.getKey()); - - - boolean b = areUpdateStatementsEqual(sql1, sql2); - - // - if (b) { - SourceAndText studentScorePojo = accumulateScoreAndLog(examMysqlKeywordList,total,answerLogPath,sql2,totalKeyScore,score,answerId,scoreTotal,judgementStr); - scoreTotal += studentScorePojo.getScore(); - judgementStr = studentScorePojo.getText(); - - - - - } else { - SourceAndText studentScorePojo= calculateTotalScoreRate(sql2, examMysqlKeywordList,totalKeyScore,score,answerId,scoreTotal,judgementStr); - scoreTotal += studentScorePojo.getScore(); - judgementStr = studentScorePojo.getText(); - - } - - - } - if (entry.getValue().trim().toUpperCase().startsWith("SELECT")) { - appendToFile(answerLogPath, "==================查找语句=================="); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "==================查找语句=================="); - List examMysqlKeywordList =new ArrayList<>(); - String answerId =null; - for (ExamQuestionAnswer examQuestionAnswer : examQuestionAnswers) { - if (normalize(examQuestionAnswer.getContent()).equals(normalize(entry.getValue()))) { - // 匹配成功 - answerId = examQuestionAnswer.getAnswerId(); - examMysqlKeywordList= examMysqlKeywordMapper.selectListByAnswerId(answerId); - break; - } - - } - String sql1 = entry.getValue(); - appendToFile(answerLogPath, "正确语句: " + sql1); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "正确语句: " + sql1); - String sql2 = resultStu.get(entry.getKey()); - - - List> answerList= new ArrayList<>(); - List> answerListStu = new ArrayList<>(); - try (Connection connanswer = DriverManager.getConnection(newDbUrl, user, password); - Statement stmtan = connanswer.createStatement()) { - try (ResultSet answer = stmtan.executeQuery(sql1)) { - answerList = getAnswerList(answer); - appendToFile(answerLogPath, "查找语句标准答案"); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "查找语句标准答案"); - printResult(answerList,judgementStr); - }catch (SQLException e) { - appendToFile(answerLogPath, "执行验证语句"+sql1+"时发生错误: " + e.getMessage()); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "执行验证语句"+sql1+"时发生错误: " + e.getMessage()); - e.printStackTrace(); - } - } - try (Connection connstu = DriverManager.getConnection(stuDbUrl, user, password); - Statement stmtstu = connstu.createStatement()) { - try (ResultSet answer = stmtstu.executeQuery(sql2)) { - answerListStu = getAnswerList(answer); - appendToFile(answerLogPath, "学生语句答案"); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "学生语句答案"); - printResult(answerListStu,judgementStr); - } catch (SQLException e) { - appendToFile(answerLogPath, "执行学生库语句"+sql2+"时发生错误: " + e.getMessage()); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "执行学生库语句"+sql2+"时发生错误: " + e.getMessage()); - } - - - } - boolean isEquivalent =false; - - if (answerListStu!=null&&answerListStu.size()>0){ - isEquivalent = compareResultsSelect(answerList, answerListStu); - } - - if (isEquivalent) { - //todo 得分 - SourceAndText studentScorePojo = accumulateScoreAndLog(examMysqlKeywordList,total,answerLogPath,sql2,totalKeyScore,score,answerId,scoreTotal,judgementStr); - scoreTotal += studentScorePojo.getScore(); - judgementStr = studentScorePojo.getText(); - - } else { - SourceAndText studentScorePojo= calculateTotalScoreRate(sql2, examMysqlKeywordList,totalKeyScore,score,answerId,scoreTotal,judgementStr); - scoreTotal += studentScorePojo.getScore(); - judgementStr = studentScorePojo.getText(); - - } - - - } - - - 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 examMysqlKeywordList =new ArrayList<>(); - String answerId=null; - for (ExamQuestionAnswer examQuestionAnswer : examQuestionAnswers) { - if (normalize(examQuestionAnswer.getContent()).equals(normalize(entry.getValue()))) { - // 匹配成功 - answerId = examQuestionAnswer.getAnswerId(); - examMysqlKeywordList= examMysqlKeywordMapper.selectListByAnswerId(answerId); - break; - } - - } - String sql1 = entry.getValue(); - appendToFile(answerLogPath, "正确语句: " + sql1); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "正确语句: " + sql1); - String sql2 = resultStu.get(entry.getKey()); - // 正则表达式,用于匹配 "VIEW" 后面的视图名称 - String regex = "(?<=VIEW\\s)([\\w`_]+)"; - String sqlviewAnswer = removeComments(sql1); - String sqlviewAnswerStu = removeComments(sql2); - - if (StringUtils.isNotBlank(sqlviewAnswerStu)) { - // 从第一个 SQL 语句中提取视图名称 - String viewNam1 = extractViewName(sqlviewAnswer, regex); - // 从第二个 SQL 语句中提取视图名称 - String viewNam2 = extractViewName(sqlviewAnswerStu, regex); - // 随机生成视图名称 - String viewName1 = "v_education_" + UUID.randomUUID().toString().replace("-", ""); - String viewName2 = "v_education_2_" + UUID.randomUUID().toString().replace("-", ""); - - - // 替换 SQL 语句中的视图名称 - String createView1 = sqlviewAnswer.replace(viewNam1, viewName1); - String createView2 = sqlviewAnswerStu.replace(viewNam2, viewName2); - - -// try (Connection conn = DriverManager.getConnection(newDbUrl, user, password); -// Statement stmt = conn.createStatement()) { - - - // 执行 CREATE VIEW 语句,创建视图 - stmt.execute(createView1); - - boolean hasError = false; // 添加标志变量 - try { - stmt.execute(createView2); - - } 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> result1 = executeQuery(stmt, sql3); - printResult(result1,judgementStr); - // 执行查询,获取视图2的结果 - appendToFile(answerLogPath, "执行考生视图语句的查询结果:"); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "执行考生视图语句的查询结果:"); - String sql4 = "SELECT * FROM " + viewName2; - List> result2 = executeQuery(stmt, sql4); - printResult(result2,judgementStr); - - // 比较两个视图的结果 - boolean isEquivalent = !hasError &&compareResults(result1, result2); - appendToFile(answerLogPath, "\n是否结果等价: " + isEquivalent); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "\n是否结果等价: " + isEquivalent); - - // 删除视图 - System.out.println("\n删除视图 " + viewName1 + " 和 " + viewName2 + "..."); - stmt.execute("DROP VIEW IF EXISTS " + viewName1); - stmt.execute("DROP VIEW IF EXISTS " + viewName2); - if (isEquivalent) { - SourceAndText studentScorePojo = accumulateScoreAndLog(examMysqlKeywordList,total,answerLogPath,sql2,totalKeyScore,score,answerId,scoreTotal,judgementStr); - scoreTotal += studentScorePojo.getScore(); - judgementStr = studentScorePojo.getText(); - - - - - } else { - SourceAndText studentScorePojo= calculateTotalScoreRate(sql2, examMysqlKeywordList,totalKeyScore,score,answerId,scoreTotal,judgementStr); - scoreTotal += studentScorePojo.getScore(); - judgementStr = studentScorePojo.getText(); - } -// } - - - } - } - - //存储过程 - if (entry.getValue().trim().toUpperCase().toUpperCase().contains("PROCEDURE")) { - String answerId=null; - List examMysqlKeywordList =new ArrayList<>(); - for (ExamQuestionAnswer examQuestionAnswer : examQuestionAnswers) { - if (normalize(examQuestionAnswer.getContent()).equals(normalize(entry.getValue()))) { - // 匹配成功 - answerId = examQuestionAnswer.getAnswerId(); - examMysqlKeywordList= examMysqlKeywordMapper.selectListByAnswerId(answerId); - break; - } - - } - 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 extractCallStatements = extractCallStatements(sql1); - //标准答案 集合 - List> anwerResults = new ArrayList<>(); - //考生答案 集合 - List> stuResults = new ArrayList<>(); - if (extractCallStatements != null && extractCallStatements.size() > 0) { - 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); -// Statement stmt = conn.createStatement()) { - ResultSet newResult = stmt.executeQuery(extractCallStatement); - anwerResults.addAll(extractResults(newResult)); -// } - } catch (SQLException e) { - appendToFile(answerLogPath, "执行标准库 SQL CALL 语句时发生错误: " + e.getMessage()); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "执行标准库 SQL CALL 语句时发生错误: " + e.getMessage()); - } - - - try (Connection connstu = DriverManager.getConnection(stuDbUrl, user, password); - Statement stmtstu = connstu.createStatement()) { - stmtstu.execute(sql2); // 创建存储过程 - - - try { - - ResultSet oldResult = stmtstu.executeQuery(extractCallStatement); - stuResults.addAll(extractResults(oldResult)); - } catch (SQLException e) { - appendToFile(answerLogPath, "执行学生库 SQL CALL 语句时发生错误: " + e.getMessage()); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "执行学生库 SQL CALL 语句时发生错误: " + e.getMessage()); - hasError = true; // 发生异常,设为 true - } - - - - - } catch (SQLException e) { - appendToFile(answerLogPath, "执行学生库语句"+sql2+"时发生错误: " + e.getMessage()); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "执行学生库语句"+sql2+"时发生错误: " + e.getMessage()); - hasError = true; // 发生异常,设为 true - } - - } - // 比较结果(如果发生异常,可以认为比较失败) - boolean flag = !hasError && compareExtractResults(anwerResults, stuResults,judgementStr); - - if (flag) { - //todo 得分 - SourceAndText studentScorePojo = accumulateScoreAndLog(examMysqlKeywordList,total,answerLogPath,sql2,totalKeyScore,score,answerId,scoreTotal,judgementStr); - scoreTotal += studentScorePojo.getScore(); - judgementStr = studentScorePojo.getText(); - - } else { - //得分 - SourceAndText studentScorePojo = calculateTotalScoreRate(sql2, examMysqlKeywordList, totalKeyScore, score, answerId, scoreTotal,judgementStr); - scoreTotal += studentScorePojo.getScore(); - judgementStr = studentScorePojo.getText(); - - } - } else { - appendToFile(answerLogPath, "此存储过程无 CALL 语句"); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "此存储过程无 CALL 语句"); - } - } - if (entry.getValue().trim().toUpperCase().toUpperCase().contains("TRIGGER")) { - appendToFile(answerLogPath, "==================触发器=================="); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "==================触发器=================="); - List examMysqlKeywordList =new ArrayList<>(); - String answerId=null; - for (ExamQuestionAnswer examQuestionAnswer : examQuestionAnswers) { - if (normalize(examQuestionAnswer.getContent()).equals(normalize(entry.getValue()))) { - // 匹配成功 - answerId = examQuestionAnswer.getAnswerId(); - examMysqlKeywordList= examMysqlKeywordMapper.selectListByAnswerId(answerId); - break; - } - - } - String sql1 = entry.getValue(); - appendToFile(answerLogPath, "正确语句: " + sql1); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "正确语句: " + sql1); - String sql2 = resultStu.get(entry.getKey()); - - // 清洗触发器语句(去除注释等) - String triggerStatementCleanSql1 = cleanProcedureSQL(sql1); - - // 标准化触发器内容(去空格、换行、小写) - String normalizedTriggerSql1 = triggerStatementCleanSql1.trim().replaceAll("\\s+", "").toLowerCase(); - - - // 清洗触发器语句(去除注释等) - String triggerStatementCleanSql2 = cleanProcedureSQL(sql2); - - // 标准化触发器内容(去空格、换行、小写) - String normalizedTriggerSql2 = triggerStatementCleanSql2.trim().replaceAll("\\s+", "").toLowerCase(); - - boolean equals = normalizedTriggerSql1.equals(normalizedTriggerSql2); - if (equals) { - //todo 得分 - SourceAndText studentScorePojo = accumulateScoreAndLog(examMysqlKeywordList, total, answerLogPath, sql2, totalKeyScore, score, answerId, scoreTotal,judgementStr); - scoreTotal += studentScorePojo.getScore(); - judgementStr = studentScorePojo.getText(); - - } else { - SourceAndText studentScorePojo = calculateTotalScoreRate(sql2, examMysqlKeywordList, totalKeyScore, score, answerId, scoreTotal,judgementStr); - scoreTotal += studentScorePojo.getScore(); - judgementStr = studentScorePojo.getText(); - - - } - - - } - - - } - // try (Connection conn = DriverManager.getConnection(newDbUrl, user, password); -// Statement stmt = conn.createStatement()) { - //删除临时创建的数据库databaseName - String dropDbSql = "DROP DATABASE " + databaseName; - stmt.executeUpdate(dropDbSql); - String dropDbSql2 = "DROP DATABASE " + databaseNameStu; - stmt.executeUpdate(dropDbSql2); -// } - } - } - double roundedResult =0.0; - - appendToFile(answerLogPath, "共得分:" + String.format("%.2f", scoreTotal)); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "共得分:" + String.format("%.2f", scoreTotal)); - folderzip.delete(); - deleteFolder(folder); - sourceAndText.setScore(scoreTotal); - sourceAndText.setText(judgementStr); - return sourceAndText; - } - - private static String compareTables(Set> standardSet, Set> studentSet, String dbTable, String tableName,String tableNameStu,String judgementStr) { - int index = 1; - // 判断表名是否一致 - String tableNameCheck = tableName.equalsIgnoreCase(tableNameStu) ? "✔" : "x"; - // 输出 - System.out.printf("%02d.【数据表】【%s】【名称】【%s】【%s】\n", index, dbTable, tableName, tableNameCheck); - appendToFile(answerLogPath, "%02d.【数据表】【%s】【名称】【%s】【%s】\n", index, dbTable, tableName, tableNameCheck); - judgementStr = HtmlAppender.appendHtmlLineMysql(judgementStr, "%02d.【数据表】【%s】【名称】【%s】【%s】\n", index, dbTable, tableName, tableNameCheck); - // 把Set转成Map,方便通过字段名快速取值 - Map> standardMap = convertSetToMap(standardSet); - Map> studentMap = convertSetToMap(studentSet); - - for (String columnName : standardMap.keySet()) { - Map stdCol = standardMap.get(columnName); - Map stuCol = studentMap.get(columnName); - - String fullName = dbTable + "." + columnName; - - String nameCheck = stuCol != null ? "✔" : "x"; - System.out.printf("%02d.【字段】【%s】【名称】【%s】【%s】\n", ++index, fullName, columnName, nameCheck); - judgementStr = HtmlAppender.appendHtmlLineMysql(judgementStr, "%02d.【字段】【%s】【名称】【%s】【%s】\n", index, fullName, columnName, nameCheck); - appendToFile(answerLogPath, "%02d.【字段】【%s】【名称】【%s】【%s】\n", index, fullName, columnName, nameCheck); - - if (stuCol != null) { - MysqlVo mysqlVo1 = compareField(index, fullName, "类型", stdCol.get("COLUMN_TYPE"), stuCol.get("COLUMN_TYPE"),judgementStr); - index=mysqlVo1.getIndex(); - judgementStr=mysqlVo1.getText(); - MysqlVo mysqlVo2 = compareField(index, fullName, "允许为空", stdCol.get("IS_NULLABLE"), stuCol.get("IS_NULLABLE"),judgementStr); - index=mysqlVo2.getIndex(); - judgementStr=mysqlVo2.getText(); - MysqlVo mysqlVo3 = compareField(index, fullName, "扩展", stdCol.get("EXTRA"), stuCol.get("EXTRA"),judgementStr); - index=mysqlVo3.getIndex(); - judgementStr=mysqlVo3.getText(); - MysqlVo mysqlVo4 = compareField(index, fullName, "键类型", stdCol.get("COLUMN_KEY"), stuCol.get("COLUMN_KEY"),judgementStr); - judgementStr=mysqlVo4.getText(); - } else { - // 缺失字段,直接输出所有属性错误 - MysqlVo mysqlVo1 = printMissing(index, fullName, "类型", stdCol.get("COLUMN_TYPE"),judgementStr); - index=mysqlVo1.getIndex(); - judgementStr=mysqlVo1.getText(); - MysqlVo mysqlVo2 = printMissing(index, fullName, "允许为空", stdCol.get("IS_NULLABLE"),judgementStr); - index=mysqlVo2.getIndex(); - judgementStr=mysqlVo2.getText(); - MysqlVo mysqlVo3 = printMissing(index, fullName, "扩展", stdCol.get("EXTRA"),judgementStr); - index=mysqlVo3.getIndex(); - judgementStr=mysqlVo3.getText(); - MysqlVo mysqlVo4 = printMissing(index, fullName, "键类型", stdCol.get("COLUMN_KEY"),judgementStr); - judgementStr=mysqlVo4.getText(); - } - } - return judgementStr; - } - - private static MysqlVo compareField(int index, String fullName, String property, String stdValue, String stuValue, String judgementStr) { - MysqlVo mysqlVo=new MysqlVo(); - String mark = stdValue.equalsIgnoreCase(stuValue) ? "✔" : "x"; - System.out.printf("%02d.【字段】【%s】【%s】【%s】【%s】\n", index + 1, fullName, property, stuValue, mark); - appendToFile(answerLogPath, "%02d.【字段】【%s】【%s】【%s】【%s】\n", index + 1, fullName, property, stuValue, mark); - judgementStr = HtmlAppender.appendHtmlLineMysql(judgementStr, "%02d.【字段】【%s】【%s】【%s】【%s】\n", index + 1, fullName, property, stuValue, mark); - mysqlVo.setText(judgementStr); - mysqlVo.setIndex(index + 1); - return mysqlVo; - } - - private static MysqlVo printMissing(int index, String fullName, String property, String stdValue,String judgementStr) { - MysqlVo mysqlVo=new MysqlVo(); - System.out.printf("%02d.【字段】【%s】【%s】【%s】【x】\n", index + 1, fullName, property, stdValue); - appendToFile(answerLogPath, "%02d.【字段】【%s】【%s】【%s】【x】\n", index + 1, fullName, property, stdValue); - judgementStr = HtmlAppender.appendHtmlLineMysql(judgementStr, "%02d.【字段】【%s】【%s】【%s】【x】\n", index + 1, fullName, property, stdValue); - mysqlVo.setText(judgementStr); - mysqlVo.setIndex(index + 1); - return mysqlVo; - } - - private static Map> convertSetToMap(Set> set) { - Map> map = new LinkedHashMap<>(); - for (Map column : set) { - map.put(column.get("COLUMN_NAME"), column); - } - return map; - } - public static void deleteFolder(File folder) { - if (folder.isDirectory()) { - File[] files = folder.listFiles(); - if (files != null) { - for (File file : files) { - deleteFolder(file); // 递归删除所有子文件/文件夹 - } - } - } - folder.delete(); // 删除空文件夹或文件 - } - //如果这个小题对了,直接累加对应的权值分 - private SourceAndText accumulateScoreAndLog(List examMysqlKeywordList, AtomicInteger total, String answerLogPath, String sql2, String totalKeyScore, double score,String answerId,double scoreTotal,String judgementStr) { - SourceAndText sourceAndText = new SourceAndText(); - if(StringUtils.isBlank(answerId)){ - appendToFile(answerLogPath, "❌该语句找不到试题id,请检查出题内容!" ); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "❌该语句找不到试题id,请检查出题内容!"); - sourceAndText.setText(judgementStr); - sourceAndText.setScore(0.0); - //返回累加的总分 - return sourceAndText; - } - //用answerid查对应答案的权值 。除以总权值 - String scoreRateStr= examQuestionAnswerMapper.selectExamQuestionAnswerScoreByAnswerId(answerId); - - // 解析权值 - double scoreRate = 0.0; - double totalKey = 0.0; - double singleScore = 0.0; - try { - scoreRate = Double.parseDouble(scoreRateStr); - totalKey = Double.parseDouble(totalKeyScore); - // 计算该答案对应的得分 - - if (totalKey > 0) { - singleScore = (scoreRate / totalKey) * score; - singleScore = Math.round(singleScore * 100.0) / 100.0; - System.out.println(scoreTotal); - System.out.println(singleScore); - - System.out.println(scoreTotal); - - } - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "✅学生语句" + sql2 + "正确,语句得分权值:" + scoreRateStr + ",得分" + singleScore); - appendToFile(answerLogPath, "✅学生语句" + sql2 + "正确,语句得分权值:" + scoreRateStr + ",得分" + singleScore); - } catch (NumberFormatException e) { - System.err.println("无效的totalKeyScore值:" + totalKeyScore); - } - sourceAndText.setText(judgementStr); - sourceAndText.setScore(singleScore); - //返回累加的总分 - return sourceAndText; - - } - - - public SourceAndText calculateTotalScoreRate(String sql, List examQuestionKeywords, String totalKeyScore, double score,String answerId,double scoreTotal,String judgementStr) { - SourceAndText sourceAndText = new SourceAndText(); - if(StringUtils.isBlank(answerId)){ - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "❌该语句找不到试题id,请检查出题内容!"); - appendToFile(answerLogPath, "❌该语句找不到试题id,请检查出题内容!" ); - sourceAndText.setText(judgementStr); - sourceAndText.setScore(0.0); - //返回累加的总分 - return sourceAndText; - } - //用answerid查对应答案的权值 。除以总权值 - String scoreRateStr= examQuestionAnswerMapper.selectExamQuestionAnswerScoreByAnswerId(answerId); - - - - // 解析权值 - double scoreRate = 0.0; - double totalKey = 0.0; - // 计算该答案对应的得分 - double singleScore = 0.0; - try { - scoreRate = Double.parseDouble(scoreRateStr); - totalKey = Double.parseDouble(totalKeyScore); - - if (totalKey > 0) { - singleScore = (scoreRate / totalKey) * score; - singleScore = Math.round(singleScore * 100.0) / 100.0; - } - - - - } catch (NumberFormatException e) { - System.err.println("无效的totalKeyScore值:" + totalKeyScore); - } - - - int totalScoreRate = 0; - Set matchedKeywords = new HashSet<>(); - for (ExamMysqlKeyword keyword : examQuestionKeywords) { - String keywordValue = keyword.getKeyword(); - if (keywordValue != null && !keywordValue.isEmpty() && !matchedKeywords.contains(keywordValue)) { - // 使用正则,确保是完整单词(字段)匹配 - String regex = keywordValue; - if (sql.contains(regex)) { - try { - totalScoreRate += Integer.parseInt(keyword.getScoreRate()); - - matchedKeywords.add(keywordValue); - } catch (NumberFormatException e) { - System.err.println("Invalid scoreRate format for keyword: " + keywordValue); - } - } - } - } - //累加答案关键字的所有权值 - int totalKeyScoreInt = examQuestionKeywords.stream() - .map(ExamMysqlKeyword::getScoreRate) - .filter(s -> s != null && !s.isEmpty()) - .mapToInt(Integer::parseInt) - .sum(); - - //乘以 对了多少个 关键字 权值 - double finalRoundedScore; - if (totalKeyScoreInt == 0) { - // 如果总键值为0,可以设置为0或其他默认值 - finalRoundedScore = 0.0; - } else { - finalRoundedScore = new BigDecimal( - ((double) totalScoreRate / totalKeyScoreInt) * singleScore - ).setScale(2, RoundingMode.HALF_UP).doubleValue(); - } - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "❌学生语句"+sql+"不正确,语句权值:"+scoreRateStr+",关键权值:"+totalKeyScoreInt+",答对得分点为:"+matchedKeywords+",答对关键得分权值"+ totalScoreRate+ ",得分" + finalRoundedScore); - - appendToFile(answerLogPath,"❌学生语句"+sql+"不正确,语句权值:"+scoreRateStr+",关键权值:"+totalKeyScoreInt+",答对得分点为:"+matchedKeywords+",答对关键得分权值"+ totalScoreRate+ ",得分" + finalRoundedScore); - sourceAndText.setText(judgementStr); - sourceAndText.setScore(finalRoundedScore); - //返回累加的总分 - return sourceAndText; - } - - // 预处理函数:去除空格和换行并转为大写 - private static String normalize(String str) { - return str.replaceAll("\\s+", "").toUpperCase(); - } - - public static String cleanProcedureSQL(String sql) { - // 删除 DELIMITER 和 $$ 标记 - sql = sql.replaceAll("(?i)DELIMITER\\s+\\$\\$", ""); // 删除 DELIMITER $$ - sql = sql.replaceAll("(?i)DELIMITER\\s+;", ""); // 删除 DELIMITER ; - sql = sql.replaceAll("\\$\\$", ""); // 删除结尾 $$ - - // 删除 CALL 语句(例如 CALL pro_xxx(...);) - sql = sql.replaceAll("(?i)CALL\\s+[^;]+;", ""); // 删除 CALL 语句(不区分大小写) - - return sql.trim(); // 去除首尾空格 - } - public static class DeleteInfo { - public String tableName; - public String whereClause; - - public DeleteInfo(String tableName, String whereClause) { - this.tableName = tableName; - this.whereClause = whereClause; - } - } - // 标准化 SQL 字符串 - public static String simplifyCreateTableSql(String sql) { - if (sql == null || sql.isEmpty()) return sql; - - // 移除字段中的 CHARACTER SET 和 COLLATE - sql = sql.replaceAll("(?i)CHARACTER SET\\s+\\w+", ""); - sql = sql.replaceAll("(?i)COLLATE\\s+\\w+", ""); - - // 移除主键中的 USING BTREE - sql = sql.replaceAll("(?i)USING\\s+BTREE", ""); - - // 移除表级 ENGINE、AUTO_INCREMENT、CHARSET、COLLATE、ROW_FORMAT - sql = sql.replaceAll("(?i)ENGINE\\s*=\\s*\\w+", ""); - sql = sql.replaceAll("(?i)AUTO_INCREMENT\\s*=\\s*\\d+", ""); - sql = sql.replaceAll("(?i)(DEFAULT\\s+)?CHARSET\\s*=\\s*\\w+", ""); - sql = sql.replaceAll("(?i)CHARACTER SET\\s*=\\s*\\w+", ""); - sql = sql.replaceAll("(?i)ROW_FORMAT\\s*=\\s*\\w+", ""); - sql = sql.replaceAll("(?i)COLLATE\\s*=\\s*\\w+", ""); - - // 清理多余逗号与空格 - sql = sql.replaceAll(",\\s*\\)", "\n)"); - sql = sql.replaceAll(" +", " "); - sql = sql.replaceAll("(?m)^\\s*$", ""); // 清除空行 - sql = sql.trim(); - - return sql; - } - - - // 比较两个结果集 - private static boolean compareExtractResults(List> newResults, List> oldResults,String judgementStr) { - appendToFile(answerLogPath,"==== 标准答案 ===="); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "==== 标准答案 ===="); - for (Map row : newResults) { - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, row.toString()); - appendToFile(answerLogPath,row.toString()); - } - appendToFile(answerLogPath,"==== 考生答案 ===="); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "==== 考生答案 ===="); - for (Map row : oldResults) { - appendToFile(answerLogPath,row.toString()); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, row.toString()); - } - - if (newResults.size() != oldResults.size()) { - appendToFile(answerLogPath,"❌考生答案与标准答案个数不对"); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "❌考生答案与标准答案个数不对"); - return false; - } - - // 不比较顺序,直接判断两个列表内容是否一样(将其转换为 Set) - Set> newSet = new HashSet<>(newResults); - Set> oldSet = new HashSet<>(oldResults); - - if (!newSet.equals(oldSet)) { - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "❌ 内容相同但顺序不同,或存在差异:"); - appendToFile(answerLogPath,"❌ 内容相同但顺序不同,或存在差异:"); - Set> onlyInNew = new HashSet<>(newSet); - onlyInNew.removeAll(oldSet); - - Set> onlyInOld = new HashSet<>(oldSet); - onlyInOld.removeAll(newSet); - - for (Map row : onlyInNew) { - appendToFile(answerLogPath,"⚠️ 标准答案中有但考生答案中没有: " + row); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "⚠️ 标准答案中有但考生答案中没有: " + row); - } - - for (Map row : onlyInOld) { - appendToFile(answerLogPath,"⚠️ 考生答案中有但标准答案中没有: " + row); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "⚠️ 考生答案中有但标准答案中没有: " + row); - } - - return false; - } - appendToFile(answerLogPath,"两个结果集内容一致(不考虑顺序)!"); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "两个结果集内容一致(不考虑顺序)!"); - return true; - } - - - // 提取ResultSet中的结果到一个列表中 - private static List> extractResults(ResultSet resultSet) throws SQLException { - List> results = new ArrayList<>(); - - // 获取列数 - ResultSetMetaData metaData = resultSet.getMetaData(); - int columnCount = metaData.getColumnCount(); - - while (resultSet.next()) { - Map row = new HashMap<>(); - for (int i = 1; i <= columnCount; i++) { - String columnName = metaData.getColumnLabel(i); - Object value = resultSet.getObject(i); - row.put(columnName, value); - } - results.add(row); - } - - return results; - } - - - - public static List extractCallStatements(String sql) { - List callStatements = new ArrayList<>(); - Pattern callPattern = Pattern.compile("CALL\\s+\\w+\\s*\\([^;]*?\\);", Pattern.CASE_INSENSITIVE); - Matcher matcher = callPattern.matcher(sql); - - while (matcher.find()) { - callStatements.add(matcher.group()); - } - - return callStatements; - } - - - /** - * 比较两个查询的结果 - */ - private static boolean compareResults(List> result1, List> result2) { - // 获取列名并比较(顺序无关) - List columnNames1 = result1.get(0); - List columnNames2 = result2.get(0); - - // 检查列名是否一致(顺序无关) - Set columnSet1 = new HashSet<>(columnNames1); - Set columnSet2 = new HashSet<>(columnNames2); - if (!columnSet1.equals(columnSet2)) { - return false; - } - - // 获取数据行(去除列名) - List> rows1 = result1.subList(1, result1.size()); - List> rows2 = result2.subList(1, result2.size()); - - // 使用 Set 存储每行数据并比较 - Set> rowSet1 = new HashSet<>(); - for (List row : rows1) { - rowSet1.add(new HashSet<>(row)); - } - - Set> rowSet2 = new HashSet<>(); - for (List row : rows2) { - rowSet2.add(new HashSet<>(row)); - } - - // 比较行数据(无顺序) - return rowSet1.equals(rowSet2); - } - /** - * 执行 SQL 查询并返回结果 - */ - private static List> executeQuery(Statement stmt, String sql) throws SQLException { - List> result = new ArrayList<>(); - - - try { - - ResultSet rs = stmt.executeQuery(sql); - // 获取列数和列名 - ResultSetMetaData metaData = rs.getMetaData(); - int columnCount = metaData.getColumnCount(); - - // 获取列名 - List columnNames = new ArrayList<>(); - for (int i = 1; i <= columnCount; i++) { - columnNames.add(metaData.getColumnLabel(i)); - } - result.add(columnNames); // 将列名添加为结果的第一行 - - // 遍历结果集 - while (rs.next()) { - List row = new ArrayList<>(); - for (int i = 1; i <= columnCount; i++) { - row.add(rs.getString(i)); - } - result.add(row); - } - } catch (SQLException e) { - appendToFile(answerLogPath, "执行学生库 SQL CALL 语句时发生错误: " + e.getMessage()); - } - - - return result; - } - // 去除 SQL 中的注释部分 - private static String removeComments(String sql) { - // 正则表达式匹配 SQL 中以 -- 开头的注释 - return sql.replaceAll("(?m)^[\\s]*--.*$", ""); - } - /** - * 比较两个查询的结果 - */ - private static boolean compareResultsSelect(List> result1, List> result2) { - // 获取列名并比较(顺序无关) - List columnNames1 = result1.get(0); - List columnNames2 = result2.get(0); - - // 检查列名是否一致(顺序无关) - Set columnSet1 = new HashSet<>(columnNames1); - Set columnSet2 = new HashSet<>(columnNames2); - if (!columnSet1.equals(columnSet2)) { - return false; - } - - // 获取数据行(去除列名) - List> rows1 = result1.subList(1, result1.size()); - List> rows2 = result2.subList(1, result2.size()); - - // 使用 Set 存储每行数据并比较 - Set> rowSet1 = new HashSet<>(); - for (List row : rows1) { - rowSet1.add(new HashSet<>(row)); - } - - Set> rowSet2 = new HashSet<>(); - for (List row : rows2) { - rowSet2.add(new HashSet<>(row)); - } - - // 比较行数据(无顺序) - return rowSet1.equals(rowSet2); - } - /** - * 打印查询结果 - */ - private static void printResult(List> result,String judgementStr) { - if (result.isEmpty()) { - appendToFile(answerLogPath, "查询结果为空"); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "查询结果为空"); - - } else { - for (int i = 0; i < result.size(); i++) { - List row = result.get(i); - StringBuilder sb = new StringBuilder(); - - if (i == 0) { - sb.append("列名:"); - } - - for (String value : row) { - sb.append(value).append("\t"); - } - - // 输出整行 - appendToFile(answerLogPath, sb.toString()); - judgementStr = HtmlAppender.appendHtmlLine(judgementStr, sb.toString()); - } - } - } - - /** - * 使用提供的正则表达式模式从给定的 SQL 语句中提取视图名称。 - */ - private static String extractViewName(String sql, String regex) { - Pattern pattern = Pattern.compile(regex); - Matcher matcher = pattern.matcher(sql); - - // 如果找到匹配项,返回匹配到的视图名称 - if (matcher.find()) { - return matcher.group(1).replace("`", ""); // 如果有反引号(`),则移除 - } else { - return "未找到视图名称"; - } - } - - private static List> getAnswerList(ResultSet answer) throws SQLException { - List> result = new ArrayList<>(); - // 获取列数和列名 - ResultSetMetaData metaData = answer.getMetaData(); - int columnCount = metaData.getColumnCount(); - - // 获取列名 - List columnNames = new ArrayList<>(); - for (int i = 1; i <= columnCount; i++) { - columnNames.add(metaData.getColumnLabel(i)); - } - result.add(columnNames); // 将列名添加为结果的第一行 - - // 遍历结果集 - while (answer.next()) { - List row = new ArrayList<>(); - for (int i = 1; i <= columnCount; i++) { - row.add(answer.getString(i)); - } - result.add(row); - } - - return result; - - } - - - - public static void generateInsertStatements(String tableName, Map.Entry entry, String newDbUrl, String user, String password) { - // 确保 entry 里包含的是 INSERT 语句 - if (entry.getValue().trim().toUpperCase().startsWith("INSERT")) { - System.out.println("==================插入语句=================="); - // 创建一个列表来存储所有的 INSERT INTO 语句 - List insertQueries = new ArrayList<>(); - try (Connection conn = DriverManager.getConnection(newDbUrl, user, password); - Statement stmt = conn.createStatement()) { - - // 查询表的所有列 - String columnsQuery = "DESCRIBE " + tableName; - - try (ResultSet columnsRs = stmt.executeQuery(columnsQuery)) { - List columnNames = new ArrayList<>(); - while (columnsRs.next()) { - String columnName = columnsRs.getString("Field"); - columnNames.add(columnName); - } - - // 获取表的数据并生成 INSERT INTO 语句 - String selectQuery = "SELECT * FROM " + tableName; - try (ResultSet dataRs = stmt.executeQuery(selectQuery)) { - - while (dataRs.next()) { - StringBuilder insertQuery = new StringBuilder("INSERT INTO `" + tableName + "` ("); - - // 构建列名部分 - for (int i = 0; i < columnNames.size(); i++) { - insertQuery.append("`").append(columnNames.get(i)).append("`"); - if (i < columnNames.size() - 1) { - insertQuery.append(", "); - } - } - insertQuery.append(") VALUES ("); - - // 构建值部分 - for (int i = 0; i < columnNames.size(); i++) { - Object value = dataRs.getObject(columnNames.get(i)); - if (value == null) { - insertQuery.append("NULL"); - } else if (value instanceof String) { - insertQuery.append("'").append(value.toString().replace("'", "''")).append("'"); - } else { - insertQuery.append(value); - } - - if (i < columnNames.size() - 1) { - insertQuery.append(", "); - } - } - insertQuery.append(");"); - // 将生成的 INSERT INTO 语句添加到列表中 - insertQueries.add(insertQuery.toString()); - // 输出生成的 INSERT INTO 语句 - System.out.println(insertQuery.toString()); - } - - } - catch (SQLException e) { - System.err.println("生成插入语句失败,表名:" + tableName); - e.printStackTrace(); - } - } - } catch (SQLException e) { - System.err.println("生成插入语句失败,表名:" + tableName); - e.printStackTrace(); - } - // 将列表赋值给 entry 的值 - entry.setValue(insertQueries.toString()); - System.out.println(entry.getValue()); - } - } - - /** - * 读取指定目录下所有文件,返回一个文件名到文件内容的键值对Map - * @param directoryPath 文件夹路径 - * @return Map<文件名, 文件内容> - * @throws IOException 读取文件异常 - */ - public static Map readFilesAsMap(String directoryPath) throws IOException { - Map fileContentMap = new HashMap<>(); - - Path dirPath = Paths.get(directoryPath); - if (!Files.isDirectory(dirPath)) { - throw new IllegalArgumentException("路径不是一个有效的目录: " + directoryPath); - } - - try (DirectoryStream stream = Files.newDirectoryStream(dirPath)) { - for (Path path : stream) { - if (Files.isRegularFile(path)) { - String fileName = path.getFileName().toString(); - String content = new String(Files.readAllBytes(path)); - fileContentMap.put(fileName, content); - } - } - } - - return fileContentMap; - } - - - /** - * 通过命令行执行 SQL 文件 - */ - public static boolean executeSqlFileUsingCommandLine(String sqlFilePath, String dbName, String user, String password) { - try { - // 拼接命令 - String[] command = { - "mysql", - "-u" + user, - "-p" + password, - "-h", "rm-bp1a44uap1mm20980mo.mysql.rds.aliyuncs.com", - "-P", "3306", - dbName, - "-e", "source " + sqlFilePath - }; - - // 启动进程 - Process process = Runtime.getRuntime().exec(command); - int exitCode = process.waitFor(); - - return exitCode == 0; - } catch (Exception e) { - e.printStackTrace(); - return false; - } - } -// private static boolean executeSqlFileUsingCommandLine(String filePath, String databaseName, String user, String password) throws IOException { -// // 构建 MySQL 命令 -// String command = String.format("mysql -u %s -p%s %s < %s", user, password, databaseName, filePath); // -// // 使用 ProcessBuilder 执行命令 -// ProcessBuilder processBuilder = new ProcessBuilder("cmd.exe", "/c", command); -// processBuilder.inheritIO(); // 将输入输出重定向到当前控制台 -// Process process = processBuilder.start(); +// +//// String fileStu = "D:\\Desktop\\202504211120_mysql\\71\\MYS_010_122\\考试素材\\考试素材\\Student"; +// String fileStu = filepath.getAbsolutePath(); +// +//// String stuAnswerPath = "D:\\Desktop\\202504211120_mysql\\71\\MYS_010_122\\考试素材\\考试素材\\Student\\db\\db_escape.myd"; +// File stuDbDir = new File(fileStu, "db"); +// String stuAnswerPath = null; +// if (stuDbDir.exists() && stuDbDir.isDirectory()) { +// File[] stuMydFiles = stuDbDir.listFiles((dir, name) -> name.toLowerCase().endsWith(".myd")); +// if (stuMydFiles != null && stuMydFiles.length > 0) { +// stuAnswerPath = stuMydFiles[0].getAbsolutePath(); // 默认取第一个 .myd 文件 +// } +// } +// +// // 生成随机数据库名,临时使用 +// databaseName = "db_" + UUID.randomUUID().toString().replace("-", "").substring(0, 8); +// databaseNameStu = "db_" + UUID.randomUUID().toString().replace("-", "").substring(0, 8); +// +//// databaseName = "db_6f80867f"; +//// databaseNameStu= "db_6f80867e"; +// // 连接到 MySQL 默认数据库 +// String url = "jdbc:mysql://rm-bp1a44uap1mm20980mo.mysql.rds.aliyuncs.com:3306/mysql?useSSL=false&serverTimezone=Asia/Shanghai"; +// String user = "root"; +// String password = "Xiaobing0308"; +// try { +// // **连接到 MySQL 默认数据库,创建新的数据库** +// try (Connection conn = DriverManager.getConnection(url, user, password); +// Statement stmt = conn.createStatement()) { +// String createDbSql = "CREATE DATABASE IF NOT EXISTS " + databaseName + +// " CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci"; +//// String createDbSql = "CREATE DATABASE " + databaseName; +// stmt.executeUpdate(createDbSql); +// System.out.println("已创建数据库:" + databaseName); +//// String createDbSql2 = "CREATE DATABASE " + databaseNameStu; +// String createDbSql2 = "CREATE DATABASE IF NOT EXISTS " + databaseNameStu + +// " CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci"; +// stmt.executeUpdate(createDbSql2); +// System.out.println("已创建数据库:" + databaseNameStu); +// +// +// } +// +// +// } catch (SQLException e) { +// e.printStackTrace(); +// } +// +//// // **建立连接到新创建的数据库** +// String newDbUrl = "jdbc:mysql://rm-bp1a44uap1mm20980mo.mysql.rds.aliyuncs.com:3306/" + databaseName + "?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=UTF-8"; +// String stuDbUrl = "jdbc:mysql://rm-bp1a44uap1mm20980mo.mysql.rds.aliyuncs.com:3306/" + databaseNameStu + "?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=UTF-8"; +// // **通过命令行执行 SQL 文件** 建立 完整正确数据库 +// boolean sqlFileExecuted = executeSqlFileUsingCommandLine(answerPath, databaseName, user, password); +// //建立考生答题数据库 +// boolean sqlFileExecutedstu = executeSqlFileUsingCommandLine(stuAnswerPath, databaseNameStu, user, password); +// +// if (sqlFileExecuted && sqlFileExecutedstu) { +// +// +// Map result = readFilesAsMap(stuFilePath); +// Map resultStu = readFilesAsMap(fileStu); +// try (Connection conn = DriverManager.getConnection(stuDbUrl, user, password); +// Statement stmt = conn.createStatement()) { +// +// +// System.out.println("已连接学生数据库"); +// for (Map.Entry entry : resultStu.entrySet()) { +// +// if (entry.getValue().trim().toUpperCase().startsWith("CREATE TABLE")) { +// // 正则表达式匹配表名 +// Pattern pattern = Pattern.compile("CREATE TABLE\\s+`?(\\w+)`?\\s*\\("); +// Matcher matcher = pattern.matcher(entry.getValue()); +// +// if (matcher.find()) { +// String tableName = matcher.group(1).replace("`", ""); // 获取表名 +// System.out.println("表名:" + tableName); +// // 获取表名和 SQL 语句 +// String createTableSql = entry.getValue(); +// +// +// // 执行 CREATE TABLE 语句 +// stmt.executeUpdate(createTableSql); +// // 查询建表语句 +// String showCreateTableSql = "SHOW CREATE TABLE " + tableName; +// try (ResultSet rs = stmt.executeQuery(showCreateTableSql)) { +// if (rs.next()) { +// String createTableSqlExport = rs.getString("Create Table"); +// // 替换 result 中的值 +// entry.setValue(createTableSqlExport); +// } +// } catch (SQLException e) { +// appendToFile(answerLogPath, "执行验证 SQL 出错!"); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "执行验证 SQL 出错!"); +// e.printStackTrace(); +// } +// } +// +// } +// +// +// if (entry.getValue().trim().toUpperCase().startsWith("DELETE")) { +// String delStatement = entry.getValue(); +// stmt.executeUpdate(delStatement); +// +// } +// +// +// } +// for (Map.Entry entry : resultStu.entrySet()) { +// +// if (entry.getValue().trim().toUpperCase().startsWith("INSERT")) { +// // 正则表达式匹配表名 +// Pattern pattern = Pattern.compile("INSERT INTO\\s+`?(\\w+)`?\\s*(\\(|VALUES)", Pattern.CASE_INSENSITIVE); +// Matcher matcher = pattern.matcher(entry.getValue()); +// if (matcher.find()) { +// String tableName = matcher.group(1).replace("`", ""); // 获取表名 +// // 获取 INSERT INTO 语句的表格数据并生成新的插入语句 +// +// String sqlBlock = entry.getValue(); +// String[] sqlStatements = sqlBlock.split(";"); +// +// for (String sql : sqlStatements) { +// sql = sql.trim(); +// if (!sql.isEmpty()) { +// stmt.executeUpdate(sql); +// } +// } +// +// generateInsertStatements(tableName, entry, stuDbUrl, user, password); +// +// } +// } +// } +// } catch (SQLException e) { +// e.printStackTrace(); +// } +// +// try (Connection conn = DriverManager.getConnection(newDbUrl, user, password); +// Statement stmt = conn.createStatement()) { +// for (Map.Entry entry : result.entrySet()) { +// +// if (entry.getValue().trim().toUpperCase().startsWith("CREATE TABLE")) { +// List examMysqlKeywordList =new ArrayList<>(); +// appendToFile(answerLogPath, "==================建表语句=================="); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "==================建表语句=================="); +// String answerId = null; +// for (ExamQuestionAnswer examQuestionAnswer : examQuestionAnswers) { +// if (normalize(examQuestionAnswer.getContent()).equals(normalize(entry.getValue()))) { +// // 匹配成功 +// answerId = examQuestionAnswer.getAnswerId(); +// examMysqlKeywordList= examMysqlKeywordMapper.selectListByAnswerId(answerId); +// break; +// } +// +// } +// // 正则表达式匹配表名 +// Pattern pattern = Pattern.compile("CREATE TABLE\\s+`?(\\w+)`?\\s*\\("); +// Matcher matcher = pattern.matcher(entry.getValue()); +// +// if (matcher.find()) { +// String tableName = matcher.group(1).replace("`", ""); // 获取表名 +// +// +// // 查询建表语句 +// String showCreateTableSql = "SHOW CREATE TABLE " + tableName; +// String sql = "SELECT COLUMN_NAME, COLUMN_TYPE, IS_NULLABLE, COLUMN_KEY, EXTRA " + +// "FROM INFORMATION_SCHEMA.COLUMNS " + +// "WHERE TABLE_NAME = '" + tableName + "' AND TABLE_SCHEMA = '" + databaseName + "'"; +// String sql2 = "SELECT COLUMN_NAME, COLUMN_TYPE, IS_NULLABLE, COLUMN_KEY, EXTRA " + +// "FROM INFORMATION_SCHEMA.COLUMNS " + +// "WHERE TABLE_NAME = '" + tableName + "' AND TABLE_SCHEMA = '" + databaseNameStu + "'"; +// +// // 获取主库字段信息 +// Set> table1Columns = new HashSet<>(); +// try (ResultSet rs = stmt.executeQuery(sql)) { +// while (rs.next()) { +// Map column = new HashMap<>(); +// column.put("COLUMN_NAME", rs.getString("COLUMN_NAME")); +// column.put("COLUMN_TYPE", rs.getString("COLUMN_TYPE")); +// column.put("IS_NULLABLE", rs.getString("IS_NULLABLE")); +// column.put("COLUMN_KEY", rs.getString("COLUMN_KEY")); +// column.put("EXTRA", rs.getString("EXTRA")); +// table1Columns.add(column); +// +// } +//// appendToFile(answerLogPath, "标准答案建表键值对:"+table1Columns); +//// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "标准答案建表键值对:"+table1Columns); +// +// +// } +// // 获取学生库字段信息 +// Set> table2Columns = new HashSet<>(); +// try (Connection connstu = DriverManager.getConnection(stuDbUrl, user, password); +// Statement stmtstu = connstu.createStatement()) { +// try (ResultSet rsstu = stmtstu.executeQuery(sql2)) { +// while (rsstu.next()) { +// Map column = new HashMap<>(); +// column.put("COLUMN_NAME", rsstu.getString("COLUMN_NAME")); +// column.put("COLUMN_TYPE", rsstu.getString("COLUMN_TYPE")); +// column.put("IS_NULLABLE", rsstu.getString("IS_NULLABLE")); +// column.put("COLUMN_KEY", rsstu.getString("COLUMN_KEY")); +// column.put("EXTRA", rsstu.getString("EXTRA")); +// table2Columns.add(column); +// } +//// appendToFile(answerLogPath, "学生答案建表键值对:"+table2Columns); +//// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "学生答案建表键值对:"+table2Columns); +// +// } +// } +// String sql3 = resultStu.get(entry.getKey()); +// Matcher matcherStu = pattern.matcher(sql3); +// String tableNameStu =""; +// if (matcherStu.find()) { +// tableNameStu= matcherStu.group(1).replace("`", ""); // 获取表名 +// } +// String yuju= compareTables(table1Columns, table2Columns, examQuestion.getTname(),tableName, tableNameStu,judgementStr); +// judgementStr=yuju; +// +// if (table1Columns.equals(table2Columns)) { +// // +// SourceAndText studentScorePojo = accumulateScoreAndLog(examMysqlKeywordList,total,answerLogPath,sql3,totalKeyScore,score,answerId,scoreTotal,judgementStr); +// scoreTotal += studentScorePojo.getScore(); +// judgementStr = studentScorePojo.getText(); +// } else { +// SourceAndText studentScorePojo= calculateTotalScoreRate(sql3, examMysqlKeywordList,totalKeyScore,score,answerId,scoreTotal,judgementStr); +// scoreTotal += studentScorePojo.getScore(); +// judgementStr = studentScorePojo.getText(); +// } +// } +// +// } +// +// if (entry.getValue().trim().toUpperCase().startsWith("INSERT")) { +// appendToFile(answerLogPath, "==================插入语句=================="); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "==================插入语句=================="); +// List examMysqlKeywordList =new ArrayList<>(); +// // 正则表达式匹配表名 +// Pattern pattern = Pattern.compile("INSERT INTO\\s+`?(\\w+)`?\\s*\\("); +// Matcher matcher = pattern.matcher(entry.getValue()); +// appendToFile(answerLogPath, "正确语句: " + entry.getValue()); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "正确语句: " + entry.getValue()); +// if (matcher.find()) { +// String tableName = matcher.group(1).replace("`", ""); // 获取表名 +// String answerId=null; +// for (ExamQuestionAnswer examQuestionAnswer : examQuestionAnswers) { +// if (normalize(examQuestionAnswer.getContent()).equals(normalize(entry.getValue()))) { +// // 匹配成功 +// answerId = examQuestionAnswer.getAnswerId(); +// examMysqlKeywordList= examMysqlKeywordMapper.selectListByAnswerId(answerId); +// break; +// } +// +// } +// // 获取 INSERT INTO 语句的表格数据并生成新的插入语句 +// +// generateInsertStatements(tableName, entry, newDbUrl, user, password); +// String sql1 = result.get(entry.getKey()); +// String sql2 = resultStu.get(entry.getKey()); +// +// +// boolean equals = sql1.equals(sql2); +// if (equals) { +// SourceAndText studentScorePojo = accumulateScoreAndLog(examMysqlKeywordList,total,answerLogPath,sql2,totalKeyScore,score,answerId,scoreTotal,judgementStr); +// scoreTotal += studentScorePojo.getScore(); +// judgementStr = studentScorePojo.getText(); +// } else { +// SourceAndText studentScorePojo= calculateTotalScoreRate(sql2, examMysqlKeywordList,totalKeyScore,score,answerId,scoreTotal,judgementStr); +// scoreTotal += studentScorePojo.getScore(); +// judgementStr = studentScorePojo.getText(); +// } +// +// +// } +// +// +// } +// +// if (entry.getValue().trim().toUpperCase().startsWith("DELETE")) { +// appendToFile(answerLogPath, "==================删除语句=================="); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "==================删除语句=================="); +// List 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()); +// // 正则提取表名和 WHERE 条件 +// Pattern pattern = Pattern.compile("DELETE\\s+FROM\\s+(\\w+)\\s+WHERE\\s+(.+)", Pattern.CASE_INSENSITIVE); +// Matcher matcher = pattern.matcher(delStatement); +// for (ExamQuestionAnswer examQuestionAnswer : examQuestionAnswers) { +// if (normalize(examQuestionAnswer.getContent()).equals(normalize(entry.getValue()))) { +// // 匹配成功 +// answerId = examQuestionAnswer.getAnswerId(); +// examMysqlKeywordList= examMysqlKeywordMapper.selectListByAnswerId(answerId); +// break; +// } +// +// } +// if (matcher.find()) { +// String tableName = matcher.group(1).trim(); +// String whereClause = matcher.group(2).trim(); +// MysqlServericeImpl.DeleteInfo deleteInfo = new MysqlServericeImpl.DeleteInfo(tableName, whereClause); +//// appendToFile(answerLogPath, "提取出的表名: " + deleteInfo.tableName); +//// appendToFile(answerLogPath, "提取出的条件: " + deleteInfo.whereClause); +// // 构造验证 SQL +// String verifySql = "SELECT COUNT(*) FROM " + deleteInfo.tableName + " WHERE " + deleteInfo.whereClause; +//// appendToFile(answerLogPath, "验证 SQL: " + verifySql); +// //查找正确答案的 +//// try (Connection conn = DriverManager.getConnection(newDbUrl, user, password); +//// Statement stmt = conn.createStatement()) { +// try (ResultSet rs = stmt.executeQuery(verifySql)) { +// if (rs.next()) { +// int count = rs.getInt(1); +// if (count == 0) { +// try (Connection connstu = DriverManager.getConnection(stuDbUrl, user, password); +// Statement stmtstu = connstu.createStatement()) { +// try (ResultSet rsstu = stmtstu.executeQuery(verifySql)) { +// if (rsstu.next()) { +// int countstu = rsstu.getInt(1); +// if (countstu == 0) { +// //累加删除语句的所有权值 examQuestionKeywords累加scorerate +// appendToFile(answerLogPath, "验证通过:符合 DELETE 条件的记录已删除。"); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "验证通过:符合 DELETE 条件的记录已删除。"); +// SourceAndText studentScorePojo = accumulateScoreAndLog(examMysqlKeywordList,total,answerLogPath,sql2,totalKeyScore,score,answerId,scoreTotal,judgementStr); +// scoreTotal += studentScorePojo.getScore(); +// judgementStr = studentScorePojo.getText(); +// +// } else { +// SourceAndText studentScorePojo= calculateTotalScoreRate(sql2, examMysqlKeywordList,totalKeyScore,score,answerId,scoreTotal,judgementStr); +// scoreTotal += studentScorePojo.getScore(); +// judgementStr = studentScorePojo.getText(); +// } +// } +// }catch (SQLException e) { +// appendToFile(answerLogPath, "验证学生库失败,"+"得分:0 ❌"); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "验证学生库失败,"+"得分:0 ❌"); +// } +// +// } +// +// +// } 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(); +// } +// +// } +// +// } +// +// if (entry.getValue().trim().toUpperCase().startsWith("UPDATE")) { +// appendToFile(answerLogPath, "==================更新语句=================="); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "==================更新语句=================="); +// List 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()))) { +// // 匹配成功 +// answerId = examQuestionAnswer.getAnswerId(); +// examMysqlKeywordList= examMysqlKeywordMapper.selectListByAnswerId(answerId); +// break; +// } +// +// } +// //根据entry的key 获得resultStu 的value +// +// // 根据 key 获取另一个文件中的 SQL 语句 +// String sql2 = resultStu.get(entry.getKey()); +// +// +// boolean b = areUpdateStatementsEqual(sql1, sql2); +// +// // +// if (b) { +// SourceAndText studentScorePojo = accumulateScoreAndLog(examMysqlKeywordList,total,answerLogPath,sql2,totalKeyScore,score,answerId,scoreTotal,judgementStr); +// scoreTotal += studentScorePojo.getScore(); +// judgementStr = studentScorePojo.getText(); +// +// +// +// +// } else { +// SourceAndText studentScorePojo= calculateTotalScoreRate(sql2, examMysqlKeywordList,totalKeyScore,score,answerId,scoreTotal,judgementStr); +// scoreTotal += studentScorePojo.getScore(); +// judgementStr = studentScorePojo.getText(); +// +// } +// +// +// } +// if (entry.getValue().trim().toUpperCase().startsWith("SELECT")) { +// appendToFile(answerLogPath, "==================查找语句=================="); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "==================查找语句=================="); +// List examMysqlKeywordList =new ArrayList<>(); +// String answerId =null; +// for (ExamQuestionAnswer examQuestionAnswer : examQuestionAnswers) { +// if (normalize(examQuestionAnswer.getContent()).equals(normalize(entry.getValue()))) { +// // 匹配成功 +// answerId = examQuestionAnswer.getAnswerId(); +// examMysqlKeywordList= examMysqlKeywordMapper.selectListByAnswerId(answerId); +// break; +// } +// +// } +// String sql1 = entry.getValue(); +// appendToFile(answerLogPath, "正确语句: " + sql1); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "正确语句: " + sql1); +// String sql2 = resultStu.get(entry.getKey()); +// +// +// List> answerList= new ArrayList<>(); +// List> answerListStu = new ArrayList<>(); +// try (Connection connanswer = DriverManager.getConnection(newDbUrl, user, password); +// Statement stmtan = connanswer.createStatement()) { +// try (ResultSet answer = stmtan.executeQuery(sql1)) { +// answerList = getAnswerList(answer); +// appendToFile(answerLogPath, "查找语句标准答案"); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "查找语句标准答案"); +// printResult(answerList,judgementStr); +// }catch (SQLException e) { +// appendToFile(answerLogPath, "执行验证语句"+sql1+"时发生错误: " + e.getMessage()); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "执行验证语句"+sql1+"时发生错误: " + e.getMessage()); +// e.printStackTrace(); +// } +// } +// try (Connection connstu = DriverManager.getConnection(stuDbUrl, user, password); +// Statement stmtstu = connstu.createStatement()) { +// try (ResultSet answer = stmtstu.executeQuery(sql2)) { +// answerListStu = getAnswerList(answer); +// appendToFile(answerLogPath, "学生语句答案"); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "学生语句答案"); +// printResult(answerListStu,judgementStr); +// } catch (SQLException e) { +// appendToFile(answerLogPath, "执行学生库语句"+sql2+"时发生错误: " + e.getMessage()); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "执行学生库语句"+sql2+"时发生错误: " + e.getMessage()); +// } +// +// +// } +// boolean isEquivalent =false; +// +// if (answerListStu!=null&&answerListStu.size()>0){ +// isEquivalent = compareResultsSelect(answerList, answerListStu); +// } +// +// if (isEquivalent) { +// //todo 得分 +// SourceAndText studentScorePojo = accumulateScoreAndLog(examMysqlKeywordList,total,answerLogPath,sql2,totalKeyScore,score,answerId,scoreTotal,judgementStr); +// scoreTotal += studentScorePojo.getScore(); +// judgementStr = studentScorePojo.getText(); +// +// } else { +// SourceAndText studentScorePojo= calculateTotalScoreRate(sql2, examMysqlKeywordList,totalKeyScore,score,answerId,scoreTotal,judgementStr); +// scoreTotal += studentScorePojo.getScore(); +// judgementStr = studentScorePojo.getText(); +// +// } +// +// +// } +// +// +// 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 examMysqlKeywordList =new ArrayList<>(); +// String answerId=null; +// for (ExamQuestionAnswer examQuestionAnswer : examQuestionAnswers) { +// if (normalize(examQuestionAnswer.getContent()).equals(normalize(entry.getValue()))) { +// // 匹配成功 +// answerId = examQuestionAnswer.getAnswerId(); +// examMysqlKeywordList= examMysqlKeywordMapper.selectListByAnswerId(answerId); +// break; +// } +// +// } +// String sql1 = entry.getValue(); +// appendToFile(answerLogPath, "正确语句: " + sql1); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "正确语句: " + sql1); +// String sql2 = resultStu.get(entry.getKey()); +// // 正则表达式,用于匹配 "VIEW" 后面的视图名称 +// String regex = "(?<=VIEW\\s)([\\w`_]+)"; +// String sqlviewAnswer = removeComments(sql1); +// String sqlviewAnswerStu = removeComments(sql2); +// +// if (StringUtils.isNotBlank(sqlviewAnswerStu)) { +// // 从第一个 SQL 语句中提取视图名称 +// String viewNam1 = extractViewName(sqlviewAnswer, regex); +// // 从第二个 SQL 语句中提取视图名称 +// String viewNam2 = extractViewName(sqlviewAnswerStu, regex); +// // 随机生成视图名称 +// String viewName1 = "v_education_" + UUID.randomUUID().toString().replace("-", ""); +// String viewName2 = "v_education_2_" + UUID.randomUUID().toString().replace("-", ""); +// +// +// // 替换 SQL 语句中的视图名称 +// String createView1 = sqlviewAnswer.replace(viewNam1, viewName1); +// String createView2 = sqlviewAnswerStu.replace(viewNam2, viewName2); +// +// +//// try (Connection conn = DriverManager.getConnection(newDbUrl, user, password); +//// Statement stmt = conn.createStatement()) { +// +// +// // 执行 CREATE VIEW 语句,创建视图 +// stmt.execute(createView1); +// +// boolean hasError = false; // 添加标志变量 +// try { +// stmt.execute(createView2); +// +// } 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> result1 = executeQuery(stmt, sql3); +// printResult(result1,judgementStr); +// // 执行查询,获取视图2的结果 +// appendToFile(answerLogPath, "执行考生视图语句的查询结果:"); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "执行考生视图语句的查询结果:"); +// String sql4 = "SELECT * FROM " + viewName2; +// List> result2 = executeQuery(stmt, sql4); +// printResult(result2,judgementStr); +// +// // 比较两个视图的结果 +// boolean isEquivalent = !hasError &&compareResults(result1, result2); +// appendToFile(answerLogPath, "\n是否结果等价: " + isEquivalent); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "\n是否结果等价: " + isEquivalent); +// +// // 删除视图 +// System.out.println("\n删除视图 " + viewName1 + " 和 " + viewName2 + "..."); +// stmt.execute("DROP VIEW IF EXISTS " + viewName1); +// stmt.execute("DROP VIEW IF EXISTS " + viewName2); +// if (isEquivalent) { +// SourceAndText studentScorePojo = accumulateScoreAndLog(examMysqlKeywordList,total,answerLogPath,sql2,totalKeyScore,score,answerId,scoreTotal,judgementStr); +// scoreTotal += studentScorePojo.getScore(); +// judgementStr = studentScorePojo.getText(); +// +// +// +// +// } else { +// SourceAndText studentScorePojo= calculateTotalScoreRate(sql2, examMysqlKeywordList,totalKeyScore,score,answerId,scoreTotal,judgementStr); +// scoreTotal += studentScorePojo.getScore(); +// judgementStr = studentScorePojo.getText(); +// } +//// } +// +// +// } +// } +// +// //存储过程 +// if (entry.getValue().trim().toUpperCase().toUpperCase().contains("PROCEDURE")) { +// String answerId=null; +// List examMysqlKeywordList =new ArrayList<>(); +// for (ExamQuestionAnswer examQuestionAnswer : examQuestionAnswers) { +// if (normalize(examQuestionAnswer.getContent()).equals(normalize(entry.getValue()))) { +// // 匹配成功 +// answerId = examQuestionAnswer.getAnswerId(); +// examMysqlKeywordList= examMysqlKeywordMapper.selectListByAnswerId(answerId); +// break; +// } +// +// } +// 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 extractCallStatements = extractCallStatements(sql1); +// //标准答案 集合 +// List> anwerResults = new ArrayList<>(); +// //考生答案 集合 +// List> stuResults = new ArrayList<>(); +// if (extractCallStatements != null && extractCallStatements.size() > 0) { +// 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); +//// Statement stmt = conn.createStatement()) { +// ResultSet newResult = stmt.executeQuery(extractCallStatement); +// anwerResults.addAll(extractResults(newResult)); +//// } +// } catch (SQLException e) { +// appendToFile(answerLogPath, "执行标准库 SQL CALL 语句时发生错误: " + e.getMessage()); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "执行标准库 SQL CALL 语句时发生错误: " + e.getMessage()); +// } +// +// +// try (Connection connstu = DriverManager.getConnection(stuDbUrl, user, password); +// Statement stmtstu = connstu.createStatement()) { +// stmtstu.execute(sql2); // 创建存储过程 +// +// +// try { +// +// ResultSet oldResult = stmtstu.executeQuery(extractCallStatement); +// stuResults.addAll(extractResults(oldResult)); +// } catch (SQLException e) { +// appendToFile(answerLogPath, "执行学生库 SQL CALL 语句时发生错误: " + e.getMessage()); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "执行学生库 SQL CALL 语句时发生错误: " + e.getMessage()); +// hasError = true; // 发生异常,设为 true +// } +// +// +// +// +// } catch (SQLException e) { +// appendToFile(answerLogPath, "执行学生库语句"+sql2+"时发生错误: " + e.getMessage()); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "执行学生库语句"+sql2+"时发生错误: " + e.getMessage()); +// hasError = true; // 发生异常,设为 true +// } +// +// } +// // 比较结果(如果发生异常,可以认为比较失败) +// boolean flag = !hasError && compareExtractResults(anwerResults, stuResults,judgementStr); +// +// if (flag) { +// //todo 得分 +// SourceAndText studentScorePojo = accumulateScoreAndLog(examMysqlKeywordList,total,answerLogPath,sql2,totalKeyScore,score,answerId,scoreTotal,judgementStr); +// scoreTotal += studentScorePojo.getScore(); +// judgementStr = studentScorePojo.getText(); +// +// } else { +// //得分 +// SourceAndText studentScorePojo = calculateTotalScoreRate(sql2, examMysqlKeywordList, totalKeyScore, score, answerId, scoreTotal,judgementStr); +// scoreTotal += studentScorePojo.getScore(); +// judgementStr = studentScorePojo.getText(); +// +// } +// } else { +// appendToFile(answerLogPath, "此存储过程无 CALL 语句"); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "此存储过程无 CALL 语句"); +// } +// } +// if (entry.getValue().trim().toUpperCase().toUpperCase().contains("TRIGGER")) { +// appendToFile(answerLogPath, "==================触发器=================="); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "==================触发器=================="); +// List examMysqlKeywordList =new ArrayList<>(); +// String answerId=null; +// for (ExamQuestionAnswer examQuestionAnswer : examQuestionAnswers) { +// if (normalize(examQuestionAnswer.getContent()).equals(normalize(entry.getValue()))) { +// // 匹配成功 +// answerId = examQuestionAnswer.getAnswerId(); +// examMysqlKeywordList= examMysqlKeywordMapper.selectListByAnswerId(answerId); +// break; +// } +// +// } +// String sql1 = entry.getValue(); +// appendToFile(answerLogPath, "正确语句: " + sql1); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "正确语句: " + sql1); +// String sql2 = resultStu.get(entry.getKey()); +// +// // 清洗触发器语句(去除注释等) +// String triggerStatementCleanSql1 = cleanProcedureSQL(sql1); +// +// // 标准化触发器内容(去空格、换行、小写) +// String normalizedTriggerSql1 = triggerStatementCleanSql1.trim().replaceAll("\\s+", "").toLowerCase(); +// +// +// // 清洗触发器语句(去除注释等) +// String triggerStatementCleanSql2 = cleanProcedureSQL(sql2); +// +// // 标准化触发器内容(去空格、换行、小写) +// String normalizedTriggerSql2 = triggerStatementCleanSql2.trim().replaceAll("\\s+", "").toLowerCase(); +// +// boolean equals = normalizedTriggerSql1.equals(normalizedTriggerSql2); +// if (equals) { +// //todo 得分 +// SourceAndText studentScorePojo = accumulateScoreAndLog(examMysqlKeywordList, total, answerLogPath, sql2, totalKeyScore, score, answerId, scoreTotal,judgementStr); +// scoreTotal += studentScorePojo.getScore(); +// judgementStr = studentScorePojo.getText(); +// +// } else { +// SourceAndText studentScorePojo = calculateTotalScoreRate(sql2, examMysqlKeywordList, totalKeyScore, score, answerId, scoreTotal,judgementStr); +// scoreTotal += studentScorePojo.getScore(); +// judgementStr = studentScorePojo.getText(); +// +// +// } +// +// +// } +// +// +// } +// // try (Connection conn = DriverManager.getConnection(newDbUrl, user, password); +//// Statement stmt = conn.createStatement()) { +// //删除临时创建的数据库databaseName +// String dropDbSql = "DROP DATABASE " + databaseName; +// stmt.executeUpdate(dropDbSql); +// String dropDbSql2 = "DROP DATABASE " + databaseNameStu; +// stmt.executeUpdate(dropDbSql2); +//// } +// } +// } +// double roundedResult =0.0; +// +// appendToFile(answerLogPath, "共得分:" + String.format("%.2f", scoreTotal)); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "共得分:" + String.format("%.2f", scoreTotal)); +// folderzip.delete(); +// deleteFolder(folder); +// sourceAndText.setScore(scoreTotal); +// sourceAndText.setText(judgementStr); +// return sourceAndText; +// } +// +// private static String compareTables(Set> standardSet, Set> studentSet, String dbTable, String tableName,String tableNameStu,String judgementStr) { +// int index = 1; +// // 判断表名是否一致 +// String tableNameCheck = tableName.equalsIgnoreCase(tableNameStu) ? "✔" : "x"; +// // 输出 +// System.out.printf("%02d.【数据表】【%s】【名称】【%s】【%s】\n", index, dbTable, tableName, tableNameCheck); +// appendToFile(answerLogPath, "%02d.【数据表】【%s】【名称】【%s】【%s】\n", index, dbTable, tableName, tableNameCheck); +// judgementStr = HtmlAppender.appendHtmlLineMysql(judgementStr, "%02d.【数据表】【%s】【名称】【%s】【%s】\n", index, dbTable, tableName, tableNameCheck); +// // 把Set转成Map,方便通过字段名快速取值 +// Map> standardMap = convertSetToMap(standardSet); +// Map> studentMap = convertSetToMap(studentSet); +// +// for (String columnName : standardMap.keySet()) { +// Map stdCol = standardMap.get(columnName); +// Map stuCol = studentMap.get(columnName); +// +// String fullName = dbTable + "." + columnName; +// +// String nameCheck = stuCol != null ? "✔" : "x"; +// System.out.printf("%02d.【字段】【%s】【名称】【%s】【%s】\n", ++index, fullName, columnName, nameCheck); +// judgementStr = HtmlAppender.appendHtmlLineMysql(judgementStr, "%02d.【字段】【%s】【名称】【%s】【%s】\n", index, fullName, columnName, nameCheck); +// appendToFile(answerLogPath, "%02d.【字段】【%s】【名称】【%s】【%s】\n", index, fullName, columnName, nameCheck); +// +// if (stuCol != null) { +// MysqlVo mysqlVo1 = compareField(index, fullName, "类型", stdCol.get("COLUMN_TYPE"), stuCol.get("COLUMN_TYPE"),judgementStr); +// index=mysqlVo1.getIndex(); +// judgementStr=mysqlVo1.getText(); +// MysqlVo mysqlVo2 = compareField(index, fullName, "允许为空", stdCol.get("IS_NULLABLE"), stuCol.get("IS_NULLABLE"),judgementStr); +// index=mysqlVo2.getIndex(); +// judgementStr=mysqlVo2.getText(); +// MysqlVo mysqlVo3 = compareField(index, fullName, "扩展", stdCol.get("EXTRA"), stuCol.get("EXTRA"),judgementStr); +// index=mysqlVo3.getIndex(); +// judgementStr=mysqlVo3.getText(); +// MysqlVo mysqlVo4 = compareField(index, fullName, "键类型", stdCol.get("COLUMN_KEY"), stuCol.get("COLUMN_KEY"),judgementStr); +// judgementStr=mysqlVo4.getText(); +// } else { +// // 缺失字段,直接输出所有属性错误 +// MysqlVo mysqlVo1 = printMissing(index, fullName, "类型", stdCol.get("COLUMN_TYPE"),judgementStr); +// index=mysqlVo1.getIndex(); +// judgementStr=mysqlVo1.getText(); +// MysqlVo mysqlVo2 = printMissing(index, fullName, "允许为空", stdCol.get("IS_NULLABLE"),judgementStr); +// index=mysqlVo2.getIndex(); +// judgementStr=mysqlVo2.getText(); +// MysqlVo mysqlVo3 = printMissing(index, fullName, "扩展", stdCol.get("EXTRA"),judgementStr); +// index=mysqlVo3.getIndex(); +// judgementStr=mysqlVo3.getText(); +// MysqlVo mysqlVo4 = printMissing(index, fullName, "键类型", stdCol.get("COLUMN_KEY"),judgementStr); +// judgementStr=mysqlVo4.getText(); +// } +// } +// return judgementStr; +// } +// +// private static MysqlVo compareField(int index, String fullName, String property, String stdValue, String stuValue, String judgementStr) { +// MysqlVo mysqlVo=new MysqlVo(); +// String mark = stdValue.equalsIgnoreCase(stuValue) ? "✔" : "x"; +// System.out.printf("%02d.【字段】【%s】【%s】【%s】【%s】\n", index + 1, fullName, property, stuValue, mark); +// appendToFile(answerLogPath, "%02d.【字段】【%s】【%s】【%s】【%s】\n", index + 1, fullName, property, stuValue, mark); +// judgementStr = HtmlAppender.appendHtmlLineMysql(judgementStr, "%02d.【字段】【%s】【%s】【%s】【%s】\n", index + 1, fullName, property, stuValue, mark); +// mysqlVo.setText(judgementStr); +// mysqlVo.setIndex(index + 1); +// return mysqlVo; +// } +// +// private static MysqlVo printMissing(int index, String fullName, String property, String stdValue,String judgementStr) { +// MysqlVo mysqlVo=new MysqlVo(); +// System.out.printf("%02d.【字段】【%s】【%s】【%s】【x】\n", index + 1, fullName, property, stdValue); +// appendToFile(answerLogPath, "%02d.【字段】【%s】【%s】【%s】【x】\n", index + 1, fullName, property, stdValue); +// judgementStr = HtmlAppender.appendHtmlLineMysql(judgementStr, "%02d.【字段】【%s】【%s】【%s】【x】\n", index + 1, fullName, property, stdValue); +// mysqlVo.setText(judgementStr); +// mysqlVo.setIndex(index + 1); +// return mysqlVo; +// } +// +// private static Map> convertSetToMap(Set> set) { +// Map> map = new LinkedHashMap<>(); +// for (Map column : set) { +// map.put(column.get("COLUMN_NAME"), column); +// } +// return map; +// } +// public static void deleteFolder(File folder) { +// if (folder.isDirectory()) { +// File[] files = folder.listFiles(); +// if (files != null) { +// for (File file : files) { +// deleteFolder(file); // 递归删除所有子文件/文件夹 +// } +// } +// } +// folder.delete(); // 删除空文件夹或文件 +// } +// //如果这个小题对了,直接累加对应的权值分 +// private SourceAndText accumulateScoreAndLog(List examMysqlKeywordList, AtomicInteger total, String answerLogPath, String sql2, String totalKeyScore, double score,String answerId,double scoreTotal,String judgementStr) { +// SourceAndText sourceAndText = new SourceAndText(); +// if(StringUtils.isBlank(answerId)){ +// appendToFile(answerLogPath, "❌该语句找不到试题id,请检查出题内容!" ); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "❌该语句找不到试题id,请检查出题内容!"); +// sourceAndText.setText(judgementStr); +// sourceAndText.setScore(0.0); +// //返回累加的总分 +// return sourceAndText; +// } +// //用answerid查对应答案的权值 。除以总权值 +// String scoreRateStr= examQuestionAnswerMapper.selectExamQuestionAnswerScoreByAnswerId(answerId); +// +// // 解析权值 +// double scoreRate = 0.0; +// double totalKey = 0.0; +// double singleScore = 0.0; +// try { +// scoreRate = Double.parseDouble(scoreRateStr); +// totalKey = Double.parseDouble(totalKeyScore); +// // 计算该答案对应的得分 +// +// if (totalKey > 0) { +// singleScore = (scoreRate / totalKey) * score; +// singleScore = Math.round(singleScore * 100.0) / 100.0; +// System.out.println(scoreTotal); +// System.out.println(singleScore); +// +// System.out.println(scoreTotal); +// +// } +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "✅学生语句" + sql2 + "正确,语句得分权值:" + scoreRateStr + ",得分" + singleScore); +// appendToFile(answerLogPath, "✅学生语句" + sql2 + "正确,语句得分权值:" + scoreRateStr + ",得分" + singleScore); +// } catch (NumberFormatException e) { +// System.err.println("无效的totalKeyScore值:" + totalKeyScore); +// } +// sourceAndText.setText(judgementStr); +// sourceAndText.setScore(singleScore); +// //返回累加的总分 +// return sourceAndText; +// +// } +// +// +// public SourceAndText calculateTotalScoreRate(String sql, List examQuestionKeywords, String totalKeyScore, double score,String answerId,double scoreTotal,String judgementStr) { +// SourceAndText sourceAndText = new SourceAndText(); +// if(StringUtils.isBlank(answerId)){ +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "❌该语句找不到试题id,请检查出题内容!"); +// appendToFile(answerLogPath, "❌该语句找不到试题id,请检查出题内容!" ); +// sourceAndText.setText(judgementStr); +// sourceAndText.setScore(0.0); +// //返回累加的总分 +// return sourceAndText; +// } +// //用answerid查对应答案的权值 。除以总权值 +// String scoreRateStr= examQuestionAnswerMapper.selectExamQuestionAnswerScoreByAnswerId(answerId); +// +// +// +// // 解析权值 +// double scoreRate = 0.0; +// double totalKey = 0.0; +// // 计算该答案对应的得分 +// double singleScore = 0.0; +// try { +// scoreRate = Double.parseDouble(scoreRateStr); +// totalKey = Double.parseDouble(totalKeyScore); +// +// if (totalKey > 0) { +// singleScore = (scoreRate / totalKey) * score; +// singleScore = Math.round(singleScore * 100.0) / 100.0; +// } +// +// +// +// } catch (NumberFormatException e) { +// System.err.println("无效的totalKeyScore值:" + totalKeyScore); +// } +// +// +// int totalScoreRate = 0; +// Set matchedKeywords = new HashSet<>(); +// for (ExamMysqlKeyword keyword : examQuestionKeywords) { +// String keywordValue = keyword.getKeyword(); +// if (keywordValue != null && !keywordValue.isEmpty() && !matchedKeywords.contains(keywordValue)) { +// // 使用正则,确保是完整单词(字段)匹配 +// String regex = keywordValue; +// if (sql.contains(regex)) { +// try { +// totalScoreRate += Integer.parseInt(keyword.getScoreRate()); +// +// matchedKeywords.add(keywordValue); +// } catch (NumberFormatException e) { +// System.err.println("Invalid scoreRate format for keyword: " + keywordValue); +// } +// } +// } +// } +// //累加答案关键字的所有权值 +// int totalKeyScoreInt = examQuestionKeywords.stream() +// .map(ExamMysqlKeyword::getScoreRate) +// .filter(s -> s != null && !s.isEmpty()) +// .mapToInt(Integer::parseInt) +// .sum(); +// +// //乘以 对了多少个 关键字 权值 +// double finalRoundedScore; +// if (totalKeyScoreInt == 0) { +// // 如果总键值为0,可以设置为0或其他默认值 +// finalRoundedScore = 0.0; +// } else { +// finalRoundedScore = new BigDecimal( +// ((double) totalScoreRate / totalKeyScoreInt) * singleScore +// ).setScale(2, RoundingMode.HALF_UP).doubleValue(); +// } +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "❌学生语句"+sql+"不正确,语句权值:"+scoreRateStr+",关键权值:"+totalKeyScoreInt+",答对得分点为:"+matchedKeywords+",答对关键得分权值"+ totalScoreRate+ ",得分" + finalRoundedScore); +// +// appendToFile(answerLogPath,"❌学生语句"+sql+"不正确,语句权值:"+scoreRateStr+",关键权值:"+totalKeyScoreInt+",答对得分点为:"+matchedKeywords+",答对关键得分权值"+ totalScoreRate+ ",得分" + finalRoundedScore); +// sourceAndText.setText(judgementStr); +// sourceAndText.setScore(finalRoundedScore); +// //返回累加的总分 +// return sourceAndText; +// } +// +// // 预处理函数:去除空格和换行并转为大写 +// private static String normalize(String str) { +// return str.replaceAll("\\s+", "").toUpperCase(); +// } +// +// public static String cleanProcedureSQL(String sql) { +// // 删除 DELIMITER 和 $$ 标记 +// sql = sql.replaceAll("(?i)DELIMITER\\s+\\$\\$", ""); // 删除 DELIMITER $$ +// sql = sql.replaceAll("(?i)DELIMITER\\s+;", ""); // 删除 DELIMITER ; +// sql = sql.replaceAll("\\$\\$", ""); // 删除结尾 $$ +// +// // 删除 CALL 语句(例如 CALL pro_xxx(...);) +// sql = sql.replaceAll("(?i)CALL\\s+[^;]+;", ""); // 删除 CALL 语句(不区分大小写) +// +// return sql.trim(); // 去除首尾空格 +// } +// public static class DeleteInfo { +// public String tableName; +// public String whereClause; +// +// public DeleteInfo(String tableName, String whereClause) { +// this.tableName = tableName; +// this.whereClause = whereClause; +// } +// } +// // 标准化 SQL 字符串 +// public static String simplifyCreateTableSql(String sql) { +// if (sql == null || sql.isEmpty()) return sql; +// +// // 移除字段中的 CHARACTER SET 和 COLLATE +// sql = sql.replaceAll("(?i)CHARACTER SET\\s+\\w+", ""); +// sql = sql.replaceAll("(?i)COLLATE\\s+\\w+", ""); +// +// // 移除主键中的 USING BTREE +// sql = sql.replaceAll("(?i)USING\\s+BTREE", ""); +// +// // 移除表级 ENGINE、AUTO_INCREMENT、CHARSET、COLLATE、ROW_FORMAT +// sql = sql.replaceAll("(?i)ENGINE\\s*=\\s*\\w+", ""); +// sql = sql.replaceAll("(?i)AUTO_INCREMENT\\s*=\\s*\\d+", ""); +// sql = sql.replaceAll("(?i)(DEFAULT\\s+)?CHARSET\\s*=\\s*\\w+", ""); +// sql = sql.replaceAll("(?i)CHARACTER SET\\s*=\\s*\\w+", ""); +// sql = sql.replaceAll("(?i)ROW_FORMAT\\s*=\\s*\\w+", ""); +// sql = sql.replaceAll("(?i)COLLATE\\s*=\\s*\\w+", ""); +// +// // 清理多余逗号与空格 +// sql = sql.replaceAll(",\\s*\\)", "\n)"); +// sql = sql.replaceAll(" +", " "); +// sql = sql.replaceAll("(?m)^\\s*$", ""); // 清除空行 +// sql = sql.trim(); +// +// return sql; +// } +// +// +// // 比较两个结果集 +// private static boolean compareExtractResults(List> newResults, List> oldResults,String judgementStr) { +// appendToFile(answerLogPath,"==== 标准答案 ===="); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "==== 标准答案 ===="); +// for (Map row : newResults) { +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, row.toString()); +// appendToFile(answerLogPath,row.toString()); +// } +// appendToFile(answerLogPath,"==== 考生答案 ===="); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "==== 考生答案 ===="); +// for (Map row : oldResults) { +// appendToFile(answerLogPath,row.toString()); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, row.toString()); +// } +// +// if (newResults.size() != oldResults.size()) { +// appendToFile(answerLogPath,"❌考生答案与标准答案个数不对"); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "❌考生答案与标准答案个数不对"); +// return false; +// } +// +// // 不比较顺序,直接判断两个列表内容是否一样(将其转换为 Set) +// Set> newSet = new HashSet<>(newResults); +// Set> oldSet = new HashSet<>(oldResults); +// +// if (!newSet.equals(oldSet)) { +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "❌ 内容相同但顺序不同,或存在差异:"); +// appendToFile(answerLogPath,"❌ 内容相同但顺序不同,或存在差异:"); +// Set> onlyInNew = new HashSet<>(newSet); +// onlyInNew.removeAll(oldSet); +// +// Set> onlyInOld = new HashSet<>(oldSet); +// onlyInOld.removeAll(newSet); +// +// for (Map row : onlyInNew) { +// appendToFile(answerLogPath,"⚠️ 标准答案中有但考生答案中没有: " + row); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "⚠️ 标准答案中有但考生答案中没有: " + row); +// } +// +// for (Map row : onlyInOld) { +// appendToFile(answerLogPath,"⚠️ 考生答案中有但标准答案中没有: " + row); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "⚠️ 考生答案中有但标准答案中没有: " + row); +// } +// +// return false; +// } +// appendToFile(answerLogPath,"两个结果集内容一致(不考虑顺序)!"); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "两个结果集内容一致(不考虑顺序)!"); +// return true; +// } +// +// +// // 提取ResultSet中的结果到一个列表中 +// private static List> extractResults(ResultSet resultSet) throws SQLException { +// List> results = new ArrayList<>(); +// +// // 获取列数 +// ResultSetMetaData metaData = resultSet.getMetaData(); +// int columnCount = metaData.getColumnCount(); +// +// while (resultSet.next()) { +// Map row = new HashMap<>(); +// for (int i = 1; i <= columnCount; i++) { +// String columnName = metaData.getColumnLabel(i); +// Object value = resultSet.getObject(i); +// row.put(columnName, value); +// } +// results.add(row); +// } +// +// return results; +// } +// +// +// +// public static List extractCallStatements(String sql) { +// List callStatements = new ArrayList<>(); +// Pattern callPattern = Pattern.compile("CALL\\s+\\w+\\s*\\([^;]*?\\);", Pattern.CASE_INSENSITIVE); +// Matcher matcher = callPattern.matcher(sql); +// +// while (matcher.find()) { +// callStatements.add(matcher.group()); +// } +// +// return callStatements; +// } +// +// +// /** +// * 比较两个查询的结果 +// */ +// private static boolean compareResults(List> result1, List> result2) { +// // 获取列名并比较(顺序无关) +// List columnNames1 = result1.get(0); +// List columnNames2 = result2.get(0); +// +// // 检查列名是否一致(顺序无关) +// Set columnSet1 = new HashSet<>(columnNames1); +// Set columnSet2 = new HashSet<>(columnNames2); +// if (!columnSet1.equals(columnSet2)) { +// return false; +// } +// +// // 获取数据行(去除列名) +// List> rows1 = result1.subList(1, result1.size()); +// List> rows2 = result2.subList(1, result2.size()); +// +// // 使用 Set 存储每行数据并比较 +// Set> rowSet1 = new HashSet<>(); +// for (List row : rows1) { +// rowSet1.add(new HashSet<>(row)); +// } +// +// Set> rowSet2 = new HashSet<>(); +// for (List row : rows2) { +// rowSet2.add(new HashSet<>(row)); +// } +// +// // 比较行数据(无顺序) +// return rowSet1.equals(rowSet2); +// } +// /** +// * 执行 SQL 查询并返回结果 +// */ +// private static List> executeQuery(Statement stmt, String sql) throws SQLException { +// List> result = new ArrayList<>(); +// // // try { -// // 等待命令执行完成 -// int exitCode = process.waitFor(); -// if (exitCode == 0) { -// System.out.println("SQL 文件执行成功:" + filePath); -// return true; // 返回 true 表示执行成功 -// } else { -// System.err.println("SQL 文件执行失败:" + filePath); -// return false; // 返回 false 表示执行失败 +// +// ResultSet rs = stmt.executeQuery(sql); +// // 获取列数和列名 +// ResultSetMetaData metaData = rs.getMetaData(); +// int columnCount = metaData.getColumnCount(); +// +// // 获取列名 +// List columnNames = new ArrayList<>(); +// for (int i = 1; i <= columnCount; i++) { +// columnNames.add(metaData.getColumnLabel(i)); // } -// } catch (InterruptedException e) { +// result.add(columnNames); // 将列名添加为结果的第一行 +// +// // 遍历结果集 +// while (rs.next()) { +// List row = new ArrayList<>(); +// for (int i = 1; i <= columnCount; i++) { +// row.add(rs.getString(i)); +// } +// result.add(row); +// } +// } catch (SQLException e) { +// appendToFile(answerLogPath, "执行学生库 SQL CALL 语句时发生错误: " + e.getMessage()); +// } +// +// +// return result; +// } +// // 去除 SQL 中的注释部分 +// private static String removeComments(String sql) { +// // 正则表达式匹配 SQL 中以 -- 开头的注释 +// return sql.replaceAll("(?m)^[\\s]*--.*$", ""); +// } +// /** +// * 比较两个查询的结果 +// */ +// private static boolean compareResultsSelect(List> result1, List> result2) { +// // 获取列名并比较(顺序无关) +// List columnNames1 = result1.get(0); +// List columnNames2 = result2.get(0); +// +// // 检查列名是否一致(顺序无关) +// Set columnSet1 = new HashSet<>(columnNames1); +// Set columnSet2 = new HashSet<>(columnNames2); +// if (!columnSet1.equals(columnSet2)) { +// return false; +// } +// +// // 获取数据行(去除列名) +// List> rows1 = result1.subList(1, result1.size()); +// List> rows2 = result2.subList(1, result2.size()); +// +// // 使用 Set 存储每行数据并比较 +// Set> rowSet1 = new HashSet<>(); +// for (List row : rows1) { +// rowSet1.add(new HashSet<>(row)); +// } +// +// Set> rowSet2 = new HashSet<>(); +// for (List row : rows2) { +// rowSet2.add(new HashSet<>(row)); +// } +// +// // 比较行数据(无顺序) +// return rowSet1.equals(rowSet2); +// } +// /** +// * 打印查询结果 +// */ +// private static void printResult(List> result,String judgementStr) { +// if (result.isEmpty()) { +// appendToFile(answerLogPath, "查询结果为空"); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, "查询结果为空"); +// +// } else { +// for (int i = 0; i < result.size(); i++) { +// List row = result.get(i); +// StringBuilder sb = new StringBuilder(); +// +// if (i == 0) { +// sb.append("列名:"); +// } +// +// for (String value : row) { +// sb.append(value).append("\t"); +// } +// +// // 输出整行 +// appendToFile(answerLogPath, sb.toString()); +// judgementStr = HtmlAppender.appendHtmlLine(judgementStr, sb.toString()); +// } +// } +// } +// +// /** +// * 使用提供的正则表达式模式从给定的 SQL 语句中提取视图名称。 +// */ +// private static String extractViewName(String sql, String regex) { +// Pattern pattern = Pattern.compile(regex); +// Matcher matcher = pattern.matcher(sql); +// +// // 如果找到匹配项,返回匹配到的视图名称 +// if (matcher.find()) { +// return matcher.group(1).replace("`", ""); // 如果有反引号(`),则移除 +// } else { +// return "未找到视图名称"; +// } +// } +// +// private static List> getAnswerList(ResultSet answer) throws SQLException { +// List> result = new ArrayList<>(); +// // 获取列数和列名 +// ResultSetMetaData metaData = answer.getMetaData(); +// int columnCount = metaData.getColumnCount(); +// +// // 获取列名 +// List columnNames = new ArrayList<>(); +// for (int i = 1; i <= columnCount; i++) { +// columnNames.add(metaData.getColumnLabel(i)); +// } +// result.add(columnNames); // 将列名添加为结果的第一行 +// +// // 遍历结果集 +// while (answer.next()) { +// List row = new ArrayList<>(); +// for (int i = 1; i <= columnCount; i++) { +// row.add(answer.getString(i)); +// } +// result.add(row); +// } +// +// return result; +// +// } +// +// +// +// public static void generateInsertStatements(String tableName, Map.Entry entry, String newDbUrl, String user, String password) { +// // 确保 entry 里包含的是 INSERT 语句 +// if (entry.getValue().trim().toUpperCase().startsWith("INSERT")) { +// System.out.println("==================插入语句=================="); +// // 创建一个列表来存储所有的 INSERT INTO 语句 +// List insertQueries = new ArrayList<>(); +// try (Connection conn = DriverManager.getConnection(newDbUrl, user, password); +// Statement stmt = conn.createStatement()) { +// +// // 查询表的所有列 +// String columnsQuery = "DESCRIBE " + tableName; +// +// try (ResultSet columnsRs = stmt.executeQuery(columnsQuery)) { +// List columnNames = new ArrayList<>(); +// while (columnsRs.next()) { +// String columnName = columnsRs.getString("Field"); +// columnNames.add(columnName); +// } +// +// // 获取表的数据并生成 INSERT INTO 语句 +// String selectQuery = "SELECT * FROM " + tableName; +// try (ResultSet dataRs = stmt.executeQuery(selectQuery)) { +// +// while (dataRs.next()) { +// StringBuilder insertQuery = new StringBuilder("INSERT INTO `" + tableName + "` ("); +// +// // 构建列名部分 +// for (int i = 0; i < columnNames.size(); i++) { +// insertQuery.append("`").append(columnNames.get(i)).append("`"); +// if (i < columnNames.size() - 1) { +// insertQuery.append(", "); +// } +// } +// insertQuery.append(") VALUES ("); +// +// // 构建值部分 +// for (int i = 0; i < columnNames.size(); i++) { +// Object value = dataRs.getObject(columnNames.get(i)); +// if (value == null) { +// insertQuery.append("NULL"); +// } else if (value instanceof String) { +// insertQuery.append("'").append(value.toString().replace("'", "''")).append("'"); +// } else { +// insertQuery.append(value); +// } +// +// if (i < columnNames.size() - 1) { +// insertQuery.append(", "); +// } +// } +// insertQuery.append(");"); +// // 将生成的 INSERT INTO 语句添加到列表中 +// insertQueries.add(insertQuery.toString()); +// // 输出生成的 INSERT INTO 语句 +// System.out.println(insertQuery.toString()); +// } +// +// } +// catch (SQLException e) { +// System.err.println("生成插入语句失败,表名:" + tableName); +// e.printStackTrace(); +// } +// } +// } catch (SQLException e) { +// System.err.println("生成插入语句失败,表名:" + tableName); +// e.printStackTrace(); +// } +// // 将列表赋值给 entry 的值 +// entry.setValue(insertQueries.toString()); +// System.out.println(entry.getValue()); +// } +// } +// +// /** +// * 读取指定目录下所有文件,返回一个文件名到文件内容的键值对Map +// * @param directoryPath 文件夹路径 +// * @return Map<文件名, 文件内容> +// * @throws IOException 读取文件异常 +// */ +// public static Map readFilesAsMap(String directoryPath) throws IOException { +// Map fileContentMap = new HashMap<>(); +// +// Path dirPath = Paths.get(directoryPath); +// if (!Files.isDirectory(dirPath)) { +// throw new IllegalArgumentException("路径不是一个有效的目录: " + directoryPath); +// } +// +// try (DirectoryStream stream = Files.newDirectoryStream(dirPath)) { +// for (Path path : stream) { +// if (Files.isRegularFile(path)) { +// String fileName = path.getFileName().toString(); +// String content = new String(Files.readAllBytes(path)); +// fileContentMap.put(fileName, content); +// } +// } +// } +// +// return fileContentMap; +// } +// +// +// /** +// * 通过命令行执行 SQL 文件 +// */ +// public static boolean executeSqlFileUsingCommandLine(String sqlFilePath, String dbName, String user, String password) { +// try { +// // 拼接命令 +// String[] command = { +// "mysql", +// "-u" + user, +// "-p" + password, +// "-h", "rm-bp1a44uap1mm20980mo.mysql.rds.aliyuncs.com", +// "-P", "3306", +// dbName, +// "-e", "source " + sqlFilePath +// }; +// +// // 启动进程 +// Process process = Runtime.getRuntime().exec(command); +// int exitCode = process.waitFor(); +// +// return exitCode == 0; +// } catch (Exception e) { // e.printStackTrace(); // return false; // } // } - /** - * 将指定内容追加写入到指定文件中。 - * - * @param filePath 文件路径 - * @param content 要写入的内容 - */ - public static void appendToFile(String filePath, String content) { - try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath, true))) { - String timestamp = LocalDateTime.now().format(formatter); - String logLine = String.format("[%s] %s", timestamp, content); - writer.write(logLine); - writer.newLine(); // 可选:添加换行符 - } catch (IOException e) { - e.printStackTrace(); - } - } - public static void appendToFile(String filePath, String format, Object... args) { - try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath, true))) { - String timestamp = LocalDateTime.now().format(formatter); - String content = String.format(format, args); - String logLine = String.format("[%s] %s", timestamp, content); - writer.write(logLine); - writer.newLine(); // 可选:添加换行符 - } catch (IOException e) { - e.printStackTrace(); - } - } - -} \ No newline at end of file +//// private static boolean executeSqlFileUsingCommandLine(String filePath, String databaseName, String user, String password) throws IOException { +//// // 构建 MySQL 命令 +//// String command = String.format("mysql -u %s -p%s %s < %s", user, password, databaseName, filePath); +//// +//// // 使用 ProcessBuilder 执行命令 +//// ProcessBuilder processBuilder = new ProcessBuilder("cmd.exe", "/c", command); +//// processBuilder.inheritIO(); // 将输入输出重定向到当前控制台 +//// Process process = processBuilder.start(); +//// +//// try { +//// // 等待命令执行完成 +//// int exitCode = process.waitFor(); +//// if (exitCode == 0) { +//// System.out.println("SQL 文件执行成功:" + filePath); +//// return true; // 返回 true 表示执行成功 +//// } else { +//// System.err.println("SQL 文件执行失败:" + filePath); +//// return false; // 返回 false 表示执行失败 +//// } +//// } catch (InterruptedException e) { +//// e.printStackTrace(); +//// return false; +//// } +//// } +// /** +// * 将指定内容追加写入到指定文件中。 +// * +// * @param filePath 文件路径 +// * @param content 要写入的内容 +// */ +// public static void appendToFile(String filePath, String content) { +// try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath, true))) { +// String timestamp = LocalDateTime.now().format(formatter); +// String logLine = String.format("[%s] %s", timestamp, content); +// writer.write(logLine); +// writer.newLine(); // 可选:添加换行符 +// } catch (IOException e) { +// e.printStackTrace(); +// } +// } +// public static void appendToFile(String filePath, String format, Object... args) { +// try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath, true))) { +// String timestamp = LocalDateTime.now().format(formatter); +// String content = String.format(format, args); +// String logLine = String.format("[%s] %s", timestamp, content); +// writer.write(logLine); +// writer.newLine(); // 可选:添加换行符 +// } catch (IOException e) { +// e.printStackTrace(); +// } +// } +// +//} \ No newline at end of file diff --git a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/service/mysql/testServiceImpl.java b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/service/mysql/testServiceImpl.java index 9afa378e..452dcc84 100644 --- a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/service/mysql/testServiceImpl.java +++ b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/service/mysql/testServiceImpl.java @@ -1,23 +1,23 @@ -package pc.exam.pp.module.judgement.controller.service.mysql; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import pc.exam.pp.module.exam.dal.mysql.paper.EducationPaperMapper; -import pc.exam.pp.module.judgement.utils.EndStuMonitorUtils; - -@Service -public class testServiceImpl implements testservice { - - @Autowired - private EndStuMonitorUtils endStuMonitorUtils; - @Override - public boolean test() { - - -// String s = endStuMonitorUtils.endStuMonitor("160", "2bf4510550e34d85a852394cea61b455"); +//package pc.exam.pp.module.judgement.controller.service.mysql; // -// endStuMonitorUtils.endStuMonitor("160","2bf4510550e34d85a852394cea61b455",20.0); - return true; - } - -} +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.stereotype.Service; +//import pc.exam.pp.module.exam.dal.mysql.paper.EducationPaperMapper; +//import pc.exam.pp.module.judgement.utils.EndStuMonitorUtils; +// +//@Service +//public class testServiceImpl implements testservice { +// +// @Autowired +// private EndStuMonitorUtils endStuMonitorUtils; +// @Override +// public boolean test() { +// +// +//// String s = endStuMonitorUtils.endStuMonitor("160", "2bf4510550e34d85a852394cea61b455"); +//// +//// endStuMonitorUtils.endStuMonitor("160","2bf4510550e34d85a852394cea61b455",20.0); +// return true; +// } +// +//} diff --git a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/service/mysql/testservice.java b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/service/mysql/testservice.java index 0816c95f..93a75180 100644 --- a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/service/mysql/testservice.java +++ b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/controller/service/mysql/testservice.java @@ -1,7 +1,7 @@ -package pc.exam.pp.module.judgement.controller.service.mysql; - -public interface testservice { - boolean test(); - - -} +//package pc.exam.pp.module.judgement.controller.service.mysql; +// +//public interface testservice { +// boolean test(); +// +// +//} diff --git a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/service/wps_excel/JudgementWpsExcelService.java b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/service/wps_excel/JudgementWpsExcelService.java index 1d88705d..d8d8b476 100644 --- a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/service/wps_excel/JudgementWpsExcelService.java +++ b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/service/wps_excel/JudgementWpsExcelService.java @@ -2,16 +2,7 @@ package pc.exam.pp.module.judgement.service.wps_excel; -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_excel.vo.XlsxVO; -import pc.exam.pp.module.judgement.utils.wps_excel.vo.xlsx_all.XlsxAllDataReqVo; -import pc.exam.pp.module.judgement.utils.wps_excel.vo.xlsx_drawing.XlsxInfoVo; -import pc.exam.pp.module.judgement.utils.wps_excel.vo.xlsx_style.XlsxStyleVO; -import pc.exam.pp.module.judgement.utils.wps_word.vo.WordVO; - -import java.io.FileNotFoundException; import java.util.List; /** diff --git a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/service/wps_excel/JudgementWpsExcelServiceImpl.java b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/service/wps_excel/JudgementWpsExcelServiceImpl.java index 3ed9aa09..35c78dd9 100644 --- a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/service/wps_excel/JudgementWpsExcelServiceImpl.java +++ b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/service/wps_excel/JudgementWpsExcelServiceImpl.java @@ -4,18 +4,10 @@ package pc.exam.pp.module.judgement.service.wps_excel; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; -import pc.exam.pp.module.exam.dal.dataobject.ExamQuestion; -import pc.exam.pp.module.exam.dal.dataobject.ExamQuestionAnswer; -import pc.exam.pp.module.exam.utils.file.LogFileUtils; import pc.exam.pp.module.infra.dal.dataobject.config.ConfigDO; import pc.exam.pp.module.infra.service.config.ConfigService; import pc.exam.pp.module.judgement.controller.admin.Wps.dto.WpsPptxJudgementDto; -import pc.exam.pp.module.judgement.dal.mysql.wpsxlsx.WpsXlsxLinkMapper; -//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_excel.WpsExcelUtils; -import pc.exam.pp.module.judgement.utils.wps_excel.vo.xlsx_drawing.XlsxInfoVo; import java.io.*; import java.net.URL; @@ -25,9 +17,6 @@ import java.util.List; @Service public class JudgementWpsExcelServiceImpl implements JudgementWpsExcelService { - @Resource - WpsXlsxLinkMapper wpsXlsxLinkMapper; - // @Resource // AutoToolsService autoToolsService; diff --git a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/service/wps_pptx/JudgementWpsPptxServiceImpl.java b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/service/wps_pptx/JudgementWpsPptxServiceImpl.java index 9a579d47..a0127bdd 100644 --- a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/service/wps_pptx/JudgementWpsPptxServiceImpl.java +++ b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/service/wps_pptx/JudgementWpsPptxServiceImpl.java @@ -2,18 +2,12 @@ package pc.exam.pp.module.judgement.service.wps_pptx; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; -import pc.exam.pp.module.exam.dal.dataobject.ExamQuestion; -import pc.exam.pp.module.exam.dal.dataobject.ExamQuestionAnswer; -import pc.exam.pp.module.exam.utils.file.LogFileUtils; import pc.exam.pp.module.infra.dal.dataobject.config.ConfigDO; import pc.exam.pp.module.infra.service.config.ConfigService; import pc.exam.pp.module.judgement.controller.admin.Wps.dto.WpsPptxJudgementDto; //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.JudgementWpsPPT; import pc.exam.pp.module.judgement.utils.wps_pptx.judgementVO.JudgementReqVo; -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.system.dal.dataobject.user.AdminUserDO; import pc.exam.pp.module.system.service.user.AdminUserService; @@ -21,7 +15,6 @@ import pc.exam.pp.module.system.service.user.AdminUserService; import java.io.*; import java.net.URL; import java.net.URLConnection; -import java.util.ArrayList; import java.util.List; import static pc.exam.pp.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; diff --git a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/service/wps_word/JudgementWpsWordService.java b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/service/wps_word/JudgementWpsWordService.java index 726968e4..b755ec16 100644 --- a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/service/wps_word/JudgementWpsWordService.java +++ b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/service/wps_word/JudgementWpsWordService.java @@ -1,19 +1,11 @@ package pc.exam.pp.module.judgement.service.wps_word; - import org.springframework.web.multipart.MultipartFile; -import pc.exam.pp.module.exam.dal.dataobject.ExamQuestion; import pc.exam.pp.module.judgement.controller.admin.AutoWps.vo.WpsDocxInfoVo; -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.docx4j.vo.DocxDataInfoVO; import pc.exam.pp.module.judgement.utils.wps_word.docx4j.vo.JudgementWordsVO; -import pc.exam.pp.module.judgement.utils.wps_word.vo.WordInfoReqVo; -import pc.exam.pp.module.judgement.utils.wps_word.vo.WordVO; -import java.math.BigDecimal; import java.util.List; /** @@ -23,20 +15,7 @@ import java.util.List; */ public interface JudgementWpsWordService { - List docxMaster(List wpsDocxInfoVos) throws Exception; + List docxMaster(List wpsDocxInfoVos, MultipartFile file) throws Exception; List docxDataInfo(MultipartFile file) throws Exception; - -// /** -// * 获取word文件内得考点及描述 -// * @param path minio文件路径 -// * @return 文件内得考点及描述 -// * @throws Exception 异常 -// */ -// List programmingWpsWord(String path) throws Exception; -// -// List programmingInfo(List wpsWordReqDtos) throws Exception; -// - - } diff --git a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/service/wps_word/JudgementWpsWordServiceImpl.java b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/service/wps_word/JudgementWpsWordServiceImpl.java index 91f937b5..29142958 100644 --- a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/service/wps_word/JudgementWpsWordServiceImpl.java +++ b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/service/wps_word/JudgementWpsWordServiceImpl.java @@ -3,36 +3,16 @@ package pc.exam.pp.module.judgement.service.wps_word; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; -import pc.exam.pp.module.exam.dal.dataobject.ExamQuestion; -import pc.exam.pp.module.exam.dal.dataobject.ExamQuestionAnswer; -import pc.exam.pp.module.exam.utils.file.LogFileUtils; -import pc.exam.pp.module.infra.dal.dataobject.config.ConfigDO; import pc.exam.pp.module.infra.service.config.ConfigService; import pc.exam.pp.module.judgement.controller.admin.AutoWps.vo.WpsDocxInfoVo; -import pc.exam.pp.module.judgement.controller.admin.Wps.dto.WpsWordChineseFunctionDto; -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.controller.admin.Wps.vo.WordListReqVO; -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.docx4j.DocxConversion; import pc.exam.pp.module.judgement.utils.wps_word.docx4j.DocxMaster; import pc.exam.pp.module.judgement.utils.wps_word.docx4j.vo.DocxDataInfoVO; import pc.exam.pp.module.judgement.utils.wps_word.docx4j.vo.JudgementWordsVO; -import pc.exam.pp.module.judgement.utils.wps_word.vo.WordInfoReqVo; -import pc.exam.pp.module.judgement.utils.wps_word.vo.WordVO; -import pc.exam.pp.module.system.dal.dataobject.user.AdminUserDO; import pc.exam.pp.module.system.service.user.AdminUserService; -import java.io.File; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; import java.util.List; -import static pc.exam.pp.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; - @Service public class JudgementWpsWordServiceImpl implements JudgementWpsWordService { @@ -42,50 +22,27 @@ public class JudgementWpsWordServiceImpl implements JudgementWpsWordService { @Resource private AdminUserService userService; + /** + * 指定考点查询 + * @param wpsDocxInfoVos 查询考点参数数组 + * @param file 文件流 + * @return 考点信息 + * @throws Exception 异常 + */ @Override - public List docxMaster(List wpsDocxInfoVos) throws Exception { - return DocxMaster.docxMaster(wpsDocxInfoVos); + public List docxMaster(List wpsDocxInfoVos, MultipartFile file) throws Exception { + return DocxMaster.docxMaster(wpsDocxInfoVos, file); } + /** + * 查询docx所有考点 + * @param file 文件流 + * @return 所有考点 + * @throws Exception 异常 + */ @Override public List docxDataInfo(MultipartFile file) throws Exception { return DocxConversion.DocxDataInfos(file); } -// @Override -// public List programmingWpsWord(String path) throws Exception { -// String pathName = ""; -// String[] strPaht = path.split("/"); -// // 1、获取文件临时下载路径 -// ConfigDO config = configService.getConfigByKey("file_down_wps_word_path"); -// AdminUserDO user = userService.getUser(getLoginUserId()); -//// Path paths = Paths.get(config.getValue() + "\\" + user.getId()); -//// if (Files.exists(paths)) { -//// pathName = config.getValue() + "\\" + user.getId() + "\\" + strPaht[strPaht.length - 1]; -//// } else { -// // 2、下载文件并返回文件完整路径 -// pathName = autoToolsService.downloadStudentFile(path, config.getValue() + "\\" + user.getId()); -//// } -// // 4、docx文件读取并返回考点及说明信息 -// List margins = WpsWordUtils.wpWord(pathName); -// // 5、已经读取完得考点删除源文件 -//// File file = new File(pathName); -//// file.delete(); -// return margins; -// } -// -// @Override -// public List programmingInfo(List wordReqDto) throws Exception { -//// List functionList = new ArrayList<>(); -//// for (String function : wordReqDto.getFunction()) { -//// WpsWordChineseFunctionDto functionDto = new WpsWordChineseFunctionDto(); -//// functionDto.setFunction(function); -//// WpsWordLinkDO wpsWordLinkDO = wpsWordLinkMapper.selectByNodeFunction(function); -//// functionDto.setChineseName(wpsWordLinkDO.getToChinese()); -//// functionList.add(functionDto); -//// } -// List judgementDtos = WpsWordUtils.getWordInfo(wordReqDto); -// return judgementDtos; -// } - } diff --git a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_excel/WpsExcelUtils.java b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_excel/WpsExcelUtils.java index ba59cde9..80fbe5ee 100644 --- a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_excel/WpsExcelUtils.java +++ b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_excel/WpsExcelUtils.java @@ -15,8 +15,6 @@ import pc.exam.pp.module.judgement.utils.wps_excel.vo.*; import pc.exam.pp.module.judgement.utils.wps_excel.vo.xlsx_chart.ChartTypeEntry; import pc.exam.pp.module.judgement.utils.wps_excel.vo.xlsx_drawing.XlsxInfoVo; import pc.exam.pp.module.judgement.utils.wps_excel.vo.xlsx_drawing.XlsxDrawingSheetVo; -import pc.exam.pp.module.judgement.utils.wps_pptx.vo.PptxInfoReqVo; -import pc.exam.pp.module.judgement.utils.wps_word.vo.WordInfoReqVo; import javax.xml.namespace.QName; import java.io.FileInputStream; diff --git a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_word/docx4j/DocxConversion.java b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_word/docx4j/DocxConversion.java index db6c8547..be235b99 100644 --- a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_word/docx4j/DocxConversion.java +++ b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_word/docx4j/DocxConversion.java @@ -4,13 +4,10 @@ import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.apache.xmlbeans.XmlCursor; import org.apache.xmlbeans.XmlObject; import org.springframework.web.multipart.MultipartFile; -import pc.exam.pp.module.judgement.utils.wps_word.WpsWordNameSpaces; -import pc.exam.pp.module.judgement.utils.wps_word.XmlUtil; import pc.exam.pp.module.judgement.utils.wps_word.docx4j.vo.DocxDataInfoVO; -import pc.exam.pp.module.judgement.utils.wps_word.vo.WordInfoReqVo; -import pc.exam.pp.module.judgement.utils.wps_word.vo.WordSecondInfoVo; +import pc.exam.pp.module.judgement.utils.wps_word.utils.WpsWordNameSpaces; +import pc.exam.pp.module.judgement.utils.wps_word.utils.XmlUtil; -import java.io.FileInputStream; import java.io.InputStream; import java.util.ArrayList; import java.util.List; @@ -32,6 +29,7 @@ public class DocxConversion { String xmlString = XmlUtil.getDocumentXml(document); String namespace = WpsWordNameSpaces.getNameSpace(xmlString); + XmlObject docXml = document.getDocument(); // 1、获取文档段落W:P标签得数量,判断出一个有多少段 XmlCursor wpCursor = docXml.newCursor(); @@ -41,7 +39,6 @@ public class DocxConversion { // 段落 String firstIdWp = getStringRandom(); setWordDataInfo(firstIdWp, "", "段落", "w:p", "", false, dataInfoVOS); - List wordSecondWp = new ArrayList<>(); while (wpCursor.toNextSelection()) { wpIndex ++; // 段落属性 @@ -73,7 +70,6 @@ public class DocxConversion { int wSectPrIndex = 0; String firstIdSectPr = getStringRandom(); setWordDataInfo(firstIdSectPr, "", "页面", "w:sectPr", "", false, dataInfoVOS); - List wordSecondWSectPr = new ArrayList<>(); while (wSectPrCursor.toNextSelection()) { wSectPrIndex ++; String secondIdSectPr = getStringRandom(); diff --git a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_word/docx4j/DocxMaster.java b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_word/docx4j/DocxMaster.java index e8054b16..6856ecfb 100644 --- a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_word/docx4j/DocxMaster.java +++ b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_word/docx4j/DocxMaster.java @@ -21,6 +21,7 @@ import org.docx4j.openpackaging.parts.WordprocessingML.NumberingDefinitionsPart; import org.docx4j.openpackaging.parts.WordprocessingML.StyleDefinitionsPart; import org.docx4j.w14.CTWordContentPart; import org.docx4j.wml.*; +import org.springframework.web.multipart.MultipartFile; import org.w3c.dom.Node; import pc.exam.pp.module.judgement.controller.admin.AutoWps.vo.WpsDocxInfoVo; import pc.exam.pp.module.judgement.utils.wps_word.docx4j.paragraph.Convert; @@ -32,6 +33,7 @@ import pc.exam.pp.module.judgement.utils.wps_word.docx4j.vo.JudgementWordsVO; import java.io.File; import java.io.IOException; +import java.io.InputStream; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.math.BigInteger; @@ -43,18 +45,31 @@ import java.util.List; */ public class DocxMaster { - public static List docxMaster(List wpsDocxInfoVos) throws Docx4JException, InvalidFormatException, IOException, JAXBException, XmlException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { + /** + * + * @param wpsDocxInfoVos 考点参数 + * @param file 文件流 + * @return + * @throws Docx4JException + * @throws InvalidFormatException + * @throws IOException + * @throws JAXBException + * @throws XmlException + * @throws NoSuchMethodException + * @throws InvocationTargetException + * @throws IllegalAccessException + */ + public static List docxMaster(List wpsDocxInfoVos, MultipartFile file) throws Docx4JException, InvalidFormatException, IOException, JAXBException, XmlException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { // 一共分为 段落, 页面,图形 String firstDuanLuoId = Convert.getStringRandom(); String firstYeMianId = Convert.getStringRandom(); String firstTuXingId = Convert.getStringRandom(); - List judgementWordsVOS = new ArrayList<>(); - // 1、获取想要判断的文件地址 - String path = wpsDocxInfoVos.get(0).getFilePath(); + // 1、获取想要判断的文件地址(文件流) + InputStream inputStream = file.getInputStream(); // 2、Docx转换对象 - WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(new File(path)); + WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(inputStream); List paragraphs = wordMLPackage.getMainDocumentPart().getContent(); // 2-1、样式对象 StyleDefinitionsPart stylePart = wordMLPackage.getMainDocumentPart().getStyleDefinitionsPart(); @@ -62,6 +77,7 @@ public class DocxMaster { NumberingDefinitionsPart ndp = wordMLPackage.getMainDocumentPart().getNumberingDefinitionsPart(); // 2-3、节对象 List sections = wordMLPackage.getDocumentModel().getSections(); + wordMLPackage.getHeaderFooterPolicy().getDefaultFooter(); for (WpsDocxInfoVo wpsDocxInfoVo : wpsDocxInfoVos) { // 参数实例化 // 大类名称 @@ -74,7 +90,9 @@ public class DocxMaster { String examName = wpsDocxInfoVo.getExamName(); // 考点代码 String examCode = wpsDocxInfoVo.getExamCode(); - + // 方式方法 + String method = wpsDocxInfoVo.getMethod(); + String docxFunction = firstName + "#" + indexParm + "#" + function + "#" + examName + "#" + examCode + "#" + method; // 创建一个索引ID,跟参数中index进行匹配 int index = 0; for (Object obj : paragraphs) { @@ -89,14 +107,35 @@ public class DocxMaster { // 查询出具体想要查询哪个段落的数据 // 目标对象 Paragraphs paragraphsFunction = new Paragraphs(); + // 获取参数中类型的定义 + String[] methods = method.split("@"); + List> classList = new ArrayList<>(); + for (String met : methods) { + if (met.equals("P")) { + classList.add(P.class); + } + if (met.equals("StyleDefinitionsPart")) { + classList.add(StyleDefinitionsPart.class); + } + if (met.equals("NumberingDefinitionsPart")) { + classList.add(NumberingDefinitionsPart.class); + } + if (met.equals("SectionWrapper")) { + classList.add(SectionWrapper.class); + } + if (met.equals("WordprocessingMLPackage")) { + classList.add(WordprocessingMLPackage.class); + } + } // 参数类型列表(按方法声明顺序) - Class[] paramTypes = {P.class, StyleDefinitionsPart.class}; +// Class[] paramTypes = classList.toArray(new Class[0]); + Class[] paramTypes = {P.class, WordprocessingMLPackage.class}; // 带参数的方法调用示例 Method methodWithArgs = paragraphsFunction.getClass().getMethod(function, paramTypes); // 实际参数值 Object[] arguments = {paragraph, stylePart}; String value = (String) methodWithArgs.invoke(obj, arguments); - judgementWordsVOS = setJudgementWord(judgementWordsVOS, examCode + "@" + value, firstName + examName + value); + judgementWordsVOS = setJudgementWord(judgementWordsVOS, docxFunction + "@" + value, firstName + examName + value); } } } diff --git a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_word/docx4j/paragraph/Paragraphs.java b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_word/docx4j/paragraph/Paragraphs.java index 0fcdfb0d..eb19c01e 100644 --- a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_word/docx4j/paragraph/Paragraphs.java +++ b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_word/docx4j/paragraph/Paragraphs.java @@ -1,14 +1,13 @@ package pc.exam.pp.module.judgement.utils.wps_word.docx4j.paragraph; import jakarta.xml.bind.JAXBElement; +import org.docx4j.openpackaging.packages.WordprocessingMLPackage; import org.docx4j.openpackaging.parts.WordprocessingML.NumberingDefinitionsPart; import org.docx4j.openpackaging.parts.WordprocessingML.StyleDefinitionsPart; import org.docx4j.wml.*; -import pc.exam.pp.module.judgement.utils.wps_word.docx4j.DocxSetInfo; -import pc.exam.pp.module.judgement.utils.wps_word.docx4j.vo.JudgementWordsVO; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTextAlignment; import java.math.BigInteger; -import java.util.List; /** * @author REN @@ -53,7 +52,7 @@ public class Paragraphs { return Convert.convertJc(style.getPPr().getOutlineLvl().getVal().toString()); } } - return ""; + return "正文"; } /// 段落格式(缩进) 左缩进 磅 public static String getParagraphIndLeft(P paragraph, StyleDefinitionsPart stylePart) { @@ -140,7 +139,23 @@ public class Paragraphs { return ""; } - /// 段落格式(间距) 段前 + /// 段落格式(间距) 段前行 + public static String getParagraphSpacingBeforeLines(P paragraph, StyleDefinitionsPart stylePart) { + PPr pPr = paragraph.getPPr(); + if (pPr != null && pPr.getSpacing() != null) { + return pPr.getSpacing().getBeforeLines().toString(); + } + if (pPr != null && pPr.getPStyle() != null && stylePart != null) { + String styleId = pPr.getPStyle().getVal(); + Style style = stylePart.getStyleById(styleId); + if (style != null && style.getPPr() != null && style.getPPr().getSpacing() != null) { + PPrBase.Spacing spacing = style.getPPr().getSpacing(); + return spacing.getBeforeLines().toString(); + } + } + return ""; + } + /// 段落格式(间距) 段前磅 public static String getParagraphSpacingBefore(P paragraph, StyleDefinitionsPart stylePart) { PPr pPr = paragraph.getPPr(); if (pPr != null && pPr.getSpacing() != null) { @@ -156,7 +171,7 @@ public class Paragraphs { } return ""; } - /// 段落格式(间距) 段后 + /// 段落格式(间距) 段后磅 public static String getParagraphSpacingAfter(P paragraph, StyleDefinitionsPart stylePart) { PPr pPr = paragraph.getPPr(); if (pPr != null && pPr.getSpacing() != null) { @@ -172,6 +187,24 @@ public class Paragraphs { } return ""; } + + /// 段落格式(间距) 段后行 + public static String getParagraphSpacingAfterLines(P paragraph, StyleDefinitionsPart stylePart) { + PPr pPr = paragraph.getPPr(); + if (pPr != null && pPr.getSpacing() != null) { + return pPr.getSpacing().getAfterLines().toString(); + } + if (pPr != null && pPr.getPStyle() != null && stylePart != null) { + String styleId = pPr.getPStyle().getVal(); + Style style = stylePart.getStyleById(styleId); + if (style != null && style.getPPr() != null && style.getPPr().getSpacing() != null) { + PPrBase.Spacing spacing = style.getPPr().getSpacing(); + return spacing.getAfterLines().toString(); + } + } + return ""; + } + /// 段落格式(间距) 间距 public static String getParagraphSpacingLine(P paragraph, StyleDefinitionsPart stylePart) { PPr pPr = paragraph.getPPr(); @@ -349,78 +382,268 @@ public class Paragraphs { return "未知"; } - // 段落-边框 -// public static List getParagraphBorder(P paragraph, StyleDefinitionsPart stylePart, List judgementWordsVOS, int betoLong, String firstId) { -// if (paragraph == null) { -// return judgementWordsVOS; -// } -// String name = "【第" + betoLong + "段】"; -// String parentId = Convert.getStringRandom(); -// // 先查询自身段落数据 -// PPr pPr = paragraph.getPPr(); -// if (pPr != null && pPr.getPBdr() != null) { -// PPrBase.PBdr border = pPr.getPBdr(); -// String topName = "【】【】"; -// Convert.printBorder("上边框", border.getTop()); -// Convert.printBorder("下边框", border.getBottom()); -// Convert.printBorder("左边框", border.getLeft()); -// Convert.printBorder("右边框", border.getRight()); -// Convert.printBorder("内横线", border.getBetween()); -// Convert.printBorder("内竖线", border.getBar()); -// } -// } - - // 段落-底纹 - public static void getParagraphShd(P paragraph, StyleDefinitionsPart stylePart) { - if (paragraph == null) { - return ; + // 段落边框 样式 + public static String getParagraphBorderStyle(P paragraph, StyleDefinitionsPart stylePart) { + // 先查询自身段落数据 + PPr pPr = paragraph.getPPr(); + if (pPr != null && pPr.getPBdr() != null) { + PPrBase.PBdr border = pPr.getPBdr(); + // 上边框 + CTBorder top = border.getTop(); + // 下边框 + CTBorder bottom = border.getBottom(); + // 左边框 + CTBorder left = border.getLeft(); + // 右边框 + CTBorder right = border.getRight(); + // 判断上下左右边框是否一致 + if (top.getVal().value().equals(bottom.getVal().value()) && top.getVal().value().equals(left.getVal().value()) && top.getVal().value().equals(right.getVal().value())) { + // 说明样式一样 + return top.getVal().value(); + } else { + // 说明样式不一样 + return top.getVal().value() + "-" + bottom.getVal().value() + "-" + left.getVal().value() + "-" + right.getVal().value(); + } } + return "未知"; + } + + // 段落边框 - 颜色 + public static String getParagraphBorderColor(P paragraph, StyleDefinitionsPart stylePart) { + // 先查询自身段落数据 + PPr pPr = paragraph.getPPr(); + if (pPr != null && pPr.getPBdr() != null) { + PPrBase.PBdr border = pPr.getPBdr(); + // 上边框 + CTBorder top = border.getTop(); + // 下边框 + CTBorder bottom = border.getBottom(); + // 左边框 + CTBorder left = border.getLeft(); + // 右边框 + CTBorder right = border.getRight(); + // 判断上下左右边框是否一致 + if (top.getColor().equals(bottom.getColor()) && top.getColor().equals(left.getColor()) && top.getColor().equals(right.getColor())) { + // 说明样式一样 + return top.getColor(); + } else { + // 说明样式不一样 + return top.getColor() + "-" + bottom.getColor() + "-" + left.getColor() + "-" + right.getColor(); + } + } + return "未知"; + } + + // 段落边框 - 宽度 + public static String getParagraphBorderSize(P paragraph, StyleDefinitionsPart stylePart) { + // 先查询自身段落数据 + PPr pPr = paragraph.getPPr(); + if (pPr != null && pPr.getPBdr() != null) { + PPrBase.PBdr border = pPr.getPBdr(); + // 上边框 + CTBorder top = border.getTop(); + // 下边框 + CTBorder bottom = border.getBottom(); + // 左边框 + CTBorder left = border.getLeft(); + // 右边框 + CTBorder right = border.getRight(); + // 判断上下左右边框是否一致 + if (top.getSz().toString().equals(bottom.getSz().toString()) && top.getSz().toString().equals(left.getSz().toString()) && top.getSz().toString().equals(right.getSz().toString())) { + // 说明样式一样 + return top.getSz().toString(); + } else { + // 说明样式不一样 + return top.getSz().toString() + "-" + bottom.getSz().toString() + "-" + left.getSz().toString() + "-" + right.getSz().toString(); + } + } + return "未知"; + } + + // 段落底纹 - 填充颜色 + public static String getParagraphShdFillColor(P paragraph, StyleDefinitionsPart stylePart) { // 先查询自身段落数据 PPr pPr = paragraph.getPPr(); if (pPr != null && pPr.getShd() != null) { CTShd shd = pPr.getShd(); - System.out.println("图案样式 (val): " + shd.getVal()); // 如 clear, solid, nil - System.out.println("图案颜色 (color): " + shd.getColor()); // 图案颜色(文字上的线) - System.out.println("填充颜色 (fill): " + shd.getFill()); // 背景色(段落底色) + return shd.getFill(); + } + return "未知"; + } + + // 段落底纹 - 图案样式 + public static String getParagraphShdStyle(P paragraph, StyleDefinitionsPart stylePart) { + // 先查询自身段落数据 + PPr pPr = paragraph.getPPr(); + if (pPr != null && pPr.getShd() != null) { + CTShd shd = pPr.getShd(); + return shd.getVal().value(); + } + return "未知"; + } + + // 段落底纹 - 图案颜色 + public static String getParagraphShdStyleColor(P paragraph, StyleDefinitionsPart stylePart) { + // 先查询自身段落数据 + PPr pPr = paragraph.getPPr(); + if (pPr != null && pPr.getShd() != null) { + CTShd shd = pPr.getShd(); + return shd.getColor(); + } + return "未知"; + } + + // 首字下沉 - 是否存在 + public static String getParagraphDropCapIsTrue(P paragraph, StyleDefinitionsPart stylePart) { + PPr pPr = paragraph.getPPr(); + if (pPr != null && pPr.getFramePr() != null) { + return "是"; + } else { + return "否"; } } - // 段落-首字下沉 - public static void getParagraphDropCap(P paragraph, StyleDefinitionsPart stylePart) { - if (paragraph == null) { - return ; - } + + + // 首字下沉 - 首字位置 + public static String getParagraphDropCapLocation(P paragraph, StyleDefinitionsPart stylePart) { PPr pPr = paragraph.getPPr(); if (pPr != null && pPr.getFramePr() != null) { CTFramePr framePr = pPr.getFramePr(); - System.out.println("---- 首字下沉 ----"); - System.out.println("存在首字下沉: 是"); - if (framePr.getDropCap() != null) { - System.out.println("首字位置 (dropCap): " + framePr.getDropCap().value()); // drop | none | margin + return framePr.getDropCap().value(); // drop | none | margin } + } + return "未知"; + } + // 首字下沉 - 行数 + public static String getParagraphDropCapLine(P paragraph, StyleDefinitionsPart stylePart) { + PPr pPr = paragraph.getPPr(); + if (pPr != null && pPr.getFramePr() != null) { + CTFramePr framePr = pPr.getFramePr(); if (framePr.getLines() != null) { - System.out.println("下沉行数 (lines): " + framePr.getLines().intValue()); + return String.valueOf(framePr.getLines().intValue()); // twips } + } + return "未知"; + } + // 首字下沉 - 距正文 + public static String getParagraphDropCapHSpace(P paragraph, StyleDefinitionsPart stylePart) { + PPr pPr = paragraph.getPPr(); + if (pPr != null && pPr.getFramePr() != null) { + CTFramePr framePr = pPr.getFramePr(); if (framePr.getHSpace() != null) { - System.out.println("距正文 (hSpace): " + framePr.getHSpace().intValue()); // twips + return String.valueOf(framePr.getHSpace().intValue()); // twips } + } + return "未知"; + } + // 首字下沉 - 字体 + public static String getParagraphDropCapFont(P paragraph, StyleDefinitionsPart stylePart) { + PPr pPr = paragraph.getPPr(); + if (pPr != null && pPr.getFramePr() != null) { // 获取首字字体 String fontName = Convert.getFirstRunFont(paragraph); if (fontName != null) { - System.out.println("字体: " + fontName); + return fontName; } - } else { - System.out.println("不存在首字下沉"); } + return "未知"; } - // 段落-分栏 - public static void getParagraphCols(P paragraph, StyleDefinitionsPart stylePart) { - if (paragraph == null) { - return ; + + // 分栏 - 栏数 +// public static String getParagraphCols(P paragraph, StyleDefinitionsPart stylePart) { +// PPr pPr = paragraph.getPPr(); +// SectPr sectPr = null; +// sectPr = pPr.getSectPr(); +// // 优先取段落自身的节属性 +// if (pPr != null && pPr.getSectPr() != null) { +// sectPr = pPr.getSectPr(); +// } +// // 或最后一个段落中会有一个节结束的SectPr +// if (sectPr == null && paragraph.getContent().size() > 0) { +// Object lastObj = paragraph.getContent().get(paragraph.getContent().size() - 1); +// if (lastObj instanceof JAXBElement && ((JAXBElement) lastObj).getValue() instanceof SectPr) { +// sectPr = (SectPr) ((JAXBElement) lastObj).getValue(); +// } +// } +// if (sectPr != null && sectPr.getCols() != null) { +// CTColumns cols = sectPr.getCols(); +// return String.valueOf(cols.getNum().intValue()); +// } +// +// return "未知"; +// } + + public static String getParagraphCols(P paragraph, WordprocessingMLPackage wordMLPackage) { + // 1. 首先检查段落自身的节属性 + if (paragraph.getPPr() != null && paragraph.getPPr().getSectPr() != null) { + CTColumns cols = paragraph.getPPr().getSectPr().getCols(); + if (cols != null && cols.getNum() != null) { + return String.valueOf(cols.getNum().intValue()); + } } + + // 2. 检查段落内容中是否有节属性 + for (Object content : paragraph.getContent()) { + if (content instanceof JAXBElement) { + Object value = ((JAXBElement) content).getValue(); + if (value instanceof SectPr) { + CTColumns cols = ((SectPr) value).getCols(); + if (cols != null && cols.getNum() != null) { + return String.valueOf(cols.getNum().intValue()); + } + } + } + } + + // 3. 向后查找后续段落中的节属性 + Body body = wordMLPackage.getMainDocumentPart().getJaxbElement().getBody(); + boolean foundCurrent = false; + + for (Object obj : body.getContent()) { + if (obj instanceof P) { + P p = (P) obj; + + // 找到当前段落后才开始查找 + if (p == paragraph) { + foundCurrent = true; + continue; + } + + if (foundCurrent) { + // 检查后续段落的节属性 + if (p.getPPr() != null && p.getPPr().getSectPr() != null) { + CTColumns cols = p.getPPr().getSectPr().getCols(); + if (cols != null && cols.getNum() != null) { + return String.valueOf(cols.getNum().intValue()); + } + } + + // 检查后续段落内容中的节属性 + for (Object content : p.getContent()) { + if (content instanceof JAXBElement) { + Object value = ((JAXBElement) content).getValue(); + if (value instanceof SectPr) { + CTColumns cols = ((SectPr) value).getCols(); + if (cols != null && cols.getNum() != null) { + return String.valueOf(cols.getNum().intValue()); + } + } + } + } + } + } + } + + // 4. 如果都没找到,返回默认值(如"1"表示单栏) + return "1"; + } + + // 分栏 - 分隔线 + public static String getParagraphColIsSep(P paragraph, StyleDefinitionsPart stylePart) { PPr pPr = paragraph.getPPr(); SectPr sectPr = null; sectPr = pPr.getSectPr(); @@ -439,21 +662,110 @@ public class Paragraphs { if (sectPr != null && sectPr.getCols() != null) { CTColumns cols = sectPr.getCols(); + return cols.isSep() ? "是" : "否"; + } + return "未知"; + } + + // 分栏 - 各栏间距 + public static String getParagraphColSpace(P paragraph, StyleDefinitionsPart stylePart) { + PPr pPr = paragraph.getPPr(); + SectPr sectPr = null; + sectPr = pPr.getSectPr(); + // 优先取段落自身的节属性 + if (pPr != null && pPr.getSectPr() != null) { + sectPr = pPr.getSectPr(); + } - System.out.println("---- 分栏信息 ----"); - System.out.println("栏数: " + (cols.getNum() != null ? cols.getNum().intValue() : "未设置")); - System.out.println("是否栏宽相等 (equalWidth): " + (cols.isEqualWidth() ? "是" : "否")); - System.out.println("是否有分隔线 (sep): " + (cols.isSep() ? "是" : "否")); - - if (cols.getCol() != null && !cols.getCol().isEmpty()) { - int index = 1; - for (CTColumn col : cols.getCol()) { - System.out.println("第 " + index + " 栏宽度 (twips): " + col.getW()); - System.out.println("第 " + index + " 栏间距 (twips): " + col.getSpace()); - index++; - } + // 或最后一个段落中会有一个节结束的SectPr + if (sectPr == null && paragraph.getContent().size() > 0) { + Object lastObj = paragraph.getContent().get(paragraph.getContent().size() - 1); + if (lastObj instanceof JAXBElement && ((JAXBElement) lastObj).getValue() instanceof SectPr) { + sectPr = (SectPr) ((JAXBElement) lastObj).getValue(); } } + + if (sectPr != null && sectPr.getCols() != null) { + CTColumns cols = sectPr.getCols(); + if (cols.getCol() != null && !cols.getCol().isEmpty()) { + int index = 1; + String value = ""; + for (CTColumn col : cols.getCol()) { + value += "第 " + index + " 栏间距 (twips): " + col.getSpace() + " "; + index++; + } + return value; + } + } + return "未知"; + } + // 分栏 - 各栏宽度 + public static String getParagraphColW(P paragraph, StyleDefinitionsPart stylePart) { + PPr pPr = paragraph.getPPr(); + SectPr sectPr = null; + sectPr = pPr.getSectPr(); + // 优先取段落自身的节属性 + if (pPr != null && pPr.getSectPr() != null) { + sectPr = pPr.getSectPr(); + } + + // 或最后一个段落中会有一个节结束的SectPr + if (sectPr == null && paragraph.getContent().size() > 0) { + Object lastObj = paragraph.getContent().get(paragraph.getContent().size() - 1); + if (lastObj instanceof JAXBElement && ((JAXBElement) lastObj).getValue() instanceof SectPr) { + sectPr = (SectPr) ((JAXBElement) lastObj).getValue(); + } + } + + if (sectPr != null && sectPr.getCols() != null) { + CTColumns cols = sectPr.getCols(); + if (cols.getCol() != null && !cols.getCol().isEmpty()) { + int index = 1; + String value = ""; + for (CTColumn col : cols.getCol()) { + value += "第 " + index + " 栏宽度 (twips): " + col.getW() + " "; + index++; + } + return value; + } + } + return "未知"; + } + + // 分栏 - 栏宽相等 + public static String getParagraphColEqualWidth(P paragraph, StyleDefinitionsPart stylePart) { + PPr pPr = paragraph.getPPr(); + SectPr sectPr = null; + sectPr = pPr.getSectPr(); + // 优先取段落自身的节属性 + if (pPr != null && pPr.getSectPr() != null) { + sectPr = pPr.getSectPr(); + } + // 或最后一个段落中会有一个节结束的SectPr + if (sectPr == null && paragraph.getContent().size() > 0) { + Object lastObj = paragraph.getContent().get(paragraph.getContent().size() - 1); + if (lastObj instanceof JAXBElement && ((JAXBElement) lastObj).getValue() instanceof SectPr) { + sectPr = (SectPr) ((JAXBElement) lastObj).getValue(); + } + } + if (sectPr != null && sectPr.getCols() != null) { + CTColumns cols = sectPr.getCols(); + return cols.isEqualWidth() ? "是" : "否"; + } + return "未知"; + } + + // 中文版式 - 双行合一 + public static String getParagraphCNBidi(P paragraph, StyleDefinitionsPart stylePart) { + PPr pPr = paragraph.getPPr(); + if (pPr.getTextAlignment() != null) { + PPrBase.TextAlignment textAlignment = pPr.getTextAlignment(); + if (textAlignment.getVal() != null && + textAlignment.getVal().equals(STTextAlignment.CENTER)) { + return "是"; + } + } + return "否"; } } diff --git a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_word/utils/WpsWordNameSpaces.java b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_word/utils/WpsWordNameSpaces.java index f35678d0..2ad6d7e7 100644 --- a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_word/utils/WpsWordNameSpaces.java +++ b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_word/utils/WpsWordNameSpaces.java @@ -1,9 +1,4 @@ -package pc.exam.pp.module.judgement.utils.wps_word; - -import java.util.HashMap; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; +package pc.exam.pp.module.judgement.utils.wps_word.utils; @SuppressWarnings("all") public class WpsWordNameSpaces { diff --git a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_word/utils/XmlUtil.java b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_word/utils/XmlUtil.java index 92020e2a..54931e69 100644 --- a/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_word/utils/XmlUtil.java +++ b/exam-module-judgement/exam-module-judgement-biz/src/main/java/pc/exam/pp/module/judgement/utils/wps_word/utils/XmlUtil.java @@ -1,4 +1,4 @@ -package pc.exam.pp.module.judgement.utils.wps_word; +package pc.exam.pp.module.judgement.utils.wps_word.utils; import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.apache.xmlbeans.XmlObject;