浏览代码

扫描空白页、手输客观题答案,增加强制绑定标记

yin 1 年之前
父节点
当前提交
31a284945e

+ 6 - 2
distributed-print-business/src/main/resources/db/log/update-yin.sql

@@ -1,5 +1,9 @@
 update mark_question t
 set t.objective_policy = 'LEAK'
-where t.category = 'LEAK_HALF';
+where t.objective_policy = 'LEAK_HALF';
 ALTER TABLE `mark_question`
-    ADD COLUMN `objective_policy_score` double DEFAULT NULL COMMENT '客观题判分策略计分';
+    ADD COLUMN `objective_policy_score` double DEFAULT NULL COMMENT '客观题判分策略计分';
+ALTER TABLE `scan_paper`
+    ADD COLUMN `invalid` bit(1) NOT NULL COMMENT '强制绑定';
+ALTER TABLE `mark_student`
+    ADD COLUMN `invalid` bit(1) NOT NULL COMMENT '强制绑定';

+ 10 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/bean/answerbatch/AnswerPaper.java

@@ -21,6 +21,9 @@ public class AnswerPaper {
     @NotNull(message = "paper.assigned不能为空")
     private Boolean assigned;
 
+    @NotNull(message = "paper.invalid")
+    private Boolean invalid;
+
     @Valid
     @NotNull(message = "paper.pages不能为空")
     @Size(min = 1, message = "paper.pages不能为空")
@@ -79,4 +82,11 @@ public class AnswerPaper {
         return list;
     }
 
+    public Boolean getInvalid() {
+        return invalid;
+    }
+
+    public void setInvalid(Boolean invalid) {
+        this.invalid = invalid;
+    }
 }

+ 10 - 1
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/bean/scananswer/AnswerPaperVo.java

@@ -9,6 +9,8 @@ public class AnswerPaperVo {
 	private Long id;
 	private Integer number;
 	private Boolean assigned;
+
+	private Boolean invalid;
 	private List<AnswerPageVo> pages;
 	public Long getId() {
 		return id;
@@ -34,5 +36,12 @@ public class AnswerPaperVo {
 	public void setPages(List<AnswerPageVo> pages) {
 		this.pages = pages;
 	}
-	
+
+	public Boolean getInvalid() {
+		return invalid;
+	}
+
+	public void setInvalid(Boolean invalid) {
+		this.invalid = invalid;
+	}
 }

+ 10 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/bean/scananswer/AnswerQueryDomain.java

@@ -43,6 +43,8 @@ public class AnswerQueryDomain extends PagerQuery {
     private Boolean assigned;
     private Boolean assignConfirmed;
 
+	private Boolean invalid;
+
     private Boolean incomplete;
 
     private Boolean questionFilled;
@@ -186,4 +188,12 @@ public class AnswerQueryDomain extends PagerQuery {
 	public void setMarkPaperStatus(String markPaperStatus) {
 		this.markPaperStatus = markPaperStatus;
 	}
+
+	public Boolean getInvalid() {
+		return invalid;
+	}
+
+	public void setInvalid(Boolean invalid) {
+		this.invalid = invalid;
+	}
 }

+ 9 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/bean/scananswer/AnswerQueryVo.java

@@ -38,6 +38,8 @@ public class AnswerQueryVo {
 
 	private Boolean assigned;
 
+	private Boolean invalid;
+
 	private Boolean incomplete;
 
 	private Integer cardNumber;
@@ -251,4 +253,11 @@ public class AnswerQueryVo {
 		this.isAbsent = isAbsent;
 	}
 
+	public Boolean getInvalid() {
+		return invalid;
+	}
+
+	public void setInvalid(Boolean invalid) {
+		this.invalid = invalid;
+	}
 }

+ 10 - 1
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/bean/scananswer/StudentPaperVo.java

@@ -5,6 +5,8 @@ public class StudentPaperVo {
 	private Long studentId;
 	private Integer number;
 	private Boolean assigned;
+	private Boolean invalid;
+
 	public Integer getNumber() {
 		return number;
 	}
@@ -29,5 +31,12 @@ public class StudentPaperVo {
 	public void setStudentId(Long studentId) {
 		this.studentId = studentId;
 	}
-	
+
+	public Boolean getInvalid() {
+		return invalid;
+	}
+
+	public void setInvalid(Boolean invalid) {
+		this.invalid = invalid;
+	}
 }

+ 13 - 3
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/entity/MarkStudent.java

@@ -5,20 +5,20 @@ import java.util.ArrayList;
 import java.util.LinkedList;
 import java.util.List;
 
-import com.baomidou.mybatisplus.annotation.FieldStrategy;
-import com.baomidou.mybatisplus.annotation.TableField;
 import org.apache.commons.lang.math.RandomUtils;
 import org.apache.commons.lang3.StringUtils;
 
 import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.annotation.FieldStrategy;
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
 import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.qmth.teachcloud.common.bean.vo.FilePathVo;
 import com.qmth.teachcloud.common.entity.MarkQuestion;
 import com.qmth.teachcloud.common.enums.ScanStatus;
 import com.qmth.teachcloud.common.enums.mark.SubjectiveStatus;
-import com.qmth.teachcloud.common.bean.vo.FilePathVo;
 import com.qmth.teachcloud.mark.dto.mark.ScoreItem;
 import com.qmth.teachcloud.mark.utils.BigDecimalUtils;
 
@@ -179,6 +179,9 @@ public class MarkStudent implements Serializable {
     private Boolean assigned;
     //人工绑定确认
     private Boolean assignConfirmed;
+    //强制绑定,强制绑定为true时,assigned也为true
+    private Boolean invalid;
+
     // 是否标记异常
     private Boolean absentSuspect;
 
@@ -726,7 +729,13 @@ public class MarkStudent implements Serializable {
     public void setMarkPaperStatus(String markPaperStatus) {
         this.markPaperStatus = markPaperStatus;
     }
+    public Boolean getInvalid() {
+        return invalid;
+    }
 
+    public void setInvalid(Boolean invalid) {
+        this.invalid = invalid;
+    }
     @Override
     public String toString() {
         return "MarkStudent{" +
@@ -763,6 +772,7 @@ public class MarkStudent implements Serializable {
                 ", scanStatus=" + scanStatus +
                 ", questionFilled=" + questionFilled +
                 ", assigned=" + assigned +
+                ", invalid=" + invalid +
                 ", absentSuspect=" + absentSuspect +
                 ", incomplete=" + incomplete +
                 ", breachCode=" + breachCode +

+ 11 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/entity/ScanPaper.java

@@ -46,6 +46,8 @@ public class ScanPaper implements Serializable {
 
     private Boolean assigned;
 
+    private Boolean invalid;
+
     private Boolean questionFilled;
 
     @JsonSerialize(using = ToStringSerializer.class)
@@ -185,6 +187,7 @@ public class ScanPaper implements Serializable {
                 ", pageCount=" + pageCount +
                 ", mismatch=" + mismatch +
                 ", assigned=" + assigned +
+                ", invalid=" + invalid +
                 ", questionFilled=" + questionFilled +
                 ", creatorId=" + creatorId +
                 ", updaterId=" + updaterId +
@@ -192,4 +195,12 @@ public class ScanPaper implements Serializable {
                 ", updateTime=" + updateTime +
                 "}";
     }
+
+    public Boolean getInvalid() {
+        return invalid;
+    }
+
+    public void setInvalid(Boolean invalid) {
+        this.invalid = invalid;
+    }
 }

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

@@ -320,6 +320,7 @@ public class MarkStudentServiceImpl extends ServiceImpl<MarkStudentMapper, MarkS
         // 重置状态
         student.setIncomplete(false);
         student.setAssigned(false);
+        student.setInvalid(false);
         student.setQuestionFilled(false);
         // student.setOmrAbsent(false);
         int paperCount = 0;
@@ -330,6 +331,7 @@ public class MarkStudentServiceImpl extends ServiceImpl<MarkStudentMapper, MarkS
             // 获取paper详情更新考生状态
             ScanPaper paper = scanPaperService.getById(studentPaper.getPaperId());
             student.setAssigned(student.getAssigned() || paper.getAssigned());
+            student.setInvalid(student.getInvalid() || paper.getInvalid());
             student.setQuestionFilled(student.getQuestionFilled() || paper.getQuestionFilled());
             student.setCardNumber(paper.getCardNumber());
             // 单独判断首张纸正面的识别结果
@@ -681,6 +683,7 @@ public class MarkStudentServiceImpl extends ServiceImpl<MarkStudentMapper, MarkS
                     pvo.setId(p.getPaperId());
                     pvo.setNumber(p.getNumber());
                     pvo.setAssigned(p.getAssigned());
+                    pvo.setInvalid(p.getInvalid());
                     paperMap.put(p.getPaperId(), pvo);
                 }
                 // 查找page

+ 16 - 9
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/ScanBatchServiceImpl.java

@@ -1,5 +1,16 @@
 package com.qmth.teachcloud.mark.service.impl;
 
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.annotation.Resource;
+
+import org.apache.commons.collections4.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.multipart.MultipartFile;
+
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.qmth.boot.core.concurrent.service.ConcurrentService;
 import com.qmth.boot.core.exception.ParameterException;
@@ -14,15 +25,6 @@ import com.qmth.teachcloud.mark.enums.BatchStatus;
 import com.qmth.teachcloud.mark.enums.LockType;
 import com.qmth.teachcloud.mark.mapper.ScanBatchMapper;
 import com.qmth.teachcloud.mark.service.*;
-import org.apache.commons.collections4.CollectionUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-import org.springframework.web.multipart.MultipartFile;
-
-import javax.annotation.Resource;
-import java.util.ArrayList;
-import java.util.List;
 
 /**
  * <p>
@@ -148,6 +150,10 @@ public class ScanBatchServiceImpl extends ServiceImpl<ScanBatchMapper, ScanBatch
         for (AnswerPaper answerPaper : domain.getPapers()) {
             // 验证page数量
             answerPaper.answerCardValidate(answerCard);
+            //验证强制输入必须为人工绑定
+            if (answerPaper.getInvalid() && !answerPaper.getAssigned()) {
+                throw new ParameterException("强制输入必须为人工绑定");
+            }
             Integer paperNumber = answerPaper.getNumber();
             ScanPaper paper = findOrCreatePaper(scanBatch, student, paperNumber, user);
             // 设置paper属性
@@ -157,6 +163,7 @@ public class ScanBatchServiceImpl extends ServiceImpl<ScanBatchMapper, ScanBatch
             paper.setMismatch(false);
             paper.setQuestionFilled(false);
             paper.setAssigned(answerPaper.getAssigned());
+            paper.setInvalid(answerPaper.getInvalid());
             // 保存paper与page到数据库
             scanPaperService.savePaperAndPages(paper, answerPaper.buildPageList());
             // 记录paper与batch关联关系

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

@@ -230,8 +230,9 @@ public class ScanOmrTaskServiceImpl extends ServiceImpl<ScanOmrTaskMapper, ScanO
                     for (int i = 0; i < size; i++) {
                         String result = pageEntity.getQuestion().getResult().get(i);
                         MarkQuestion question = questiongList.get(i);
+                        String newStr = result.replace(OMR_SUSPECT, "");
                         if (question.getQuestionType().equals(QuestionType.SINGLE.getValue()) && result != null
-                                && result.length() > 1) {
+                                && newStr.length() > 1) {
                             OmrTaskItem item = new OmrTaskItem();
                             item.setIndex(i + 1);
                             item.setField(OmrField.QUESTION);

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

@@ -251,6 +251,7 @@ public class ScanPaperServiceImpl extends ServiceImpl<ScanPaperMapper, ScanPaper
         ms.setScanStatus(ScanStatus.UNEXIST);
         ms.setQuestionFilled(false);
         ms.setAssigned(false);
+        ms.setInvalid(false);
         ms.setAssignConfirmed(false);
         ms.setAbsentSuspect(false);
         ms.setIncomplete(false);

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

@@ -4,199 +4,194 @@
 
     <!-- 通用查询映射结果 -->
     <resultMap id="BaseResultMap" type="com.qmth.teachcloud.mark.entity.MarkStudent">
-        <id column="id" property="id" />
-        <result column="exam_id" property="examId" />
-        <result column="course_code" property="courseCode" />
-        <result column="course_name" property="courseName" />
-        <result column="paper_number" property="paperNumber" />
-        <result column="course_paper_id" property="coursePaperId" />
-        <result column="secret_number" property="secretNumber" />
-        <result column="student_code" property="studentCode" />
-        <result column="student_name" property="studentName" />
-        <result column="package_code" property="packageCode" />
-        <result column="exam_place" property="examPlace" />
-        <result column="exam_room" property="examRoom" />
-        <result column="remark" property="remark" />
-        <result column="batch_code" property="batchCode" />
-        <result column="sheet_count" property="sheetCount" />
-        <result column="answers" property="answers" />
-        <result column="is_upload" property="upload" />
-        <result column="is_absent" property="absent" />
-        <result column="is_manual_absent" property="manualAbsent" />
-        <result column="is_breach" property="breach" />
-        <result column="upload_time" property="uploadTime" />
-        <result column="check_time" property="checkTime" />
-        <result column="check_user_id" property="checkUserId" />
-        <result column="objective_score" property="objectiveScore" />
-        <result column="objective_score_list" property="objectiveScoreList" />
-        <result column="subjective_status" property="subjectiveStatus" />
-        <result column="subjective_score" property="subjectiveScore" />
-        <result column="subjective_score_list" property="subjectiveScoreList" />
-        <result column="college" property="college" />
-        <result column="class_name" property="className" />
-        <result column="teacher" property="teacher" />
-        <result column="scan_status" property="scanStatus" />
-        <result column="omr_absent_checked" property="omrAbsentChecked" />
-        <result column="question_filled" property="questionFilled" />
-        <result column="assigned" property="assigned" />
-        <result column="absent_suspect" property="absentSuspect" />
-        <result column="incomplete" property="incomplete" />
-        <result column="breach_code" property="breachCode" />
-        <result column="card_number" property="cardNumber" />
+        <id column="id" property="id"/>
+        <result column="exam_id" property="examId"/>
+        <result column="course_code" property="courseCode"/>
+        <result column="course_name" property="courseName"/>
+        <result column="paper_number" property="paperNumber"/>
+        <result column="course_paper_id" property="coursePaperId"/>
+        <result column="secret_number" property="secretNumber"/>
+        <result column="student_code" property="studentCode"/>
+        <result column="student_name" property="studentName"/>
+        <result column="package_code" property="packageCode"/>
+        <result column="exam_place" property="examPlace"/>
+        <result column="exam_room" property="examRoom"/>
+        <result column="remark" property="remark"/>
+        <result column="batch_code" property="batchCode"/>
+        <result column="sheet_count" property="sheetCount"/>
+        <result column="answers" property="answers"/>
+        <result column="is_upload" property="upload"/>
+        <result column="is_absent" property="absent"/>
+        <result column="is_manual_absent" property="manualAbsent"/>
+        <result column="is_breach" property="breach"/>
+        <result column="upload_time" property="uploadTime"/>
+        <result column="check_time" property="checkTime"/>
+        <result column="check_user_id" property="checkUserId"/>
+        <result column="objective_score" property="objectiveScore"/>
+        <result column="objective_score_list" property="objectiveScoreList"/>
+        <result column="subjective_status" property="subjectiveStatus"/>
+        <result column="subjective_score" property="subjectiveScore"/>
+        <result column="subjective_score_list" property="subjectiveScoreList"/>
+        <result column="college" property="college"/>
+        <result column="class_name" property="className"/>
+        <result column="teacher" property="teacher"/>
+        <result column="scan_status" property="scanStatus"/>
+        <result column="omr_absent_checked" property="omrAbsentChecked"/>
+        <result column="question_filled" property="questionFilled"/>
+        <result column="assigned" property="assigned"/>
+        <result column="absent_suspect" property="absentSuspect"/>
+        <result column="incomplete" property="incomplete"/>
+        <result column="breach_code" property="breachCode"/>
+        <result column="card_number" property="cardNumber"/>
     </resultMap>
     <select id="pageStudentScore" resultType="com.qmth.teachcloud.mark.dto.mark.score.StudentScoreDetailDto">
         SELECT
-            ms.id studentId,
-            ms.exam_id examId,
-            ms.course_code courseCode,
-            ms.course_name courseName,
-            ms.paper_number paperNumber,
-            ms.student_name studentName,
-            ms.student_code studentCode,
-            ms.secret_number secretNumber,
-            ms.college,
-            ms.major_name majorName,
-            ms.class_name className,
-            ms.objective_score objectiveScore,
-            ms.subjective_score subjectiveScore,
-            ifnull(ms.objective_score, 0) +  ifnull(ms.subjective_score, 0) totalScore,
-            ms.objective_score_list objectiveScoreList,
-            ms.subjective_score_list subjectiveScoreList,
-            ms.check_user_id checkUserId,
-            su.login_name checkUserLoginName,
-            su.real_name checkUserName,
-            ms.check_time checkTime,
-            ms.sheet_path sheetPath,
-            ms.exam_start_time examStartTime,
-            ms.exam_end_time examEndTime,
-            ms.scan_status scanStatus,
-            ms.subjective_status subjectiveStatus,
-            ms.is_absent absent,
-            ms.omr_absent omrAbsent,
-            ms.is_upload upload
+        ms.id studentId,
+        ms.exam_id examId,
+        ms.course_code courseCode,
+        ms.course_name courseName,
+        ms.paper_number paperNumber,
+        ms.student_name studentName,
+        ms.student_code studentCode,
+        ms.secret_number secretNumber,
+        ms.college,
+        ms.major_name majorName,
+        ms.class_name className,
+        ms.objective_score objectiveScore,
+        ms.subjective_score subjectiveScore,
+        ifnull(ms.objective_score, 0) + ifnull(ms.subjective_score, 0) totalScore,
+        ms.objective_score_list objectiveScoreList,
+        ms.subjective_score_list subjectiveScoreList,
+        ms.check_user_id checkUserId,
+        su.login_name checkUserLoginName,
+        su.real_name checkUserName,
+        ms.check_time checkTime,
+        ms.sheet_path sheetPath,
+        ms.exam_start_time examStartTime,
+        ms.exam_end_time examEndTime,
+        ms.scan_status scanStatus,
+        ms.subjective_status subjectiveStatus,
+        ms.is_absent absent,
+        ms.omr_absent omrAbsent,
+        ms.is_upload upload
         FROM
-            mark_student ms
-                left join sys_user su on ms.check_user_id = su.id
+        mark_student ms
+        left join sys_user su on ms.check_user_id = su.id
         where ms.exam_id = #{examId}
-            AND ms.paper_number = #{paperNumber}
-            <if test="college != null and college != ''">
-                AND ms.college like concat(#{college}, '%')
-            </if>
-            <if test="majorName != null and majorName != ''">
-                AND ms.major_name like concat(#{majorName}, '%')
-            </if>
-            <if test="className != null and className != ''">
-                AND ms.class_name like concat(#{className}, '%')
-            </if>
-            <if test="teacher != null and teacher != ''">
-                AND ms.teacher = #{teacher}
-            </if>
-            <if test="filter != null">
-                <choose>
-                    <when test="filter == 1">
-                        AND ms.objective_score = 0
-                    </when>
-                    <when test="filter == 2">
-                        AND ms.objective_score = 0 AND ms.subjective_score > 0
-                    </when>
-                    <when test="filter == 3">
-                        AND ms.objective_score > 0 AND ms.subjective_score = 0
-                    </when>
-                </choose>
-            </if>
-            <if test="status != null">
-                <choose>
-                    <when test="status == 'ABSENT'">
-                        AND (ms.is_absent = 1 OR ms.omr_absent = 1 OR ms.scan_status = 'MANUAL_ABSENT')
-                    </when>
-                    <when test="status == 'NORMAL'">
-                        AND (ms.is_absent = 0 and ms.omr_absent = 0 and ms.scan_status = 'SCANNED' AND ms.is_upload = 1)
-                    </when>
-                    <otherwise>
-                        AND (ms.scan_status = 'UNEXIST')
-                    </otherwise>
-                </choose>
-            </if>
-            <if test="breach != null">
-                AND ms.is_breach = #{breach}
-            </if>
-            <if test="startScore != null">
-                <choose>
-                    <when test="startScore == 0">
-                        AND (ms.is_absent = 1 OR ms.is_breach = 1 OR ((ifnull(ms.subjective_score, 0) + ifnull(ms.objective_score, 0)) &gt;= #{startScore} AND (ifnull(ms.subjective_score,0) + ifnull(ms.objective_score,0)) &lt;= #{endScore}))
-                    </when>
-                    <otherwise>
-                        AND (ms.is_absent = 0 AND ms.is_breach = 0 AND ((ifnull(ms.subjective_score,0) + ifnull(ms.objective_score,0)) &gt;= #{startScore} AND (ifnull(ms.subjective_score,0) + ifnull(ms.objective_score,0)) &lt;= #{endScore}))
-                    </otherwise>
-                </choose>
-            </if>
-            <if test="subScore != null">
-                AND exists (SELECT 1 FROM mark_subjective_score mss WHERE ms.id = mss.student_id AND mss.score = #{subScore})
-            </if>
-            <if test="objectiveScoreLt != null">
-                AND ms.objective_score &lt; #{objectiveScoreLt}
-            </if>
-            <if test="studentName != null and studentName != ''">
-                AND ms.student_name like concat(#{studentName}, '%')
-            </if>
-            <if test="studentCode != null and studentCode != ''">
-                AND ms.student_code = #{studentCode}
-            </if>
-            <if test="orderType != null and orderType != '' and orderField != null and orderField != ''">
-                <choose>
-                    <when test="orderField == 'totalScore'">
-                        <if test="orderType == 'ASC'">
-                            order by (ifnull(ms.objective_score, 0) +  ifnull(ms.subjective_score, 0)) ASC
-                        </if>
-                        <if test="orderType == 'DESC'">
-                            order by (ifnull(ms.objective_score, 0) +  ifnull(ms.subjective_score, 0)) DESC
-                        </if>
-                    </when>
-                    <otherwise>
-                        order by #{orderField} #{orderType}
-                    </otherwise>
-                </choose>
-            </if>
-            <if test="orderType == null or orderType == '' or orderField == null or orderField == ''">
-                order by ms.student_code
-            </if>
+        AND ms.paper_number = #{paperNumber}
+        <if test="college != null and college != ''">
+            AND ms.college like concat(#{college}, '%')
+        </if>
+        <if test="majorName != null and majorName != ''">
+            AND ms.major_name like concat(#{majorName}, '%')
+        </if>
+        <if test="className != null and className != ''">
+            AND ms.class_name like concat(#{className}, '%')
+        </if>
+        <if test="teacher != null and teacher != ''">
+            AND ms.teacher = #{teacher}
+        </if>
+        <if test="filter != null">
+            <choose>
+                <when test="filter == 1">
+                    AND ms.objective_score = 0
+                </when>
+                <when test="filter == 2">
+                    AND ms.objective_score = 0 AND ms.subjective_score > 0
+                </when>
+                <when test="filter == 3">
+                    AND ms.objective_score > 0 AND ms.subjective_score = 0
+                </when>
+            </choose>
+        </if>
+        <if test="status != null">
+            <choose>
+                <when test="status == 'ABSENT'">
+                    AND (ms.is_absent = 1 OR ms.omr_absent = 1 OR ms.scan_status = 'MANUAL_ABSENT')
+                </when>
+                <when test="status == 'NORMAL'">
+                    AND (ms.is_absent = 0 and ms.omr_absent = 0 and ms.scan_status = 'SCANNED' AND ms.is_upload = 1)
+                </when>
+                <otherwise>
+                    AND (ms.scan_status = 'UNEXIST')
+                </otherwise>
+            </choose>
+        </if>
+        <if test="breach != null">
+            AND ms.is_breach = #{breach}
+        </if>
+        <if test="startScore != null">
+            <choose>
+                <when test="startScore == 0">
+                    AND (ms.is_absent = 1 OR ms.is_breach = 1 OR ((ifnull(ms.subjective_score, 0) +
+                    ifnull(ms.objective_score, 0)) &gt;= #{startScore} AND (ifnull(ms.subjective_score,0) +
+                    ifnull(ms.objective_score,0)) &lt;= #{endScore}))
+                </when>
+                <otherwise>
+                    AND (ms.is_absent = 0 AND ms.is_breach = 0 AND ((ifnull(ms.subjective_score,0) +
+                    ifnull(ms.objective_score,0)) &gt;= #{startScore} AND (ifnull(ms.subjective_score,0) +
+                    ifnull(ms.objective_score,0)) &lt;= #{endScore}))
+                </otherwise>
+            </choose>
+        </if>
+        <if test="subScore != null">
+            AND exists (SELECT 1 FROM mark_subjective_score mss WHERE ms.id = mss.student_id AND mss.score =
+            #{subScore})
+        </if>
+        <if test="objectiveScoreLt != null">
+            AND ms.objective_score &lt; #{objectiveScoreLt}
+        </if>
+        <if test="studentName != null and studentName != ''">
+            AND ms.student_name like concat(#{studentName}, '%')
+        </if>
+        <if test="studentCode != null and studentCode != ''">
+            AND ms.student_code = #{studentCode}
+        </if>
+        <if test="orderType != null and orderType != '' and orderField != null and orderField != ''">
+            <choose>
+                <when test="orderField == 'totalScore'">
+                    <if test="orderType == 'ASC'">
+                        order by (ifnull(ms.objective_score, 0) + ifnull(ms.subjective_score, 0)) ASC
+                    </if>
+                    <if test="orderType == 'DESC'">
+                        order by (ifnull(ms.objective_score, 0) + ifnull(ms.subjective_score, 0)) DESC
+                    </if>
+                </when>
+                <otherwise>
+                    order by #{orderField} #{orderType}
+                </otherwise>
+            </choose>
+        </if>
+        <if test="orderType == null or orderType == '' or orderField == null or orderField == ''">
+            order by ms.student_code
+        </if>
     </select>
     <select id="listAbsentOrBreachMarkTaskStudent" resultMap="BaseResultMap">
-        SELECT
-            *
-        FROM
-            mark_student ms
-        WHERE
-            ms.exam_id = #{examId} AND ms.paper_number = #{paperNumber}
+        SELECT *
+        FROM mark_student ms
+        WHERE ms.exam_id = #{examId}
+          AND ms.paper_number = #{paperNumber}
           AND ms.is_upload = TRUE
           AND (is_absent = TRUE OR is_breach = TRUE OR omr_absent = TRUE)
-          AND EXISTS( SELECT
-                          1
-                      FROM
-                          mark_task mt
-                      WHERE
-                          ms.id = mt.student_id)
+          AND EXISTS(SELECT 1
+                     FROM mark_task mt
+                     WHERE ms.id = mt.student_id)
     </select>
     <select id="listUnMarkTaskStudent" resultMap="BaseResultMap">
-        SELECT
-            *
-        FROM
-            mark_student ms
-        WHERE
-            ms.exam_id = #{examId} AND ms.paper_number = #{paperNumber}
+        SELECT *
+        FROM mark_student ms
+        WHERE ms.exam_id = #{examId}
+          AND ms.paper_number = #{paperNumber}
           AND ms.is_upload = TRUE
           AND is_absent = FALSE
           AND is_breach = FALSE
           AND omr_absent = FALSE
-          AND NOT EXISTS( SELECT
-                              1
-                          FROM
-                              mark_task mt
-                          WHERE
-                              ms.id = mt.student_id
-                            AND mt.group_number = #{groupNumber})
+          AND NOT EXISTS(SELECT 1
+                         FROM mark_task mt
+                         WHERE ms.id = mt.student_id
+                           AND mt.group_number = #{groupNumber})
     </select>
-	<sql id="queryWhereAndOrder">
+    <sql id="queryWhereAndOrder">
         where t.exam_id=#{query.examId}
         <if test="query.studentId != null and query.studentId !=''">
             and t.id=#{query.studentId}
@@ -229,10 +224,10 @@
         <if test="query.examPlace != null and query.examPlace !=''">
             and t.exam_place=#{query.examPlace}
         </if>
-		<if test="query.examRoom != null and query.examRoom !=''">
+        <if test="query.examRoom != null and query.examRoom !=''">
             and t.exam_room=#{query.examRoom}
         </if>
-        
+
         <if test="query.absentSuspect != null">
             and t.absent_suspect=#{query.absentSuspect}
         </if>
@@ -248,6 +243,9 @@
         <if test="query.assignConfirmed != null">
             and t.assign_confirmed=#{query.assignConfirmed}
         </if>
+        <if test="query.invalid != null">
+            and t.invalid=#{query.invalid}
+        </if>
         <if test="query.incomplete != null">
             and t.incomplete=#{query.incomplete}
         </if>
@@ -289,7 +287,10 @@
         order by t.id
     </select>
     <select id="findIdByExamIdAndPaperNumber" resultType="java.lang.Long">
-        select id from mark_student where exam_id = #{examId} and paper_number = #{paperNumber}
+        select id
+        from mark_student
+        where exam_id = #{examId}
+          and paper_number = #{paperNumber}
     </select>
     <select id="studentList"
             resultType="com.qmth.teachcloud.mark.bean.archivescore.ArchiveStudentVo">
@@ -327,10 +328,10 @@
             <choose>
                 <when test="req.orderField == 'totalScore'">
                     <if test="req.orderType == 'ASC'">
-                        order by (ifnull(t.objective_score, 0) +  ifnull(t.subjective_score, 0)) ASC
+                        order by (ifnull(t.objective_score, 0) + ifnull(t.subjective_score, 0)) ASC
                     </if>
                     <if test="req.orderType == 'DESC'">
-                        order by (ifnull(t.objective_score, 0) +  ifnull(t.subjective_score, 0)) DESC
+                        order by (ifnull(t.objective_score, 0) + ifnull(t.subjective_score, 0)) DESC
                     </if>
                 </when>
                 <otherwise>
@@ -343,89 +344,106 @@
         </if>
     </select>
     <select id="overview" resultType="com.qmth.teachcloud.mark.bean.archivescore.OverViewVo">
-        SELECT 
-        count(*) studentCount,
-        sum(case when s.is_absent =0 and s.omr_absent =0 and s.is_breach = 0 and s.is_upload = 1 then 1 else 0 end) actualCount,
-        sum(case when s.is_absent =1 or s.omr_absent =1 then 1 else 0 end) absentCount,
-        sum(case when s.is_breach =1 then 1 else 0 end) breachCount,
-        avg(case when s.is_absent !=1 then s.objective_score+s.subjective_score else null end) avgScore,
-        max(case when s.is_absent !=1 then s.objective_score+s.subjective_score else null end) maxScore,
-        min(case when s.is_absent !=1 then s.objective_score+s.subjective_score else null end) minScore,
-        sum(case when s.objective_score+s.subjective_score >=t.total_score * t.pass_score/100 then 1 else 0 end) passCount,
-        sum(case when s.objective_score+s.subjective_score >=t.total_score * t.excellent_score/100 then 1 else 0 end) excellentCount
+        SELECT count(*)                                                                                 studentCount,
+               sum(case
+                       when s.is_absent = 0 and s.omr_absent = 0 and s.is_breach = 0 and s.is_upload = 1 then 1
+                       else 0 end)                                                                      actualCount,
+               sum(case when s.is_absent = 1 or s.omr_absent = 1 then 1 else 0 end)                     absentCount,
+               sum(case when s.is_breach = 1 then 1 else 0 end)                                         breachCount,
+               avg(case when s.is_absent !=1 then s.objective_score + s.subjective_score else null end) avgScore,
+               max(case when s.is_absent !=1 then s.objective_score + s.subjective_score else null end) maxScore,
+               min(case when s.is_absent !=1 then s.objective_score + s.subjective_score else null end) minScore,
+               sum(case
+                       when s.objective_score + s.subjective_score >= t.total_score * t.pass_score / 100 then 1
+                       else 0 end)                                                                      passCount,
+               sum(case
+                       when s.objective_score + s.subjective_score >= t.total_score * t.excellent_score / 100 then 1
+                       else 0 end)                                                                      excellentCount
         FROM mark_student s
-            left join mark_paper t on s.exam_id = t.exam_id
-                and s.paper_number = t.paper_number
-                and s.paper_type = t.paper_type
-        WHERE
-            s.exam_id = #{examId} and s.paper_number = #{paperNumber}
+                 left join mark_paper t on s.exam_id = t.exam_id
+            and s.paper_number = t.paper_number
+            and s.paper_type = t.paper_type
+        WHERE s.exam_id = #{examId}
+          and s.paper_number = #{paperNumber}
     </select>
     <select id="getCountByScoreRange" resultType="int">
-        SELECT 
-        count(*) 
-        FROM mark_student s 
-        WHERE
-            s.exam_id = #{examId} and s.paper_number = #{paperNumber} 
-            and s.is_absent !=1 and s.objective_score+s.subjective_score&gt;=#{start}
-            and s.objective_score+s.subjective_score&lt;=#{end}
+        SELECT count(*)
+        FROM mark_student s
+        WHERE s.exam_id = #{examId}
+          and s.paper_number = #{paperNumber}
+          and s.is_absent !=1 and s.objective_score+s.subjective_score&gt;=#{start}
+          and s.objective_score+s.subjective_score&lt;=#{end}
     </select>
     <select id="college" resultType="com.qmth.teachcloud.mark.bean.archivescore.CollegeVo">
-        SELECT
-        s.college,
-        count(*) studentCount,
-        sum(case when s.is_absent =1 then 1 else 0 end) absentCount,
-        avg(case when s.is_absent !=1 then s.objective_score+s.subjective_score else null end) avgScore,
-        max(case when s.is_absent !=1 then s.objective_score+s.subjective_score else null end) maxScore,
-        min(case when s.is_absent !=1 then s.objective_score+s.subjective_score else null end) minScore,
-        sum(case when s.objective_score+s.subjective_score >=t.total_score * t.pass_score/100 then 1 else 0 end) passCount,
-        sum(case when s.objective_score+s.subjective_score >=t.total_score * t.excellent_score/100 then 1 else 0 end) excellentCount
+        SELECT s.college,
+               count(*)                                                                                 studentCount,
+               sum(case when s.is_absent = 1 then 1 else 0 end)                                         absentCount,
+               avg(case when s.is_absent !=1 then s.objective_score + s.subjective_score else null end) avgScore,
+               max(case when s.is_absent !=1 then s.objective_score + s.subjective_score else null end) maxScore,
+               min(case when s.is_absent !=1 then s.objective_score + s.subjective_score else null end) minScore,
+               sum(case
+                       when s.objective_score + s.subjective_score >= t.total_score * t.pass_score / 100 then 1
+                       else 0 end)                                                                      passCount,
+               sum(case
+                       when s.objective_score + s.subjective_score >= t.total_score * t.excellent_score / 100 then 1
+                       else 0 end)                                                                      excellentCount
         FROM mark_student s
                  left join mark_paper t on s.exam_id = t.exam_id
             and s.paper_number = t.paper_number
             and s.paper_type = t.paper_type
-        WHERE
-            s.exam_id = #{examId} and s.paper_number = #{paperNumber} and s.college is not null
+        WHERE s.exam_id = #{examId}
+          and s.paper_number = #{paperNumber}
+          and s.college is not null
         group by s.college
     </select>
     <select id="classData" resultType="com.qmth.teachcloud.mark.bean.archivescore.ClassVo">
-        SELECT
-        s.class_name,
-        count(*) studentCount,
-        sum(case when s.is_absent =1 then 1 else 0 end) absentCount,
-        avg(case when s.is_absent !=1 then s.objective_score+s.subjective_score else null end) avgScore,
-        max(case when s.is_absent !=1 then s.objective_score+s.subjective_score else null end) maxScore,
-        min(case when s.is_absent !=1 then s.objective_score+s.subjective_score else null end) minScore,
-        sum(case when s.objective_score+s.subjective_score >=t.total_score * t.pass_score/100 then 1 else 0 end) passCount,
-        sum(case when s.objective_score+s.subjective_score >=t.total_score * t.excellent_score/100 then 1 else 0 end) excellentCount
+        SELECT s.class_name,
+               count(*)                                                                                 studentCount,
+               sum(case when s.is_absent = 1 then 1 else 0 end)                                         absentCount,
+               avg(case when s.is_absent !=1 then s.objective_score + s.subjective_score else null end) avgScore,
+               max(case when s.is_absent !=1 then s.objective_score + s.subjective_score else null end) maxScore,
+               min(case when s.is_absent !=1 then s.objective_score + s.subjective_score else null end) minScore,
+               sum(case
+                       when s.objective_score + s.subjective_score >= t.total_score * t.pass_score / 100 then 1
+                       else 0 end)                                                                      passCount,
+               sum(case
+                       when s.objective_score + s.subjective_score >= t.total_score * t.excellent_score / 100 then 1
+                       else 0 end)                                                                      excellentCount
         FROM mark_student s
                  left join mark_paper t on s.exam_id = t.exam_id
             and s.paper_number = t.paper_number
             and s.paper_type = t.paper_type
-        WHERE
-            s.exam_id = #{examId} and s.paper_number = #{paperNumber} and s.class_name is not null
+        WHERE s.exam_id = #{examId}
+          and s.paper_number = #{paperNumber}
+          and s.class_name is not null
         group by s.class_name
     </select>
     <select id="teacher" resultType="com.qmth.teachcloud.mark.bean.archivescore.TeacherVo">
-        SELECT
-        s.teacher,
-        count(*) studentCount,
-        sum(case when s.is_absent =1 then 1 else 0 end) absentCount,
-        avg(case when s.is_absent !=1 then s.objective_score+s.subjective_score else null end) avgScore,
-        max(case when s.is_absent !=1 then s.objective_score+s.subjective_score else null end) maxScore,
-        min(case when s.is_absent !=1 then s.objective_score+s.subjective_score else null end) minScore,
-        sum(case when s.objective_score+s.subjective_score >=t.total_score * t.pass_score/100 then 1 else 0 end) passCount,
-        sum(case when s.objective_score+s.subjective_score >=t.total_score * t.excellent_score/100 then 1 else 0 end) excellentCount
+        SELECT s.teacher,
+               count(*)                                                                                 studentCount,
+               sum(case when s.is_absent = 1 then 1 else 0 end)                                         absentCount,
+               avg(case when s.is_absent !=1 then s.objective_score + s.subjective_score else null end) avgScore,
+               max(case when s.is_absent !=1 then s.objective_score + s.subjective_score else null end) maxScore,
+               min(case when s.is_absent !=1 then s.objective_score + s.subjective_score else null end) minScore,
+               sum(case
+                       when s.objective_score + s.subjective_score >= t.total_score * t.pass_score / 100 then 1
+                       else 0 end)                                                                      passCount,
+               sum(case
+                       when s.objective_score + s.subjective_score >= t.total_score * t.excellent_score / 100 then 1
+                       else 0 end)                                                                      excellentCount
         FROM mark_student s
                  left join mark_paper t on s.exam_id = t.exam_id
             and s.paper_number = t.paper_number
             and s.paper_type = t.paper_type
-        WHERE
-            s.exam_id = #{examId} and s.paper_number = #{paperNumber} and s.teacher is not null
+        WHERE s.exam_id = #{examId}
+          and s.paper_number = #{paperNumber}
+          and s.teacher is not null
         group by s.teacher
     </select>
     <select id="findOne" resultType="com.qmth.teachcloud.mark.bean.student.StudentVo"
             parameterType="com.qmth.teachcloud.mark.bean.student.StudentQuery">
-        select * from mark_student
+        select *
+        from mark_student
         where exam_id = #{query.examId}
           and course_paper_id = #{query.coursePaperId}
           and student_code = #{query.studentCode}
@@ -433,55 +451,60 @@
     <select id="listUnexistStudentByExamIdAndCoursePaperId"
             resultType="com.qmth.teachcloud.mark.dto.UnexistStudentDto">
         SELECT
-            t.course_code courseCode,
-            t.course_name courseName,
-            t.paper_number paperNumber,
-            t.student_code studentCode,
-            t.student_name studentName
+        t.course_code courseCode,
+        t.course_name courseName,
+        t.paper_number paperNumber,
+        t.student_code studentCode,
+        t.student_name studentName
         FROM
-            mark_student t left join sys_user su on t.create_id = su.id
+        mark_student t left join sys_user su on t.create_id = su.id
         WHERE
-            t.exam_id = #{examId}
-          AND t.scan_status = 'UNEXIST'
-            <if test="courseCode != null and courseCode != ''">
-                and t.course_code = #{courseCode}
-            </if>
-            <if test="coursePaperId != null and coursePaperId != ''">
-                and t.course_paper_id = #{coursePaperId}
-            </if>
-            <if test="status != null and status != ''">
-                and exists(select 1 from mark_paper mp where t.exam_id = mp.exam_id and t.course_paper_id = mp.course_paper_id and t.paper_type = mp.paper_type and mp.status = #{status})
+        t.exam_id = #{examId}
+        AND t.scan_status = 'UNEXIST'
+        <if test="courseCode != null and courseCode != ''">
+            and t.course_code = #{courseCode}
+        </if>
+        <if test="coursePaperId != null and coursePaperId != ''">
+            and t.course_paper_id = #{coursePaperId}
+        </if>
+        <if test="status != null and status != ''">
+            and exists(select 1 from mark_paper mp where t.exam_id = mp.exam_id and t.course_paper_id =
+            mp.course_paper_id and t.paper_type = mp.paper_type and mp.status = #{status})
+        </if>
+        <if test="dpr != null">
+            <if test="dpr.requestUserId != null">
+                AND t.create_id = #{dpr.requestUserId}
             </if>
-            <if test="dpr != null">
-                <if test="dpr.requestUserId != null">
-                    AND t.create_id = #{dpr.requestUserId}
-                </if>
-                <if test="dpr.orgIdSet != null and dpr.orgIdSet != '' and dpr.orgIdSet.size > 0">
-                    AND su.org_id IN
-                    <foreach collection="dpr.orgIdSet" item="item" index="index" open="(" separator="," close=")">
-                        #{item}
-                    </foreach>
-                </if>
+            <if test="dpr.orgIdSet != null and dpr.orgIdSet != '' and dpr.orgIdSet.size > 0">
+                AND su.org_id IN
+                <foreach collection="dpr.orgIdSet" item="item" index="index" open="(" separator="," close=")">
+                    #{item}
+                </foreach>
             </if>
+        </if>
         order by t.student_code
     </select>
     <select id="teacherClass" resultType="com.qmth.teachcloud.mark.bean.archivescore.TeacherClassVo">
-        SELECT
-            s.teacher,
-            s.class_name,
-            count(*) studentCount,
-            sum(case when s.is_absent =1 then 1 else 0 end) absentCount,
-            avg(case when s.is_absent !=1 then s.objective_score+s.subjective_score else null end) avgScore,
-            max(case when s.is_absent !=1 then s.objective_score+s.subjective_score else null end) maxScore,
-            min(case when s.is_absent !=1 then s.objective_score+s.subjective_score else null end) minScore,
-            sum(case when s.objective_score+s.subjective_score >=t.total_score * t.pass_score/100 then 1 else 0 end) passCount,
-            sum(case when s.objective_score+s.subjective_score >=t.total_score * t.excellent_score/100 then 1 else 0 end) excellentCount
+        SELECT s.teacher,
+               s.class_name,
+               count(*)                                                                                 studentCount,
+               sum(case when s.is_absent = 1 then 1 else 0 end)                                         absentCount,
+               avg(case when s.is_absent !=1 then s.objective_score + s.subjective_score else null end) avgScore,
+               max(case when s.is_absent !=1 then s.objective_score + s.subjective_score else null end) maxScore,
+               min(case when s.is_absent !=1 then s.objective_score + s.subjective_score else null end) minScore,
+               sum(case
+                       when s.objective_score + s.subjective_score >= t.total_score * t.pass_score / 100 then 1
+                       else 0 end)                                                                      passCount,
+               sum(case
+                       when s.objective_score + s.subjective_score >= t.total_score * t.excellent_score / 100 then 1
+                       else 0 end)                                                                      excellentCount
         FROM mark_student s
                  left join mark_paper t on s.exam_id = t.exam_id
             and s.paper_number = t.paper_number
             and s.paper_type = t.paper_type
-        WHERE
-            s.exam_id = #{examId} and s.paper_number = #{paperNumber} and s.class_name is not null
+        WHERE s.exam_id = #{examId}
+          and s.paper_number = #{paperNumber}
+          and s.class_name is not null
         group by s.teacher, s.class_name
     </select>
     <select id="selectCountByQuery" resultType="java.lang.Integer">
@@ -524,7 +547,8 @@
                 </if>
             </if>
             <if test="markStudent.markPaperStatus != null">
-                AND exists(select 1 from mark_paper mp where ms.exam_id = mp.exam_id and ms.paper_number = mp.paper_number and ms.paper_type = mp.paper_type and mp.status = #{markStudent.markPaperStatus})
+                AND exists(select 1 from mark_paper mp where ms.exam_id = mp.exam_id and ms.paper_number =
+                mp.paper_number and ms.paper_type = mp.paper_type and mp.status = #{markStudent.markPaperStatus})
             </if>
         </where>
     </select>
@@ -532,8 +556,8 @@
         SELECT
         count(1)
         FROM
-            mark_student ms
-                LEFT JOIN sys_user su ON ms.create_id = su.id
+        mark_student ms
+        LEFT JOIN sys_user su ON ms.create_id = su.id
         <where>
             ms.exam_id = #{markStudent.examId}
             <if test="markStudent.courseCode != null">
@@ -560,7 +584,8 @@
                 </if>
             </if>
             <if test="markStudent.markPaperStatus != null">
-                AND exists(select 1 from mark_paper mp where ms.exam_id = mp.exam_id and ms.paper_number = mp.paper_number and ms.paper_type = mp.paper_type and mp.status = #{markStudent.markPaperStatus})
+                AND exists(select 1 from mark_paper mp where ms.exam_id = mp.exam_id and ms.paper_number =
+                mp.paper_number and ms.paper_type = mp.paper_type and mp.status = #{markStudent.markPaperStatus})
             </if>
         </where>
     </select>
@@ -591,7 +616,8 @@
                 </if>
             </if>
             <if test="status != null">
-                AND exists(select 1 from mark_paper mp where ms.exam_id = mp.exam_id and ms.paper_number = mp.paper_number and ms.paper_type = mp.paper_type and mp.status = #{status})
+                AND exists(select 1 from mark_paper mp where ms.exam_id = mp.exam_id and ms.paper_number =
+                mp.paper_number and ms.paper_type = mp.paper_type and mp.status = #{status})
             </if>
         </where>
     </select>

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

@@ -59,7 +59,8 @@
         t.paper_id,
         t.student_id,
         t.paper_index number,
-        p.assigned
+        p.assigned,
+        p.invalid
         FROM
         scan_student_paper t
         inner join scan_paper p on t.paper_id=p.id