xiaofei 1 ano atrás
pai
commit
31b9150478
18 arquivos alterados com 411 adições e 336 exclusões
  1. 4 0
      distributed-print-business/pom.xml
  2. 2 1
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/enums/ExamDetailStatusEnum.java
  3. 15 6
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamDetailServiceImpl.java
  4. 21 14
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamTaskDetailServiceImpl.java
  5. 3 6
      distributed-print/src/main/java/com/qmth/distributed/print/api/ExamPrintTaskController.java
  6. 1 5
      distributed-print/src/main/java/com/qmth/distributed/print/api/ExamTaskQueryController.java
  7. 2 1
      distributed-print/src/main/java/com/qmth/distributed/print/api/mark/ScanAnswerBatchController.java
  8. 9 5
      distributed-print/src/main/java/com/qmth/distributed/print/api/mark/ScanAnswerCardController.java
  9. 36 19
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/bean/answercard/AnswerCardSaveVo.java
  10. 67 30
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/entity/ScanAnswerCard.java
  11. 1 1
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/ScanAnswerCardService.java
  12. 2 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/ScanPaperService.java
  13. 2 4
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkFileServiceImpl.java
  14. 15 4
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/ScanAnswerCardServiceImpl.java
  15. 213 211
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/ScanPaperServiceImpl.java
  16. 3 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/utils/FileStoreUtils.java
  17. 1 1
      teachcloud-task/src/main/java/com/qmth/teachcloud/task/service/PrintFinishService.java
  18. 14 28
      teachcloud-task/src/main/java/com/qmth/teachcloud/task/service/impl/PrintFinishServiceImpl.java

+ 4 - 0
distributed-print-business/pom.xml

@@ -35,6 +35,10 @@
             <groupId>com.qmth.teachcloud.common</groupId>
             <artifactId>teachcloud-common</artifactId>
         </dependency>
+        <dependency>
+            <groupId>com.qmth.teachcloud.mark</groupId>
+            <artifactId>teachcloud-mark</artifactId>
+        </dependency>
         <dependency>
             <groupId>org.jetbrains</groupId>
             <artifactId>annotations</artifactId>

+ 2 - 1
distributed-print-business/src/main/java/com/qmth/distributed/print/business/enums/ExamDetailStatusEnum.java

@@ -15,7 +15,8 @@ public enum ExamDetailStatusEnum {
     WAITING("待打印"),
     PRINTING("印刷中"),
     FINISH("已完成"),
-    CANCEL("作废");
+    CANCEL("作废"),
+    REJECT("打回");
     private final String desc;
 
     ExamDetailStatusEnum(String desc) {

+ 15 - 6
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamDetailServiceImpl.java

@@ -17,21 +17,21 @@ import com.qmth.distributed.print.business.bean.examRule.FieldsDto;
 import com.qmth.distributed.print.business.bean.result.ExaminationDetailResult;
 import com.qmth.distributed.print.business.bean.result.ExaminationResult;
 import com.qmth.distributed.print.business.bean.result.SummarizedDataResult;
-import com.qmth.teachcloud.common.bean.vo.PaperInfoVo;
 import com.qmth.distributed.print.business.entity.*;
 import com.qmth.distributed.print.business.enums.*;
 import com.qmth.distributed.print.business.mapper.ExamDetailMapper;
 import com.qmth.distributed.print.business.service.*;
 import com.qmth.distributed.print.business.templete.execute.AsyncExaminationImportTemplateService;
-import com.qmth.teachcloud.common.util.RedisCounterUtil;
 import com.qmth.teachcloud.common.bean.dto.DataPermissionRule;
 import com.qmth.teachcloud.common.bean.dto.MqDto;
 import com.qmth.teachcloud.common.bean.result.TbTaskDetailResult;
+import com.qmth.teachcloud.common.bean.vo.PaperInfoVo;
 import com.qmth.teachcloud.common.contant.SystemConstant;
 import com.qmth.teachcloud.common.entity.*;
 import com.qmth.teachcloud.common.enums.*;
 import com.qmth.teachcloud.common.service.*;
 import com.qmth.teachcloud.common.util.*;
+import com.qmth.teachcloud.mark.service.ScanPaperService;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.poi.ss.usermodel.FillPatternType;
 import org.apache.poi.ss.usermodel.Font;
@@ -136,9 +136,8 @@ public class ExamDetailServiceImpl extends ServiceImpl<ExamDetailMapper, ExamDet
 
     @Resource
     BasicPrintConfigService basicPrintConfigService;
-
     @Resource
-    BasicCardRuleService basicCardRuleService;
+    private ScanPaperService scanPaperService;
 
     @Resource
     @Lazy
@@ -935,8 +934,18 @@ public class ExamDetailServiceImpl extends ServiceImpl<ExamDetailMapper, ExamDet
 
     @Override
     public boolean taskNormal(ExamDetail examDetail) {
+        // 已扫描过,不能作废
+        if (!examDetail.getNormal()) {
+            List<ExamDetailCourse> examDetailCourseList = examDetailCourseService.listByExamDetailId(examDetail.getId());
+            for (ExamDetailCourse examDetailCourse : examDetailCourseList) {
+                boolean isScanPaper = scanPaperService.isScanByExamIdAndPaperNumber(examDetail.getExamId(), examDetailCourse.getPaperNumber());
+                if (isScanPaper) {
+                    throw ExceptionResultEnum.ERROR.exception("有课程已开始扫描,无法作废");
+                }
+            }
+        }
         ExamDetail detail = this.getById(examDetail.getId());
-        if (ExamDetailStatusEnum.CANCEL.equals(detail.getStatus()) && !examDetail.getNormal()) {
+        if (ExamDetailStatusEnum.CANCEL.equals(detail.getStatus()) && examDetail.getNormal()) {
             throw ExceptionResultEnum.ERROR.exception("印刷任务关联的命题任务已作废,无法恢复");
         }
         UpdateWrapper<ExamDetail> updateWrapper = new UpdateWrapper<>();
@@ -1164,7 +1173,7 @@ public class ExamDetailServiceImpl extends ServiceImpl<ExamDetailMapper, ExamDet
 
         // 清掉客户端产生的数据和考场文件,包含状态、校验状态,pdf文件路径,打印信息
         UpdateWrapper<ExamDetail> examDetailUpdateWrapper = new UpdateWrapper<>();
-        examDetailUpdateWrapper.lambda().set(ExamDetail::getStatus, ExamDetailStatusEnum.NEW)
+        examDetailUpdateWrapper.lambda().set(ExamDetail::getStatus, ExamDetailStatusEnum.REJECT)
                 .set(ExamDetail::getValidate, false)
                 .set(ExamDetail::getAttachmentId, null)
                 .set(ExamDetail::getCardAttachmentId, null)

+ 21 - 14
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamTaskDetailServiceImpl.java

@@ -25,13 +25,14 @@ import com.qmth.teachcloud.common.service.*;
 import com.qmth.teachcloud.common.util.ExamTaskUtil;
 import com.qmth.teachcloud.common.util.RedisUtil;
 import com.qmth.teachcloud.common.util.ServletUtil;
+import com.qmth.teachcloud.mark.service.ScanPaperService;
 import org.activiti.engine.TaskService;
 import org.activiti.engine.task.Task;
+import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
-import org.springframework.util.CollectionUtils;
 
 import javax.annotation.Resource;
 import java.util.*;
@@ -86,6 +87,8 @@ public class ExamTaskDetailServiceImpl extends ServiceImpl<ExamTaskDetailMapper,
     @Resource
     private ExamTaskDetailMapper examTaskDetailMapper;
     @Resource
+    private ScanPaperService scanPaperService;
+    @Resource
     private BasicRoleDataPermissionService basicRoleDataPermissionService;
 
     @Transactional
@@ -182,7 +185,7 @@ public class ExamTaskDetailServiceImpl extends ServiceImpl<ExamTaskDetailMapper,
             for (ExamDetail examDetail : examDetails) {
                 List<ExamDetailCourse> examDetailCourses = examDetailCourseService.listByExamDetailIdAndStatus(examDetail.getId());
                 // 4.没有未完成的命题任务
-                if (!CollectionUtils.isEmpty(examDetailCourses)) {
+                if (CollectionUtils.isNotEmpty(examDetailCourses)) {
                     throw ExceptionResultEnum.ERROR.exception("有关联该任务的考场有未完成的命题任务,不能修改关联类型");
                 }
             }
@@ -280,7 +283,7 @@ public class ExamTaskDetailServiceImpl extends ServiceImpl<ExamTaskDetailMapper,
         QueryWrapper<ExamTaskDetail> examTaskDetailQueryWrapper = new QueryWrapper<>();
         examTaskDetailQueryWrapper.lambda().eq(ExamTaskDetail::getExamTaskId, id);
         List<ExamTaskDetail> examTaskDetails = this.list(examTaskDetailQueryWrapper);
-        if (!CollectionUtils.isEmpty(examTaskDetails)) {
+        if (CollectionUtils.isNotEmpty(examTaskDetails)) {
             for (ExamTaskDetail e : examTaskDetails) {
                 if (Objects.nonNull(e.getPaperAttachmentIds())) {
                     List<PaperInfoVo> paperInfoVoList = ExamTaskUtil.parsePaperAttachmentPath(e.getPaperAttachmentIds());
@@ -298,7 +301,7 @@ public class ExamTaskDetailServiceImpl extends ServiceImpl<ExamTaskDetailMapper,
     public List<Map<String, String>> getPaperUrl(Long schoolId, Long printPlanId, Long examTaskId) {
         ExamTask examTask = examTaskService.getById(examTaskId);
         List<ExamDetailCourse> examDetailCourses = examDetailCourseService.listByPrintPlanIdAndCourseCodeAndPaperNumber(schoolId, printPlanId, examTask.getCourseCode(), examTask.getPaperNumber());
-        if (!CollectionUtils.isEmpty(examDetailCourses)) {
+        if (CollectionUtils.isNotEmpty(examDetailCourses)) {
             Set<String> relatePaperTypes = examDetailCourses.stream().filter(m -> StringUtils.isNotBlank(m.getPaperType())).map(m -> m.getPaperType()).collect(Collectors.toSet());
             List<Map<String, String>> paperList = new ArrayList<>();
             QueryWrapper<ExamTaskDetail> examTaskDetailQueryWrapper = new QueryWrapper<>();
@@ -369,7 +372,7 @@ public class ExamTaskDetailServiceImpl extends ServiceImpl<ExamTaskDetailMapper,
         QueryWrapper<ExamTaskDetail> examTaskDetailQueryWrapper = new QueryWrapper<>();
         examTaskDetailQueryWrapper.lambda().eq(ExamTaskDetail::getExamTaskId, examTaskDetail.getExamTaskId());
         List<ExamTaskDetail> examTaskDetailList = this.list(examTaskDetailQueryWrapper);
-        if (!CollectionUtils.isEmpty(examTaskDetailList)) {
+        if (CollectionUtils.isNotEmpty(examTaskDetailList)) {
             for (ExamTaskDetail e : examTaskDetailList) {
                 e.setPaperType(examTaskDetail.getPaperType());
                 e.setPaperAttachmentIds(examTaskDetail.getPaperAttachmentIds());
@@ -379,7 +382,7 @@ public class ExamTaskDetailServiceImpl extends ServiceImpl<ExamTaskDetailMapper,
 
         ExamTask examTask = examTaskService.getById(examTaskDetail.getExamTaskId());
         List<ExamDetail> examDetails = examDetailService.listByCourseCodeAndPaperNumber(examTask.getSchoolId(), examTask.getExamId(), examTask.getCourseCode(), examTask.getPaperNumber());
-        if (!CollectionUtils.isEmpty(examDetails)) {
+        if (CollectionUtils.isNotEmpty(examDetails)) {
             StringJoiner stringJoiner = new StringJoiner("_");
             stringJoiner.add(String.valueOf(examDetails.get(0).getSchoolId()))
                     .add(String.valueOf(examDetails.get(0).getExamStartTime()))
@@ -449,16 +452,20 @@ public class ExamTaskDetailServiceImpl extends ServiceImpl<ExamTaskDetailMapper,
 
         Map<String, Object> mapVar = new HashMap<>();
         ExamTask examTask = examTaskService.getById(examTaskDetail.getExamTaskId());
-        List<ExamDetail> examDetails = examDetailService.listByCourseCodeAndPaperNumber(examTask.getSchoolId(), examTask.getExamId(), examTask.getCourseCode(), examTask.getPaperNumber());
-        if (!CollectionUtils.isEmpty(examDetails)) {
+        List<ExamDetail> examDetailList = examDetailService.listByCourseCodeAndPaperNumber(examTask.getSchoolId(), examTask.getExamId(), examTask.getCourseCode(), examTask.getPaperNumber());
+        if (CollectionUtils.isNotEmpty(examDetailList)) {
             ExamTaskDetail taskDetail = this.getByExamTaskId(examTaskDetail.getExamTaskId());
             if (StringUtils.isNotBlank(taskDetail.getExposedPaperType())) {
-                List<Long> examDetailIds = examDetails.stream().map(ExamDetail::getId).collect(Collectors.toList());
+                List<Long> examDetailIds = examDetailList.stream().map(ExamDetail::getId).collect(Collectors.toList());
                 QueryWrapper<ExamDetailCourse> queryWrapper = new QueryWrapper<>();
                 queryWrapper.lambda().in(ExamDetailCourse::getExamDetailId, examDetailIds);
                 List<ExamDetailCourse> examDetailCourseList = examDetailCourseService.list(queryWrapper);
                 Set<String> paperTypeSet = new HashSet<>();
                 for (ExamDetailCourse examDetailCourse : examDetailCourseList) {
+                    boolean isScanPaper = scanPaperService.isScanByExamIdAndPaperNumber(examTask.getExamId(), examDetailCourse.getPaperNumber());
+                    if (isScanPaper) {
+                        throw ExceptionResultEnum.ERROR.exception("有课程已开始扫描,无法打回");
+                    }
                     if (StringUtils.isNotBlank(examDetailCourse.getPaperType())) {
                         paperTypeSet.addAll(Arrays.asList(examDetailCourse.getPaperType().split(",")));
                     }
@@ -481,10 +488,10 @@ public class ExamTaskDetailServiceImpl extends ServiceImpl<ExamTaskDetailMapper,
             }
 
             StringJoiner stringJoiner = new StringJoiner("_");
-            stringJoiner.add(String.valueOf(examTask.getExamId())).add(examTask.getPaperNumber()).add(String.valueOf(examDetails.get(0).getExamStartTime())).add(String.valueOf(examDetails.get(0).getExamEndTime()));
+            stringJoiner.add(String.valueOf(examTask.getExamId())).add(examTask.getPaperNumber()).add(String.valueOf(examDetailList.get(0).getExamStartTime())).add(String.valueOf(examDetailList.get(0).getExamEndTime()));
             String key = stringJoiner.toString();
             CreatePdfCacheUtil.deletePaperType(key);
-            for (ExamDetail examDetail : examDetails) {
+            for (ExamDetail examDetail : examDetailList) {
                 examDetailService.resetExamDetail(examDetail.getId(), true);
             }
         }
@@ -543,7 +550,7 @@ public class ExamTaskDetailServiceImpl extends ServiceImpl<ExamTaskDetailMapper,
         } else {
             // 不需要审核
             UpdateWrapper<ExamTask> updateWrapper = new UpdateWrapper<>();
-            updateWrapper.lambda().set(ExamTask::getStatus, ExamStatusEnum.STAGE).eq(ExamTask::getId, examTaskDetail.getExamTaskId());
+            updateWrapper.lambda().set(ExamTask::getStatus, ExamStatusEnum.SUBMIT).eq(ExamTask::getId, examTaskDetail.getExamTaskId());
             examTaskService.update(updateWrapper);
         }
         mapVar.put(SystemConstant.SUCCESS, true);
@@ -634,7 +641,7 @@ public class ExamTaskDetailServiceImpl extends ServiceImpl<ExamTaskDetailMapper,
         // 作废后,考场状态改为作废,考务数据保留
         List<ExamDetailCourse> examDetailCourseList = examDetailCourseService.listExamDetailByExamIdAndPaperNumber(examTask.getSchoolId(), examTask.getExamId(), paperNumber);
         // 考场状态改为作废
-        if (!CollectionUtils.isEmpty(examDetailCourseList)) {
+        if (CollectionUtils.isNotEmpty(examDetailCourseList)) {
             for (ExamDetailCourse examDetailCourse : examDetailCourseList) {
                 UpdateWrapper<ExamDetail> examDetailUpdateWrapper = new UpdateWrapper<>();
                 examDetailUpdateWrapper.lambda().set(ExamDetail::getStatus, ExamDetailStatusEnum.CANCEL)
@@ -717,7 +724,7 @@ public class ExamTaskDetailServiceImpl extends ServiceImpl<ExamTaskDetailMapper,
 
         // 提交印刷的考场,不允许修改关联试卷
         List<ExamDetail> examDetails = examDetailService.listByCourseCodeAndPaperNumber(examTask.getSchoolId(), examTask.getExamId(), examTask.getCourseCode(), examTask.getPaperNumber());
-        if (!CollectionUtils.isEmpty(examDetails)) {
+        if (CollectionUtils.isNotEmpty(examDetails)) {
             List<ExamDetail> examDetails1 = examDetails.stream().filter(m -> !ExamDetailStatusEnum.NEW.equals(m.getStatus())
                     && !ExamDetailStatusEnum.READY.equals(m.getStatus())
                     && !ExamDetailStatusEnum.WAITING.equals(m.getStatus())).collect(Collectors.toList());

+ 3 - 6
distributed-print/src/main/java/com/qmth/distributed/print/api/ExamPrintTaskController.java

@@ -53,9 +53,9 @@ public class ExamPrintTaskController {
     @Resource
     private ExamDetailService examDetailService;
     @Resource
-    TBTaskService tbTaskService;
+    private TBTaskService tbTaskService;
     @Resource
-    AsyncDownloadPdfTempleteService asyncDownloadPdfTempleteService;
+    private AsyncDownloadPdfTempleteService asyncDownloadPdfTempleteService;
 
     /**
      * 印刷任务管理-查询
@@ -232,11 +232,8 @@ public class ExamPrintTaskController {
 
     /**
      * 印刷任务做废、恢复
-     *
-     * @param examDetail
-     * @return
      */
-    @ApiOperation(value = "印刷任务管理-废/恢复")
+    @ApiOperation(value = "印刷任务管理-作废/恢复")
     @RequestMapping(value = "/task_normal", method = RequestMethod.POST)
     @OperationLogDetail(customizedOperationType = CustomizedOperationTypeEnum.UPDATE)
     public Result taskNormal(@RequestBody ExamDetail examDetail) {

+ 1 - 5
distributed-print/src/main/java/com/qmth/distributed/print/api/ExamTaskQueryController.java

@@ -47,18 +47,14 @@ public class ExamTaskQueryController {
 
     @Resource
     private ExamTaskService examTaskService;
-
     @Resource
     private ExamTaskDetailService examTaskDetailService;
-
     @Resource
     private PrintCommonService printCommonService;
-
     @Resource
     private BasicMessageService basicMessageService;
-
     @Resource
-    ActivitiService activitiService;
+    private ActivitiService activitiService;
 
     /**
      * 卷库查询

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

@@ -1,6 +1,7 @@
 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;
@@ -46,7 +47,7 @@ public class ScanAnswerBatchController {
 	
 	@Autowired
 	private BasicExamService basicExamService;
-	
+
     @ApiOperation(value = "答题卡扫描批次创建")
     @RequestMapping(value = "create", method = RequestMethod.POST)
     public Result batchCreate(@Validated @RequestBody BatchCreateDomain domain) {

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

@@ -7,12 +7,13 @@ import com.qmth.boot.core.exception.ReentrantException;
 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.service.TeachcloudCommonService;
 import com.qmth.teachcloud.common.util.Result;
 import com.qmth.teachcloud.common.util.ResultUtil;
 import com.qmth.teachcloud.mark.bean.UriVo;
 import com.qmth.teachcloud.mark.bean.answercard.AnswerCardSaveDomain;
 import com.qmth.teachcloud.mark.bean.answercard.AnswerCardSaveVo;
-import com.qmth.teachcloud.mark.bean.answercard.AnswerCardVo;
+import com.qmth.teachcloud.mark.entity.ScanAnswerCard;
 import com.qmth.teachcloud.mark.enums.LockType;
 import com.qmth.teachcloud.mark.service.ScanAnswerCardService;
 import io.swagger.annotations.Api;
@@ -24,6 +25,8 @@ import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.multipart.MultipartFile;
 
+import javax.annotation.Resource;
+
 /**
  * <p>
  * 题卡卡格式表 前端控制器
@@ -45,6 +48,8 @@ public class ScanAnswerCardController {
 
     @Autowired
     private BasicExamService basicExamService;
+    @Resource
+    private TeachcloudCommonService teachcloudCommonService;
 
     @ApiOperation(value = "答题卡卡格式列表")
     @RequestMapping(value = "list", method = RequestMethod.POST)
@@ -63,12 +68,11 @@ public class ScanAnswerCardController {
         if (exam == null) {
             throw new ParameterException("未找到考试信息");
         }
-        AnswerCardSaveDomain domain = new AnswerCardSaveDomain(number, examId, coursePaperId, remark, paperCount, file,
-                md5, dpi);
+        AnswerCardSaveDomain domain = new AnswerCardSaveDomain(number, examId, coursePaperId, remark, paperCount, file, md5, dpi);
         if (concurrentService.getLock(LockType.CARD_SAVE + "-" + examId).tryLock()) {
             try {
-                scanAnswerCardService.cardSave(domain);
-                AnswerCardSaveVo vo = new AnswerCardSaveVo(domain.getNumber(), System.currentTimeMillis());
+                ScanAnswerCard scanAnswerCard = scanAnswerCardService.cardSave(domain);
+                AnswerCardSaveVo vo = new AnswerCardSaveVo(scanAnswerCard.getExamId(), scanAnswerCard.getCoursePaperId(), scanAnswerCard.getMd5(), teachcloudCommonService.filePreview(scanAnswerCard.getUri()), scanAnswerCard.getNumber(), System.currentTimeMillis());
                 return ResultUtil.ok(vo);
             } finally {
                 concurrentService.getLock(LockType.CARD_SAVE + "-" + examId).unlock();

+ 36 - 19
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/bean/answercard/AnswerCardSaveVo.java

@@ -2,27 +2,44 @@ package com.qmth.teachcloud.mark.bean.answercard;
 
 public class AnswerCardSaveVo {
 
+    private Long examId;
+    private String coursePaperId;
+    private String md5;
+    private String uri;
     private Integer number;
     private Long updateTime;
-    
-    
-	public AnswerCardSaveVo(Integer number, Long updateTime) {
-		super();
-		this.number = number;
-		this.updateTime = updateTime;
-	}
-	public Integer getNumber() {
-		return number;
-	}
-	public void setNumber(Integer number) {
-		this.number = number;
-	}
-	public Long getUpdateTime() {
-		return updateTime;
-	}
-	public void setUpdateTime(Long updateTime) {
-		this.updateTime = updateTime;
-	}
+
+
+    public AnswerCardSaveVo(Integer number, Long updateTime) {
+        super();
+        this.number = number;
+        this.updateTime = updateTime;
+    }
+
+    public AnswerCardSaveVo(Long examId, String coursePaperId, String md5, String uri, Integer number, Long updateTime) {
+        this.examId = examId;
+        this.coursePaperId = coursePaperId;
+        this.md5 = md5;
+        this.uri = uri;
+        this.number = number;
+        this.updateTime = updateTime;
+    }
+
+    public Integer getNumber() {
+        return number;
+    }
+
+    public void setNumber(Integer number) {
+        this.number = number;
+    }
+
+    public Long getUpdateTime() {
+        return updateTime;
+    }
+
+    public void setUpdateTime(Long updateTime) {
+        this.updateTime = updateTime;
+    }
 
 
 }

+ 67 - 30
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/entity/ScanAnswerCard.java

@@ -1,16 +1,16 @@
 package com.qmth.teachcloud.mark.entity;
 
-import java.io.Serializable;
-
+import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
 import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
 import com.qmth.teachcloud.mark.enums.CardSource;
-
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
+import java.io.Serializable;
+
 /**
  * <p>
  * 题卡卡格式表
@@ -20,14 +20,18 @@ import io.swagger.annotations.ApiModelProperty;
  * @since 2023-09-22
  */
 @TableName("scan_answer_card")
-@ApiModel(value="ScanAnswerCard对象", description="题卡卡格式表")
+@ApiModel(value = "ScanAnswerCard对象", description = "题卡卡格式表")
 public class ScanAnswerCard implements Serializable {
 
     private static final long serialVersionUID = 1L;
 
+    @JsonSerialize(using = ToStringSerializer.class)
+    @ApiModelProperty(value = "ID")
+    @TableId(value = "id", type = IdType.INPUT)
+    private Long id;
+
     @JsonSerialize(using = ToStringSerializer.class)
     @ApiModelProperty(value = "考试ID")
-    @TableId(value = "exam_id")
     private Long examId;
 
     @ApiModelProperty(value = "试卷编号")
@@ -35,6 +39,8 @@ public class ScanAnswerCard implements Serializable {
 
     @ApiModelProperty(value = "试卷编号(交互)")
     private String coursePaperId;
+    @ApiModelProperty(value = "试卷类型")
+    private String paperType;
 
     @ApiModelProperty(value = "题卡ID")
     private Long cardId;
@@ -79,6 +85,14 @@ public class ScanAnswerCard implements Serializable {
 
     private String adapteUri;
 
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
     public Long getExamId() {
         return examId;
     }
@@ -86,6 +100,7 @@ public class ScanAnswerCard implements Serializable {
     public void setExamId(Long examId) {
         this.examId = examId;
     }
+
     public String getPaperNumber() {
         return paperNumber;
     }
@@ -93,6 +108,15 @@ public class ScanAnswerCard implements Serializable {
     public void setPaperNumber(String paperNumber) {
         this.paperNumber = paperNumber;
     }
+
+    public String getPaperType() {
+        return paperType;
+    }
+
+    public void setPaperType(String paperType) {
+        this.paperType = paperType;
+    }
+
     public String getCoursePaperId() {
         return coursePaperId;
     }
@@ -116,6 +140,7 @@ public class ScanAnswerCard implements Serializable {
     public void setNumber(Integer number) {
         this.number = number;
     }
+
     public CardSource getSource() {
         return source;
     }
@@ -123,6 +148,7 @@ public class ScanAnswerCard implements Serializable {
     public void setSource(CardSource source) {
         this.source = source;
     }
+
     public String getMd5() {
         return md5;
     }
@@ -130,6 +156,7 @@ public class ScanAnswerCard implements Serializable {
     public void setMd5(String md5) {
         this.md5 = md5;
     }
+
     public String getParameter() {
         return parameter;
     }
@@ -137,6 +164,7 @@ public class ScanAnswerCard implements Serializable {
     public void setParameter(String parameter) {
         this.parameter = parameter;
     }
+
     public String getRemark() {
         return remark;
     }
@@ -144,6 +172,7 @@ public class ScanAnswerCard implements Serializable {
     public void setRemark(String remark) {
         this.remark = remark;
     }
+
     public Long getUpdateTime() {
         return updateTime;
     }
@@ -151,6 +180,7 @@ public class ScanAnswerCard implements Serializable {
     public void setUpdateTime(Long updateTime) {
         this.updateTime = updateTime;
     }
+
     public Boolean getNeedAdapte() {
         return needAdapte;
     }
@@ -158,6 +188,7 @@ public class ScanAnswerCard implements Serializable {
     public void setNeedAdapte(Boolean needAdapte) {
         this.needAdapte = needAdapte;
     }
+
     public Integer getPaperCount() {
         return paperCount;
     }
@@ -165,6 +196,7 @@ public class ScanAnswerCard implements Serializable {
     public void setPaperCount(Integer paperCount) {
         this.paperCount = paperCount;
     }
+
     public Boolean getSinglePage() {
         return singlePage;
     }
@@ -172,6 +204,7 @@ public class ScanAnswerCard implements Serializable {
     public void setSinglePage(Boolean singlePage) {
         this.singlePage = singlePage;
     }
+
     public String getSliceConfig() {
         return sliceConfig;
     }
@@ -179,6 +212,7 @@ public class ScanAnswerCard implements Serializable {
     public void setSliceConfig(String sliceConfig) {
         this.sliceConfig = sliceConfig;
     }
+
     public Integer getDpi() {
         return dpi;
     }
@@ -186,6 +220,7 @@ public class ScanAnswerCard implements Serializable {
     public void setDpi(Integer dpi) {
         this.dpi = dpi;
     }
+
     public String getCode() {
         return code;
     }
@@ -193,6 +228,7 @@ public class ScanAnswerCard implements Serializable {
     public void setCode(String code) {
         this.code = code;
     }
+
     public String getAdapteMd5() {
         return adapteMd5;
     }
@@ -200,6 +236,7 @@ public class ScanAnswerCard implements Serializable {
     public void setAdapteMd5(String adapteMd5) {
         this.adapteMd5 = adapteMd5;
     }
+
     public String getAdapteUri() {
         return adapteUri;
     }
@@ -209,34 +246,34 @@ public class ScanAnswerCard implements Serializable {
     }
 
 
-	public String getUri() {
-		return uri;
-	}
+    public String getUri() {
+        return uri;
+    }
 
-	public void setUri(String uri) {
-		this.uri = uri;
-	}
+    public void setUri(String uri) {
+        this.uri = uri;
+    }
 
-	@Override
+    @Override
     public String toString() {
         return "ScanAnswerCard{" +
-            "examId=" + examId +
-            ", paperNumber=" + paperNumber +
-            ", coursePaperId=" + coursePaperId +
-            ", number=" + number +
-            ", source=" + source.name() +
-            ", md5=" + md5 +
-            ", parameter=" + parameter +
-            ", remark=" + remark +
-            ", updateTime=" + updateTime +
-            ", needAdapte=" + needAdapte +
-            ", paperCount=" + paperCount +
-            ", singlePage=" + singlePage +
-            ", sliceConfig=" + sliceConfig +
-            ", dpi=" + dpi +
-            ", code=" + code +
-            ", adapteMd5=" + adapteMd5 +
-            ", adapteUri=" + adapteUri +
-        "}";
+                "examId=" + examId +
+                ", paperNumber=" + paperNumber +
+                ", coursePaperId=" + coursePaperId +
+                ", number=" + number +
+                ", source=" + source.name() +
+                ", md5=" + md5 +
+                ", parameter=" + parameter +
+                ", remark=" + remark +
+                ", updateTime=" + updateTime +
+                ", needAdapte=" + needAdapte +
+                ", paperCount=" + paperCount +
+                ", singlePage=" + singlePage +
+                ", sliceConfig=" + sliceConfig +
+                ", dpi=" + dpi +
+                ", code=" + code +
+                ", adapteMd5=" + adapteMd5 +
+                ", adapteUri=" + adapteUri +
+                "}";
     }
 }

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

@@ -25,7 +25,7 @@ public interface ScanAnswerCardService extends IService<ScanAnswerCard> {
 
 	List<AnswerCardVo> cardList(Long examId, String coursePaperId);
 
-	void cardSave(AnswerCardSaveDomain domain);
+	ScanAnswerCard cardSave(AnswerCardSaveDomain domain);
 
 	Integer findMaxCardNumberByExamId(Long examId);
 

+ 2 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/ScanPaperService.java

@@ -37,4 +37,6 @@ public interface ScanPaperService extends IService<ScanPaper> {
 	PaperMigrateVo paperMigrate(SysUser user, PaperMigrateDomain domain);
 
 	boolean updateMismatch(Long id, boolean mismatch);
+
+    boolean isScanByExamIdAndPaperNumber(Long examId, String paperNumber);
 }

+ 2 - 4
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkFileServiceImpl.java

@@ -26,8 +26,7 @@ public class MarkFileServiceImpl implements MarkFileService {
     public String uploadAnswerCard(InputStream in, String md5, Long examId, String coursePaperId, Integer number) {
         String path = getAnswerCardUri(examId, coursePaperId, number);
         try {
-            path = fileStoreUtils.uploadFile(in, md5, UploadFileEnum.CARD, path);
-            return fileStoreUtils.filePreview(path);
+            return fileStoreUtils.uploadFile(in, md5, UploadFileEnum.CARD, path);
         } catch (RuntimeException e) {
             throw e;
         } catch (Exception e) {
@@ -46,8 +45,7 @@ public class MarkFileServiceImpl implements MarkFileService {
     public String uploadAdapteFile(InputStream in, String md5, Long examId, String coursePaperId, Integer number) {
         String path = getAdapteFileUri(examId, coursePaperId, number);
         try {
-            path = fileStoreUtils.uploadFile(in, md5, UploadFileEnum.ADAPT, path);
-            return fileStoreUtils.filePreview(path);
+            return fileStoreUtils.uploadFile(in, md5, UploadFileEnum.ADAPT, path);
         } catch (RuntimeException e) {
             throw e;
         } catch (Exception e) {

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

@@ -6,7 +6,9 @@ import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.qmth.boot.core.exception.ParameterException;
+import com.qmth.teachcloud.common.contant.SystemConstant;
 import com.qmth.teachcloud.common.enums.mark.MarkPaperStatus;
+import com.qmth.teachcloud.common.service.TeachcloudCommonService;
 import com.qmth.teachcloud.mark.bean.UriVo;
 import com.qmth.teachcloud.mark.bean.answercard.AnswerCardSaveDomain;
 import com.qmth.teachcloud.mark.bean.answercard.AnswerCardVo;
@@ -50,6 +52,8 @@ public class ScanAnswerCardServiceImpl extends ServiceImpl<ScanAnswerCardMapper,
 
     @Resource
     private MarkFileService markFileService;
+    @Resource
+    private TeachcloudCommonService teachcloudCommonService;
 
     @Resource
     private FileStoreUtils fileStoreUtils;
@@ -81,12 +85,13 @@ public class ScanAnswerCardServiceImpl extends ServiceImpl<ScanAnswerCardMapper,
 
     @Transactional
     @Override
-    public void cardSave(AnswerCardSaveDomain domain) {
+    public ScanAnswerCard cardSave(AnswerCardSaveDomain domain) {
         boolean singlePage = false;
         MarkPaper mp = markPaperService.getByExamIdAndCoursePaperId(domain.getExamId(), domain.getCoursePaperId());
         if (MarkPaperStatus.FINISH.equals(mp.getStatus())) {
             throw new ParameterException("阅卷已结束");
         }
+
         ScanAnswerCard card = null;
         if (domain.getNumber() != null) {
             card = findByExamAndNumber(domain.getExamId(), domain.getNumber());
@@ -95,7 +100,10 @@ public class ScanAnswerCardServiceImpl extends ServiceImpl<ScanAnswerCardMapper,
             }
         } else {
             card = new ScanAnswerCard();
+            card.setId(SystemConstant.getDbUuid());
             card.setExamId(domain.getExamId());
+            card.setPaperNumber(mp.getPaperNumber());
+            card.setPaperType(mp.getPaperType());
             card.setCoursePaperId(domain.getCoursePaperId());
             card.setPaperCount(domain.getPaperCount());
             card.setSinglePage(singlePage);
@@ -105,6 +113,7 @@ public class ScanAnswerCardServiceImpl extends ServiceImpl<ScanAnswerCardMapper,
             card.setNumber(findMaxCardNumberByExamId(domain.getExamId()) + 1);
             card.setNeedAdapte(false);
         }
+
         CardFile cardFile;
         byte[] fileData;
         String sliceConfig;
@@ -125,7 +134,7 @@ public class ScanAnswerCardServiceImpl extends ServiceImpl<ScanAnswerCardMapper,
         }
         String filePath = null;
         try {
-            markFileService.uploadAnswerCard(domain.getFile().getInputStream(), domain.getMd5(), domain.getExamId(), domain.getCoursePaperId(), domain.getNumber());
+            filePath = markFileService.uploadAnswerCard(domain.getFile().getInputStream(), domain.getMd5(), domain.getExamId(), domain.getCoursePaperId(), card.getNumber());
         } catch (IOException e) {
             throw new ParameterException("文件上传失败", e);
         }
@@ -133,6 +142,7 @@ public class ScanAnswerCardServiceImpl extends ServiceImpl<ScanAnswerCardMapper,
         card.setMd5(domain.getMd5());
         card.setUri(filePath);
         this.saveOrUpdate(card);
+        return card;
     }
 
     /**
@@ -196,14 +206,15 @@ public class ScanAnswerCardServiceImpl extends ServiceImpl<ScanAnswerCardMapper,
         }
         String filePath = null;
         try {
-            markFileService.uploadAdapteFile(file.getInputStream(), md5, examId, coursePaperId, cardNumber);
+            filePath = markFileService.uploadAdapteFile(file.getInputStream(), md5, examId, coursePaperId, cardNumber);
         } catch (IOException e) {
             throw new ParameterException("文件上传失败", e);
         }
         card.setAdapteMd5(md5);
         card.setAdapteUri(filePath);
+        this.updateById(card);
         UriVo vo = new UriVo();
-        vo.setUri(filePath);
+        vo.setUri(teachcloudCommonService.filePreview(filePath));
         return vo;
     }
 

+ 213 - 211
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/ScanPaperServiceImpl.java

@@ -1,16 +1,5 @@
 package com.qmth.teachcloud.mark.service.impl;
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.stream.Collectors;
-
-import javax.validation.constraints.NotNull;
-
-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;
@@ -25,19 +14,19 @@ import com.qmth.teachcloud.mark.bean.papermigrate.PaperMigrateVo;
 import com.qmth.teachcloud.mark.bean.scananswer.StudentPaperVo;
 import com.qmth.teachcloud.mark.bean.scanpaper.PaperVo;
 import com.qmth.teachcloud.mark.dto.mark.score.StudentPaperDetailDto;
-import com.qmth.teachcloud.mark.entity.MarkStudent;
-import com.qmth.teachcloud.mark.entity.ScanAnswerCard;
-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.entity.*;
 import com.qmth.teachcloud.mark.enums.LockType;
 import com.qmth.teachcloud.mark.mapper.ScanPaperMapper;
-import com.qmth.teachcloud.mark.service.MarkStudentService;
-import com.qmth.teachcloud.mark.service.ScanAnswerCardService;
-import com.qmth.teachcloud.mark.service.ScanAnswerCardSubjectService;
-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.validation.constraints.NotNull;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
 
 /**
  * <p>
@@ -49,205 +38,206 @@ import com.qmth.teachcloud.mark.service.ScanStudentPaperService;
  */
 @Service
 public class ScanPaperServiceImpl extends ServiceImpl<ScanPaperMapper, ScanPaper> implements ScanPaperService {
-	@Autowired
-	private ScanAnswerCardService answerCardService;
-	@Autowired
-	private ScanPaperPageService paperPageService;
-	@Autowired
-	private MarkStudentService markStudentService;
-	@Autowired
-	private ConcurrentService concurrentService;
-	@Autowired
-	private ScanStudentPaperService scanStudentPaperService;
-	@Autowired
-	private ScanAnswerCardSubjectService scanAnswerCardSubjectService;
+    @Autowired
+    private ScanAnswerCardService answerCardService;
+    @Autowired
+    private ScanPaperPageService paperPageService;
+    @Autowired
+    private MarkStudentService markStudentService;
+    @Autowired
+    private ConcurrentService concurrentService;
+    @Autowired
+    private ScanStudentPaperService scanStudentPaperService;
+    @Autowired
+    private ScanAnswerCardSubjectService scanAnswerCardSubjectService;
 
-	/**
-	 * 全量更新paper和所属的page集合,并刷新paper相关属性
-	 *
-	 * @param paper
-	 * @param pages
-	 */
-	@Override
-	@Transactional
-	public void savePaperAndPages(@NotNull ScanPaper paper, @NotNull List<ScanPaperPage> pages) {
-		// 与卡格式校验
-		ScanAnswerCard answerCard = answerCardService.findByExamAndNumber(paper.getExamId(), paper.getCardNumber());
-		if (answerCard == null) {
-			throw ExceptionResultEnum.ERROR.exception("卡格式不存在, cardNumber=" + paper.getCardNumber());
-		}
-		if (pages.size() != (answerCard.getSinglePage() ? 1 : 2)) {
-			throw ExceptionResultEnum.ERROR.exception("paper.page数量与卡格式不符, cardNumber=" + paper.getCardNumber());
-		}
-		// 更新paper属性
-		paper.setPageCount(pages.size());
-		paper.setQuestionFilled(false);
-		// 判断是否客观题已填涂
-		for (ScanPaperPage page : pages) {
-			paper.setQuestionFilled(paper.getQuestionFilled() || page.isQuestionFilled());
-		}
-		// 保存paper数据
-		saveOrUpdate(paper);
-		for (ScanPaperPage page : pages) {
-			// FIXME
-			// 验证原图与裁切图已上传
+    /**
+     * 全量更新paper和所属的page集合,并刷新paper相关属性
+     *
+     * @param paper
+     * @param pages
+     */
+    @Override
+    @Transactional
+    public void savePaperAndPages(@NotNull ScanPaper paper, @NotNull List<ScanPaperPage> pages) {
+        // 与卡格式校验
+        ScanAnswerCard answerCard = answerCardService.findByExamAndNumber(paper.getExamId(), paper.getCardNumber());
+        if (answerCard == null) {
+            throw ExceptionResultEnum.ERROR.exception("卡格式不存在, cardNumber=" + paper.getCardNumber());
+        }
+        if (pages.size() != (answerCard.getSinglePage() ? 1 : 2)) {
+            throw ExceptionResultEnum.ERROR.exception("paper.page数量与卡格式不符, cardNumber=" + paper.getCardNumber());
+        }
+        // 更新paper属性
+        paper.setPageCount(pages.size());
+        paper.setQuestionFilled(false);
+        // 判断是否客观题已填涂
+        for (ScanPaperPage page : pages) {
+            paper.setQuestionFilled(paper.getQuestionFilled() || page.isQuestionFilled());
+        }
+        // 保存paper数据
+        saveOrUpdate(paper);
+        for (ScanPaperPage page : pages) {
+            // FIXME
+            // 验证原图与裁切图已上传
 //            if (!fileStore.exist(page.getSheetPath())) {
 //            	throw ExceptionResultEnum.ERROR.exception("原图不存在:" + page.getSheetPath());
 //            }
-			page.setPaperId(paper.getId());
-		}
-		// 保存page数据
-		paperPageService.saveOrUpdateBatch(pages);
-	}
+            page.setPaperId(paper.getId());
+        }
+        // 保存page数据
+        paperPageService.saveOrUpdateBatch(pages);
+    }
+
+    @Override
+    public int getAssignedCount(Long examId, Boolean checked) {
+        QueryWrapper<ScanPaper> wrapper = new QueryWrapper<>();
+        LambdaQueryWrapper<ScanPaper> lw = wrapper.lambda();
+        lw.eq(ScanPaper::getExamId, examId);
+        lw.eq(ScanPaper::getAssigned, true);
+        if (checked != null) {
+            lw.eq(ScanPaper::getAssignConfirmed, checked);
+        }
+        return baseMapper.selectCount(wrapper);
+    }
 
-	@Override
-	public int getAssignedCount(Long examId, Boolean checked) {
-		QueryWrapper<ScanPaper> wrapper = new QueryWrapper<>();
-		LambdaQueryWrapper<ScanPaper> lw = wrapper.lambda();
-		lw.eq(ScanPaper::getExamId, examId);
-		lw.eq(ScanPaper::getAssigned, true);
-		if (checked != null) {
-			lw.eq(ScanPaper::getAssignConfirmed, checked);
-		}
-		return baseMapper.selectCount(wrapper);
-	}
+    @Override
+    public List<StudentPaperDetailDto> listStudentPaperDetail(Long studentId) {
+        return this.baseMapper.listStudentPaperDetail(studentId);
+    }
 
-	@Override
-	public List<StudentPaperDetailDto> listStudentPaperDetail(Long studentId) {
-		return this.baseMapper.listStudentPaperDetail(studentId);
-	}
+    @Override
+    public int getCountByExamAndCardNumber(Long examId, Integer number) {
+        LambdaQueryWrapper<ScanPaper> lw = new LambdaQueryWrapper<>();
+        lw.eq(ScanPaper::getExamId, examId);
+        lw.eq(ScanPaper::getCardNumber, number);
+        return this.count(lw);
+    }
 
-	@Override
-	public int getCountByExamAndCardNumber(Long examId, Integer number) {
-		LambdaQueryWrapper<ScanPaper> lw = new LambdaQueryWrapper<>();
-		lw.eq(ScanPaper::getExamId, examId);
-		lw.eq(ScanPaper::getCardNumber, number);
-		return this.count(lw);
-	}
+    @Override
+    public List<PaperVo> findStudentPaper(Long studentId) {
+        return baseMapper.findStudentPaper(studentId);
+    }
 
-	@Override
-	public List<PaperVo> findStudentPaper(Long studentId) {
-		return baseMapper.findStudentPaper(studentId);
-	}
+    @Override
+    public List<StudentPaperVo> listByStudentIds(List<Long> paramList) {
+        return baseMapper.listByStudentIds(paramList);
+    }
 
-	@Override
-	public List<StudentPaperVo> listByStudentIds(List<Long> paramList) {
-		return baseMapper.listByStudentIds(paramList);
-	}
+    @Transactional
+    @Override
+    public PaperMigrateVo paperMigrate(SysUser user, PaperMigrateDomain domain) {
+        // 查找修改paper
+        ScanPaper paper = getById(domain.getPaperId());
+        if (paper == null) {
+            throw new ParameterException("题卡信息未找到, paperId=" + domain.getPaperId());
+        }
+        // 查找目标考生
+        MarkStudent student = markStudentService.findByExamIdAndCoursePaperIdAndStudentCode(domain.getExamId(),
+                domain.getCoursePaperId(), domain.getStudentCode());
+        if (student == null) {
+            throw new ParameterException("考生信息未找到");
+        }
+        // 目标考生已扫描时,输入卡格式需要保持一致
+        if (student.getCardNumber() != null && !student.getCardNumber().equals(domain.getCardNumber())) {
+            throw new ParameterException("卡格式与目标考生不一致");
+        }
+        // 校验卡格式
+        ScanAnswerCard answerCard = answerCardService.findByExamAndNumber(domain.getExamId(), domain.getCardNumber());
+        if (answerCard == null) {
+            throw new ParameterException("卡格式信息未找到");
+        }
+        // 验证卡格式所属科目
+        boolean allowSubject = scanAnswerCardSubjectService.checkSubject(answerCard.getExamId(), answerCard.getNumber(),
+                student.getCoursePaperId());
+        if (!allowSubject) {
+            throw new ParameterException("卡格式与考生科目不一致");
+        }
+        // cardNumber或paperNumber有变化,都需要重新识别
+        if ((!paper.getNumber().equals(domain.getPaperNumber())
+                || !paper.getCardNumber().equals(domain.getCardNumber()))
+                && CollectionUtils.isEmpty(domain.getPages())) {
+            throw new ParameterException("卡格式有变化需要重新识别, pages信息不能为空");
+        }
+        // 指定paper现有绑定考生
+        MarkStudent previousStudent = null;
+        ScanStudentPaper previousStudentPaper = scanStudentPaperService.findByPaperId(domain.getPaperId());
+        if (previousStudentPaper != null) {
+            // 考生没变,张数也没变
+            if (previousStudentPaper.getStudentId().equals(student.getId())
+                    && previousStudentPaper.getPaperIndex().equals(domain.getPaperNumber())) {
+                throw new ParameterException("该题卡已绑定该考生");
+            }
+            // 考生ID变了才需要获取原考生
+            if (!previousStudentPaper.getStudentId().equals(student.getId())) {
+                previousStudent = markStudentService.getById(previousStudentPaper.getStudentId());
+            }
+        }
+        if (previousStudent != null) {
+            concurrentService.getReadWriteLock(LockType.STUDENT + "-" + previousStudent.getId()).writeLock().lock();
+        }
+        concurrentService.getReadWriteLock(LockType.STUDENT + "-" + student.getId()).writeLock().lock();
+        try {
+            if (previousStudentPaper != null) {
+                // 解绑paper和原有考生
+                if (previousStudent != null) {
+                    List<ScanStudentPaper> studentPaperList = scanStudentPaperService
+                            .findByStudentId(previousStudent.getId()).stream()
+                            .filter(entity -> !entity.getPaperId().equals(previousStudentPaper.getPaperId()))
+                            .collect(Collectors.toList());
+                    markStudentService.updateStudentAndPaper(user, previousStudent.getId(), studentPaperList);
+                }
+                // 考生没变,直接解绑paper
+                else {
+                    scanStudentPaperService.removeByStudentIdAndPaperId(previousStudentPaper.getStudentId(),
+                            previousStudentPaper.getPaperId());
+                }
+            }
+            // 更新paper属性
+            paper.setCardNumber(domain.getCardNumber());
+            paper.setNumber(domain.getPaperNumber());
+            // 修改的paper强制置为人工绑定
+            paper.setAssigned(true);
+            // 原有mismatch标记需要清除
+            paper.setMismatch(false);
+            paper.setUpdaterId(user.getId());
+            paper.setUpdateTime(System.currentTimeMillis());
+            if (CollectionUtils.isNotEmpty(domain.getPages())) {
+                // 重新识别时更新所有page
+                List<ScanPaperPage> pages = new ArrayList<>();
+                for (PaperMigratePage page : domain.getPages()) {
+                    pages.add(page.update(paperPageService.findPaperIdAndIndex(paper.getId(), page.getIndex())));
+                }
+                savePaperAndPages(paper, pages);
+            } else {
+                saveOrUpdate(paper);
+            }
+            // 查找目标考生现有绑定paper
+            boolean exist = false;
+            List<ScanStudentPaper> currentStudentPaperList = scanStudentPaperService.findByStudentId(student.getId());
+            for (ScanStudentPaper current : currentStudentPaperList) {
+                if (current.getPaperIndex().equals(paper.getNumber())) {
+                    exist = true;
+                    updateMismatch(current.getPaperId(), true);
+                    current.setPaperId(paper.getId());
+                }
+            }
+            if (!exist) {
+                currentStudentPaperList.add(new ScanStudentPaper(student.getId(), paper.getNumber(), paper.getId()));
+            }
+            // 更新目标考生状态
+            markStudentService.updateStudentAndPaper(user, student.getId(), currentStudentPaperList);
+            // 返回数据结果
+            return PaperMigrateVo.create(domain.getPaperId());
+        } finally {
+            concurrentService.getReadWriteLock(LockType.STUDENT + "-" + student.getId()).writeLock().unlock();
+            if (previousStudent != null) {
+                concurrentService.getReadWriteLock(LockType.STUDENT + "-" + previousStudent.getId()).writeLock()
+                        .unlock();
+            }
+        }
+    }
 
-	@Transactional
-	@Override
-	public PaperMigrateVo paperMigrate(SysUser user, PaperMigrateDomain domain) {
-		// 查找修改paper
-		ScanPaper paper = getById(domain.getPaperId());
-		if (paper == null) {
-			throw new ParameterException("题卡信息未找到, paperId=" + domain.getPaperId());
-		}
-		// 查找目标考生
-		MarkStudent student = markStudentService.findByExamIdAndCoursePaperIdAndStudentCode(domain.getExamId(),
-				domain.getCoursePaperId(), domain.getStudentCode());
-		if (student == null) {
-			throw new ParameterException("考生信息未找到");
-		}
-		// 目标考生已扫描时,输入卡格式需要保持一致
-		if (student.getCardNumber() != null && !student.getCardNumber().equals(domain.getCardNumber())) {
-			throw new ParameterException("卡格式与目标考生不一致");
-		}
-		// 校验卡格式
-		ScanAnswerCard answerCard = answerCardService.findByExamAndNumber(domain.getExamId(), domain.getCardNumber());
-		if (answerCard == null) {
-			throw new ParameterException("卡格式信息未找到");
-		}
-		// 验证卡格式所属科目
-		boolean allowSubject = scanAnswerCardSubjectService.checkSubject(answerCard.getExamId(), answerCard.getNumber(),
-				student.getCoursePaperId());
-		if (!allowSubject) {
-			throw new ParameterException("卡格式与考生科目不一致");
-		}
-		// cardNumber或paperNumber有变化,都需要重新识别
-		if ((!paper.getNumber().equals(domain.getPaperNumber())
-				|| !paper.getCardNumber().equals(domain.getCardNumber()))
-				&& CollectionUtils.isEmpty(domain.getPages())) {
-			throw new ParameterException("卡格式有变化需要重新识别, pages信息不能为空");
-		}
-		// 指定paper现有绑定考生
-		MarkStudent previousStudent = null;
-		ScanStudentPaper previousStudentPaper = scanStudentPaperService.findByPaperId(domain.getPaperId());
-		if (previousStudentPaper != null) {
-			// 考生没变,张数也没变
-			if (previousStudentPaper.getStudentId().equals(student.getId())
-					&& previousStudentPaper.getPaperIndex().equals(domain.getPaperNumber())) {
-				throw new ParameterException("该题卡已绑定该考生");
-			}
-			// 考生ID变了才需要获取原考生
-			if (!previousStudentPaper.getStudentId().equals(student.getId())) {
-				previousStudent = markStudentService.getById(previousStudentPaper.getStudentId());
-			}
-		}
-		if (previousStudent != null) {
-			concurrentService.getReadWriteLock(LockType.STUDENT + "-" + previousStudent.getId()).writeLock().lock();
-		}
-		concurrentService.getReadWriteLock(LockType.STUDENT + "-" + student.getId()).writeLock().lock();
-		try {
-			if (previousStudentPaper != null) {
-				// 解绑paper和原有考生
-				if (previousStudent != null) {
-					List<ScanStudentPaper> studentPaperList = scanStudentPaperService
-							.findByStudentId(previousStudent.getId()).stream()
-							.filter(entity -> !entity.getPaperId().equals(previousStudentPaper.getPaperId()))
-							.collect(Collectors.toList());
-					markStudentService.updateStudentAndPaper(user, previousStudent.getId(), studentPaperList);
-				}
-				// 考生没变,直接解绑paper
-				else {
-					scanStudentPaperService.removeByStudentIdAndPaperId(previousStudentPaper.getStudentId(),
-							previousStudentPaper.getPaperId());
-				}
-			}
-			// 更新paper属性
-			paper.setCardNumber(domain.getCardNumber());
-			paper.setNumber(domain.getPaperNumber());
-			// 修改的paper强制置为人工绑定
-			paper.setAssigned(true);
-			// 原有mismatch标记需要清除
-			paper.setMismatch(false);
-			paper.setUpdaterId(user.getId());
-			paper.setUpdateTime(System.currentTimeMillis());
-			if (CollectionUtils.isNotEmpty(domain.getPages())) {
-				// 重新识别时更新所有page
-				List<ScanPaperPage> pages = new ArrayList<>();
-				for (PaperMigratePage page : domain.getPages()) {
-					pages.add(page.update(paperPageService.findPaperIdAndIndex(paper.getId(), page.getIndex())));
-				}
-				savePaperAndPages(paper, pages);
-			} else {
-				saveOrUpdate(paper);
-			}
-			// 查找目标考生现有绑定paper
-			boolean exist = false;
-			List<ScanStudentPaper> currentStudentPaperList = scanStudentPaperService.findByStudentId(student.getId());
-			for (ScanStudentPaper current : currentStudentPaperList) {
-				if (current.getPaperIndex().equals(paper.getNumber())) {
-					exist = true;
-					updateMismatch(current.getPaperId(), true);
-					current.setPaperId(paper.getId());
-				}
-			}
-			if (!exist) {
-				currentStudentPaperList.add(new ScanStudentPaper(student.getId(), paper.getNumber(), paper.getId()));
-			}
-			// 更新目标考生状态
-			markStudentService.updateStudentAndPaper(user, student.getId(), currentStudentPaperList);
-			// 返回数据结果
-			return PaperMigrateVo.create(domain.getPaperId());
-		} finally {
-			concurrentService.getReadWriteLock(LockType.STUDENT + "-" + student.getId()).writeLock().unlock();
-			if (previousStudent != null) {
-				concurrentService.getReadWriteLock(LockType.STUDENT + "-" + previousStudent.getId()).writeLock()
-						.unlock();
-			}
-		}
-	}
     @Override
     @Transactional
     public boolean updateMismatch(Long id, boolean mismatch) {
@@ -256,4 +246,16 @@ public class ScanPaperServiceImpl extends ServiceImpl<ScanPaperMapper, ScanPaper
         lw.eq(ScanPaper::getId, id);
         return this.update(lw);
     }
+
+    @Override
+    public boolean isScanByExamIdAndPaperNumber(Long examId, String paperNumber) {
+        List<ScanAnswerCard> scanAnswerCardList = answerCardService.listByExamIdAndPaperNumber(examId, paperNumber);
+        for (ScanAnswerCard scanAnswerCard : scanAnswerCardList) {
+            int countByExamAndCardNumber = this.getCountByExamAndCardNumber(examId, scanAnswerCard.getNumber());
+            if (countByExamAndCardNumber > 0) {
+                return true;
+            }
+        }
+        return false;
+    }
 }

+ 3 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/utils/FileStoreUtils.java

@@ -299,6 +299,9 @@ public class FileStoreUtils {
     }
 
     public String filePreview(String path) {
+        if (StringUtils.isBlank(path)) {
+            return null;
+        }
         String url = null;
         FilePathVo filePathVo = JSON.parseObject(path, FilePathVo.class);
         String type = filePathVo.getType();

+ 1 - 1
teachcloud-task/src/main/java/com/qmth/teachcloud/task/service/PrintFinishService.java

@@ -16,5 +16,5 @@ public interface PrintFinishService {
 
     void insertScanAnswerCard(ExamDetailCourseInitMarkDto dto, PaperInfoVo paperInfoVo, String content);
 
-    void insertMarkQuestion(Long examId, String paperNumber, String content);
+    void insertMarkQuestion(Long examId, String paperNumber, String paperType, String content);
 }

+ 14 - 28
teachcloud-task/src/main/java/com/qmth/teachcloud/task/service/impl/PrintFinishServiceImpl.java

@@ -138,7 +138,7 @@ public class PrintFinishServiceImpl implements PrintFinishService {
                         continue;
                     }
                     // 解析卡格式中试卷结构并保存
-                    this.insertMarkQuestion(dto.getExamId(), dto.getPaperNumber(), examCard.getContent());
+                    this.insertMarkQuestion(dto.getExamId(), dto.getPaperNumber(), dto.getPaperType(), examCard.getContent());
                     // 生成并保存卡格式文件(后缀为.json)
                     this.insertScanAnswerCard(dto, paperInfoVo, examCard.getContent());
                 }
@@ -169,9 +169,11 @@ public class PrintFinishServiceImpl implements PrintFinishService {
                     String uploadPath = fileStoreUtils.uploadFile(inputStream, md5, UploadFileEnum.CARD, path);
 
                     scanAnswerCard = new ScanAnswerCard();
+                    scanAnswerCard.setId(SystemConstant.getDbUuid());
                     scanAnswerCard.setExamId(dto.getExamId());
                     scanAnswerCard.setPaperNumber(dto.getPaperNumber());
                     scanAnswerCard.setCoursePaperId(dto.getCoursePaperId());
+                    scanAnswerCard.setPaperType(dto.getPaperType());
                     scanAnswerCard.setCardId(paperInfoVo.getCardId());
                     scanAnswerCard.setNumber(number);
                     scanAnswerCard.setSource(CardSource.WEB);
@@ -204,13 +206,14 @@ public class PrintFinishServiceImpl implements PrintFinishService {
     }
 
     @Override
-    public void insertMarkQuestion(Long examId, String paperNumber, String content) {
+    public void insertMarkQuestion(Long examId, String paperNumber, String paperType, String content) {
         try {
             List<Struct> structList = CardParseUtils.parseCardContent(content);
             if (CollectionUtils.isEmpty(structList)) {
                 return;
             }
             List<MarkQuestion> markQuestionList = markQuestionService.listQuestionByExamIdAndPaperNumber(examId, paperNumber);
+            // 第一次新增
             if (CollectionUtils.isEmpty(markQuestionList)) {
                 List<MarkQuestion> markQuestions = new ArrayList<>();
                 for (Struct struct : structList) {
@@ -218,6 +221,7 @@ public class PrintFinishServiceImpl implements PrintFinishService {
                     markQuestion.setId(SystemConstant.getDbUuid());
                     markQuestion.setExamId(examId);
                     markQuestion.setPaperNumber(paperNumber);
+                    markQuestion.setPaperType(paperType);
                     markQuestion.setObjective(struct.getObjective());
                     markQuestion.setMainNumber(struct.getMainNumber());
                     markQuestion.setSubNumber(struct.getSubNumber());
@@ -230,33 +234,15 @@ public class PrintFinishServiceImpl implements PrintFinishService {
                 }
                 markQuestionService.saveBatch(markQuestions);
             } else {
-
                 List<ScanAnswerCard> scanAnswerCardList = scanAnswerCardService.listByExamIdAndPaperNumber(examId, paperNumber);
-                if (CollectionUtils.isNotEmpty(scanAnswerCardList)) {
-                    for (ScanAnswerCard scanAnswerCard : scanAnswerCardList) {
-                        int count = scanPaperService.getCountByExamAndCardNumber(examId, scanAnswerCard.getNumber());
-                        if (count > 0) return;
-                    }
-                }
-
-                // todo 题卡变动后,结构数据处理逻辑
-                if (structList.size() == markQuestionList.size()) {
-                    for (int i = 0; i < structList.size(); i++) {
-                        Struct struct = structList.get(i);
-                        MarkQuestion markQuestion = markQuestionList.get(i);
-                        if (markQuestion.getGroupNumber() != null) {
-                            if (struct.getMainNumber() == markQuestion.getMainNumber()
-                                    && struct.getSubNumber() == markQuestion.getSubNumber()
-                                    && struct.getObjective().equals(markQuestion.getObjective())
-                                    && struct.getType() == markQuestion.getQuestionType()
-                                    && struct.getMainTitle().equals(markQuestion.getMainTitle())) {
-                                continue;
-                            }
-                        }
-                    }
-                } else {
-
-                }
+//                if (CollectionUtils.isNotEmpty(scanAnswerCardList)) {
+//                    for (ScanAnswerCard scanAnswerCard : scanAnswerCardList) {
+//                        int count = scanPaperService.getCountByExamAndCardNumber(examId, scanAnswerCard.getNumber());
+//                        if (count > 0) {
+//                            return;
+//                        }
+//                    }
+//                }
             }
         } catch (Exception e) {
             log.info("同步结构失败");