xiaofei 1 gadu atpakaļ
vecāks
revīzija
e773b16280

+ 0 - 11
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/entity/ScanBatch.java

@@ -38,9 +38,6 @@ public class ScanBatch implements Serializable {
     @ApiModelProperty(value = "扫描员ID")
     private Long userId;
 
-    @ApiModelProperty(value = "卷袋号")
-    private String packageCode;
-
     @ApiModelProperty(value = "扫描数量")
     private Integer scanCount;
 
@@ -83,13 +80,6 @@ public class ScanBatch implements Serializable {
     public void setUserId(Long userId) {
         this.userId = userId;
     }
-    public String getPackageCode() {
-        return packageCode;
-    }
-
-    public void setPackageCode(String packageCode) {
-        this.packageCode = packageCode;
-    }
     public Integer getScanCount() {
         return scanCount;
     }
@@ -153,7 +143,6 @@ public class ScanBatch implements Serializable {
             "id=" + id +
             ", examId=" + examId +
             ", userId=" + userId +
-            ", packageCode=" + packageCode +
             ", scanCount=" + scanCount +
             ", assignedCount=" + assignedCount +
             ", status=" + status +

+ 13 - 1
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/entity/ScanBatchPaper.java

@@ -23,9 +23,13 @@ import io.swagger.annotations.ApiModelProperty;
 public class ScanBatchPaper 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 = "batch_id", type = IdType.AUTO)
     private Long batchId;
 
     @JsonSerialize(using = ToStringSerializer.class)
@@ -44,6 +48,14 @@ public class ScanBatchPaper implements Serializable {
 
     private Boolean assigned;
 
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
     public Long getBatchId() {
         return batchId;
     }

+ 11 - 2
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/entity/ScanPaperPage.java

@@ -28,9 +28,10 @@ import io.swagger.annotations.ApiModel;
 public class ScanPaperPage implements Serializable {
 
 	private static final long serialVersionUID = 1L;
-
 	@JsonSerialize(using = ToStringSerializer.class)
-	@TableId(value = "paper_id")
+	@TableId(value = "id")
+	private Long id;
+	@JsonSerialize(using = ToStringSerializer.class)
 	private Long paperId;
 	private Integer pageIndex;
 
@@ -60,6 +61,14 @@ public class ScanPaperPage implements Serializable {
 
 	private Long updateTime;
 
+	public Long getId() {
+		return id;
+	}
+
+	public void setId(Long id) {
+		this.id = id;
+	}
+
 	public Long getPaperId() {
 		return paperId;
 	}

+ 38 - 22
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/entity/ScanStudentPaper.java

@@ -7,24 +7,28 @@ 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.common.contant.SystemConstant;
 import io.swagger.annotations.ApiModel;
 
 /**
  * <p>
- * 
+ *
  * </p>
  *
  * @author xf
  * @since 2023-09-22
  */
 @TableName("scan_student_paper")
-@ApiModel(value="ScanStudentPaper对象", description="")
+@ApiModel(value = "ScanStudentPaper对象", description = "")
 public class ScanStudentPaper implements Serializable {
 
     private static final long serialVersionUID = 1L;
 
     @JsonSerialize(using = ToStringSerializer.class)
-    @TableId(value = "student_id")
+    @TableId(value = "id")
+    private Long id;
+
+    @JsonSerialize(using = ToStringSerializer.class)
     private Long studentId;
 
     private Integer paperIndex;
@@ -36,29 +40,38 @@ public class ScanStudentPaper implements Serializable {
 
     private Long updateTime;
 
-    
-    
+
     public ScanStudentPaper(Long studentId, Integer paperIndex, Long paperId) {
-		super();
-		this.studentId = studentId;
-		this.paperIndex = paperIndex;
-		this.paperId = paperId;
-	}
+        super();
+        this.id = SystemConstant.getDbUuid();
+        this.studentId = studentId;
+        this.paperIndex = paperIndex;
+        this.paperId = paperId;
+    }
+
+
+    public ScanStudentPaper() {
+        super();
+        // TODO Auto-generated constructor stub
+    }
 
 
-	public ScanStudentPaper() {
-		super();
-		// TODO Auto-generated constructor stub
-	}
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
 
-    
-	public Long getStudentId() {
+    public Long getStudentId() {
         return studentId;
     }
 
     public void setStudentId(Long studentId) {
         this.studentId = studentId;
     }
+
     public Integer getPaperIndex() {
         return paperIndex;
     }
@@ -66,6 +79,7 @@ public class ScanStudentPaper implements Serializable {
     public void setPaperIndex(Integer paperIndex) {
         this.paperIndex = paperIndex;
     }
+
     public Long getPaperId() {
         return paperId;
     }
@@ -73,6 +87,7 @@ public class ScanStudentPaper implements Serializable {
     public void setPaperId(Long paperId) {
         this.paperId = paperId;
     }
+
     public Long getCreateTime() {
         return createTime;
     }
@@ -80,6 +95,7 @@ public class ScanStudentPaper implements Serializable {
     public void setCreateTime(Long createTime) {
         this.createTime = createTime;
     }
+
     public Long getUpdateTime() {
         return updateTime;
     }
@@ -91,11 +107,11 @@ public class ScanStudentPaper implements Serializable {
     @Override
     public String toString() {
         return "ScanStudentPaper{" +
-            "studentId=" + studentId +
-            ", paperIndex=" + paperIndex +
-            ", paperId=" + paperId +
-            ", createTime=" + createTime +
-            ", updateTime=" + updateTime +
-        "}";
+                "studentId=" + studentId +
+                ", paperIndex=" + paperIndex +
+                ", paperId=" + paperId +
+                ", createTime=" + createTime +
+                ", updateTime=" + updateTime +
+                "}";
     }
 }

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

@@ -1,5 +1,6 @@
 package com.qmth.teachcloud.mark.service.impl;
 
+import com.qmth.teachcloud.common.contant.SystemConstant;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -37,6 +38,7 @@ public class ScanBatchPaperServiceImpl extends ServiceImpl<ScanBatchPaperMapper,
     @Transactional
     public void update(ScanBatch batch, ScanPaper paper, Long studentId, Integer paperNumber) {
     	ScanBatchPaper batchPaperEntity = new ScanBatchPaper();
+        batchPaperEntity.setId(SystemConstant.getDbUuid());
         batchPaperEntity.setBatchId(batch.getId());
         batchPaperEntity.setStudentId(studentId);
         batchPaperEntity.setPaperIndex(paperNumber);

+ 220 - 249
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/ScanBatchServiceImpl.java

@@ -1,50 +1,27 @@
 package com.qmth.teachcloud.mark.service.impl;
 
-import java.util.ArrayList;
-import java.util.List;
-
-import com.qmth.teachcloud.common.service.TeachcloudCommonService;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-import org.springframework.web.multipart.MultipartFile;
-
 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.entity.SysUser;
-import com.qmth.teachcloud.mark.bean.answerbatch.AnswerDomain;
-import com.qmth.teachcloud.mark.bean.answerbatch.AnswerPaper;
-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.bean.answerbatch.Paper;
-import com.qmth.teachcloud.mark.bean.answerbatch.Rescan;
+import com.qmth.teachcloud.common.service.TeachcloudCommonService;
+import com.qmth.teachcloud.mark.bean.answerbatch.*;
 import com.qmth.teachcloud.mark.bean.scananswer.SheetUploadVo;
 import com.qmth.teachcloud.mark.bean.scanpaper.PaperVo;
-import com.qmth.teachcloud.mark.entity.MarkStudent;
-import com.qmth.teachcloud.mark.entity.ScanAnswerCard;
-import com.qmth.teachcloud.mark.entity.ScanBatch;
-import com.qmth.teachcloud.mark.entity.ScanBatchPaper;
-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.BatchStatus;
 import com.qmth.teachcloud.mark.enums.LockType;
 import com.qmth.teachcloud.mark.mapper.ScanBatchMapper;
-import com.qmth.teachcloud.mark.service.MarkFileService;
-import com.qmth.teachcloud.mark.service.MarkStudentService;
-import com.qmth.teachcloud.mark.service.ScanAnswerCardService;
-import com.qmth.teachcloud.mark.service.ScanBatchPaperService;
-import com.qmth.teachcloud.mark.service.ScanBatchService;
-import com.qmth.teachcloud.mark.service.ScanFilePropertyService;
-import com.qmth.teachcloud.mark.service.ScanPaperPageService;
-import com.qmth.teachcloud.mark.service.ScanPaperService;
+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 org.springframework.web.multipart.MultipartFile;
 
 import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * <p>
@@ -56,219 +33,213 @@ import javax.annotation.Resource;
  */
 @Service
 public class ScanBatchServiceImpl extends ServiceImpl<ScanBatchMapper, ScanBatch> implements ScanBatchService {
-	@Autowired
-	private MarkFileService markFileService;
-	@Autowired
-	private ConcurrentService concurrentService;
-	@Autowired
-	private MarkStudentService markStudentService;
-
-	@Autowired
-	private ScanPaperService scanPaperService;
-
-	@Autowired
-	private ScanPaperPageService scanPaperPageService;
-
-	@Autowired
-	private ScanBatchPaperService scanBatchPaperService;
-
-	@Autowired
-	private ScanAnswerCardService scanAnswerCardService;
-	@Autowired
-	private ScanFilePropertyService scanFilePropertyService;
-	@Resource
-	private TeachcloudCommonService teachcloudCommonService;
-	
-	@Transactional
-	@Override
-	public BatchCreateVo batchCreate(BatchCreateDomain domain, SysUser sysUser) {
-		List<Rescan> rescan = new ArrayList<>();
-		String packageCode = null;
-		for (String studentCode : domain.getStudentCodes()) {
-			MarkStudent student = markStudentService.findByExamIdAndCoursePaperIdAndStudentCode(domain.getExamId(),
-					domain.getCoursePaperId(), studentCode);
-			if (student == null) {
-				throw new ParameterException("未找到考生信息:" + studentCode);
-			}
-			Rescan rc = getRescan(student);
-			if (rc != null) {
-				rescan.add(rc);
-			}
-		}
-
-		ScanBatch b = new ScanBatch();
-		b.setExamId(domain.getExamId());
-		b.setUserId(sysUser.getId());
-		b.setPackageCode(packageCode);
-		b.setCoursePaperId(domain.getCoursePaperId());
-		b.setAssignedCount(0);
-		b.setScanCount(0);
-		b.setStatus(BatchStatus.INIT);
-		this.save(b);
-
-		BatchCreateVo vo = new BatchCreateVo();
-		vo.setRescan(rescan);
-		vo.setId(b.getId());
-		vo.setCreateTime(b.getCreateTime());
-		return vo;
-	}
-
-	private Rescan getRescan(MarkStudent student) {
-		Rescan res = new Rescan();
-		res.setStudentCode(student.getStudentCode());
-		List<PaperVo> papers = scanPaperService.findStudentPaper(student.getId());
-		List<Paper> resPapers = new ArrayList<>();
-		res.setPapers(resPapers);
-		if (CollectionUtils.isEmpty(papers)) {
-			return null;
-		}
-		PaperVo first = papers.get(0);
-		res.setBatchId(first.getBatchId());
-		res.setUser(first.getUserName());
-		res.setCreateTime(first.getCreateTime());
-		for (PaperVo paper : papers) {
-			Paper p = new Paper();
-			p.setId(paper.getId());
-			p.setNumber(paper.getNumber());
-			p.setMismatch(paper.getMismatch());
-			List<String> pages = new ArrayList<>();
-			p.setPages(pages);
-			List<ScanPaperPage> paperPages = scanPaperPageService.listByPaperId(paper.getId());
-			if (CollectionUtils.isNotEmpty(paperPages)) {
-				for (ScanPaperPage pp : paperPages) {
-					pages.add(pp.getSheetPath());
-				}
-			}
-			resPapers.add(p);
-		}
-		return res;
-	}
-
-	@Transactional
-	@Override
-	public BatchFinishVo batchFinish(Long id) {
-		ScanBatch batch = checkBatchStatus(getById(id));
-		batch.setStatus(BatchStatus.FINISH);
-		this.saveOrUpdate(batch);
-		BatchFinishVo vo = new BatchFinishVo();
-		vo.setStatus(batch.getStatus());
-		vo.setUpdateTime(System.currentTimeMillis());
-		return vo;
-	}
-
-	@Transactional
-	@Override
-	public AnswerSaveVo batchSave(AnswerDomain domain, SysUser user) {
-		ScanBatch batch = checkBatchStatus(getById(domain.getBatchId()));
-		String studentCode = domain.getStudentCode();
-		MarkStudent student = markStudentService.findByExamIdAndCoursePaperIdAndStudentCode(batch.getExamId(),
-				batch.getCoursePaperId(), studentCode);
-		if (student == null) {
-			throw new ParameterException("未找到考生信息:" + studentCode);
-		}
-		ScanAnswerCard answerCard = scanAnswerCardService.findByExamAndNumber(batch.getExamId(),
-				domain.getCardNumber());
-		if (answerCard == null) {
-			throw new ParameterException("卡格式信息未找到");
-		}
-		if (!StringUtils.equals(batch.getPackageCode(), student.getPackageCode())) {
-			throw new ParameterException("与批次卷袋号不一致");
-		}
-		boolean studentAssigned = false;
-		List<ScanStudentPaper> studentPaperList = new ArrayList<>();
-		for (AnswerPaper answerPaper : domain.getPapers()) {
-			// 验证page数量
-			answerPaper.answerCardValidate(answerCard);
-			Integer paperNumber = answerPaper.getNumber();
-			ScanPaper paper = findOrCreatePaper(batch, student, paperNumber, user);
-			// 设置paper属性
-			paper.setExamId(batch.getExamId());
-			paper.setCardNumber(answerCard.getNumber());
-			paper.setNumber(paperNumber);
-			paper.setMismatch(false);
-			paper.setQuestionFilled(false);
-			paper.setAssigned(answerPaper.getAssigned());
-			// 保存paper与page到数据库
-			scanPaperService.savePaperAndPages(paper, answerPaper.buildPageList());
-			// 记录paper与batch关联关系
-			scanBatchPaperService.update(batch, paper, student.getId(), paperNumber);
-			// 创建student与paper的关联关系
-			studentPaperList.add(new ScanStudentPaper(student.getId(), paperNumber, paper.getId()));
-			studentAssigned = studentAssigned || paper.getAssigned();
-		}
-		// 更新批次统计数量
-		updateAssignedCount(batch.getId());
-		updateScanCount(batch.getId());
-		// 没有人工绑定的情况下,直接更新考生扫描状态
-		if (!studentAssigned) {
-			concurrentService.getReadWriteLock(LockType.STUDENT + "-" + student.getId()).writeLock().lock();
-			try {
-				markStudentService.updateStudentAndPaper(user, student.getId(), studentPaperList);
-			} finally {
-				concurrentService.getReadWriteLock(LockType.STUDENT + "-" + student.getId()).writeLock().unlock();
-			}
-		}
-		return AnswerSaveVo.create(findStudentCountByBatch(batch.getId()));
-	}
-
-	@Override
-	public Integer findStudentCountByBatch(Long batchId) {
-		return baseMapper.findStudentCountByBatch(batchId);
-	}
-
-	@Transactional
-	@Override
-	public void updateAssignedCount(Long id) {
-		baseMapper.updateAssignedCount(id);
-	}
-
-	@Transactional
-	@Override
-	public void updateScanCount(Long id) {
-		baseMapper.updateScanCount(id);
-	}
-
-	private ScanPaper findOrCreatePaper(ScanBatch batch, MarkStudent student, Integer paperNumber, SysUser user) {
-		ScanPaper paper = null;
-		// 尝试重用已有paper对象
-		ScanBatchPaper batchPaper = scanBatchPaperService.findByBatchIdAndStudentIdAndPaperNumber(batch.getId(),
-				student.getId(), paperNumber);
-		if (batchPaper != null) {
-			paper = scanPaperService.getById(batchPaper.getPaperId());
-		}
-		// 构造全新paper对象
-		if (paper == null) {
-			paper = new ScanPaper();
-			paper.setCreateTime(System.currentTimeMillis());
-			paper.setCreatorId(user.getId());
-		}
-		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,
-			Integer pageIndex, MultipartFile file, String md5) {
-		ScanBatch batch = checkBatchStatus(getById(batchId));
-		try {
-			String path = markFileService.uploadSheet(file.getInputStream(), md5, batch.getExamId(), batchId, coursePaperId,
-					studentCode, paperNumber, pageIndex);
-			scanFilePropertyService.save(batch.getExamId(), path, md5, file.getSize());
-			return SheetUploadVo.create(teachcloudCommonService.filePreview(path));
-		} catch (Exception e) {
-			log.error("原图上传失败,batchId=" + batch + ", coursePaperId=" + coursePaperId + ",studentCode=" + studentCode
-					+ ", paperNumber=" + paperNumber + ", pageIndex=" + pageIndex, e);
-			throw new ParameterException("原图上传失败", e);
-		}
-	}
+    @Autowired
+    private MarkFileService markFileService;
+    @Autowired
+    private ConcurrentService concurrentService;
+    @Autowired
+    private MarkStudentService markStudentService;
+
+    @Autowired
+    private ScanPaperService scanPaperService;
+
+    @Autowired
+    private ScanPaperPageService scanPaperPageService;
+
+    @Autowired
+    private ScanBatchPaperService scanBatchPaperService;
+
+    @Autowired
+    private ScanAnswerCardService scanAnswerCardService;
+    @Autowired
+    private ScanFilePropertyService scanFilePropertyService;
+    @Resource
+    private TeachcloudCommonService teachcloudCommonService;
+
+    @Transactional
+    @Override
+    public BatchCreateVo batchCreate(BatchCreateDomain domain, SysUser sysUser) {
+        List<Rescan> rescan = new ArrayList<>();
+        for (String studentCode : domain.getStudentCodes()) {
+            MarkStudent student = markStudentService.findByExamIdAndCoursePaperIdAndStudentCode(domain.getExamId(),
+                    domain.getCoursePaperId(), studentCode);
+            if (student == null) {
+                throw new ParameterException("未找到考生信息:" + studentCode);
+            }
+            Rescan rc = getRescan(student);
+            if (rc != null) {
+                rescan.add(rc);
+            }
+        }
+
+        ScanBatch b = new ScanBatch();
+        b.setExamId(domain.getExamId());
+        b.setUserId(sysUser.getId());
+        b.setCoursePaperId(domain.getCoursePaperId());
+        b.setAssignedCount(0);
+        b.setScanCount(0);
+        b.setStatus(BatchStatus.INIT);
+        this.save(b);
+
+        BatchCreateVo vo = new BatchCreateVo();
+        vo.setRescan(rescan);
+        vo.setId(b.getId());
+        vo.setCreateTime(b.getCreateTime());
+        return vo;
+    }
+
+    private Rescan getRescan(MarkStudent student) {
+        Rescan res = new Rescan();
+        res.setStudentCode(student.getStudentCode());
+        List<PaperVo> papers = scanPaperService.findStudentPaper(student.getId());
+        List<Paper> resPapers = new ArrayList<>();
+        res.setPapers(resPapers);
+        if (CollectionUtils.isEmpty(papers)) {
+            return null;
+        }
+        PaperVo first = papers.get(0);
+        res.setBatchId(first.getBatchId());
+        res.setUser(first.getUserName());
+        res.setCreateTime(first.getCreateTime());
+        for (PaperVo paper : papers) {
+            Paper p = new Paper();
+            p.setId(paper.getId());
+            p.setNumber(paper.getNumber());
+            p.setMismatch(paper.getMismatch());
+            List<String> pages = new ArrayList<>();
+            p.setPages(pages);
+            List<ScanPaperPage> paperPages = scanPaperPageService.listByPaperId(paper.getId());
+            if (CollectionUtils.isNotEmpty(paperPages)) {
+                for (ScanPaperPage pp : paperPages) {
+                    pages.add(pp.getSheetPath());
+                }
+            }
+            resPapers.add(p);
+        }
+        return res;
+    }
+
+    @Transactional
+    @Override
+    public BatchFinishVo batchFinish(Long id) {
+        ScanBatch batch = checkBatchStatus(getById(id));
+        batch.setStatus(BatchStatus.FINISH);
+        this.saveOrUpdate(batch);
+        BatchFinishVo vo = new BatchFinishVo();
+        vo.setStatus(batch.getStatus());
+        vo.setUpdateTime(System.currentTimeMillis());
+        return vo;
+    }
+
+    @Transactional
+    @Override
+    public AnswerSaveVo batchSave(AnswerDomain domain, SysUser user) {
+        ScanBatch batch = checkBatchStatus(getById(domain.getBatchId()));
+        String studentCode = domain.getStudentCode();
+        MarkStudent student = markStudentService.findByExamIdAndCoursePaperIdAndStudentCode(batch.getExamId(), batch.getCoursePaperId(), studentCode);
+        if (student == null) {
+            throw new ParameterException("未找到考生信息:" + studentCode);
+        }
+        ScanAnswerCard answerCard = scanAnswerCardService.findByExamAndNumber(batch.getExamId(),
+                domain.getCardNumber());
+        if (answerCard == null) {
+            throw new ParameterException("卡格式信息未找到");
+        }
+        boolean studentAssigned = false;
+        List<ScanStudentPaper> studentPaperList = new ArrayList<>();
+        for (AnswerPaper answerPaper : domain.getPapers()) {
+            // 验证page数量
+            answerPaper.answerCardValidate(answerCard);
+            Integer paperNumber = answerPaper.getNumber();
+            ScanPaper paper = findOrCreatePaper(batch, student, paperNumber, user);
+            // 设置paper属性
+            paper.setExamId(batch.getExamId());
+            paper.setCardNumber(answerCard.getNumber());
+            paper.setNumber(paperNumber);
+            paper.setMismatch(false);
+            paper.setQuestionFilled(false);
+            paper.setAssigned(answerPaper.getAssigned());
+            // 保存paper与page到数据库
+            scanPaperService.savePaperAndPages(paper, answerPaper.buildPageList());
+            // 记录paper与batch关联关系
+            scanBatchPaperService.update(batch, paper, student.getId(), paperNumber);
+            // 创建student与paper的关联关系
+            studentPaperList.add(new ScanStudentPaper(student.getId(), paperNumber, paper.getId()));
+            studentAssigned = studentAssigned || paper.getAssigned();
+        }
+        // 更新批次统计数量
+        updateAssignedCount(batch.getId());
+        updateScanCount(batch.getId());
+        // 没有人工绑定的情况下,直接更新考生扫描状态
+        if (!studentAssigned) {
+            concurrentService.getReadWriteLock(LockType.STUDENT + "-" + student.getId()).writeLock().lock();
+            try {
+                markStudentService.updateStudentAndPaper(user, student.getId(), studentPaperList);
+            } finally {
+                concurrentService.getReadWriteLock(LockType.STUDENT + "-" + student.getId()).writeLock().unlock();
+            }
+        }
+        return AnswerSaveVo.create(findStudentCountByBatch(batch.getId()));
+    }
+
+    @Override
+    public Integer findStudentCountByBatch(Long batchId) {
+        return baseMapper.findStudentCountByBatch(batchId);
+    }
+
+    @Transactional
+    @Override
+    public void updateAssignedCount(Long id) {
+        baseMapper.updateAssignedCount(id);
+    }
+
+    @Transactional
+    @Override
+    public void updateScanCount(Long id) {
+        baseMapper.updateScanCount(id);
+    }
+
+    private ScanPaper findOrCreatePaper(ScanBatch batch, MarkStudent student, Integer paperNumber, SysUser user) {
+        ScanPaper paper = null;
+        // 尝试重用已有paper对象
+        ScanBatchPaper batchPaper = scanBatchPaperService.findByBatchIdAndStudentIdAndPaperNumber(batch.getId(),
+                student.getId(), paperNumber);
+        if (batchPaper != null) {
+            paper = scanPaperService.getById(batchPaper.getPaperId());
+        }
+        // 构造全新paper对象
+        if (paper == null) {
+            paper = new ScanPaper();
+            paper.setCreateTime(System.currentTimeMillis());
+            paper.setCreatorId(user.getId());
+        }
+        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,
+                                     Integer pageIndex, MultipartFile file, String md5) {
+        ScanBatch batch = checkBatchStatus(getById(batchId));
+        try {
+            String path = markFileService.uploadSheet(file.getInputStream(), md5, batch.getExamId(), batchId, coursePaperId,
+                    studentCode, paperNumber, pageIndex);
+            scanFilePropertyService.save(batch.getExamId(), path, md5, file.getSize());
+            return SheetUploadVo.create(path);
+        } catch (Exception e) {
+            log.error("原图上传失败,batchId=" + batch + ", coursePaperId=" + coursePaperId + ",studentCode=" + studentCode
+                    + ", paperNumber=" + paperNumber + ", pageIndex=" + pageIndex, e);
+            throw new ParameterException("原图上传失败", e);
+        }
+    }
 }

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

@@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 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.contant.SystemConstant;
 import com.qmth.teachcloud.common.entity.SysUser;
 import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
 import com.qmth.teachcloud.mark.bean.papermigrate.PaperMigrateDomain;
@@ -83,6 +84,7 @@ public class ScanPaperServiceImpl extends ServiceImpl<ScanPaperMapper, ScanPaper
 //            if (!fileStore.exist(page.getSheetPath())) {
 //            	throw ExceptionResultEnum.ERROR.exception("原图不存在:" + page.getSheetPath());
 //            }
+            page.setId(SystemConstant.getDbUuid());
             page.setPaperId(paper.getId());
         }
         // 保存page数据

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

@@ -31,7 +31,7 @@ public class ScanStudentPaperServiceImpl extends ServiceImpl<ScanStudentPaperMap
 		QueryWrapper<ScanStudentPaper> wrapper = new QueryWrapper<>();
 		LambdaQueryWrapper<ScanStudentPaper> lw = wrapper.lambda();
 		lw.eq(ScanStudentPaper::getStudentId, studentId);
-		wrapper.orderByAsc("paper_number");
+        lw.orderByAsc(ScanStudentPaper::getPaperIndex);
 		return this.list(wrapper);
 	}
 

+ 2 - 1
teachcloud-mark/src/main/resources/mapper/ScanAnswerCardMapper.xml

@@ -4,7 +4,8 @@
 
     <!-- 通用查询映射结果 -->
     <resultMap id="BaseResultMap" type="com.qmth.teachcloud.mark.entity.ScanAnswerCard">
-        <id column="exam_id" property="examId" />
+        <id column="id" property="id" />
+        <result column="exam_id" property="examId" />
         <result column="paper_number" property="paperNumber" />
         <result column="course_paper_id" property="coursePaperId" />
         <result column="card_id" property="cardId" />

+ 0 - 1
teachcloud-mark/src/main/resources/mapper/ScanBatchMapper.xml

@@ -7,7 +7,6 @@
         <id column="id" property="id" />
         <result column="exam_id" property="examId" />
         <result column="user_id" property="userId" />
-        <result column="package_code" property="packageCode" />
         <result column="scan_count" property="scanCount" />
         <result column="assigned_count" property="assignedCount" />
         <result column="status" property="status" />

+ 2 - 1
teachcloud-mark/src/main/resources/mapper/ScanPaperPageMapper.xml

@@ -4,7 +4,8 @@
 
     <!-- 通用查询映射结果 -->
     <resultMap id="BaseResultMap" type="com.qmth.teachcloud.mark.entity.ScanPaperPage">
-        <id column="paper_id" property="paperId" />
+        <id column="id" property="id" />
+        <result column="paper_id" property="paperId" />
         <result column="page_index" property="pageIndex" />
         <result column="absent" property="absent" jdbcType="BLOB" typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler"/>
         <result column="breach" property="breach" jdbcType="BLOB" typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler" />

+ 2 - 1
teachcloud-mark/src/main/resources/mapper/ScanStudentPaperMapper.xml

@@ -4,7 +4,8 @@
 
     <!-- 通用查询映射结果 -->
     <resultMap id="BaseResultMap" type="com.qmth.teachcloud.mark.entity.ScanStudentPaper">
-        <id column="student_id" property="studentId" />
+        <id column="id" property="id" />
+        <result column="student_id" property="studentId" />
         <result column="paper_index" property="paperIndex" />
         <result column="paper_id" property="paperId" />
         <result column="create_time" property="createTime" />