【新增】 判分总入口增加(学号,试卷ID)

This commit is contained in:
RENWEIBING\letre
2025-05-05 20:20:35 +08:00
parent 85ea237b37
commit 04a73be668
8 changed files with 163 additions and 12 deletions

View File

@@ -1,4 +1,26 @@
package pc.exam.pp.module.judgement.controller.admin.autoTools;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
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.admin.autoTools.vo.StuPaperReqVo;
import pc.exam.pp.module.judgement.service.auto_tools.AutoToolsService;
@RestController
@RequestMapping("/tool")
@Tag( name = "测试判分")
@Validated
public class AutoToolsController {
@Resource
private AutoToolsService autoToolsService;
@GetMapping("/get")
public CommonResult<Double> get(StuPaperReqVo stuPaperReqVo) {
return autoToolsService.judgementScore(stuPaperReqVo.getStuId(),stuPaperReqVo.getPaperId());
}
}

View File

@@ -5,15 +5,13 @@ import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class StudentUploadFileZipReqVo {
public class StuPaperReqVo {
@Schema(description = "学号")
private Long studentId;
private Long stuId;
@Schema(description = "试卷号")
private String paperId;
@Schema(description = "上传文件路径")
private String filePath;
}

View File

@@ -1,5 +1,7 @@
package pc.exam.pp.module.judgement.service.auto_tools;
import pc.exam.pp.framework.common.pojo.CommonResult;
public interface AutoToolsService {
@@ -23,4 +25,12 @@ public interface AutoToolsService {
* @return 解压后的目录
*/
String unzipToNamedFolder(String zipFilePath);
/**
* 判分
* @param stuId 学号
* @param paperId 试卷ID
* @return 分数
*/
CommonResult<Double> judgementScore(Long stuId, String paperId);
}

View File

@@ -1,6 +1,16 @@
package pc.exam.pp.module.judgement.service.auto_tools;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import pc.exam.pp.framework.common.exception.ErrorCode;
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.service.question.IExamQuestionService;
import pc.exam.pp.module.exam.service.stu_paper_file.StuPaperFileService;
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.service.c_programming.JudgementService;
import java.io.*;
import java.net.MalformedURLException;
@@ -11,6 +21,14 @@ import java.util.zip.ZipInputStream;
@Service
public class AutoToolsServiceImpl implements AutoToolsService{
@Resource
private StuPaperFileService stuPaperFileService;
@Resource
ConfigService configService;
@Resource
IExamQuestionService examQuestionService;
@Resource
JudgementService judgementService;
@Override
public String downloadStudentFile(String fileUrl, String filePath) {
@@ -94,4 +112,66 @@ public class AutoToolsServiceImpl implements AutoToolsService{
return null;
}
}
@Override
public CommonResult<Double> judgementScore(Long stuId, String paperId) {
double score = 0;
// 1、通过学号,试卷ID查询文件路径
StuPaperFileDO stuPaperFileDO = stuPaperFileService.findByStuIDAndPaperId(stuId, paperId);
// 2、判断文件路径是否存在
if (stuPaperFileDO == null) {
return CommonResult.error(100031, "试题文件没有上传,无法判分!");
}
// 3、下载文件
// 获取平台文件参数
ConfigDO config = configService.getConfigByKey("file_down_path");
String patn = downloadStudentFile(stuPaperFileDO.getUrl(), config.getValue());
// 4、获取到得是zip文件需要解压
String stuFilePath = unzipToNamedFolder(patn);
// 5、解压之后得文件获取文件夹和文件
File folder = new File(stuFilePath);
File[] files = folder.listFiles();
String stu_files = null;
// 5.1、 只查询文件夹 (学号-试卷ID-试题ID-具体内容)
if (files == null) return CommonResult.error(100032, "1、试题文件上传目录不正确");
if (files.length > 1) return CommonResult.error(100033, "2、试题文件上传目录不正确");
if (!files[0].isDirectory()) return CommonResult.error(100034, "3、试题文件上传目录不正确");
// 判断学号是否正确
if (!files[0].getName().equals(stuId.toString())) return CommonResult.error(100035, "文件与学号匹配异常");
// 5.2、查询试题ID
File folders = new File(files[0].getPath());
File[] filess = folders.listFiles();
if (filess == null) return CommonResult.error(100036, "4、试卷文件上传目录不正确");
if (filess.length > 1) return CommonResult.error(100037, "5、试卷文件上传目录不正确");
if (!filess[0].isDirectory()) return CommonResult.error(100038, "6、试卷文件上传目录不正确");
// 判断学号是否正确
if (!files[0].getName().equals(paperId)) return CommonResult.error(100039, "文件与试卷匹配异常");
// 5.3、查询出来所有试题
File qu_files = new File(filess[0].getPath());
// 所有试题文件夹
File[] filess_qu = qu_files.listFiles();
if (filess_qu == null) return CommonResult.error(100040, "没有试题文件!");
for (File file : filess_qu) {
// 6、根据试题ID查询试题详情
ExamQuestion examQuestion = examQuestionService.selectExamQuestionByQuId(file.getName());
// 7、进行对应得判分
// --- 7.1、查询试题文件
File qu_file = new File(file.getPath());
File[] qu_file_list = qu_files.listFiles();
if (qu_file_list == null) continue;
// --- 7.2、通过文件名称进行判分
for (File file_one : qu_file_list) {
// 判断名称 类似于 C语言程序设计。
if (file_one.getName().split("\\.")[0].equals(examQuestion.getCourseName()+examQuestion.getSubjectName())) {
double c_score = judgementService.ProgrammingC(15.0, file.getPath(), file_one.getName(), examQuestion);
score += c_score;
break;
}
// wps 类型存在多级文文件夹,需要个性化设置
// if ()
}
}
return CommonResult.success(score);
}
}

View File

@@ -12,11 +12,12 @@ public interface JudgementService {
/**
* 程序设计判分
* @param examQuestion 程序设计题内容
* @param path 文件路径
* @param fileName 文件名称
* @param pathC 文件路径 C语言文件
* @param score 分数
* @return 返回判分
*/
public double ProgrammingC(double score, String path, ExamQuestion examQuestion);
public double ProgrammingC(double score, String pathC, String fileName, ExamQuestion examQuestion);
/**

View File

@@ -21,11 +21,11 @@ public class JudgementServiceImpl implements JudgementService
/**
* 程序设计判分
* @param examQuestion 程序设计题内容
* @param path 文件路径
* @param fileName 文件名称
* @param score 分数
* @return 返回判分
*/
public double ProgrammingC(double score, String path, ExamQuestion examQuestion) {
public double ProgrammingC(double score, String pathC, String fileName, ExamQuestion examQuestion) {
// 关键字比对,超过权重-测试用例/运行(测试用例全对,直接满分-不全对)-结果,不超过权重只给关键字几个的分
// 获取该题有多少分
@@ -61,11 +61,9 @@ public class JudgementServiceImpl implements JudgementService
// 编译分数分数占比
double pass_score = score * is_pass_score;
// 试卷其中有C语言的试题
String path_c = path + "/" + examQuestion.getQuBankName();
// 创建log文件txt用于记录
LogFileUtils.createFile(path_c + "/log.txt");
String code = JudgementCUtils.readFile(path_c, examQuestion.getQuId()+".txt");
LogFileUtils.createFile(pathC + "/log.txt");
String code = JudgementCUtils.readFile(pathC, fileName);
LogFileUtils.writeLine("✅ 系统开始读取文件:" + code);
if (code == null) {
// 如果没有读到源码

View File

@@ -2,8 +2,10 @@ package pc.exam.pp.module.judgement.service.wps_word;
import pc.exam.pp.module.exam.dal.dataobject.ExamQuestion;
import pc.exam.pp.module.judgement.utils.wps_word.vo.WordVO;
import java.math.BigDecimal;
import java.util.List;
/**
@@ -20,4 +22,14 @@ public interface JudgementWpsWordService {
* @throws Exception 异常
*/
public List<WordVO> ProgrammingWpsWord(String path) throws Exception;
/**
* 读取考生文件,与题型中要求进行判断
* @param path 文件路径
* @param examQuestion 试题参数
* @param sorce 试题分数
* @return 得分
* @throws Exception 异常
*/
public BigDecimal judgementWpsWord(BigDecimal sorce, String path, ExamQuestion examQuestion) throws Exception;
}

View File

@@ -4,6 +4,8 @@ package pc.exam.pp.module.judgement.service.wps_word;
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.infra.dal.dataobject.config.ConfigDO;
import pc.exam.pp.module.infra.service.config.ConfigService;
import pc.exam.pp.module.judgement.controller.admin.WpsWord.vo.WordListReqVO;
@@ -14,6 +16,8 @@ import pc.exam.pp.module.judgement.utils.wps_word.WpsWordUtils;
import pc.exam.pp.module.judgement.utils.wps_word.vo.WordVO;
import java.io.File;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
@Service
@@ -46,5 +50,31 @@ public class JudgementWpsWordServiceImpl implements JudgementWpsWordService {
return margins1;
}
@Override
public BigDecimal judgementWpsWord(BigDecimal sorce, String path, ExamQuestion examQuestion) throws Exception {
BigDecimal wps_word_sorce = new BigDecimal(0);
// 1、查询Word考点tree
WordListReqVO wordListReqVO = new WordListReqVO();
wordListReqVO.setBelongTo(0);
List<WpsWordLinkDO> list = wpsWordLinkMapper.selectList(wordListReqVO);
// 2、docx文件读取并返回考点及说明信息
List<WordVO> margins1 = WpsWordUtils.wps_word(path, list);
// 3、获取答案得组成
List<ExamQuestionAnswer> answerList = examQuestion.getAnswerList();
// 4、进行关联判断
for (ExamQuestionAnswer examQuestionAnswer : answerList) {
for (WordVO wordVO : margins1) {
for (String str : wordVO.getExamKeynote()) {
if (str.equals(examQuestionAnswer.getContent())) {
// 得分 根据权重进行得分 每个选项分值 = 总分 / 总权重
BigDecimal one_sorce = sorce.multiply(new BigDecimal(examQuestionAnswer.getScoreRate())).setScale(2, RoundingMode.HALF_UP);
wps_word_sorce = wps_word_sorce.add(one_sorce);
}
}
}
}
return wps_word_sorce;
}
}