xiaofei 1 год назад
Родитель
Сommit
ee501475c1

+ 68 - 0
distributed-print/src/main/java/com/qmth/distributed/print/api/mark/BaseController.java

@@ -0,0 +1,68 @@
+package com.qmth.distributed.print.api.mark;
+
+import com.qmth.boot.core.exception.ParameterException;
+import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
+import com.qmth.teachcloud.common.enums.mark.MarkPaperStatus;
+import com.qmth.teachcloud.common.util.DateDisposeUtils;
+import com.qmth.teachcloud.mark.entity.MarkPaper;
+import com.qmth.teachcloud.mark.entity.ScanBatch;
+import com.qmth.teachcloud.mark.enums.BatchStatus;
+import com.qmth.teachcloud.mark.service.MarkPaperService;
+
+import javax.annotation.Resource;
+import java.util.Date;
+
+public class BaseController {
+
+    @Resource
+    private MarkPaperService markPaperService;
+
+    /**
+     * @param examId
+     * @param paperNumber
+     */
+    public void validMarkPaperForMark(Long examId, String paperNumber) {
+        MarkPaper markPaper = markPaperService.getByExamIdAndPaperNumber(examId, paperNumber);
+        if (markPaper == null) {
+            throw ExceptionResultEnum.DATA_ERROR.exception();
+        }
+        validMarkPaperStatus(markPaper);
+        validMarkPaperMarkTime(markPaper);
+    }
+
+    public void validMarkPaperForScan(Long examId, String coursePaperId) {
+        MarkPaper markPaper = markPaperService.getByExamIdAndCoursePaperId(examId, coursePaperId);
+        if (markPaper == null) {
+            throw ExceptionResultEnum.DATA_ERROR.exception();
+        }
+        validMarkPaperStatus(markPaper);
+    }
+
+    private void validMarkPaperMarkTime(MarkPaper markPaper) {
+        if (MarkPaperStatus.FINISH.equals(markPaper.getStatus())) {
+            throw ExceptionResultEnum.MARK_PAPER_FINISH.exception();
+        }
+    }
+
+    private void validMarkPaperStatus(MarkPaper markPaper) {
+        Long markStartTime = markPaper.getMarkStartTime();
+        Long markEndTime = markPaper.getMarkEndTime();
+        if (markPaper != null && markStartTime != null && markEndTime != null) {
+            long time = System.currentTimeMillis();
+            if (time < markStartTime || time > markEndTime) {
+                String markStartTimeStr = DateDisposeUtils.parseDateToStr(DateDisposeUtils.YYYY_MM_DD_HH_MM_SS, new Date(markStartTime));
+                String markEndTimeStr = DateDisposeUtils.parseDateToStr(DateDisposeUtils.YYYY_MM_DD_HH_MM_SS, new Date(markEndTime));
+                throw ExceptionResultEnum.MARK_PAPER_OUT_MARK_TIME.exception(ExceptionResultEnum.MARK_PAPER_OUT_MARK_TIME.getMessage() + "[" + markStartTimeStr + "-" + markEndTimeStr + "]");
+            }
+        }
+    }
+
+    public void checkBatchStatus(ScanBatch b) {
+        if (b == null) {
+            throw new ParameterException("批次未找到");
+        }
+        if (BatchStatus.FINISH.equals(b.getStatus())) {
+            throw new ParameterException("批次已经完成");
+        }
+    }
+}

+ 3 - 1
distributed-print/src/main/java/com/qmth/distributed/print/api/mark/MarkController.java

@@ -38,7 +38,7 @@ import java.util.Map;
 @Api(tags = "评卷-评卷接口")
 @RestController
 @RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + "/mark")
-public class MarkController {
+public class MarkController extends BaseController {
 
     @Autowired
     private MarkService markService;
@@ -67,6 +67,7 @@ public class MarkController {
     @RequestMapping(value = "/getSetting", method = RequestMethod.POST)
     public Result getSetting(@RequestParam Long examId, @RequestParam String paperNumber,
                              @RequestParam Integer groupNumber) {
+        validMarkPaperForMark(examId, paperNumber);
         SysUser user = (SysUser) ServletUtil.getRequestUser();
         return ResultUtil.ok(markService.getSetting(user, examId, paperNumber, groupNumber));
     }
@@ -95,6 +96,7 @@ public class MarkController {
     @RequestMapping(value = "/saveTask", method = RequestMethod.POST)
     public Result saveTask(HttpServletRequest request, @RequestParam Long examId, @RequestParam String paperNumber,
                            @RequestParam Integer groupNumber, @RequestBody MarkResult markResult) {
+        validMarkPaperForMark(examId, paperNumber);
         SysUser user = (SysUser) ServletUtil.getRequestUser();
         return ResultUtil.ok(markService.saveTask(examId, paperNumber, groupNumber, user.getId(), markResult));
     }

+ 31 - 33
distributed-print/src/main/java/com/qmth/distributed/print/api/mark/ScanAnswerBatchController.java

@@ -1,33 +1,24 @@
 package com.qmth.distributed.print.api.mark;
 
 
-import com.qmth.boot.api.annotation.Aac;
-import com.qmth.teachcloud.common.util.Result;
-import com.qmth.teachcloud.common.util.ResultUtil;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.RestController;
-
 import com.qmth.boot.api.constant.ApiConstant;
 import com.qmth.boot.core.exception.ParameterException;
 import com.qmth.distributed.print.business.service.BasicExamService;
 import com.qmth.teachcloud.common.contant.SystemConstant;
 import com.qmth.teachcloud.common.entity.BasicExam;
 import com.qmth.teachcloud.common.entity.SysUser;
+import com.qmth.teachcloud.common.util.Result;
+import com.qmth.teachcloud.common.util.ResultUtil;
 import com.qmth.teachcloud.common.util.ServletUtil;
 import com.qmth.teachcloud.mark.bean.answerbatch.AnswerDomain;
-import com.qmth.teachcloud.mark.bean.answerbatch.AnswerSaveVo;
 import com.qmth.teachcloud.mark.bean.answerbatch.BatchCreateDomain;
-import com.qmth.teachcloud.mark.bean.answerbatch.BatchCreateVo;
-import com.qmth.teachcloud.mark.bean.answerbatch.BatchFinishVo;
+import com.qmth.teachcloud.mark.entity.ScanBatch;
 import com.qmth.teachcloud.mark.service.ScanBatchService;
-
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
 
 /**
  * <p>
@@ -40,35 +31,42 @@ import io.swagger.annotations.ApiOperation;
 @Api(tags = "扫描-批次")
 @RestController
 @RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + SystemConstant.PREFIX_URL_SCAN + "/answer/batch")
-public class ScanAnswerBatchController {
-	
-	@Autowired
-	private ScanBatchService scanBatchService;
-	
-	@Autowired
-	private BasicExamService basicExamService;
+public class ScanAnswerBatchController extends BaseController {
+
+    @Autowired
+    private ScanBatchService scanBatchService;
+
+    @Autowired
+    private BasicExamService basicExamService;
 
     @ApiOperation(value = "答题卡扫描批次创建")
     @RequestMapping(value = "create", method = RequestMethod.POST)
     public Result batchCreate(@Validated @RequestBody BatchCreateDomain domain) {
-    	BasicExam exam = basicExamService.getById(domain.getExamId());
-		if (exam == null) {
-			throw new ParameterException("未找到考试信息");
-		}
-		SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
-        return ResultUtil.ok(scanBatchService.batchCreate(domain,sysUser));
+        validMarkPaperForScan(domain.getExamId(), domain.getCoursePaperId());
+        BasicExam exam = basicExamService.getById(domain.getExamId());
+        if (exam == null) {
+            throw new ParameterException("未找到考试信息");
+        }
+        SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
+        return ResultUtil.ok(scanBatchService.batchCreate(domain, sysUser));
     }
-    
+
     @ApiOperation(value = "答题卡扫描批次完成")
     @RequestMapping(value = "finish", method = RequestMethod.POST)
     public Result batchFinish(@RequestParam Long id) {
-        return ResultUtil.ok(scanBatchService.batchFinish(id));
+        ScanBatch scanBatch = scanBatchService.getById(id);
+        checkBatchStatus(scanBatch);
+        validMarkPaperForScan(scanBatch.getExamId(), scanBatch.getCoursePaperId());
+        return ResultUtil.ok(scanBatchService.batchFinish(scanBatch));
     }
-    
+
     @ApiOperation(value = "答题卡扫描结果保存")
     @RequestMapping(value = "save", method = RequestMethod.POST)
     public Result batchSave(@Validated @RequestBody AnswerDomain domain) {
-    	SysUser user = (SysUser) ServletUtil.getRequestUser();
-        return ResultUtil.ok(scanBatchService.batchSave(domain, user));
+        ScanBatch scanBatch = scanBatchService.getById(domain.getBatchId());
+        checkBatchStatus(scanBatch);
+        validMarkPaperForScan(scanBatch.getExamId(), scanBatch.getCoursePaperId());
+        SysUser user = (SysUser) ServletUtil.getRequestUser();
+        return ResultUtil.ok(scanBatchService.batchSave(domain,scanBatch, user));
     }
 }

+ 9 - 2
distributed-print/src/main/java/com/qmth/distributed/print/api/mark/ScanAnswerCardController.java

@@ -38,7 +38,7 @@ import javax.annotation.Resource;
 @Api(tags = "扫描-卡格式")
 @RestController
 @RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + SystemConstant.PREFIX_URL_SCAN + "/answer/card")
-public class ScanAnswerCardController {
+public class ScanAnswerCardController extends BaseController {
 
     @Autowired
     private ScanAnswerCardService scanAnswerCardService;
@@ -64,6 +64,7 @@ public class ScanAnswerCardController {
                            @RequestParam String coursePaperId, @RequestParam String md5,
                            @RequestParam(required = false) Integer number, @RequestParam(required = false) String remark,
                            @RequestParam Integer paperCount, @RequestParam MultipartFile file) {
+        validMarkPaperForScan(examId, coursePaperId);
         BasicExam exam = basicExamService.getById(examId);
         if (exam == null) {
             throw new ParameterException("未找到考试信息");
@@ -89,9 +90,14 @@ public class ScanAnswerCardController {
         if (exam == null) {
             throw new ParameterException("未找到考试信息");
         }
+        ScanAnswerCard card = scanAnswerCardService.findByExamAndNumber(examId, number);
+        if (card == null) {
+            throw new ParameterException("未找到卡格式信息");
+        }
+        validMarkPaperForScan(card.getExamId(), card.getCoursePaperId());
         if (concurrentService.getLock(LockType.CARD_SAVE + "-" + examId).tryLock()) {
             try {
-                scanAnswerCardService.cardDelete(examId, number);
+                scanAnswerCardService.cardDelete(card);
                 AnswerCardSaveVo vo = new AnswerCardSaveVo(number, System.currentTimeMillis());
                 return ResultUtil.ok(vo);
             } finally {
@@ -107,6 +113,7 @@ public class ScanAnswerCardController {
     public Result adapteUpload(@RequestParam Long examId, @RequestParam String coursePaperId,
                                @RequestParam Integer cardNumber, @RequestParam MultipartFile file, @RequestParam String md5,
                                @RequestParam Integer dpi, @RequestParam(required = false) String remark) {
+        validMarkPaperForScan(examId, coursePaperId);
         BasicExam exam = basicExamService.getById(examId);
         if (exam == null) {
             throw new ParameterException("未找到考试信息");

+ 45 - 30
distributed-print/src/main/java/com/qmth/distributed/print/api/mark/ScanAnswerController.java

@@ -1,5 +1,9 @@
 package com.qmth.distributed.print.api.mark;
 
+import com.qmth.boot.core.exception.ParameterException;
+import com.qmth.teachcloud.common.entity.BasicClazz;
+import com.qmth.teachcloud.mark.entity.MarkStudent;
+import com.qmth.teachcloud.mark.entity.ScanBatch;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.RequestBody;
@@ -41,56 +45,67 @@ import io.swagger.annotations.ApiOperation;
 @Api(tags = "扫描-考生题卡")
 @RestController
 @RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + SystemConstant.PREFIX_URL_SCAN + "/answer")
-public class ScanAnswerController {
+public class ScanAnswerController extends BaseController {
 
-	@Autowired
-	private ScanRefixBatchService refixBatchService;
-	
-	@Autowired
-	private ScanBatchService scanBatchService;
-	@Autowired
-	private ScanPaperService scanPaperService;
-	@Autowired
-	private MarkStudentService markStudentService;
+    @Autowired
+    private ScanRefixBatchService refixBatchService;
 
-	@ApiOperation(value = "答题卡二次识别")
-	@RequestMapping(value = "refix", method = RequestMethod.POST)
-	public Result refix(@Validated @RequestBody AnswerRefixDomain query) {
-		SysUser user = (SysUser) ServletUtil.getRequestUser();
-		return ResultUtil.ok(refixBatchService.answerRefix(user.getId(), query));
-	}
+    @Autowired
+    private ScanBatchService scanBatchService;
+    @Autowired
+    private ScanPaperService scanPaperService;
+    @Autowired
+    private MarkStudentService markStudentService;
+
+    @ApiOperation(value = "答题卡二次识别")
+    @RequestMapping(value = "refix", method = RequestMethod.POST)
+    public Result refix(@Validated @RequestBody AnswerRefixDomain query) {
+        MarkStudent student = markStudentService.getById(query.getStudentId());
+        if (student == null) {
+            throw new ParameterException("考生信息未找到");
+        }
+        validMarkPaperForScan(student.getExamId(), student.getCoursePaperId());
+        SysUser user = (SysUser) ServletUtil.getRequestUser();
+        return ResultUtil.ok(refixBatchService.answerRefix(user.getId(), query));
+    }
+
+    @ApiOperation(value = "答题卡扫描原图上传")
+    @RequestMapping(value = "sheet/upload", method = RequestMethod.POST)
+    public Result sheetUpload(@RequestParam Long batchId, @RequestParam String coursePaperId,
+                              @RequestParam String studentCode, @RequestParam Integer paperNumber, @RequestParam Integer pageIndex,
+                              @RequestParam MultipartFile file, @RequestParam String md5) {
+        ScanBatch batch = scanBatchService.getById(batchId);
+        checkBatchStatus(batch);
+        validMarkPaperForScan(batch.getExamId(), batch.getCoursePaperId());
+        SheetUploadVo sheetUploadVo = scanBatchService.sheetUpload(batch, coursePaperId, studentCode, paperNumber, pageIndex, file, md5);
+        return ResultUtil.ok(sheetUploadVo);
+    }
 
-	@ApiOperation(value = "答题卡扫描原图上传")
-	@RequestMapping(value = "sheet/upload", method = RequestMethod.POST)
-	public Result sheetUpload(@RequestParam Long batchId, @RequestParam String coursePaperId,
-			@RequestParam String studentCode, @RequestParam Integer paperNumber, @RequestParam Integer pageIndex,
-			@RequestParam MultipartFile file, @RequestParam String md5) {
-		SheetUploadVo sheetUploadVo = scanBatchService.sheetUpload(batchId, coursePaperId, studentCode, paperNumber, pageIndex, file, md5);
-		return ResultUtil.ok(sheetUploadVo);
-	}
-	
     @ApiOperation(value = "查询答题卡扫描详情")
     @RequestMapping(value = "query", method = RequestMethod.POST)
     public Result query(@Validated AnswerQueryDomain query) {
         return ResultUtil.ok(markStudentService.query(query));
     }
+
     @ApiOperation(value = "查询答题卡扫描概要")
     @RequestMapping(value = "summary", method = RequestMethod.POST)
     public Result summary(@Validated AnswerQueryDomain query) {
         return ResultUtil.ok(markStudentService.summary(query));
     }
-    
+
     @ApiOperation(value = "修改答题卡识别结果")
     @RequestMapping(value = "omr/edit", method = RequestMethod.POST)
     public UpdateTimeVo omrEdit(@Validated @RequestBody OmrEditDomain domain) {
-    	SysUser user = (SysUser) ServletUtil.getRequestUser();
-        return markStudentService.omrEdit(user.getId(),domain);
+        validMarkPaperForScan(domain.getExamId(), domain.getCoursePaperId());
+        SysUser user = (SysUser) ServletUtil.getRequestUser();
+        return markStudentService.omrEdit(user.getId(), domain);
     }
-    
+
     @ApiOperation(value = "修改答题卡扫描图片绑定考生")
     @RequestMapping(value = "paper/migrate", method = RequestMethod.POST)
     public PaperMigrateVo paperMigrate(@Validated @RequestBody PaperMigrateDomain domain) {
-    	SysUser user = (SysUser) ServletUtil.getRequestUser();
+        validMarkPaperForScan(domain.getExamId(), domain.getCoursePaperId());
+        SysUser user = (SysUser) ServletUtil.getRequestUser();
         return scanPaperService.paperMigrate(user, domain);
     }
 }

+ 1 - 1
distributed-print/src/main/java/com/qmth/distributed/print/api/mark/ScanOmrTaskController.java

@@ -36,7 +36,7 @@ import io.swagger.annotations.ApiOperation;
 @Api(tags = "扫描-识别对照")
 @RestController
 @RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + SystemConstant.PREFIX_URL_SCAN + "/task/omr")
-public class ScanOmrTaskController {
+public class ScanOmrTaskController extends BaseController{
     protected static final Logger log = LoggerFactory.getLogger(ScanOmrTaskController.class);
 
     @Autowired

+ 3 - 1
distributed-print/src/main/java/com/qmth/distributed/print/api/mark/ScanStudentController.java

@@ -28,7 +28,7 @@ import javax.servlet.http.HttpServletResponse;
 @Api(tags = "扫描-考生")
 @RestController
 @RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + SystemConstant.PREFIX_URL_SCAN + "/student")
-public class ScanStudentController {
+public class ScanStudentController extends BaseController {
     @Autowired
     private MarkStudentService markStudentService;
 
@@ -42,6 +42,7 @@ public class ScanStudentController {
     @PostMapping("absent/update")
     public AbsentManualUpdateVo absentManualUpdate(@RequestParam Long examId, @RequestParam String coursePaperId,
                                                    @RequestParam String studentCode) {
+        validMarkPaperForScan(examId, coursePaperId);
         return markStudentService.absentManualUpdate(examId, coursePaperId, studentCode);
     }
 
@@ -49,6 +50,7 @@ public class ScanStudentController {
     @PostMapping("confirm")
     public UpdateTimeVo confirm(@RequestParam Long examId, @RequestParam String coursePaperId,
                                 @RequestParam String studentCode, @RequestParam(required = false) Boolean omrAbsent) {
+        validMarkPaperForScan(examId, coursePaperId);
         return markStudentService.confirm(examId, coursePaperId, studentCode, omrAbsent);
     }
 

+ 2 - 0
teachcloud-common/src/main/java/com/qmth/teachcloud/common/enums/ExceptionResultEnum.java

@@ -92,6 +92,8 @@ public enum ExceptionResultEnum {
     SYNC_TASK_NO_DATA(HttpStatus.INTERNAL_SERVER_ERROR, 5000033, "同步任务不存在"),
 
     PAPER_STRUCT_EXCEPTION(HttpStatus.INTERNAL_SERVER_ERROR, 5100003, "试卷结构不一致"),
+    MARK_PAPER_FINISH(HttpStatus.INTERNAL_SERVER_ERROR, 5000034, "科目已结束评卷"),
+    MARK_PAPER_OUT_MARK_TIME(HttpStatus.INTERNAL_SERVER_ERROR, 5000035, "不在评卷时间范围"),
 
     /**
      * 401

+ 8 - 8
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/ScanAnswerCardService.java

@@ -21,20 +21,20 @@ import com.baomidou.mybatisplus.extension.service.IService;
  */
 public interface ScanAnswerCardService extends IService<ScanAnswerCard> {
 
-	ScanAnswerCard findByExamAndNumber(Long examId, Integer cardNumber);
+    ScanAnswerCard findByExamAndNumber(Long examId, Integer cardNumber);
 
-	List<AnswerCardVo> cardList(Long examId, String coursePaperId);
+    List<AnswerCardVo> cardList(Long examId, String coursePaperId);
 
-	ScanAnswerCard cardSave(AnswerCardSaveDomain domain);
+    ScanAnswerCard cardSave(AnswerCardSaveDomain domain);
 
-	Integer findMaxCardNumberByExamId(Long examId);
+    Integer findMaxCardNumberByExamId(Long examId);
 
-	void cardDelete(Long examId, Integer number);
+    void cardDelete(ScanAnswerCard card);
 
-	UriVo adapteUpload(Long examId, String coursePaperId, Integer cardNumber, String md5, Integer dpi,
-			MultipartFile file, String remark);
+    UriVo adapteUpload(Long examId, String coursePaperId, Integer cardNumber, String md5, Integer dpi,
+                       MultipartFile file, String remark);
 
-	AnswerCardVo cardGet(Long examId, Integer number);
+    AnswerCardVo cardGet(Long examId, Integer number);
 
     ScanAnswerCard getByExamIdAndCoursePaperIdAndCardId(Long examId, String coursePaperId, Long cardId);
 

+ 3 - 3
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/ScanBatchService.java

@@ -25,9 +25,9 @@ public interface ScanBatchService extends IService<ScanBatch> {
 
 	BatchCreateVo batchCreate(BatchCreateDomain domain,SysUser sysUser);
 
-	BatchFinishVo batchFinish(Long id);
+	BatchFinishVo batchFinish(ScanBatch scanBatch);
 
-	AnswerSaveVo batchSave(AnswerDomain domain, SysUser user);
+	AnswerSaveVo batchSave(AnswerDomain domain, ScanBatch scanBatch, SysUser user);
 
 	void updateAssignedCount(Long id);
 
@@ -35,7 +35,7 @@ public interface ScanBatchService extends IService<ScanBatch> {
 
 	Integer findStudentCountByBatch(Long batchId);
 
-	SheetUploadVo sheetUpload(Long batchId, String coursePaperId, String studentCode, Integer paperNumber,
+	SheetUploadVo sheetUpload(ScanBatch batch, String coursePaperId, String studentCode, Integer paperNumber,
 			Integer pageIndex, MultipartFile file, String md5);
 
 }

+ 4 - 8
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/ScanAnswerCardServiceImpl.java

@@ -179,18 +179,14 @@ public class ScanAnswerCardServiceImpl extends ServiceImpl<ScanAnswerCardMapper,
 
     @Transactional
     @Override
-    public void cardDelete(Long examId, Integer number) {
-        ScanAnswerCard card = findByExamAndNumber(examId, number);
-        if (card == null) {
-            throw new ParameterException("未找到卡格式信息");
-        }
-        int studentCount = scanPaperService.getCountByExamAndCardNumber(examId, number);
+    public void cardDelete(ScanAnswerCard card) {
+        int studentCount = scanPaperService.getCountByExamAndCardNumber(card.getExamId(), card.getNumber());
         if (studentCount != 0) {
             throw new ParameterException("卡格式已被使用,无法删除");
         }
         UpdateWrapper<ScanAnswerCard> updateWrapper = new UpdateWrapper<>();
-        updateWrapper.lambda().eq(ScanAnswerCard::getExamId, examId);
-        updateWrapper.lambda().eq(ScanAnswerCard::getNumber, number);
+        updateWrapper.lambda().eq(ScanAnswerCard::getExamId, card.getExamId());
+        updateWrapper.lambda().eq(ScanAnswerCard::getNumber, card.getNumber());
         int count = this.baseMapper.delete(updateWrapper);
         if (count == 0) {
             throw new ParameterException("未找到卡格式");

+ 16 - 27
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/ScanBatchServiceImpl.java

@@ -122,26 +122,24 @@ public class ScanBatchServiceImpl extends ServiceImpl<ScanBatchMapper, ScanBatch
 
     @Transactional
     @Override
-    public BatchFinishVo batchFinish(Long id) {
-        ScanBatch batch = checkBatchStatus(getById(id));
-        batch.setStatus(BatchStatus.FINISH);
-        this.saveOrUpdate(batch);
+    public BatchFinishVo batchFinish(ScanBatch scanBatch) {
+        scanBatch.setStatus(BatchStatus.FINISH);
+        this.saveOrUpdate(scanBatch);
         BatchFinishVo vo = new BatchFinishVo();
-        vo.setStatus(batch.getStatus());
+        vo.setStatus(scanBatch.getStatus());
         vo.setUpdateTime(System.currentTimeMillis());
         return vo;
     }
 
     @Transactional
     @Override
-    public AnswerSaveVo batchSave(AnswerDomain domain, SysUser user) {
-        ScanBatch batch = checkBatchStatus(getById(domain.getBatchId()));
+    public AnswerSaveVo batchSave(AnswerDomain domain, ScanBatch scanBatch, SysUser user) {
         String studentCode = domain.getStudentCode();
-        MarkStudent student = markStudentService.findByExamIdAndCoursePaperIdAndStudentCode(batch.getExamId(), batch.getCoursePaperId(), studentCode);
+        MarkStudent student = markStudentService.findByExamIdAndCoursePaperIdAndStudentCode(scanBatch.getExamId(), scanBatch.getCoursePaperId(), studentCode);
         if (student == null) {
             throw new ParameterException("未找到考生信息:" + studentCode);
         }
-        ScanAnswerCard answerCard = scanAnswerCardService.findByExamAndNumber(batch.getExamId(),
+        ScanAnswerCard answerCard = scanAnswerCardService.findByExamAndNumber(scanBatch.getExamId(),
                 domain.getCardNumber());
         if (answerCard == null) {
             throw new ParameterException("卡格式信息未找到");
@@ -151,9 +149,9 @@ public class ScanBatchServiceImpl extends ServiceImpl<ScanBatchMapper, ScanBatch
             // 验证page数量
             answerPaper.answerCardValidate(answerCard);
             Integer paperNumber = answerPaper.getNumber();
-            ScanPaper paper = findOrCreatePaper(batch, student, paperNumber, user);
+            ScanPaper paper = findOrCreatePaper(scanBatch, student, paperNumber, user);
             // 设置paper属性
-            paper.setExamId(batch.getExamId());
+            paper.setExamId(scanBatch.getExamId());
             paper.setCardNumber(answerCard.getNumber());
             paper.setNumber(paperNumber);
             paper.setMismatch(false);
@@ -162,13 +160,13 @@ public class ScanBatchServiceImpl extends ServiceImpl<ScanBatchMapper, ScanBatch
             // 保存paper与page到数据库
             scanPaperService.savePaperAndPages(paper, answerPaper.buildPageList());
             // 记录paper与batch关联关系
-            scanBatchPaperService.update(batch, paper, student.getId(), paperNumber);
+            scanBatchPaperService.update(scanBatch, paper, student.getId(), paperNumber);
             // 创建student与paper的关联关系
             studentPaperList.add(new ScanStudentPaper(student.getId(), paperNumber, paper.getId()));
         }
         // 更新批次统计数量
-        updateAssignedCount(batch.getId());
-        updateScanCount(batch.getId());
+        updateAssignedCount(scanBatch.getId());
+        updateScanCount(scanBatch.getId());
         //直接更新考生扫描状态
         concurrentService.getReadWriteLock(LockType.STUDENT + "-" + student.getId()).writeLock().lock();
         try {
@@ -176,7 +174,7 @@ public class ScanBatchServiceImpl extends ServiceImpl<ScanBatchMapper, ScanBatch
         } finally {
             concurrentService.getReadWriteLock(LockType.STUDENT + "-" + student.getId()).writeLock().unlock();
         }
-        return AnswerSaveVo.create(findStudentCountByBatch(batch.getId()));
+        return AnswerSaveVo.create(findStudentCountByBatch(scanBatch.getId()));
     }
 
     @Override
@@ -214,23 +212,14 @@ public class ScanBatchServiceImpl extends ServiceImpl<ScanBatchMapper, ScanBatch
         return paper;
     }
 
-    private ScanBatch checkBatchStatus(ScanBatch b) {
-        if (b == null) {
-            throw new ParameterException("批次未找到");
-        }
-        if (BatchStatus.FINISH.equals(b.getStatus())) {
-            throw new ParameterException("批次已经完成");
-        }
-        return b;
-    }
+
 
     @Transactional
     @Override
-    public SheetUploadVo sheetUpload(Long batchId, String coursePaperId, String studentCode, Integer paperNumber,
+    public SheetUploadVo sheetUpload(ScanBatch batch, String coursePaperId, String studentCode, Integer paperNumber,
                                      Integer pageIndex, MultipartFile file, String md5) {
-        ScanBatch batch = checkBatchStatus(getById(batchId));
         try {
-            String path = markFileService.uploadSheet(file.getInputStream(), md5, batch.getExamId(), batchId, coursePaperId,
+            String path = markFileService.uploadSheet(file.getInputStream(), md5, batch.getExamId(), batch.getId(), coursePaperId,
                     studentCode, paperNumber, pageIndex);
             scanFilePropertyService.save(batch.getExamId(), path, md5, file.getSize());
             return SheetUploadVo.create(path);

+ 536 - 542
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/ScanOmrTaskServiceImpl.java

@@ -1,19 +1,5 @@
 package com.qmth.teachcloud.mark.service.impl;
 
-import java.util.*;
-import java.util.stream.Collectors;
-
-import javax.annotation.Resource;
-import javax.validation.constraints.NotNull;
-
-import com.qmth.teachcloud.common.bean.dto.DataPermissionRule;
-import com.qmth.teachcloud.common.contant.SystemConstant;
-import com.qmth.teachcloud.common.service.TeachcloudCommonService;
-import org.apache.commons.collections4.CollectionUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
@@ -21,38 +7,33 @@ import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.qmth.boot.core.concurrent.service.ConcurrentService;
 import com.qmth.boot.core.exception.ParameterException;
+import com.qmth.teachcloud.common.bean.dto.DataPermissionRule;
+import com.qmth.teachcloud.common.contant.SystemConstant;
 import com.qmth.teachcloud.common.entity.MarkQuestion;
 import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
 import com.qmth.teachcloud.common.enums.QuestionType;
 import com.qmth.teachcloud.common.enums.ScanStatus;
+import com.qmth.teachcloud.common.enums.mark.MarkPaperStatus;
 import com.qmth.teachcloud.common.enums.scan.ConditionType;
 import com.qmth.teachcloud.common.enums.scan.OmrField;
+import com.qmth.teachcloud.common.service.TeachcloudCommonService;
 import com.qmth.teachcloud.mark.bean.OmrTaskItem;
 import com.qmth.teachcloud.mark.bean.OmrTaskPage;
-import com.qmth.teachcloud.mark.dto.OmrTaskDto;
-import com.qmth.teachcloud.mark.dto.OmrTaskPageDto;
-import com.qmth.teachcloud.mark.dto.ScanOmrStudent;
-import com.qmth.teachcloud.mark.dto.ScanOmrTaskDto;
-import com.qmth.teachcloud.mark.dto.ScanOmrTaskPageDto;
-import com.qmth.teachcloud.mark.dto.ScanOmrTaskResultDto;
-import com.qmth.teachcloud.mark.dto.ScanOmrTaskResultPageDto;
-import com.qmth.teachcloud.mark.dto.ScanOmrTaskSaveDto;
-import com.qmth.teachcloud.mark.dto.ScanOmrTaskStatusDto;
-import com.qmth.teachcloud.mark.dto.ScanStudentDto;
-import com.qmth.teachcloud.mark.entity.MarkStudent;
-import com.qmth.teachcloud.mark.entity.ScanOmrTask;
-import com.qmth.teachcloud.mark.entity.ScanPaper;
-import com.qmth.teachcloud.mark.entity.ScanPaperPage;
-import com.qmth.teachcloud.mark.entity.ScanStudentPaper;
+import com.qmth.teachcloud.mark.dto.*;
+import com.qmth.teachcloud.mark.entity.*;
 import com.qmth.teachcloud.mark.enums.LockType;
 import com.qmth.teachcloud.mark.enums.OmrTaskStatus;
 import com.qmth.teachcloud.mark.mapper.ScanOmrTaskMapper;
-import com.qmth.teachcloud.mark.service.MarkQuestionService;
-import com.qmth.teachcloud.mark.service.MarkStudentService;
-import com.qmth.teachcloud.mark.service.ScanOmrTaskService;
-import com.qmth.teachcloud.mark.service.ScanPaperPageService;
-import com.qmth.teachcloud.mark.service.ScanPaperService;
-import com.qmth.teachcloud.mark.service.ScanStudentPaperService;
+import com.qmth.teachcloud.mark.service.*;
+import org.apache.commons.collections4.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+import javax.validation.constraints.NotNull;
+import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  * <p>
@@ -64,81 +45,83 @@ import com.qmth.teachcloud.mark.service.ScanStudentPaperService;
  */
 @Service
 public class ScanOmrTaskServiceImpl extends ServiceImpl<ScanOmrTaskMapper, ScanOmrTask> implements ScanOmrTaskService {
-	@Autowired
-	private ScanStudentPaperService studentPaperService;
-	@Autowired
-	private MarkStudentService studentService;
-	@Autowired
-	private ScanPaperService paperService;
-	@Autowired
-	private ScanPaperPageService pageService;
-	@Autowired
-	private ConcurrentService concurrentService;
-	@Autowired
-	private MarkQuestionService questionService;
-	@Resource
-	private TeachcloudCommonService teachcloudCommonService;
+    @Autowired
+    private ScanStudentPaperService studentPaperService;
+    @Autowired
+    private MarkStudentService studentService;
+    @Autowired
+    private ScanPaperService paperService;
+    @Autowired
+    private ScanPaperPageService pageService;
+    @Autowired
+    private ConcurrentService concurrentService;
+    @Autowired
+    private MarkQuestionService questionService;
+    @Resource
+    private MarkPaperService markPaperService;
+    @Resource
+    private TeachcloudCommonService teachcloudCommonService;
 
-	private static final String OMR_SUSPECT = "?";
+    private static final String OMR_SUSPECT = "?";
 
-	private static final String OMR_BLANK = "#";
+    private static final String OMR_BLANK = "#";
 
-	@Override
-	@Transactional
-	public ScanOmrTask buildTask(ConditionType c, Long studentId) {
-		List<ScanStudentPaper> paperIds = clearAndToDispose(c, studentId);
-		if (CollectionUtils.isEmpty(paperIds)) {
-			return null;
-		}
-		MarkStudent student = studentService.getById(studentId);
-		// 所有客观题空白
-		boolean allObjectiveBlank = isAllBlank(paperIds);
-		List<OmrTaskDto> retList = new ArrayList<>();
-		boolean multi_blank = false;
-		boolean single_blank = false;
-		int multi_blank_count = 0;
-		int single_blank_count = 0;
-		for (ScanStudentPaper spe : paperIds) {
-			ScanPaper paper = paperService.getById(spe.getPaperId());
-			if (paper == null) {
-				throw new ParameterException("paper不存在");
-			}
-			Long paperId = spe.getPaperId();
-			ScanOmrTask task = new ScanOmrTask();
-			task.setId(SystemConstant.getDbUuid());
-			task.setCardNumber(paper.getCardNumber());
-			task.setExamId(paper.getExamId());
-			task.setConditions(c);
-			task.setPaperId(paperId);
-			task.setPaperIndex(spe.getPaperIndex());
-			task.setStatus(OmrTaskStatus.WAITING);
-			task.setStudentId(spe.getStudentId());
-			task.setPages(new ArrayList<>());
-			List<ScanPaperPage> pageList = pageService.listByPaperId(paperId);
-			OmrTaskDto taskDto = new OmrTaskDto(task);
-			retList.add(taskDto);
-			// 循环试卷
-			for (ScanPaperPage pageEntity : pageList) {
-				OmrTaskPageDto pageDto = new OmrTaskPageDto(pageEntity.getPageIndex());
-				taskDto.getPage().add(pageDto);
-				List<OmrTaskItem> items = pageDto.getItems();
-				// 分组类型
-				// 识别嫌疑
-				if (ConditionType.FILL_SUSPECT.equals(c)) {
-					for (int i = 0; pageEntity.getQuestion() != null && pageEntity.getQuestion().getResult() != null
-							&& i < pageEntity.getQuestion().getResult().size(); i++) {
-						String result = pageEntity.getQuestion().getResult().get(i);
-						if (result != null && result.startsWith(OMR_SUSPECT)) {
-							OmrTaskItem item = new OmrTaskItem();
-							item.setIndex(i + 1);
-							item.setField(OmrField.QUESTION);
-							item.setOmrResult(result);
-							items.add(item);
-						}
-					}
-					pageDto.setItems(items);
-				}
-				// 卷型空选
+    @Override
+    @Transactional
+    public ScanOmrTask buildTask(ConditionType c, Long studentId) {
+        List<ScanStudentPaper> paperIds = clearAndToDispose(c, studentId);
+        if (CollectionUtils.isEmpty(paperIds)) {
+            return null;
+        }
+        MarkStudent student = studentService.getById(studentId);
+        // 所有客观题空白
+        boolean allObjectiveBlank = isAllBlank(paperIds);
+        List<OmrTaskDto> retList = new ArrayList<>();
+        boolean multi_blank = false;
+        boolean single_blank = false;
+        int multi_blank_count = 0;
+        int single_blank_count = 0;
+        for (ScanStudentPaper spe : paperIds) {
+            ScanPaper paper = paperService.getById(spe.getPaperId());
+            if (paper == null) {
+                throw new ParameterException("paper不存在");
+            }
+            Long paperId = spe.getPaperId();
+            ScanOmrTask task = new ScanOmrTask();
+            task.setId(SystemConstant.getDbUuid());
+            task.setCardNumber(paper.getCardNumber());
+            task.setExamId(paper.getExamId());
+            task.setConditions(c);
+            task.setPaperId(paperId);
+            task.setPaperIndex(spe.getPaperIndex());
+            task.setStatus(OmrTaskStatus.WAITING);
+            task.setStudentId(spe.getStudentId());
+            task.setPages(new ArrayList<>());
+            List<ScanPaperPage> pageList = pageService.listByPaperId(paperId);
+            OmrTaskDto taskDto = new OmrTaskDto(task);
+            retList.add(taskDto);
+            // 循环试卷
+            for (ScanPaperPage pageEntity : pageList) {
+                OmrTaskPageDto pageDto = new OmrTaskPageDto(pageEntity.getPageIndex());
+                taskDto.getPage().add(pageDto);
+                List<OmrTaskItem> items = pageDto.getItems();
+                // 分组类型
+                // 识别嫌疑
+                if (ConditionType.FILL_SUSPECT.equals(c)) {
+                    for (int i = 0; pageEntity.getQuestion() != null && pageEntity.getQuestion().getResult() != null
+                            && i < pageEntity.getQuestion().getResult().size(); i++) {
+                        String result = pageEntity.getQuestion().getResult().get(i);
+                        if (result != null && result.startsWith(OMR_SUSPECT)) {
+                            OmrTaskItem item = new OmrTaskItem();
+                            item.setIndex(i + 1);
+                            item.setField(OmrField.QUESTION);
+                            item.setOmrResult(result);
+                            items.add(item);
+                        }
+                    }
+                    pageDto.setItems(items);
+                }
+                // 卷型空选
 //                if (ConditionType.PAPER_TYPE_BLANK.equals(c)) {
 //                    if (pageEntity.getPaperType() != null
 //                            && pageEntity.getPaperType().getResult().contains(OMR_BLANK)) {
@@ -149,7 +132,7 @@ public class ScanOmrTaskServiceImpl extends ServiceImpl<ScanOmrTaskMapper, ScanO
 //                        items.add(item);
 //                    }
 //                }
-				// 卷型多选
+                // 卷型多选
 //                if (ConditionType.PAPER_TYPE_EXCEED.equals(c)) {
 //                    if ((!pageEntity.getPaperType().getResult().contains(OMR_SUSPECT)
 //                            && pageEntity.getPaperType().getResult().length() > 2)
@@ -161,76 +144,76 @@ public class ScanOmrTaskServiceImpl extends ServiceImpl<ScanOmrTaskMapper, ScanO
 //                        items.add(item);
 //                    }
 //                }
-				if (ConditionType.QUESTION_MULTI_BLANK.equals(c)) {
-					List<MarkQuestion> questiongList = questionService
-							.listByExamIdAndPaperNumberAndPaperIndexAndPageIndex(student.getExamId(),
-									student.getPaperNumber(), spe.getPaperIndex(), pageEntity.getPageIndex());
-					if (pageEntity.getQuestion() == null || pageEntity.getQuestion().getResult() == null
-							|| questiongList.isEmpty()) {
-						continue;
-					}
-					int size = pageEntity.getQuestion().getResult().size() > questiongList.size() ? questiongList.size()
-							: pageEntity.getQuestion().getResult().size();
-					for (int i = 0; i < size; i++) {
-						String result = pageEntity.getQuestion().getResult().get(i);
-						MarkQuestion question = questiongList.get(i);
-						if (question.getQuestionType().equals(QuestionType.MULTIPLE.getValue()) && result != null
-								&& result.contains(OMR_BLANK)) {
-							OmrTaskItem item = new OmrTaskItem();
-							item.setIndex(i + 1);
-							item.setField(OmrField.QUESTION);
-							item.setOmrResult(result);
-							pageDto.getPageMultiBlankItems().add(item);
-							multi_blank_count++;
-							if (multi_blank_count > 0) {
-								multi_blank = true;
-							}
-						}
-					}
-				}
-				if (ConditionType.QUESTION_SINGLE_BLANK.equals(c) && ScanStatus.SCANNED.equals(student.getScanStatus())
-						&& !allObjectiveBlank) {
-					List<MarkQuestion> questiongList = questionService
-							.listByExamIdAndPaperNumberAndPaperIndexAndPageIndex(student.getExamId(),
-									student.getPaperNumber(), spe.getPaperIndex(), pageEntity.getPageIndex());
-					if (pageEntity.getQuestion() == null || pageEntity.getQuestion().getResult() == null
-							|| questiongList.isEmpty()) {
-						continue;
-					}
-					int size = pageEntity.getQuestion().getResult().size() > questiongList.size() ? questiongList.size()
-							: pageEntity.getQuestion().getResult().size();
-					for (int i = 0; i < size; i++) {
-						String result = pageEntity.getQuestion().getResult().get(i);
-						MarkQuestion question = questiongList.get(i);
-						if (question.getQuestionType().equals(QuestionType.SINGLE.getValue()) && result != null
-								&& result.contains(OMR_BLANK)) {
-							OmrTaskItem item = new OmrTaskItem();
-							item.setIndex(i + 1);
-							item.setField(OmrField.QUESTION);
-							item.setOmrResult(result);
-							pageDto.getPageSingleBlankItems().add(item);
-							single_blank_count++;
-							multi_blank_count++;
-							if (single_blank_count > 0) {
-								single_blank = true;
-							}
-						}
-					}
-				}
+                if (ConditionType.QUESTION_MULTI_BLANK.equals(c)) {
+                    List<MarkQuestion> questiongList = questionService
+                            .listByExamIdAndPaperNumberAndPaperIndexAndPageIndex(student.getExamId(),
+                                    student.getPaperNumber(), spe.getPaperIndex(), pageEntity.getPageIndex());
+                    if (pageEntity.getQuestion() == null || pageEntity.getQuestion().getResult() == null
+                            || questiongList.isEmpty()) {
+                        continue;
+                    }
+                    int size = pageEntity.getQuestion().getResult().size() > questiongList.size() ? questiongList.size()
+                            : pageEntity.getQuestion().getResult().size();
+                    for (int i = 0; i < size; i++) {
+                        String result = pageEntity.getQuestion().getResult().get(i);
+                        MarkQuestion question = questiongList.get(i);
+                        if (question.getQuestionType().equals(QuestionType.MULTIPLE.getValue()) && result != null
+                                && result.contains(OMR_BLANK)) {
+                            OmrTaskItem item = new OmrTaskItem();
+                            item.setIndex(i + 1);
+                            item.setField(OmrField.QUESTION);
+                            item.setOmrResult(result);
+                            pageDto.getPageMultiBlankItems().add(item);
+                            multi_blank_count++;
+                            if (multi_blank_count > 0) {
+                                multi_blank = true;
+                            }
+                        }
+                    }
+                }
+                if (ConditionType.QUESTION_SINGLE_BLANK.equals(c) && ScanStatus.SCANNED.equals(student.getScanStatus())
+                        && !allObjectiveBlank) {
+                    List<MarkQuestion> questiongList = questionService
+                            .listByExamIdAndPaperNumberAndPaperIndexAndPageIndex(student.getExamId(),
+                                    student.getPaperNumber(), spe.getPaperIndex(), pageEntity.getPageIndex());
+                    if (pageEntity.getQuestion() == null || pageEntity.getQuestion().getResult() == null
+                            || questiongList.isEmpty()) {
+                        continue;
+                    }
+                    int size = pageEntity.getQuestion().getResult().size() > questiongList.size() ? questiongList.size()
+                            : pageEntity.getQuestion().getResult().size();
+                    for (int i = 0; i < size; i++) {
+                        String result = pageEntity.getQuestion().getResult().get(i);
+                        MarkQuestion question = questiongList.get(i);
+                        if (question.getQuestionType().equals(QuestionType.SINGLE.getValue()) && result != null
+                                && result.contains(OMR_BLANK)) {
+                            OmrTaskItem item = new OmrTaskItem();
+                            item.setIndex(i + 1);
+                            item.setField(OmrField.QUESTION);
+                            item.setOmrResult(result);
+                            pageDto.getPageSingleBlankItems().add(item);
+                            single_blank_count++;
+                            multi_blank_count++;
+                            if (single_blank_count > 0) {
+                                single_blank = true;
+                            }
+                        }
+                    }
+                }
                 if (ConditionType.QUESTION_SINGLE_EXCEED.equals(c)
                         && ScanStatus.SCANNED.equals(student.getScanStatus()) && !allObjectiveBlank) {
-                	List<MarkQuestion> questiongList = questionService
-							.listByExamIdAndPaperNumberAndPaperIndexAndPageIndex(student.getExamId(),
-									student.getPaperNumber(), spe.getPaperIndex(), pageEntity.getPageIndex());
-                	if (pageEntity.getQuestion() == null || pageEntity.getQuestion().getResult() == null
-							|| questiongList.isEmpty()) {
-						continue;
-					}
-					int size = pageEntity.getQuestion().getResult().size() > questiongList.size() ? questiongList.size()
-							: pageEntity.getQuestion().getResult().size();
-					for (int i = 0; i < size; i++) {
-                    	String result = pageEntity.getQuestion().getResult().get(i);
-						MarkQuestion question = questiongList.get(i);
+                    List<MarkQuestion> questiongList = questionService
+                            .listByExamIdAndPaperNumberAndPaperIndexAndPageIndex(student.getExamId(),
+                                    student.getPaperNumber(), spe.getPaperIndex(), pageEntity.getPageIndex());
+                    if (pageEntity.getQuestion() == null || pageEntity.getQuestion().getResult() == null
+                            || questiongList.isEmpty()) {
+                        continue;
+                    }
+                    int size = pageEntity.getQuestion().getResult().size() > questiongList.size() ? questiongList.size()
+                            : pageEntity.getQuestion().getResult().size();
+                    for (int i = 0; i < size; i++) {
+                        String result = pageEntity.getQuestion().getResult().get(i);
+                        MarkQuestion question = questiongList.get(i);
                         if (question.getQuestionType().equals(QuestionType.SINGLE.getValue()) && result != null && result.length() > 1) {
                             OmrTaskItem item = new OmrTaskItem();
                             item.setIndex(i + 1);
@@ -239,390 +222,401 @@ public class ScanOmrTaskServiceImpl extends ServiceImpl<ScanOmrTaskMapper, ScanO
                             items.add(item);
                         }
                     }
-					pageDto.setItems(items);
+                    pageDto.setItems(items);
+                }
+            }
+        }
+        if (retList.size() == 0) {
+            return null;
+        }
+        for (OmrTaskDto dto : retList) {
+            for (OmrTaskPageDto pageDto : dto.getPage()) {
+                if (multi_blank) {
+                    pageDto.getItems().addAll(pageDto.getPageMultiBlankItems());
+                }
+                if (single_blank) {
+                    pageDto.getItems().addAll(pageDto.getPageSingleBlankItems());
+                }
+                if (pageDto.getItems().size() > 0) {
+                    OmrTaskPage page = new OmrTaskPage();
+                    page.setItems(pageDto.getItems());
+                    page.setIndex(pageDto.getPageIndex());
+                    dto.getTask().getPages().add(page);
                 }
-			}
-		}
-		if (retList.size() == 0) {
-			return null;
-		}
-		for (OmrTaskDto dto : retList) {
-			for (OmrTaskPageDto pageDto : dto.getPage()) {
-				if (multi_blank) {
-					pageDto.getItems().addAll(pageDto.getPageMultiBlankItems());
-				}
-				if (single_blank) {
-					pageDto.getItems().addAll(pageDto.getPageSingleBlankItems());
-				}
-				if (pageDto.getItems().size() > 0) {
-					OmrTaskPage page = new OmrTaskPage();
-					page.setItems(pageDto.getItems());
-					page.setIndex(pageDto.getPageIndex());
-					dto.getTask().getPages().add(page);
-				}
-			}
-			if (dto.getTask().getPages().size() > 0) {
-				return dto.getTask();
-			}
-		}
-		return null;
-	}
+            }
+            if (dto.getTask().getPages().size() > 0) {
+                return dto.getTask();
+            }
+        }
+        return null;
+    }
 
-	private List<ScanStudentPaper> clearAndToDispose(ConditionType c, Long studentId) {
-		List<ScanStudentPaper> spes = studentPaperService.findByStudentId(studentId);
-		if (CollectionUtils.isEmpty(spes)) {
-			return spes;
-		}
-		List<ScanOmrTask> tasks = getByStudent(c, studentId);
-		if (CollectionUtils.isEmpty(tasks)) {
-			return spes;
-		}
-		Map<Integer, Long> speMap = new HashMap<>();
-		for (ScanStudentPaper spe : spes) {
-			speMap.put(spe.getPaperIndex(), spe.getPaperId());
-		}
-		Map<Integer, Long> taskMap = new HashMap<>();
-		for (ScanOmrTask t : tasks) {
-			taskMap.put(t.getPaperIndex(), t.getPaperId());
-		}
-		if (ConditionType.FILL_SUSPECT.equals(c)) {
-			List<ScanStudentPaper> ret = new ArrayList<>();
-			for (ScanStudentPaper spe : spes) {
-				Long paperId = taskMap.get(spe.getPaperIndex());
-				if (paperId == null) {// 没有task的直接创建
-					ret.add(spe);
-				} else if (paperId.longValue() != spe.getPaperId().longValue()) {// 和task不一致的删除并创建
-					delete(c, studentId, paperId);
-					ret.add(spe);
-				}
-			}
-			for (ScanOmrTask t : tasks) {
-				if (speMap.get(t.getPaperIndex()) == null) {// 不在绑定关系的task删除
-					delete(c, studentId, t.getPaperId());
-				}
-			}
-			return ret;
-		} else {
-			if (spes.size() != tasks.size()) {// 数量不一致的删除重建
-				delete(c, studentId);
-				return spes;
-			}
-			for (ScanOmrTask t : tasks) {
-				if (!t.getPaperId().equals(speMap.get(t.getPaperIndex()))) {// 有一个不一致的删除重建
-					delete(c, studentId);
-					return spes;
-				}
-			}
-			return null;// 完全一致的不处理
-		}
-	}
+    private List<ScanStudentPaper> clearAndToDispose(ConditionType c, Long studentId) {
+        List<ScanStudentPaper> spes = studentPaperService.findByStudentId(studentId);
+        if (CollectionUtils.isEmpty(spes)) {
+            return spes;
+        }
+        List<ScanOmrTask> tasks = getByStudent(c, studentId);
+        if (CollectionUtils.isEmpty(tasks)) {
+            return spes;
+        }
+        Map<Integer, Long> speMap = new HashMap<>();
+        for (ScanStudentPaper spe : spes) {
+            speMap.put(spe.getPaperIndex(), spe.getPaperId());
+        }
+        Map<Integer, Long> taskMap = new HashMap<>();
+        for (ScanOmrTask t : tasks) {
+            taskMap.put(t.getPaperIndex(), t.getPaperId());
+        }
+        if (ConditionType.FILL_SUSPECT.equals(c)) {
+            List<ScanStudentPaper> ret = new ArrayList<>();
+            for (ScanStudentPaper spe : spes) {
+                Long paperId = taskMap.get(spe.getPaperIndex());
+                if (paperId == null) {// 没有task的直接创建
+                    ret.add(spe);
+                } else if (paperId.longValue() != spe.getPaperId().longValue()) {// 和task不一致的删除并创建
+                    delete(c, studentId, paperId);
+                    ret.add(spe);
+                }
+            }
+            for (ScanOmrTask t : tasks) {
+                if (speMap.get(t.getPaperIndex()) == null) {// 不在绑定关系的task删除
+                    delete(c, studentId, t.getPaperId());
+                }
+            }
+            return ret;
+        } else {
+            if (spes.size() != tasks.size()) {// 数量不一致的删除重建
+                delete(c, studentId);
+                return spes;
+            }
+            for (ScanOmrTask t : tasks) {
+                if (!t.getPaperId().equals(speMap.get(t.getPaperIndex()))) {// 有一个不一致的删除重建
+                    delete(c, studentId);
+                    return spes;
+                }
+            }
+            return null;// 完全一致的不处理
+        }
+    }
 
-	private List<ScanOmrTask> getByStudent(ConditionType c, Long studentId) {
-		QueryWrapper<ScanOmrTask> wrapper = new QueryWrapper<>();
-		LambdaQueryWrapper<ScanOmrTask> lw = wrapper.lambda();
-		lw.eq(ScanOmrTask::getConditions, c);
-		lw.eq(ScanOmrTask::getStudentId, studentId);
-		return baseMapper.selectList(wrapper);
-	}
+    private List<ScanOmrTask> getByStudent(ConditionType c, Long studentId) {
+        QueryWrapper<ScanOmrTask> wrapper = new QueryWrapper<>();
+        LambdaQueryWrapper<ScanOmrTask> lw = wrapper.lambda();
+        lw.eq(ScanOmrTask::getConditions, c);
+        lw.eq(ScanOmrTask::getStudentId, studentId);
+        return baseMapper.selectList(wrapper);
+    }
 
-	private void delete(ConditionType c, Long studentId, Long paperId) {
-		UpdateWrapper<ScanOmrTask> wrapper = new UpdateWrapper<>();
-		LambdaUpdateWrapper<ScanOmrTask> lw = wrapper.lambda();
-		lw.eq(ScanOmrTask::getConditions, c);
-		lw.eq(ScanOmrTask::getStudentId, studentId);
-		lw.eq(ScanOmrTask::getPaperId, paperId);
-		this.baseMapper.delete(wrapper);
-	}
+    private void delete(ConditionType c, Long studentId, Long paperId) {
+        UpdateWrapper<ScanOmrTask> wrapper = new UpdateWrapper<>();
+        LambdaUpdateWrapper<ScanOmrTask> lw = wrapper.lambda();
+        lw.eq(ScanOmrTask::getConditions, c);
+        lw.eq(ScanOmrTask::getStudentId, studentId);
+        lw.eq(ScanOmrTask::getPaperId, paperId);
+        this.baseMapper.delete(wrapper);
+    }
 
-	private void delete(ConditionType c, Long studentId) {
-		UpdateWrapper<ScanOmrTask> wrapper = new UpdateWrapper<>();
-		LambdaUpdateWrapper<ScanOmrTask> lw = wrapper.lambda();
-		lw.eq(ScanOmrTask::getConditions, c);
-		lw.eq(ScanOmrTask::getStudentId, studentId);
-		this.baseMapper.delete(wrapper);
-	}
+    private void delete(ConditionType c, Long studentId) {
+        UpdateWrapper<ScanOmrTask> wrapper = new UpdateWrapper<>();
+        LambdaUpdateWrapper<ScanOmrTask> lw = wrapper.lambda();
+        lw.eq(ScanOmrTask::getConditions, c);
+        lw.eq(ScanOmrTask::getStudentId, studentId);
+        this.baseMapper.delete(wrapper);
+    }
 
-	private boolean isAllBlank(List<ScanStudentPaper> paperIds) {
-		for (ScanStudentPaper spe : paperIds) {
-			ScanPaper paper = paperService.getById(spe.getPaperId());
-			if (paper == null) {
-				throw new ParameterException("paper不存在");
-			}
-			List<ScanPaperPage> pageList = pageService.listByPaperId(spe.getPaperId());
-			for (ScanPaperPage pageEntity : pageList) {
-				for (int i = 0; pageEntity.getQuestion() != null && pageEntity.getQuestion().getResult() != null
-						&& i < pageEntity.getQuestion().getResult().size(); i++) {
-					String result = pageEntity.getQuestion().getResult().get(i);
-					if (!"#".equals(result)) {
-						return false;
-					}
-				}
-			}
-		}
-		return true;
-	}
+    private boolean isAllBlank(List<ScanStudentPaper> paperIds) {
+        for (ScanStudentPaper spe : paperIds) {
+            ScanPaper paper = paperService.getById(spe.getPaperId());
+            if (paper == null) {
+                throw new ParameterException("paper不存在");
+            }
+            List<ScanPaperPage> pageList = pageService.listByPaperId(spe.getPaperId());
+            for (ScanPaperPage pageEntity : pageList) {
+                for (int i = 0; pageEntity.getQuestion() != null && pageEntity.getQuestion().getResult() != null
+                        && i < pageEntity.getQuestion().getResult().size(); i++) {
+                    String result = pageEntity.getQuestion().getResult().get(i);
+                    if (!"#".equals(result)) {
+                        return false;
+                    }
+                }
+            }
+        }
+        return true;
+    }
 
-	@Override
-	public ScanOmrStudent getTask(Long studentId) {
-		MarkStudent student = studentService.getById(studentId);
-		if (student == null) {
-			throw ExceptionResultEnum.ERROR.exception("没有识别对照任务");
-		}
-		QueryWrapper<ScanOmrTask> wrapper = new QueryWrapper<>();
-		LambdaQueryWrapper<ScanOmrTask> lw = wrapper.lambda();
-		lw.eq(ScanOmrTask::getStudentId, studentId);
-		List<ScanOmrTask> list = baseMapper.selectList(wrapper);
-		if (list.isEmpty()) {
-			throw ExceptionResultEnum.ERROR.exception("没有识别对照任务");
-		}
-		ScanOmrStudent scanOmrStudent = new ScanOmrStudent();
-		scanOmrStudent.setCardNumber(student.getCardNumber());
-		scanOmrStudent.setStudentCode(student.getStudentCode());
-		scanOmrStudent.setStudentName(student.getStudentName());
-		scanOmrStudent.setCourseCode(student.getCourseCode());
-		scanOmrStudent.setCourseName(student.getCourseName());
-		scanOmrStudent.setCoursePaperId(student.getCoursePaperId());
-		scanOmrStudent.setCoursePaperNumber(student.getPaperNumber());
-		scanOmrStudent.setTasks(toTaskVo(list));
-		return scanOmrStudent;
-	}
+    @Override
+    public ScanOmrStudent getTask(Long studentId) {
+        MarkStudent student = studentService.getById(studentId);
+        if (student == null) {
+            throw ExceptionResultEnum.ERROR.exception("没有识别对照任务");
+        }
+        QueryWrapper<ScanOmrTask> wrapper = new QueryWrapper<>();
+        LambdaQueryWrapper<ScanOmrTask> lw = wrapper.lambda();
+        lw.eq(ScanOmrTask::getStudentId, studentId);
+        List<ScanOmrTask> list = baseMapper.selectList(wrapper);
+        if (list.isEmpty()) {
+            throw ExceptionResultEnum.ERROR.exception("没有识别对照任务");
+        }
+        ScanOmrStudent scanOmrStudent = new ScanOmrStudent();
+        scanOmrStudent.setCardNumber(student.getCardNumber());
+        scanOmrStudent.setStudentCode(student.getStudentCode());
+        scanOmrStudent.setStudentName(student.getStudentName());
+        scanOmrStudent.setCourseCode(student.getCourseCode());
+        scanOmrStudent.setCourseName(student.getCourseName());
+        scanOmrStudent.setCoursePaperId(student.getCoursePaperId());
+        scanOmrStudent.setCoursePaperNumber(student.getPaperNumber());
+        scanOmrStudent.setTasks(toTaskVo(list));
+        return scanOmrStudent;
+    }
 
-	private List<ScanOmrTaskDto> toTaskVo(List<ScanOmrTask> tasks) {
-		List<ScanOmrTaskDto> list = new ArrayList<ScanOmrTaskDto>();
-		for (ScanOmrTask task : tasks) {
-			ScanOmrTaskDto vo = new ScanOmrTaskDto();
-			vo.setId(task.getId());
-			vo.setPaperId(task.getPaperId());
-			vo.setPaperNum(task.getPaperIndex());
-			vo.setConditions(task.getConditions());
-			List<ScanOmrTaskPageDto> pages = new ArrayList<>();
-			for (OmrTaskPage taskPage : task.getPages()) {
-				ScanOmrTaskPageDto page = new ScanOmrTaskPageDto();
-				Map<Integer, List<String>> question = new HashMap<>();
-				Map<Integer, List<String>> selective = new HashMap<>();
-				for (OmrTaskItem item : taskPage.getItems()) {
-					if (OmrField.ABSENT.equals(item.getField())) {
-						page.setAbsent(getBooleanItem(item));
-					}
-					if (OmrField.BREACH.equals(item.getField())) {
-						page.setBreach(getBooleanItem(item));
-					}
-					if (OmrField.PAPER_TYPE.equals(item.getField())) {
-						page.setPaperType(getStringItem(item));
-					}
-					if (OmrField.QUESTION.equals(item.getField())) {
-						List<String> content = getStringItem(item);
-						if (content != null) {
-							question.put(item.getIndex(), content);
-						}
-					}
-					if (OmrField.SELECTIVE.equals(item.getField())) {
-						List<String> content = getStringItem(item);
-						if (content != null) {
-							selective.put(item.getIndex(), content);
-						}
-					}
-				}
-				if (question.size() > 0) {
-					page.setQuestion(question);
-				}
-				if (selective.size() > 0) {
-					page.setSelective(selective);
-				}
-				// 有需要仲裁的数据才返回结构
-				if (page.getAbsent() != null || page.getBreach() != null || page.getPaperType() != null
-						|| page.getQuestion() != null || page.getSelective() != null) {
-					page.setIndex(taskPage.getIndex());
-					ScanPaperPage p = pageService.findPaperIdAndIndex(task.getPaperId(), taskPage.getIndex());
-					page.setRecogData(p.getRecogData());
-					page.setUri(teachcloudCommonService.filePreview(p.getSheetPath()));
-					pages.add(page);
-				}
-			}
-			vo.setPages(pages);
-			list.add(vo);
-		}
-		return list;
-	}
+    private List<ScanOmrTaskDto> toTaskVo(List<ScanOmrTask> tasks) {
+        List<ScanOmrTaskDto> list = new ArrayList<ScanOmrTaskDto>();
+        for (ScanOmrTask task : tasks) {
+            ScanOmrTaskDto vo = new ScanOmrTaskDto();
+            vo.setId(task.getId());
+            vo.setPaperId(task.getPaperId());
+            vo.setPaperNum(task.getPaperIndex());
+            vo.setConditions(task.getConditions());
+            List<ScanOmrTaskPageDto> pages = new ArrayList<>();
+            for (OmrTaskPage taskPage : task.getPages()) {
+                ScanOmrTaskPageDto page = new ScanOmrTaskPageDto();
+                Map<Integer, List<String>> question = new HashMap<>();
+                Map<Integer, List<String>> selective = new HashMap<>();
+                for (OmrTaskItem item : taskPage.getItems()) {
+                    if (OmrField.ABSENT.equals(item.getField())) {
+                        page.setAbsent(getBooleanItem(item));
+                    }
+                    if (OmrField.BREACH.equals(item.getField())) {
+                        page.setBreach(getBooleanItem(item));
+                    }
+                    if (OmrField.PAPER_TYPE.equals(item.getField())) {
+                        page.setPaperType(getStringItem(item));
+                    }
+                    if (OmrField.QUESTION.equals(item.getField())) {
+                        List<String> content = getStringItem(item);
+                        if (content != null) {
+                            question.put(item.getIndex(), content);
+                        }
+                    }
+                    if (OmrField.SELECTIVE.equals(item.getField())) {
+                        List<String> content = getStringItem(item);
+                        if (content != null) {
+                            selective.put(item.getIndex(), content);
+                        }
+                    }
+                }
+                if (question.size() > 0) {
+                    page.setQuestion(question);
+                }
+                if (selective.size() > 0) {
+                    page.setSelective(selective);
+                }
+                // 有需要仲裁的数据才返回结构
+                if (page.getAbsent() != null || page.getBreach() != null || page.getPaperType() != null
+                        || page.getQuestion() != null || page.getSelective() != null) {
+                    page.setIndex(taskPage.getIndex());
+                    ScanPaperPage p = pageService.findPaperIdAndIndex(task.getPaperId(), taskPage.getIndex());
+                    page.setRecogData(p.getRecogData());
+                    page.setUri(teachcloudCommonService.filePreview(p.getSheetPath()));
+                    pages.add(page);
+                }
+            }
+            vo.setPages(pages);
+            list.add(vo);
+        }
+        return list;
+    }
 
-	private List<String> getStringItem(OmrTaskItem item) {
-		List<String> value = new ArrayList<>();
-		value.add(item.getOmrResult());
-		if (item.getFirstResult() != null && item.getSecondResult() == null) {
-			value.add(item.getFirstResult());
-		} else if (item.getSecondResult() != null) {
-			value.add(item.getSecondResult());
-		}
-		return value;
-	}
+    private List<String> getStringItem(OmrTaskItem item) {
+        List<String> value = new ArrayList<>();
+        value.add(item.getOmrResult());
+        if (item.getFirstResult() != null && item.getSecondResult() == null) {
+            value.add(item.getFirstResult());
+        } else if (item.getSecondResult() != null) {
+            value.add(item.getSecondResult());
+        }
+        return value;
+    }
 
-	private List<Boolean> getBooleanItem(OmrTaskItem item) {
-		List<Boolean> value = new ArrayList<>();
-		value.add(Boolean.valueOf(item.getOmrResult()));
-		if (item.getFirstResult() != null && item.getSecondResult() == null) {
-			value.add(Boolean.valueOf(item.getFirstResult()));
-		} else if (item.getSecondResult() != null) {
-			value.add(Boolean.valueOf(item.getSecondResult()));
-		}
-		return value;
-	}
+    private List<Boolean> getBooleanItem(OmrTaskItem item) {
+        List<Boolean> value = new ArrayList<>();
+        value.add(Boolean.valueOf(item.getOmrResult()));
+        if (item.getFirstResult() != null && item.getSecondResult() == null) {
+            value.add(Boolean.valueOf(item.getFirstResult()));
+        } else if (item.getSecondResult() != null) {
+            value.add(Boolean.valueOf(item.getSecondResult()));
+        }
+        return value;
+    }
 
-	@Override
-	@Transactional
-	public ScanOmrTaskSaveDto submitTask(@NotNull List<ScanOmrTaskResultDto> results, @NotNull Long userId) {
-		Long studentId = null;
-		for (ScanOmrTaskResultDto result : results) {
-			ScanOmrTask task = this.getById(result.getId());
-			if (task == null) {
-				throw new ParameterException("任务不存在");
-			}
-			if (studentId == null) {
-				studentId = task.getStudentId();
-			}
-			if (!Objects.equals(studentId, task.getStudentId())) {
-				throw new ParameterException("任务非同一个学生");
-			}
-			concurrentService.getReadWriteLock(LockType.STUDENT + "-" + task.getStudentId()).writeLock().lock();
+    @Override
+    @Transactional
+    public ScanOmrTaskSaveDto submitTask(@NotNull List<ScanOmrTaskResultDto> results, @NotNull Long userId) {
+        Long studentId = null;
+        for (ScanOmrTaskResultDto result : results) {
+            ScanOmrTask task = this.getById(result.getId());
+            if (task == null) {
+                throw new ParameterException("任务不存在");
+            }
+            if (studentId == null) {
+                studentId = task.getStudentId();
+            }
+            if (!Objects.equals(studentId, task.getStudentId())) {
+                throw new ParameterException("任务非同一个学生");
+            }
+            MarkStudent markStudent = studentService.getById(studentId);
+            if (markStudent == null) {
+                throw new ParameterException("考生不存在");
+            }
+            MarkPaper markPaper = markPaperService.getByExamIdAndCoursePaperId(markStudent.getExamId(), markStudent.getCoursePaperId());
+            if (markPaper == null) {
+                throw new ParameterException("课程不存在");
+            }
+            if (MarkPaperStatus.FINISH.equals(markPaper.getStatus())) {
+                throw ExceptionResultEnum.MARK_PAPER_FINISH.exception();
+            }
+            concurrentService.getReadWriteLock(LockType.STUDENT + "-" + task.getStudentId()).writeLock().lock();
 
-			try {
-				for (OmrTaskPage page : task.getPages()) {
-					ScanOmrTaskResultPageDto pageVo = result.findPage(page.getIndex());
-					if (pageVo == null) {
-						throw new ParameterException("page[" + page.getIndex() + "]不存在");
-					}
-					for (OmrTaskItem item : page.getItems()) {
-						if (OmrField.ABSENT.equals(item.getField())) {
-							if (pageVo.getAbsent() == null) {
-								throw new ParameterException("page[" + page.getIndex() + "].absent不存在");
-							}
-							item.setFirstResult(pageVo.getAbsent().toString());
-						}
-						if (OmrField.BREACH.equals(item.getField())) {
-							if (pageVo.getBreach() == null) {
-								throw new ParameterException("page[" + page.getIndex() + "].breach不存在");
-							}
-							item.setFirstResult(pageVo.getBreach().toString());
-						}
-						if (OmrField.QUESTION.equals(item.getField())) {
-							String content = pageVo.getQuestion() != null ? pageVo.getQuestion().get(item.getIndex())
-									: null;
-							if (content == null) {
-								throw new ParameterException(
-										"page[" + page.getIndex() + "].question[" + item.getIndex() + "]不存在");
-							}
-							item.setFirstResult(content);
-						}
-						if (OmrField.SELECTIVE.equals(item.getField())) {
-							String content = pageVo.getSelective() != null ? pageVo.getSelective().get(item.getIndex())
-									: null;
-							if (content == null) {
-								throw new ParameterException(
-										"page[" + page.getIndex() + "].selective[" + item.getIndex() + "]不存在");
-							}
-							item.setFirstResult(content);
-						}
-					}
-				}
-				task.setStatus(OmrTaskStatus.PROCESSED);
-				updatePaperResult(result, task.getPaperId(), userId);
-				task.setUserId(userId);
-				task.setUpdateTime(System.currentTimeMillis());
-				this.saveOrUpdate(task);
-			} finally {
-				concurrentService.getReadWriteLock(LockType.STUDENT + "-" + task.getStudentId()).writeLock().unlock();
-			}
-		}
-		ScanOmrTaskSaveDto vo = new ScanOmrTaskSaveDto();
-		vo.setStudentId(studentId);
-		vo.setUpdateTime(System.currentTimeMillis());
-		return vo;
-	}
+            try {
+                for (OmrTaskPage page : task.getPages()) {
+                    ScanOmrTaskResultPageDto pageVo = result.findPage(page.getIndex());
+                    if (pageVo == null) {
+                        throw new ParameterException("page[" + page.getIndex() + "]不存在");
+                    }
+                    for (OmrTaskItem item : page.getItems()) {
+                        if (OmrField.ABSENT.equals(item.getField())) {
+                            if (pageVo.getAbsent() == null) {
+                                throw new ParameterException("page[" + page.getIndex() + "].absent不存在");
+                            }
+                            item.setFirstResult(pageVo.getAbsent().toString());
+                        }
+                        if (OmrField.BREACH.equals(item.getField())) {
+                            if (pageVo.getBreach() == null) {
+                                throw new ParameterException("page[" + page.getIndex() + "].breach不存在");
+                            }
+                            item.setFirstResult(pageVo.getBreach().toString());
+                        }
+                        if (OmrField.QUESTION.equals(item.getField())) {
+                            String content = pageVo.getQuestion() != null ? pageVo.getQuestion().get(item.getIndex())
+                                    : null;
+                            if (content == null) {
+                                throw new ParameterException(
+                                        "page[" + page.getIndex() + "].question[" + item.getIndex() + "]不存在");
+                            }
+                            item.setFirstResult(content);
+                        }
+                        if (OmrField.SELECTIVE.equals(item.getField())) {
+                            String content = pageVo.getSelective() != null ? pageVo.getSelective().get(item.getIndex())
+                                    : null;
+                            if (content == null) {
+                                throw new ParameterException(
+                                        "page[" + page.getIndex() + "].selective[" + item.getIndex() + "]不存在");
+                            }
+                            item.setFirstResult(content);
+                        }
+                    }
+                }
+                task.setStatus(OmrTaskStatus.PROCESSED);
+                updatePaperResult(result, task.getPaperId(), userId);
+                task.setUserId(userId);
+                task.setUpdateTime(System.currentTimeMillis());
+                this.saveOrUpdate(task);
+            } finally {
+                concurrentService.getReadWriteLock(LockType.STUDENT + "-" + task.getStudentId()).writeLock().unlock();
+            }
+        }
+        ScanOmrTaskSaveDto vo = new ScanOmrTaskSaveDto();
+        vo.setStudentId(studentId);
+        vo.setUpdateTime(System.currentTimeMillis());
+        return vo;
+    }
 
-	private void updatePaperResult(ScanOmrTaskResultDto result, Long paperId, Long userId) {
-		ScanPaper paper = paperService.getById(paperId);
-		ScanStudentPaper sp = studentPaperService.findByPaperId(paperId);
-		if (paper == null) {
-			throw new ParameterException("未找到paper信息");
-		}
-		if (sp == null) {
-			throw new ParameterException("paper未绑定考生");
-		}
-		List<ScanPaperPage> pages = pageService.listByPaperId(paperId);
-		if (CollectionUtils.isEmpty(pages)) {
-			throw new ParameterException("未找到page信息");
-		}
-		for (ScanPaperPage page : pages) {
-			ScanOmrTaskResultPageDto vo = result.findPage(page.getPageIndex());
-			if (vo != null) {
-				vo.update(page);
-			}
-		}
-		paperService.savePaperAndPages(paper, pages);
-		studentService.updateStudentByPaper(userId, sp.getStudentId(), false);
-	}
+    private void updatePaperResult(ScanOmrTaskResultDto result, Long paperId, Long userId) {
+        ScanPaper paper = paperService.getById(paperId);
+        ScanStudentPaper sp = studentPaperService.findByPaperId(paperId);
+        if (paper == null) {
+            throw new ParameterException("未找到paper信息");
+        }
+        if (sp == null) {
+            throw new ParameterException("paper未绑定考生");
+        }
+        List<ScanPaperPage> pages = pageService.listByPaperId(paperId);
+        if (CollectionUtils.isEmpty(pages)) {
+            throw new ParameterException("未找到page信息");
+        }
+        for (ScanPaperPage page : pages) {
+            ScanOmrTaskResultPageDto vo = result.findPage(page.getPageIndex());
+            if (vo != null) {
+                vo.update(page);
+            }
+        }
+        paperService.savePaperAndPages(paper, pages);
+        studentService.updateStudentByPaper(userId, sp.getStudentId(), false);
+    }
 
-	@Override
-	public ScanOmrTaskStatusDto getStatus(Long examId, Long userId) {
-		ScanOmrTaskStatusDto status = new ScanOmrTaskStatusDto();
-		status.setFinishCount(this.getFinishStudentCountByExamAndUserId(examId, userId));
-		status.setTodoCount(this.getTodoStudentCountByExam(examId));
-		return status;
-	}
+    @Override
+    public ScanOmrTaskStatusDto getStatus(Long examId, Long userId) {
+        ScanOmrTaskStatusDto status = new ScanOmrTaskStatusDto();
+        status.setFinishCount(this.getFinishStudentCountByExamAndUserId(examId, userId));
+        status.setTodoCount(this.getTodoStudentCountByExam(examId));
+        return status;
+    }
 
-	@Override
-	public int getFinishStudentCountByExamAndUserId(Long examId, Long userId) {
-		return this.baseMapper.getStudentCountByExamAndStatusAndUserId(examId, userId, OmrTaskStatus.PROCESSED);
-	}
+    @Override
+    public int getFinishStudentCountByExamAndUserId(Long examId, Long userId) {
+        return this.baseMapper.getStudentCountByExamAndStatusAndUserId(examId, userId, OmrTaskStatus.PROCESSED);
+    }
 
-	@Override
-	public int getTodoStudentCountByExam(Long examId) {
-		return this.baseMapper.getStudentCountByExamAndStatus(examId, OmrTaskStatus.WAITING);
-	}
+    @Override
+    public int getTodoStudentCountByExam(Long examId) {
+        return this.baseMapper.getStudentCountByExamAndStatus(examId, OmrTaskStatus.WAITING);
+    }
 
-	@Transactional
-	@Override
-	public void deleteByStudentId(Long examId, Long studentId) {
-		QueryWrapper<ScanOmrTask> wrapper = new QueryWrapper<>();
-		LambdaQueryWrapper<ScanOmrTask> lw = wrapper.lambda();
-		lw.eq(ScanOmrTask::getExamId, examId);
-		lw.eq(ScanOmrTask::getStudentId, studentId);
-		List<ScanOmrTask> tasks = baseMapper.selectList(wrapper);
-		if (CollectionUtils.isEmpty(tasks)) {
-			return;
-		}
-		concurrentService.getReadWriteLock(LockType.STUDENT + "-" + studentId).writeLock().lock();
-		try {
-			List<Long> ids=tasks.stream().map(e->e.getId()).collect(Collectors.toList());
-			this.removeByIds(ids);
-		} finally {
-			concurrentService.getReadWriteLock(LockType.STUDENT + "-" + studentId).writeLock().unlock();
-		}
-	}
+    @Transactional
+    @Override
+    public void deleteByStudentId(Long examId, Long studentId) {
+        QueryWrapper<ScanOmrTask> wrapper = new QueryWrapper<>();
+        LambdaQueryWrapper<ScanOmrTask> lw = wrapper.lambda();
+        lw.eq(ScanOmrTask::getExamId, examId);
+        lw.eq(ScanOmrTask::getStudentId, studentId);
+        List<ScanOmrTask> tasks = baseMapper.selectList(wrapper);
+        if (CollectionUtils.isEmpty(tasks)) {
+            return;
+        }
+        concurrentService.getReadWriteLock(LockType.STUDENT + "-" + studentId).writeLock().lock();
+        try {
+            List<Long> ids = tasks.stream().map(e -> e.getId()).collect(Collectors.toList());
+            this.removeByIds(ids);
+        } finally {
+            concurrentService.getReadWriteLock(LockType.STUDENT + "-" + studentId).writeLock().unlock();
+        }
+    }
 
-	@Override
-	public int getCount(Long examId, OmrTaskStatus status, DataPermissionRule dpr) {
-		ScanOmrTask scanOmrTask = new ScanOmrTask();
-		scanOmrTask.setExamId(examId);
-		scanOmrTask.setStatus(status);
-		return baseMapper.countOmrTask(scanOmrTask, dpr);
-	}
+    @Override
+    public int getCount(Long examId, OmrTaskStatus status, DataPermissionRule dpr) {
+        ScanOmrTask scanOmrTask = new ScanOmrTask();
+        scanOmrTask.setExamId(examId);
+        scanOmrTask.setStatus(status);
+        return baseMapper.countOmrTask(scanOmrTask, dpr);
+    }
 
-	@Override
-	public List<ScanStudentDto> list(Long examId, OmrTaskStatus status, Long userId) {
-		return this.baseMapper.listByExamIdAndStatusAndUserId(examId, status, userId);
-	}
+    @Override
+    public List<ScanStudentDto> list(Long examId, OmrTaskStatus status, Long userId) {
+        return this.baseMapper.listByExamIdAndStatusAndUserId(examId, status, userId);
+    }
 
-	@Override
-	public void saveTask(Long studentId) {
-		List<ScanOmrTask> omrTaskList = new ArrayList<ScanOmrTask>();
-		for (ConditionType c : ConditionType.values()) {
-			ScanOmrTask omrTask = this.buildTask(c, studentId);
-			if (omrTask != null) {
-				omrTaskList.add(omrTask);
-			}
-		}
-		if (!omrTaskList.isEmpty()) {
-			this.saveBatch(omrTaskList);
-		}
-	}
+    @Override
+    public void saveTask(Long studentId) {
+        List<ScanOmrTask> omrTaskList = new ArrayList<ScanOmrTask>();
+        for (ConditionType c : ConditionType.values()) {
+            ScanOmrTask omrTask = this.buildTask(c, studentId);
+            if (omrTask != null) {
+                omrTaskList.add(omrTask);
+            }
+        }
+        if (!omrTaskList.isEmpty()) {
+            this.saveBatch(omrTaskList);
+        }
+    }
 }