|
@@ -1,16 +1,27 @@
|
|
|
package com.qmth.teachcloud.mark.service.impl;
|
|
|
|
|
|
+import java.io.IOException;
|
|
|
import java.util.List;
|
|
|
|
|
|
+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.extension.service.impl.ServiceImpl;
|
|
|
+import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
import com.qmth.boot.core.exception.ParameterException;
|
|
|
+import com.qmth.teachcloud.common.enums.mark.MarkPaperStatus;
|
|
|
+import com.qmth.teachcloud.mark.bean.answercard.AnswerCardSaveDomain;
|
|
|
import com.qmth.teachcloud.mark.bean.answercard.AnswerCardVo;
|
|
|
+import com.qmth.teachcloud.mark.bean.answercard.CardFile;
|
|
|
+import com.qmth.teachcloud.mark.entity.MarkPaper;
|
|
|
import com.qmth.teachcloud.mark.entity.ScanAnswerCard;
|
|
|
+import com.qmth.teachcloud.mark.enums.CardSource;
|
|
|
import com.qmth.teachcloud.mark.mapper.ScanAnswerCardMapper;
|
|
|
+import com.qmth.teachcloud.mark.service.FileService;
|
|
|
+import com.qmth.teachcloud.mark.service.MarkPaperService;
|
|
|
import com.qmth.teachcloud.mark.service.ScanAnswerCardService;
|
|
|
|
|
|
/**
|
|
@@ -25,6 +36,13 @@ import com.qmth.teachcloud.mark.service.ScanAnswerCardService;
|
|
|
public class ScanAnswerCardServiceImpl extends ServiceImpl<ScanAnswerCardMapper, ScanAnswerCard>
|
|
|
implements ScanAnswerCardService {
|
|
|
|
|
|
+ @Autowired
|
|
|
+ private MarkPaperService markPaperService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private FileService fileService;
|
|
|
+
|
|
|
+
|
|
|
@Override
|
|
|
public ScanAnswerCard findByExamAndNumber(Long examId, Integer cardNumber) {
|
|
|
if (examId == null) {
|
|
@@ -45,4 +63,81 @@ public class ScanAnswerCardServiceImpl extends ServiceImpl<ScanAnswerCardMapper,
|
|
|
return baseMapper.cardList(examId,coursePaperId);
|
|
|
}
|
|
|
|
|
|
+ @Transactional
|
|
|
+ @Override
|
|
|
+ public void 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());
|
|
|
+ if(card==null) {
|
|
|
+ throw new ParameterException("未找到卡格式信息");
|
|
|
+ }
|
|
|
+ }else {
|
|
|
+ card=new ScanAnswerCard();
|
|
|
+ card.setExamId(domain.getExamId());
|
|
|
+ card.setCoursePaperId(domain.getCoursePaperId());
|
|
|
+ card.setPaperCount(domain.getPaperCount());
|
|
|
+ card.setSinglePage(singlePage);
|
|
|
+ card.setRemark(domain.getRemark());
|
|
|
+ card.setDpi(domain.getDpi());
|
|
|
+ card.setSource(CardSource.CLIENT);
|
|
|
+ card.setNumber(findMaxCardNumberByExamId(domain.getExamId())+1);
|
|
|
+ card.setNeedAdapte(false);
|
|
|
+ }
|
|
|
+ CardFile cardFile;
|
|
|
+ byte[] fileData;
|
|
|
+ String sliceConfig;
|
|
|
+ try {
|
|
|
+ fileData = domain.getFile().getBytes();
|
|
|
+ //解析卡格式文件
|
|
|
+ cardFile = parseCardFile(fileData);
|
|
|
+ if (singlePage && domain.getPaperCount()!=cardFile.getPages().size()) {
|
|
|
+ throw new ParameterException("卡格式数量不一致");
|
|
|
+ }
|
|
|
+ if (!singlePage && domain.getPaperCount()*2!=cardFile.getPages().size()) {
|
|
|
+ throw new ParameterException("卡格式数量不一致");
|
|
|
+ }
|
|
|
+ //提取裁切坐标
|
|
|
+ sliceConfig = cardFile.getSliceConfig().toString();
|
|
|
+ } catch (IOException e) {
|
|
|
+ throw new ParameterException("文件解析失败", e);
|
|
|
+ }
|
|
|
+ String filePath=null;
|
|
|
+ try {
|
|
|
+ fileService.uploadAnswerCard(domain.getFile().getInputStream(), domain.getMd5(), domain.getExamId(), domain.getNumber());
|
|
|
+ } catch (IOException e) {
|
|
|
+ throw new ParameterException("文件上传失败", e);
|
|
|
+ }
|
|
|
+ card.setSliceConfig(sliceConfig);
|
|
|
+ card.setMd5(domain.getMd5());
|
|
|
+ card.setUri(filePath);
|
|
|
+ this.saveOrUpdate(card);
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 解析卡格式文件中的裁切图坐标,用于云阅卷同步
|
|
|
+ *
|
|
|
+ * @param data
|
|
|
+ */
|
|
|
+ private CardFile parseCardFile(byte[] data) throws IOException {
|
|
|
+ ObjectMapper objectMapper = new ObjectMapper();
|
|
|
+ return objectMapper.readValue(data, CardFile.class);
|
|
|
+ }
|
|
|
+ private Integer findMaxCardNumberByExamId(Long examId) {
|
|
|
+ int number = 0;
|
|
|
+ QueryWrapper<ScanAnswerCard> queryWrapper = new QueryWrapper<>();
|
|
|
+ queryWrapper.lambda().eq(ScanAnswerCard::getExamId, examId);
|
|
|
+ List<ScanAnswerCard> list = this.list(queryWrapper);
|
|
|
+ for (ScanAnswerCard card : list) {
|
|
|
+ if (number < card.getNumber()) {
|
|
|
+ number = card.getNumber();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return number;
|
|
|
+ }
|
|
|
+
|
|
|
}
|