浏览代码

3.4.2 update

xiaofei 7 月之前
父节点
当前提交
09225fa18f
共有 17 个文件被更改,包括 195 次插入66 次删除
  1. 1 1
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/mapper/ExamCardMapper.java
  2. 1 1
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ExamCardService.java
  3. 37 15
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/BasicExamStudentServiceImpl.java
  4. 2 2
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamCardServiceImpl.java
  5. 5 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamTaskServiceImpl.java
  6. 0 1
      distributed-print-business/src/main/resources/mapper/ExamCardMapper.xml
  7. 15 6
      distributed-print-business/src/main/resources/mapper/ExamTaskMapper.xml
  8. 2 3
      distributed-print/src/main/java/com/qmth/distributed/print/api/ExamCardController.java
  9. 2 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/MarkQuestionAnswerService.java
  10. 2 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/MarkQuestionService.java
  11. 1 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/ScanAnswerCardService.java
  12. 8 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkQuestionAnswerServiceImpl.java
  13. 9 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkQuestionServiceImpl.java
  14. 1 1
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkServiceImpl.java
  15. 36 27
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkStudentServiceImpl.java
  16. 69 6
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/ScanAnswerCardServiceImpl.java
  17. 4 3
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/ScanOmrTaskServiceImpl.java

+ 1 - 1
distributed-print-business/src/main/java/com/qmth/distributed/print/business/mapper/ExamCardMapper.java

@@ -21,7 +21,7 @@ public interface ExamCardMapper extends BaseMapper<ExamCard> {
 
     List<ExamCard> listGenericCard(@Param("schoolId") Long schoolId, @Param("type") String type, @Param("cardRuleId") Long cardRuleId);
 
-    List<ExamCard> listCustom(@Param("schoolId") Long schoolId, @Param("courseId") Long courseId, @Param("type") String type, @Param("cardRuleId") Long cardRuleId, @Param("paperId") Long paperId, @Param("userId") Long userId, @Param("openAb") Boolean openAb);
+    List<ExamCard> listCustom(@Param("schoolId") Long schoolId, @Param("courseId") Long courseId, @Param("type") String type, @Param("cardRuleId") Long cardRuleId, @Param("paperId") Long paperId, @Param("userId") Long userId);
 
     IPage<ExamCard> listPage(@Param("page") Page<ExamCard> page, @Param("schoolId") Long schoolId, @Param("semesterId") Long semesterId, @Param("examId") Long examId, @Param("courseId") Long courseId, @Param("paperNumber") String paperNumber, @Param("cardType") String cardType, @Param("title") String title, @Param("createMethod") String createMethod, @Param("enable") Boolean enable, @Param("createStartTime") Long createStartTime, @Param("createEndTime") Long createEndTime, @Param("dpr") DataPermissionRule dpr);
 

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

@@ -23,7 +23,7 @@ public interface ExamCardService extends IService<ExamCard> {
 
     Map<String, String> saveExamCard(ExamCardParams examCardParams) throws Exception;
 
-    List<ExamCard> listSelectCard(Long examId, Long courseId, String paperNumber, Long paperId, Boolean openAb);
+    List<ExamCard> listSelectCard(Long examId, Long courseId, String paperNumber, Long paperId);
 
     IPage<ExamCard> listPage(Long semesterId, Long examId, Long courseId, String paperNumber, String cardType, String title, String createMethod, Boolean enable, Long createStartTime, Long createEndTime, Integer pageNumber, Integer pageSize);
 

+ 37 - 15
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/BasicExamStudentServiceImpl.java

@@ -302,29 +302,51 @@ public class BasicExamStudentServiceImpl extends ServiceImpl<BasicExamStudentMap
             basicExamStudent.insertInfo(requestUserId);
         }
 
+        // 模式4必填字段校验
+        if (ExamModelEnum.MODEL4.equals(basicExam.getExamModel())) {
+            if (StringUtils.isBlank(basicExamStudent.getPaperNumber())) {
+                throw ExceptionResultEnum.ERROR.exception(RequiredFieldsEnum.PAPER_NUMBER.getName() + "必填");
+            }
+            if (StringUtils.isBlank(basicExamStudent.getStudentCode())) {
+                throw ExceptionResultEnum.ERROR.exception(RequiredFieldsEnum.STUDENT_CODE.getName() + "必填");
+            }
+            if (StringUtils.isBlank(basicExamStudent.getStudentName())) {
+                throw ExceptionResultEnum.ERROR.exception(RequiredFieldsEnum.STUDENT_NAME.getName() + "必填");
+            }
+            if (basicExamStudent.getCourseId() == null) {
+                throw ExceptionResultEnum.ERROR.exception(RequiredFieldsEnum.COURSE_CODE.getName() + "必填");
+            }
+            if (StringUtils.isBlank(basicExamStudent.getTeachClassName())) {
+                throw ExceptionResultEnum.ERROR.exception(RequiredFieldsEnum.TEACH_CLASS_NAME.getName() + "必填");
+            }
+        }
+
         // 试卷编号绑定其它课程
         if (StringUtils.isNotBlank(basicExamStudent.getPaperNumber())) {
-            BasicExamRule basicExamRule = basicExamRuleService.getBySchoolId(schoolId);
-            Optional<EnumResult> optional = basicExamRule.getRequiredFieldList().stream().filter(m -> RequiredFieldsEnum.EXAM_PLACE.getCode().equals(m.getCode()) && m.getEnable()).findFirst();
-            // 试卷编号不为空时,校区(考点)必填
-            if (optional.isPresent() && optional.get().getEnable() && StringUtils.isBlank(basicExamStudent.getExamPlace())) {
-                throw ExceptionResultEnum.ERROR.exception(RequiredFieldsEnum.EXAM_PLACE.getName() + "必填");
+//            BasicExamRule basicExamRule = basicExamRuleService.getBySchoolId(schoolId);
+//            Optional<EnumResult> optional = basicExamRule.getRequiredFieldList().stream().filter(m -> RequiredFieldsEnum.EXAM_PLACE.getCode().equals(m.getCode()) && m.getEnable()).findFirst();
+//            // 试卷编号不为空时,校区(考点)必填
+//            if (optional.isPresent() && optional.get().getEnable() && StringUtils.isBlank(basicExamStudent.getExamPlace())) {
+//                throw ExceptionResultEnum.ERROR.exception(RequiredFieldsEnum.EXAM_PLACE.getName() + "必填");
+//            }
+            if (basicExamStudent.getExamStartTime() != null && basicExamStudent.getExamEndTime() != null) {
+                QueryWrapper<BasicExamStudent> queryWrapper = new QueryWrapper<>();
+                LambdaQueryWrapper<BasicExamStudent> lambda = queryWrapper.lambda();
+                lambda.eq(BasicExamStudent::getExamId, basicExamStudent.getExamId()).eq(BasicExamStudent::getPaperNumber, basicExamStudent.getPaperNumber())
+                        .and(m -> m.ne(BasicExamStudent::getExamStartTime, basicExamStudent.getExamStartTime()).or().ne(BasicExamStudent::getExamEndTime, basicExamStudent.getExamEndTime()));
+                if (basicExamStudent.getId() != null) {
+                    lambda.ne(BasicExamStudent::getId, basicExamStudent.getId());
+                }
+                if (this.count(queryWrapper) > 0) {
+                    throw ExceptionResultEnum.ERROR.exception(String.format("试卷编号[%s]存在不同考试时间", basicExamStudent.getPaperNumber()));
+                }
             }
+
             if (this.count(new QueryWrapper<BasicExamStudent>().lambda()
                     .eq(BasicExamStudent::getExamId, basicExamStudent.getExamId()).eq(BasicExamStudent::getPaperNumber, basicExamStudent.getPaperNumber())
                     .ne(BasicExamStudent::getCourseId, basicExamStudent.getCourseId())) > 0) {
                 throw ExceptionResultEnum.ERROR.exception(String.format("试卷编号[%s]已绑定其它课程", basicExamStudent.getPaperNumber()));
             }
-            QueryWrapper<BasicExamStudent> queryWrapper = new QueryWrapper<>();
-            LambdaQueryWrapper<BasicExamStudent> lambda = queryWrapper.lambda();
-            lambda.eq(BasicExamStudent::getExamId, basicExamStudent.getExamId()).eq(BasicExamStudent::getPaperNumber, basicExamStudent.getPaperNumber())
-                    .and(m -> m.ne(BasicExamStudent::getExamStartTime, basicExamStudent.getExamStartTime()).or().ne(BasicExamStudent::getExamEndTime, basicExamStudent.getExamEndTime()));
-            if (basicExamStudent.getId() != null) {
-                lambda.ne(BasicExamStudent::getId, basicExamStudent.getId());
-            }
-            if (this.count(queryWrapper) > 0) {
-                throw ExceptionResultEnum.ERROR.exception(String.format("试卷编号[%s]存在不同考试时间", basicExamStudent.getPaperNumber()));
-            }
         }
 
         parserRequiredField(basicExamStudent);

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

@@ -180,7 +180,7 @@ public class ExamCardServiceImpl extends ServiceImpl<ExamCardMapper, ExamCard> i
     }
 
     @Override
-    public List<ExamCard> listSelectCard(Long examId, Long courseId, String paperNumber, Long paperId, Boolean openAb) {
+    public List<ExamCard> listSelectCard(Long examId, Long courseId, String paperNumber, Long paperId) {
         SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
         BasicPrintConfig basicPrintConfig = basicPrintConfigService.getByExamId(examId);
         Long cardRuleId = basicPrintConfig.getCardRuleId();
@@ -197,7 +197,7 @@ public class ExamCardServiceImpl extends ServiceImpl<ExamCardMapper, ExamCard> i
         // 专卡
         if (SystemConstant.ALL_CARD != cardRuleId) {
             // 只查自己创建的专卡(20230405已改为查询课程下所有题卡,允许复制,不能选择)
-            List<ExamCard> customCards = this.baseMapper.listCustom(sysUser.getSchoolId(), courseId, CardTypeEnum.CUSTOM.name(), cardRuleId, paperId, sysUser.getId(), openAb);
+            List<ExamCard> customCards = this.baseMapper.listCustom(sysUser.getSchoolId(), courseId, CardTypeEnum.CUSTOM.name(), cardRuleId, paperId, sysUser.getId());
             if (!customCards.isEmpty()) {
                 list.addAll(customCards);
             }

+ 5 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamTaskServiceImpl.java

@@ -565,6 +565,11 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
             throw ExceptionResultEnum.ERROR.exception("读取excel内容失败");
         }
 
+        // 单次导入限制不超过150条数据,否则页面渲染会导致页面崩溃(2024-11-11 add)
+        if(examTaskImportDtoList.size() > 150){
+            throw ExceptionResultEnum.ERROR.exception("单次导入命题任务数量不超过150条");
+        }
+
         AtomicInteger i = new AtomicInteger(3);
         List<SysOrg> sysOrgList = sysOrgService.getSecondOrg(schoolId, null);
         if (CollectionUtils.isEmpty(sysOrgList)) {

+ 0 - 1
distributed-print-business/src/main/resources/mapper/ExamCardMapper.xml

@@ -40,7 +40,6 @@
                 AND a.paper_id is null
             </if>
             AND a.create_id = #{userId}
-            AND a.open_ab = #{openAb}
         </where>
         order by a.create_time desc
     </select>

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

@@ -1205,8 +1205,8 @@
             a.paper_number,
             a.login_name,
             a.real_name,
-            a.unexposed_paper_type,
-            a.exposed_paper_type,
+            a.unexposedPaperType,
+            a.exposedPaperType,
             b.id examDetailId,
             b.print_plan_id,
             b.total_subjects,
@@ -1224,13 +1224,22 @@
             et.paper_number,
             su.login_name,
             su.real_name,
-            etd.unexposed_paper_type,
-            etd.exposed_paper_type,
+            d.unexposedPaperType,
+            d.exposedPaperType,
             c.exam_place,
             c.clazz_name
         FROM
             exam_task et
-        LEFT JOIN exam_task_detail etd ON et.id = etd.exam_task_id
+        LEFT JOIN
+        (SELECT
+            etd.exam_task_id,
+            GROUP_CONCAT(CASE etd.exposed WHEN 1 THEN etd.serial_number ELSE NULL END) exposedPaperType,
+            GROUP_CONCAT(CASE etd.exposed WHEN 0 THEN etd.serial_number ELSE NULL END) unexposedPaperType
+        FROM
+            exam_task_detail etd
+        WHERE
+            exists (select 1 from exam_task et where exam_id = #{examId} and etd.exam_task_id = et.id)
+            GROUP BY exam_task_id) d ON et.id = d.exam_task_id
         LEFT JOIN t_f_flow_approve g ON g.flow_id = et.flow_id
         LEFT JOIN basic_exam be ON et.exam_id = be.id
         LEFT JOIN sys_user su ON et.user_id = su.id
@@ -1276,7 +1285,7 @@
             et.course_id = bc.id
             AND bc.teaching_room_id = #{collegeId})
         </if>
-        AND etd.unexposed_paper_type is not null
+        AND d.unexposedPaperType is not null
         and (et.status = 'SUBMIT' and (et.flow_id is null or (et.flow_id is not null and g.status = 'FINISH')))) a
         LEFT JOIN
         (SELECT

+ 2 - 3
distributed-print/src/main/java/com/qmth/distributed/print/api/ExamCardController.java

@@ -143,9 +143,8 @@ public class ExamCardController {
     public Result selectCardList(@ApiParam(value = "考试ID") @RequestParam Long examId,
                                  @ApiParam(value = "课程ID") @RequestParam Long courseId,
                                  @ApiParam(value = "试卷编号") @RequestParam(required = false) String paperNumber,
-                                 @ApiParam(value = "题库试卷ID") @RequestParam(required = false) Long paperId,
-                                 @ApiParam(value = "是否开启AB卷") @RequestParam(required = false, defaultValue = "false") Boolean openAb) {
-        List<ExamCard> list = examCardService.listSelectCard(examId, courseId, paperNumber, paperId, openAb);
+                                 @ApiParam(value = "题库试卷ID") @RequestParam(required = false) Long paperId) {
+        List<ExamCard> list = examCardService.listSelectCard(examId, courseId, paperNumber, paperId);
         return ResultUtil.ok(list);
     }
 

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

@@ -21,4 +21,6 @@ public interface MarkQuestionAnswerService extends IService<MarkQuestionAnswer>
     List<MarkQuestionAnswer> listByExamIdAndPaperNumberAndPaperType(Long examId, String paperNumber, String paperType);
 
     int countByExamIdAndPaperNumber(Long examId, String paperNumber);
+
+    void deleteByExamIdAndPaperNumber(Long examId, String paperNumber);
 }

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

@@ -98,4 +98,6 @@ public interface MarkQuestionService extends IService<MarkQuestion> {
     List<MarkQuestionAnswerVo> listQuestionAnswerByExamIdAndPaperNumberAndPaperType(Long examId, String paperNumber, String paperType, Boolean objective);
 
     List<MarkQuestion> listByExamIdAndPaperNumber(Long examId, String paperNumber);
+
+    void deleteByExamIdAndPaperNumberAndObjective(Long examId, String paperNumber, boolean objective);
 }

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

@@ -47,4 +47,5 @@ public interface ScanAnswerCardService extends IService<ScanAnswerCard> {
     List<CardJpgResult> listPageImage(Long examId, String paperNumber);
 
     List<ScanAnswerCard> listByExamIdAndCoursePaperIdAndSource(Long examId, String coursePaperId, CardSource source);
+
 }

+ 8 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkQuestionAnswerServiceImpl.java

@@ -57,4 +57,12 @@ public class MarkQuestionAnswerServiceImpl extends ServiceImpl<MarkQuestionAnswe
                 .eq(MarkQuestionAnswer::getPaperNumber, paperNumber);
         return this.count(queryWrapper);
     }
+
+    @Override
+    public void deleteByExamIdAndPaperNumber(Long examId, String paperNumber) {
+        UpdateWrapper<MarkQuestionAnswer> updateWrapper = new UpdateWrapper<>();
+        updateWrapper.lambda().eq(MarkQuestionAnswer::getExamId, examId)
+                .eq(MarkQuestionAnswer::getPaperNumber, paperNumber);
+        this.remove(updateWrapper);
+    }
 }

+ 9 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkQuestionServiceImpl.java

@@ -544,4 +544,13 @@ public class MarkQuestionServiceImpl extends ServiceImpl<MarkQuestionMapper, Mar
                 .eq(MarkQuestion::getPaperNumber, paperNumber);
         return this.list(queryWrapper);
     }
+
+    @Override
+    public void deleteByExamIdAndPaperNumberAndObjective(Long examId, String paperNumber, boolean objective) {
+        UpdateWrapper<MarkQuestion> updateWrapper = new UpdateWrapper<>();
+        updateWrapper.lambda().eq(MarkQuestion::getExamId, examId)
+                .eq(MarkQuestion::getPaperNumber, paperNumber)
+                .eq(MarkQuestion::getObjective, objective);
+        this.remove(updateWrapper);
+    }
 }

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

@@ -793,7 +793,7 @@ public class MarkServiceImpl implements MarkService {
         dto.getSubject().setAnswerUrl(StringUtils.isBlank(markPaper.getAnswerFilePath()) ? null
                 : teachcloudCommonService.filePreview(markPaper.getAnswerFilePath()));
         dto.getSubject().setPaperUrl(StringUtils.isBlank(markPaper.getPaperFilePath()) ? null
-                : teachcloudCommonService.filePreview(markPaper.getPaperFilePath()));
+                : JSON.toJSONString(teachcloudCommonService.filePreview(JSON.parseArray(markPaper.getPaperFilePath(), String.class))));
         BasicCourse basicCourse = basicCourseService.getById(markPaper.getCourseId());
         dto.getSubject().setCode(markPaper.getPaperNumber());
         dto.getSubject().setName(basicCourse != null ? basicCourse.getName() : null);

+ 36 - 27
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkStudentServiceImpl.java

@@ -561,13 +561,22 @@ public class MarkStudentServiceImpl extends ServiceImpl<MarkStudentMapper, MarkS
             if (studentPaper.getPaperIndex() == 1) {
                 // 根据识别结果更新考生属性
                 ScanPaperPage page = scanPaperPageService.findPaperIdAndIndex(paper.getId(), 1);
-                student.setOmrAbsent(page.getAbsent() != null && page.getAbsent().getResult());
-                student.setOmrBreach(page.getBreach() != null && page.getBreach().getResult());
-                student.setOmrAbsentChecked(false);
-                if (student.getOmrAbsent()) {
-                    student.setObjectiveScore(null);
-                    student.setObjectiveScoreList(null);
+                if (!omrEdit) {
+                    student.setOmrAbsent(page.getAbsent() != null && page.getAbsent().getResult());
+                    student.setOmrBreach(page.getBreach() != null && page.getBreach().getResult());
+                    student.setOmrAbsentChecked(false);
+                    student.setAbsent(false);
+                    student.setManualAbsent(false);
+                    if (student.getOmrAbsent()) {
+                        student.setObjectiveScore(null);
+                        student.setObjectiveScoreList(null);
+                    }
+                } else {
+                    student.setScanStatus(page.getAbsent() != null && page.getAbsent().getResult() ? ScanStatus.MANUAL_ABSENT : student.getScanStatus());
+                    student.setManualAbsent(ScanStatus.MANUAL_ABSENT.equals(student.getScanStatus()));
+                    student.setBreach(page.getBreach() != null && page.getBreach().getResult());
                 }
+
                 // student.setDevice(batchService.findByPaperId(paper.getId()).getDevice());
 
                 PaperTypeCheckStatus paperTypeCheckStatus = PaperTypeCheckStatus.NORMAL;
@@ -588,16 +597,18 @@ public class MarkStudentServiceImpl extends ServiceImpl<MarkStudentMapper, MarkS
                         // 未识别到卷型 (正常不会出现这种情况)
                         throw ExceptionResultEnum.ERROR.exception("卷型识别错误");
                     }
-                    if (paperType.length() > 1) {
-                        // 多卷型
-                        paperTypeCheckStatus = PaperTypeCheckStatus.WAITING;
-                    }
-                    if ("#".equals(paperType)) {
-                        // 没有识别到卷型
-                        paperTypeCheckStatus = PaperTypeCheckStatus.WAITING;
-                    }
                     student.setPaperType(paperType);
-                    student.setPaperTypeCheckStatus(paperTypeCheckStatus);
+                    if (!omrEdit) {
+                        if (paperType.length() > 1) {
+                            // 多卷型
+                            paperTypeCheckStatus = PaperTypeCheckStatus.WAITING;
+                        }
+                        if ("#".equals(paperType)) {
+                            // 没有识别到卷型
+                            paperTypeCheckStatus = PaperTypeCheckStatus.WAITING;
+                        }
+                        student.setPaperTypeCheckStatus(paperTypeCheckStatus);
+                    }
                 }
 
             }
@@ -622,24 +633,22 @@ public class MarkStudentServiceImpl extends ServiceImpl<MarkStudentMapper, MarkS
             student.setUpload(true);
             student.setIncomplete(paperCount != answerCard.getPaperCount());
             student.setScanStatus(ScanStatus.SCANNED);
-            student.setAbsent(false);
-            student.setManualAbsent(false);
             student.setMissScan(false);
             // 更新图片数量和图片地址
             updateStudentSheetInfo(student, studentPaperList);
         } else {
             student.setScanStatus(ScanStatus.UNEXIST);
         }
-        if (omrEdit) {
-            boolean absent = student.getOmrAbsent();
-            student.setAbsent(absent);
-            student.setBreach(student.getOmrBreach());
-            if (absent) {
-                // 缺考的缺考检查改为已处理
-                student.setOmrAbsentChecked(true);
-            }
-            student.setPaperTypeCheckStatus(PaperTypeCheckStatus.PROCESSED);
-        }
+//        if (omrEdit) {
+//            boolean absent = student.getOmrAbsent();
+//            student.setAbsent(absent);
+//            student.setBreach(student.getOmrBreach());
+//            if (absent) {
+//                // 缺考的缺考检查改为已处理
+//                student.setOmrAbsentChecked(true);
+//            }
+//            student.setPaperTypeCheckStatus(PaperTypeCheckStatus.PROCESSED);
+//        }
         // student.setUpdaterId(userId);
         // student.setUpdateTime(System.currentTimeMillis());
         this.saveOrUpdate(student);

+ 69 - 6
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/ScanAnswerCardServiceImpl.java

@@ -13,18 +13,18 @@ import com.qmth.teachcloud.common.bean.marking.scanAnswerCard.AnswerCard;
 import com.qmth.teachcloud.common.bean.marking.scanAnswerCard.AnswerCardPage;
 import com.qmth.teachcloud.common.bean.vo.FilePathVo;
 import com.qmth.teachcloud.common.contant.SystemConstant;
+import com.qmth.teachcloud.common.entity.MarkQuestion;
 import com.qmth.teachcloud.common.entity.SysUser;
 import com.qmth.teachcloud.common.enums.mark.MarkPaperStatus;
+import com.qmth.teachcloud.common.enums.scan.OmrField;
 import com.qmth.teachcloud.common.service.BasicRoleDataPermissionService;
 import com.qmth.teachcloud.common.service.FileUploadService;
 import com.qmth.teachcloud.common.service.TeachcloudCommonService;
-import com.qmth.teachcloud.common.util.HttpUtil;
 import com.qmth.teachcloud.common.util.ServletUtil;
 import com.qmth.teachcloud.mark.bean.UriVo;
-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.bean.answercard.*;
 import com.qmth.teachcloud.mark.entity.MarkPaper;
+import com.qmth.teachcloud.mark.entity.MarkQuestionAnswer;
 import com.qmth.teachcloud.mark.entity.ScanAnswerCard;
 import com.qmth.teachcloud.mark.enums.CardSource;
 import com.qmth.teachcloud.mark.mapper.ScanAnswerCardMapper;
@@ -41,6 +41,7 @@ import javax.annotation.Resource;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.stream.Collectors;
 
 /**
  * <p>
@@ -63,6 +64,10 @@ public class ScanAnswerCardServiceImpl extends ServiceImpl<ScanAnswerCardMapper,
     @Resource
     private MarkStudentService markStudentService;
     @Resource
+    private MarkQuestionService markQuestionService;
+    @Resource
+    private MarkQuestionAnswerService markQuestionAnswerService;
+    @Resource
     private BasicRoleDataPermissionService basicRoleDataPermissionService;
     @Resource
     private TeachcloudCommonService teachcloudCommonService;
@@ -150,7 +155,7 @@ public class ScanAnswerCardServiceImpl extends ServiceImpl<ScanAnswerCardMapper,
 //            if (!singlePage && domain.getPaperCount() * 2 != cardFile.getPages().size()) {
 //                throw new ParameterException("卡格式数量不一致");
 //            }
-////            // 提取裁切坐标
+//            // 提取裁切坐标
 //            sliceConfig = cardFile.getSliceConfig().toString();
 //        } catch (IOException e) {
 //            throw new ParameterException("文件解析失败", e);
@@ -167,9 +172,68 @@ public class ScanAnswerCardServiceImpl extends ServiceImpl<ScanAnswerCardMapper,
         card.setAdapteMd5(domain.getMd5());
         card.setAdapteUri(filePath);
         this.saveOrUpdate(card);
+
+        saveObjectiveStruct(domain.getExamId(), domain.getCoursePaperId(), domain.getFile());
         return card;
     }
 
+    /**
+     * 根据卡格式中的结构,更新客观题试卷结构
+     */
+    private void saveObjectiveStruct(Long examId, String coursePaperId, MultipartFile file) {
+        MarkPaper markPaper = markPaperService.getByExamIdAndCoursePaperId(examId, coursePaperId);
+        CardFile cardFile;
+        byte[] fileData;
+        String sliceConfig;
+        try {
+            fileData = file.getBytes();
+            // 解析卡格式文件
+            cardFile = parseCardFile(fileData);
+            List<MarkQuestion> markQuestions = new ArrayList<>();
+            List<MarkQuestionAnswer> markQuestionAnswers = new ArrayList<>();
+            int i = 1;
+            for (CardPageWrapper page : cardFile.getPages()) {
+                for (FillArea fillArea : page.getExchange().getFillArea().stream().filter(m -> OmrField.QUESTION.equals(m.getField())).collect(Collectors.toList())) {
+                    for (FillItem item : fillArea.getItems()) {
+                        MarkQuestion markQuestion = new MarkQuestion();
+                        markQuestion.setId(SystemConstant.getDbUuid());
+                        markQuestion.setExamId(examId);
+                        markQuestion.setPaperNumber(markPaper.getPaperNumber());
+                        markQuestion.setObjective(fillArea.isSingle());
+                        markQuestion.setMainNumber(item.getMainNumber());
+                        markQuestion.setSubNumber(item.getSubNumber());
+                        markQuestion.setMainTitle(fillArea.isSingle() ? item.getOptions().size() == 2 ? "判断题" : "单选题" : "多选题");
+                        markQuestion.setOptionCount(item.getOptions().size());
+                        markQuestion.setQuestionType(fillArea.isSingle() ? item.getOptions().size() == 2 ? 3 : 1 : 2);
+                        markQuestion.setPaperIndex(i / 2);
+                        markQuestion.setPageIndex(i % 2 == 1 ? 1 : 2);
+                        markQuestions.add(markQuestion);
+
+                        // 保存客观题数据
+                        for (String paperType : markPaper.getPaperTypeList()) {
+                            MarkQuestionAnswer markQuestionAnswer = new MarkQuestionAnswer(examId, markQuestion.getPaperNumber(), paperType, markQuestion.getMainNumber(), markQuestion.getSubNumber());
+                            markQuestionAnswers.add(markQuestionAnswer);
+                        }
+                    }
+                }
+                i++;
+            }
+
+            if (CollectionUtils.isNotEmpty(markQuestions)) {
+                // 删除
+                markQuestionService.deleteByExamIdAndPaperNumberAndObjective(examId, markPaper.getPaperNumber(), true);
+                markQuestionService.saveBatch(markQuestions);
+            }
+            if (CollectionUtils.isNotEmpty(markQuestionAnswers)) {
+                // 删除客观题标答
+                markQuestionAnswerService.deleteByExamIdAndPaperNumber(examId, markPaper.getPaperNumber());
+                markQuestionAnswerService.saveBatch(markQuestionAnswers);
+            }
+        } catch (IOException e) {
+            throw new ParameterException("文件解析失败", e);
+        }
+    }
+
     /**
      * 解析卡格式文件中的裁切图坐标,用于云阅卷同步
      *
@@ -318,5 +382,4 @@ public class ScanAnswerCardServiceImpl extends ServiceImpl<ScanAnswerCardMapper,
                 .eq(ScanAnswerCard::getSource, source);
         return this.list(queryWrapper);
     }
-
 }

+ 4 - 3
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/ScanOmrTaskServiceImpl.java

@@ -95,7 +95,8 @@ public class ScanOmrTaskServiceImpl extends ServiceImpl<ScanOmrTaskMapper, ScanO
         MarkStudent student = studentService.getById(studentId);
         // 所有客观题空白
         boolean allObjectiveBlank = isAllBlank(paperIds);
-        if (allObjectiveBlank) {
+        // 非缺考,空白卷需要进客观题检查(2024-11-11 add)
+        if ((student.getAbsent() || student.getManualAbsent() || student.getOmrAbsent()) && allObjectiveBlank) {
             return null;
         }
         List<OmrTaskDto> retList = new ArrayList<>();
@@ -374,8 +375,8 @@ public class ScanOmrTaskServiceImpl extends ServiceImpl<ScanOmrTaskMapper, ScanO
             }
             List<ScanPaperPage> pageList = pageService.listByPaperId(spe.getPaperId());
             for (ScanPaperPage pageEntity : pageList) {
-                if(pageEntity.getAbsent()==null ||
-                        (pageEntity.getAbsent()!=null && !pageEntity.getAbsent().getResult())){
+                if (pageEntity.getAbsent() == null ||
+                        (pageEntity.getAbsent() != null && !pageEntity.getAbsent().getResult())) {
                     return false;
                 }
                 for (int i = 0; pageEntity.getQuestion() != null && pageEntity.getQuestion().getResult() != null