Jelajahi Sumber

3.4.2 update

xiaofei 7 bulan lalu
induk
melakukan
bf78a1bd48
28 mengubah file dengan 567 tambahan dan 136 penghapusan
  1. 6 0
      distributed-print-business/pom.xml
  2. 33 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/entity/ExamTaskPaperData.java
  3. 0 1
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ExamPrintPlanService.java
  4. 1 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ExamTaskPaperDataService.java
  5. 2 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ClientServiceImpl.java
  6. 13 2
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/DownloadServiceImpl.java
  7. 1 1
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamDetailServiceImpl.java
  8. 0 13
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamPrintPlanServiceImpl.java
  9. 8 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamTaskPaperDataServiceImpl.java
  10. 54 47
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamTaskServiceImpl.java
  11. 44 40
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/service/impl/DownloadLogicServiceImpl.java
  12. 8 13
      distributed-print-business/src/main/resources/mapper/ExamTaskDetailMapper.xml
  13. 0 6
      distributed-print-business/src/main/resources/mapper/ExamTaskMapper.xml
  14. 25 0
      teachcloud-common/src/main/java/com/qmth/teachcloud/common/bean/tiku/paperData/answer/AnswerDetail.java
  15. 31 0
      teachcloud-common/src/main/java/com/qmth/teachcloud/common/bean/tiku/paperData/answer/AnswerDetailQuestion.java
  16. 52 0
      teachcloud-common/src/main/java/com/qmth/teachcloud/common/bean/tiku/paperData/answer/TikuAnswer.java
  17. 52 0
      teachcloud-common/src/main/java/com/qmth/teachcloud/common/bean/tiku/paperData/paper/PaperStructDetail.java
  18. 53 0
      teachcloud-common/src/main/java/com/qmth/teachcloud/common/bean/tiku/paperData/paper/PaperStructDetailQuestion.java
  19. 61 0
      teachcloud-common/src/main/java/com/qmth/teachcloud/common/bean/tiku/paperData/paper/TikuPaper.java
  20. 62 0
      teachcloud-common/src/main/java/com/qmth/teachcloud/common/bean/vo/PaperInfoCardVo.java
  21. 12 0
      teachcloud-common/src/main/java/com/qmth/teachcloud/common/bean/vo/PaperInfoVo.java
  22. 2 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/mapper/ScanPaperMapper.java
  23. 11 3
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkStudentServiceImpl.java
  24. 2 1
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/ScanConditionServiceImpl.java
  25. 1 4
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/ScanPaperServiceImpl.java
  26. 15 0
      teachcloud-mark/src/main/resources/mapper/ScanPaperMapper.xml
  27. 1 1
      teachcloud-task/src/main/java/com/qmth/teachcloud/task/service/PrintFinishService.java
  28. 17 4
      teachcloud-task/src/main/java/com/qmth/teachcloud/task/service/impl/PrintFinishServiceImpl.java

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

@@ -213,6 +213,12 @@
             <groupId>io.github.burukeyou</groupId>
             <artifactId>jdframe</artifactId>
         </dependency>
+        <dependency>
+            <groupId>com.aspose.words</groupId>
+            <artifactId>aspose-words-jdk16</artifactId>
+            <version>15.8.0</version>
+            <scope>compile</scope>
+        </dependency>
     </dependencies>
 
 </project>

+ 33 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/entity/ExamTaskPaperData.java

@@ -1,13 +1,22 @@
 package com.qmth.distributed.print.business.entity;
 
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableName;
 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
 import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
 import com.github.jeffreyning.mybatisplus.anno.MppMultiId;
+import com.qmth.teachcloud.common.bean.tiku.paperData.answer.AnswerDetail;
+import com.qmth.teachcloud.common.bean.tiku.paperData.answer.TikuAnswer;
+import com.qmth.teachcloud.common.bean.tiku.paperData.paper.TikuPaper;
+import com.qmth.teachcloud.common.entity.MarkQuestion;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
+import org.apache.commons.lang3.StringUtils;
 
 import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * <p>
@@ -43,9 +52,17 @@ public class ExamTaskPaperData implements Serializable {
     @ApiModelProperty(value = "试卷结构内容(从paper.json解析)")
     private String paperJson;
 
+    @TableField(exist = false)
+    @ApiModelProperty(value = "试卷结构内容)")
+    private TikuPaper tikuPaper;
+
     @ApiModelProperty(value = "试卷答案内容(从answer.json解析)")
     private String answerJson;
 
+    @TableField(exist = false)
+    @ApiModelProperty(value = "试卷答案内容")
+    private TikuAnswer tikuAnswer;
+
     @JsonSerialize(using = ToStringSerializer.class)
     @ApiModelProperty(value = "试卷pdf文件地址(paper.pdf上传附件ID)")
     private Long paperPdfAttachmentId;
@@ -133,6 +150,22 @@ public class ExamTaskPaperData implements Serializable {
         this.uuid = uuid;
     }
 
+    public TikuPaper getTikuPaper() {
+        return StringUtils.isNotBlank(this.paperJson) ? JSON.parseObject(this.paperJson, TikuPaper.class) : null;
+    }
+
+    public void setTikuPaper(TikuPaper tikuPaper) {
+        this.tikuPaper = tikuPaper;
+    }
+
+    public TikuAnswer getTikuAnswer() {
+        return StringUtils.isNotBlank(this.answerJson) ? JSON.parseObject(this.answerJson, TikuAnswer.class) : null;
+    }
+
+    public void setTikuAnswer(TikuAnswer tikuAnswer) {
+        this.tikuAnswer = tikuAnswer;
+    }
+
     @Override
     public String toString() {
         return "ExamTaskPaperData{" +

+ 0 - 1
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ExamPrintPlanService.java

@@ -94,5 +94,4 @@ public interface ExamPrintPlanService extends IService<ExamPrintPlan> {
 
     void updateStatusById(Long printPlanId, PrintPlanStatusEnum status);
 
-    void updateFinishStatus(Long printPlanId);
 }

+ 1 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ExamTaskPaperDataService.java

@@ -13,4 +13,5 @@ import com.qmth.distributed.print.business.entity.ExamTaskPaperData;
  */
 public interface ExamTaskPaperDataService extends IMppService<ExamTaskPaperData> {
 
+    void deleteByExamIdAndPaperNumber(Long examId, String paperNumber);
 }

+ 2 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ClientServiceImpl.java

@@ -135,6 +135,8 @@ public class ClientServiceImpl implements ClientService {
 
             // 所有考场打印完成,更新印刷计划状态
             examPrintPlanService.updateStatusById(examDetail.getPrintPlanId(), PrintPlanStatusEnum.FINISH);
+            // 更新曝光卷型
+            examTaskDetailService.updateExposePaperType(examDetail.getExamId(), examDetailCourseService.listByExamDetailId(examDetail.getId()));
 
             // 记录机器打印数量
             SysUser sysUser = (SysUser) ServletUtil.getRequestUser();

+ 13 - 2
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/DownloadServiceImpl.java

@@ -11,6 +11,7 @@ import com.qmth.distributed.print.business.mapper.ExamCardMapper;
 import com.qmth.distributed.print.business.mapper.ExamTaskDetailMapper;
 import com.qmth.distributed.print.business.mapper.ExamTaskMapper;
 import com.qmth.distributed.print.business.service.DownloadService;
+import com.qmth.distributed.print.business.service.ExamTaskDetailService;
 import com.qmth.distributed.print.business.service.ExamTaskService;
 import com.qmth.distributed.print.business.util.CreatePdfUtil;
 import com.qmth.teachcloud.common.bean.dto.DataPermissionRule;
@@ -39,6 +40,7 @@ import javax.servlet.http.HttpServletResponse;
 import java.io.File;
 import java.nio.charset.StandardCharsets;
 import java.util.*;
+import java.util.stream.Collectors;
 
 @Service
 public class DownloadServiceImpl implements DownloadService {
@@ -53,6 +55,8 @@ public class DownloadServiceImpl implements DownloadService {
     BasicAttachmentMapper basicAttachmentMapper;
     @Resource
     ExamTaskService examTaskService;
+    @Resource
+    private ExamTaskDetailService examTaskDetailService;
 
     @Resource
     ExamCardMapper examCardMapper;
@@ -69,11 +73,18 @@ public class DownloadServiceImpl implements DownloadService {
         Page<ExamTaskDetailDto> page = new Page<>(pageNumber, pageSize);
         SysUser requestUser = (SysUser) ServletUtil.getRequestUser();
         DataPermissionRule dpr = basicRoleDataPermissionService.findDataPermission(requestUser.getSchoolId(), requestUser.getId(), ServletUtil.getRequest().getServletPath());
-        return examTaskMapper.listExamTaskDetailDownload(page, examId, courseId, paperNumber, orgId, userParam, dpr);
+        IPage<ExamTaskDetailDto> examTaskDetailDtoIPage = examTaskMapper.listExamTaskDetailDownload(page, examId, courseId, paperNumber, orgId, userParam, dpr);
+        for (ExamTaskDetailDto record : examTaskDetailDtoIPage.getRecords()) {
+            List<ExamTaskDetail> examTaskDetailList = examTaskDetailService.listByExamTaskId(record.getId());
+            record.setPaperType(examTaskDetailList.stream().map(m -> m.getSerialNumber().toString()).collect(Collectors.joining(",")));
+            record.setExposedPaperType(examTaskDetailList.stream().filter(ExamTaskDetail::getExposed).map(m -> m.getSerialNumber().toString()).collect(Collectors.joining(",")));
+            record.setUnexposedPaperType(examTaskDetailList.stream().filter(m -> !m.getExposed()).map(m -> m.getSerialNumber().toString()).collect(Collectors.joining(",")));
+        }
+        return examTaskDetailDtoIPage;
     }
 
     @Override
-    public void paperDownload(HttpServletResponse response, Long id) throws Exception {
+    public void paperDownload(HttpServletResponse response, Long id) {
         ExamTask examTask = examTaskService.getByIdIncludeCourse(id);
         QueryWrapper<ExamTaskDetail> queryWrapper = new QueryWrapper<>();
         queryWrapper.lambda().eq(ExamTaskDetail::getExamTaskId, id);

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

@@ -526,7 +526,7 @@ public class ExamDetailServiceImpl extends ServiceImpl<ExamDetailMapper, ExamDet
         this.update(updateWrapper);
 
         // 所有考场打印完成,更新印刷计划状态
-        examPrintPlanService.updateFinishStatus(examDetail.getPrintPlanId());
+        examPrintPlanService.updateStatusById(examDetail.getPrintPlanId(), PrintPlanStatusEnum.FINISH);
 
         // 更新曝光卷型
         examTaskDetailService.updateExposePaperType(examDetail.getExamId(), examDetailCourseService.listByExamDetailId(examDetail.getId()));

+ 0 - 13
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamPrintPlanServiceImpl.java

@@ -363,19 +363,6 @@ public class ExamPrintPlanServiceImpl extends ServiceImpl<ExamPrintPlanMapper, E
         }
     }
 
-    @Override
-    public void updateFinishStatus(Long printPlanId) {
-        // 所有考场打印完成,更新印刷计划状态
-        QueryWrapper<ExamDetail> examDetailQueryWrapper = new QueryWrapper<>();
-        examDetailQueryWrapper.lambda().eq(ExamDetail::getPrintPlanId, printPlanId).ne(ExamDetail::getStatus, ExamDetailStatusEnum.FINISH);
-        int count = examDetailService.count(examDetailQueryWrapper);
-        if (count == 0) {
-            UpdateWrapper<ExamPrintPlan> examPrintPlanUpdateWrapper = new UpdateWrapper<>();
-            examPrintPlanUpdateWrapper.lambda().set(ExamPrintPlan::getStatus, PrintPlanStatusEnum.FINISH).eq(ExamPrintPlan::getId, printPlanId);
-            this.update(examPrintPlanUpdateWrapper);
-        }
-    }
-
     /**
      * 查找子机构
      *

+ 8 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamTaskPaperDataServiceImpl.java

@@ -1,5 +1,6 @@
 package com.qmth.distributed.print.business.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.github.jeffreyning.mybatisplus.service.MppServiceImpl;
 import com.qmth.distributed.print.business.entity.ExamTaskPaperData;
 import com.qmth.distributed.print.business.mapper.ExamTaskPaperDataMapper;
@@ -17,4 +18,11 @@ import org.springframework.stereotype.Service;
 @Service
 public class ExamTaskPaperDataServiceImpl extends MppServiceImpl<ExamTaskPaperDataMapper, ExamTaskPaperData> implements ExamTaskPaperDataService {
 
+    @Override
+    public void deleteByExamIdAndPaperNumber(Long examId, String paperNumber) {
+        UpdateWrapper<ExamTaskPaperData> updateWrapper = new UpdateWrapper<>();
+        updateWrapper.lambda().eq(ExamTaskPaperData::getExamId, examId)
+                .eq(ExamTaskPaperData::getPaperNumber, paperNumber);
+        this.remove(updateWrapper);
+    }
 }

+ 54 - 47
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamTaskServiceImpl.java

@@ -566,7 +566,7 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
         }
 
         // 单次导入限制不超过150条数据,否则页面渲染会导致页面崩溃(2024-11-11 add)
-        if(examTaskImportDtoList.size() > 150){
+        if (examTaskImportDtoList.size() > 150) {
             throw ExceptionResultEnum.ERROR.exception("单次导入命题任务数量不超过150条");
         }
 
@@ -676,7 +676,6 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
             } else {
                 examTaskDto.setUsers(sysUserList);
             }
-            examTaskDto.setUsers(sysUserList);
             examTaskDtos.add(examTaskDto);
 
         }
@@ -914,8 +913,8 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
             List<Long> cardIds = paperInfoVoList.stream().filter(m -> StringUtils.isNotBlank(m.getCardId())).map(m -> Long.parseLong(m.getCardId())).collect(Collectors.toList());
             for (Long cardId : cardIds) {
                 ExamCard examCard = examCardService.getById(cardId);
-                if(!examTask.getOpenAb().equals(examCard.getOpenAb())){
-                    throw ExceptionResultEnum.ERROR.exception(examTask.getOpenAb() && !examCard.getOpenAb() ? "命题任务开启了AB卷,请选择AB卷题卡或者编辑题卡开启AB卷": "命题任务未开启了AB卷,请选择单题卡或者编辑题卡关闭AB卷");
+                if (!examTask.getOpenAb().equals(examCard.getOpenAb())) {
+                    throw ExceptionResultEnum.ERROR.exception(examTask.getOpenAb() && !examCard.getOpenAb() ? "命题任务开启了AB卷,请选择AB卷题卡或者编辑题卡开启AB卷" : "命题任务未开启了AB卷,请选择单题卡或者编辑题卡关闭AB卷");
                 }
             }
             // 将题卡更新为已绑定
@@ -1034,42 +1033,46 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
                     .add(examTaskDetailPdfDownloadDto.getExamName()).add(File.separator)
                     .add(examTaskDetailPdfDownloadDto.getCourseNameCode().replaceAll(" ", "")).add(File.separator)
                     .add(examTaskDetailPdfDownloadDto.getPaperNumber()).add(File.separator);
-            List<PaperInfoVo> paperInfoVoList = ExamTaskUtil.parsePaperAttachmentPath(examTaskDetailPdfDownloadDto.getPaperAttachmentIds());
-            // 试卷
-            for (PaperInfoVo paperInfoVo : paperInfoVoList) {
-                Long attachmentId = Long.valueOf(paperInfoVo.getAttachmentId());
-                String name = paperInfoVo.getName();
-                if (Objects.nonNull(attachmentId)) {
-                    BasicAttachment attachment = basicAttachmentService.getById(attachmentId);
-                    Optional.ofNullable(attachment).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("附件数据异常"));
-                    String fileName = dirPath + "试卷" + SystemConstant.HYPHEN + name + attachment.getType();
-                    fileUploadService.downloadFile(attachment, fileName);
-                }
 
-                // 题卡
-                Long cardId = Long.valueOf(paperInfoVo.getCardId());
-                if (cardId != null) {
-                    ExamCard examCard = examCardService.getById(cardId);
+            List<ExamTaskDetail> examTaskDetailList = examTaskDetailService.listByExamTaskId(examTaskId);
+            for (ExamTaskDetail examTaskDetail : examTaskDetailList) {
+                List<PaperInfoVo> paperInfoVoList = ExamTaskUtil.parsePaperAttachmentPath(examTaskDetail.getPaperAttachmentIds());
+                // 试卷
+                for (PaperInfoVo paperInfoVo : paperInfoVoList) {
+                    Long attachmentId = Long.valueOf(paperInfoVo.getAttachmentId());
+                    String name = paperInfoVo.getName();
+                    if (Objects.nonNull(attachmentId)) {
+                        BasicAttachment attachment = basicAttachmentService.getById(attachmentId);
+                        Optional.ofNullable(attachment).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("附件数据异常"));
+                        String fileName = dirPath + "卷" + examTaskDetail.getSerialNumber() + SystemConstant.HYPHEN + "试卷" + SystemConstant.HYPHEN + name + attachment.getType();
+                        fileUploadService.downloadFile(attachment, fileName);
+                    }
 
-                    String cardHtmlPath = dirPath + "题卡" + SystemConstant.HYPHEN + name + SystemConstant.HTML_PREFIX;
-                    String cardPdfPath = dirPath + "题卡" + SystemConstant.HYPHEN + name + SystemConstant.PDF_PREFIX;
+                    // 题卡
+                    Long cardId = Long.valueOf(paperInfoVo.getCardId());
+                    if (cardId != null) {
+                        ExamCard examCard = examCardService.getById(cardId);
 
-                    String htmlContent = createPdfUtil.replaceBlankHtmlContent(examCard.getHtmlContent(), examCard.getCourseId());
-                    // html
-                    File htmlFile = new File(cardHtmlPath);
-                    if (!htmlFile.exists()) {
-                        htmlFile.getParentFile().mkdirs();
-                        htmlFile.createNewFile();
-                    }
-                    // 生成html文件
-                    FileUtil.writeContent(htmlFile, htmlContent);
-                    // 转pdf文件
-                    File pdfFile = new File(cardPdfPath);
-                    if (!pdfFile.exists()) {
-                        pdfFile.getParentFile().mkdirs();
-                        pdfFile.createNewFile();
+                        String cardHtmlPath = dirPath + "卷" + examTaskDetail.getSerialNumber() + SystemConstant.HYPHEN + "题卡" + SystemConstant.HYPHEN + name + SystemConstant.HTML_PREFIX;
+                        String cardPdfPath = dirPath + "卷" + examTaskDetail.getSerialNumber() + SystemConstant.HYPHEN + "题卡" + SystemConstant.HYPHEN + name + SystemConstant.PDF_PREFIX;
+
+                        String htmlContent = createPdfUtil.replaceBlankHtmlContent(examCard.getHtmlContent(), examCard.getCourseId());
+                        // html
+                        File htmlFile = new File(cardHtmlPath);
+                        if (!htmlFile.exists()) {
+                            htmlFile.getParentFile().mkdirs();
+                            htmlFile.createNewFile();
+                        }
+                        // 生成html文件
+                        FileUtil.writeContent(htmlFile, htmlContent);
+                        // 转pdf文件
+                        File pdfFile = new File(cardPdfPath);
+                        if (!pdfFile.exists()) {
+                            pdfFile.getParentFile().mkdirs();
+                            pdfFile.createNewFile();
+                        }
+                        HtmlToPdfUtil.convert(cardHtmlPath, cardPdfPath, PageSizeEnum.A3);
                     }
-                    HtmlToPdfUtil.convert(cardHtmlPath, cardPdfPath, PageSizeEnum.A3);
                 }
             }
             String zipFileName = downloadPathFile.getName() + SystemConstant.ZIP_PREFIX;
@@ -1211,7 +1214,7 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
             throw ExceptionResultEnum.ERROR.exception("正在校验试卷编号,请稍后再试");
         }
         try {
-            ExamTask task = this.getByExamIdAndCourseIdAndPaperNumber(examTask.getExamId(), null, examTask.getPaperNumber());
+            ExamTask task = this.getByExamIdAndPaperNumber(examTask.getExamId(), examTask.getPaperNumber());
             if (task != null) {
                 throw ExceptionResultEnum.ERROR.exception("试卷编号已使用");
             }
@@ -1311,8 +1314,8 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
                 List<Long> cardIds = paperInfoVoList.stream().filter(m -> StringUtils.isNotBlank(m.getCardId())).map(m -> Long.parseLong(m.getCardId())).collect(Collectors.toList());
                 for (Long cardId : cardIds) {
                     ExamCard examCard = examCardService.getById(cardId);
-                    if(!examTask.getOpenAb().equals(examCard.getOpenAb())){
-                        throw ExceptionResultEnum.ERROR.exception(examTask.getOpenAb() && !examCard.getOpenAb() ? "命题任务开启了AB卷,请选择AB卷题卡或者编辑题卡开启AB卷": "命题任务未开启了AB卷,请选择单题卡或者编辑题卡关闭AB卷");
+                    if (!examTask.getOpenAb().equals(examCard.getOpenAb())) {
+                        throw ExceptionResultEnum.ERROR.exception(examTask.getOpenAb() && !examCard.getOpenAb() ? "命题任务开启了AB卷,请选择AB卷题卡或者编辑题卡开启AB卷" : "命题任务未开启了AB卷,请选择单题卡或者编辑题卡关闭AB卷");
                     }
                 }
                 // 将题卡更新为已绑定
@@ -1327,15 +1330,17 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
                                 .eq(ExamTaskPaperData::getPaperId, paperInfoVo.getPaperId())
                                 .eq(ExamTaskPaperData::getUuid, paperInfoVo.getUuid());
                         examTaskPaperDataService.update(updateWrapper);
-
-                        // 删除临时数据
-                        QueryWrapper<ExamTaskPaperData> deleteWrapper = new QueryWrapper<>();
-                        deleteWrapper.lambda().eq(ExamTaskPaperData::getExamId, examTask.getExamId())
-                                .eq(ExamTaskPaperData::getPaperNumber, paperInfoVo.getUuid())
-                                .ne(ExamTaskPaperData::getPaperId, paperInfoVo.getPaperId());
-                        examTaskPaperDataService.remove(deleteWrapper);
                     }
                 }
+
+                if (StringUtils.isNotBlank(paperInfoVoList.get(0).getUuid())) {
+                    // 删除临时数据
+                    QueryWrapper<ExamTaskPaperData> deleteWrapper = new QueryWrapper<>();
+                    deleteWrapper.lambda().eq(ExamTaskPaperData::getExamId, examTask.getExamId())
+                            .eq(ExamTaskPaperData::getPaperNumber, paperInfoVoList.get(0).getUuid())
+                            .notIn(ExamTaskPaperData::getPaperId, paperInfoVoList.stream().filter(m -> m.getPaperId() != null).map(PaperInfoVo::getPaperId).collect(Collectors.toList()));
+                    examTaskPaperDataService.remove(deleteWrapper);
+                }
             }
 
             BasicExam basicExam = basicExamService.getById(examTask.getExamId());
@@ -1431,7 +1436,7 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
                         if (basicStudentIdUserMap.containsKey(i)) {
                             BasicExamStudent basicExamStudent = basicExamStudentService.getById(i);
                             if (basicExamStudent != null) {
-                                throw ExceptionResultEnum.ERROR.exception("教学班[" + basicExamStudent.getTeachClassName() + "]内有考生已被[" + basicStudentIdUserMap.get(i) + "]选择");
+//                                throw ExceptionResultEnum.ERROR.exception("教学班[" + basicExamStudent.getTeachClassName() + "]内有考生已被[" + basicStudentIdUserMap.get(i) + "]选择");
                             }
                         }
                     });
@@ -1829,6 +1834,8 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
         }
         // 删除命题任务及试卷信息
         this.removeByExamTaskId(id);
+        // 删除题库试卷包信息
+        examTaskPaperDataService.deleteByExamIdAndPaperNumber(examTask.getExamId(), examTask.getPaperNumber());
         // 删除考场信息
         examDetailService.deleteByExamIdAndPaperNumber(examTask.getSchoolId(), examTask.getExamId(), examTask.getPaperNumber());
     }

+ 44 - 40
distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/service/impl/DownloadLogicServiceImpl.java

@@ -15,6 +15,7 @@ import com.qmth.distributed.print.business.bean.query.BasicExamStudentPageQuery;
 import com.qmth.distributed.print.business.bean.result.BasicExamStudentResult;
 import com.qmth.distributed.print.business.bean.result.TSyncExamStudentScoreResult;
 import com.qmth.distributed.print.business.entity.ExamCard;
+import com.qmth.distributed.print.business.entity.ExamTaskDetail;
 import com.qmth.distributed.print.business.entity.TSyncExamStudentScore;
 import com.qmth.distributed.print.business.entity.TeachClazz;
 import com.qmth.distributed.print.business.enums.ImageTrajectoryEnum;
@@ -278,48 +279,51 @@ public class DownloadLogicServiceImpl implements DownloadLogicService {
                         .add(examTaskDetailPdfDownloadDto.getCourseNameCode().replaceAll(" ", "")).add(SystemConstant.HYPHEN)
                         .add(examTaskDetailPdfDownloadDto.getPaperNumber()).add(SystemConstant.HYPHEN);
                 // 试卷
-                String paperAttachmentIds = examTaskDetailPdfDownloadDto.getPaperAttachmentIds();
-                if (StringUtils.isNotBlank(paperAttachmentIds)) {
-                    List<PaperInfoVo> paperInfoVoList = ExamTaskUtil.parsePaperAttachmentPath(paperAttachmentIds);
-                    if (CollectionUtils.isEmpty(paperInfoVoList)) {
-                        throw ExceptionResultEnum.ERROR.exception("试卷信息不存在");
-                    }
-                    for (PaperInfoVo paperInfoVo : paperInfoVoList) {
-                        Long attachmentId = Long.valueOf(paperInfoVo.getAttachmentId());
-                        String name = paperInfoVo.getName();
-                        if (Objects.nonNull(attachmentId)) {
-                            BasicAttachment attachment = basicAttachmentService.getById(attachmentId);
-                            if (Objects.nonNull(attachment)) {
-                                String fileName = dirPath + "试卷" + SystemConstant.HYPHEN + name + attachment.getType();
-                                File paperFile = fileUploadService.downloadFile(attachment, fileName);
-                                sourceFileList.add(paperFile);
-                            }
+                List<ExamTaskDetail> examTaskDetailList = examTaskDetailService.listByExamTaskId(examTask.getId());
+                for (ExamTaskDetail examTaskDetail : examTaskDetailList) {
+                    String paperAttachmentIds = examTaskDetail.getPaperAttachmentIds();
+                    if (StringUtils.isNotBlank(paperAttachmentIds)) {
+                        List<PaperInfoVo> paperInfoVoList = ExamTaskUtil.parsePaperAttachmentPath(paperAttachmentIds);
+                        if (CollectionUtils.isEmpty(paperInfoVoList)) {
+                            throw ExceptionResultEnum.ERROR.exception("试卷信息不存在");
                         }
-                        Long cardId = Long.valueOf(paperInfoVo.getCardId());
-                        ExamCard examCard = examCardService.getById(cardId);
-                        Optional.ofNullable(examCard).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("找不到答题卡"));
-
-                        String cardHtmlPath = dirPath + "题卡" + SystemConstant.HYPHEN + name + SystemConstant.HTML_PREFIX;
-                        String cardPdfPath = dirPath + "题卡" + SystemConstant.HYPHEN + name + SystemConstant.PDF_PREFIX;
-                        // 通用题卡
-                        String htmlContent = createPdfUtil.replaceBlankHtmlContent(examCard.getHtmlContent(), examCard.getCourseId());
-                        // html
-                        File localFile = new File(cardHtmlPath);
-                        if (!localFile.exists()) {
-                            localFile.getParentFile().mkdirs();
-                            localFile.createNewFile();
-                        }
-                        // 生成html文件
-                        FileCopyUtils.copy(htmlContent.getBytes(StandardCharsets.UTF_8), localFile);
-                        sourceFileList.add(localFile);
-                        // 转pdf文件
-                        File file = new File(cardPdfPath);
-                        if (!file.exists()) {
-                            file.getParentFile().mkdirs();
-                            file.createNewFile();
+                        for (PaperInfoVo paperInfoVo : paperInfoVoList) {
+                            Long attachmentId = Long.valueOf(paperInfoVo.getAttachmentId());
+                            String name = paperInfoVo.getName();
+                            if (Objects.nonNull(attachmentId)) {
+                                BasicAttachment attachment = basicAttachmentService.getById(attachmentId);
+                                if (Objects.nonNull(attachment)) {
+                                    String fileName = dirPath + "卷" + examTaskDetail.getSerialNumber() + SystemConstant.HYPHEN + "试卷" + SystemConstant.HYPHEN + name + attachment.getType();
+                                    File paperFile = fileUploadService.downloadFile(attachment, fileName);
+                                    sourceFileList.add(paperFile);
+                                }
+                            }
+                            Long cardId = Long.valueOf(paperInfoVo.getCardId());
+                            ExamCard examCard = examCardService.getById(cardId);
+                            Optional.ofNullable(examCard).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("找不到答题卡"));
+
+                            String cardHtmlPath = dirPath + "卷" + examTaskDetail.getSerialNumber() + SystemConstant.HYPHEN + "题卡" + SystemConstant.HYPHEN + name + SystemConstant.HTML_PREFIX;
+                            String cardPdfPath = dirPath + "卷" + examTaskDetail.getSerialNumber() + SystemConstant.HYPHEN + "题卡" + SystemConstant.HYPHEN + name + SystemConstant.PDF_PREFIX;
+                            // 通用题卡
+                            String htmlContent = createPdfUtil.replaceBlankHtmlContent(examCard.getHtmlContent(), examCard.getCourseId());
+                            // html
+                            File localFile = new File(cardHtmlPath);
+                            if (!localFile.exists()) {
+                                localFile.getParentFile().mkdirs();
+                                localFile.createNewFile();
+                            }
+                            // 生成html文件
+                            FileCopyUtils.copy(htmlContent.getBytes(StandardCharsets.UTF_8), localFile);
+                            sourceFileList.add(localFile);
+                            // 转pdf文件
+                            File file = new File(cardPdfPath);
+                            if (!file.exists()) {
+                                file.getParentFile().mkdirs();
+                                file.createNewFile();
+                            }
+                            HtmlToPdfUtil.convert(cardHtmlPath, cardPdfPath, PageSizeEnum.A3);
+                            sourceFileList.add(file);
                         }
-                        HtmlToPdfUtil.convert(cardHtmlPath, cardPdfPath, PageSizeEnum.A3);
-                        sourceFileList.add(file);
                     }
                 }
             }

+ 8 - 13
distributed-print-business/src/main/resources/mapper/ExamTaskDetailMapper.xml

@@ -172,24 +172,19 @@
     </select>
     <select id="findPdfDownload" resultType="com.qmth.distributed.print.business.bean.dto.ExamTaskDetailPdfDownloadDto">
         select
-            etd.*,
             bs.name as semesterName,
             be.name as examName,
-            GROUP_CONCAT(CONCAT(bc.name, '(', bc.code, ')')) as courseNameCode,
-            GROUP_CONCAT(et.paper_number) paperNumber
-        from
-            exam_task_detail etd
-                join exam_task et on et.id = etd.exam_task_id
-                join basic_exam be on be.id = et.exam_id
-                join basic_semester bs on bs.id = be.semester_id
-                join basic_course bc on et.course_id = bc.id
+            CONCAT(bc.name, '(', bc.code, ')') as courseNameCode,
+            et.paper_number paperNumber
+        from exam_task et
+            join basic_course bc on et.course_id = bc.id
+            join basic_exam be on be.id = et.exam_id
+            join basic_semester bs on bs.id = be.semester_id
         <where>
-            <if test="examTaskId != null and examTaskId != ''">
-                etd.exam_task_id = #{examTaskId}
+            <if test="examTaskId != null">
+                et.id = #{examTaskId}
             </if>
         </where>
-        GROUP BY
-            etd.id
     </select>
     <select id="countByCardId" resultType="java.lang.Integer">
         select

+ 0 - 6
distributed-print-business/src/main/resources/mapper/ExamTaskMapper.xml

@@ -1007,10 +1007,6 @@
             bc.code courseCode,
             bc.name courseName,
             a.paper_number paperNumber,
-            b.enable,
-            b.paper_type paperType,
-            b.exposed_paper_type exposedPaperType,
-            b.unexposed_paper_type unexposedPaperType,
             a.user_id userId,
             su.login_name loginName,
             su.real_name userName,
@@ -1018,8 +1014,6 @@
         FROM
             exam_task a
                 LEFT JOIN
-            exam_task_detail b ON a.id = b.exam_task_id
-                LEFT JOIN
             basic_course bc ON a.course_id = bc.id
                 LEFT JOIN
             sys_org so ON bc.teaching_room_id = so.id

+ 25 - 0
teachcloud-common/src/main/java/com/qmth/teachcloud/common/bean/tiku/paperData/answer/AnswerDetail.java

@@ -0,0 +1,25 @@
+package com.qmth.teachcloud.common.bean.tiku.paperData.answer;
+
+import java.util.List;
+
+public class AnswerDetail {
+
+    private Integer number;
+    private List<AnswerDetailQuestion> questions;
+
+    public Integer getNumber() {
+        return number;
+    }
+
+    public void setNumber(Integer number) {
+        this.number = number;
+    }
+
+    public List<AnswerDetailQuestion> getQuestions() {
+        return questions;
+    }
+
+    public void setQuestions(List<AnswerDetailQuestion> questions) {
+        this.questions = questions;
+    }
+}

+ 31 - 0
teachcloud-common/src/main/java/com/qmth/teachcloud/common/bean/tiku/paperData/answer/AnswerDetailQuestion.java

@@ -0,0 +1,31 @@
+package com.qmth.teachcloud.common.bean.tiku.paperData.answer;
+
+public class AnswerDetailQuestion {
+    private Integer number;
+    private Object answer;
+    private String answerString;
+
+    public Integer getNumber() {
+        return number;
+    }
+
+    public void setNumber(Integer number) {
+        this.number = number;
+    }
+
+    public Object getAnswer() {
+        return answer;
+    }
+
+    public void setAnswer(Object answer) {
+        this.answer = answer;
+    }
+
+    public String getAnswerString() {
+        return answerString;
+    }
+
+    public void setAnswerString(String answerString) {
+        this.answerString = answerString;
+    }
+}

+ 52 - 0
teachcloud-common/src/main/java/com/qmth/teachcloud/common/bean/tiku/paperData/answer/TikuAnswer.java

@@ -0,0 +1,52 @@
+package com.qmth.teachcloud.common.bean.tiku.paperData.answer;
+
+import com.alibaba.fastjson.JSON;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringJoiner;
+
+public class TikuAnswer {
+
+    private final String[] LETTER = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "G", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"};
+
+    private List<AnswerDetail> details;
+
+    public List<AnswerDetail> getDetails() {
+        return details;
+    }
+
+    public void setDetails(List<AnswerDetail> details) {
+        this.details = details;
+    }
+
+    public AnswerDetailQuestion getByMainNumberAndSubNumber(Integer mainNumber, Integer subNumber) {
+        if (this.details.isEmpty()) {
+            return new AnswerDetailQuestion();
+        }
+        for (AnswerDetail detail : this.details) {
+            if (!detail.getNumber().equals(mainNumber)) {
+                continue;
+            }
+            List<AnswerDetailQuestion> questions = detail.getQuestions();
+            for (AnswerDetailQuestion question : questions) {
+                if (!question.getNumber().equals(subNumber)) {
+                    continue;
+                }
+                Object answer = question.getAnswer();
+                if (answer instanceof Boolean) {
+                    question.setAnswerString(Boolean.parseBoolean(answer.toString()) ? LETTER[0] : LETTER[1]);
+                } else if (answer instanceof List) {
+                    StringJoiner stringJoiner = new StringJoiner("");
+                    List<Integer> integers = JSON.parseArray(answer.toString(), Integer.class);
+                    for (Integer integer : integers) {
+                        stringJoiner.add(LETTER[integer - 1]);
+                    }
+                    question.setAnswerString(stringJoiner.toString());
+                }
+                return question;
+            }
+        }
+        return new AnswerDetailQuestion();
+    }
+}

+ 52 - 0
teachcloud-common/src/main/java/com/qmth/teachcloud/common/bean/tiku/paperData/paper/PaperStructDetail.java

@@ -0,0 +1,52 @@
+package com.qmth.teachcloud.common.bean.tiku.paperData.paper;
+
+import java.util.List;
+
+public class PaperStructDetail {
+
+    private Integer number;
+    private String name;
+    private Double totalScore;
+    private Integer questionCount;
+    private List<PaperStructDetailQuestion> questions;
+
+    public Integer getNumber() {
+        return number;
+    }
+
+    public void setNumber(Integer number) {
+        this.number = number;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public Double getTotalScore() {
+        return totalScore;
+    }
+
+    public void setTotalScore(Double totalScore) {
+        this.totalScore = totalScore;
+    }
+
+    public Integer getQuestionCount() {
+        return questionCount;
+    }
+
+    public void setQuestionCount(Integer questionCount) {
+        this.questionCount = questionCount;
+    }
+
+    public List<PaperStructDetailQuestion> getQuestions() {
+        return questions;
+    }
+
+    public void setQuestions(List<PaperStructDetailQuestion> questions) {
+        this.questions = questions;
+    }
+}

+ 53 - 0
teachcloud-common/src/main/java/com/qmth/teachcloud/common/bean/tiku/paperData/paper/PaperStructDetailQuestion.java

@@ -0,0 +1,53 @@
+package com.qmth.teachcloud.common.bean.tiku.paperData.paper;
+
+public class PaperStructDetailQuestion {
+
+    private Integer id;
+    private Integer number;
+    private Double score;
+    /**
+     * 1-单选,2-多选,3-判断,4-填空,5-问答,6-套题,7-听力,8-配对题
+     */
+    private Integer structType;
+    private Boolean objective;
+
+    public Integer getId() {
+        return id;
+    }
+
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    public Integer getNumber() {
+        return number;
+    }
+
+    public void setNumber(Integer number) {
+        this.number = number;
+    }
+
+    public Double getScore() {
+        return score;
+    }
+
+    public void setScore(Double score) {
+        this.score = score;
+    }
+
+    public Integer getStructType() {
+        return structType;
+    }
+
+    public void setStructType(Integer structType) {
+        this.structType = structType;
+    }
+
+    public Boolean getObjective() {
+        return objective;
+    }
+
+    public void setObjective(Boolean objective) {
+        this.objective = objective;
+    }
+}

+ 61 - 0
teachcloud-common/src/main/java/com/qmth/teachcloud/common/bean/tiku/paperData/paper/TikuPaper.java

@@ -0,0 +1,61 @@
+package com.qmth.teachcloud.common.bean.tiku.paperData.paper;
+
+import java.util.List;
+
+public class TikuPaper {
+
+    private String name;
+    private String courseCode;
+    private String courseName;
+    private Double totalScore;
+    private Integer detailCount;
+    private List<PaperStructDetail> details;
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getCourseCode() {
+        return courseCode;
+    }
+
+    public void setCourseCode(String courseCode) {
+        this.courseCode = courseCode;
+    }
+
+    public String getCourseName() {
+        return courseName;
+    }
+
+    public void setCourseName(String courseName) {
+        this.courseName = courseName;
+    }
+
+    public Double getTotalScore() {
+        return totalScore;
+    }
+
+    public void setTotalScore(Double totalScore) {
+        this.totalScore = totalScore;
+    }
+
+    public Integer getDetailCount() {
+        return detailCount;
+    }
+
+    public void setDetailCount(Integer detailCount) {
+        this.detailCount = detailCount;
+    }
+
+    public List<PaperStructDetail> getDetails() {
+        return details;
+    }
+
+    public void setDetails(List<PaperStructDetail> details) {
+        this.details = details;
+    }
+}

+ 62 - 0
teachcloud-common/src/main/java/com/qmth/teachcloud/common/bean/vo/PaperInfoCardVo.java

@@ -0,0 +1,62 @@
+package com.qmth.teachcloud.common.bean.vo;
+
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+
+public class PaperInfoCardVo {
+
+    private String id;
+    private String makeMethod;
+    private String title;
+    private String type;
+    private String createId;
+    private boolean used;
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getMakeMethod() {
+        return makeMethod;
+    }
+
+    public void setMakeMethod(String makeMethod) {
+        this.makeMethod = makeMethod;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public String getCreateId() {
+        return createId;
+    }
+
+    public void setCreateId(String createId) {
+        this.createId = createId;
+    }
+
+    public boolean isUsed() {
+        return used;
+    }
+
+    public void setUsed(boolean used) {
+        this.used = used;
+    }
+}

+ 12 - 0
teachcloud-common/src/main/java/com/qmth/teachcloud/common/bean/vo/PaperInfoVo.java

@@ -1,5 +1,7 @@
 package com.qmth.teachcloud.common.bean.vo;
 
+import java.util.List;
+
 public class PaperInfoVo {
 
     private String name;
@@ -18,6 +20,8 @@ public class PaperInfoVo {
 
     private OriginalVo original;
 
+    private List<PaperInfoCardVo> cards;
+
     public String getName() {
         return name;
     }
@@ -129,4 +133,12 @@ public class PaperInfoVo {
     public void setOriginal(OriginalVo original) {
         this.original = original;
     }
+
+    public List<PaperInfoCardVo> getCards() {
+        return cards;
+    }
+
+    public void setCards(List<PaperInfoCardVo> cards) {
+        this.cards = cards;
+    }
 }

+ 2 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/mapper/ScanPaperMapper.java

@@ -25,4 +25,6 @@ public interface ScanPaperMapper extends BaseMapper<ScanPaper> {
 	List<PaperVo> findStudentPaper(@Param("studentId")Long studentId);
 
 	List<StudentPaperVo> listByStudentIds(@Param("studentIds")List<Long> studentIds);
+
+    int countByExamIdAndCardNumber(@Param("examId") Long examId, @Param("number") Integer number);
 }

+ 11 - 3
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkStudentServiceImpl.java

@@ -565,7 +565,8 @@ public class MarkStudentServiceImpl extends ServiceImpl<MarkStudentMapper, MarkS
             paperCount++;
             // 获取paper详情更新考生状态
             ScanPaper paper = scanPaperService.getById(studentPaper.getPaperId());
-            student.setAssigned(student.getAssigned() || paper.getAssigned());
+            // 二次识别不进人工绑定检查
+            student.setAssigned(omrEdit && (student.getAssigned() || paper.getAssigned()));
             student.setInvalid(student.getInvalid() || paper.getInvalid());
             student.setQuestionFilled(student.getQuestionFilled() || paper.getQuestionFilled());
             student.setCardNumber(paper.getCardNumber());
@@ -584,6 +585,10 @@ public class MarkStudentServiceImpl extends ServiceImpl<MarkStudentMapper, MarkS
                         student.setObjectiveScoreList(null);
                     }
                 } else {
+                    // 人工指定后,识别缺考未处理的数据,不再处理,已处理的,不变
+                    if (!student.getOmrAbsentChecked()) {
+                        student.setOmrAbsent(false);
+                    }
                     student.setManualAbsent(page.getAbsent() != null && page.getAbsent().getResult());
                     student.setManualBreach(page.getBreach() != null && page.getBreach().getResult());
                 }
@@ -616,7 +621,10 @@ public class MarkStudentServiceImpl extends ServiceImpl<MarkStudentMapper, MarkS
                             student.setPaperTypeCheckStatus(PaperTypeCheckStatus.NORMAL);
                         }
                     } else {
-                        student.setPaperTypeCheckStatus(PaperTypeCheckStatus.PROCESSED);
+                        // 卷型检查,待检查的数据,不再处理,已处理的,不变
+                        if (PaperTypeCheckStatus.WAITING.equals(student.getPaperTypeCheckStatus())) {
+                            student.setPaperTypeCheckStatus(PaperTypeCheckStatus.NORMAL);
+                        }
                     }
                 }
 
@@ -1413,7 +1421,7 @@ public class MarkStudentServiceImpl extends ServiceImpl<MarkStudentMapper, MarkS
             lambdaQueryWrapper.eq(MarkStudent::getSubjectiveStatus, status);
         }
         lambdaQueryWrapper.eq(MarkStudent::getUpload, true).eq(MarkStudent::getAbsent, false)
-                .and(m->m.eq(MarkStudent::getManualAbsent, false).or().isNull(MarkStudent::getManualAbsent)).eq(MarkStudent::getOmrAbsent, false);
+                .and(m -> m.eq(MarkStudent::getManualAbsent, false).or().isNull(MarkStudent::getManualAbsent)).eq(MarkStudent::getOmrAbsent, false);
         return this.count(queryWrapper);
     }
 

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

@@ -24,6 +24,7 @@ import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
@@ -81,7 +82,7 @@ public class ScanConditionServiceImpl implements ScanConditionService {
         DataPermissionRule dpr = basicRoleDataPermissionService.findDataPermission(sysUser.getSchoolId(), sysUser.getId(), ServletUtil.getRequest().getServletPath());
         List<MarkPaper> markPaperList = markPaperService.listByExamId(examId, MarkPaperStatus.FORMAL, dpr);
         Map<Long, List<MarkPaper>> map = markPaperList.stream().collect(Collectors.groupingBy(m -> m.getCourseId()));
-        List<BasicCourse> list= basicCourseService.listByIds(map.keySet());
+        List<BasicCourse> list = !map.isEmpty() ? basicCourseService.listByIds(map.keySet()) : Collections.emptyList();
         List<CoursePaperNumberDto> coursePaperNumberDtoList = new ArrayList<>();
         for (BasicCourse basicCourse : list) {
             CoursePaperNumberDto coursePaperNumberDto = new CoursePaperNumberDto();

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

@@ -109,10 +109,7 @@ public class ScanPaperServiceImpl extends ServiceImpl<ScanPaperMapper, ScanPaper
 
     @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);
+        return this.baseMapper.countByExamIdAndCardNumber(examId, number);
     }
 
     @Override

+ 15 - 0
teachcloud-mark/src/main/resources/mapper/ScanPaperMapper.xml

@@ -70,4 +70,19 @@
         </foreach>
         order by t.paper_index
     </select>
+    <select id="countByExamIdAndCardNumber" resultType="java.lang.Integer">
+        SELECT
+            COUNT(1)
+        FROM
+            scan_paper sp
+        WHERE
+            sp.exam_id = #{examId}
+          AND sp.card_number = #{number}
+          AND EXISTS( SELECT
+                          1
+                      FROM
+                          scan_student_paper ssp
+                      WHERE
+                          sp.id = ssp.paper_id)
+    </select>
 </mapper>

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

@@ -20,7 +20,7 @@ public interface PrintFinishService {
 
     ScanAnswerCard insertScanAnswerCard(ExamDetailCourseInitMarkDto dto, String cardId, String content);
 
-    void insertMarkQuestion(Long examId, String paperNumber, String content);
+    void insertMarkQuestion(Long examId, String paperNumber, String content, List<PaperInfoVo> paperInfoVoList);
 
     void insertPaperAnswerFile(Long examId, String paperNumber, Integer serialNumber, Long paperId);
 

+ 17 - 4
teachcloud-task/src/main/java/com/qmth/teachcloud/task/service/impl/PrintFinishServiceImpl.java

@@ -9,6 +9,7 @@ import com.qmth.distributed.print.business.entity.*;
 import com.qmth.distributed.print.business.enums.CardTypeEnum;
 import com.qmth.distributed.print.business.enums.ExamNumberStyleEnum;
 import com.qmth.distributed.print.business.service.*;
+import com.qmth.teachcloud.common.bean.tiku.paperData.answer.TikuAnswer;
 import com.qmth.teachcloud.common.bean.vo.PaperInfoVo;
 import com.qmth.teachcloud.common.contant.SystemConstant;
 import com.qmth.teachcloud.common.entity.BasicAttachment;
@@ -161,7 +162,7 @@ public class PrintFinishServiceImpl implements PrintFinishService {
                     continue;
                 }
                 // 解析卡格式中试卷结构并保存
-                this.insertMarkQuestion(dto.getExamId(), dto.getPaperNumber(), examCard.getContent());
+                this.insertMarkQuestion(dto.getExamId(), dto.getPaperNumber(), examCard.getContent(), paperInfoVoList);
                 // 生成并保存卡格式文件(后缀为.json)
                 ScanAnswerCard scanAnswerCard = this.insertScanAnswerCard(dto, cardId, examCard.getContent());
                 if (scanAnswerCard != null) {
@@ -246,7 +247,7 @@ public class PrintFinishServiceImpl implements PrintFinishService {
 
     @Transactional
     @Override
-    public void insertMarkQuestion(Long examId, String paperNumber, String content) {
+    public void insertMarkQuestion(Long examId, String paperNumber, String content, List<PaperInfoVo> paperInfoVoList) {
         try {
             List<Struct> structList = CardParseUtils.parseCardContent(content);
             if (CollectionUtils.isEmpty(structList)) {
@@ -255,6 +256,18 @@ public class PrintFinishServiceImpl implements PrintFinishService {
             List<MarkQuestion> markQuestionList = markQuestionService.listQuestionByExamIdAndPaperNumber(examId, paperNumber);
             // 第一次新增
             if (CollectionUtils.isEmpty(markQuestionList)) {
+                // 解析题卡选择试卷的客观题标答和分数
+                Map<String, TikuAnswer> map = new HashMap<>();
+                for (PaperInfoVo paperInfoVo : paperInfoVoList) {
+                    if (paperInfoVo.getPaperId() == null) {
+                        continue;
+                    }
+                    ExamTaskPaperData examTaskPaperData = examTaskPaperDataService.selectByMultiId(new ExamTaskPaperData(examId, paperNumber, paperInfoVo.getPaperId()));
+                    if (examTaskPaperData != null && examTaskPaperData.getTikuAnswer() != null) {
+                        map.put(paperInfoVo.getName(), examTaskPaperData.getTikuAnswer());
+                    }
+                }
+
                 MarkPaper markPaper = markPaperService.getByExamIdAndPaperNumber(examId, paperNumber);
                 List<MarkQuestion> markQuestions = new ArrayList<>();
                 List<MarkQuestionAnswer> markQuestionAnswers = new ArrayList<>();
@@ -284,9 +297,9 @@ public class PrintFinishServiceImpl implements PrintFinishService {
                     if (struct.getObjective()) {
                         for (String paperType : markPaper.getPaperTypeList()) {
                             MarkQuestionAnswer markQuestionAnswer = new MarkQuestionAnswer(examId, paperNumber, paperType, struct.getMainNumber(), struct.getSubNumber());
-                            if (StringUtils.isNotBlank(struct.getAnswer())) {
+                            if (!map.isEmpty() && map.get(paperType) != null) {
                                 // 客观题有标答时,给分策略默认为全对给分
-                                markQuestionAnswer.setAnswer(struct.getAnswer());
+                                markQuestionAnswer.setAnswer(map.get(paperType).getByMainNumberAndSubNumber(markQuestion.getMainNumber(), markQuestion.getSubNumber()).getAnswerString());
                                 markQuestionAnswer.setObjectivePolicy(ObjectivePolicy.NONE);
                             }
                             markQuestionAnswers.add(markQuestionAnswer);