xiaofei 8 mesiacov pred
rodič
commit
eedd0d38d4
28 zmenil súbory, kde vykonal 737 pridanie a 354 odobranie
  1. 2 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ExamTaskDetailService.java
  2. 4 4
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/GradePaperStructService.java
  3. 6 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamTaskDetailServiceImpl.java
  4. 8 8
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/GradePaperStructServiceImpl.java
  5. 13 11
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/service/impl/ImportLogicServiceImpl.java
  6. 21 0
      distributed-print-business/src/main/resources/db/log/xf.sql
  7. 17 18
      distributed-print/src/main/java/com/qmth/distributed/print/api/GradePaperStructController.java
  8. 12 7
      distributed-print/src/main/java/com/qmth/distributed/print/api/mark/MarkQuestionController.java
  9. 0 48
      teachcloud-common/src/main/java/com/qmth/teachcloud/common/bean/result/MarkQuestionResult.java
  10. 32 42
      teachcloud-common/src/main/java/com/qmth/teachcloud/common/entity/MarkQuestion.java
  11. 41 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/dto/mark/MarkQuestionAnswerVo.java
  12. 15 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/entity/MarkPaper.java
  13. 164 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/entity/MarkQuestionAnswer.java
  14. 20 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/mapper/MarkQuestionAnswerMapper.java
  15. 2 3
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/mapper/MarkQuestionMapper.java
  16. 4 3
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/params/MarkObjectiveQuestionParams.java
  17. 0 1
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/params/MarkQuestionParams.java
  18. 24 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/MarkQuestionAnswerService.java
  19. 42 13
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/MarkQuestionService.java
  20. 32 22
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkPaperServiceImpl.java
  21. 60 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkQuestionAnswerServiceImpl.java
  22. 99 53
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkQuestionServiceImpl.java
  23. 6 5
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkStudentServiceImpl.java
  24. 9 8
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/utils/ScoreCalculateUtil.java
  25. 43 0
      teachcloud-mark/src/main/resources/mapper/MarkQuestionAnswerMapper.xml
  26. 24 46
      teachcloud-mark/src/main/resources/mapper/MarkQuestionMapper.xml
  27. 1 1
      teachcloud-task/src/main/java/com/qmth/teachcloud/task/service/PrintFinishService.java
  28. 36 61
      teachcloud-task/src/main/java/com/qmth/teachcloud/task/service/impl/PrintFinishServiceImpl.java

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

@@ -70,4 +70,6 @@ public interface ExamTaskDetailService extends IService<ExamTaskDetail> {
     List<ExamTaskDetail> listByExamTaskId(Long examTaskId);
 
     void updateExposedExamIdById(Long examId, Long id);
+
+    ExamTaskDetail findByExamIdAndPaperNumberAndSerialNumber(Long examId, String paperNumber, Integer serialNumber);
 }

+ 4 - 4
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/GradePaperStructService.java

@@ -5,9 +5,9 @@ import com.qmth.distributed.print.business.bean.dto.open.PaperStructure;
 import com.qmth.distributed.print.business.bean.params.analyze.GradePaperStructParam;
 import com.qmth.distributed.print.business.bean.result.analyze.GradePaperStructResult;
 import com.qmth.distributed.print.business.entity.GradePaperStruct;
-import com.qmth.teachcloud.common.bean.result.MarkQuestionResult;
 import com.qmth.teachcloud.common.entity.MarkQuestion;
 import com.qmth.teachcloud.common.entity.SysUser;
+import com.qmth.teachcloud.mark.dto.mark.MarkQuestionAnswerVo;
 import org.springframework.web.multipart.MultipartFile;
 
 import java.io.IOException;
@@ -34,7 +34,7 @@ public interface GradePaperStructService extends IService<GradePaperStruct> {
      * @return 结果
      */
     List<GradePaperStructResult> findGradePaperStructureResultList(Long examId, String paperNumber, String paperType,
-            SysUser requestUser, List<MarkQuestionResult> markQuestionList);
+                                                                   SysUser requestUser, List<MarkQuestionAnswerVo> markQuestionList);
 
     /**
      * 批量保存分析试卷结构
@@ -55,7 +55,7 @@ public interface GradePaperStructService extends IService<GradePaperStruct> {
      * @param requestUser 请求用户
      */
     void importGradePaperStruct(MultipartFile file, Long examId, String paperNumber, String paperType, String paperName,
-            SysUser requestUser) throws IOException, NoSuchFieldException;
+                                SysUser requestUser) throws IOException, NoSuchFieldException;
 
     /**
      * 分析 - 试卷结构模板导出
@@ -66,7 +66,7 @@ public interface GradePaperStructService extends IService<GradePaperStruct> {
      * @param markQuestionList markQuestionList
      * @throws Exception 异常
      */
-    void exportGradePaperStructTemplate(Long examId, String paperNumber, String paperType, SysUser requestUser, List<MarkQuestionResult> markQuestionList) throws Exception;
+    void exportGradePaperStructTemplate(Long examId, String paperNumber, String paperType, SysUser requestUser, List<MarkQuestionAnswerVo> markQuestionList) throws Exception;
 
     List<PaperStructure> findBySchoolIdAndPaperNumberAndPaperType(Long schoolId, Long examId, String paperNumber, String paperType);
 

+ 6 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamTaskDetailServiceImpl.java

@@ -759,6 +759,12 @@ public class ExamTaskDetailServiceImpl extends ServiceImpl<ExamTaskDetailMapper,
         this.update(updateWrapper);
     }
 
+    @Override
+    public ExamTaskDetail findByExamIdAndPaperNumberAndSerialNumber(Long examId, String paperNumber, Integer serialNumber) {
+        List<ExamTaskDetail> examTaskDetailList = this.listByExamIdAndPaperNumber(examId, paperNumber);
+        return examTaskDetailList.stream().filter(m -> m.getSerialNumber() != null && m.getSerialNumber().equals(serialNumber)).findFirst().orElse(null);
+    }
+
     /**
      * 卷库校验
      *

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

@@ -14,7 +14,6 @@ import com.qmth.distributed.print.business.mapper.GradePaperStructMapper;
 import com.qmth.distributed.print.business.service.GradeBatchPaperService;
 import com.qmth.distributed.print.business.service.GradePaperStructService;
 import com.qmth.teachcloud.common.bean.marking.Question;
-import com.qmth.teachcloud.common.bean.result.MarkQuestionResult;
 import com.qmth.teachcloud.common.contant.SystemConstant;
 import com.qmth.teachcloud.common.entity.BasicCourse;
 import com.qmth.teachcloud.common.entity.MarkQuestion;
@@ -24,6 +23,7 @@ import com.qmth.teachcloud.common.enums.ObjectiveType;
 import com.qmth.teachcloud.common.service.BasicCourseService;
 import com.qmth.teachcloud.common.util.ExcelUtil;
 import com.qmth.teachcloud.common.util.ServletUtil;
+import com.qmth.teachcloud.mark.dto.mark.MarkQuestionAnswerVo;
 import com.qmth.teachcloud.mark.entity.MarkPaper;
 import com.qmth.teachcloud.mark.service.MarkPaperService;
 import org.apache.commons.collections4.CollectionUtils;
@@ -61,7 +61,7 @@ public class GradePaperStructServiceImpl extends ServiceImpl<GradePaperStructMap
     private MarkPaperService markPaperService;
 
     @Override
-    public List<GradePaperStructResult> findGradePaperStructureResultList(Long examId, String paperNumber, String paperType, SysUser requestUser, List<MarkQuestionResult> markQuestionList) {
+    public List<GradePaperStructResult> findGradePaperStructureResultList(Long examId, String paperNumber, String paperType, SysUser requestUser, List<MarkQuestionAnswerVo> markQuestionList) {
         Long schoolId = requestUser.getSchoolId();
         List<GradePaperStructResult> result = new ArrayList<>();
         // 先从分析试卷结构表取
@@ -160,7 +160,7 @@ public class GradePaperStructServiceImpl extends ServiceImpl<GradePaperStructMap
     @Transactional(rollbackFor = Exception.class)
     @Override
     public void importGradePaperStruct(MultipartFile file, Long examId, String paperNumber, String paperType, String paperName,
-            SysUser requestUser) throws IOException, NoSuchFieldException {
+                                       SysUser requestUser) throws IOException, NoSuchFieldException {
         if (Objects.isNull(file)) {
             throw ExceptionResultEnum.ERROR.exception("找不到附件");
         }
@@ -204,10 +204,10 @@ public class GradePaperStructServiceImpl extends ServiceImpl<GradePaperStructMap
     }
 
     @Override
-    public void exportGradePaperStructTemplate(Long examId, String paperNumber, String paperType, @NotNull SysUser requestUser, List<MarkQuestionResult> markQuestionList) throws Exception {
+    public void exportGradePaperStructTemplate(Long examId, String paperNumber, String paperType, @NotNull SysUser requestUser, List<MarkQuestionAnswerVo> markQuestionList) throws Exception {
 
         MarkPaper markPaper = markPaperService.getOne(
-                new QueryWrapper<MarkPaper>().lambda().eq(MarkPaper::getExamId,examId).eq(MarkPaper::getPaperNumber, paperNumber).eq(MarkPaper::getPaperType,paperType));
+                new QueryWrapper<MarkPaper>().lambda().eq(MarkPaper::getExamId, examId).eq(MarkPaper::getPaperNumber, paperNumber).eq(MarkPaper::getPaperType, paperType));
         if (Objects.isNull(markPaper)) {
             throw ExceptionResultEnum.ERROR.exception("没有找到试卷编号对应的试卷结构");
         }
@@ -242,7 +242,7 @@ public class GradePaperStructServiceImpl extends ServiceImpl<GradePaperStructMap
 
     @Override
     public List<PaperStructure> findBySchoolIdAndPaperNumberAndPaperType(Long schoolId, Long examId, String paperNumber,
-            String paperType) {
+                                                                         String paperType) {
         return this.baseMapper.findBySchoolIdAndPaperNumberAndPaperType(schoolId, examId, paperNumber, paperType);
     }
 
@@ -310,11 +310,11 @@ public class GradePaperStructServiceImpl extends ServiceImpl<GradePaperStructMap
         }).collect(Collectors.toList());
     }
 
-    private Map<ObjectiveType, List<Question>> parseExamCloudPaperStruct(List<MarkQuestionResult> markQuestionList) {
+    private Map<ObjectiveType, List<Question>> parseExamCloudPaperStruct(List<MarkQuestionAnswerVo> markQuestionList) {
         Map<ObjectiveType, List<Question>> result = new HashMap<>();
         List<Question> objList = new ArrayList<>();
         List<Question> subList = new ArrayList<>();
-        for (MarkQuestion markQuestion : markQuestionList) {
+        for (MarkQuestionAnswerVo markQuestion : markQuestionList) {
             boolean objective = markQuestion.getObjective();
             String mainTitle = markQuestion.getMainTitle();
             Integer mainNumber = markQuestion.getMainNumber();

+ 13 - 11
distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/service/impl/ImportLogicServiceImpl.java

@@ -159,26 +159,26 @@ public class ImportLogicServiceImpl implements ImportLogicService {
             // 校验excel内容
             basicExamStudentImport.getRequiredFieldList().forEach(m -> {
                 // 模式4必填字段校验
-                if(ExamModelEnum.MODEL4.equals(basicExam.getExamModel())){
-                    if(StringUtils.isBlank(basicExamStudentImport.getPaperNumber())){
+                if (ExamModelEnum.MODEL4.equals(basicExam.getExamModel())) {
+                    if (StringUtils.isBlank(basicExamStudentImport.getPaperNumber())) {
                         stringJoiner.add(RequiredFieldsEnum.PAPER_NUMBER.getName() + "必填");
                     }
-                    if(StringUtils.isBlank(basicExamStudentImport.getStudentCode())){
+                    if (StringUtils.isBlank(basicExamStudentImport.getStudentCode())) {
                         stringJoiner.add(RequiredFieldsEnum.STUDENT_CODE.getName() + "必填");
                     }
-                    if(StringUtils.isBlank(basicExamStudentImport.getStudentName())){
+                    if (StringUtils.isBlank(basicExamStudentImport.getStudentName())) {
                         stringJoiner.add(RequiredFieldsEnum.STUDENT_NAME.getName() + "必填");
                     }
-                    if(StringUtils.isBlank(basicExamStudentImport.getCourseCode())){
+                    if (StringUtils.isBlank(basicExamStudentImport.getCourseCode())) {
                         stringJoiner.add(RequiredFieldsEnum.COURSE_CODE.getName() + "必填");
                     }
-                    if(StringUtils.isBlank(basicExamStudentImport.getCourseName())){
+                    if (StringUtils.isBlank(basicExamStudentImport.getCourseName())) {
                         stringJoiner.add(RequiredFieldsEnum.COURSE_NAME.getName() + "必填");
                     }
-                    if(StringUtils.isBlank(basicExamStudentImport.getTeachingRoomName())){
+                    if (StringUtils.isBlank(basicExamStudentImport.getTeachingRoomName())) {
                         stringJoiner.add(RequiredFieldsEnum.TEACHING_ROOM_NAME.getName() + "必填");
                     }
-                    if(StringUtils.isBlank(basicExamStudent.getTeachClassName())){
+                    if (StringUtils.isBlank(basicExamStudent.getTeachClassName())) {
                         stringJoiner.add(RequiredFieldsEnum.TEACH_CLASS_NAME.getName() + "必填");
                     }
                 } else {
@@ -214,7 +214,7 @@ public class ImportLogicServiceImpl implements ImportLogicService {
 
                     // 反向更新examDate为标准日期格式,
                     for (CodeNameEnableDisabledValue codeNameEnableDisabledValue : basicExamStudentImport.getRequiredFieldList()) {
-                        if(codeNameEnableDisabledValue.getCode().equals(RequiredFieldsEnum.EXAM_DATE.getCode())){
+                        if (codeNameEnableDisabledValue.getCode().equals(RequiredFieldsEnum.EXAM_DATE.getCode())) {
                             codeNameEnableDisabledValue.setValue(String.valueOf(timeMap.get("dateStr")));
                         }
                     }
@@ -1025,10 +1025,12 @@ public class ImportLogicServiceImpl implements ImportLogicService {
                 markQuestion.setMainNumber(mainNumber);
                 markQuestion.setSubNumber(subNumber);
                 markQuestion.setMainTitle(mainTitle);
-                markQuestion.setAnswer(answer);
+                // todo 2024-10-16
+//                markQuestion.setAnswer(answer);
                 markQuestion.setOptionCount(optionCount);
                 markQuestion.setTotalScore(totalScore);
-                markQuestion.setObjectivePolicy(ObjectivePolicy.NONE);
+                // todo 2024-10-16
+//                markQuestion.setObjectivePolicy(ObjectivePolicy.NONE);
                 markQuestion.setQuestionType(questionType);
                 markQuestionList.add(markQuestion);
             }

+ 21 - 0
distributed-print-business/src/main/resources/db/log/xf.sql

@@ -34,3 +34,24 @@ ALTER TABLE `mark_paper_package` ADD COLUMN `serial_number` INT(1) NULL COMMENT
 ALTER TABLE `mark_student` ADD COLUMN `serial_number` INT(2) NULL COMMENT '备用卷序号' AFTER `course_paper_id`;
 ALTER TABLE `scan_answer_card` ADD COLUMN `serial_number` INT(2) NULL COMMENT '备用卷序号' AFTER `course_paper_id`;
 ALTER TABLE `mark_question` ADD COLUMN `serial_number` INT(2) NULL COMMENT '备用卷序号' AFTER `paper_number`;
+
+-- 2024-10-16
+ALTER TABLE `mark_question` DROP COLUMN `serial_number`;
+
+CREATE TABLE `mark_question_answer` (
+       `id` BIGINT(20) NOT NULL,
+       `exam_id` BIGINT(20) NULL COMMENT '考试ID',
+       `paper_number` VARCHAR(50) NULL COMMENT '试卷编号',
+       `paper_type` VARCHAR(10) NULL COMMENT '卷型',
+       `main_number` INT NULL COMMENT '大题号',
+       `sub_number` INT NULL COMMENT '小题号',
+       `answer` VARCHAR(16) NULL COMMENT '客观题标答',
+       `objective_policy` VARCHAR(16) NULL COMMENT '判分策略',
+       `objective_policy_score` DOUBLE NULL COMMENT '客观题判分策略计分(漏选给分)',
+       `create_id` BIGINT(20) NULL,
+       `create_time` BIGINT(20) NULL,
+       `update_id` BIGINT(20) NULL,
+       `update_time` BIGINT(20) NULL,
+       PRIMARY KEY (`id`))
+    COMMENT = '客观题信息';
+

+ 17 - 18
distributed-print/src/main/java/com/qmth/distributed/print/api/GradePaperStructController.java

@@ -5,7 +5,6 @@ import com.qmth.distributed.print.business.bean.params.analyze.GradePaperStructP
 import com.qmth.distributed.print.business.bean.result.analyze.GradePaperStructResult;
 import com.qmth.distributed.print.business.service.GradePaperStructService;
 import com.qmth.teachcloud.common.annotation.OperationLogDetail;
-import com.qmth.teachcloud.common.bean.result.MarkQuestionResult;
 import com.qmth.teachcloud.common.contant.SystemConstant;
 import com.qmth.teachcloud.common.entity.MarkQuestion;
 import com.qmth.teachcloud.common.entity.SysUser;
@@ -49,27 +48,27 @@ public class GradePaperStructController {
 
     @ApiOperation(value = "成绩分析试卷结构-查询")
     @RequestMapping(value = "/list", method = RequestMethod.POST)
-    @ApiResponses({ @ApiResponse(code = 200, message = "查询成功", response = GradePaperStructResult.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "查询成功", response = GradePaperStructResult.class)})
     public Result findGradePaperStructList(@ApiParam(value = "考试id", required = true) @RequestParam Long examId, @ApiParam(value = "试卷编号", required = true) @RequestParam String paperNumber,
-            @ApiParam(value = "试卷类型", required = true) @RequestParam String paperType) {
+                                           @ApiParam(value = "试卷类型", required = true) @RequestParam String paperType) {
 
         SysUser requestUser = (SysUser) ServletUtil.getRequestUser();
         if (SystemConstant.isOneNull(paperNumber, paperType)) {
             throw ExceptionResultEnum.ERROR.exception("试卷参数不完整");
         }
-        List<MarkQuestionResult> markQuestionList = markQuestionService.listDetailByExamIdAndPaperNumberAndPaperType(
-                examId, paperNumber, paperType, null);
+//        List<MarkQuestionResult> markQuestionList = markQuestionService.listDetailByExamIdAndPaperNumberAndPaperType(
+//                examId, paperNumber, paperType, null);
         return ResultUtil.ok(
                 gradePaperStructService.findGradePaperStructureResultList(examId, paperNumber, paperType, requestUser,
-                        markQuestionList));
+                        markQuestionService.listQuestionAnswerByExamIdAndPaperNumberAndPaperType(examId, paperNumber, paperType, null)));
     }
 
     @ApiOperation(value = "成绩分析试卷结构-新建试卷结构")
     @RequestMapping(value = "/save", method = RequestMethod.POST)
-    @ApiResponses({ @ApiResponse(code = 200, message = "更新成功", response = Result.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "更新成功", response = Result.class)})
     @OperationLogDetail(operationType = OperationTypeEnum.ADD)
     public Result saveGradePaperStructBatch(@Valid @RequestBody GradePaperStructParam gradePaperStructParam,
-            BindingResult bindingResult) {
+                                            BindingResult bindingResult) {
         if (bindingResult.hasErrors()) {
             return ResultUtil.error(bindingResult.getAllErrors().get(0).getDefaultMessage());
         }
@@ -80,11 +79,11 @@ public class GradePaperStructController {
 
     @ApiOperation(value = "成绩分析试卷结构-导入")
     @RequestMapping(value = "/import", method = RequestMethod.POST)
-    @ApiResponses({ @ApiResponse(code = 200, message = "{\"success\":true}", response = Result.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "{\"success\":true}", response = Result.class)})
     @OperationLogDetail(operationType = OperationTypeEnum.IMPORT)
     public Result gradePaperStructImport(@ApiParam(value = "上传文件", required = true) @RequestParam MultipartFile file, @ApiParam(value = "考试id", required = true) @RequestParam Long examId,
-            @ApiParam(value = "试卷编号", required = true) @RequestParam String paperNumber, @ApiParam(value = "试卷类型", required = true) @RequestParam String paperType,
-            @ApiParam(value = "试卷名称", required = true) @RequestParam String paperName) throws IOException, NoSuchFieldException {
+                                         @ApiParam(value = "试卷编号", required = true) @RequestParam String paperNumber, @ApiParam(value = "试卷类型", required = true) @RequestParam String paperType,
+                                         @ApiParam(value = "试卷名称", required = true) @RequestParam String paperName) throws IOException, NoSuchFieldException {
 
         SysUser requestUser = (SysUser) ServletUtil.getRequestUser();
         if (SystemConstant.isOneNull(file, examId, paperNumber, paperType, paperName)) {
@@ -96,28 +95,28 @@ public class GradePaperStructController {
 
     @ApiOperation(value = "成绩分析试卷结构-模板导出")
     @RequestMapping(value = "/export", method = RequestMethod.POST)
-    @ApiResponses({ @ApiResponse(code = 200, message = "{\"success\":true}", response = Result.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "{\"success\":true}", response = Result.class)})
     @OperationLogDetail(operationType = OperationTypeEnum.EXPORT)
     public Result gradePaperStructExport(@ApiParam(value = "考试id", required = true) @RequestParam Long examId, @ApiParam(value = "课程编号", required = true) @RequestParam String paperNumber,
-            @ApiParam(value = "课程名称", required = true) @RequestParam String paperType) throws Exception {
+                                         @ApiParam(value = "课程名称", required = true) @RequestParam String paperType) throws Exception {
 
         SysUser requestUser = (SysUser) ServletUtil.getRequestUser();
         if (SystemConstant.isOneNull(examId, paperNumber, paperType)) {
             throw ExceptionResultEnum.ERROR.exception("参数不完整");
         }
-        List<MarkQuestionResult> markQuestionList = markQuestionService.listDetailByExamIdAndPaperNumberAndPaperType(
-                examId, paperNumber, paperType, null);
+//        List<MarkQuestionResult> markQuestionList = markQuestionService.listDetailByExamIdAndPaperNumberAndPaperType(
+//                examId, paperNumber, paperType, null);
         gradePaperStructService.exportGradePaperStructTemplate(examId, paperNumber, paperType, requestUser,
-                markQuestionList);
+                markQuestionService.listQuestionAnswerByExamIdAndPaperNumberAndPaperType(examId, paperNumber, paperType, null));
         return ResultUtil.ok();
     }
 
     @ApiOperation(value = "成绩分析试卷结构-更新试卷机构")
     @RequestMapping(value = "/change_paper_structure", method = RequestMethod.POST)
-    @ApiResponses({ @ApiResponse(code = 200, message = "更新成功", response = Result.class) })
+    @ApiResponses({@ApiResponse(code = 200, message = "更新成功", response = Result.class)})
     @OperationLogDetail(operationType = OperationTypeEnum.UPDATE)
     public Result updateExamCloudPaperStruct(@ApiParam(value = "考试ID", required = true) @RequestParam Long examId, @ApiParam(value = "试卷编号", required = true) @RequestParam String paperNumber,
-            @ApiParam(value = "试卷类型") @RequestParam(required = false) String paperType) {
+                                             @ApiParam(value = "试卷类型") @RequestParam(required = false) String paperType) {
         if (SystemConstant.isOneNull(paperNumber)) {
             throw ExceptionResultEnum.ERROR.exception("缺少试卷编号");
         }

+ 12 - 7
distributed-print/src/main/java/com/qmth/distributed/print/api/mark/MarkQuestionController.java

@@ -17,8 +17,10 @@ import com.qmth.teachcloud.common.util.Result;
 import com.qmth.teachcloud.common.util.ResultUtil;
 import com.qmth.teachcloud.common.util.ServletUtil;
 import com.qmth.teachcloud.mark.dto.mark.setting.MarkQuestionDto;
+import com.qmth.teachcloud.mark.entity.MarkQuestionAnswer;
 import com.qmth.teachcloud.mark.params.MarkObjectiveQuestionParams;
 import com.qmth.teachcloud.mark.params.MarkQuestionParams;
+import com.qmth.teachcloud.mark.service.MarkQuestionAnswerService;
 import com.qmth.teachcloud.mark.service.MarkQuestionService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
@@ -51,6 +53,8 @@ public class MarkQuestionController extends BaseController {
     @Resource
     private MarkQuestionService markQuestionService;
     @Resource
+    private MarkQuestionAnswerService markQuestionAnswerService;
+    @Resource
     private ExamTaskDetailService examTaskDetailService;
     @Resource
     private ExamCardService examCardService;
@@ -62,13 +66,13 @@ public class MarkQuestionController extends BaseController {
     @RequestMapping(value = "/list", method = RequestMethod.POST)
     public Result list(@ApiParam(value = "考试ID", required = true) @RequestParam Long examId,
                        @ApiParam(value = "试卷编号", required = true) @RequestParam String paperNumber,
-                       @ApiParam(value = "试卷类型", required = true) @RequestParam String paperType) {
+                       @ApiParam(value = "备用卷", required = true) @RequestParam Integer serialNumber) {
         boolean canCreate = false;
-        ExamTaskDetail examTaskDetail = examTaskDetailService.findByExamIdAndCourseIdAndPaperNumber(examId, null, paperNumber);
+        ExamTaskDetail examTaskDetail = examTaskDetailService.findByExamIdAndPaperNumberAndSerialNumber(examId, paperNumber, serialNumber);
         if (examTaskDetail == null) {
             canCreate = true;
         } else {
-            List<PaperInfoVo> paperInfoVoList = ExamTaskUtil.parsePaperAttachmentPath(examTaskDetail.getPaperAttachmentIds(), paperType);
+            List<PaperInfoVo> paperInfoVoList = ExamTaskUtil.parsePaperAttachmentPath(examTaskDetail.getPaperAttachmentIds());
             PaperInfoVo paperInfoVo = paperInfoVoList.get(0);
             if (paperInfoVo.getCardId() != null) {
                 ExamCard examCard = examCardService.getById(paperInfoVo.getCardId());
@@ -79,7 +83,7 @@ public class MarkQuestionController extends BaseController {
                 }
             }
         }
-        MarkQuestionDto markQuestionDto = markQuestionService.pageQuestionsByExamIdAndPaperNumber(examId, paperNumber, paperType);
+        MarkQuestionDto markQuestionDto = markQuestionService.pageQuestionsByExamIdAndPaperNumberAndSerialNumberAndPaperType(examId, paperNumber, examTaskDetail.getSerialNumber(), examTaskDetail.getPaperType());
         markQuestionDto.setCanCreate(canCreate);
         return ResultUtil.ok(markQuestionDto);
     }
@@ -102,9 +106,10 @@ public class MarkQuestionController extends BaseController {
     @ApiOperation(value = "客观题标答查询")
     @RequestMapping(value = "/objective/list", method = RequestMethod.POST)
     public Result listObjective(@ApiParam(value = "考试ID", required = true) @RequestParam Long examId,
-                                @ApiParam(value = "试卷编号", required = true) @RequestParam String paperNumber) {
-        List<MarkQuestion> markQuestionList = markQuestionService.listQuestionByExamIdAndPaperNumberAndGroupNumber(examId, paperNumber, null, true);
-        return ResultUtil.ok(markQuestionList);
+                                @ApiParam(value = "试卷编号", required = true) @RequestParam String paperNumber,
+                                @ApiParam(value = "试卷类型", required = true) @RequestParam String paperType) {
+        List<MarkQuestionAnswer> markQuestionAnswerList = markQuestionAnswerService.listByExamIdAndPaperNumberAndPaperType(examId, paperNumber, paperType);
+        return ResultUtil.ok(markQuestionAnswerList);
     }
 
     /**

+ 0 - 48
teachcloud-common/src/main/java/com/qmth/teachcloud/common/bean/result/MarkQuestionResult.java

@@ -1,48 +0,0 @@
-package com.qmth.teachcloud.common.bean.result;
-
-import com.fasterxml.jackson.databind.annotation.JsonSerialize;
-import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
-import com.qmth.teachcloud.common.entity.MarkQuestion;
-import io.swagger.annotations.ApiModelProperty;
-
-/**
- * @Description: 试卷结构详情(带课程信息)
- * @Author: CaoZixuan
- * @Date: 2024-07-11
- */
-public class MarkQuestionResult extends MarkQuestion {
-
-    @JsonSerialize(using = ToStringSerializer.class)
-    @ApiModelProperty(value = "课程id")
-    private Long courseId;
-
-    @ApiModelProperty(value = "课程编号")
-    private String courseCode;
-
-    @ApiModelProperty(value = "课程名称")
-    private String courseName;
-
-    public Long getCourseId() {
-        return courseId;
-    }
-
-    public void setCourseId(Long courseId) {
-        this.courseId = courseId;
-    }
-
-    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;
-    }
-}

+ 32 - 42
teachcloud-common/src/main/java/com/qmth/teachcloud/common/entity/MarkQuestion.java

@@ -35,8 +35,6 @@ public class MarkQuestion extends BaseEntity implements Serializable {
 
     @ApiModelProperty(value = "试卷类型")
     private String paperNumber;
-    @ApiModelProperty(value = "备用卷序号")
-    private Integer serialNumber;
     @ApiModelProperty(value = "试卷卷型")
     private String paperType;
 
@@ -56,9 +54,9 @@ public class MarkQuestion extends BaseEntity implements Serializable {
     @ApiModelProperty(value = "大题名称")
     private String mainTitle;
 
-    @ApiModelProperty(value = "正确答案")
-    @TableField(updateStrategy = FieldStrategy.IGNORED)
-    private String answer;
+//    @ApiModelProperty(value = "正确答案")
+//    @TableField(updateStrategy = FieldStrategy.IGNORED)
+//    private String answer;
     @ApiModelProperty(value = "客观题答案数量")
     private Integer optionCount;
 
@@ -69,13 +67,13 @@ public class MarkQuestion extends BaseEntity implements Serializable {
     @TableField(updateStrategy = FieldStrategy.IGNORED)
     private Double intervalScore;
 
-    @ApiModelProperty(value = "客观题判分策略")
-    @TableField(updateStrategy = FieldStrategy.IGNORED)
-    private ObjectivePolicy objectivePolicy;
+//    @ApiModelProperty(value = "客观题判分策略")
+//    @TableField(updateStrategy = FieldStrategy.IGNORED)
+//    private ObjectivePolicy objectivePolicy;
 
-    @ApiModelProperty(value = "客观题判分策略计分")
-    @TableField(updateStrategy = FieldStrategy.IGNORED)
-    private Double objectivePolicyScore;
+//    @ApiModelProperty(value = "客观题判分策略计分")
+//    @TableField(updateStrategy = FieldStrategy.IGNORED)
+//    private Double objectivePolicyScore;
 
     @ApiModelProperty(value = "题型")
     private Integer questionType;
@@ -101,14 +99,6 @@ public class MarkQuestion extends BaseEntity implements Serializable {
         this.paperNumber = paperNumber;
     }
 
-    public Integer getSerialNumber() {
-        return serialNumber;
-    }
-
-    public void setSerialNumber(Integer serialNumber) {
-        this.serialNumber = serialNumber;
-    }
-
     public String getPaperType() {
         return paperType;
     }
@@ -153,13 +143,13 @@ public class MarkQuestion extends BaseEntity implements Serializable {
     public void setMainTitle(String mainTitle) {
         this.mainTitle = mainTitle;
     }
-    public String getAnswer() {
-        return answer;
-    }
-
-    public void setAnswer(String answer) {
-        this.answer = answer;
-    }
+//    public String getAnswer() {
+//        return answer;
+//    }
+//
+//    public void setAnswer(String answer) {
+//        this.answer = answer;
+//    }
 
     public Integer getOptionCount() {
         return optionCount;
@@ -183,13 +173,13 @@ public class MarkQuestion extends BaseEntity implements Serializable {
     public void setIntervalScore(Double intervalScore) {
         this.intervalScore = intervalScore;
     }
-    public ObjectivePolicy getObjectivePolicy() {
-        return objectivePolicy;
-    }
-
-    public void setObjectivePolicy(ObjectivePolicy objectivePolicy) {
-        this.objectivePolicy = objectivePolicy;
-    }
+//    public ObjectivePolicy getObjectivePolicy() {
+//        return objectivePolicy;
+//    }
+//
+//    public void setObjectivePolicy(ObjectivePolicy objectivePolicy) {
+//        this.objectivePolicy = objectivePolicy;
+//    }
     public Integer getQuestionType() {
         return questionType;
     }
@@ -234,22 +224,22 @@ public class MarkQuestion extends BaseEntity implements Serializable {
             ", mainNumber=" + mainNumber +
             ", subNumber=" + subNumber +
             ", mainTitle=" + mainTitle +
-            ", answer=" + answer +
+//            ", answer=" + answer +
             ", totalScore=" + totalScore +
             ", intervalScore=" + intervalScore +
-            ", objectivePolicy=" + objectivePolicy +
+//            ", objectivePolicy=" + objectivePolicy +
             ", questionType=" + questionType +
             ", name=" + name +
         "}";
     }
 
-    public Double getObjectivePolicyScore() {
-        return objectivePolicyScore;
-    }
-
-    public void setObjectivePolicyScore(Double objectivePolicyScore) {
-        this.objectivePolicyScore = objectivePolicyScore;
-    }
+//    public Double getObjectivePolicyScore() {
+//        return objectivePolicyScore;
+//    }
+//
+//    public void setObjectivePolicyScore(Double objectivePolicyScore) {
+//        this.objectivePolicyScore = objectivePolicyScore;
+//    }
 
     @Override
     public boolean equals(Object o) {

+ 41 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/dto/mark/MarkQuestionAnswerVo.java

@@ -0,0 +1,41 @@
+package com.qmth.teachcloud.mark.dto.mark;
+
+import com.qmth.teachcloud.common.entity.MarkQuestion;
+import com.qmth.teachcloud.common.enums.ObjectivePolicy;
+import io.swagger.annotations.ApiModelProperty;
+
+public class MarkQuestionAnswerVo extends MarkQuestion {
+
+    @ApiModelProperty(value = "客观题标答")
+    private String answer;
+
+    @ApiModelProperty(value = "客观题判分策略")
+    private ObjectivePolicy objectivePolicy;
+
+    @ApiModelProperty(value = "客观题判分策略计分")
+    private Double objectivePolicyScore;
+
+    public String getAnswer() {
+        return answer;
+    }
+
+    public void setAnswer(String answer) {
+        this.answer = answer;
+    }
+
+    public ObjectivePolicy getObjectivePolicy() {
+        return objectivePolicy;
+    }
+
+    public void setObjectivePolicy(ObjectivePolicy objectivePolicy) {
+        this.objectivePolicy = objectivePolicy;
+    }
+
+    public Double getObjectivePolicyScore() {
+        return objectivePolicyScore;
+    }
+
+    public void setObjectivePolicyScore(Double objectivePolicyScore) {
+        this.objectivePolicyScore = objectivePolicyScore;
+    }
+}

+ 15 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/entity/MarkPaper.java

@@ -11,8 +11,12 @@ import com.qmth.teachcloud.common.enums.mark.MarkMode;
 import com.qmth.teachcloud.common.enums.mark.MarkPaperStatus;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
+import org.apache.commons.lang3.StringUtils;
 
 import java.io.Serializable;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
 
 /**
  * <p>
@@ -133,6 +137,9 @@ public class MarkPaper implements Serializable {
     @ApiModelProperty(value = "试卷类型")
     private String paperType;
 
+    @TableField(exist = false)
+    private List<String> paperTypeList;
+
     public MarkPaper() {
     }
 
@@ -453,6 +460,14 @@ public class MarkPaper implements Serializable {
         this.paperType = paperType;
     }
 
+    public List<String> getPaperTypeList() {
+        return StringUtils.isBlank(this.paperType) ? Collections.emptyList() : Arrays.asList(this.paperType.split(","));
+    }
+
+    public void setPaperTypeList(List<String> paperTypeList) {
+        this.paperTypeList = paperTypeList;
+    }
+
     @Override
     public String toString() {
         return "MarkPaper{" +

+ 164 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/entity/MarkQuestionAnswer.java

@@ -0,0 +1,164 @@
+package com.qmth.teachcloud.mark.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+
+import java.io.Serializable;
+
+import com.qmth.teachcloud.common.base.BaseEntity;
+import com.qmth.teachcloud.common.contant.SystemConstant;
+import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
+import com.qmth.teachcloud.common.enums.ObjectivePolicy;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * <p>
+ * 客观题信息
+ * </p>
+ *
+ * @author xf
+ * @since 2024-10-16
+ */
+@TableName("mark_question_answer")
+@ApiModel(value = "MarkQuestionAnswer对象", description = "客观题信息")
+public class MarkQuestionAnswer extends BaseEntity implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "考试ID")
+    private Long examId;
+
+    @ApiModelProperty(value = "试卷编号")
+    private String paperNumber;
+
+    @ApiModelProperty(value = "卷型")
+    private String paperType;
+
+    @ApiModelProperty(value = "大题号")
+    private Integer mainNumber;
+
+    @ApiModelProperty(value = "小题号")
+    private Integer subNumber;
+
+    @ApiModelProperty(value = "客观题标答")
+    @TableField(updateStrategy = FieldStrategy.IGNORED)
+    private String answer;
+
+    @ApiModelProperty(value = "客观题判分策略")
+    @TableField(updateStrategy = FieldStrategy.IGNORED)
+    private ObjectivePolicy objectivePolicy;
+
+    @ApiModelProperty(value = "客观题判分策略计分")
+    @TableField(updateStrategy = FieldStrategy.IGNORED)
+    private Double objectivePolicyScore;
+
+    @TableField(exist = false)
+    private String mainTitle;
+    @TableField(exist = false)
+    private Double totalScore;
+    public MarkQuestionAnswer() {
+    }
+
+    public MarkQuestionAnswer(Long examId, String paperNumber, String paperType, Integer mainNumber, Integer subNumber) {
+        super.setId(SystemConstant.getDbUuid());
+        this.examId = examId;
+        this.paperNumber = paperNumber;
+        this.paperType = paperType;
+        this.mainNumber = mainNumber;
+        this.subNumber = subNumber;
+    }
+
+    public Long getExamId() {
+        return examId;
+    }
+
+    public void setExamId(Long examId) {
+        this.examId = examId;
+    }
+
+    public String getPaperNumber() {
+        return paperNumber;
+    }
+
+    public void setPaperNumber(String paperNumber) {
+        this.paperNumber = paperNumber;
+    }
+
+    public String getPaperType() {
+        return paperType;
+    }
+
+    public void setPaperType(String paperType) {
+        this.paperType = paperType;
+    }
+
+    public Integer getMainNumber() {
+        return mainNumber;
+    }
+
+    public void setMainNumber(Integer mainNumber) {
+        this.mainNumber = mainNumber;
+    }
+
+    public Integer getSubNumber() {
+        return subNumber;
+    }
+
+    public void setSubNumber(Integer subNumber) {
+        this.subNumber = subNumber;
+    }
+
+    public String getAnswer() {
+        return answer;
+    }
+
+    public void setAnswer(String answer) {
+        this.answer = answer;
+    }
+
+    public ObjectivePolicy getObjectivePolicy() {
+        return objectivePolicy;
+    }
+
+    public void setObjectivePolicy(ObjectivePolicy objectivePolicy) {
+        this.objectivePolicy = objectivePolicy;
+    }
+
+    public Double getObjectivePolicyScore() {
+        return objectivePolicyScore;
+    }
+
+    public void setObjectivePolicyScore(Double objectivePolicyScore) {
+        this.objectivePolicyScore = objectivePolicyScore;
+    }
+
+    public String getMainTitle() {
+        return mainTitle;
+    }
+
+    public void setMainTitle(String mainTitle) {
+        this.mainTitle = mainTitle;
+    }
+
+    public Double getTotalScore() {
+        return totalScore;
+    }
+
+    public void setTotalScore(Double totalScore) {
+        this.totalScore = totalScore;
+    }
+
+    @Override
+    public String toString() {
+        return "MarkQuestionAnswer{" +
+                ", examId=" + examId +
+                ", paperNumber=" + paperNumber +
+                ", paperType=" + paperType +
+                ", mainNumber=" + mainNumber +
+                ", subNumber=" + subNumber +
+                ", answer=" + answer +
+                ", objectivePolicy=" + objectivePolicy +
+                ", objectivePolicyScore=" + objectivePolicyScore +
+                "}";
+    }
+}

+ 20 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/mapper/MarkQuestionAnswerMapper.java

@@ -0,0 +1,20 @@
+package com.qmth.teachcloud.mark.mapper;
+
+import com.qmth.teachcloud.mark.entity.MarkQuestionAnswer;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 客观题信息 Mapper 接口
+ * </p>
+ *
+ * @author xf
+ * @since 2024-10-16
+ */
+public interface MarkQuestionAnswerMapper extends BaseMapper<MarkQuestionAnswer> {
+
+    List<MarkQuestionAnswer> listByExamIdAndPaperNumberAndPaperType(@Param("examId") Long examId, @Param("paperNumber") String paperNumber, @Param("paperType") String paperType);
+}

+ 2 - 3
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/mapper/MarkQuestionMapper.java

@@ -1,8 +1,8 @@
 package com.qmth.teachcloud.mark.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.qmth.teachcloud.common.bean.result.MarkQuestionResult;
 import com.qmth.teachcloud.common.entity.MarkQuestion;
+import com.qmth.teachcloud.mark.dto.mark.MarkQuestionAnswerVo;
 import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
@@ -21,6 +21,5 @@ public interface MarkQuestionMapper extends BaseMapper<MarkQuestion> {
 
     Double sumTotalScoreByGroupNumber(@Param("examId") Long examId, @Param("paperNumber") String paperNumber, @Param("groupNumber") Integer groupNumber);
 
-    List<MarkQuestionResult> listByExamIdAndPaperNumberAndPaperType(@Param("examId") Long examId, @Param("paperNumber") String paperNumber, @Param("paperType") String paperType,
-            @Param("objective") Boolean objective);
+    List<MarkQuestionAnswerVo> listQuestionAnswerByExamIdAndPaperNumberAndPaperType(@Param("examId") Long examId, @Param("paperNumber") String paperNumber, @Param("paperType") String paperType, @Param("objective") boolean objective);
 }

+ 4 - 3
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/params/MarkObjectiveQuestionParams.java

@@ -1,6 +1,7 @@
 package com.qmth.teachcloud.mark.params;
 
 import com.qmth.teachcloud.common.entity.MarkQuestion;
+import com.qmth.teachcloud.mark.entity.MarkQuestionAnswer;
 
 import java.io.Serializable;
 import java.util.List;
@@ -12,7 +13,7 @@ public class MarkObjectiveQuestionParams implements Serializable {
 
     private Long examId;
     private String paperNumber;
-    private List<MarkQuestion> objectiveInfo;
+    private List<MarkQuestionAnswer> objectiveInfo;
 
     public Long getExamId() {
         return examId;
@@ -30,11 +31,11 @@ public class MarkObjectiveQuestionParams implements Serializable {
         this.paperNumber = paperNumber;
     }
 
-    public List<MarkQuestion> getObjectiveInfo() {
+    public List<MarkQuestionAnswer> getObjectiveInfo() {
         return objectiveInfo;
     }
 
-    public void setObjectiveInfo(List<MarkQuestion> objectiveInfo) {
+    public void setObjectiveInfo(List<MarkQuestionAnswer> objectiveInfo) {
         this.objectiveInfo = objectiveInfo;
     }
 }

+ 0 - 1
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/params/MarkQuestionParams.java

@@ -11,7 +11,6 @@ import java.util.List;
 public class MarkQuestionParams implements Serializable {
 
     private Long examId;
-
     private String paperNumber;
 
     private List<MarkQuestion> questions;

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

@@ -0,0 +1,24 @@
+package com.qmth.teachcloud.mark.service;
+
+import com.qmth.teachcloud.mark.entity.MarkQuestionAnswer;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 客观题信息 服务类
+ * </p>
+ *
+ * @author xf
+ * @since 2024-10-16
+ */
+public interface MarkQuestionAnswerService extends IService<MarkQuestionAnswer> {
+
+    void deleteByExamIdAndPaperNumberAndMainNumberAndSubNumber(Long examId, String paperNumber, Integer mainNumber, Integer subNumber);
+    void resetObjectivePolicyByExamIdAndPaperNumberAndMainNumberAndSubNumber(Long examId, String paperNumber, Integer mainNumber, Integer subNumber);
+
+    List<MarkQuestionAnswer> listByExamIdAndPaperNumberAndPaperType(Long examId, String paperNumber, String paperType);
+
+    int countByExamIdAndPaperNumber(Long examId, String paperNumber);
+}

+ 42 - 13
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/MarkQuestionService.java

@@ -1,19 +1,15 @@
 package com.qmth.teachcloud.mark.service;
 
-import java.util.List;
-
-import javax.servlet.http.HttpServletResponse;
-
-import com.qmth.teachcloud.common.bean.result.MarkQuestionResult;
-import com.qmth.teachcloud.mark.bean.cardJson.DescriptionCourse;
-import com.qmth.teachcloud.mark.bean.vo.parseCard.Struct;
-import org.springframework.web.multipart.MultipartFile;
-
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.qmth.teachcloud.common.entity.MarkQuestion;
+import com.qmth.teachcloud.mark.dto.mark.MarkQuestionAnswerVo;
 import com.qmth.teachcloud.mark.dto.mark.setting.MarkQuestionDto;
 import com.qmth.teachcloud.mark.params.MarkObjectiveQuestionParams;
 import com.qmth.teachcloud.mark.params.MarkQuestionParams;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
 
 /**
  * <p>
@@ -34,8 +30,41 @@ public interface MarkQuestionService extends IService<MarkQuestion> {
      */
     String assembleGroupQuestionsByExamIdAndPaperNumberAndNumber(Long examId, String paperNumber, Integer groupNumber);
 
+    /**
+     * 查询指定卷型完整试卷结构
+     * @param examId
+     * @param paperNumber
+     * @return
+     */
+    List<MarkQuestion> listQuestionByExamIdAndPaperNumber(Long examId, String paperNumber);
+    /**
+     * 查询指定卷型完整试卷结构
+     * @param examId
+     * @param paperNumber
+     * @param paperType
+     * @return
+     */
     List<MarkQuestion> listQuestionByExamIdAndPaperNumberAndPaperType(Long examId, String paperNumber, String paperType);
-    List<MarkQuestion> listQuestionByExamIdAndPaperNumberAndSerialNumber(Long examId, String paperNumber, Integer serialNumber);
+    List<MarkQuestion> listQuestionByExamIdAndPaperNumberAndPaperType(Long examId, String paperNumber, String paperType, Boolean objective);
+
+    /**
+     * 查询主观题结构
+     * @param examId
+     * @param paperNumber
+     * @param serialNumber
+     * @return
+     */
+    List<MarkQuestion> listQuestionByExamIdAndPaperNumberAndSerialNumberAndObjectiveFalse(Long examId, String paperNumber, Integer serialNumber);
+
+    /**
+     * 查询指定卷型客观题结构
+     * @param examId
+     * @param paperNumber
+     * @param serialNumber
+     * @param paperType
+     * @return
+     */
+    List<MarkQuestion> listQuestionByExamIdAndPaperNumberAndSerialNumberAndPaperTypeAndObjectiveTrue(Long examId, String paperNumber, Integer serialNumber, String paperType);
 
     void saveQuestions(MarkQuestionParams markQuestionParams);
 
@@ -72,7 +101,7 @@ public interface MarkQuestionService extends IService<MarkQuestion> {
 
     List<MarkQuestion> listByExamIdAndPaperNumberAndPaperIndexAndPageIndex(Long examId, String paperNumber, Integer paperIndex, Integer pageIndex, boolean isObjective);
 
-    MarkQuestionDto pageQuestionsByExamIdAndPaperNumber(Long examId, String paperNumber, String paperType);
+    MarkQuestionDto pageQuestionsByExamIdAndPaperNumberAndSerialNumberAndPaperType(Long examId, String paperNumber, Integer serialNumber, String paperType);
 
     void updateGroupNumberByExamIdAndPaperNumberAndGroupNumber(Integer newGroupNumber, Long examId, String paperNumber,
             Integer groupNumber);
@@ -81,8 +110,6 @@ public interface MarkQuestionService extends IService<MarkQuestion> {
 
     List<MarkQuestion> listByExamIdAndPaperNumberAndPaperType(Long examId, String paperNumber, String paperType, Boolean objective);
 
-    List<MarkQuestionResult> listDetailByExamIdAndPaperNumberAndPaperType(Long examId, String paperNumber, String paperType, Boolean objective);
-
     void deleteByExamIdAndPaperNumber(Long examId, String paperNumber);
 
     /**
@@ -93,4 +120,6 @@ public interface MarkQuestionService extends IService<MarkQuestion> {
      * @param paperType   试卷类型
      */
     void updateMarkPaperScore(Long examId, String paperNumber, String paperType);
+
+    List<MarkQuestionAnswerVo> listQuestionAnswerByExamIdAndPaperNumberAndPaperType(Long examId, String paperNumber, String paperType, Boolean objective);
 }

+ 32 - 22
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkPaperServiceImpl.java

@@ -44,13 +44,11 @@ import com.qmth.teachcloud.mark.bean.document.ArchivePaperQuery;
 import com.qmth.teachcloud.mark.bean.document.ArchivePaperVo;
 import com.qmth.teachcloud.mark.bean.vo.parseCard.Struct;
 import com.qmth.teachcloud.mark.dto.ArchiveScoreExportDto;
+import com.qmth.teachcloud.mark.dto.mark.MarkQuestionAnswerVo;
 import com.qmth.teachcloud.mark.dto.mark.score.CheckScoreListDto;
 import com.qmth.teachcloud.mark.dto.mark.score.MarkPaperPackageDto;
 import com.qmth.teachcloud.mark.dto.mark.score.SettingDto;
-import com.qmth.teachcloud.mark.entity.MarkPaper;
-import com.qmth.teachcloud.mark.entity.MarkStudent;
-import com.qmth.teachcloud.mark.entity.ScanAnswerCard;
-import com.qmth.teachcloud.mark.entity.ScanPackage;
+import com.qmth.teachcloud.mark.entity.*;
 import com.qmth.teachcloud.mark.enums.CardSource;
 import com.qmth.teachcloud.mark.enums.OmrTaskStatus;
 import com.qmth.teachcloud.mark.mapper.MarkPaperMapper;
@@ -104,6 +102,8 @@ public class MarkPaperServiceImpl extends ServiceImpl<MarkPaperMapper, MarkPaper
     @Resource
     private MarkQuestionService markQuestionService;
     @Resource
+    private MarkQuestionAnswerService markQuestionAnswerService;
+    @Resource
     private MarkStudentService markStudentService;
     @Resource
     private MarkUserGroupService markUserGroupService;
@@ -245,10 +245,13 @@ public class MarkPaperServiceImpl extends ServiceImpl<MarkPaperMapper, MarkPaper
             if (MarkPaperStatus.FINISH.equals(status)) {
                 BasicCourse basicCourse = basicCourseService.getById(markPaper.getCourseId());
                 String courseInfo = String.format("%s[%s],试卷编号%s,", basicCourse.getName(), basicCourse.getCode(), markPaper.getPaperNumber());
-                // 主观题是否全部分组
-                List<MarkQuestion> markQuestionObjectiveList = markQuestionService.listQuestionByExamIdAndPaperNumberAndGroupNumber(examId, paperNumber, null, true);
-                if (CollectionUtils.isNotEmpty(markQuestionObjectiveList)) {
-                    if (markQuestionObjectiveList.stream().filter(m -> StringUtils.isBlank(m.getAnswer())).count() > 0) {
+                // 客观题标答是否全部设置
+                List<MarkQuestionAnswerVo> list = new ArrayList<>();
+                for (String paperType : markPaper.getPaperTypeList()) {
+                    list.addAll(markQuestionService.listQuestionAnswerByExamIdAndPaperNumberAndPaperType(examId, paperNumber, paperType, true));
+                }
+                if (CollectionUtils.isNotEmpty(list)) {
+                    if (list.stream().filter(m -> StringUtils.isBlank(m.getAnswer())).count() > 0) {
                         stringJoiner.add(courseInfo + "客观题标答未设置,无法结束评卷");
                         continue;
                     }
@@ -327,17 +330,17 @@ public class MarkPaperServiceImpl extends ServiceImpl<MarkPaperMapper, MarkPaper
         Objects.requireNonNull(markPaper, "未找到评卷信息");
         BasicCourse basicCourse = basicCourseService.getById(markPaper.getCourseId());
         String courseInfo = String.format("%s[%s],试卷编号%s,", basicCourse.getName(), basicCourse.getCode(), markPaper.getPaperNumber());
-//        if (Objects.nonNull(markPaper.getStatus()) && markPaper.getStatus() != MarkPaperStatus.FINISH) {
-//            throw ExceptionResultEnum.ERROR.exception(courseInfo + "评卷任务未完成,请完成评卷任务并检查成绩后再导出");
-//        }
-        // 主观题是否全部分组
-        List<MarkQuestion> markQuestionObjectiveList = markQuestionService.listQuestionByExamIdAndPaperNumberAndGroupNumber(examId, paperNumber, null, true);
-        if (CollectionUtils.isNotEmpty(markQuestionObjectiveList)) {
-            if (markQuestionObjectiveList.stream().filter(m -> StringUtils.isBlank(m.getAnswer())).count() > 0) {
-                throw ExceptionResultEnum.ERROR.exception(courseInfo + "客观题标答未设置,无法结束评卷");
+        // 客观题标答是否全部设置
+        for (String paperType : markPaper.getPaperTypeList()) {
+            List<MarkQuestionAnswerVo> markQuestionObjectiveList = markQuestionService.listQuestionAnswerByExamIdAndPaperNumberAndPaperType(examId, paperNumber, paperType, true);
+            if (CollectionUtils.isNotEmpty(markQuestionObjectiveList)) {
+                if (markQuestionObjectiveList.stream().filter(m -> StringUtils.isBlank(m.getAnswer())).count() > 0) {
+                    throw ExceptionResultEnum.ERROR.exception(courseInfo + "客观题标答未设置,无法结束评卷");
+                }
             }
         }
 
+
         // 主观题是否全部分组
         List<MarkQuestion> markQuestionSubjectiveList = markQuestionService.listQuestionByExamIdAndPaperNumberAndGroupNumber(examId, paperNumber, null, false);
         // 没有主观题,不校验考生评卷
@@ -662,12 +665,12 @@ public class MarkPaperServiceImpl extends ServiceImpl<MarkPaperMapper, MarkPaper
                     markQuestionService.deleteByExamIdAndPaperNumber(examId, markPaper.getPaperNumber());
                     // 保存试卷结构
                     List<MarkQuestion> markQuestions = new ArrayList<>();
+                    List<MarkQuestionAnswer> markQuestionAnswers = new ArrayList<>();
                     for (Struct struct : structList) {
                         MarkQuestion markQuestion = new MarkQuestion();
                         markQuestion.setId(SystemConstant.getDbUuid());
                         markQuestion.setExamId(examId);
                         markQuestion.setPaperNumber(markPaper.getPaperNumber());
-                        markQuestion.setPaperType(markPaper.getPaperType());
                         markQuestion.setObjective(struct.getObjective());
                         markQuestion.setMainNumber(struct.getMainNumber());
                         markQuestion.setSubNumber(struct.getSubNumber());
@@ -676,11 +679,6 @@ public class MarkPaperServiceImpl extends ServiceImpl<MarkPaperMapper, MarkPaper
                         markQuestion.setQuestionType(struct.getType());
                         markQuestion.setPaperIndex(struct.getPaperIndex());
                         markQuestion.setPageIndex(struct.getPageIndex());
-                        if (StringUtils.isNotBlank(struct.getAnswer())) {
-                            // 客观题有标答时,给分策略默认为全对给分
-                            markQuestion.setAnswer(struct.getAnswer());
-                            markQuestion.setObjectivePolicy(ObjectivePolicy.NONE);
-                        }
                         if (struct.getScore() != null) {
                             markQuestion.setTotalScore(struct.getScore());
                             // 间隔分(整数默认1,小数默认0.5)
@@ -689,8 +687,20 @@ public class MarkPaperServiceImpl extends ServiceImpl<MarkPaperMapper, MarkPaper
                             }
                         }
                         markQuestions.add(markQuestion);
+
+                        // 保存客观题数据
+                        for (String paperType : markPaper.getPaperTypeList()) {
+                            MarkQuestionAnswer markQuestionAnswer = new MarkQuestionAnswer(examId, markPaper.getPaperNumber(), paperType, struct.getMainNumber(), struct.getSubNumber());
+                            if (StringUtils.isNotBlank(struct.getAnswer())) {
+                                // 客观题有标答时,给分策略默认为全对给分
+                                markQuestionAnswer.setAnswer(struct.getAnswer());
+                                markQuestionAnswer.setObjectivePolicy(ObjectivePolicy.NONE);
+                            }
+                            markQuestionAnswers.add(markQuestionAnswer);
+                        }
                     }
                     markQuestionService.saveBatch(markQuestions);
+                    markQuestionAnswerService.saveBatch(markQuestionAnswers);
                     // 删除卡格式
                     scanAnswerCardService.deleteByExamIdAndPaperNumber(examId, markPaper.getPaperNumber());
                     // 保存

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

@@ -0,0 +1,60 @@
+package com.qmth.teachcloud.mark.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.qmth.teachcloud.mark.entity.MarkQuestionAnswer;
+import com.qmth.teachcloud.mark.mapper.MarkQuestionAnswerMapper;
+import com.qmth.teachcloud.mark.service.MarkQuestionAnswerService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.qmth.teachcloud.mark.service.MarkQuestionService;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 客观题信息 服务实现类
+ * </p>
+ *
+ * @author xf
+ * @since 2024-10-16
+ */
+@Service
+public class MarkQuestionAnswerServiceImpl extends ServiceImpl<MarkQuestionAnswerMapper, MarkQuestionAnswer> implements MarkQuestionAnswerService {
+
+    @Override
+    public void deleteByExamIdAndPaperNumberAndMainNumberAndSubNumber(Long examId, String paperNumber, Integer mainNumber, Integer subNumber) {
+        UpdateWrapper<MarkQuestionAnswer> updateWrapper = new UpdateWrapper<>();
+        updateWrapper.lambda().eq(MarkQuestionAnswer::getExamId, examId)
+                .eq(MarkQuestionAnswer::getPaperNumber, paperNumber)
+                .eq(MarkQuestionAnswer::getMainNumber, mainNumber)
+                .eq(MarkQuestionAnswer::getSubNumber, subNumber);
+        this.remove(updateWrapper);
+    }
+
+    @Override
+    public void resetObjectivePolicyByExamIdAndPaperNumberAndMainNumberAndSubNumber(Long examId, String paperNumber, Integer mainNumber, Integer subNumber) {
+        UpdateWrapper<MarkQuestionAnswer> updateWrapper = new UpdateWrapper<>();
+        updateWrapper.lambda().set(MarkQuestionAnswer::getAnswer, null)
+                .set(MarkQuestionAnswer::getObjectivePolicy, null)
+                .set(MarkQuestionAnswer::getObjectivePolicyScore, null)
+                .eq(MarkQuestionAnswer::getExamId, examId)
+                .eq(MarkQuestionAnswer::getPaperNumber, paperNumber)
+                .eq(MarkQuestionAnswer::getMainNumber, mainNumber)
+                .eq(MarkQuestionAnswer::getSubNumber, subNumber);
+        this.update(updateWrapper);
+    }
+
+    @Override
+    public List<MarkQuestionAnswer> listByExamIdAndPaperNumberAndPaperType(Long examId, String paperNumber, String paperType) {
+        return this.baseMapper.listByExamIdAndPaperNumberAndPaperType(examId, paperNumber, paperType);
+    }
+
+    @Override
+    public int countByExamIdAndPaperNumber(Long examId, String paperNumber) {
+        QueryWrapper<MarkQuestionAnswer> queryWrapper = new QueryWrapper<>();
+        queryWrapper.lambda().eq(MarkQuestionAnswer::getExamId, examId)
+                .eq(MarkQuestionAnswer::getPaperNumber, paperNumber);
+        return this.count(queryWrapper);
+    }
+}

+ 99 - 53
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkQuestionServiceImpl.java

@@ -1,23 +1,5 @@
 package com.qmth.teachcloud.mark.service.impl;
 
-import java.util.*;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-import javax.annotation.Resource;
-import javax.servlet.http.HttpServletResponse;
-
-import com.qmth.teachcloud.common.bean.result.MarkQuestionResult;
-import com.qmth.teachcloud.mark.bean.cardJson.DescriptionCourse;
-import com.qmth.teachcloud.mark.bean.vo.parseCard.Struct;
-import com.qmth.teachcloud.mark.service.*;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.collections4.MapUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-import org.springframework.web.multipart.MultipartFile;
-
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
@@ -33,11 +15,26 @@ import com.qmth.teachcloud.common.util.ConvertUtil;
 import com.qmth.teachcloud.common.util.ExcelUtil;
 import com.qmth.teachcloud.common.util.FileStoreUtil;
 import com.qmth.teachcloud.common.util.ServletUtil;
+import com.qmth.teachcloud.mark.dto.mark.MarkQuestionAnswerVo;
 import com.qmth.teachcloud.mark.dto.mark.setting.MarkQuestionDto;
 import com.qmth.teachcloud.mark.entity.MarkPaper;
+import com.qmth.teachcloud.mark.entity.MarkQuestionAnswer;
 import com.qmth.teachcloud.mark.mapper.MarkQuestionMapper;
 import com.qmth.teachcloud.mark.params.MarkObjectiveQuestionParams;
 import com.qmth.teachcloud.mark.params.MarkQuestionParams;
+import com.qmth.teachcloud.mark.service.*;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.MapUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
+import java.util.*;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 /**
  * <p>
@@ -57,6 +54,8 @@ public class MarkQuestionServiceImpl extends ServiceImpl<MarkQuestionMapper, Mar
     @Resource
     private MarkGroupService markGroupService;
     @Resource
+    private MarkQuestionAnswerService markQuestionAnswerService;
+    @Resource
     private MarkService markService;
     @Resource
     private FileStoreUtil fileStoreUtil;
@@ -66,14 +65,45 @@ public class MarkQuestionServiceImpl extends ServiceImpl<MarkQuestionMapper, Mar
         return this.baseMapper.assembleQuestionsByExamIdAndPaperNumberAndNumber(examId, paperNumber, groupNumber);
     }
 
+    @Override
+    public List<MarkQuestion> listQuestionByExamIdAndPaperNumber(Long examId, String paperNumber) {
+        QueryWrapper<MarkQuestion> queryWrapper = new QueryWrapper<>();
+        LambdaQueryWrapper<MarkQuestion> lambdaQueryWrapper = queryWrapper.lambda();
+        lambdaQueryWrapper.eq(MarkQuestion::getExamId, examId)
+                .eq(MarkQuestion::getPaperNumber, paperNumber);
+        lambdaQueryWrapper.orderByAsc(MarkQuestion::getMainNumber)
+                .orderByAsc(MarkQuestion::getSubNumber);
+        return this.list(queryWrapper);
+    }
+
     @Override
     public List<MarkQuestion> listQuestionByExamIdAndPaperNumberAndPaperType(Long examId, String paperNumber, String paperType) {
+        QueryWrapper<MarkQuestion> queryWrapper = new QueryWrapper<>();
+        LambdaQueryWrapper<MarkQuestion> lambdaQueryWrapper = queryWrapper.lambda();
+        lambdaQueryWrapper.eq(MarkQuestion::getExamId, examId)
+                .eq(MarkQuestion::getPaperNumber, paperNumber)
+                .and(m -> m.isNull(MarkQuestion::getPaperType).or().eq(MarkQuestion::getPaperType, paperType));
+        lambdaQueryWrapper.orderByAsc(MarkQuestion::getMainNumber)
+                .orderByAsc(MarkQuestion::getSubNumber);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<MarkQuestion> listQuestionByExamIdAndPaperNumberAndPaperType(Long examId, String paperNumber, String paperType, Boolean objective) {
+        if (objective == null) {
+            throw ExceptionResultEnum.ERROR.exception("objective参数必传");
+        }
         QueryWrapper<MarkQuestion> queryWrapper = new QueryWrapper<>();
         LambdaQueryWrapper<MarkQuestion> lambdaQueryWrapper = queryWrapper.lambda();
         lambdaQueryWrapper.eq(MarkQuestion::getExamId, examId)
                 .eq(MarkQuestion::getPaperNumber, paperNumber);
-        if (StringUtils.isNotBlank(paperType)) {
+        if (objective) {
+            if (StringUtils.isBlank(paperType)) {
+                throw ExceptionResultEnum.ERROR.exception("查询客观题时,卷型必传");
+            }
             lambdaQueryWrapper.eq(MarkQuestion::getPaperType, paperType);
+        } else {
+            lambdaQueryWrapper.isNull(MarkQuestion::getPaperType);
         }
         lambdaQueryWrapper.orderByAsc(MarkQuestion::getMainNumber)
                 .orderByAsc(MarkQuestion::getSubNumber);
@@ -81,12 +111,25 @@ public class MarkQuestionServiceImpl extends ServiceImpl<MarkQuestionMapper, Mar
     }
 
     @Override
-    public List<MarkQuestion> listQuestionByExamIdAndPaperNumberAndSerialNumber(Long examId, String paperNumber, Integer serialNumber) {
+    public List<MarkQuestion> listQuestionByExamIdAndPaperNumberAndSerialNumberAndObjectiveFalse(Long examId, String paperNumber, Integer serialNumber) {
         QueryWrapper<MarkQuestion> queryWrapper = new QueryWrapper<>();
         LambdaQueryWrapper<MarkQuestion> lambdaQueryWrapper = queryWrapper.lambda();
         lambdaQueryWrapper.eq(MarkQuestion::getExamId, examId)
                 .eq(MarkQuestion::getPaperNumber, paperNumber)
-            .eq(MarkQuestion::getSerialNumber, serialNumber);
+                .eq(MarkQuestion::getObjective, false);
+        lambdaQueryWrapper.orderByAsc(MarkQuestion::getMainNumber)
+                .orderByAsc(MarkQuestion::getSubNumber);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<MarkQuestion> listQuestionByExamIdAndPaperNumberAndSerialNumberAndPaperTypeAndObjectiveTrue(Long examId, String paperNumber, Integer serialNumber, String paperType) {
+        QueryWrapper<MarkQuestion> queryWrapper = new QueryWrapper<>();
+        LambdaQueryWrapper<MarkQuestion> lambdaQueryWrapper = queryWrapper.lambda();
+        lambdaQueryWrapper.eq(MarkQuestion::getExamId, examId)
+                .eq(MarkQuestion::getPaperNumber, paperNumber)
+                .eq(MarkQuestion::getPaperType, paperType)
+                .eq(MarkQuestion::getObjective, true);
         lambdaQueryWrapper.orderByAsc(MarkQuestion::getMainNumber)
                 .orderByAsc(MarkQuestion::getSubNumber);
         return this.list(queryWrapper);
@@ -113,7 +156,7 @@ public class MarkQuestionServiceImpl extends ServiceImpl<MarkQuestionMapper, Mar
         }
 
         // 查询已有结构信息
-        List<MarkQuestion> markQuestionList = this.listQuestionByExamIdAndPaperNumberAndPaperType(examId, paperNumber, null);
+        List<MarkQuestion> markQuestionList = this.listQuestionByExamIdAndPaperNumber(examId, paperNumber);
         if (CollectionUtils.isEmpty(markQuestionList)) {
             for (MarkQuestion question : questions) {
                 if (question.getTotalScore() <= 0) {
@@ -163,19 +206,15 @@ public class MarkQuestionServiceImpl extends ServiceImpl<MarkQuestionMapper, Mar
                         // 客观题变主观题
                         if (markQuestion.getObjective() && !question.getObjective()) {
                             // 清除判分策略
-                            markQuestion.setObjectivePolicy(null);
-                            markQuestion.setObjectivePolicyScore(null);
-                            markQuestion.setAnswer(null);
                             markQuestion.setOptionCount(0);
+                            markQuestionAnswerService.deleteByExamIdAndPaperNumberAndMainNumberAndSubNumber(examId, paperNumber, markQuestion.getMainNumber(), markQuestion.getSubNumber());
                         }
                         // 客观题
                         if (question.getObjective()) {
                             markQuestion.setOptionCount(question.getOptionCount());
                             if (!markQuestion.getQuestionType().equals(question.getQuestionType())) {
                                 // 清除判分策略
-                                markQuestion.setObjectivePolicy(null);
-                                markQuestion.setObjectivePolicyScore(null);
-                                markQuestion.setAnswer(null);
+                                markQuestionAnswerService.resetObjectivePolicyByExamIdAndPaperNumberAndMainNumberAndSubNumber(examId, paperNumber, markQuestion.getMainNumber(), markQuestion.getSubNumber());
                             }
                         }
                         // 大题号
@@ -212,6 +251,10 @@ public class MarkQuestionServiceImpl extends ServiceImpl<MarkQuestionMapper, Mar
             if (CollectionUtils.isNotEmpty(markQuestionList)) {
                 List<Long> deleteIds = markQuestionList.stream().map(MarkQuestion::getId).collect(Collectors.toList());
                 this.removeByIds(deleteIds);
+
+                markQuestionList.stream().filter(m -> m.getObjective()).forEach(m -> {
+                    markQuestionAnswerService.deleteByExamIdAndPaperNumberAndMainNumberAndSubNumber(examId, paperNumber, m.getMainNumber(), m.getSubNumber());
+                });
             }
             this.saveOrUpdateBatch(saveOrUpdateList);
         }
@@ -277,7 +320,8 @@ public class MarkQuestionServiceImpl extends ServiceImpl<MarkQuestionMapper, Mar
             dto.setMainNumber(String.valueOf(e.getMainNumber()));
             dto.setSubNumber(String.valueOf(e.getSubNumber()));
             dto.setMainTitle(e.getMainTitle());
-            dto.setAnswer(e.getAnswer());
+            // todo 2024-10-16
+//            dto.setAnswer(e.getAnswer());
             return Stream.of(dto);
         }).collect(Collectors.toList());
 
@@ -326,7 +370,8 @@ public class MarkQuestionServiceImpl extends ServiceImpl<MarkQuestionMapper, Mar
                 questionNumberSet.add(key);
                 if (markQuestionMap.containsKey(key)) {
                     MarkQuestion markQuestion = markQuestionMap.get(key);
-                    markQuestion.setAnswer(exAnswer);
+                    // todo 2024-10-16
+//                    markQuestion.setAnswer(exAnswer);
                     willEditList.add(markQuestion);
                     String mainTitle = markQuestion.getMainTitle();
                     if (!Objects.equals(exMainTitle, mainTitle)) {
@@ -403,28 +448,29 @@ public class MarkQuestionServiceImpl extends ServiceImpl<MarkQuestionMapper, Mar
     @Transactional
     @Override
     public void saveObjectiveQuestions(MarkObjectiveQuestionParams markObjectiveQuestionParams) {
-        for (MarkQuestion question : markObjectiveQuestionParams.getObjectiveInfo()) {
-            if (StringUtils.isBlank(question.getAnswer())) {
+        for (MarkQuestionAnswer answer : markObjectiveQuestionParams.getObjectiveInfo()) {
+            if (StringUtils.isBlank(answer.getAnswer())) {
                 throw ExceptionResultEnum.ERROR.exception("答案不能为空");
             }
-            if (question.getObjectivePolicy() != null && question.getObjectivePolicy().equals(ObjectivePolicy.LEAK)) {
-                if (question.getObjectivePolicyScore() == null) {
+            if (answer.getObjectivePolicy() != null && answer.getObjectivePolicy().equals(ObjectivePolicy.LEAK)) {
+                if (answer.getObjectivePolicyScore() == null) {
                     throw ExceptionResultEnum.ERROR.exception("漏选给分不能没有计分规则");
                 }
-                if (question.getObjectivePolicyScore() > (question.getTotalScore() / question.getAnswer().length())) {
+                if (answer.getObjectivePolicyScore() > (answer.getTotalScore() / answer.getAnswer().length())) {
                     throw ExceptionResultEnum.ERROR.exception("漏选给分计分规则有误");
                 }
             }
-            UpdateWrapper<MarkQuestion> updateWrapper = new UpdateWrapper<>();
-            updateWrapper.lambda().set(MarkQuestion::getAnswer, question.getAnswer());
-            if (question.getObjectivePolicy() != null) {
-                updateWrapper.lambda().set(MarkQuestion::getObjectivePolicy, question.getObjectivePolicy());
+            UpdateWrapper<MarkQuestionAnswer> updateWrapper = new UpdateWrapper<>();
+            updateWrapper.lambda().set(MarkQuestionAnswer::getAnswer, answer.getAnswer())
+                    .set(MarkQuestionAnswer::getUpdateTime, System.currentTimeMillis());
+            if (answer.getObjectivePolicy() != null) {
+                updateWrapper.lambda().set(MarkQuestionAnswer::getObjectivePolicy, answer.getObjectivePolicy());
             }
-            if (question.getObjectivePolicyScore() != null) {
-                updateWrapper.lambda().set(MarkQuestion::getObjectivePolicyScore, question.getObjectivePolicyScore());
+            if (answer.getObjectivePolicyScore() != null) {
+                updateWrapper.lambda().set(MarkQuestionAnswer::getObjectivePolicyScore, answer.getObjectivePolicyScore());
             }
-            updateWrapper.lambda().eq(MarkQuestion::getId, question.getId());
-            this.update(updateWrapper);
+            updateWrapper.lambda().eq(MarkQuestionAnswer::getId, answer.getId());
+            markQuestionAnswerService.update(updateWrapper);
         }
     }
 
@@ -480,13 +526,13 @@ public class MarkQuestionServiceImpl extends ServiceImpl<MarkQuestionMapper, Mar
     }
 
     @Override
-    public MarkQuestionDto pageQuestionsByExamIdAndPaperNumber(Long examId, String paperNumber, String paperType) {
+    public MarkQuestionDto pageQuestionsByExamIdAndPaperNumberAndSerialNumberAndPaperType(Long examId, String paperNumber, Integer serialNumber, String paperType) {
         MarkQuestionDto markQuestionDto = new MarkQuestionDto();
-        MarkPaper markPaper = markPaperService.getByExamIdAndPaperNumber(examId, paperNumber);
-        List<MarkQuestion> markQuestionList = this.listQuestionByExamIdAndPaperNumberAndPaperType(examId, paperNumber, null);
+        MarkPaper markPaper = markPaperService.getByExamIdAndPaperNumberAndSerialNumber(examId, paperNumber, serialNumber);
+        // 试卷结构,默认只取A卷
+        List<MarkQuestion> markQuestionList = this.listQuestionByExamIdAndPaperNumberAndPaperType(examId, paperNumber, SystemConstant.DEFAULT_PAPER_TYPE_A);
         markQuestionDto.setQuestionSubmit(markPaper.getQuestionStatus());
-        long objectiveCount = markQuestionList.stream().filter(m -> m.getObjective() && StringUtils.isNotBlank(m.getAnswer()) && m.getUpdateTime() != null).count();
-        markQuestionDto.setObjectiveSubmit(objectiveCount > 0);
+        markQuestionDto.setObjectiveSubmit(markQuestionAnswerService.countByExamIdAndPaperNumber(examId, paperNumber) > 0);
         markQuestionDto.setQuestions(markQuestionList);
         return markQuestionDto;
     }
@@ -528,11 +574,6 @@ public class MarkQuestionServiceImpl extends ServiceImpl<MarkQuestionMapper, Mar
         return this.list(queryWrapper);
     }
 
-    @Override
-    public List<MarkQuestionResult> listDetailByExamIdAndPaperNumberAndPaperType(Long examId, String paperNumber, String paperType, Boolean objective) {
-        return this.baseMapper.listByExamIdAndPaperNumberAndPaperType(examId, paperNumber, paperType, objective);
-    }
-
     @Override
     public void deleteByExamIdAndPaperNumber(Long examId, String paperNumber) {
         UpdateWrapper<MarkQuestion> updateWrapper = new UpdateWrapper<>();
@@ -558,4 +599,9 @@ public class MarkQuestionServiceImpl extends ServiceImpl<MarkQuestionMapper, Mar
                 .eq(MarkPaper::getPaperNumber, paperNumber);
         markPaperService.update(updateWrapper);
     }
+
+    @Override
+    public List<MarkQuestionAnswerVo> listQuestionAnswerByExamIdAndPaperNumberAndPaperType(Long examId, String paperNumber, String paperType, Boolean objective) {
+        return this.baseMapper.listQuestionAnswerByExamIdAndPaperNumberAndPaperType(examId, paperNumber, paperType, objective);
+    }
 }

+ 6 - 5
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkStudentServiceImpl.java

@@ -49,6 +49,7 @@ import com.qmth.teachcloud.mark.bean.student.StudentQuery;
 import com.qmth.teachcloud.mark.bean.student.StudentVo;
 import com.qmth.teachcloud.mark.dto.ScanOmrTaskStatusDto;
 import com.qmth.teachcloud.mark.dto.UnexistStudentDto;
+import com.qmth.teachcloud.mark.dto.mark.MarkQuestionAnswerVo;
 import com.qmth.teachcloud.mark.dto.mark.MarkStudentVo;
 import com.qmth.teachcloud.mark.dto.mark.ScoreInfo;
 import com.qmth.teachcloud.mark.dto.mark.ScoreItem;
@@ -730,8 +731,8 @@ public class MarkStudentServiceImpl extends ServiceImpl<MarkStudentMapper, MarkS
             studentObjectiveDetailDto.setAbsent(markStudent.getAbsent());
             studentObjectiveDetailDto.setSheetUrls(this.buildSheetUrls(studentId));
 
-            List<MarkQuestion> questions = markQuestionService.listQuestionByExamIdAndPaperNumberAndGroupNumber(
-                    markStudent.getExamId(), markStudent.getPaperNumber(), null, true);
+            List<MarkQuestionAnswerVo> questions = markQuestionService.listQuestionAnswerByExamIdAndPaperNumberAndPaperType(
+                    markStudent.getExamId(), markStudent.getPaperNumber(), markStudent.getPaperType(), true);
             List<String> answers = markStudent.getAnswerList();
             List<String> answerScores = markStudent.getAnswerScoreList();
             int questionCount = questions.size();
@@ -743,7 +744,7 @@ public class MarkStudentServiceImpl extends ServiceImpl<MarkStudentMapper, MarkS
             // 已设置客观题
             int maxCount = Math.max(questionCount, answerCount);
             for (int i = 0; i < maxCount; i++) {
-                MarkQuestion q = questionCount > i ? questions.get(i) : null;
+                MarkQuestionAnswerVo q = questionCount > i ? questions.get(i) : null;
                 String answer = answerCount > i ? answers.get(i) : "#";
                 String answerScore = answerScoreCount > i ? answerScores.get(i) : "0";
                 StudentObjectiveAnswerDto studentObjectiveAnswerDto = new StudentObjectiveAnswerDto();
@@ -865,8 +866,8 @@ public class MarkStudentServiceImpl extends ServiceImpl<MarkStudentMapper, MarkS
         // 缺考状态不统分(人工指定缺考、识别缺考)
         if (!ScanStatus.MANUAL_ABSENT.equals(student.getScanStatus()) && !student.getAbsent() && !student.getOmrAbsent()) {
             ScoreCalculateUtil util = ScoreCalculateUtil.instance(student);
-            ScoreInfo info = util.calculate(markQuestionService.listQuestionByExamIdAndPaperNumberAndGroupNumber(
-                    student.getExamId(), student.getPaperNumber(), null, true), null);
+            ScoreInfo info = util.calculate(markQuestionService.listQuestionAnswerByExamIdAndPaperNumberAndPaperType(
+                    student.getExamId(), student.getPaperNumber(), student.getPaperType(), true), null);
             student.setObjectiveScore(info.getObjectiveScore());
             student.setScoreList(info.getScoreList(), true);
             this.updateObjectiveScoreAndScoreList(student);

+ 9 - 8
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/utils/ScoreCalculateUtil.java

@@ -3,6 +3,7 @@ package com.qmth.teachcloud.mark.utils;
 import java.util.LinkedList;
 import java.util.List;
 
+import com.qmth.teachcloud.mark.dto.mark.MarkQuestionAnswerVo;
 import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -23,7 +24,7 @@ public class ScoreCalculateUtil {
         this.student = student;
     }
 
-    public ScoreInfo calculate(List<MarkQuestion> oList, List<MarkQuestion> sList) {
+    public ScoreInfo calculate(List<MarkQuestionAnswerVo> oList, List<MarkQuestion> sList) {
         // log.debug("start calculate, examId=" + student.getExamId() +
         // ", examNumber=" + student.getExamNumber());
 
@@ -37,7 +38,7 @@ public class ScoreCalculateUtil {
         return info;
     }
 
-    private void calculateObjective(List<MarkQuestion> questionList, ScoreInfo scoreInfo) {
+    private void calculateObjective(List<MarkQuestionAnswerVo> questionList, ScoreInfo scoreInfo) {
         // log.debug("start calculate objective score");
         List<String> answerList = student.getAnswerList();
         // Map<String, Integer> config = exam.getObjectiveBlockMap();
@@ -53,7 +54,7 @@ public class ScoreCalculateUtil {
 
         int index = -1;
         int lastMainNumber = 0;
-        for (MarkQuestion question : questionList) {
+        for (MarkQuestionAnswerVo question : questionList) {
             if (StringUtils.isBlank(question.getAnswer())) {
                 continue;
             }
@@ -154,10 +155,10 @@ public class ScoreCalculateUtil {
         // q.setTotalScore(3d);
         // oList.add(q);
 
-        ScoreInfo info = util.calculate(oList, null);
-        System.out.println(info.getObjectiveScore());
-        for (ScoreItem item : info.getScoreList()) {
-            System.out.println(item.getTitle() + ": " + item.toString());
-        }
+//        ScoreInfo info = util.calculate(oList, null);
+//        System.out.println(info.getObjectiveScore());
+//        for (ScoreItem item : info.getScoreList()) {
+//            System.out.println(item.getTitle() + ": " + item.toString());
+//        }
     }
 }

+ 43 - 0
teachcloud-mark/src/main/resources/mapper/MarkQuestionAnswerMapper.xml

@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.qmth.teachcloud.mark.mapper.MarkQuestionAnswerMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.qmth.teachcloud.mark.entity.MarkQuestionAnswer">
+        <id column="id" property="id" />
+        <result column="exam_id" property="examId" />
+        <result column="paper_number" property="paperNumber" />
+        <result column="paper_type" property="paperType" />
+        <result column="main_number" property="mainNumber" />
+        <result column="sub_number" property="subNumber" />
+        <result column="answer" property="answer" />
+        <result column="objective_policy" property="objectivePolicy" />
+        <result column="create_id" property="createId" />
+        <result column="create_time" property="createTime" />
+        <result column="update_id" property="updateId" />
+        <result column="update_time" property="updateTime" />
+    </resultMap>
+    <select id="listByExamIdAndPaperNumberAndPaperType"
+            resultType="com.qmth.teachcloud.mark.entity.MarkQuestionAnswer">
+        SELECT
+            mqa.*, mq.main_title, mq.total_score
+        FROM
+            (SELECT
+                 *
+             FROM
+                 mark_question
+             WHERE
+                 exam_id = #{examId} AND paper_number = #{paperNumber}
+               AND objective = TRUE) mq
+                LEFT JOIN
+            (SELECT
+                 *
+             FROM
+                 mark_question_answer
+             WHERE
+                 exam_id = #{examId} AND paper_number = #{paperNumber}
+               AND paper_type = #{paperType}) mqa ON mq.main_number = mqa.main_number
+                AND mq.sub_number = mqa.sub_number
+    </select>
+
+</mapper>

+ 24 - 46
teachcloud-mark/src/main/resources/mapper/MarkQuestionMapper.xml

@@ -41,55 +41,33 @@
           AND q.paper_number = #{paperNumber}
           AND q.group_number = #{groupNumber}
     </select>
-    <select id="listByExamIdAndPaperNumberAndPaperType"
-            resultType="com.qmth.teachcloud.common.bean.result.MarkQuestionResult">
+    <select id="listQuestionAnswerByExamIdAndPaperNumberAndPaperType"
+            resultType="com.qmth.teachcloud.mark.dto.mark.MarkQuestionAnswerVo">
         SELECT
-            mq.id AS id,
-            mq.exam_id AS examId,
-            mq.paper_number AS paperNumber,
-            mq.paper_type AS paperType,
-            mq.objective AS objective,
-            mq.group_number AS groupNumber,
-            mq.main_number AS mainNumber,
-            mq.sub_number AS subNumber,
-            mq.main_title AS mainTitle,
-            mq.answer AS answer,
-            mq.total_score AS totalScore,
-            mq.option_count AS optionCount,
-            mq.interval_score AS intervalScore,
-            mq.objective_policy AS objectivePolicy,
-            mq.question_type AS questionType,
-            mq.name AS name,
-            mq.paper_index AS paperIndex,
-            mq.page_index AS pageIndex,
-            mq.objective_policy_score AS objectivePolicyScore,
-            mq.create_id AS createId,
-            mq.create_time AS createTime,
-            mq.update_id AS updateId,
-            mq.update_time AS updateTime,
-            bc.code AS courseCode,
-            bc.name AS courseName,
-            bc.id AS courseId
+            mq.*,
+            mqa.answer,
+            mqa.objective_policy,
+            mqa.objective_policy_score
         FROM
-            mark_question mq
-                LEFT JOIN
-            mark_paper mp ON mq.exam_id = mp.exam_id AND mq.paper_number = mp.paper_number AND mq.paper_type = mp.paper_type
+            (SELECT
+                 *
+             FROM
+                 mark_question
+             WHERE
+                 exam_id = #{examId} AND paper_number = #{paperNumber}
+                <if test="objective != null">
+                    AND objective = #{objective}
+                </if>
+               ) mq
                 LEFT JOIN
-            basic_course bc ON mp.course_id = bc.id
-        <where>
-            <if test="examId != null">
-                AND mq.exam_id = #{examId}
-            </if>
-            <if test="paperType != null and paperType != ''">
-                AND mp.paper_type = #{paperType}
-            </if>
-            <if test="paperNumber != null and paperNumber != ''">
-                AND mq.paper_number = #{paperNumber}
-            </if>
-            <if test="objective != null">
-                AND mq.objective = #{objective}
-            </if>
-        </where>
+            (SELECT
+                 *
+             FROM
+                 mark_question_answer
+             WHERE
+                 exam_id = #{examId} AND paper_number = #{paperNumber}
+               AND paper_type = #{paperType}) mqa ON mq.main_number = mqa.main_number
+                AND mq.sub_number = mqa.sub_number
     </select>
 
 </mapper>

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

@@ -19,7 +19,7 @@ public interface PrintFinishService {
 
     void insertScanAnswerCard(ExamDetailCourseInitMarkDto dto, String cardId, String content);
 
-    void insertMarkQuestion(Long examId, String paperNumber, Integer serialNumber, String paperType, String content);
+    void insertMarkQuestion(Long examId, String paperNumber, String content);
 
     void insertPaperAnswerFile(Long examId, String paperNumber, Integer serialNumber, Long paperId);
 

+ 36 - 61
teachcloud-task/src/main/java/com/qmth/teachcloud/task/service/impl/PrintFinishServiceImpl.java

@@ -21,10 +21,7 @@ import com.qmth.teachcloud.common.service.BasicAttachmentService;
 import com.qmth.teachcloud.common.util.ExamTaskUtil;
 import com.qmth.teachcloud.mark.bean.answercard.CardFile;
 import com.qmth.teachcloud.mark.bean.vo.parseCard.Struct;
-import com.qmth.teachcloud.mark.entity.MarkPaper;
-import com.qmth.teachcloud.mark.entity.MarkPaperPackage;
-import com.qmth.teachcloud.mark.entity.MarkStudent;
-import com.qmth.teachcloud.mark.entity.ScanAnswerCard;
+import com.qmth.teachcloud.mark.entity.*;
 import com.qmth.teachcloud.mark.enums.CardSource;
 import com.qmth.teachcloud.mark.service.*;
 import com.qmth.teachcloud.mark.utils.CardParseUtils;
@@ -63,6 +60,8 @@ public class PrintFinishServiceImpl implements PrintFinishService {
     @Resource
     private MarkQuestionService markQuestionService;
     @Resource
+    private MarkQuestionAnswerService markQuestionAnswerService;
+    @Resource
     private MarkStudentService markStudentService;
     @Resource
     private ScanAnswerCardService scanAnswerCardService;
@@ -158,7 +157,7 @@ public class PrintFinishServiceImpl implements PrintFinishService {
                     continue;
                 }
                 // 解析卡格式中试卷结构并保存
-                this.insertMarkQuestion(dto.getExamId(), dto.getPaperNumber(), dto.getSerialNumber(), dto.getPaperType(), examCard.getContent());
+                this.insertMarkQuestion(dto.getExamId(), dto.getPaperNumber(), examCard.getContent());
                 // 生成并保存卡格式文件(后缀为.json)
                 this.insertScanAnswerCard(dto, cardId, examCard.getContent());
                 // 题库获取的试卷,同步标答文件
@@ -236,79 +235,55 @@ public class PrintFinishServiceImpl implements PrintFinishService {
         }
     }
 
+    @Transactional
     @Override
-    public void insertMarkQuestion(Long examId, String paperNumber, Integer serialNumber, String paperType, String content) {
+    public void insertMarkQuestion(Long examId, String paperNumber, String content) {
         try {
             List<Struct> structList = CardParseUtils.parseCardContent(content);
             if (CollectionUtils.isEmpty(structList)) {
                 return;
             }
-            List<MarkQuestion> markQuestionList = markQuestionService.listQuestionByExamIdAndPaperNumberAndSerialNumber(examId, paperNumber, serialNumber);
+            List<MarkQuestion> markQuestionList = markQuestionService.listQuestionByExamIdAndPaperNumber(examId, paperNumber);
             // 第一次新增
             if (CollectionUtils.isEmpty(markQuestionList)) {
+                MarkPaper markPaper = markPaperService.getByExamIdAndPaperNumber(examId, paperNumber);
                 List<MarkQuestion> markQuestions = new ArrayList<>();
-                AtomicInteger i = new AtomicInteger(1);
-                for (String pType : paperType.split(",")) {
-                    if (i.getAndIncrement() == 1) {
-                        for (Struct struct : structList) {
-                            // 保存主观题结构(主观题卷型为空)
-                            if (struct.getObjective()) {
-                                continue;
-                            }
-                            MarkQuestion markQuestion = new MarkQuestion();
-                            markQuestion.setId(SystemConstant.getDbUuid());
-                            markQuestion.setExamId(examId);
-                            markQuestion.setPaperNumber(paperNumber);
-                            markQuestion.setSerialNumber(serialNumber);
-                            markQuestion.setObjective(struct.getObjective());
-                            markQuestion.setMainNumber(struct.getMainNumber());
-                            markQuestion.setSubNumber(struct.getSubNumber());
-                            markQuestion.setMainTitle(struct.getMainTitle());
-                            markQuestion.setOptionCount(struct.getOptionCount());
-                            markQuestion.setQuestionType(struct.getType());
-                            markQuestion.setPaperIndex(struct.getPaperIndex());
-                            markQuestion.setPageIndex(struct.getPageIndex());
-                            if (struct.getScore() != null) {
-                                markQuestion.setTotalScore(struct.getScore());
-                                // 间隔分(整数默认1,小数默认0.5)
-                                if (!markQuestion.getObjective()) {
-                                    markQuestion.setIntervalScore(markQuestion.getTotalScore() % 1 > 0 ? 0.5 : 1);
-                                }
-                            }
-                            markQuestions.add(markQuestion);
+                List<MarkQuestionAnswer> markQuestionAnswers = new ArrayList<>();
+                for (Struct struct : structList) {
+                    MarkQuestion markQuestion = new MarkQuestion();
+                    markQuestion.setId(SystemConstant.getDbUuid());
+                    markQuestion.setExamId(examId);
+                    markQuestion.setPaperNumber(paperNumber);
+                    markQuestion.setObjective(struct.getObjective());
+                    markQuestion.setMainNumber(struct.getMainNumber());
+                    markQuestion.setSubNumber(struct.getSubNumber());
+                    markQuestion.setMainTitle(struct.getMainTitle());
+                    markQuestion.setOptionCount(struct.getOptionCount());
+                    markQuestion.setQuestionType(struct.getType());
+                    markQuestion.setPaperIndex(struct.getPaperIndex());
+                    markQuestion.setPageIndex(struct.getPageIndex());
+                    if (struct.getScore() != null) {
+                        markQuestion.setTotalScore(struct.getScore());
+                        // 间隔分(整数默认1,小数默认0.5)
+                        if (!markQuestion.getObjective()) {
+                            markQuestion.setIntervalScore(markQuestion.getTotalScore() % 1 > 0 ? 0.5 : 1);
                         }
                     }
-                    for (Struct struct : structList) {
-                        // 保存客观题结构
-                        if (!struct.getObjective()) {
-                            continue;
-                        }
-                        MarkQuestion markQuestion = new MarkQuestion();
-                        markQuestion.setId(SystemConstant.getDbUuid());
-                        markQuestion.setExamId(examId);
-                        markQuestion.setPaperNumber(paperNumber);
-                        markQuestion.setSerialNumber(serialNumber);
-                        markQuestion.setPaperType(pType);
-                        markQuestion.setObjective(struct.getObjective());
-                        markQuestion.setMainNumber(struct.getMainNumber());
-                        markQuestion.setSubNumber(struct.getSubNumber());
-                        markQuestion.setMainTitle(struct.getMainTitle());
-                        markQuestion.setOptionCount(struct.getOptionCount());
-                        markQuestion.setQuestionType(struct.getType());
-                        markQuestion.setPaperIndex(struct.getPaperIndex());
-                        markQuestion.setPageIndex(struct.getPageIndex());
+                    markQuestions.add(markQuestion);
+
+                    // 保存客观题数据
+                    for (String paperType : markPaper.getPaperTypeList()) {
+                        MarkQuestionAnswer markQuestionAnswer = new MarkQuestionAnswer(examId, paperNumber, paperType, struct.getMainNumber(), struct.getSubNumber());
                         if (StringUtils.isNotBlank(struct.getAnswer())) {
                             // 客观题有标答时,给分策略默认为全对给分
-                            markQuestion.setAnswer(struct.getAnswer());
-                            markQuestion.setObjectivePolicy(ObjectivePolicy.NONE);
-                        }
-                        if (struct.getScore() != null) {
-                            markQuestion.setTotalScore(struct.getScore());
+                            markQuestionAnswer.setAnswer(struct.getAnswer());
+                            markQuestionAnswer.setObjectivePolicy(ObjectivePolicy.NONE);
                         }
-                        markQuestions.add(markQuestion);
+                        markQuestionAnswers.add(markQuestionAnswer);
                     }
                 }
                 markQuestionService.saveBatch(markQuestions);
+                markQuestionAnswerService.saveBatch(markQuestionAnswers);
             }
         } catch (Exception e) {
             log.info("同步结构失败");