修改了一些前端展示细节,完成自动批阅功能实现。
This commit is contained in:
parent
5fd14d4684
commit
f53d9efe79
|
|
@ -57,7 +57,7 @@ export default {
|
|||
|
||||
runPlagiarism:(data) => request.post('/plagiarism/runPlagiarism', data),//运行查重算法
|
||||
|
||||
|
||||
autoScore:(data) => request.post('/problem/autoscore', data),//运行自动批阅
|
||||
//保存文件名到数据库
|
||||
saveInfoToProps: (data) => request.post('/problem/saveInfoToProps', data),
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<footer f-c-c flex-col text-14 color="#6a6a6a">
|
||||
<p>报告自动评测系统</p>
|
||||
<p>报告自动批阅系统</p>
|
||||
<p>Copyright © 2023-2024 . All Rights Reserved.</p>
|
||||
<p>技术支持:Turbo Email:11249242@qq.com</p>
|
||||
</footer>
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@
|
|||
>
|
||||
<LoginForm
|
||||
:login="api.login"
|
||||
:title="isAdminEnd() ? '报告自动评测系统 - 管理端' : '报告自动评测系统 - 登录'"
|
||||
:title="isAdminEnd() ? '报告自动批阅系统 - 管理端' : '报告自动批阅系统 - 登录'"
|
||||
@close="userStore.closeLoginModal"
|
||||
/>
|
||||
</n-modal>
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ const columns = [
|
|||
align: 'center',
|
||||
render: (row) => {
|
||||
const statusText = row.status; // 假设分数存储在row.status
|
||||
const isPlagiarized = row.plagiarismStatus === "2";//疑似抄袭
|
||||
const isPlagiarized = row.plagiarismStatus === "疑似抄袭";
|
||||
// 使用内联样式标红
|
||||
const style = isPlagiarized ? { color: 'red' } : {};
|
||||
// 如果使用内联样式
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
<!-- 整个页面外层container -->
|
||||
<div class="container">
|
||||
<!-- 测试标题 -->
|
||||
<p id="indexTitle" class="lead">在线报告评测系统(首页)</p>
|
||||
<p id="indexTitle" class="lead">在线报告批阅系统(首页)</p>
|
||||
<!-- 图片和文字说明的外层容器 -->
|
||||
<div class="index-content">
|
||||
<!-- 图片 -->
|
||||
|
|
|
|||
|
|
@ -1,13 +0,0 @@
|
|||
<template>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "index"
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
|
|
@ -93,8 +93,9 @@ const onSaveAndSubmit = async () => {//保存并提交
|
|||
};
|
||||
const res = await api.submitInfoToProps(submitReport1);
|
||||
|
||||
// 提交成功后,调用查重函数并后台挂起
|
||||
// 提交成功后,调用查重函数与自动批阅并后台挂起
|
||||
checkPlagiarismInBackground();
|
||||
autoScoreBackground();
|
||||
emit('clickSaveAndSubmit');
|
||||
emit('refreshAttachment');
|
||||
ElMessage.success('提交成功!正在后台进行查重...');
|
||||
|
|
@ -165,6 +166,28 @@ const checkPlagiarismInBackground = async () => {
|
|||
}
|
||||
});
|
||||
|
||||
// 自动批阅函数
|
||||
const autoScoreBackground = async () => {
|
||||
try{
|
||||
// 获取文件名
|
||||
const attachment = props.attachment;
|
||||
const adminuserId =props.adminuserId;
|
||||
const problemId = ProblemId;
|
||||
const submitReport = {
|
||||
adminuserId,
|
||||
problemId,
|
||||
attachment
|
||||
};
|
||||
|
||||
// 调用自动批阅接口,同样使用永不超时longRequest
|
||||
const res1 = await longRequest.post('/problem/autoscore', submitReport);
|
||||
console.log('查重结果:', res1);
|
||||
} catch (error) {
|
||||
ElMessage.error('自动批阅过程中发生错误!');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
|
|
|||
|
|
@ -144,8 +144,12 @@
|
|||
<scope>system</scope>
|
||||
<systemPath>${project.basedir}/src/main/WEB-INF/lib/jave-1.0.2.jar</systemPath>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- 执行外部命令-->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-exec</artifactId>
|
||||
<version>1.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-codec</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
|
|
|
|||
|
|
@ -16,6 +16,10 @@ import org.springframework.web.bind.annotation.*;
|
|||
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.sql.Timestamp;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -522,7 +526,6 @@ public class ProblemController {
|
|||
submitReport.setReadTime(now);
|
||||
|
||||
|
||||
|
||||
boolean result = problemServiceI.saveSubmitInfoToProps(submitReport);//直接调用保存逻辑
|
||||
if (result) {
|
||||
return RespBean.ok("领取成功");
|
||||
|
|
@ -530,4 +533,47 @@ public class ProblemController {
|
|||
return RespBean.error("领取失败");
|
||||
}
|
||||
}
|
||||
|
||||
//自动批改作业返回分数
|
||||
@PostMapping("/autoscore")
|
||||
public RespBean autoscore(@RequestBody SubmitReport submitReport, HttpServletRequest request) {
|
||||
DecodeToken decodeToken = new DecodeToken(request);
|
||||
String userIdStr = decodeToken.getUserId();
|
||||
int userId = Integer.parseInt(userIdStr);
|
||||
submitReport.setStudentId(userId);
|
||||
|
||||
// 构建文件路径
|
||||
String uploadDirectory = System.getProperty("user.dir") + File.separator + "upload";
|
||||
Path filePath = Paths.get(uploadDirectory, submitReport.getAttachment());
|
||||
|
||||
// 检查文件是否存在
|
||||
if (!Files.exists(filePath)) {
|
||||
return RespBean.error("文件不存在");
|
||||
}
|
||||
// 调用Service层进行批改
|
||||
AutoScoreResult autoScoreResult =new AutoScoreResult();
|
||||
autoScoreResult.setTotalScore(-1.0);
|
||||
// 调用Service层进行批改
|
||||
autoScoreResult = problemServiceI.getAutoScore(filePath, submitReport.getProblemId());
|
||||
//自动批阅结果存数据库
|
||||
Float autoScore =(float) autoScoreResult.getTotalScore();
|
||||
submitReport.setAutoscore(autoScore);
|
||||
// 将所有的评语合并为一句,中间用分号隔开
|
||||
List<String> remarks = autoScoreResult.getRemarks();
|
||||
String combinedRemarks = String.join("; ", remarks);
|
||||
submitReport.setAutocomment(combinedRemarks);
|
||||
|
||||
boolean saveresult = problemServiceI.saveAutoScoreResultToProps(submitReport);
|
||||
|
||||
if(saveresult) {
|
||||
return RespBean.ok("批改完成,已保存数据!");
|
||||
}
|
||||
else{
|
||||
return RespBean.error("批改过程中发生错误!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -27,4 +27,6 @@ public interface SubmitReportDaoI extends BaseDaoI<SubmitReport> {
|
|||
public boolean withdrawReportSubmitted(SubmitReport submitReport);
|
||||
public String getReportSubmittedStatus(SubmitReport submitReport);
|
||||
public boolean savePlagiarismResult(SubmitReport submitReport);
|
||||
public boolean saveAutoScoreResult(SubmitReport submitReport);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -427,4 +427,29 @@ public class SubmitReportDaoImpl extends BaseDaoImpl<SubmitReport> implements Su
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean saveAutoScoreResult(SubmitReport submitReport) {
|
||||
Session session = this.getCurrentSession();
|
||||
try {
|
||||
String hql = "UPDATE SubmitReport SET autoscore = :autoscore, " +
|
||||
"autocomment = :autocomment " +
|
||||
"WHERE problemId = :problemId " +
|
||||
"AND adminuserId = :adminuserId " +
|
||||
"AND studentId = :studentId";
|
||||
|
||||
Query query = session.createQuery(hql);
|
||||
query.setParameter("autoscore", submitReport.getAutoscore());
|
||||
query.setParameter("autocomment", submitReport.getAutocomment());
|
||||
query.setParameter("problemId", submitReport.getProblemId());
|
||||
query.setParameter("adminuserId", submitReport.getAdminuserId());
|
||||
query.setParameter("studentId", submitReport.getStudentId());
|
||||
|
||||
int result = query.executeUpdate();
|
||||
return result > 0;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package com.example.aes.problem.model;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class AutoScoreResult {
|
||||
private double totalScore;
|
||||
private List<String> remarks;
|
||||
|
||||
public AutoScoreResult(double totalScore, List<String> remarks) {
|
||||
this.totalScore = totalScore;
|
||||
this.remarks = remarks;
|
||||
}
|
||||
|
||||
public AutoScoreResult() {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -141,6 +141,20 @@ public class PlagiarismServiceImpl implements PlagiarismServiceI {
|
|||
|
||||
return content;
|
||||
}
|
||||
public String readFileWithoutClean(String filePath) {
|
||||
String fileExtension = getFileExtension(filePath).toLowerCase();
|
||||
String content = "";
|
||||
|
||||
if (fileExtension.equals("txt")) {
|
||||
content = readTextFile(filePath);
|
||||
} else if (fileExtension.equals("doc")||fileExtension.equals("docx")) {
|
||||
content = readDocFile(filePath);
|
||||
} else if (fileExtension.equals("pdf")) {
|
||||
content = readPdfFile(filePath);
|
||||
}
|
||||
|
||||
return content;
|
||||
}
|
||||
//读取.txt文件
|
||||
public String readTextFile(String filePath) {
|
||||
StringBuilder contentBuilder = new StringBuilder();
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.example.aes.problem.service.Impl;
|
|||
|
||||
import com.example.aes.problem.dao.*;
|
||||
import com.example.aes.problem.model.*;
|
||||
import com.example.aes.problem.service.PlagiarismServiceI;
|
||||
import com.example.aes.problem.service.ProblemServiceI;
|
||||
import com.example.aes.user.dao.AdminusersDaoI;
|
||||
import com.example.aes.user.dao.ClassesDaoI;
|
||||
|
|
@ -9,6 +10,10 @@ import com.example.aes.user.model.DataGrid;
|
|||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.file.Path;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
|
@ -26,6 +31,10 @@ public class ProblemServiceImpl implements ProblemServiceI {
|
|||
private AdminusersDaoI adminusersDao;
|
||||
private PostProblemDaoI postProblemDao;
|
||||
private ClassesDaoI classesDao;
|
||||
|
||||
@Autowired
|
||||
private PlagiarismServiceI plagiarismServiceI;
|
||||
|
||||
@Autowired
|
||||
public void setClassesDao(ClassesDaoI classesDao) {
|
||||
this.classesDao = classesDao;
|
||||
|
|
@ -525,6 +534,69 @@ public int redoReport(PMReviewMessage pmReviewMessage){
|
|||
return studentSubmitDao.savePlagiarismResult(submitReport);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AutoScoreResult getAutoScore(Path filePath, int problemId) {
|
||||
// 读取报告文件内容
|
||||
String reportContent = (plagiarismServiceI.readFileWithoutClean(filePath.toString()));
|
||||
|
||||
// 从数据库获取评分标准
|
||||
List<ScoringStandard> standards = scoringStandardDao.getStandardIdByProblemId(problemId);
|
||||
double totalScore = 0.0;
|
||||
List<String> remarks = new ArrayList<>(); // 用于存储评语
|
||||
|
||||
for (ScoringStandard standard : standards) {
|
||||
String dimension = standard.getDimension();
|
||||
// 根据standardId获取评分细则
|
||||
List<ScoringRubric> rubrics = scoringRubricDao.getScoringRubricByStandardId(standard.getId());
|
||||
// 如果找到了评分细则,格式化dimension字符串
|
||||
if (rubrics != null && !rubrics.isEmpty()) {
|
||||
StringBuilder dimensionBuilder = new StringBuilder(dimension + ":");
|
||||
for (int i = 0; i < rubrics.size(); i++) {
|
||||
ScoringRubric rubric = rubrics.get(i);
|
||||
if (i > 0) {
|
||||
dimensionBuilder.append(";"); // 分隔不同的细则
|
||||
}
|
||||
dimensionBuilder.append(rubric.getLowerLimit())
|
||||
.append("分~")
|
||||
.append(rubric.getUpperLimit())
|
||||
.append("分,")
|
||||
.append(rubric.getDescription());
|
||||
}
|
||||
dimension = dimensionBuilder.toString();
|
||||
}
|
||||
double weight = standard.getWeight();
|
||||
String scoreStr = null;
|
||||
try { // 调用Python脚本进行评分
|
||||
scoreStr = executePythonScript(reportContent, dimension);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
// 使用逗号分割评分和评语
|
||||
String[] scoreAndReason = scoreStr.split("\n");
|
||||
if (scoreAndReason.length < 2) {
|
||||
throw new RuntimeException("Python脚本输出格式不正确");
|
||||
}
|
||||
double score = Double.parseDouble(scoreAndReason[0].replace("score: ", "").trim());
|
||||
String reason = scoreAndReason[1].replace("reason: ", "").trim();
|
||||
|
||||
// 存储评语
|
||||
remarks.add(reason);
|
||||
// 计算加权分数
|
||||
totalScore += score * weight;
|
||||
}
|
||||
// 将总分转换为100分制
|
||||
totalScore *= 10;
|
||||
// 返回评分和评语
|
||||
return new AutoScoreResult(totalScore, remarks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean saveAutoScoreResultToProps(SubmitReport submitReport) {
|
||||
return studentSubmitDao.saveAutoScoreResult(submitReport);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int editPostProblem(int classId,
|
||||
int problemId,LocalDateTime startTime,LocalDateTime endTime,boolean allow){
|
||||
|
|
@ -654,4 +726,33 @@ public int redoReport(PMReviewMessage pmReviewMessage){
|
|||
}
|
||||
}
|
||||
}
|
||||
private String executePythonScript(String content, String dim) throws IOException, InterruptedException {
|
||||
// 构建Python命令
|
||||
String pythonCommand = String.format("python original.py \"%s\" \"%s\"", content, dim);
|
||||
|
||||
// 执行Python脚本
|
||||
Process process = Runtime.getRuntime().exec(pythonCommand);
|
||||
int exitCode = process.waitFor();
|
||||
|
||||
if (exitCode != 0) {
|
||||
throw new RuntimeException("Python脚本执行失败");
|
||||
}
|
||||
|
||||
// 读取输出
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
||||
StringBuilder output = new StringBuilder();
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
output.append(line).append("\n");
|
||||
}
|
||||
reader.close();
|
||||
|
||||
String scoreAndReason = output.toString().trim();
|
||||
|
||||
if (scoreAndReason == null || scoreAndReason.isEmpty()) {
|
||||
throw new RuntimeException("Python脚本输出为空");
|
||||
}
|
||||
|
||||
return scoreAndReason;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,5 +10,5 @@ import java.util.List;
|
|||
public interface PlagiarismServiceI {
|
||||
|
||||
public PlagiarismResult checkPlagiarism(String toString, String uploadDirectory);
|
||||
|
||||
public String readFileWithoutClean(String filePath);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import com.example.aes.problem.model.DataGrid;
|
|||
import com.example.aes.user.model.*;
|
||||
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import java.nio.file.Path;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
|
|
@ -64,4 +65,6 @@ public interface ProblemServiceI {
|
|||
public boolean withdrawSubmitInfo(SubmitReport submitReport);//学生撤回报告
|
||||
public String findReportSubmittedStatus(SubmitReport submitReport);//查询该学生之前已经提交过该问题的报告状态
|
||||
public boolean savePlagiarismResultToProps(SubmitReport submitReport);//保存查重信息
|
||||
public AutoScoreResult getAutoScore(Path filePath, int problemId);//自动批阅
|
||||
public boolean saveAutoScoreResultToProps(SubmitReport submitReport);//保存自动批阅信息
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue