Browse Source

mark_student新增版本号

wangliang 3 months ago
parent
commit
8b72ab6968

+ 8 - 0
distributed-print/src/main/java/com/qmth/distributed/print/start/StartRunning.java

@@ -137,6 +137,14 @@ public class StartRunning implements CommandLineRunner {
         quartzService.addJob(CreatePdfTaskJob.class, JobEnum.CREATE_PDF_JOB.name(), JobEnum.CREATE_PDF_JOB.getGroupName(), "0 0/2 * * * ?", createPdfJobMap);
         log.info("服务器启动时执行,PDF生成定时任务 end");
 
+        // 每2分钟一次
+        log.info("服务器启动时执行,阅卷统分定时任务 start");
+        Map markScoreCalculateJobMap = new HashMap();
+        markScoreCalculateJobMap.computeIfAbsent("name", v -> MarkScoreCalculateJob.class.getName());
+        quartzService.deleteJob(JobEnum.MARK_SCORE_CALCULATE_JOB.name(), JobEnum.MARK_SCORE_CALCULATE_JOB.getGroupName());
+        quartzService.addJob(MarkScoreCalculateJob.class, JobEnum.MARK_SCORE_CALCULATE_JOB.name(), JobEnum.MARK_SCORE_CALCULATE_JOB.getGroupName(), "0 0/2 * * * ?", markScoreCalculateJobMap);
+        log.info("服务器启动时执行,阅卷统分定时任务 end");
+
         // 数据同步
         dataSync();
 

+ 802 - 793
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/entity/MarkStudent.java

@@ -1,793 +1,802 @@
-package com.qmth.teachcloud.mark.entity;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-
-import com.qmth.teachcloud.mark.enums.PaperTypeCheckStatus;
-import org.apache.commons.collections4.CollectionUtils;
-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.mark.dto.mark.ScoreItem;
-import com.qmth.teachcloud.mark.utils.BigDecimalUtils;
-
-import io.swagger.annotations.ApiModel;
-import io.swagger.annotations.ApiModelProperty;
-
-/**
- * <p>
- * 考试考生库
- * </p>
- *
- * @author xf
- * @since 2023-09-22
- */
-@TableName("mark_student")
-@ApiModel(value = "MarkStudent对象", description = "考试考生库")
-public class MarkStudent implements Serializable {
-
-    public static final String SPLIT = ";";
-
-    public static final String ANSWER_SPLIT = ",";
-
-    public static final int SECRET_NUMBER_START = 10000000;
-
-    public static final int SECRET_NUMBER_END = 99999999;
-
-    private static final long serialVersionUID = 1L;
-
-    @JsonSerialize(using = ToStringSerializer.class)
-    @ApiModelProperty(value = "主键(和exam_student表id一样)")
-    @TableId(value = "id")
-    private Long id;
-
-    @JsonSerialize(using = ToStringSerializer.class)
-    @ApiModelProperty(value = "考试ID")
-    private Long examId;
-
-    @JsonSerialize(using = ToStringSerializer.class)
-    @ApiModelProperty(value = "考生ID")
-    private Long basicStudentId;
-
-    @JsonSerialize(using = ToStringSerializer.class)
-    @ApiModelProperty(value = "课程ID")
-    private Long courseId;
-
-    @ApiModelProperty(value = "试卷编号(交互)")
-    private String coursePaperId;
-
-    @ApiModelProperty(value = "试卷编号")
-    private String paperNumber;
-
-    @ApiModelProperty(value = "备用卷")
-    private Integer serialNumber;
-    @ApiModelProperty(value = "试卷类型")
-    private String paperType;
-
-    @ApiModelProperty(value = "密号")
-    private String secretNumber;
-
-    @ApiModelProperty(value = "学号")
-    private String studentCode;
-
-    @ApiModelProperty(value = "试卷袋编号")
-    private String packageCode;
-
-    @ApiModelProperty(value = "校区")
-    private String examPlace;
-
-    @ApiModelProperty(value = "考场")
-    private String examRoom;
-
-    @ApiModelProperty(value = "备注")
-    private String remark;
-
-    @ApiModelProperty(value = "扫描批次号")
-    private String batchCode;
-
-    @ApiModelProperty(value = "原图数量")
-    private Integer sheetCount;
-
-    @ApiModelProperty(value = "原图地址url")
-    @TableField(updateStrategy = FieldStrategy.IGNORED)
-    private String sheetPath;
-
-    @ApiModelProperty(value = "客观题识别结果")
-    @TableField(updateStrategy = FieldStrategy.IGNORED)
-    private String answers;
-
-    @ApiModelProperty(value = "是否已上传")
-    @TableField(value = "is_upload")
-    private Boolean upload;
-
-    @ApiModelProperty(value = "是否缺考")
-    @TableField(value = "is_absent")
-    private Boolean absent;
-
-    @ApiModelProperty(value = "是否人工指定缺考")
-    @TableField(value = "is_manual_absent")
-    private Boolean manualAbsent;
-
-    @ApiModelProperty(value = "是否违纪")
-    @TableField(value = "is_breach")
-    private Boolean breach;
-
-    @ApiModelProperty(value = "是否人工指定违纪")
-    @TableField(value = "is_manual_breach")
-    private Boolean manualBreach;
-
-    @ApiModelProperty(value = "上传时间")
-    @TableField(updateStrategy = FieldStrategy.IGNORED)
-    private Long uploadTime;
-
-    @ApiModelProperty(value = "检查时间")
-    @TableField(value = "check_time", updateStrategy = FieldStrategy.IGNORED)
-    private Long checkTime;
-
-    @JsonSerialize(using = ToStringSerializer.class)
-    @ApiModelProperty(value = "检查人ID")
-    @TableField(value = "check_user_id", updateStrategy = FieldStrategy.IGNORED)
-    private Long checkUserId;
-
-    @ApiModelProperty(value = "客观总分")
-    @TableField(value = "objective_score", updateStrategy = FieldStrategy.IGNORED)
-    private Double objectiveScore;
-
-    @ApiModelProperty(value = "客观得分明细")
-    @TableField(value = "objective_score_list", updateStrategy = FieldStrategy.IGNORED)
-    private String objectiveScoreList;
-
-    @ApiModelProperty(value = "主观题状态")
-    private SubjectiveStatus subjectiveStatus;
-
-    @ApiModelProperty(value = "主观总分")
-    @TableField(value = "subjective_score", updateStrategy = FieldStrategy.IGNORED)
-    private Double subjectiveScore;
-
-    @ApiModelProperty(value = "主观得分明细")
-    @TableField(value = "subjective_score_list", updateStrategy = FieldStrategy.IGNORED)
-    private String subjectiveScoreList;
-
-    @ApiModelProperty(value = "扫描状态")
-    private ScanStatus scanStatus;
-    //识别缺考
-    private Boolean omrAbsent;
-    //识别缺考检查
-    private Boolean omrAbsentChecked;
-    // 识别违纪
-    private Boolean omrBreach;
-    //是否有填涂
-    private Boolean questionFilled;
-
-    //是否人工绑定
-    private Boolean assigned;
-    //人工绑定确认
-    private Boolean assignConfirmed;
-    //强制绑定,强制绑定为true时,assigned也为true
-    private Boolean invalid;
-
-    // 是否标记异常
-    private Boolean absentSuspect;
-
-    // 是否有缺页
-    private Boolean incomplete;
-
-    //违纪码
-    @TableField(updateStrategy = FieldStrategy.IGNORED)
-    private String breachCode;
-    @TableField(updateStrategy = FieldStrategy.IGNORED)
-    private Integer cardNumber;
-    private Long examStartTime;
-    private Long examEndTime;
-    private Long createId;
-    //是否漏扫
-    private Boolean missScan;
-
-    @TableField(exist = false)
-    private String markPaperStatus;
-
-    @ApiModelProperty(value = "卷型检查状态")
-    private PaperTypeCheckStatus paperTypeCheckStatus;
-
-    public MarkStudent() {
-    }
-
-    public MarkStudent(Long id, Long examId, Long basicStudentId, Long courseId,
-                       String paperNumber, String coursePaperId, Integer serialNumber, String paperType,
-                       String studentCode, String packageCode, String examPlace,
-                       String examRoom, Long examStartTime, Long examEndTime, Long createId) {
-        this.id = id;
-        this.examId = examId;
-        this.basicStudentId = basicStudentId;
-        this.courseId = courseId;
-        this.paperNumber = paperNumber;
-        this.coursePaperId = coursePaperId;
-        this.serialNumber = serialNumber;
-        this.paperType = paperType;
-        this.studentCode = studentCode;
-        this.packageCode = packageCode;
-        this.examPlace = examPlace;
-        this.examRoom = examRoom;
-        this.sheetCount = 0;
-        this.upload = false;
-        this.absent = false;
-        this.manualAbsent = false;
-        this.breach = false;
-        this.absentSuspect = false;
-        this.assignConfirmed = false;
-        this.missScan = false;
-        this.subjectiveStatus = SubjectiveStatus.UNMARK;
-        this.scanStatus = ScanStatus.UNEXIST;
-        this.omrAbsent = false;
-        this.omrAbsentChecked = false;
-        this.paperTypeCheckStatus = PaperTypeCheckStatus.NORMAL;
-        this.examStartTime = examStartTime;
-        this.examEndTime = examEndTime;
-        this.createId = createId;
-    }
-
-    public Long getId() {
-        return id;
-    }
-
-    public void setId(Long id) {
-        this.id = id;
-    }
-
-    public Long getExamId() {
-        return examId;
-    }
-
-    public void setExamId(Long examId) {
-        this.examId = examId;
-    }
-
-    public Long getBasicStudentId() {
-        return basicStudentId;
-    }
-
-    public void setBasicStudentId(Long basicStudentId) {
-        this.basicStudentId = basicStudentId;
-    }
-
-    public Long getCourseId() {
-        return courseId;
-    }
-
-    public void setCourseId(Long courseId) {
-        this.courseId = courseId;
-    }
-
-    public String getPaperNumber() {
-        return paperNumber;
-    }
-
-    public void setPaperNumber(String paperNumber) {
-        this.paperNumber = paperNumber;
-    }
-
-    public Integer getSerialNumber() {
-        return serialNumber;
-    }
-
-    public void setSerialNumber(Integer serialNumber) {
-        this.serialNumber = serialNumber;
-    }
-
-    public String getPaperType() {
-        return paperType;
-    }
-
-    public void setPaperType(String paperType) {
-        this.paperType = paperType;
-    }
-
-    public String getSecretNumber() {
-        return secretNumber;
-    }
-
-    public void setSecretNumber(String secretNumber) {
-        this.secretNumber = secretNumber;
-    }
-
-    public String getStudentCode() {
-        return studentCode;
-    }
-
-    public void setStudentCode(String studentCode) {
-        this.studentCode = studentCode;
-    }
-
-    public String getPackageCode() {
-        return packageCode;
-    }
-
-    public void setPackageCode(String packageCode) {
-        this.packageCode = packageCode;
-    }
-
-    public String getExamPlace() {
-        return examPlace;
-    }
-
-    public void setExamPlace(String examPlace) {
-        this.examPlace = examPlace;
-    }
-
-    public String getExamRoom() {
-        return examRoom;
-    }
-
-    public void setExamRoom(String examRoom) {
-        this.examRoom = examRoom;
-    }
-
-    public String getRemark() {
-        return remark;
-    }
-
-    public void setRemark(String remark) {
-        this.remark = remark;
-    }
-
-    public String getBatchCode() {
-        return batchCode;
-    }
-
-    public void setBatchCode(String batchCode) {
-        this.batchCode = batchCode;
-    }
-
-    public Integer getSheetCount() {
-        return sheetCount;
-    }
-
-    public void setSheetCount(Integer sheetCount) {
-        this.sheetCount = sheetCount;
-    }
-
-    public String getSheetPath() {
-        return sheetPath;
-    }
-
-    public void setSheetPath(String sheetPath) {
-        this.sheetPath = sheetPath;
-    }
-
-    public String getAnswers() {
-        return answers;
-    }
-
-    public void setAnswers(String answers) {
-        this.answers = answers;
-    }
-
-    public Boolean getUpload() {
-        return upload;
-    }
-
-    public void setUpload(Boolean upload) {
-        this.upload = upload;
-    }
-
-    public Boolean getAbsent() {
-        return absent;
-    }
-
-    public void setAbsent(Boolean absent) {
-        this.absent = absent;
-    }
-
-    public Boolean getManualAbsent() {
-        return manualAbsent;
-    }
-
-    public void setManualAbsent(Boolean manualAbsent) {
-        this.manualAbsent = manualAbsent;
-    }
-
-    public Boolean getBreach() {
-        return breach;
-    }
-
-    public void setBreach(Boolean breach) {
-        this.breach = breach;
-    }
-
-    public Boolean getManualBreach() {
-        return manualBreach;
-    }
-
-    public void setManualBreach(Boolean manualBreach) {
-        this.manualBreach = manualBreach;
-    }
-
-    public Long getUploadTime() {
-        return uploadTime;
-    }
-
-    public void setUploadTime(Long uploadTime) {
-        this.uploadTime = uploadTime;
-    }
-
-    public Long getCheckTime() {
-        return checkTime;
-    }
-
-    public void setCheckTime(Long checkTime) {
-        this.checkTime = checkTime;
-    }
-
-    public Long getCheckUserId() {
-        return checkUserId;
-    }
-
-    public void setCheckUserId(Long checkUserId) {
-        this.checkUserId = checkUserId;
-    }
-
-    public Double getObjectiveScore() {
-        return objectiveScore;
-    }
-
-    public void setObjectiveScore(Double objectiveScore) {
-        this.objectiveScore = objectiveScore;
-    }
-
-    public String getObjectiveScoreList() {
-        return objectiveScoreList;
-    }
-
-    public void setObjectiveScoreList(String objectiveScoreList) {
-        this.objectiveScoreList = objectiveScoreList;
-    }
-
-    public SubjectiveStatus getSubjectiveStatus() {
-        return subjectiveStatus;
-    }
-
-    public void setSubjectiveStatus(SubjectiveStatus subjectiveStatus) {
-        this.subjectiveStatus = subjectiveStatus;
-    }
-
-    public Double getSubjectiveScore() {
-        return subjectiveScore;
-    }
-
-    public void setSubjectiveScore(Double subjectiveScore) {
-        this.subjectiveScore = subjectiveScore;
-    }
-
-    public String getSubjectiveScoreList() {
-        return subjectiveScoreList;
-    }
-
-    public void setSubjectiveScoreList(String subjectiveScoreList) {
-        this.subjectiveScoreList = subjectiveScoreList;
-    }
-
-    public ScanStatus getScanStatus() {
-        return scanStatus;
-    }
-
-    public void setScanStatus(ScanStatus scanStatus) {
-        this.scanStatus = scanStatus;
-    }
-
-    public Boolean getQuestionFilled() {
-        return questionFilled;
-    }
-
-    public void setQuestionFilled(Boolean questionFilled) {
-        this.questionFilled = questionFilled;
-    }
-
-    public Boolean getAssigned() {
-        return assigned;
-    }
-
-    public void setAssigned(Boolean assigned) {
-        this.assigned = assigned;
-    }
-
-    public Boolean getAbsentSuspect() {
-        return absentSuspect;
-    }
-
-    public void setAbsentSuspect(Boolean absentSuspect) {
-        this.absentSuspect = absentSuspect;
-    }
-
-    public Boolean getIncomplete() {
-        return incomplete;
-    }
-
-    public void setIncomplete(Boolean incomplete) {
-        this.incomplete = incomplete;
-    }
-
-    public String getBreachCode() {
-        return breachCode;
-    }
-
-    public void setBreachCode(String breachCode) {
-        this.breachCode = breachCode;
-    }
-
-    public Boolean getOmrAbsent() {
-        return omrAbsent;
-    }
-
-    public void setOmrAbsent(Boolean omrAbsent) {
-        this.omrAbsent = omrAbsent;
-    }
-
-    public Boolean getOmrBreach() {
-        return omrBreach;
-    }
-
-    public void setOmrBreach(Boolean omrBreach) {
-        this.omrBreach = omrBreach;
-    }
-
-    public Integer getCardNumber() {
-        return cardNumber;
-    }
-
-    public void setCardNumber(Integer cardNumber) {
-        this.cardNumber = cardNumber;
-    }
-
-    public static String buildScoreList(List<ScoreItem> scoreList) {
-        if (scoreList != null) {
-            return StringUtils.join(scoreList, ";");
-        } else {
-            return null;
-        }
-    }
-
-    public void randomSecretNumber() {
-        secretNumber = String.valueOf((int) (RandomUtils.nextDouble() * (SECRET_NUMBER_END - SECRET_NUMBER_START)) + SECRET_NUMBER_START);
-    }
-
-    public Boolean getOmrAbsentChecked() {
-        return omrAbsentChecked;
-    }
-
-    public void setOmrAbsentChecked(Boolean omrAbsentChecked) {
-        this.omrAbsentChecked = omrAbsentChecked;
-    }
-
-    public String getCoursePaperId() {
-        return coursePaperId;
-    }
-
-    public void setCoursePaperId(String coursePaperId) {
-        this.coursePaperId = coursePaperId;
-    }
-
-    public PaperTypeCheckStatus getPaperTypeCheckStatus() {
-        return paperTypeCheckStatus;
-    }
-
-    public void setPaperTypeCheckStatus(PaperTypeCheckStatus paperTypeCheckStatus) {
-        this.paperTypeCheckStatus = paperTypeCheckStatus;
-    }
-
-    public double getTotalScore() {
-        double score = 0;
-        if (objectiveScore != null) {
-            score = BigDecimalUtils.add(score, objectiveScore);
-        }
-        if (subjectiveScore != null) {
-            score = BigDecimalUtils.add(score, subjectiveScore);
-        }
-        return score;
-    }
-
-    public List<String> getAnswerList() {
-        List<String> list = new ArrayList<>();
-        if (StringUtils.isNotBlank(answers)) {
-            try {
-                list = JSON.parseArray(answers, String.class);
-            } catch (Exception e) {
-                String[] values = StringUtils.split(StringUtils.trimToNull(answers), ANSWER_SPLIT);
-                if (values != null && values.length > 0) {
-                    for (String answer : values) {
-                        list.add(StringUtils.trim(answer));
-                    }
-                }
-            }
-        }
-        return list;
-    }
-
-    public List<String> getAnswerScoreList() {
-        List<String> scoreList = new ArrayList<>();
-        List<String> answerList = getAnswerList();
-        if (StringUtils.isNotBlank(objectiveScoreList) && CollectionUtils.isNotEmpty(answerList)) {
-            String[] answerScores = objectiveScoreList.split(";");
-            for (String answerScore : answerScores) {
-                scoreList.add(answerScore.split(":")[1]);
-            }
-        }
-        return scoreList;
-    }
-
-    public List<String> getSheetPathList() {
-        List<String> list = new ArrayList<String>();
-        String trimSheetPath = StringUtils.trimToNull(sheetPath);
-        if (StringUtils.isNotBlank(trimSheetPath)) {
-            List<FilePathVo> vos = JSON.parseArray(trimSheetPath, FilePathVo.class);
-            for (FilePathVo filePathVo : vos) {
-                list.add(JSON.toJSONString(filePathVo));
-            }
-        }
-        return list;
-    }
-
-    public void setScoreList(List<ScoreItem> scoreList, boolean objective) {
-        if (scoreList != null) {
-            if (objective) {
-                setObjectiveScoreList(StringUtils.join(scoreList, SPLIT));
-            } else {
-                setSubjectiveScoreList(StringUtils.join(scoreList, SPLIT));
-            }
-        }
-    }
-
-    public List<ScoreItem> getScoreList(boolean objective) {
-        List<ScoreItem> scoreList = new LinkedList<ScoreItem>();
-        try {
-            String[] values = StringUtils.split(objective ? objectiveScoreList : subjectiveScoreList, SPLIT);
-            for (String value : values) {
-                ScoreItem item = ScoreItem.parse(value, objective);
-                item.setObjective(objective);
-                if (item != null) {
-                    scoreList.add(item);
-                }
-            }
-        } catch (Exception e) {
-        }
-        return scoreList;
-    }
-
-    public List<ScoreItem> getScoreList(boolean objective, List<MarkQuestion> questionList) {
-        List<ScoreItem> scoreList = new LinkedList<ScoreItem>();
-        try {
-            String[] values = StringUtils.split(objective ? objectiveScoreList : subjectiveScoreList, SPLIT);
-            int i = 0;
-            for (String value : values) {
-                i++;
-                if (questionList.size() < i) {
-                    break;
-                }
-                MarkQuestion question = questionList.get(i - 1);
-                if (question.getTotalScore() == null || question.getTotalScore() == 0) {
-                    continue;
-                }
-                ScoreItem item = ScoreItem.parse(value, objective);
-                item.setObjective(objective);
-                item.setMainNumber(question.getMainNumber());
-                item.setTitle(question.getMainTitle());
-                item.setTotalScore(question.getTotalScore());
-                item.setSubNumber(question.getSubNumber());
-                if (item != null) {
-                    scoreList.add(item);
-                }
-            }
-        } catch (Exception e) {
-        }
-        return scoreList;
-    }
-
-    public Boolean getAssignConfirmed() {
-        return assignConfirmed;
-    }
-
-    public void setAssignConfirmed(Boolean assignConfirmed) {
-        this.assignConfirmed = assignConfirmed;
-    }
-
-    public Long getExamStartTime() {
-        return examStartTime;
-    }
-
-    public void setExamStartTime(Long examStartTime) {
-        this.examStartTime = examStartTime;
-    }
-
-    public Long getExamEndTime() {
-        return examEndTime;
-    }
-
-    public void setExamEndTime(Long examEndTime) {
-        this.examEndTime = examEndTime;
-    }
-
-    public Long getCreateId() {
-        return createId;
-    }
-
-    public void setCreateId(Long createId) {
-        this.createId = createId;
-    }
-
-    public String getMarkPaperStatus() {
-        return markPaperStatus;
-    }
-
-    public void setMarkPaperStatus(String markPaperStatus) {
-        this.markPaperStatus = markPaperStatus;
-    }
-
-    public Boolean getInvalid() {
-        return invalid;
-    }
-
-    public void setInvalid(Boolean invalid) {
-        this.invalid = invalid;
-    }
-
-    public Boolean getMissScan() {
-        return missScan;
-    }
-
-    public void setMissScan(Boolean missScan) {
-        this.missScan = missScan;
-    }
-
-    @Override
-    public String toString() {
-        return "MarkStudent{" +
-                "id=" + id +
-                ", examId=" + examId +
-                ", paperNumber=" + paperNumber +
-                ", secretNumber=" + secretNumber +
-                ", studentCode=" + studentCode +
-                ", packageCode=" + packageCode +
-                ", examPlace=" + examPlace +
-                ", examRoom=" + examRoom +
-                ", remark=" + remark +
-                ", batchCode=" + batchCode +
-                ", sheetCount=" + sheetCount +
-                ", answers=" + answers +
-                ", isUpload=" + upload +
-                ", isAbsent=" + absent +
-                ", isManualAbsent=" + manualAbsent +
-                ", isBreach=" + breach +
-                ", uploadTime=" + uploadTime +
-                ", checkTime=" + checkTime +
-                ", checkUserId=" + checkUserId +
-                ", objectiveScore=" + objectiveScore +
-                ", objectiveScoreList=" + objectiveScoreList +
-                ", subjectiveStatus=" + subjectiveStatus +
-                ", subjectiveScore=" + subjectiveScore +
-                ", subjectiveScoreList=" + subjectiveScoreList +
-                ", scanStatus=" + scanStatus +
-                ", questionFilled=" + questionFilled +
-                ", assigned=" + assigned +
-                ", invalid=" + invalid +
-                ", absentSuspect=" + absentSuspect +
-                ", incomplete=" + incomplete +
-                ", breachCode=" + breachCode +
-                ", omrAbsent=" + omrAbsent +
-                ", cardNumber=" + cardNumber +
-                ", coursePaperId=" + coursePaperId +
-                "}";
-    }
-
-}
+package com.qmth.teachcloud.mark.entity;
+
+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.mark.dto.mark.ScoreItem;
+import com.qmth.teachcloud.mark.enums.PaperTypeCheckStatus;
+import com.qmth.teachcloud.mark.utils.BigDecimalUtils;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang.math.RandomUtils;
+import org.apache.commons.lang3.StringUtils;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * <p>
+ * 考试考生库
+ * </p>
+ *
+ * @author xf
+ * @since 2023-09-22
+ */
+@TableName("mark_student")
+@ApiModel(value = "MarkStudent对象", description = "考试考生库")
+public class MarkStudent implements Serializable {
+
+    public static final String SPLIT = ";";
+
+    public static final String ANSWER_SPLIT = ",";
+
+    public static final int SECRET_NUMBER_START = 10000000;
+
+    public static final int SECRET_NUMBER_END = 99999999;
+
+    private static final long serialVersionUID = 1L;
+
+    @JsonSerialize(using = ToStringSerializer.class)
+    @ApiModelProperty(value = "主键(和exam_student表id一样)")
+    @TableId(value = "id")
+    private Long id;
+
+    @JsonSerialize(using = ToStringSerializer.class)
+    @ApiModelProperty(value = "考试ID")
+    private Long examId;
+
+    @JsonSerialize(using = ToStringSerializer.class)
+    @ApiModelProperty(value = "考生ID")
+    private Long basicStudentId;
+
+    @JsonSerialize(using = ToStringSerializer.class)
+    @ApiModelProperty(value = "课程ID")
+    private Long courseId;
+
+    @ApiModelProperty(value = "试卷编号(交互)")
+    private String coursePaperId;
+
+    @ApiModelProperty(value = "试卷编号")
+    private String paperNumber;
+
+    @ApiModelProperty(value = "备用卷")
+    private Integer serialNumber;
+    @ApiModelProperty(value = "试卷类型")
+    private String paperType;
+
+    @ApiModelProperty(value = "密号")
+    private String secretNumber;
+
+    @ApiModelProperty(value = "学号")
+    private String studentCode;
+
+    @ApiModelProperty(value = "试卷袋编号")
+    private String packageCode;
+
+    @ApiModelProperty(value = "校区")
+    private String examPlace;
+
+    @ApiModelProperty(value = "考场")
+    private String examRoom;
+
+    @ApiModelProperty(value = "备注")
+    private String remark;
+
+    @ApiModelProperty(value = "扫描批次号")
+    private String batchCode;
+
+    @ApiModelProperty(value = "原图数量")
+    private Integer sheetCount;
+
+    @ApiModelProperty(value = "原图地址url")
+    @TableField(updateStrategy = FieldStrategy.IGNORED)
+    private String sheetPath;
+
+    @ApiModelProperty(value = "客观题识别结果")
+    @TableField(updateStrategy = FieldStrategy.IGNORED)
+    private String answers;
+
+    @ApiModelProperty(value = "是否已上传")
+    @TableField(value = "is_upload")
+    private Boolean upload;
+
+    @ApiModelProperty(value = "是否缺考")
+    @TableField(value = "is_absent")
+    private Boolean absent;
+
+    @ApiModelProperty(value = "是否人工指定缺考")
+    @TableField(value = "is_manual_absent")
+    private Boolean manualAbsent;
+
+    @ApiModelProperty(value = "是否违纪")
+    @TableField(value = "is_breach")
+    private Boolean breach;
+
+    @ApiModelProperty(value = "是否人工指定违纪")
+    @TableField(value = "is_manual_breach")
+    private Boolean manualBreach;
+
+    @ApiModelProperty(value = "上传时间")
+    @TableField(updateStrategy = FieldStrategy.IGNORED)
+    private Long uploadTime;
+
+    @ApiModelProperty(value = "检查时间")
+    @TableField(value = "check_time", updateStrategy = FieldStrategy.IGNORED)
+    private Long checkTime;
+
+    @JsonSerialize(using = ToStringSerializer.class)
+    @ApiModelProperty(value = "检查人ID")
+    @TableField(value = "check_user_id", updateStrategy = FieldStrategy.IGNORED)
+    private Long checkUserId;
+
+    @ApiModelProperty(value = "客观总分")
+    @TableField(value = "objective_score", updateStrategy = FieldStrategy.IGNORED)
+    private Double objectiveScore;
+
+    @ApiModelProperty(value = "客观得分明细")
+    @TableField(value = "objective_score_list", updateStrategy = FieldStrategy.IGNORED)
+    private String objectiveScoreList;
+
+    @ApiModelProperty(value = "主观题状态")
+    private SubjectiveStatus subjectiveStatus;
+
+    @ApiModelProperty(value = "主观总分")
+    @TableField(value = "subjective_score", updateStrategy = FieldStrategy.IGNORED)
+    private Double subjectiveScore;
+
+    @ApiModelProperty(value = "主观得分明细")
+    @TableField(value = "subjective_score_list", updateStrategy = FieldStrategy.IGNORED)
+    private String subjectiveScoreList;
+
+    @ApiModelProperty(value = "扫描状态")
+    private ScanStatus scanStatus;
+    //识别缺考
+    private Boolean omrAbsent;
+    //识别缺考检查
+    private Boolean omrAbsentChecked;
+    // 识别违纪
+    private Boolean omrBreach;
+    //是否有填涂
+    private Boolean questionFilled;
+
+    //是否人工绑定
+    private Boolean assigned;
+    //人工绑定确认
+    private Boolean assignConfirmed;
+    //强制绑定,强制绑定为true时,assigned也为true
+    private Boolean invalid;
+
+    // 是否标记异常
+    private Boolean absentSuspect;
+
+    // 是否有缺页
+    private Boolean incomplete;
+
+    //违纪码
+    @TableField(updateStrategy = FieldStrategy.IGNORED)
+    private String breachCode;
+    @TableField(updateStrategy = FieldStrategy.IGNORED)
+    private Integer cardNumber;
+    private Long examStartTime;
+    private Long examEndTime;
+    private Long createId;
+    //是否漏扫
+    private Boolean missScan;
+
+    @TableField(exist = false)
+    private String markPaperStatus;
+
+    @ApiModelProperty(value = "卷型检查状态")
+    private PaperTypeCheckStatus paperTypeCheckStatus;
+
+    @ApiModelProperty(value = "版本号")
+    private Integer version = 1;
+
+    public MarkStudent() {
+    }
+
+    public MarkStudent(Long id, Long examId, Long basicStudentId, Long courseId,
+                       String paperNumber, String coursePaperId, Integer serialNumber, String paperType,
+                       String studentCode, String packageCode, String examPlace,
+                       String examRoom, Long examStartTime, Long examEndTime, Long createId) {
+        this.id = id;
+        this.examId = examId;
+        this.basicStudentId = basicStudentId;
+        this.courseId = courseId;
+        this.paperNumber = paperNumber;
+        this.coursePaperId = coursePaperId;
+        this.serialNumber = serialNumber;
+        this.paperType = paperType;
+        this.studentCode = studentCode;
+        this.packageCode = packageCode;
+        this.examPlace = examPlace;
+        this.examRoom = examRoom;
+        this.sheetCount = 0;
+        this.upload = false;
+        this.absent = false;
+        this.manualAbsent = false;
+        this.breach = false;
+        this.absentSuspect = false;
+        this.assignConfirmed = false;
+        this.missScan = false;
+        this.subjectiveStatus = SubjectiveStatus.UNMARK;
+        this.scanStatus = ScanStatus.UNEXIST;
+        this.omrAbsent = false;
+        this.omrAbsentChecked = false;
+        this.paperTypeCheckStatus = PaperTypeCheckStatus.NORMAL;
+        this.examStartTime = examStartTime;
+        this.examEndTime = examEndTime;
+        this.createId = createId;
+    }
+
+    public Integer getVersion() {
+        return version;
+    }
+
+    public void setVersion(Integer version) {
+        this.version = version;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Long getExamId() {
+        return examId;
+    }
+
+    public void setExamId(Long examId) {
+        this.examId = examId;
+    }
+
+    public Long getBasicStudentId() {
+        return basicStudentId;
+    }
+
+    public void setBasicStudentId(Long basicStudentId) {
+        this.basicStudentId = basicStudentId;
+    }
+
+    public Long getCourseId() {
+        return courseId;
+    }
+
+    public void setCourseId(Long courseId) {
+        this.courseId = courseId;
+    }
+
+    public String getPaperNumber() {
+        return paperNumber;
+    }
+
+    public void setPaperNumber(String paperNumber) {
+        this.paperNumber = paperNumber;
+    }
+
+    public Integer getSerialNumber() {
+        return serialNumber;
+    }
+
+    public void setSerialNumber(Integer serialNumber) {
+        this.serialNumber = serialNumber;
+    }
+
+    public String getPaperType() {
+        return paperType;
+    }
+
+    public void setPaperType(String paperType) {
+        this.paperType = paperType;
+    }
+
+    public String getSecretNumber() {
+        return secretNumber;
+    }
+
+    public void setSecretNumber(String secretNumber) {
+        this.secretNumber = secretNumber;
+    }
+
+    public String getStudentCode() {
+        return studentCode;
+    }
+
+    public void setStudentCode(String studentCode) {
+        this.studentCode = studentCode;
+    }
+
+    public String getPackageCode() {
+        return packageCode;
+    }
+
+    public void setPackageCode(String packageCode) {
+        this.packageCode = packageCode;
+    }
+
+    public String getExamPlace() {
+        return examPlace;
+    }
+
+    public void setExamPlace(String examPlace) {
+        this.examPlace = examPlace;
+    }
+
+    public String getExamRoom() {
+        return examRoom;
+    }
+
+    public void setExamRoom(String examRoom) {
+        this.examRoom = examRoom;
+    }
+
+    public String getRemark() {
+        return remark;
+    }
+
+    public void setRemark(String remark) {
+        this.remark = remark;
+    }
+
+    public String getBatchCode() {
+        return batchCode;
+    }
+
+    public void setBatchCode(String batchCode) {
+        this.batchCode = batchCode;
+    }
+
+    public Integer getSheetCount() {
+        return sheetCount;
+    }
+
+    public void setSheetCount(Integer sheetCount) {
+        this.sheetCount = sheetCount;
+    }
+
+    public String getSheetPath() {
+        return sheetPath;
+    }
+
+    public void setSheetPath(String sheetPath) {
+        this.sheetPath = sheetPath;
+    }
+
+    public String getAnswers() {
+        return answers;
+    }
+
+    public void setAnswers(String answers) {
+        this.answers = answers;
+    }
+
+    public Boolean getUpload() {
+        return upload;
+    }
+
+    public void setUpload(Boolean upload) {
+        this.upload = upload;
+    }
+
+    public Boolean getAbsent() {
+        return absent;
+    }
+
+    public void setAbsent(Boolean absent) {
+        this.absent = absent;
+    }
+
+    public Boolean getManualAbsent() {
+        return manualAbsent;
+    }
+
+    public void setManualAbsent(Boolean manualAbsent) {
+        this.manualAbsent = manualAbsent;
+    }
+
+    public Boolean getBreach() {
+        return breach;
+    }
+
+    public void setBreach(Boolean breach) {
+        this.breach = breach;
+    }
+
+    public Boolean getManualBreach() {
+        return manualBreach;
+    }
+
+    public void setManualBreach(Boolean manualBreach) {
+        this.manualBreach = manualBreach;
+    }
+
+    public Long getUploadTime() {
+        return uploadTime;
+    }
+
+    public void setUploadTime(Long uploadTime) {
+        this.uploadTime = uploadTime;
+    }
+
+    public Long getCheckTime() {
+        return checkTime;
+    }
+
+    public void setCheckTime(Long checkTime) {
+        this.checkTime = checkTime;
+    }
+
+    public Long getCheckUserId() {
+        return checkUserId;
+    }
+
+    public void setCheckUserId(Long checkUserId) {
+        this.checkUserId = checkUserId;
+    }
+
+    public Double getObjectiveScore() {
+        return objectiveScore;
+    }
+
+    public void setObjectiveScore(Double objectiveScore) {
+        this.objectiveScore = objectiveScore;
+    }
+
+    public String getObjectiveScoreList() {
+        return objectiveScoreList;
+    }
+
+    public void setObjectiveScoreList(String objectiveScoreList) {
+        this.objectiveScoreList = objectiveScoreList;
+    }
+
+    public SubjectiveStatus getSubjectiveStatus() {
+        return subjectiveStatus;
+    }
+
+    public void setSubjectiveStatus(SubjectiveStatus subjectiveStatus) {
+        this.subjectiveStatus = subjectiveStatus;
+    }
+
+    public Double getSubjectiveScore() {
+        return subjectiveScore;
+    }
+
+    public void setSubjectiveScore(Double subjectiveScore) {
+        this.subjectiveScore = subjectiveScore;
+    }
+
+    public String getSubjectiveScoreList() {
+        return subjectiveScoreList;
+    }
+
+    public void setSubjectiveScoreList(String subjectiveScoreList) {
+        this.subjectiveScoreList = subjectiveScoreList;
+    }
+
+    public ScanStatus getScanStatus() {
+        return scanStatus;
+    }
+
+    public void setScanStatus(ScanStatus scanStatus) {
+        this.scanStatus = scanStatus;
+    }
+
+    public Boolean getQuestionFilled() {
+        return questionFilled;
+    }
+
+    public void setQuestionFilled(Boolean questionFilled) {
+        this.questionFilled = questionFilled;
+    }
+
+    public Boolean getAssigned() {
+        return assigned;
+    }
+
+    public void setAssigned(Boolean assigned) {
+        this.assigned = assigned;
+    }
+
+    public Boolean getAbsentSuspect() {
+        return absentSuspect;
+    }
+
+    public void setAbsentSuspect(Boolean absentSuspect) {
+        this.absentSuspect = absentSuspect;
+    }
+
+    public Boolean getIncomplete() {
+        return incomplete;
+    }
+
+    public void setIncomplete(Boolean incomplete) {
+        this.incomplete = incomplete;
+    }
+
+    public String getBreachCode() {
+        return breachCode;
+    }
+
+    public void setBreachCode(String breachCode) {
+        this.breachCode = breachCode;
+    }
+
+    public Boolean getOmrAbsent() {
+        return omrAbsent;
+    }
+
+    public void setOmrAbsent(Boolean omrAbsent) {
+        this.omrAbsent = omrAbsent;
+    }
+
+    public Boolean getOmrBreach() {
+        return omrBreach;
+    }
+
+    public void setOmrBreach(Boolean omrBreach) {
+        this.omrBreach = omrBreach;
+    }
+
+    public Integer getCardNumber() {
+        return cardNumber;
+    }
+
+    public void setCardNumber(Integer cardNumber) {
+        this.cardNumber = cardNumber;
+    }
+
+    public static String buildScoreList(List<ScoreItem> scoreList) {
+        if (scoreList != null) {
+            return StringUtils.join(scoreList, ";");
+        } else {
+            return null;
+        }
+    }
+
+    public void randomSecretNumber() {
+        secretNumber = String.valueOf((int) (RandomUtils.nextDouble() * (SECRET_NUMBER_END - SECRET_NUMBER_START)) + SECRET_NUMBER_START);
+    }
+
+    public Boolean getOmrAbsentChecked() {
+        return omrAbsentChecked;
+    }
+
+    public void setOmrAbsentChecked(Boolean omrAbsentChecked) {
+        this.omrAbsentChecked = omrAbsentChecked;
+    }
+
+    public String getCoursePaperId() {
+        return coursePaperId;
+    }
+
+    public void setCoursePaperId(String coursePaperId) {
+        this.coursePaperId = coursePaperId;
+    }
+
+    public PaperTypeCheckStatus getPaperTypeCheckStatus() {
+        return paperTypeCheckStatus;
+    }
+
+    public void setPaperTypeCheckStatus(PaperTypeCheckStatus paperTypeCheckStatus) {
+        this.paperTypeCheckStatus = paperTypeCheckStatus;
+    }
+
+    public double getTotalScore() {
+        double score = 0;
+        if (objectiveScore != null) {
+            score = BigDecimalUtils.add(score, objectiveScore);
+        }
+        if (subjectiveScore != null) {
+            score = BigDecimalUtils.add(score, subjectiveScore);
+        }
+        return score;
+    }
+
+    public List<String> getAnswerList() {
+        List<String> list = new ArrayList<>();
+        if (StringUtils.isNotBlank(answers)) {
+            try {
+                list = JSON.parseArray(answers, String.class);
+            } catch (Exception e) {
+                String[] values = StringUtils.split(StringUtils.trimToNull(answers), ANSWER_SPLIT);
+                if (values != null && values.length > 0) {
+                    for (String answer : values) {
+                        list.add(StringUtils.trim(answer));
+                    }
+                }
+            }
+        }
+        return list;
+    }
+
+    public List<String> getAnswerScoreList() {
+        List<String> scoreList = new ArrayList<>();
+        List<String> answerList = getAnswerList();
+        if (StringUtils.isNotBlank(objectiveScoreList) && CollectionUtils.isNotEmpty(answerList)) {
+            String[] answerScores = objectiveScoreList.split(";");
+            for (String answerScore : answerScores) {
+                scoreList.add(answerScore.split(":")[1]);
+            }
+        }
+        return scoreList;
+    }
+
+    public List<String> getSheetPathList() {
+        List<String> list = new ArrayList<String>();
+        String trimSheetPath = StringUtils.trimToNull(sheetPath);
+        if (StringUtils.isNotBlank(trimSheetPath)) {
+            List<FilePathVo> vos = JSON.parseArray(trimSheetPath, FilePathVo.class);
+            for (FilePathVo filePathVo : vos) {
+                list.add(JSON.toJSONString(filePathVo));
+            }
+        }
+        return list;
+    }
+
+    public void setScoreList(List<ScoreItem> scoreList, boolean objective) {
+        if (scoreList != null) {
+            if (objective) {
+                setObjectiveScoreList(StringUtils.join(scoreList, SPLIT));
+            } else {
+                setSubjectiveScoreList(StringUtils.join(scoreList, SPLIT));
+            }
+        }
+    }
+
+    public List<ScoreItem> getScoreList(boolean objective) {
+        List<ScoreItem> scoreList = new LinkedList<ScoreItem>();
+        try {
+            String[] values = StringUtils.split(objective ? objectiveScoreList : subjectiveScoreList, SPLIT);
+            for (String value : values) {
+                ScoreItem item = ScoreItem.parse(value, objective);
+                item.setObjective(objective);
+                if (item != null) {
+                    scoreList.add(item);
+                }
+            }
+        } catch (Exception e) {
+        }
+        return scoreList;
+    }
+
+    public List<ScoreItem> getScoreList(boolean objective, List<MarkQuestion> questionList) {
+        List<ScoreItem> scoreList = new LinkedList<ScoreItem>();
+        try {
+            String[] values = StringUtils.split(objective ? objectiveScoreList : subjectiveScoreList, SPLIT);
+            int i = 0;
+            for (String value : values) {
+                i++;
+                if (questionList.size() < i) {
+                    break;
+                }
+                MarkQuestion question = questionList.get(i - 1);
+                if (question.getTotalScore() == null || question.getTotalScore() == 0) {
+                    continue;
+                }
+                ScoreItem item = ScoreItem.parse(value, objective);
+                item.setObjective(objective);
+                item.setMainNumber(question.getMainNumber());
+                item.setTitle(question.getMainTitle());
+                item.setTotalScore(question.getTotalScore());
+                item.setSubNumber(question.getSubNumber());
+                if (item != null) {
+                    scoreList.add(item);
+                }
+            }
+        } catch (Exception e) {
+        }
+        return scoreList;
+    }
+
+    public Boolean getAssignConfirmed() {
+        return assignConfirmed;
+    }
+
+    public void setAssignConfirmed(Boolean assignConfirmed) {
+        this.assignConfirmed = assignConfirmed;
+    }
+
+    public Long getExamStartTime() {
+        return examStartTime;
+    }
+
+    public void setExamStartTime(Long examStartTime) {
+        this.examStartTime = examStartTime;
+    }
+
+    public Long getExamEndTime() {
+        return examEndTime;
+    }
+
+    public void setExamEndTime(Long examEndTime) {
+        this.examEndTime = examEndTime;
+    }
+
+    public Long getCreateId() {
+        return createId;
+    }
+
+    public void setCreateId(Long createId) {
+        this.createId = createId;
+    }
+
+    public String getMarkPaperStatus() {
+        return markPaperStatus;
+    }
+
+    public void setMarkPaperStatus(String markPaperStatus) {
+        this.markPaperStatus = markPaperStatus;
+    }
+
+    public Boolean getInvalid() {
+        return invalid;
+    }
+
+    public void setInvalid(Boolean invalid) {
+        this.invalid = invalid;
+    }
+
+    public Boolean getMissScan() {
+        return missScan;
+    }
+
+    public void setMissScan(Boolean missScan) {
+        this.missScan = missScan;
+    }
+
+    @Override
+    public String toString() {
+        return "MarkStudent{" +
+                "id=" + id +
+                ", examId=" + examId +
+                ", paperNumber=" + paperNumber +
+                ", secretNumber=" + secretNumber +
+                ", studentCode=" + studentCode +
+                ", packageCode=" + packageCode +
+                ", examPlace=" + examPlace +
+                ", examRoom=" + examRoom +
+                ", remark=" + remark +
+                ", batchCode=" + batchCode +
+                ", sheetCount=" + sheetCount +
+                ", answers=" + answers +
+                ", isUpload=" + upload +
+                ", isAbsent=" + absent +
+                ", isManualAbsent=" + manualAbsent +
+                ", isBreach=" + breach +
+                ", uploadTime=" + uploadTime +
+                ", checkTime=" + checkTime +
+                ", checkUserId=" + checkUserId +
+                ", objectiveScore=" + objectiveScore +
+                ", objectiveScoreList=" + objectiveScoreList +
+                ", subjectiveStatus=" + subjectiveStatus +
+                ", subjectiveScore=" + subjectiveScore +
+                ", subjectiveScoreList=" + subjectiveScoreList +
+                ", scanStatus=" + scanStatus +
+                ", questionFilled=" + questionFilled +
+                ", assigned=" + assigned +
+                ", invalid=" + invalid +
+                ", absentSuspect=" + absentSuspect +
+                ", incomplete=" + incomplete +
+                ", breachCode=" + breachCode +
+                ", omrAbsent=" + omrAbsent +
+                ", cardNumber=" + cardNumber +
+                ", coursePaperId=" + coursePaperId +
+                "}";
+    }
+
+}

+ 28 - 16
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/mapper/MarkStudentMapper.java

@@ -5,7 +5,6 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.qmth.teachcloud.common.bean.dto.DataPermissionRule;
 import com.qmth.teachcloud.common.entity.BasicTeachClazz;
-import com.qmth.teachcloud.common.enums.BasicExamStudentStatusEnum;
 import com.qmth.teachcloud.mark.bean.archivescore.*;
 import com.qmth.teachcloud.mark.bean.scananswer.AnswerQueryDomain;
 import com.qmth.teachcloud.mark.bean.scananswer.AnswerQueryVo;
@@ -32,12 +31,12 @@ import java.util.List;
 public interface MarkStudentMapper extends BaseMapper<MarkStudent> {
 
     IPage<StudentScoreDetailDto> pageStudentScore(@Param("page") Page<StudentScoreDetailDto> page, @Param("examId") Long examId, @Param("paperNumber") String paperNumber, @Param("college") String college,
-            @Param("majorName") String majorName, @Param("teachClassName") String teachClassName, @Param("className") String className, @Param("teacher") String teacher, @Param("filter") Integer filter,
-            @Param("status") String status, @Param("breach") Boolean breach, @Param("startScore") Double startScore, @Param("endScore") Double endScore,
-            @Param("subjectiveStartScore") Double subjectiveStartScore, @Param("subjectiveEndScore") Double subjectiveEndScore,
-            @Param("objectiveStartScore") Double objectiveStartScore, @Param("objectiveEndScore") Double objectiveEndScore, @Param("subScore") Double subScore,
-            @Param("objectiveScoreLt") Double objectiveScoreLt, @Param("studentName") String studentName, @Param("studentCode") String studentCode, @Param("secretNumber") String secretNumber,
-            @Param("orderType") String orderType, @Param("orderField") String orderField, @Param("dpr") DataPermissionRule dpr);
+                                                  @Param("majorName") String majorName, @Param("teachClassName") String teachClassName, @Param("className") String className, @Param("teacher") String teacher, @Param("filter") Integer filter,
+                                                  @Param("status") String status, @Param("breach") Boolean breach, @Param("startScore") Double startScore, @Param("endScore") Double endScore,
+                                                  @Param("subjectiveStartScore") Double subjectiveStartScore, @Param("subjectiveEndScore") Double subjectiveEndScore,
+                                                  @Param("objectiveStartScore") Double objectiveStartScore, @Param("objectiveEndScore") Double objectiveEndScore, @Param("subScore") Double subScore,
+                                                  @Param("objectiveScoreLt") Double objectiveScoreLt, @Param("studentName") String studentName, @Param("studentCode") String studentCode, @Param("secretNumber") String secretNumber,
+                                                  @Param("orderType") String orderType, @Param("orderField") String orderField, @Param("dpr") DataPermissionRule dpr);
 
     /**
      * 评卷管理/成绩检查/成绩详情导出
@@ -68,12 +67,12 @@ public interface MarkStudentMapper extends BaseMapper<MarkStudent> {
      * @return
      */
     List<StudentScoreDetailDto> pageStudentScoreExport(@Param("examId") Long examId, @Param("paperNumber") String paperNumber, @Param("college") String college,
-            @Param("majorName") String majorName, @Param("teachClassName") String teachClassName, @Param("className") String className, @Param("teacher") String teacher, @Param("filter") Integer filter,
-            @Param("status") String status, @Param("breach") Boolean breach, @Param("startScore") Double startScore, @Param("endScore") Double endScore,
-            @Param("subjectiveStartScore") Double subjectiveStartScore, @Param("subjectiveEndScore") Double subjectiveEndScore,
-            @Param("objectiveStartScore") Double objectiveStartScore, @Param("objectiveEndScore") Double objectiveEndScore, @Param("subScore") Double subScore,
-            @Param("objectiveScoreLt") Double objectiveScoreLt, @Param("studentName") String studentName, @Param("studentCode") String studentCode, @Param("secretNumber") String secretNumber,
-            @Param("orderType") String orderType, @Param("orderField") String orderField, @Param("dpr") DataPermissionRule dpr);
+                                                       @Param("majorName") String majorName, @Param("teachClassName") String teachClassName, @Param("className") String className, @Param("teacher") String teacher, @Param("filter") Integer filter,
+                                                       @Param("status") String status, @Param("breach") Boolean breach, @Param("startScore") Double startScore, @Param("endScore") Double endScore,
+                                                       @Param("subjectiveStartScore") Double subjectiveStartScore, @Param("subjectiveEndScore") Double subjectiveEndScore,
+                                                       @Param("objectiveStartScore") Double objectiveStartScore, @Param("objectiveEndScore") Double objectiveEndScore, @Param("subScore") Double subScore,
+                                                       @Param("objectiveScoreLt") Double objectiveScoreLt, @Param("studentName") String studentName, @Param("studentCode") String studentCode, @Param("secretNumber") String secretNumber,
+                                                       @Param("orderType") String orderType, @Param("orderField") String orderField, @Param("dpr") DataPermissionRule dpr);
 
     List<MarkStudent> listAbsentOrBreachMarkTaskStudent(@Param("examId") Long examId, @Param("paperNumber") String paperNumber);
 
@@ -100,7 +99,7 @@ public interface MarkStudentMapper extends BaseMapper<MarkStudent> {
     List<TeacherVo> teacher(@Param("schoolId") Long schoolId, @Param("req") ArchiveStudentQuery query, @Param("dpr") DataPermissionRule dpr);
 
     List<UnexistStudentDto> listUnexistStudentByExamIdAndCoursePaperId(@Param("examId") Long examId, @Param("courseId") Long courseId, @Param("coursePaperId") String coursePaperId,
-            @Param("status") String status, @Param("dpr") DataPermissionRule dpr);
+                                                                       @Param("status") String status, @Param("dpr") DataPermissionRule dpr);
 
     IPage<ArchiveStudentVo> studentList(@Param("page") Page<ArchiveStudentVo> page, @Param("schoolId") Long schoolId, @Param("req") ArchiveStudentQuery query, @Param("dpr") DataPermissionRule dpr);
 
@@ -113,7 +112,7 @@ public interface MarkStudentMapper extends BaseMapper<MarkStudent> {
     int countAssignedNew(@Param("markStudent") MarkStudent markStudent, @Param("dpr") DataPermissionRule dpr, @Param("teachClassName") String teachClassName);
 
     List<MarkStudent> listScanCollegeByExamIdAndCourseCodeAndCoursePaperId(@Param("examId") Long examId, @Param("courseId") Long courseId, @Param("coursePaperId") String coursePaperId,
-            @Param("status") String status, @Param("dpr") DataPermissionRule dpr);
+                                                                           @Param("status") String status, @Param("dpr") DataPermissionRule dpr);
 
     BasicTeachClazz getBasicTeachClazzById(Long clazzId);
 
@@ -126,7 +125,7 @@ public interface MarkStudentMapper extends BaseMapper<MarkStudent> {
     IPage<MarkStudentVo> listMarkStudentVo(@Param("page") Page<MarkStudentVo> page, @Param("markStudentQuery") MarkStudentQuery markStudentQuery);
 
     int countOmrAbsentStudent(@Param("examId") Long examId, @Param("paperNumber") String paperNumber, @Param("isOmrAbsentConfirm") boolean isOmrAbsentConfirm,
-            @Param("teachClassName") String teachClassName);
+                              @Param("teachClassName") String teachClassName);
 
     void updateBasicExamStudentPaperType(@Param("paperType") String paperType, @Param("basicStudentId") Long basicStudentId);
 
@@ -142,4 +141,17 @@ public interface MarkStudentMapper extends BaseMapper<MarkStudent> {
     AbInfoVo findExamTaskPaperTypeOpenStatus(@Param("examId") Long examId, @Param("paperNumber") String paperNumber);
 
     List<Long> findUnMarked(@Param("page") Page<Long> page, @Param("examId") Long examId, @Param("paperNumber") String paperNumber, @Param("userId") Long userId, @Param("classMark") Boolean classMark);
+
+    /**
+     * 根据版本号更新主观题分数
+     *
+     * @param studentId
+     * @param status
+     * @param score
+     * @param scoreList
+     * @param version
+     * @return
+     */
+    int updateSubjectiveScoreByVersion(@Param("studentId") Long studentId, @Param("status") String status, @Param("score") Double score,
+                                           @Param("scoreList") String scoreList, @Param("version") Integer version);
 }

+ 24 - 10
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/MarkStudentService.java

@@ -6,6 +6,7 @@ import java.util.Set;
 import javax.servlet.http.HttpServletResponse;
 import javax.validation.constraints.NotNull;
 
+import com.qmth.teachcloud.common.enums.TaskStatusEnum;
 import org.springframework.web.multipart.MultipartFile;
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -63,10 +64,10 @@ public interface MarkStudentService extends IService<MarkStudent> {
     ScanExamInfoVo getScanExamInfo(BasicExam exam, Long courseId, String coursePaperId);
 
     IPage<StudentScoreDetailDto> pageStudentScore(Long examId, String paperNumber, String college, String majorName,
-            String teachClassName, String className, String teacher, Integer filter, String status, Boolean breach,
-            Double startScore, Double endScore, Double subjectiveStartScore, Double subjectiveEndScore, Double objectiveStartScore, Double objectiveEndScore,
-            Double subScore, Integer objectiveScoreRateLt, String studentName, String studentCode, String secretNumber, String orderType,
-            String orderField, Integer pageNumber, Integer pageSize);
+                                                  String teachClassName, String className, String teacher, Integer filter, String status, Boolean breach,
+                                                  Double startScore, Double endScore, Double subjectiveStartScore, Double subjectiveEndScore, Double objectiveStartScore, Double objectiveEndScore,
+                                                  Double subScore, Integer objectiveScoreRateLt, String studentName, String studentCode, String secretNumber, String orderType,
+                                                  String orderField, Integer pageNumber, Integer pageSize);
 
     /**
      * 评卷管理/成绩检查/成绩详情导出
@@ -96,10 +97,10 @@ public interface MarkStudentService extends IService<MarkStudent> {
      * @return
      */
     List<StudentScoreDetailDto> pageStudentScoreExport(Long examId, String paperNumber, String college, String majorName, String teachClassName,
-            String className, String teacher, Integer filter, String status, Boolean breach, Double startScore, Double endScore,
-            Double subjectiveStartScore, Double subjectiveEndScore, Double objectiveStartScore, Double objectiveEndScore,
-            Double subScore, Integer objectiveScoreRateLt, String studentName, String studentCode, String secretNumber, String orderType,
-            String orderField);
+                                                       String className, String teacher, Integer filter, String status, Boolean breach, Double startScore, Double endScore,
+                                                       Double subjectiveStartScore, Double subjectiveEndScore, Double objectiveStartScore, Double objectiveEndScore,
+                                                       Double subScore, Integer objectiveScoreRateLt, String studentName, String studentCode, String secretNumber, String orderType,
+                                                       String orderField);
 
     List<SheetUrlDto> buildSheetUrls(Long studentId);
 
@@ -194,10 +195,10 @@ public interface MarkStudentService extends IService<MarkStudent> {
     boolean updateAssignConfirm(Long studentId, boolean assignConfirm);
 
     int getAssignedCount(Long examId, Boolean checked, Long courseId, String coursePaperId, MarkPaperStatus status,
-            DataPermissionRule dpr);
+                         DataPermissionRule dpr);
 
     int getAssignedCount(Long examId, Boolean checked, Long courseId, String coursePaperId, MarkPaperStatus status,
-            DataPermissionRule dpr, String teachClassName);
+                         DataPermissionRule dpr, String teachClassName);
 
     int countAbsentByExamIdAndPaperNumber(Long examId, String paperNumber);
 
@@ -267,4 +268,17 @@ public interface MarkStudentService extends IService<MarkStudent> {
     UpdateTimeVo add(Long examId, String coursePaperId, String studentCode, String studentName, String paperType, Long basicStudentId);
 
     List<Long> findUnMarked(Page<Long> page, Long examId, String paperNumber, Long userId, Boolean classMark);
+
+    /**
+     * 根据版本号更新主观题分数
+     *
+     * @param studentId
+     * @param status
+     * @param score
+     * @param scoreList
+     * @param version
+     * @return
+     */
+    int updateSubjectiveScoreByVersion(Long studentId, SubjectiveStatus status, Double score,
+                                           String scoreList, Integer version);
 }

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

@@ -2450,5 +2450,19 @@ public class MarkStudentServiceImpl extends ServiceImpl<MarkStudentMapper, MarkS
         return this.baseMapper.findUnMarked(page, examId, paperNumber, userId, classMark);
     }
 
-
+    /**
+     * 根据版本号更新主观题分数
+     *
+     * @param studentId
+     * @param status
+     * @param score
+     * @param scoreList
+     * @param version
+     * @return
+     */
+    @Override
+    public int updateSubjectiveScoreByVersion(Long studentId, SubjectiveStatus status, Double score, String scoreList, Integer version) {
+        Objects.requireNonNull(status, "主观题状态不能为空");
+        return this.baseMapper.updateSubjectiveScoreByVersion(studentId, status.name(), score, scoreList, version);
+    }
 }

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

@@ -1062,4 +1062,16 @@
         </if>
         </where>
     </select>
+
+    <update id="updateSubjectiveScoreByVersion">
+        update mark_student t set t.subjective_status = #{status},t.subjective_score = #{score},t.subjective_score_list = #{scoreList},t.version = version + 1
+        <where>
+            <if test="studentId != null and studentId != ''">
+                AND t.id = #{studentId}
+            </if>
+            <if test="version != null and version != ''">
+                AND t.version = #{version}
+            </if>
+        </where>
+    </update>
 </mapper>

+ 2 - 1
teachcloud-task/src/main/java/com/qmth/teachcloud/task/enums/JobEnum.java

@@ -21,7 +21,8 @@ public enum JobEnum {
     BUILD_MARK_TASK("BUILD_MARK_TASK_GROUP", "创建评卷任务"),
     INIT_MARK_DATA("INIT_MARK_DATA_GROUP", "初始化阅卷数据"),
     DATA_SYNC("DATA_SYNC_GROUP", "数据同步"),
-    CLEAR_TIMEOUT_TASK("CLEAR_TIMEOUT_TASK_GROUP", "清空过期任务");
+    CLEAR_TIMEOUT_TASK("CLEAR_TIMEOUT_TASK_GROUP", "清空过期任务"),
+    MARK_SCORE_CALCULATE_JOB("MARK_SCORE_CALCULATE_JOB_GROUP", "阅卷统分定时任务");
 
     private String groupName;
 

+ 30 - 0
teachcloud-task/src/main/java/com/qmth/teachcloud/task/job/MarkScoreCalculateJob.java

@@ -0,0 +1,30 @@
+package com.qmth.teachcloud.task.job;
+
+import com.qmth.teachcloud.task.job.service.JobService;
+import org.quartz.DisallowConcurrentExecution;
+import org.quartz.JobExecutionContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.scheduling.quartz.QuartzJobBean;
+
+import javax.annotation.Resource;
+
+/**
+ * @Description: 阅卷统分定时任务
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2025/3/5
+ */
+@DisallowConcurrentExecution//串行执行
+public class MarkScoreCalculateJob extends QuartzJobBean {
+    private final static Logger log = LoggerFactory.getLogger(MarkScoreCalculateJob.class);
+
+    @Resource
+    JobService jobService;
+
+    @Override
+    protected void executeInternal(JobExecutionContext jobExecutionContext) {
+        jobService.markScoreCalculate();
+    }
+}

+ 5 - 0
teachcloud-task/src/main/java/com/qmth/teachcloud/task/job/service/JobService.java

@@ -53,4 +53,9 @@ public interface JobService {
     void createPdfTask() throws InterruptedException;
 
     void sentDataSync(String name, String s);
+
+    /**
+     * 统分定时任务
+     */
+    void markScoreCalculate();
 }

+ 12 - 4
teachcloud-task/src/main/java/com/qmth/teachcloud/task/job/service/impl/JobServiceImpl.java

@@ -24,10 +24,7 @@ import com.qmth.teachcloud.mark.entity.MarkPaper;
 import com.qmth.teachcloud.mark.entity.MarkUserQuestion;
 import com.qmth.teachcloud.mark.enums.LockType;
 import com.qmth.teachcloud.mark.lock.LockService;
-import com.qmth.teachcloud.mark.service.MarkPaperService;
-import com.qmth.teachcloud.mark.service.MarkQuestionService;
-import com.qmth.teachcloud.mark.service.MarkService;
-import com.qmth.teachcloud.mark.service.MarkUserQuestionService;
+import com.qmth.teachcloud.mark.service.*;
 import com.qmth.teachcloud.mark.utils.TaskLockUtil;
 import com.qmth.teachcloud.task.job.service.JobService;
 import com.qmth.teachcloud.task.service.PrintFinishService;
@@ -95,6 +92,9 @@ public class JobServiceImpl implements JobService {
     @Resource
     private TSyncDataService tSyncDataService;
 
+    @Resource
+    MarkStudentService markStudentService;
+
     @Override
     public void sendSmsExpireTask() {
         smsSendService.sendSmsExpireTask();
@@ -243,6 +243,14 @@ public class JobServiceImpl implements JobService {
         tSyncDataService.syncData(Long.valueOf(schoolId), Long.valueOf(examId));
     }
 
+    /**
+     * 统分定时任务
+     */
+    @Override
+    public void markScoreCalculate() {
+        log.info("markScoreCalculate is come in");
+    }
+
     /**
      * 组装job
      *