Browse Source

3.4.4 update-20250306,联调bug修复-主观题复核、轨迹图

xiaofei 3 months ago
parent
commit
0720532656
21 changed files with 306 additions and 54 deletions
  1. 5 0
      distributed-print/install/mysql/upgrade/3.4.4.sql
  2. 1 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/enums/LockType.java
  3. 2 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/mapper/MarkTaskMapper.java
  4. 3 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/MarkArbitrateHistoryService.java
  5. 1 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/MarkRejectHistoryService.java
  6. 7 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/MarkService.java
  7. 2 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/MarkSubjectiveScoreService.java
  8. 3 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/MarkSyncService.java
  9. 6 4
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/MarkTaskService.java
  10. 10 4
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkArbitrateHistoryServiceImpl.java
  11. 28 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkQuestionServiceImpl.java
  12. 9 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkRejectHistoryServiceImpl.java
  13. 45 9
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkServiceImpl.java
  14. 9 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkSubjectiveScoreServiceImpl.java
  15. 20 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkSyncServiceImpl.java
  16. 18 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkTaskServiceImpl.java
  17. 2 4
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkUserQuestionServiceImpl.java
  18. 16 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/utils/TaskLock.java
  19. 1 1
      teachcloud-mark/src/main/resources/mapper/MarkStudentMapper.xml
  20. 117 27
      teachcloud-mark/src/main/resources/mapper/MarkTaskMapper.xml
  21. 1 5
      teachcloud-mark/src/main/resources/mapper/MarkUserQuestionMapper.xml

+ 5 - 0
distributed-print/install/mysql/upgrade/3.4.4.sql

@@ -181,3 +181,8 @@ INSERT INTO sys_config
 VALUES(51, NULL, NULL, 'mark.score.calculate.job.db.limit', '统分查询考生条数', 'limit 0,500', NULL, 1, 20, 1, NULL, NULL, NULL);
 
 -- 2025-03-06
+ALTER TABLE `mark_arbitrate_history` CHANGE COLUMN `group_number` `group_number` INT NULL COMMENT '大题号' ;
+ALTER TABLE `mark_problem_history` CHANGE COLUMN `group_number` `group_number` INT NULL COMMENT '大题号' ;
+ALTER TABLE `mark_subjective_score` CHANGE COLUMN `group_number` `group_number` INT NULL COMMENT '分组序号' ;
+ALTER TABLE `mark_subjective_score` CHANGE COLUMN `group_score` `group_score` DOUBLE NULL COMMENT '分组得分' ;
+ALTER TABLE `mark_subjective_score` CHANGE COLUMN `uncalculate` `uncalculate` TINYINT(1) NULL COMMENT '是否合分' ;

+ 1 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/enums/LockType.java

@@ -3,6 +3,7 @@ package com.qmth.teachcloud.mark.enums;
 public enum LockType {
 	EXAM_SUBJECT("exam_subject"),
 	QUESTION("question"),
+	QUESTION_UPDATE("question_update"),
 	STUDENT("student"),
 	MARK_USER_QUESTION("mark_user_group"),
 	MARKER_RESET("marker_reset"), 

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

@@ -43,6 +43,8 @@ public interface MarkTaskMapper extends BaseMapper<MarkTask> {
     List<MarkTask> listByExamIdAndPaperNumberAndQuestionIdAndUserIdAndClassName(@Param("examId") Long examId, @Param("paperNumber") String paperNumber, @Param("questionId") Long questionId, @Param("userId") Long userId, @Param("className") String className);
 
     int countByExamIdAndPaperNumberAndQuestionIdAndUserIdAndAndClassNameStatusIn(@Param("examId") Long examId, @Param("paperNumber") String paperNumber, @Param("questionId") Long questionId, @Param("userId") Long userId, @Param("classNames") List<String> classNames, @Param("statusList") MarkTaskStatus[] statusList);
+    int countByExamIdAndPaperNumberAndUserIdAndAndClassName(@Param("examId") Long examId, @Param("paperNumber") String paperNumber, @Param("markerId") Long markerId, @Param("userId") Long userId, @Param("classNames") List<String> classNames);
+    int countByExamIdAndPaperNumberAndUserIdAndAndClassNameStatusIn(@Param("examId") Long examId, @Param("paperNumber") String paperNumber, @Param("markerId") Long markerId, @Param("userId") Long userId, @Param("classNames") List<String> classNames, @Param("status") String status);
 
     IPage<MarkTaskDto> pageMarkTask(@Param("page") Page<Object> page, @Param("examId") Long examId, @Param("paperNumber") String paperNumber, @Param("questionId") Long questionId, @Param("loginName") String loginName, @Param("status") MarkTaskStatus status, @Param("studentCode") String studentCode, @Param("secretNumber") String secretNumber, @Param("teachClassName") String teachClassName, @Param("subScore") Double subScore);
 

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

@@ -42,4 +42,7 @@ public interface MarkArbitrateHistoryService extends IService<MarkArbitrateHisto
     List<Task> getHistory(Long examId, String paperNumber, Long questionId, Integer pageNumber, Integer pageSize);
 
     Integer waitArbitrateCount(Long examId, String paperNumber, Long questionId, String className);
+
+    void deleteByExamIdAndPaperNumberAndQuestionId(Long examId, String paperNumber, Long questionId);
+
 }

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

@@ -17,4 +17,5 @@ public interface MarkRejectHistoryService extends IService<MarkRejectHistory> {
 
     IPage<MarkRejectHistoryDto> pageRejectHistory(Long examId, String paperNumber, Long questionId, String loginName, String studentCode, String secretNumber, String teachClassName, Integer pageNumber, Integer pageSize);
 
+    void deleteByExamIdAndPaperNumberAndQuestionId(Long examId, String paperNumber, Long questionId);
 }

+ 7 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/MarkService.java

@@ -97,4 +97,11 @@ public interface MarkService {
     void checkStudentSubjectiveScore(Long examId, String coursePaperId, long unGroupQuestionCount);
 
     boolean rejectMarkTask(MarkTask markTask, Long userId, String reason);
+
+    void deleteMarkTask(MarkQuestion markQuestion);
+
+    /**
+     * /** 释放整修科目的锁定任务
+     */
+    void releaseByMarkQuestion(MarkQuestion markQuestion);
 }

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

@@ -32,4 +32,6 @@ public interface MarkSubjectiveScoreService extends IMppService<MarkSubjectiveSc
     void updateRejected(Long studentId, Long questionId, boolean rejectd);
 
     long countByStudentId(Long studentId);
+
+    void deleteByExamIdAndPaperNumberAndQuestionId(Long examId, String paperNumber, Long questionId);
 }

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

@@ -1,5 +1,6 @@
 package com.qmth.teachcloud.mark.service;
 
+import com.qmth.teachcloud.common.entity.MarkQuestion;
 import com.qmth.teachcloud.mark.entity.MarkPaper;
 import com.qmth.teachcloud.mark.entity.MarkUserQuestion;
 import org.slf4j.Logger;
@@ -16,4 +17,6 @@ public interface MarkSyncService {
     void updateQuality(List<MarkUserQuestion> markUserGroups, String lockKey);
 
     void calcObjectiveScore(MarkPaper markPaper);
+
+    void deleteMarkTask(MarkQuestion markQuestion);
 }

+ 6 - 4
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/MarkTaskService.java

@@ -1,9 +1,5 @@
 package com.qmth.teachcloud.mark.service;
 
-import java.util.List;
-
-import javax.servlet.http.HttpServletResponse;
-
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.IService;
@@ -17,6 +13,9 @@ import com.qmth.teachcloud.mark.enums.MarkTaskStatus;
 import com.qmth.teachcloud.mark.enums.QuestionModel;
 import com.qmth.teachcloud.mark.params.MarkResultQuestion;
 
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
+
 /**
  * <p>
  * 评卷任务表 服务类
@@ -55,7 +54,10 @@ public interface MarkTaskService extends IService<MarkTask> {
 
     void deleteByStudentId(Long studentId);
 
+    void deleteByExamIdAndPaperNumberAndQuestionId(Long examId, String paperNumber, Long questionId);
+
     int countByExamIdAndPaperNumberAndQuestionIdAndUserIdAndAndClassNameStatusIn(Long examId, String paperNumber, Long questionId, Long userId, List<String> className, MarkTaskStatus... status);
+    int countByExamIdAndPaperNumberAndUserIdAndAndClassNameStatusIn(Long examId, String paperNumber, Long markerId, Long userId, List<String> className, String status);
 
     IPage<Long> listPageHistory(Page<Long> page, Long userId, Long examId, String paperNumber, String secretNumber, Double markerScore);
 

+ 10 - 4
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkArbitrateHistoryServiceImpl.java

@@ -21,10 +21,7 @@ import com.qmth.teachcloud.mark.dto.mark.manage.MarkArbitrateDto;
 import com.qmth.teachcloud.mark.dto.mark.manage.MarkArbitrateMarkerDto;
 import com.qmth.teachcloud.mark.dto.mark.manage.MarkArbitrateSettingDto;
 import com.qmth.teachcloud.mark.dto.mark.manage.Task;
-import com.qmth.teachcloud.mark.entity.MarkArbitrateHistory;
-import com.qmth.teachcloud.mark.entity.MarkPaper;
-import com.qmth.teachcloud.mark.entity.MarkTask;
-import com.qmth.teachcloud.mark.entity.MarkUserQuestion;
+import com.qmth.teachcloud.mark.entity.*;
 import com.qmth.teachcloud.mark.enums.LockType;
 import com.qmth.teachcloud.mark.lock.LockService;
 import com.qmth.teachcloud.mark.mapper.MarkArbitrateHistoryMapper;
@@ -255,6 +252,15 @@ public class MarkArbitrateHistoryServiceImpl extends ServiceImpl<MarkArbitrateHi
         return this.baseMapper.waitArbitrateCount(examId, paperNumber, questionId, MarkArbitrateStatus.WAITING.name(), className);
     }
 
+    @Override
+    public void deleteByExamIdAndPaperNumberAndQuestionId(Long examId, String paperNumber, Long questionId) {
+        UpdateWrapper<MarkArbitrateHistory> updateWrapper = new UpdateWrapper<>();
+        updateWrapper.lambda().eq(MarkArbitrateHistory::getExamId, examId)
+                .eq(MarkArbitrateHistory::getPaperNumber, paperNumber)
+                .eq(MarkArbitrateHistory::getQuestionId, questionId);
+        this.remove(updateWrapper);
+    }
+
     private void releaseTask(Long taskId) {
         synchronized (currentTaskMap) {
             currentTaskMap.remove(taskId);

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

@@ -36,7 +36,9 @@ import com.qmth.teachcloud.mark.entity.MarkPaper;
 import com.qmth.teachcloud.mark.entity.MarkQuestionAnswer;
 import com.qmth.teachcloud.mark.entity.MarkTask;
 import com.qmth.teachcloud.mark.entity.MarkUserQuestion;
+import com.qmth.teachcloud.mark.enums.LockType;
 import com.qmth.teachcloud.mark.enums.MarkTaskStatus;
+import com.qmth.teachcloud.mark.lock.LockService;
 import com.qmth.teachcloud.mark.mapper.MarkQuestionMapper;
 import com.qmth.teachcloud.mark.params.MarkObjectiveQuestionParams;
 import com.qmth.teachcloud.mark.params.MarkQuestionParams;
@@ -51,6 +53,7 @@ import org.springframework.web.multipart.MultipartFile;
 
 import javax.annotation.Resource;
 import javax.servlet.http.HttpServletResponse;
+import java.math.BigDecimal;
 import java.util.*;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
@@ -86,6 +89,10 @@ public class MarkQuestionServiceImpl extends ServiceImpl<MarkQuestionMapper, Mar
     private MarkService markService;
     @Resource
     private FileStoreUtil fileStoreUtil;
+    @Resource
+    private LockService lockService;
+    @Resource
+    private MarkSyncService markSyncService;
 
     @Override
     public String assembleGroupQuestionsByExamIdAndPaperNumberAndNumber(Long examId, String paperNumber, Integer groupNumber) {
@@ -740,12 +747,33 @@ public class MarkQuestionServiceImpl extends ServiceImpl<MarkQuestionMapper, Mar
 
     @Override
     public void updateDoubleMarkByQuestionId(DoubleMarkParam doubleMarkParam) {
+        Long examId = doubleMarkParam.getExamId();
+        String paperNumber = doubleMarkParam.getPaperNumber();
+        Long questionId = doubleMarkParam.getQuestionId();
+        List<MarkTaskStatus> markTaskStatuses = Arrays.asList(MarkTaskStatus.MARKED, MarkTaskStatus.WAIT_ARBITRATE, MarkTaskStatus.PROBLEM, MarkTaskStatus.REJECTED, MarkTaskStatus.ARBITRATED);
+        if (markTaskService.countByExamIdAndPaperNumberAndQuestionIdAndStatusIn(examId, paperNumber, questionId, markTaskStatuses) > 0) {
+            throw ExceptionResultEnum.ERROR.exception("该题已开始评卷,不允许修改");
+        }
+
+        MarkQuestion markQuestion = this.getById(questionId);
+
         UpdateWrapper<MarkQuestion> updateWrapper = new UpdateWrapper<>();
         updateWrapper.lambda().set(MarkQuestion::getDoubleRate, doubleMarkParam.getDoubleRate())
                 .set(MarkQuestion::getArbitrateThreshold, doubleMarkParam.getArbitrateThreshold())
                 .set(MarkQuestion::getScorePolicy, doubleMarkParam.getScorePolicy())
                 .eq(MarkQuestion::getId, doubleMarkParam.getQuestionId());
         this.update(updateWrapper);
+
+        // 单、又评切换、双评比例修改,删除任务
+        if (!markQuestion.getDoubleRate().equals(doubleMarkParam.getDoubleRate())) {
+            this.updateMarkedCount(questionId, 0);
+            this.updateTaskCount(questionId, 0);
+            if (lockService.trylock(LockType.QUESTION_UPDATE, questionId)) {
+                markSyncService.deleteMarkTask(markQuestion);
+            }
+        }
+
+
     }
 
     @Override

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

@@ -39,4 +39,13 @@ public class MarkRejectHistoryServiceImpl extends ServiceImpl<MarkRejectHistoryM
         return rejectHistoryDtoIPage;
     }
 
+    @Override
+    public void deleteByExamIdAndPaperNumberAndQuestionId(Long examId, String paperNumber, Long questionId) {
+        UpdateWrapper<MarkRejectHistory> updateWrapper = new UpdateWrapper<>();
+        updateWrapper.lambda().eq(MarkRejectHistory::getExamId, examId)
+                .eq(MarkRejectHistory::getPaperNumber, paperNumber)
+                .eq(MarkRejectHistory::getQuestionId, questionId);
+        this.remove(updateWrapper);
+    }
+
 }

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

@@ -120,11 +120,10 @@ public class MarkServiceImpl implements MarkService {
      */
     @Override
     public int applyCurrentCount(MarkQuestion markQuestion) {
-        // todo 正在评卷数量查询 (评卷员和评卷分组分开2个方法)
         TaskLock taskLock = getTaskLock(markQuestion);
         int count = 0;
         if (taskLock != null) {
-            count = taskLock.count();
+            count = taskLock.count(markQuestion.getId());
         }
         return count;
     }
@@ -372,7 +371,7 @@ public class MarkServiceImpl implements MarkService {
                 scoreCalculate(studentId, version);
             } else {//否则更新该学生主观题状态为未阅卷
 //                markStudentService.updateSubjectiveStatusAndScore(studentId, SubjectiveStatus.UNMARK, null, null);
-                markStudentService.updateSubjectiveScoreByVersion(studentId, SubjectiveStatus.MARKED, null, null, version);
+                markStudentService.updateSubjectiveScoreByVersion(studentId, SubjectiveStatus.UNMARK, null, null, version);
             }
         } catch (Exception e) {
             log.error(SystemConstant.LOG_ERROR, e);
@@ -423,8 +422,7 @@ public class MarkServiceImpl implements MarkService {
                 return;
             }
             int count = 0;
-            List<MarkStudent> studentList = markStudentService.listUnMarkTaskStudent(markQuestion.getExamId(), markQuestion.getPaperNumber(), markQuestion.getId(), pageSize);
-            while (CollectionUtils.isNotEmpty(studentList)) {
+            List<MarkStudent> studentList = markStudentService.listUnMarkTaskStudent(markQuestion.getExamId(), markQuestion.getPaperNumber(), markQuestion.getId(), pageSize);while (CollectionUtils.isNotEmpty(studentList)) {
                 // 已生成的双评任务总数的第一组任务数
                 int doubleMarkTaskCount1 = markTaskService.countByExamIdAndPaperNumberAndQuestionIdAndTaskNumber(
                         markQuestion.getExamId(), markQuestion.getPaperNumber(), markQuestion.getId(), 1);
@@ -844,6 +842,7 @@ public class MarkServiceImpl implements MarkService {
                 Set<Long> questions = markTaskList.stream().map(MarkTask::getQuestionId).collect(Collectors.toSet());
                 if (this.applyTask(examId, paperNumber, studentId, 1, userId, questions)) {
                     task = taskService.build(userId, markTaskList);
+                    break;
                 }
             }
 
@@ -954,7 +953,7 @@ public class MarkServiceImpl implements MarkService {
 
     private SubmitResult submitResult(Long examId, String paperNumber, Long userId, MarkResult result) {
         int spentAvg = result.getSpent() / result.getQuestionList().size();
-        int i = 0;
+        int count = 0;
         for (MarkResultQuestion markResultQuestion : result.getQuestionList()) {
             try {
                 lockService.watch(LockType.QUESTION, markResultQuestion.getQuestionId());
@@ -974,13 +973,13 @@ public class MarkServiceImpl implements MarkService {
                             updateMarkedCount(markUserQuestion.getExamId(), markUserQuestion.getPaperNumber(), markUserQuestion.getQuestionId());
                             // 未评完
                             resetStudentGroup(task.getStudentId());
-                            i++;
+                            count++;
                         }
                     }
                     if (markResultQuestion.getMarkerScore() <= markQuestion.getTotalScore()) {//阅卷分是否小于等于该组总分
                         if (submitTask(task, userId, markQuestion, markResultQuestion)) {
                             updateMarkedCount(markUserQuestion.getExamId(), markUserQuestion.getPaperNumber(), markUserQuestion.getQuestionId());
-                            i++;
+                            count++;
                         }
                     }
                 }
@@ -990,7 +989,7 @@ public class MarkServiceImpl implements MarkService {
                 lockService.unwatch(LockType.QUESTION, markResultQuestion.getQuestionId());
             }
         }
-        if (CollectionUtils.size(result.getQuestionList()) == i) {
+        if (CollectionUtils.size(result.getQuestionList()) == count) {
             return SubmitResult.success(examId, paperNumber, result.getStudentId());
         } else {
             return SubmitResult.faile();
@@ -1131,4 +1130,41 @@ public class MarkServiceImpl implements MarkService {
         }
     }
 
+    @Override
+    public void deleteMarkTask(MarkQuestion markQuestion) {
+        // 正评相关数据
+        markArbitrateHistoryService.deleteByExamIdAndPaperNumberAndQuestionId(markQuestion.getExamId(), markQuestion.getPaperNumber(), markQuestion.getId());
+        markProblemHistoryService.deleteByExamIdAndPaperNumberAndQuestionId(markQuestion.getExamId(), markQuestion.getPaperNumber(), markQuestion.getId());
+        markTaskService.deleteByExamIdAndPaperNumberAndQuestionId(markQuestion.getExamId(), markQuestion.getPaperNumber(), markQuestion.getId());
+        markRejectHistoryService.deleteByExamIdAndPaperNumberAndQuestionId(markQuestion.getExamId(), markQuestion.getPaperNumber(), markQuestion.getId());
+        markSubjectiveScoreService.deleteByExamIdAndPaperNumberAndQuestionId(markQuestion.getExamId(), markQuestion.getPaperNumber(), markQuestion.getId());
+        // 释放本小题所有评卷员的任务
+        List<MarkUserQuestion> markUserQuestions = markUserQuestionService.listByExamIdAndPaperNumberAndQuestionId(markQuestion.getExamId(), markQuestion.getPaperNumber(), markQuestion.getId());
+        for (MarkUserQuestion markUserQuestion : markUserQuestions) {
+            releaseByMarkUserGroup(markUserQuestion);
+        }
+
+        // 未分组的题目
+//        long unGroupQuestionCount = markQuestionService.countByExamIdAndPaperNumberAndObjectiveAndGroupNumberIsNull(
+//                markGroup.getExamId(), markGroup.getPaperNumber(), false);
+//        // 考生整体状态与总分更新
+//        long groupCount = markGroupService.countByExamIdAndPaperNumber(markGroup.getExamId(),
+//                markGroup.getPaperNumber());
+//        if (groupCount == 0 || unGroupQuestionCount > 0) {
+//            markStudentService.updateSubjectiveStatusAndScore(markGroup.getExamId(), markGroup.getPaperNumber(),
+//                    SubjectiveStatus.UNMARK, null, null);
+//        } else {
+//            List<Long> studentList = markStudentService.findIdByExamIdAndPaperNumber(markGroup.getExamId(), markGroup.getPaperNumber());
+//            for (Long studentId : studentList) {
+//                checkStudentSubjective(studentId, groupCount, unGroupQuestionCount);
+//            }
+//        }
+    }
+
+    @Override
+    public void releaseByMarkQuestion(MarkQuestion markQuestion) {
+        TaskLock taskLock = getTaskLock(markQuestion);
+        taskLock.clear();
+    }
+
 }

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

@@ -91,4 +91,13 @@ public class MarkSubjectiveScoreServiceImpl extends MppServiceImpl<MarkSubjectiv
         return this.count(queryWrapper);
     }
 
+    @Override
+    public void deleteByExamIdAndPaperNumberAndQuestionId(Long examId, String paperNumber, Long questionId) {
+        UpdateWrapper<MarkSubjectiveScore> updateWrapper = new UpdateWrapper<>();
+        updateWrapper.lambda().eq(MarkSubjectiveScore::getExamId, examId)
+                .eq(MarkSubjectiveScore::getPaperNumber, paperNumber)
+                .eq(MarkSubjectiveScore::getQuestionId, questionId);
+        this.remove(updateWrapper);
+    }
+
 }

+ 20 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkSyncServiceImpl.java

@@ -1,5 +1,6 @@
 package com.qmth.teachcloud.mark.service.impl;
 
+import com.qmth.teachcloud.common.entity.MarkQuestion;
 import com.qmth.teachcloud.mark.entity.MarkPaper;
 import com.qmth.teachcloud.mark.entity.MarkUserQuestion;
 import com.qmth.teachcloud.mark.enums.LockType;
@@ -75,4 +76,23 @@ public class MarkSyncServiceImpl implements MarkSyncService {
             lockService.unlock(LockType.SCORE_CALCULATE, markPaper.getId());
         }
     }
+
+    @Async
+    @Override
+    public void deleteMarkTask(MarkQuestion markQuestion) {
+        if (markQuestion == null) {
+            return;
+        }
+        try {
+            lockService.waitlock(LockType.EXAM_SUBJECT, markQuestion.getExamId(), markQuestion.getPaperNumber());
+            lockService.waitlock(LockType.QUESTION, markQuestion.getId());
+            markService.deleteMarkTask(markQuestion);
+        } catch (Exception e) {
+            log.error("delete group error", e);
+        } finally {
+            lockService.unlock(LockType.QUESTION, markQuestion.getId());
+            lockService.unlock(LockType.EXAM_SUBJECT, markQuestion.getExamId(), markQuestion.getPaperNumber());
+            lockService.unlock(LockType.QUESTION_UPDATE, markQuestion.getId());
+        }
+    }
 }

+ 18 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkTaskServiceImpl.java

@@ -223,11 +223,29 @@ public class MarkTaskServiceImpl extends ServiceImpl<MarkTaskMapper, MarkTask> i
         this.remove(updateWrapper);
     }
 
+    @Override
+    public void deleteByExamIdAndPaperNumberAndQuestionId(Long examId, String paperNumber, Long questionId) {
+        UpdateWrapper<MarkTask> updateWrapper = new UpdateWrapper<>();
+        updateWrapper.lambda().eq(MarkTask::getExamId, examId)
+                .eq(MarkTask::getPaperNumber, paperNumber)
+                .eq(MarkTask::getQuestionId, questionId);
+        this.remove(updateWrapper);
+    }
+
     @Override
     public int countByExamIdAndPaperNumberAndQuestionIdAndUserIdAndAndClassNameStatusIn(Long examId, String paperNumber, Long questionId, Long userId, List<String> className, MarkTaskStatus... status) {
         return this.baseMapper.countByExamIdAndPaperNumberAndQuestionIdAndUserIdAndAndClassNameStatusIn(examId, paperNumber, questionId, userId, className, status);
     }
 
+    @Override
+    public int countByExamIdAndPaperNumberAndUserIdAndAndClassNameStatusIn(Long examId, String paperNumber, Long markerId, Long userId, List<String> className, String status) {
+        if(status == null){
+            return this.baseMapper.countByExamIdAndPaperNumberAndUserIdAndAndClassName(examId, paperNumber, markerId, userId, className);
+        } else {
+            return this.baseMapper.countByExamIdAndPaperNumberAndUserIdAndAndClassNameStatusIn(examId, paperNumber, markerId, userId, className, status);
+        }
+    }
+
     @Override
     public IPage<Long> listPageHistory(Page<Long> page, Long userId, Long examId, String paperNumber, String secretNumber, Double markerScore) {
         return this.baseMapper.listPageHistory(page, userId, examId, paperNumber, secretNumber, markerScore);

+ 2 - 4
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkUserQuestionServiceImpl.java

@@ -74,8 +74,6 @@ public class MarkUserQuestionServiceImpl extends ServiceImpl<MarkUserQuestionMap
         Page<MarkUserQuestion> page = new Page<>(pageNumber, pageSize);
         IPage<MarkEntranceDto> markEntranceDtoIPage = this.baseMapper.listEntranceGroup(page, examId, openCollegeId, courseId, paperNumber, sysUser.getId(), MarkPaperStatus.FORMAL.name());
         for (MarkEntranceDto record : markEntranceDtoIPage.getRecords()) {
-            int taskCount = 0;
-            int markedCount = 0;
             MarkPaper markPaper = markPaperService.getByExamIdAndPaperNumber(record.getExamId(), record.getPaperNumber());
             // 分班阅
             List<String> classNames = null;
@@ -85,9 +83,9 @@ public class MarkUserQuestionServiceImpl extends ServiceImpl<MarkUserQuestionMap
                     classNames = markUserClassList.stream().map(MarkUserClass::getClassName).collect(Collectors.toList());
                 }
             }
-            taskCount = markTaskService.countByExamIdAndPaperNumberAndQuestionIdAndUserIdAndAndClassNameStatusIn(record.getExamId(), record.getPaperNumber(), null, null, classNames);
+            int taskCount = markTaskService.countByExamIdAndPaperNumberAndUserIdAndAndClassNameStatusIn(record.getExamId(), record.getPaperNumber(),null, sysUser.getId(), classNames, null);
             record.setTaskCount(taskCount);
-            markedCount = markTaskService.countByExamIdAndPaperNumberAndQuestionIdAndUserIdAndAndClassNameStatusIn(record.getExamId(), record.getPaperNumber(), null, null, classNames, MarkTaskStatus.MARKED, MarkTaskStatus.ARBITRATED);
+            int markedCount = markTaskService.countByExamIdAndPaperNumberAndUserIdAndAndClassNameStatusIn(record.getExamId(), record.getPaperNumber(),sysUser.getId(), sysUser.getId(), classNames, "('"+MarkTaskStatus.MARKED+"','"+MarkTaskStatus.ARBITRATED+"')");
             record.setMarkedCount(markedCount);
 
             record.setLeftCount(taskCount == 0 ? 0 : taskCount - markedCount);

+ 16 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/utils/TaskLock.java

@@ -161,6 +161,18 @@ public class TaskLock {
         return count;
     }
 
+    public int count(Long questionId) {
+        int count = 0;
+        LockNode node = head.next;
+        while (node != null) {
+            if (node.containsQuestionId(questionId)) {
+                count++;
+            }
+            node = node.next;
+        }
+        return count;
+    }
+
     public List<Map<String, Object>> list() {
         List<Map<String, Object>> list = new LinkedList<>();
         LockNode node = head.next;
@@ -216,6 +228,10 @@ public class TaskLock {
             return this.owner.equals(owner);
         }
 
+        private boolean containsQuestionId(Long questionId) {
+            return this.questions.contains(questionId);
+        }
+
         private void remove() {
             this.previous.next = this.next;
             if (this.next != null) {

+ 1 - 1
teachcloud-mark/src/main/resources/mapper/MarkStudentMapper.xml

@@ -1083,7 +1083,7 @@
         where exists(select 1 from basic_school bs where bs.enable = true and bs.id = be.school_id)
         and be.enable = true and be.id = mp.exam_id) and ms.exam_id = mp.exam_id and ms.paper_number = mp.paper_number)
         and (ms.subjective_status = 'UNMARK' or ms.subjective_score = 0 or ms.subjective_score is null)
-        and ms.is_upload = true and (ms.is_absent = true or ms.is_manual_absent = true or omr_absent = true)
+        and ms.is_upload = true and (ms.is_absent = false and ms.is_manual_absent = false and omr_absent = false)
         <!--and exists(select 1 from mark_task mt where ms.id = mt.student_id)*-->
         <if test="limit != null and limit != ''">
             ${limit}

+ 117 - 27
teachcloud-mark/src/main/resources/mapper/MarkTaskMapper.xml

@@ -292,6 +292,95 @@
             mt.student_id = ms.id)
         </if>
     </select>
+    <select id="countByExamIdAndPaperNumberAndUserIdAndAndClassName" resultType="java.lang.Integer">
+        SELECT
+        count(distinct mt.student_id)
+        FROM
+        mark_task mt
+        WHERE
+        mt.exam_id = #{examId}
+        AND mt.paper_number = #{paperNumber}
+        <if test="markerId != null">
+            AND mt.user_id = #{markerId}
+        </if>
+        AND EXISTS( SELECT
+            1
+                FROM
+            mark_user_question muq
+        WHERE
+            mt.exam_id = muq.exam_id
+            AND mt.paper_number = muq.paper_number
+            AND mt.question_id = muq.question_id
+            AND muq.user_id = #{userId}
+            AND muq.enable = true)
+        <if test="classNames != null and classNames.size() > 0">
+            AND EXISTS( SELECT
+            ms.id, ms.exam_id, ms.paper_number, bes.teach_class_name
+            FROM
+            (SELECT
+            *
+            FROM
+            mark_student
+            WHERE
+            exam_id = #{examId} AND paper_number = #{paperNumber}) ms
+            JOIN (SELECT
+            *
+            FROM
+            basic_exam_student
+            WHERE
+            exam_id = #{examId} AND teach_class_name in
+            <foreach collection="classNames" item="className" separator="," open="(" close=")">
+                #{className}
+            </foreach>) bes ON ms.basic_student_id = bes.id
+            WHERE
+            mt.student_id = ms.id)
+        </if>
+    </select>
+    <select id="countByExamIdAndPaperNumberAndUserIdAndAndClassNameStatusIn" resultType="java.lang.Integer">
+        select count(distinct t.student_id) from (SELECT
+        mt.student_id,
+        sum(case when mt.status in ('ARBITRATED','MARKED') then 0 else 1 end) unMarkCount
+        FROM
+        mark_task mt
+        WHERE
+        mt.exam_id = #{examId}
+        AND mt.paper_number = #{paperNumber}
+        <if test="markerId != null">
+            AND mt.user_id = #{markerId}
+        </if>
+        AND EXISTS( SELECT
+        1
+        FROM
+        mark_user_question muq
+        WHERE
+        mt.exam_id = muq.exam_id
+        AND mt.paper_number = muq.paper_number
+        AND mt.question_id = muq.question_id
+        AND muq.user_id = #{userId}
+        AND muq.enable = true)
+        <if test="classNames != null and classNames.size() > 0">
+            AND EXISTS( SELECT
+            ms.id, ms.exam_id, ms.paper_number, bes.teach_class_name
+            FROM
+            (SELECT
+            *
+            FROM
+            mark_student
+            WHERE
+            exam_id = #{examId} AND paper_number = #{paperNumber}) ms
+            JOIN (SELECT
+            *
+            FROM
+            basic_exam_student
+            WHERE
+            exam_id = #{examId} AND teach_class_name in
+            <foreach collection="classNames" item="className" separator="," open="(" close=")">
+                #{className}
+            </foreach>) bes ON ms.basic_student_id = bes.id
+            WHERE
+            mt.student_id = ms.id)
+        </if> group by mt.student_id) t where t.unMarkCount = 0
+    </select>
     <select id="pageMarkTask" resultType="com.qmth.teachcloud.mark.dto.mark.manage.MarkTaskDto">
         SELECT
             mt.*,
@@ -384,35 +473,36 @@
     </select>
     <select id="listByStudentIdAndUserId" resultType="com.qmth.teachcloud.mark.entity.MarkTask">
         SELECT
-            mt.*
+            t.*
         FROM
-            mark_task mt
+            (SELECT
+                 *
+             FROM
+                 mark_task
+             WHERE
+                 student_id = #{studentId}) t
         <where>
-            mt.student_id = #{studentId}
-            and (mt.user_id is null or mt.user_id =#{userId})
-            and (mt.status='WAITING' or mt.status='REJECTED')
-            AND EXISTS( SELECT
-                          1
-                      FROM
-                          mark_user_question muq
-                      WHERE
-                          mt.exam_id = muq.exam_id
-                        AND mt.paper_Number = muq.paper_number
-                        AND mt.question_id = muq.question_id
-                        AND muq.user_id = #{userId}
-                        AND muq.enable = true)
-            AND NOT EXISTS (
-                SELECT 1 FROM
-                    mark_task t
-                WHERE
-                t.student_id = mt.student_id
-                AND t.exam_id = mt.exam_id
-                AND t.paper_number = mt.paper_number
-                AND t.question_id = mt.question_id
-                AND t.user_id = #{userId}
-                AND t.marker_score IS NOT NULL
-            )
-            order by mt.main_number, mt.sub_number
+                t.id IN (SELECT
+                             MIN(id) AS id
+                         FROM
+                             mark_task mt
+                         WHERE
+                             mt.student_id = #{studentId}
+                           AND mt.user_id IS NULL
+                           AND (mt.status = 'WAITING'
+                             OR mt.status = 'REJECTED')
+                           AND EXISTS( SELECT
+                                           1
+                                       FROM
+                                           mark_user_question muq
+                                       WHERE
+                                           mt.exam_id = muq.exam_id
+                                         AND mt.paper_Number = muq.paper_number
+                                         AND mt.question_id = muq.question_id
+                                         AND muq.user_id = #{userId}
+                                         AND muq.enable = TRUE)
+                         GROUP BY mt.question_id)
+            order by t.main_number, t.sub_number
         </where>
     </select>
 </mapper>

+ 1 - 5
teachcloud-mark/src/main/resources/mapper/MarkUserQuestionMapper.xml

@@ -129,11 +129,7 @@
                         and muq.class_name = #{className})
             </if>
             <if test="marked == true">
-                AND EXISTS (select 1 from mark_task mt
-                where muq.exam_id = mt.exam_id
-                and muq.paper_number = mt.paper_number
-                and muq.user_id = mt.user_id
-                and mt.status in ('MARKED','ARBITRATED','WAIT_ARBITRATE'))
+                AND muq.finish_count > 0
             </if>
         </where>
     </select>