|
@@ -3,8 +3,12 @@ package cn.com.qmth.examcloud.core.oe.admin.api.controller.client;
|
|
|
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.JsonMapper;
|
|
|
import cn.com.qmth.examcloud.core.oe.admin.api.bean.ExamRecordDataBeanConvert;
|
|
|
import cn.com.qmth.examcloud.core.oe.admin.api.bean.ExamRecordDataDomain;
|
|
|
+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.entity.ExamRecordDataEntity;
|
|
|
import cn.com.qmth.examcloud.core.oe.admin.dao.entity.ExamRecordPaperStructEntity;
|
|
@@ -12,19 +16,25 @@ import cn.com.qmth.examcloud.core.oe.admin.dao.entity.ExamRecordQuestionsEntity;
|
|
|
import cn.com.qmth.examcloud.core.oe.admin.service.*;
|
|
|
import cn.com.qmth.examcloud.core.oe.admin.service.bean.*;
|
|
|
import cn.com.qmth.examcloud.core.oe.admin.service.bean.examscore.ObjectiveScoreInfo;
|
|
|
+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.bean.ExamPropertyCacheBean;
|
|
|
+import cn.com.qmth.examcloud.support.enums.ExamProperties;
|
|
|
+import cn.com.qmth.examcloud.support.helper.ExamCacheTransferHelper;
|
|
|
+import cn.com.qmth.examcloud.web.config.SystemProperties;
|
|
|
import cn.com.qmth.examcloud.web.helpers.GlobalHelper;
|
|
|
import cn.com.qmth.examcloud.web.support.ControllerSupport;
|
|
|
import io.swagger.annotations.Api;
|
|
|
import io.swagger.annotations.ApiOperation;
|
|
|
import io.swagger.annotations.ApiParam;
|
|
|
+import org.apache.commons.lang3.ArrayUtils;
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
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.RequestParam;
|
|
|
-import org.springframework.web.bind.annotation.RestController;
|
|
|
+import org.springframework.web.bind.annotation.*;
|
|
|
import org.springframework.web.multipart.MultipartFile;
|
|
|
|
|
|
import java.util.List;
|
|
|
+import java.util.Optional;
|
|
|
|
|
|
@Api(tags = "(客户端)考试过程相关接口")
|
|
|
@RestController
|
|
@@ -161,18 +171,79 @@ public class ExamProcessController extends ControllerSupport {
|
|
|
|
|
|
@ApiOperation(value = "离线考试:交卷")
|
|
|
@PostMapping("/submitPaper")
|
|
|
- public void submitPaper(@RequestParam(value = "file") MultipartFile file,
|
|
|
- @RequestParam long examRecordDataId) throws Exception {
|
|
|
+ public void submitPaper(@RequestPart(value = "file") MultipartFile file,
|
|
|
+ @RequestParam Long examRecordDataId) throws Exception {
|
|
|
+ Check.isNull(file, "上传文件不能为空");
|
|
|
|
|
|
+ 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("000500", "考试记录不存在");
|
|
|
+ }
|
|
|
+
|
|
|
+ ExamRecordDataEntity examRecordData = optional.get();
|
|
|
+ if (ExamType.OFFLINE != examRecordData.getExamType()) {
|
|
|
+ throw new StatusException("000500", "非离线考试");
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!examStudentService.isEnableExamStudent(examRecordData.getExamStudentId())) {
|
|
|
+ throw new StatusException("000500", "当前考生已禁用");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 当前考试允许的附件类型,示例:["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("000500", "当前考试设置不允许上传附件");
|
|
|
+ }
|
|
|
+ if (!matchFileTypes(settingFileTypes, fileSuffix)) {
|
|
|
+ throw new StatusException("000500", "当前考试允许上传文件格式为:" + examProperty.getValue());
|
|
|
+ }
|
|
|
+
|
|
|
+ // todo
|
|
|
+ // offlineExamService.submitPaper(examRecordDataId, file.getInputStream(), fileSuffix);
|
|
|
+
|
|
|
+ User user = getAccessUser();
|
|
|
+ ReportsUtil.report(new AdminOperateReport(user.getRootOrgId(), user.getUserId(), "考试进度详情-上传作答",
|
|
|
+ "考试记录ID:" + examRecordDataId + " 考生ID:" + examRecordData.getExamStudentId()));
|
|
|
}
|
|
|
|
|
|
@ApiOperation(value = "离线考试:多文件交卷")
|
|
|
@PostMapping("/batchSubmitPaper")
|
|
|
- public void batchSubmitPaper(@ApiParam(value = "文件数组") @RequestParam MultipartFile[] fileArray,
|
|
|
- @ApiParam(value = "考试记录id") @RequestParam long examRecordDataId,
|
|
|
+ public void batchSubmitPaper(@ApiParam(value = "文件数组") @RequestPart MultipartFile[] fileArray,
|
|
|
+ @ApiParam(value = "考试记录id") @RequestParam Long examRecordDataId,
|
|
|
@ApiParam(value = "文件类型:ZIP/PDF/IMAGE") @RequestParam String fileType,
|
|
|
@ApiParam(value = "md5加密的文件摘要") @RequestParam String[] fileMd5Array) throws Exception {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ 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;
|
|
|
+ }
|
|
|
+
|
|
|
}
|