Преглед на файлове

update offline submitPaper api

deason преди 3 години
родител
ревизия
ffd388f6ab

+ 18 - 42
examcloud-core-oe-admin-api-provider/src/main/java/cn/com/qmth/examcloud/core/oe/admin/api/controller/OfflineExamController.java

@@ -3,6 +3,7 @@ package cn.com.qmth.examcloud.core.oe.admin.api.controller;
 import cn.com.qmth.examcloud.api.commons.enums.ExamType;
 import cn.com.qmth.examcloud.api.commons.security.bean.User;
 import cn.com.qmth.examcloud.commons.exception.StatusException;
+import cn.com.qmth.examcloud.commons.util.FileUtil;
 import cn.com.qmth.examcloud.commons.util.MD5;
 import cn.com.qmth.examcloud.core.oe.admin.base.utils.Check;
 import cn.com.qmth.examcloud.core.oe.admin.dao.ExamRecordDataRepo;
@@ -97,56 +98,31 @@ public class OfflineExamController extends ControllerSupport {
     @ApiOperation(value = "离线考试:交卷")
     @PostMapping("/submitPaper")
     public void submitPaper(@RequestParam long examRecordDataId,
-                            @RequestPart(value = "file") MultipartFile file) throws Exception {
-        Check.isNull(file, "file不能为空");
-        Check.isNull(examRecordDataId, "examRecordDataId不能为空");
-
-        ExamRecordDataEntity examRecordData = GlobalHelper.getEntity(examRecordDataRepo, examRecordDataId, ExamRecordDataEntity.class);
-        if (examRecordData.getExamType() != ExamType.OFFLINE) {
-            throw new StatusException("OfflineExamController-submitPaper-002", "非离线考试");
-        }
-
-        boolean isEnable = examStudentService.isEnableExamStudent(examRecordData.getExamStudentId());
-        if (!isEnable) {
-            throw new StatusException("000500", "当前考生已禁用!");
-        }
-
-        String fileName = file.getOriginalFilename();
-        int index = fileName.lastIndexOf(".");
-        String fileSuffix = fileName.substring(index + 1).toUpperCase();
-
-        if (!"PDF".equals(fileSuffix) && !"ZIP".equals(fileSuffix)
-                && !"JPG".equals(fileSuffix) && !"JPEG".equals(fileSuffix) && !"PNG".equals(fileSuffix)) {
-            throw new StatusException("OfflineExamController-submitPaper-001", "文件格式不正确");
-        }
-
-        String offlineUploadFileType = ExamCacheTransferHelper.getCachedExamProperty(examRecordData.getExamId(),
-                examRecordData.getStudentId(),
-                ExamProperties.OFFLINE_UPLOAD_FILE_TYPE.name()).getValue();
-        if (StringUtils.isBlank(offlineUploadFileType) || "[]".equals(offlineUploadFileType)) {
-            throw new StatusException("OfflineExamController-submitPaper-003", "当前考试设置不允许上传附件");
-        }
-
-        if (offlineUploadFileType.indexOf(fileSuffix) < 0) {
-            throw new StatusException("OfflineExamController-submitPaper-004", "当前考试允许上传文件格式为:" + offlineUploadFileType);
-        }
+                            @RequestPart(value = "file", required = false) MultipartFile file) throws Exception {
+        Check.isNull(file, "上传文件不能为空");
+        User user = getAccessUser();
 
-        //判断文件大小
-        long fileSize = file.getSize();
-        if (fileSize > answerMaxsize * 1048576) {
-            throw new StatusException("OfflineExamController-submitPaper-005", "文件大小不能超过" + answerMaxsize + "M");
+        String fileSuffix = FileUtil.getFileSuffix(file.getOriginalFilename());
+
+        String fileType;
+        if (".zip".equals(fileSuffix)) {
+            fileType = "ZIP";
+        } else if (".pdf".equals(fileSuffix)) {
+            fileType = "PDF";
+        } else if (".jpg.jpeg.png".contains(fileSuffix)) {
+            fileType = "IMAGE";
+        } else {
+            fileType = "UNKNOWN";
         }
 
         FileInfo fileInfo = new FileInfo();
         fileInfo.setOriginalFileName(file.getOriginalFilename());
         fileInfo.setFileBytes(file.getBytes());
+        fileInfo.setFileSize(file.getSize());
         fileInfo.setFileSuffix(fileSuffix);
-        fileInfo.setFileType(fileSuffix);
-        offlineExamService.submitPaper(examRecordDataId, fileInfo);
+        fileInfo.setFileType(fileType);
 
-        User user = getAccessUser();
-        ReportsUtil.report(new AdminOperateReport(user.getRootOrgId(), user.getUserId(), "考试进度详情-上传作答",
-                "考试记录ID:" + examRecordDataId + " 考生ID:" + examRecordData.getExamStudentId()));
+        offlineExamService.submitPaper(examRecordDataId, fileInfo, user.getUserId());
     }
 
     /**

+ 9 - 39
examcloud-core-oe-admin-api-provider/src/main/java/cn/com/qmth/examcloud/core/oe/admin/api/controller/client/ExamProcessController.java

@@ -178,61 +178,31 @@ public class ExamProcessController extends ControllerSupport {
     @ApiOperation(value = "离线考试:交卷")
     @PostMapping("/submitPaper")
     public void submitPaper(@RequestParam Long examRecordDataId,
-                            @RequestPart(value = "file") MultipartFile file) throws Exception {
+                            @RequestPart(value = "file", required = false) MultipartFile file) throws Exception {
         Check.isNull(file, "上传文件不能为空");
+        User user = getAccessUser();
 
         String fileSuffix = FileUtil.getFileSuffix(file.getOriginalFilename());
-        if (!FileUtil.checkFileSuffix("jpg|jpeg|png|pdf|zip", fileSuffix)) {
-            throw new StatusException("400401", "文件格式不正确");
-        }
-
-        if (file.getSize() > Constants.ANSWER_FILE_MAX_SIZE * Constants.M_SIZE) {
-            throw new StatusException("400402", "文件大小不能超过" + Constants.ANSWER_FILE_MAX_SIZE + "M");
-        }
-
-        Optional<ExamRecordDataEntity> optional = examRecordDataRepo.findById(examRecordDataId);
-        if (!optional.isPresent()) {
-            throw new StatusException("400403", "考试记录不存在");
-        }
-
-        ExamRecordDataEntity examRecordData = optional.get();
-        if (ExamType.OFFLINE != examRecordData.getExamType()) {
-            throw new StatusException("400403", "非离线考试");
-        }
-
-        if (!examStudentService.isEnableExamStudent(examRecordData.getExamStudentId())) {
-            throw new StatusException("400403", "当前考生已禁用");
-        }
-
-        // 当前考试允许的附件类型,示例:["ZIP","PDF","IMAGE"]
-        ExamPropertyCacheBean examProperty = ExamCacheTransferHelper.getCachedExamProperty(examRecordData.getExamId(),
-                examRecordData.getStudentId(), ExamProperties.OFFLINE_UPLOAD_FILE_TYPE.name());
-        String[] settingFileTypes = new JsonMapper().toArray(examProperty.getValue(), String.class);
-        if (ArrayUtils.isEmpty(settingFileTypes)) {
-            throw new StatusException("400403", "当前考试设置不允许上传附件");
-        }
-
-        if (!matchFileTypes(settingFileTypes, fileSuffix)) {
-            throw new StatusException("400403", "当前考试允许上传文件格式为:" + examProperty.getValue());
-        }
 
-        String fileType = "IMAGE";
+        String fileType;
         if (".zip".equals(fileSuffix)) {
             fileType = "ZIP";
         } else if (".pdf".equals(fileSuffix)) {
             fileType = "PDF";
+        } else if (".jpg.jpeg.png".contains(fileSuffix)) {
+            fileType = "IMAGE";
+        } else {
+            fileType = "UNKNOWN";
         }
 
         FileInfo fileInfo = new FileInfo();
         fileInfo.setOriginalFileName(file.getOriginalFilename());
         fileInfo.setFileBytes(file.getBytes());
+        fileInfo.setFileSize(file.getSize());
         fileInfo.setFileSuffix(fileSuffix);
         fileInfo.setFileType(fileType);
-        offlineExamService.submitPaper(examRecordDataId, fileInfo);
 
-        User user = getAccessUser();
-        ReportsUtil.report(new AdminOperateReport(user.getRootOrgId(), user.getUserId(), "考试进度详情-上传作答",
-                "考试记录ID:" + examRecordDataId + " 考生ID:" + examRecordData.getExamStudentId()));
+        offlineExamService.submitPaper(examRecordDataId, fileInfo, user.getUserId());
     }
 
     @ApiOperation(value = "离线考试:多文件交卷")

+ 1 - 1
examcloud-core-oe-admin-service/src/main/java/cn/com/qmth/examcloud/core/oe/admin/service/OfflineExamService.java

@@ -37,7 +37,7 @@ public interface OfflineExamService {
      * @param examRecordDataId
      * @param fileInfo
      */
-    void submitPaper(Long examRecordDataId, FileInfo fileInfo) throws Exception;
+    void submitPaper(Long examRecordDataId, FileInfo fileInfo, Long userId);
 
     /**
      * 上传作答

+ 13 - 0
examcloud-core-oe-admin-service/src/main/java/cn/com/qmth/examcloud/core/oe/admin/service/bean/uploadfile/FileInfo.java

@@ -14,6 +14,11 @@ public class FileInfo implements JsonSerializable {
      */
     private byte[] fileBytes;
 
+    /**
+     * 文件大小
+     */
+    private long fileSize;
+
     /**
      * 原始文件名称
      */
@@ -57,6 +62,14 @@ public class FileInfo implements JsonSerializable {
         this.fileBytes = fileBytes;
     }
 
+    public long getFileSize() {
+        return fileSize;
+    }
+
+    public void setFileSize(long fileSize) {
+        this.fileSize = fileSize;
+    }
+
     public String getOriginalFileName() {
         return originalFileName;
     }

+ 66 - 6
examcloud-core-oe-admin-service/src/main/java/cn/com/qmth/examcloud/core/oe/admin/service/impl/OfflineExamServiceImpl.java

@@ -3,6 +3,9 @@ package cn.com.qmth.examcloud.core.oe.admin.service.impl;
 import cn.com.qmth.examcloud.api.commons.enums.ExamSpecialSettingsType;
 import cn.com.qmth.examcloud.api.commons.enums.ExamType;
 import cn.com.qmth.examcloud.commons.exception.StatusException;
+import cn.com.qmth.examcloud.commons.util.FileUtil;
+import cn.com.qmth.examcloud.commons.util.JsonMapper;
+import cn.com.qmth.examcloud.core.oe.admin.base.Constants;
 import cn.com.qmth.examcloud.core.oe.admin.base.utils.Check;
 import cn.com.qmth.examcloud.core.oe.admin.dao.ExamRecordDataRepo;
 import cn.com.qmth.examcloud.core.oe.admin.dao.ExamRecordFileAnswerRepo;
@@ -20,6 +23,8 @@ import cn.com.qmth.examcloud.core.oe.admin.service.bean.uploadfile.FileInfo;
 import cn.com.qmth.examcloud.core.questions.api.ExtractConfigCloudService;
 import cn.com.qmth.examcloud.core.questions.api.request.GetPaperReq;
 import cn.com.qmth.examcloud.core.questions.api.response.GetPaperResp;
+import cn.com.qmth.examcloud.reports.commons.bean.AdminOperateReport;
+import cn.com.qmth.examcloud.reports.commons.util.ReportsUtil;
 import cn.com.qmth.examcloud.support.cache.CacheHelper;
 import cn.com.qmth.examcloud.support.cache.bean.*;
 import cn.com.qmth.examcloud.support.enums.ExamProperties;
@@ -28,6 +33,8 @@ import cn.com.qmth.examcloud.support.helper.ExamCacheTransferHelper;
 import cn.com.qmth.examcloud.web.filestorage.FileStoragePathEnvInfo;
 import cn.com.qmth.examcloud.web.filestorage.YunPathInfo;
 import cn.com.qmth.examcloud.web.helpers.GlobalHelper;
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -39,6 +46,7 @@ import java.io.File;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
+import java.util.Optional;
 
 /**
  * @author chenken
@@ -263,7 +271,7 @@ public class OfflineExamServiceImpl implements OfflineExamService {
 
     @Override
     @Transactional
-    public void submitPaper(Long examRecordDataId, FileInfo fileInfo) throws Exception {
+    public void submitPaper(Long examRecordDataId, FileInfo fileInfo, Long userId) {
         Check.isNull(examRecordDataId, "examRecordDataId不能为空");
 
         SysPropertyCacheBean stuClientLoginLimit = CacheHelper.getSysProperty("STU_CLIENT_LOGIN_LIMIT");
@@ -275,12 +283,41 @@ public class OfflineExamServiceImpl implements OfflineExamService {
             throw new StatusException("4001", "系统维护中... ...");
         }
 
-        ExamRecordDataEntity examRecordData = GlobalHelper.getEntity(examRecordDataRepo, examRecordDataId, ExamRecordDataEntity.class);
-        if (examRecordData == null) {
-            return;
+        if (!FileUtil.checkFileSuffix("jpg|jpeg|png|pdf|zip", fileInfo.getFileSuffix())) {
+            throw new StatusException("400401", "文件格式不正确");
         }
 
-        //上传文件至又拍云
+        if (fileInfo.getFileSize() > Constants.ANSWER_FILE_MAX_SIZE * Constants.M_SIZE) {
+            throw new StatusException("400402", "文件大小不能超过" + Constants.ANSWER_FILE_MAX_SIZE + "M");
+        }
+
+        Optional<ExamRecordDataEntity> optional = examRecordDataRepo.findById(examRecordDataId);
+        if (!optional.isPresent()) {
+            throw new StatusException("400403", "考试记录不存在");
+        }
+
+        ExamRecordDataEntity examRecordData = optional.get();
+        if (ExamType.OFFLINE != examRecordData.getExamType()) {
+            throw new StatusException("400403", "非离线考试");
+        }
+
+        if (!examStudentService.isEnableExamStudent(examRecordData.getExamStudentId())) {
+            throw new StatusException("400403", "当前考生已禁用");
+        }
+
+        // 当前考试允许的附件类型,示例:["ZIP","PDF","IMAGE"]
+        ExamPropertyCacheBean examProperty = ExamCacheTransferHelper.getCachedExamProperty(examRecordData.getExamId(),
+                examRecordData.getStudentId(), ExamProperties.OFFLINE_UPLOAD_FILE_TYPE.name());
+        String[] settingFileTypes = new JsonMapper().toArray(examProperty.getValue(), String.class);
+        if (ArrayUtils.isEmpty(settingFileTypes)) {
+            throw new StatusException("400403", "当前考试设置不允许上传附件");
+        }
+
+        if (!matchFileTypes(settingFileTypes, fileInfo.getFileSuffix())) {
+            throw new StatusException("400403", "当前考试允许上传文件格式为:" + examProperty.getValue());
+        }
+
+        // 上传文件
         ExamRecordDataBean bean = of(examRecordData);
         String fileNewName = createOfflineFileName(bean) + fileInfo.getFileSuffix();
         String relativePath = upyunUploadUrl + examRecordData.getExamId() + "/" + fileNewName;
@@ -294,10 +331,13 @@ public class OfflineExamServiceImpl implements OfflineExamService {
         examRecordForMarkingService.saveOffLineExamRecordForMarking(bean, fileNewName, pi.getRelativePath());
 
         saveExamRecordFileAnswer(examRecordDataId, fileInfo.getOriginalFileName(), fileNewName, pi.getRelativePath(),
-                fileInfo.getFileType().toLowerCase(), fileInfo.getFileSuffix().toLowerCase());
+                fileInfo.getFileType().toLowerCase(), fileInfo.getFileSuffix().replaceFirst(".", ""));
 
         //更新考试记录状态,交卷(上传)时间
         examRecordDataRepo.updateExamRecordStatusById(examRecordDataId, ExamRecordStatus.EXAM_END, new Date());
+
+        ReportsUtil.report(new AdminOperateReport(examRecordData.getRootOrgId(), userId, "考试进度详情-上传作答",
+                "考试记录ID:" + examRecordDataId + " 考生ID:" + examRecordData.getExamStudentId()));
     }
 
     /**
@@ -369,6 +409,26 @@ public class OfflineExamServiceImpl implements OfflineExamService {
         }
     }
 
+    private boolean matchFileTypes(String[] settingFileTypes, String fileSuffix) {
+        if (ArrayUtils.isEmpty(settingFileTypes) || StringUtils.isEmpty(fileSuffix)) {
+            return false;
+        }
+
+        for (String fileType : settingFileTypes) {
+            if ("IMAGE".equals(fileType)) {
+                if (".jpg.jpeg.png".contains(fileSuffix)) {
+                    return true;
+                }
+            } else {
+                // ZIP、PDF
+                if (("." + fileType).equalsIgnoreCase(fileSuffix)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
     /**
      * 保存考试记录文件作答
      *