Преглед изворни кода

3.4.4 update-20250327,bug修改

xiaofei пре 2 месеци
родитељ
комит
5fb5ded86a
14 измењених фајлова са 168 додато и 47 уклоњено
  1. 2 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ExamCardModelFourService.java
  2. 2 1
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/PrintFinishService.java
  3. 13 4
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamCardModelFourServiceImpl.java
  4. 1 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamCardServiceImpl.java
  5. 11 2
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/PrintFinishServiceImpl.java
  6. 10 1
      distributed-print/src/main/java/com/qmth/distributed/print/api/ExamCardModelFourController.java
  7. 6 9
      distributed-print/src/main/java/com/qmth/distributed/print/api/mark/MarkArbitrateController.java
  8. 11 0
      teachcloud-common/src/main/java/com/qmth/teachcloud/common/contant/SystemConstant.java
  9. 1 1
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/mapper/MarkArbitrateHistoryMapper.java
  10. 3 3
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/MarkArbitrateHistoryService.java
  11. 51 14
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkArbitrateHistoryServiceImpl.java
  12. 52 8
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkServiceImpl.java
  13. 2 4
      teachcloud-mark/src/main/resources/mapper/MarkArbitrateHistoryMapper.xml
  14. 3 0
      teachcloud-mark/src/main/resources/mapper/MarkUserQuestionMapper.xml

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

@@ -92,4 +92,6 @@ public interface ExamCardModelFourService extends IService<ExamCardModelFour> {
     void validCourse(GenericExamCardModelFourParams params);
     void validCourse(GenericExamCardModelFourParams params);
 
 
     void saveQuestionAndAnswerCard(ExamCardModelFour examCardModelFour, MarkPaper markPaper, Long userId);
     void saveQuestionAndAnswerCard(ExamCardModelFour examCardModelFour, MarkPaper markPaper, Long userId);
+
+    void createJpgImageSync(Long id);
 }
 }

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

@@ -3,6 +3,7 @@ package com.qmth.distributed.print.business.service;
 import com.qmth.distributed.print.business.bean.dto.initMarkData.ExamDetailCourseInitMarkDto;
 import com.qmth.distributed.print.business.bean.dto.initMarkData.ExamDetailCourseInitMarkDto;
 import com.qmth.distributed.print.business.entity.BasicCardRule;
 import com.qmth.distributed.print.business.entity.BasicCardRule;
 import com.qmth.teachcloud.common.bean.vo.PaperInfoVo;
 import com.qmth.teachcloud.common.bean.vo.PaperInfoVo;
+import com.qmth.teachcloud.common.enums.ExamModelEnum;
 import com.qmth.teachcloud.mark.entity.ScanAnswerCard;
 import com.qmth.teachcloud.mark.entity.ScanAnswerCard;
 
 
 import java.util.List;
 import java.util.List;
@@ -20,7 +21,7 @@ public interface PrintFinishService {
 
 
     ScanAnswerCard insertScanAnswerCard(ExamDetailCourseInitMarkDto dto, String cardId, String content);
     ScanAnswerCard insertScanAnswerCard(ExamDetailCourseInitMarkDto dto, String cardId, String content);
 
 
-    void insertMarkQuestion(Long examId, Long courseId, String paperNumber, String content, List<PaperInfoVo> paperInfoVoList);
+    void insertMarkQuestion(Long examId, Long courseId, String paperNumber, String content, List<PaperInfoVo> paperInfoVoList, ExamModelEnum model);
 
 
     void insertPaperAnswerFile(Long examId, String paperNumber, Integer serialNumber, Long paperId);
     void insertPaperAnswerFile(Long examId, String paperNumber, Integer serialNumber, Long paperId);
 
 

+ 13 - 4
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamCardModelFourServiceImpl.java

@@ -28,6 +28,7 @@ import com.qmth.teachcloud.common.contant.SystemConstant;
 import com.qmth.teachcloud.common.entity.BasicAttachment;
 import com.qmth.teachcloud.common.entity.BasicAttachment;
 import com.qmth.teachcloud.common.entity.BasicCourse;
 import com.qmth.teachcloud.common.entity.BasicCourse;
 import com.qmth.teachcloud.common.entity.SysUser;
 import com.qmth.teachcloud.common.entity.SysUser;
+import com.qmth.teachcloud.common.enums.ExamModelEnum;
 import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
 import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
 import com.qmth.teachcloud.common.enums.FieldUniqueEnum;
 import com.qmth.teachcloud.common.enums.FieldUniqueEnum;
 import com.qmth.teachcloud.common.enums.PageSizeEnum;
 import com.qmth.teachcloud.common.enums.PageSizeEnum;
@@ -42,6 +43,7 @@ import org.apache.commons.codec.digest.DigestUtils;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.dao.DuplicateKeyException;
 import org.springframework.dao.DuplicateKeyException;
+import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.transaction.annotation.Transactional;
 
 
@@ -187,9 +189,6 @@ public class ExamCardModelFourServiceImpl extends ServiceImpl<ExamCardModelFourM
             }
             }
 
 
             if (ExamCardStatusEnum.SUBMIT.equals(params.getStatus())) {
             if (ExamCardStatusEnum.SUBMIT.equals(params.getStatus())) {
-                // 生成题卡图片
-                createJpgImage(examCardModelFour);
-
                 List<MarkPaper> markPaperList = markPaperService.listByExamIdAndCourseIdForModel4(examCardModelFour.getExamId(), examCardModelFour.getCourseId());
                 List<MarkPaper> markPaperList = markPaperService.listByExamIdAndCourseIdForModel4(examCardModelFour.getExamId(), examCardModelFour.getCourseId());
                 if (CollectionUtils.isNotEmpty(markPaperList) && markPaperList.size() == 1) {
                 if (CollectionUtils.isNotEmpty(markPaperList) && markPaperList.size() == 1) {
                     saveQuestionAndAnswerCard(examCardModelFour, markPaperList.get(0), sysUser.getId());
                     saveQuestionAndAnswerCard(examCardModelFour, markPaperList.get(0), sysUser.getId());
@@ -435,7 +434,7 @@ public class ExamCardModelFourServiceImpl extends ServiceImpl<ExamCardModelFourM
         }
         }
         ExamDetailCourseInitMarkDto dto = new ExamDetailCourseInitMarkDto(examCardModelFour, markPaper, userId);
         ExamDetailCourseInitMarkDto dto = new ExamDetailCourseInitMarkDto(examCardModelFour, markPaper, userId);
         // 解析卡格式中试卷结构并保存
         // 解析卡格式中试卷结构并保存
-        printFinishService.insertMarkQuestion(dto.getExamId(), dto.getCourseId(), dto.getPaperNumber(), examCardModelFour.getContent(), null);
+        printFinishService.insertMarkQuestion(dto.getExamId(), dto.getCourseId(), dto.getPaperNumber(), examCardModelFour.getContent(), null, ExamModelEnum.MODEL4);
         // 生成并保存卡格式文件(后缀为.json)
         // 生成并保存卡格式文件(后缀为.json)
         ScanAnswerCard scanAnswerCard = printFinishService.insertScanAnswerCard(dto, examCardModelFour.getId().toString(), examCardModelFour.getContent());
         ScanAnswerCard scanAnswerCard = printFinishService.insertScanAnswerCard(dto, examCardModelFour.getId().toString(), examCardModelFour.getContent());
         if (Objects.nonNull(scanAnswerCard)) {
         if (Objects.nonNull(scanAnswerCard)) {
@@ -445,6 +444,16 @@ public class ExamCardModelFourServiceImpl extends ServiceImpl<ExamCardModelFourM
         printFinishService.updateMarkSheetConfig(dto, examCardModelFour.getContent());
         printFinishService.updateMarkSheetConfig(dto, examCardModelFour.getContent());
     }
     }
 
 
+    @Async
+    @Override
+    public void createJpgImageSync(Long id) {
+        ExamCardModelFour examCardModelFour = this.getById(id);
+        if (examCardModelFour != null) {
+            ExamCardModelFour cardModelFour = createJpgImage(examCardModelFour);
+            this.updateById(cardModelFour);
+        }
+    }
+
     /**
     /**
      * 创建zip
      * 创建zip
      *
      *

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

@@ -299,6 +299,7 @@ public class ExamCardServiceImpl extends ServiceImpl<ExamCardMapper, ExamCard> i
                 examCard.setUpdateTime(System.currentTimeMillis());
                 examCard.setUpdateTime(System.currentTimeMillis());
             }
             }
             examCard.setTitle(params.getTitle());
             examCard.setTitle(params.getTitle());
+            examCard.setOpenAb(params.getOpenAb());
             examCard.setAttachmentId(params.getAttachmentId());
             examCard.setAttachmentId(params.getAttachmentId());
             examCard.setCardRuleId(params.getCardRuleId());
             examCard.setCardRuleId(params.getCardRuleId());
             // 上传题卡,状态为提交
             // 上传题卡,状态为提交

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

@@ -165,7 +165,7 @@ public class PrintFinishServiceImpl implements PrintFinishService {
                     continue;
                     continue;
                 }
                 }
                 // 解析卡格式中试卷结构并保存
                 // 解析卡格式中试卷结构并保存
-                this.insertMarkQuestion(dto.getExamId(), dto.getCourseId(), dto.getPaperNumber(), examCard.getContent(), paperInfoVoList);
+                this.insertMarkQuestion(dto.getExamId(), dto.getCourseId(), dto.getPaperNumber(), examCard.getContent(), paperInfoVoList, null);
                 // 生成并保存卡格式文件(后缀为.json)
                 // 生成并保存卡格式文件(后缀为.json)
                 ScanAnswerCard scanAnswerCard = this.insertScanAnswerCard(dto, cardId, examCard.getContent());
                 ScanAnswerCard scanAnswerCard = this.insertScanAnswerCard(dto, cardId, examCard.getContent());
                 if (scanAnswerCard != null) {
                 if (scanAnswerCard != null) {
@@ -246,13 +246,22 @@ public class PrintFinishServiceImpl implements PrintFinishService {
 
 
     @Transactional
     @Transactional
     @Override
     @Override
-    public void insertMarkQuestion(Long examId, Long courseId, String paperNumber, String content, List<PaperInfoVo> paperInfoVoList) {
+    public void insertMarkQuestion(Long examId, Long courseId, String paperNumber, String content, List<PaperInfoVo> paperInfoVoList, ExamModelEnum model) {
         try {
         try {
             List<Struct> structList = CardParseUtils.parseCardContent(content);
             List<Struct> structList = CardParseUtils.parseCardContent(content);
             if (CollectionUtils.isEmpty(structList)) {
             if (CollectionUtils.isEmpty(structList)) {
                 return;
                 return;
             }
             }
             List<MarkQuestion> markQuestionList = markQuestionService.listQuestionByExamIdAndPaperNumber(examId, paperNumber);
             List<MarkQuestion> markQuestionList = markQuestionService.listQuestionByExamIdAndPaperNumber(examId, paperNumber);
+            // 模式4,结构不一致先删除
+            if (model != null && ExamModelEnum.MODEL4.equals(model) && CollectionUtils.isNotEmpty(markQuestionList)) {
+                List<String> structListString = structList.stream().map(m -> SystemConstant.mergeString("#", m.getMainNumber(), m.getSubNumber(), m.getType())).collect(Collectors.toList());
+                List<String> markQuestionListString = markQuestionList.stream().map(m -> SystemConstant.mergeString("#", m.getMainNumber(), m.getSubNumber(), m.getQuestionType())).collect(Collectors.toList());
+                if (!CollectionUtils.isEqualCollection(structListString, markQuestionListString)) {
+                    markQuestionService.deleteByExamIdAndPaperNumber(examId, paperNumber);
+                    markQuestionList = markQuestionService.listQuestionByExamIdAndPaperNumber(examId, paperNumber);
+                }
+            }
             // 第一次新增
             // 第一次新增
             if (CollectionUtils.isEmpty(markQuestionList)) {
             if (CollectionUtils.isEmpty(markQuestionList)) {
                 // 解析题卡选择试卷的客观题标答和分数
                 // 解析题卡选择试卷的客观题标答和分数

+ 10 - 1
distributed-print/src/main/java/com/qmth/distributed/print/api/ExamCardModelFourController.java

@@ -5,13 +5,16 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.qmth.boot.api.constant.ApiConstant;
 import com.qmth.boot.api.constant.ApiConstant;
 import com.qmth.distributed.print.business.bean.params.GenericExamCardModelFourParams;
 import com.qmth.distributed.print.business.bean.params.GenericExamCardModelFourParams;
 import com.qmth.distributed.print.business.bean.result.EditResult;
 import com.qmth.distributed.print.business.bean.result.EditResult;
+import com.qmth.distributed.print.business.enums.ExamCardStatusEnum;
 import com.qmth.distributed.print.business.service.ExamCardModelFourService;
 import com.qmth.distributed.print.business.service.ExamCardModelFourService;
 import com.qmth.teachcloud.common.annotation.OperationLogDetail;
 import com.qmth.teachcloud.common.annotation.OperationLogDetail;
 import com.qmth.teachcloud.common.contant.SystemConstant;
 import com.qmth.teachcloud.common.contant.SystemConstant;
 import com.qmth.teachcloud.common.enums.log.OperationTypeEnum;
 import com.qmth.teachcloud.common.enums.log.OperationTypeEnum;
 import com.qmth.teachcloud.common.util.Result;
 import com.qmth.teachcloud.common.util.Result;
 import com.qmth.teachcloud.common.util.ResultUtil;
 import com.qmth.teachcloud.common.util.ResultUtil;
+import com.qmth.teachcloud.mark.entity.MarkPaper;
 import io.swagger.annotations.*;
 import io.swagger.annotations.*;
+import org.apache.commons.collections4.CollectionUtils;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RequestParam;
@@ -21,6 +24,7 @@ import javax.annotation.Resource;
 import javax.validation.constraints.Max;
 import javax.validation.constraints.Max;
 import javax.validation.constraints.Min;
 import javax.validation.constraints.Min;
 import java.util.List;
 import java.util.List;
+import java.util.Map;
 
 
 /**
 /**
  * <p>
  * <p>
@@ -73,7 +77,12 @@ public class ExamCardModelFourController {
     @OperationLogDetail(operationType = OperationTypeEnum.SAVE, detail = "新增/修改操作,题卡ID:{{params.id}}、题卡标题:{{params.title}}")
     @OperationLogDetail(operationType = OperationTypeEnum.SAVE, detail = "新增/修改操作,题卡ID:{{params.id}}、题卡标题:{{params.title}}")
     @ApiResponses({@ApiResponse(code = 200, message = "新增/修改", response = EditResult.class)})
     @ApiResponses({@ApiResponse(code = 200, message = "新增/修改", response = EditResult.class)})
     public Result saveGeneric(GenericExamCardModelFourParams params) throws Exception {
     public Result saveGeneric(GenericExamCardModelFourParams params) throws Exception {
-        return ResultUtil.ok(examCardModelFourService.saveGeneric(params));
+        Map<String, String> map = examCardModelFourService.saveGeneric(params);
+        if (ExamCardStatusEnum.SUBMIT.equals(params.getStatus())) {
+            // 生成题卡图片
+            examCardModelFourService.createJpgImageSync(Long.valueOf(map.get("id").toString()));
+        }
+        return ResultUtil.ok(map);
     }
     }
 
 
     @ApiOperation(value = "删除")
     @ApiOperation(value = "删除")

+ 6 - 9
distributed-print/src/main/java/com/qmth/distributed/print/api/mark/MarkArbitrateController.java

@@ -72,9 +72,8 @@ public class MarkArbitrateController {
     @ApiOperation(value = "获取评卷状态")
     @ApiOperation(value = "获取评卷状态")
     @RequestMapping(value = "/getStatus", method = RequestMethod.POST)
     @RequestMapping(value = "/getStatus", method = RequestMethod.POST)
     public Result getStatus(@ApiParam(value = "考试ID", required = true) @RequestParam Long examId,
     public Result getStatus(@ApiParam(value = "考试ID", required = true) @RequestParam Long examId,
-                            @ApiParam(value = "试卷编号", required = true) @RequestParam String paperNumber,
-                            @ApiParam(value = "题目ID", required = true) @RequestParam Long questionId) {
-        return ResultUtil.ok(markArbitrateHistoryService.getArbitrateStatus(examId, paperNumber, questionId));
+                            @ApiParam(value = "试卷编号", required = true) @RequestParam String paperNumber) {
+        return ResultUtil.ok(markArbitrateHistoryService.getArbitrateStatus(examId, paperNumber));
     }
     }
 
 
     /**
     /**
@@ -94,9 +93,8 @@ public class MarkArbitrateController {
     @RequestMapping(value = "/getSetting", method = RequestMethod.POST)
     @RequestMapping(value = "/getSetting", method = RequestMethod.POST)
     public Result getSetting(@ApiParam(value = "仲裁历史ID") @RequestParam(required = false) Long arbitrateId,
     public Result getSetting(@ApiParam(value = "仲裁历史ID") @RequestParam(required = false) Long arbitrateId,
                              @ApiParam(value = "考试ID") @RequestParam(required = false) Long examId,
                              @ApiParam(value = "考试ID") @RequestParam(required = false) Long examId,
-                             @ApiParam(value = "试卷编号") @RequestParam(required = false) String paperNumber,
-                             @ApiParam(value = "题目ID") @RequestParam(required = false) Long questionId) {
-        MarkArbitrateSettingDto markArbitrateSettingDto = markArbitrateHistoryService.getArbitrateSetting(arbitrateId, examId, paperNumber, questionId);
+                             @ApiParam(value = "试卷编号") @RequestParam(required = false) String paperNumber) {
+        MarkArbitrateSettingDto markArbitrateSettingDto = markArbitrateHistoryService.getArbitrateSetting(arbitrateId, examId, paperNumber);
         return ResultUtil.ok(markArbitrateSettingDto);
         return ResultUtil.ok(markArbitrateSettingDto);
     }
     }
 
 
@@ -107,9 +105,8 @@ public class MarkArbitrateController {
     @RequestMapping(value = "/getTask", method = RequestMethod.POST)
     @RequestMapping(value = "/getTask", method = RequestMethod.POST)
     public Result getTask(@ApiParam(value = "仲裁历史ID") @RequestParam(required = false) Long arbitrateId,
     public Result getTask(@ApiParam(value = "仲裁历史ID") @RequestParam(required = false) Long arbitrateId,
                           @ApiParam(value = "考试ID") @RequestParam(required = false) Long examId,
                           @ApiParam(value = "考试ID") @RequestParam(required = false) Long examId,
-                          @ApiParam(value = "试卷编号") @RequestParam(required = false) String paperNumber,
-                          @ApiParam(value = "题目ID") @RequestParam(required = false) Long questionId) {
-        Task task = markArbitrateHistoryService.getArbitrateTask(arbitrateId, examId, paperNumber, questionId);
+                          @ApiParam(value = "试卷编号") @RequestParam(required = false) String paperNumber) {
+        Task task = markArbitrateHistoryService.getArbitrateTask(arbitrateId, examId, paperNumber);
         return ResultUtil.ok(task);
         return ResultUtil.ok(task);
     }
     }
 
 

+ 11 - 0
teachcloud-common/src/main/java/com/qmth/teachcloud/common/contant/SystemConstant.java

@@ -1385,4 +1385,15 @@ public class SystemConstant {
         // 时间:事件
         // 时间:事件
         stringJoinerSummary.add(MessageFormat.format("{0}{1}{2}", DateUtil.format(new Date(), SystemConstant.DEFAULT_DATE_PATTERN), "->", message));
         stringJoinerSummary.add(MessageFormat.format("{0}{1}{2}", DateUtil.format(new Date(), SystemConstant.DEFAULT_DATE_PATTERN), "->", message));
     }
     }
+
+    public static String mergeString(String separator, Object...objects) {
+        if(StringUtils.isBlank(separator)){
+            separator = "#";
+        }
+        StringJoiner stringJoiner = new StringJoiner(separator);
+        for (Object object : objects) {
+            stringJoiner.add(object.toString());
+        }
+        return stringJoiner.toString();
+    }
 }
 }

+ 1 - 1
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/mapper/MarkArbitrateHistoryMapper.java

@@ -22,7 +22,7 @@ public interface MarkArbitrateHistoryMapper extends BaseMapper<MarkArbitrateHist
 
 
     IPage<MarkArbitrateDto> pageArbitrate(@Param("page") Page<MarkArbitrateDto> page, @Param("examId") Long examId, @Param("paperNumber") String paperNumber, @Param("questionId") Long questionId, @Param("status") String status, @Param("className") String className);
     IPage<MarkArbitrateDto> pageArbitrate(@Param("page") Page<MarkArbitrateDto> page, @Param("examId") Long examId, @Param("paperNumber") String paperNumber, @Param("questionId") Long questionId, @Param("status") String status, @Param("className") String className);
 
 
-    MarkArbitrateHistory getArbitrateWaitingOne(@Param("examId") Long examId, @Param("paperNumber") String paperNumber, @Param("questionId") Long questionId);
+    IPage<MarkArbitrateHistory> getArbitrateWaiting(@Param("page") Page<MarkArbitrateHistory> page, @Param("examId") Long examId, @Param("paperNumber") String paperNumber);
 
 
     List<MarkArbitrateHistory> getHistory(@Param("page") Page<MarkArbitrateHistory> page, @Param("examId") Long examId, @Param("paperNumber") String paperNumber, @Param("questionId") Long questionId, @Param("status") String status, @Param("userId") Long userId);
     List<MarkArbitrateHistory> getHistory(@Param("page") Page<MarkArbitrateHistory> page, @Param("examId") Long examId, @Param("paperNumber") String paperNumber, @Param("questionId") Long questionId, @Param("status") String status, @Param("userId") Long userId);
 
 

+ 3 - 3
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/MarkArbitrateHistoryService.java

@@ -31,15 +31,15 @@ public interface MarkArbitrateHistoryService extends IService<MarkArbitrateHisto
 
 
     List<MarkArbitrateMarkerDto> listMarkerArbitrateRecord(Long arbitrateId);
     List<MarkArbitrateMarkerDto> listMarkerArbitrateRecord(Long arbitrateId);
 
 
-    MarkArbitrateSettingDto getArbitrateSetting(Long arbitrateId, Long examId, String paperNumber, Long questionId);
+    MarkArbitrateSettingDto getArbitrateSetting(Long arbitrateId, Long examId, String paperNumber);
 
 
-    Task getArbitrateTask(Long arbitrateId, Long examId, String paperNumber, Long questionId);
+    Task getArbitrateTask(Long arbitrateId, Long examId, String paperNumber);
 
 
     void saveArbitrateTask(MarkArbitrateResult markResult);
     void saveArbitrateTask(MarkArbitrateResult markResult);
 
 
     void deleteByStudentId(Long studentId);
     void deleteByStudentId(Long studentId);
 
 
-    JSONObject getArbitrateStatus(Long examId, String paperNumber, Long questionId);
+    JSONObject getArbitrateStatus(Long examId, String paperNumber);
 
 
     List<Task> getHistory(Long examId, String paperNumber, Long questionId, Integer pageNumber, Integer pageSize);
     List<Task> getHistory(Long examId, String paperNumber, Long questionId, Integer pageNumber, Integer pageSize);
 
 

+ 51 - 14
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkArbitrateHistoryServiceImpl.java

@@ -25,6 +25,7 @@ import com.qmth.teachcloud.mark.dto.mark.manage.MarkArbitrateSettingDto;
 import com.qmth.teachcloud.mark.dto.mark.manage.Task;
 import com.qmth.teachcloud.mark.dto.mark.manage.Task;
 import com.qmth.teachcloud.mark.entity.*;
 import com.qmth.teachcloud.mark.entity.*;
 import com.qmth.teachcloud.mark.enums.LockType;
 import com.qmth.teachcloud.mark.enums.LockType;
+import com.qmth.teachcloud.mark.enums.OmrTaskStatus;
 import com.qmth.teachcloud.mark.lock.LockService;
 import com.qmth.teachcloud.mark.lock.LockService;
 import com.qmth.teachcloud.mark.mapper.MarkArbitrateHistoryMapper;
 import com.qmth.teachcloud.mark.mapper.MarkArbitrateHistoryMapper;
 import com.qmth.teachcloud.mark.params.MarkArbitrateResult;
 import com.qmth.teachcloud.mark.params.MarkArbitrateResult;
@@ -49,7 +50,7 @@ import java.util.*;
 public class MarkArbitrateHistoryServiceImpl extends ServiceImpl<MarkArbitrateHistoryMapper, MarkArbitrateHistory> implements MarkArbitrateHistoryService {
 public class MarkArbitrateHistoryServiceImpl extends ServiceImpl<MarkArbitrateHistoryMapper, MarkArbitrateHistory> implements MarkArbitrateHistoryService {
 
 
     // 并发处理互斥锁
     // 并发处理互斥锁
-    private Map<Long, Integer> currentTaskMap = new HashMap<>();
+    private Map<Long, Long> currentTaskMap = new HashMap<>();
 
 
     @Resource
     @Resource
     private BasicCourseService basicCourseService;
     private BasicCourseService basicCourseService;
@@ -68,8 +69,6 @@ public class MarkArbitrateHistoryServiceImpl extends ServiceImpl<MarkArbitrateHi
     @Resource
     @Resource
     private TaskService taskService;
     private TaskService taskService;
     @Resource
     @Resource
-    private FileUploadService fileUploadService;
-    @Resource
     private MarkService markService;
     private MarkService markService;
     @Resource
     @Resource
     private LockService lockService;
     private LockService lockService;
@@ -126,7 +125,7 @@ public class MarkArbitrateHistoryServiceImpl extends ServiceImpl<MarkArbitrateHi
     }
     }
 
 
     @Override
     @Override
-    public MarkArbitrateSettingDto getArbitrateSetting(Long arbitrateId, Long examId, String paperNumber, Long questionId) {
+    public MarkArbitrateSettingDto getArbitrateSetting(Long arbitrateId, Long examId, String paperNumber) {
         SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
         SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
         MarkArbitrateHistory markArbitrateHistory;
         MarkArbitrateHistory markArbitrateHistory;
         if (arbitrateId != null) {
         if (arbitrateId != null) {
@@ -137,7 +136,7 @@ public class MarkArbitrateHistoryServiceImpl extends ServiceImpl<MarkArbitrateHi
             examId = markArbitrateHistory.getExamId();
             examId = markArbitrateHistory.getExamId();
             paperNumber = markArbitrateHistory.getPaperNumber();
             paperNumber = markArbitrateHistory.getPaperNumber();
         } else {
         } else {
-            if (examId == null || StringUtils.isBlank(paperNumber) || questionId == null) {
+            if (examId == null || StringUtils.isBlank(paperNumber)) {
                 throw ExceptionResultEnum.ERROR.exception("参数有误");
                 throw ExceptionResultEnum.ERROR.exception("参数有误");
             }
             }
         }
         }
@@ -168,18 +167,24 @@ public class MarkArbitrateHistoryServiceImpl extends ServiceImpl<MarkArbitrateHi
     }
     }
 
 
     @Override
     @Override
-    public Task getArbitrateTask(Long arbitrateId, Long examId, String paperNumber, Long questionId) {
+    public Task getArbitrateTask(Long arbitrateId, Long examId, String paperNumber) {
+        Long userId = ServletUtil.getRequestUserId();
         MarkArbitrateHistory markArbitrateHistory;
         MarkArbitrateHistory markArbitrateHistory;
         if (arbitrateId != null) {
         if (arbitrateId != null) {
             markArbitrateHistory = this.getById(arbitrateId);
             markArbitrateHistory = this.getById(arbitrateId);
-            if (MarkArbitrateStatus.MARKED.equals(markArbitrateHistory.getStatus())) {
-                throw ExceptionResultEnum.ERROR.exception("数据已处理,请刷新数据列表");
+            if (this.applyTask(markArbitrateHistory.getId(), userId)) {
+                if (MarkArbitrateStatus.MARKED.equals(markArbitrateHistory.getStatus())) {
+                    this.releaseTask(markArbitrateHistory.getId());
+                    throw ExceptionResultEnum.ERROR.exception("数据已处理,请刷新数据列表");
+                }
+            } else {
+                throw ExceptionResultEnum.ERROR.exception("任务已经其它人占用");
             }
             }
         } else {
         } else {
-            if (examId == null || StringUtils.isBlank(paperNumber) || questionId == null) {
+            if (examId == null || StringUtils.isBlank(paperNumber)) {
                 throw ExceptionResultEnum.ERROR.exception("参数有误");
                 throw ExceptionResultEnum.ERROR.exception("参数有误");
             }
             }
-            markArbitrateHistory = this.baseMapper.getArbitrateWaitingOne(examId, paperNumber, questionId);
+            markArbitrateHistory = this.findWaitingTask(examId, paperNumber, userId);
         }
         }
         if (markArbitrateHistory == null) {
         if (markArbitrateHistory == null) {
             return null;
             return null;
@@ -188,6 +193,29 @@ public class MarkArbitrateHistoryServiceImpl extends ServiceImpl<MarkArbitrateHi
         return taskService.build(markArbitrateHistory, markQuestion);
         return taskService.build(markArbitrateHistory, markQuestion);
     }
     }
 
 
+    private MarkArbitrateHistory findWaitingTask(Long examId, String paperNumber, Long userId) {
+        int retry = 0;
+        MarkArbitrateHistory markArbitrateHistory = null;
+        while (markArbitrateHistory == null) {
+            Page<MarkArbitrateHistory> page = new Page<>(retry * 20, 20);
+            IPage<MarkArbitrateHistory> historyIPage = this.baseMapper.getArbitrateWaiting(page, examId, paperNumber);
+            List<MarkArbitrateHistory> list = historyIPage.getRecords();
+            if (list.isEmpty()) {
+                break;
+            }
+            for (MarkArbitrateHistory mh : list) {
+                if (this.applyTask(mh.getId(), userId)) {
+                    markArbitrateHistory = mh;
+                    break;
+                }
+            }
+            if (markArbitrateHistory == null) {
+                retry++;
+            }
+        }
+        return markArbitrateHistory;
+    }
+
     @Override
     @Override
     public void saveArbitrateTask(MarkArbitrateResult markResult) {
     public void saveArbitrateTask(MarkArbitrateResult markResult) {
         SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
         SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
@@ -217,12 +245,11 @@ public class MarkArbitrateHistoryServiceImpl extends ServiceImpl<MarkArbitrateHi
     }
     }
 
 
     @Override
     @Override
-    public JSONObject getArbitrateStatus(Long examId, String paperNumber, Long questionId) {
+    public JSONObject getArbitrateStatus(Long examId, String paperNumber) {
         Long userId = ServletUtil.getRequestUserId();
         Long userId = ServletUtil.getRequestUserId();
         QueryWrapper<MarkArbitrateHistory> queryWrapper = new QueryWrapper<>();
         QueryWrapper<MarkArbitrateHistory> queryWrapper = new QueryWrapper<>();
         queryWrapper.lambda().eq(MarkArbitrateHistory::getExamId, examId)
         queryWrapper.lambda().eq(MarkArbitrateHistory::getExamId, examId)
-                .eq(MarkArbitrateHistory::getPaperNumber, paperNumber)
-                .eq(MarkArbitrateHistory::getQuestionId, questionId);
+                .eq(MarkArbitrateHistory::getPaperNumber, paperNumber);
         List<MarkArbitrateHistory> markArbitrateHistoryList = this.list(queryWrapper);
         List<MarkArbitrateHistory> markArbitrateHistoryList = this.list(queryWrapper);
         JSONObject jsonObject = new JSONObject();
         JSONObject jsonObject = new JSONObject();
         if (CollectionUtils.isEmpty(markArbitrateHistoryList)) {
         if (CollectionUtils.isEmpty(markArbitrateHistoryList)) {
@@ -277,6 +304,16 @@ public class MarkArbitrateHistoryServiceImpl extends ServiceImpl<MarkArbitrateHi
         this.remove(updateWrapper);
         this.remove(updateWrapper);
     }
     }
 
 
+    private boolean applyTask(Long taskId, Long userId) {
+        synchronized (currentTaskMap) {
+            if (currentTaskMap.containsKey(taskId)) {
+                return false;
+            }
+            currentTaskMap.put(taskId, userId);
+            return true;
+        }
+    }
+
     private void releaseTask(Long taskId) {
     private void releaseTask(Long taskId) {
         synchronized (currentTaskMap) {
         synchronized (currentTaskMap) {
             currentTaskMap.remove(taskId);
             currentTaskMap.remove(taskId);
@@ -288,7 +325,7 @@ public class MarkArbitrateHistoryServiceImpl extends ServiceImpl<MarkArbitrateHi
         taskIds.addAll(currentTaskMap.keySet());
         taskIds.addAll(currentTaskMap.keySet());
         synchronized (currentTaskMap) {
         synchronized (currentTaskMap) {
             for (Long taskId : taskIds) {
             for (Long taskId : taskIds) {
-                Integer value = currentTaskMap.get(taskId);
+                Long value = currentTaskMap.get(taskId);
                 if (value != null && value.equals(userId)) {
                 if (value != null && value.equals(userId)) {
                     currentTaskMap.remove(taskId);
                     currentTaskMap.remove(taskId);
                 }
                 }

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

@@ -10,6 +10,7 @@ import com.qmth.teachcloud.common.entity.BasicCourse;
 import com.qmth.teachcloud.common.entity.MarkQuestion;
 import com.qmth.teachcloud.common.entity.MarkQuestion;
 import com.qmth.teachcloud.common.entity.SysUser;
 import com.qmth.teachcloud.common.entity.SysUser;
 import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
 import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
+import com.qmth.teachcloud.common.enums.ScorePolicy;
 import com.qmth.teachcloud.common.enums.mark.*;
 import com.qmth.teachcloud.common.enums.mark.*;
 import com.qmth.teachcloud.common.service.BasicCourseService;
 import com.qmth.teachcloud.common.service.BasicCourseService;
 import com.qmth.teachcloud.common.service.BasicOperationLogService;
 import com.qmth.teachcloud.common.service.BasicOperationLogService;
@@ -30,6 +31,7 @@ import com.qmth.teachcloud.mark.params.MarkArbitrateResult;
 import com.qmth.teachcloud.mark.params.MarkResult;
 import com.qmth.teachcloud.mark.params.MarkResult;
 import com.qmth.teachcloud.mark.params.MarkResultQuestion;
 import com.qmth.teachcloud.mark.params.MarkResultQuestion;
 import com.qmth.teachcloud.mark.service.*;
 import com.qmth.teachcloud.mark.service.*;
+import com.qmth.teachcloud.mark.utils.BigDecimalUtils;
 import com.qmth.teachcloud.mark.utils.TaskLock;
 import com.qmth.teachcloud.mark.utils.TaskLock;
 import com.qmth.teachcloud.mark.utils.TaskLockUtil;
 import com.qmth.teachcloud.mark.utils.TaskLockUtil;
 import io.lettuce.core.GeoArgs.Sort;
 import io.lettuce.core.GeoArgs.Sort;
@@ -345,7 +347,9 @@ public class MarkServiceImpl implements MarkService {
                 markArbitrateHistory.getUpdateUserId(), markResult.getMarkerScore(), markResult.getMarkerTrackList(), markResult.getMarkerTagList(), markArbitrateHistory.getUpdateTime(), MarkTaskStatus.ARBITRATED);
                 markArbitrateHistory.getUpdateUserId(), markResult.getMarkerScore(), markResult.getMarkerTrackList(), markResult.getMarkerTagList(), markArbitrateHistory.getUpdateTime(), MarkTaskStatus.ARBITRATED);
         updateMarkedCount(markArbitrateHistory.getExamId(), markArbitrateHistory.getPaperNumber(),
         updateMarkedCount(markArbitrateHistory.getExamId(), markArbitrateHistory.getPaperNumber(),
                 markArbitrateHistory.getQuestionId());
                 markArbitrateHistory.getQuestionId());
-        checkStudentQuestion(markArbitrateHistory.getStudentId(), markQuestionService.getById(markArbitrateHistory.getQuestionId()), markResult.getMarkerScore());
+        MarkQuestion markQuestion = markQuestionService.getById(markArbitrateHistory.getQuestionId());
+        markQuestion.setMarkScore(markResult.getMarkerScore());
+        checkStudentQuestion(markArbitrateHistory.getStudentId(), markQuestion);
         // 评卷质量重新统计
         // 评卷质量重新统计
         List<MarkUserQuestion> markUserGroups = markUserQuestionService.listByExamIdAndPaperNumberAndQuestionId(markArbitrateHistory.getExamId(), markArbitrateHistory.getPaperNumber(), markArbitrateHistory.getQuestionId());
         List<MarkUserQuestion> markUserGroups = markUserQuestionService.listByExamIdAndPaperNumberAndQuestionId(markArbitrateHistory.getExamId(), markArbitrateHistory.getPaperNumber(), markArbitrateHistory.getQuestionId());
         markUserGroups.forEach(m -> this.updateQuality(m));
         markUserGroups.forEach(m -> this.updateQuality(m));
@@ -356,12 +360,11 @@ public class MarkServiceImpl implements MarkService {
      *
      *
      * @param studentId
      * @param studentId
      * @param markQuestion
      * @param markQuestion
-     * @param markScore
      */
      */
-    private void checkStudentQuestion(Long studentId, MarkQuestion markQuestion, Double markScore) {
-        if (calculateQuestionId(markQuestion, studentId)) {
+    private void checkStudentQuestion(Long studentId, MarkQuestion markQuestion) {
+        if (calculateQuestion(markQuestion, studentId)) {
             //更新考生分组分数
             //更新考生分组分数
-            updateStudentQuestionScore(studentId, markQuestion, markScore);
+            updateStudentQuestionScore(studentId, markQuestion, markQuestion.getMarkScore());
 //            checkStudentSubjective(studentId, markQuestion.getExamId(), markQuestion.getPaperNumber(), version);
 //            checkStudentSubjective(studentId, markQuestion.getExamId(), markQuestion.getPaperNumber(), version);
         } else {
         } else {
             markStudentService.updateSubjectiveStatusAndScore(studentId, SubjectiveStatus.UNMARK);
             markStudentService.updateSubjectiveStatusAndScore(studentId, SubjectiveStatus.UNMARK);
@@ -666,7 +669,11 @@ public class MarkServiceImpl implements MarkService {
         markQuestionService.updateTaskCount(questionId, count);
         markQuestionService.updateTaskCount(questionId, count);
     }
     }
 
 
-    private boolean calculateQuestionId(MarkQuestion markQuestion, Long studentId) {
+    private boolean calculateQuestion(MarkQuestion markQuestion, Long studentId) {
+        double score = 0;
+        int count = 0;
+        // 未设置算分策略的情况下,默认取平均分
+        ScorePolicy policy = markQuestion.getScorePolicy() != null ? markQuestion.getScorePolicy() : ScorePolicy.AVG;
         List<MarkTask> list = markTaskService.listByExamIdAndPaperNumberAndQuestionIdAndStudentId(markQuestion.getExamId(),
         List<MarkTask> list = markTaskService.listByExamIdAndPaperNumberAndQuestionIdAndStudentId(markQuestion.getExamId(),
                 markQuestion.getPaperNumber(), markQuestion.getId(), studentId);
                 markQuestion.getPaperNumber(), markQuestion.getId(), studentId);
         if (list.isEmpty()) {
         if (list.isEmpty()) {
@@ -678,6 +685,40 @@ public class MarkServiceImpl implements MarkService {
                 return false;
                 return false;
             }
             }
         }
         }
+        for (MarkTask markTask : list) {
+            count++;
+            Double current = markTask.getHeaderScore() != null ? markTask.getHeaderScore() : markTask.getMarkerScore();
+            if (count == 1) {
+                // 首份评卷任务,直接取总分与明细
+                score = current;
+            } else {
+                switch (policy) {
+                    case AVG:
+                        // 直接累加
+                        score = BigDecimalUtils.add(score, current);
+                        break;
+                    case MAX:
+                        // 高分优先
+                        if (current > score) {
+                            score = current;
+                        }
+                        break;
+                    case MIN:
+                        // 低分优先
+                        if (current < score) {
+                            score = current;
+                        }
+                        break;
+                    default:
+                        break;
+                }
+            }
+        }
+        // 取平均分策略下,累计分数需要重新计算一次
+        if (policy == ScorePolicy.AVG && count > 1) {
+            score = BigDecimalUtils.div(score, count);
+        }
+        markQuestion.setMarkScore(score);
         return true;
         return true;
     }
     }
 
 
@@ -894,7 +935,9 @@ public class MarkServiceImpl implements MarkService {
                 updateMarkedCount(markStudent.getExamId(), markStudent.getPaperNumber(), result.getQuestionId());
                 updateMarkedCount(markStudent.getExamId(), markStudent.getPaperNumber(), result.getQuestionId());
                 resetStudentStatus(markStudent.getId());
                 resetStudentStatus(markStudent.getId());
                 markStudentService.updateCheckInfo(markStudent.getId(), userId);
                 markStudentService.updateCheckInfo(markStudent.getId(), userId);
-                checkStudentQuestion(markStudent.getId(), markQuestionService.getById(result.getQuestionId()), result.getMarkerScore());
+                MarkQuestion markQuestion = markQuestionService.getById(result.getQuestionId());
+                markQuestion.setMarkScore(result.getMarkerScore());
+                checkStudentQuestion(markStudent.getId(), markQuestion);
             } catch (ApiException e) {
             } catch (ApiException e) {
                 throw ExceptionResultEnum.ERROR.exception(e.getMessage());
                 throw ExceptionResultEnum.ERROR.exception(e.getMessage());
             } finally {
             } finally {
@@ -1299,7 +1342,8 @@ public class MarkServiceImpl implements MarkService {
                 markHeaderHistoryService.deleteByStudentIdAndQuestionId(task.getStudentId(), task.getQuestionId());
                 markHeaderHistoryService.deleteByStudentIdAndQuestionId(task.getStudentId(), task.getQuestionId());
             }
             }
             // 判断当前分组是否已完成评卷
             // 判断当前分组是否已完成评卷
-            checkStudentQuestion(task.getStudentId(), markQuestion, result.getMarkerScore());
+            markQuestion.setMarkScore(result.getMarkerScore());
+            checkStudentQuestion(task.getStudentId(), markQuestion);
         }
         }
         return true;
         return true;
     }
     }

+ 2 - 4
teachcloud-mark/src/main/resources/mapper/MarkArbitrateHistoryMapper.xml

@@ -65,17 +65,15 @@
             </if>
             </if>
             ORDER BY mah.status desc, mah.create_time asc
             ORDER BY mah.status desc, mah.create_time asc
     </select>
     </select>
-    <select id="getArbitrateWaitingOne" resultType="com.qmth.teachcloud.mark.entity.MarkArbitrateHistory">
+    <select id="getArbitrateWaiting" resultType="com.qmth.teachcloud.mark.entity.MarkArbitrateHistory">
         SELECT
         SELECT
             *
             *
         FROM
         FROM
             mark_arbitrate_history
             mark_arbitrate_history
         WHERE
         WHERE
             exam_id = #{examId} AND paper_number = #{paperNumber}
             exam_id = #{examId} AND paper_number = #{paperNumber}
-          AND question_id = #{questionId}
           AND status = 'WAITING'
           AND status = 'WAITING'
-            ORDER BY id
-            LIMIT 1
+        ORDER BY create_time asc
     </select>
     </select>
     <select id="getHistory" resultType="com.qmth.teachcloud.mark.entity.MarkArbitrateHistory">
     <select id="getHistory" resultType="com.qmth.teachcloud.mark.entity.MarkArbitrateHistory">
         SELECT
         SELECT

+ 3 - 0
teachcloud-mark/src/main/resources/mapper/MarkUserQuestionMapper.xml

@@ -109,6 +109,8 @@
         FROM
         FROM
             mark_user_question muq
             mark_user_question muq
                 LEFT JOIN
                 LEFT JOIN
+            mark_question mq ON muq.exam_id = mq.exam_id AND muq.paper_number = mq.paper_number AND muq.question_id = mq.id
+                LEFT JOIN
             sys_user su ON muq.user_id = su.id
             sys_user su ON muq.user_id = su.id
                 LEFT JOIN
                 LEFT JOIN
             sys_org so ON su.org_id = so.id
             sys_org so ON su.org_id = so.id
@@ -132,6 +134,7 @@
                 AND muq.finish_count > 0
                 AND muq.finish_count > 0
             </if>
             </if>
         </where>
         </where>
+        order by muq.enable desc, mq.main_number, mq.sub_number
     </select>
     </select>
     <select id="pageQuality" resultType="com.qmth.teachcloud.mark.dto.mark.manage.MarkQualityDto">
     <select id="pageQuality" resultType="com.qmth.teachcloud.mark.dto.mark.manage.MarkQualityDto">
         SELECT
         SELECT