diff --git a/AES-front/src/api/user.js b/AES-front/src/api/user.js index 4638c04..ccb2a3d 100644 --- a/AES-front/src/api/user.js +++ b/AES-front/src/api/user.js @@ -34,6 +34,21 @@ export default { getPostProblemInfo:(config) => request.get('/problem/getPostProblemInfo', config),//»ñȡµ±ǰ±¨¸沼ÖÃÐÅϢ - findProblemById1:(config)=>request.get('/problem/findProblemById1',config)//»ñȡµ±ǰ±¨¸æ¾ßÌåÐÅϢ + findProblemById1:(config)=>request.get('/problem/findProblemById1',config),//»ñȡµ±ǰ±¨¸æ¾ßÌåÐÅϢ + getSubmitReport:(config) => request.get('/problem/getSubmitReport', config),//»ñȡѧÉúÒÑÉϴ«±¨¸æÐÅϢ + + //Îļþ´¦Àí²¿·Ö + uploadFiles: (data) => + request({ + url: '/importClassStudentsFile/uploadFiles', + method: 'post', + data: data, + }), //ѧÉúÉϴ«Îļþ + + downloadFile: (fileName) => + request({ + url: `/downloadFile/downloadFile/${fileName}`, + method: 'get', + }), // ÎļþÏÂÔØ } diff --git a/AES-front/src/views/user/report-submit/components/leftparts.vue b/AES-front/src/views/user/report-submit/components/leftparts.vue index 6635036..18fae11 100644 --- a/AES-front/src/views/user/report-submit/components/leftparts.vue +++ b/AES-front/src/views/user/report-submit/components/leftparts.vue @@ -12,29 +12,59 @@
实验提交
- - 上传附件 - +
+ 上传附件 +
+ 已上传文件: + +
+ + + + + +
将文件拖到此处,或点击上传
+
+ + 取消 + 确定 + +
+ + + \ No newline at end of file diff --git a/AES-front/src/views/user/report-submit/components/report-actions.vue b/AES-front/src/views/user/report-submit/components/report-actions.vue index 0ab4a4e..0e18981 100644 --- a/AES-front/src/views/user/report-submit/components/report-actions.vue +++ b/AES-front/src/views/user/report-submit/components/report-actions.vue @@ -1,8 +1,8 @@ diff --git a/AES-front/src/views/user/report-submit/components/rightparts.vue b/AES-front/src/views/user/report-submit/components/rightparts.vue index b8f0c42..ceb56ef 100644 --- a/AES-front/src/views/user/report-submit/components/rightparts.vue +++ b/AES-front/src/views/user/report-submit/components/rightparts.vue @@ -27,7 +27,7 @@ const plagiarismStatus = ref(0); // 初始化抄袭状态 const getJudgeInfo = async () => { // 查询批阅相关信息 try { - const res = await api.getStudentRank({ params: { examId } }); + const res = await api.getSubmitReport({ params: { examId } }); comment.value = res.data.comment; // 更新教师评语 plagiarismStatus.value = res.data.plagiarismStatus; // 更新抄袭状态 } catch (error) { diff --git a/AES-front/src/views/user/report-submit/index.vue b/AES-front/src/views/user/report-submit/index.vue index a566ff2..fcc365c 100644 --- a/AES-front/src/views/user/report-submit/index.vue +++ b/AES-front/src/views/user/report-submit/index.vue @@ -14,21 +14,20 @@ - diff --git a/AES-front/src/views/user/score-rank/components/personal-rank.vue b/AES-front/src/views/user/score-rank/components/personal-rank.vue index 96bc2cf..aa77a88 100644 --- a/AES-front/src/views/user/score-rank/components/personal-rank.vue +++ b/AES-front/src/views/user/score-rank/components/personal-rank.vue @@ -20,7 +20,7 @@ const examId = route.params.examId; const classId = route.params.classId; const title = ref(""); // 从API获取的作业名称 const score = ref(0); // 个人得分 -const rank = ref(0); // 个人排名 +const rank = ref("-"); // 个人排名,默认为 "-" const totalStudents = ref(0); // 班级总人数 const paginationReactive = reactive({ @@ -53,18 +53,20 @@ const queryExamScores = async () => { const res = await api.getStudentRank({ params: { examId } }); + title.value = res.data.title; // 更新作业名称 + score.value = res.data.score; // 更新个人得分 + rank.value = res.data.rank || "-"; // 更新个人排名,如果rank为空则显示 "-" +}; + +const queryClassStudents = async () => { //查询班级总人数 const res1 = await api.getClassStudents({ params: { classId } }); - - title.value = res.data.title; // 更新作业名称 - score.value = res.data.score; // 更新个人得分 - rank.value = res.data.rank; // 更新个人排名 + console.log(res1); totalStudents.value = res1.data;// 更新班级总人数 }; - // 行键函数 const rowKey = (rowData) => { return rowData.id; @@ -73,6 +75,7 @@ const rowKey = (rowData) => { // 生命周期钩子 onMounted(() => { queryExamScores(); // 挂载时查询成绩 + queryClassStudents();// 同时查询班级人数 }); diff --git a/AES/src/main/java/com/example/aes/problem/controller/ProblemController.java b/AES/src/main/java/com/example/aes/problem/controller/ProblemController.java index 344fff7..2258548 100644 --- a/AES/src/main/java/com/example/aes/problem/controller/ProblemController.java +++ b/AES/src/main/java/com/example/aes/problem/controller/ProblemController.java @@ -359,7 +359,22 @@ public class ProblemController { if (ureportsubmitted != null) { return RespBean.ok("查询成绩排名成功!", ureportsubmitted); } else { - return RespBean.error("查询成绩排名失败!"); + return RespBean.error("尚未提交作业!暂时无法查看排名!"); + } + } + + //根据作业id和学生id获取学生当前报告成绩排名,与上一方法基本类似,处理空搜索时的输出 + @GetMapping("/getSubmitReport") + public RespBean getSubmitReport(Integer examId, HttpServletRequest request) { + DecodeToken decodeToken = new DecodeToken(request); + String UserId = decodeToken.getUserId(); + int userId = Integer.parseInt(UserId); + UReportSubmitted ureportsubmitted = + problemServiceI.findScoreAndRankByIds(examId, userId); + if (ureportsubmitted != null) { + return RespBean.ok("查询成绩排名成功!", ureportsubmitted); + } else { + return RespBean.ok("尚未提交作业!"); } } diff --git a/AES/src/main/java/com/example/aes/user/controller/DownLoadFileController.java b/AES/src/main/java/com/example/aes/user/controller/DownLoadFileController.java index 0295b1a..1fe0aa4 100644 --- a/AES/src/main/java/com/example/aes/user/controller/DownLoadFileController.java +++ b/AES/src/main/java/com/example/aes/user/controller/DownLoadFileController.java @@ -2,10 +2,15 @@ package com.example.aes.user.controller; import cn.hutool.core.io.FileUtil; +import cn.hutool.core.io.resource.UrlResource; import com.example.aes.global.model.RespBean; import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -13,6 +18,8 @@ import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; import java.io.*; import java.net.URLEncoder; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; @@ -139,4 +146,25 @@ public class DownLoadFileController { } } + // 提供文件下载的方法 + @GetMapping("/downloadFile/{fileName:.+}") + public ResponseEntity downloadFile(@PathVariable String fileName) { + try { + String root = System.getProperty("user.dir") + File.separator + "upload"; + Path filePath = Paths.get(root).toAbsolutePath().normalize().resolve(fileName); + javax.annotation.Resource resource = (javax.annotation.Resource) new UrlResource(filePath.toUri()); + String contentType = "application/octet-stream"; + return ResponseEntity.ok() + .contentType(MediaType.parseMediaType(contentType)) + .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + resource.name() + "\"") + .body(resource); + } catch (Exception e) { + e.printStackTrace(); + return ResponseEntity.badRequest() + .body(null); + } + } + + + } diff --git a/AES/src/main/java/com/example/aes/user/controller/importClassStudentsFileController.java b/AES/src/main/java/com/example/aes/user/controller/importClassStudentsFileController.java index 1a26ad4..30ef793 100644 --- a/AES/src/main/java/com/example/aes/user/controller/importClassStudentsFileController.java +++ b/AES/src/main/java/com/example/aes/user/controller/importClassStudentsFileController.java @@ -1,6 +1,7 @@ package com.example.aes.user.controller; import cn.hutool.core.io.FileUtil; +import cn.hutool.core.io.resource.UrlResource; import com.example.aes.global.model.RespBean; import com.example.aes.user.dao.AdminusersDaoI; import com.example.aes.user.dao.ClassesDaoI; @@ -11,19 +12,21 @@ import com.example.aes.user.model.PMUser; import com.example.aes.user.model.Users; import com.example.aes.user.service.UserServiceI; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; import java.io.*; +import java.nio.file.Path; +import java.nio.file.Paths; import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Date; -import java.util.List; +import java.util.*; @RestController @@ -374,4 +377,79 @@ public class importClassStudentsFileController{ return true; } + @PostMapping("/uploadFiles") // 学生上传文件并提供其URL + public ResponseEntity> uploadFiles(MultipartFile[] files) { + Map response = new HashMap<>(); + try { + // 获取文件存储根目录 + String root = System.getProperty("user.dir") + File.separator + "upload"; + if (!new File(root).exists()) { + new File(root).mkdirs(); + } + + // 用于存储所有上传文件的名称和URL + StringBuilder fileNames = new StringBuilder(); + StringBuilder fileUrls = new StringBuilder(); + + for (MultipartFile file : files) { + // 获取文件原始名 + String uploadFileName = file.getOriginalFilename(); + + // 检查文件类型 + if (!uploadFileName.endsWith(".txt") && !uploadFileName.endsWith(".doc") && + !uploadFileName.endsWith(".docx") && !uploadFileName.endsWith(".pdf")) { + throw new IllegalArgumentException("不支持的文件类型: " + uploadFileName); + } + + // 获取主要名称 + String mainName = FileUtil.mainName(uploadFileName); + // 获取文件后缀名 + String extName = FileUtil.extName(uploadFileName); + // 用当前时间避免重复 + SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss"); + Date date1 = new Date(); + String timeStamp = formatter.format(date1); + + // 构造新的文件名 + String newFileName = mainName + "_" + timeStamp + "." + extName; + + // 构造文件保存路径 + String filePath = root + File.separator + newFileName; + + // 保存文件到服务器 + File dest = new File(filePath); + file.transferTo(dest); + + // 构造文件访问URL + String fileDownloadUri = ServletUriComponentsBuilder.fromCurrentContextPath() + .path("/downloadFile/") + .path(newFileName) + .toUriString(); + + // 添加文件名和URL到返回信息中 + fileNames.append(newFileName).append(", "); + fileUrls.append(fileDownloadUri).append(", "); + } + + // 移除最后一个逗号和空格 + if (fileNames.length() > 0) { + fileNames.setLength(fileNames.length() - 2); + } + if (fileUrls.length() > 0) { + fileUrls.setLength(fileUrls.length() - 2); + } + + response.put("code", 0); + response.put("message", "文件上传成功"); + response.put("data", fileNames.toString()); + response.put("urls", fileUrls.toString()); + return ResponseEntity.ok(response); + } catch (Exception e) { + e.printStackTrace(); + response.put("code", 1); + response.put("message", "文件上传异常: " + e.getMessage()); + return ResponseEntity.badRequest().body(response); + } + } + } diff --git a/upload/t1_20250413215728.txt b/upload/t1_20250413215728.txt new file mode 100644 index 0000000..b9add5b --- /dev/null +++ b/upload/t1_20250413215728.txt @@ -0,0 +1,4 @@ +智能手机在当代社会的作用不可小觑,它不仅使得人们的通讯变得极为便捷,还提供了多样化的娱乐和工作功能。在我国,智能手机的普及率不断上升,几乎成了每个人生活中的必需品。它的多功能性和便携性,使其成为了现代科技的一个标志性产物。无论是通讯、娱乐还是学习,都离不开这款电子设备。 +在城市边缘的那所著名大学的操场上,一场几千人参加的批斗会已经进行了近两个小时。 +“爱因斯坦是反动的学术权威,他有奶便是娘,跑去为美帝国主义造原子弹!要建立起革命的科学,就要打倒以相对论为代表的资产阶级理论黑旗!” +然后在法文词下列出同义的上海方言词语,再尽可能详尽地列出近义的上海方言词语、短语或句子。这种编写方式,对中法两国学习者或词典使用者尽可能多地掌握法汉词汇,显然是很有意义的。 \ No newline at end of file