فهرست منبع

3.3.0 成绩检查-客观题检查,签到表列表

xiaofei 1 سال پیش
والد
کامیت
53e9db7ec1
22فایلهای تغییر یافته به همراه902 افزوده شده و 41 حذف شده
  1. 3 3
      distributed-print/install/mysql/upgrade/3.3.0.sql
  2. 18 0
      distributed-print/src/main/java/com/qmth/distributed/print/api/mark/MarkPaperController.java
  3. 21 1
      distributed-print/src/main/java/com/qmth/distributed/print/api/mark/MarkStudentController.java
  4. 81 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/dto/mark/ScoreInfo.java
  5. 34 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/dto/mark/score/MarkPaperPackageDto.java
  6. 50 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/dto/mark/score/StudentObjectiveAnswerDto.java
  7. 184 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/dto/mark/score/StudentObjectiveDetailDto.java
  8. 9 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/entity/MarkPaper.java
  9. 4 3
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/entity/MarkQuestion.java
  10. 57 16
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/entity/MarkStudent.java
  11. 11 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/entity/ScanPackage.java
  12. 35 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/enums/ObjectivePolicy.java
  13. 3 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/mapper/MarkPaperMapper.java
  14. 10 3
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/MarkPaperService.java
  15. 8 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/MarkStudentService.java
  16. 3 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/ScanPackageService.java
  17. 47 2
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkPaperServiceImpl.java
  18. 1 1
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkQuestionServiceImpl.java
  19. 139 3
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkStudentServiceImpl.java
  20. 25 9
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/ScanPackageServiceImpl.java
  21. 146 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/utils/ScoreCalculateUtil.java
  22. 13 0
      teachcloud-mark/src/main/resources/mapper/MarkPaperMapper.xml

+ 3 - 3
distributed-print/install/mysql/upgrade/3.3.0.sql

@@ -84,9 +84,9 @@ INSERT INTO `sys_privilege` (`id`, `name`, `url`, `type`, `parent_id`, `sequence
 INSERT INTO `sys_privilege` (`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `enable`, `default_auth`, `front_display`) VALUES ('956', '主观题检查-获取配置', '/api/admin/mark/inspected/getSetting', 'URL', '946', '5', 'AUTH', '1', '1', '1');
 INSERT INTO `sys_privilege` (`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `enable`, `default_auth`, `front_display`) VALUES ('957', '主观题检查-获取任务', '/api/admin/mark/inspected/getTask', 'URL', '946', '6', 'AUTH', '1', '1', '1');
 INSERT INTO `sys_privilege` (`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `enable`, `default_auth`, `front_display`) VALUES ('958', '主观题检查-保存任务', '/api/admin/mark/inspected/saveTask', 'URL', '946', '7', 'AUTH', '1', '1', '1');
-INSERT INTO `sys_privilege` (`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `enable`, `default_auth`, `front_display`) VALUES ('959', '客观题检查-获取任务', '/api/admin/mark/check/answer/getTask', 'URL', '946', '8', 'AUTH', '1', '1', '1');
-INSERT INTO `sys_privilege` (`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `enable`, `default_auth`, `front_display`) VALUES ('960', '客观题检查-保存任务', '/api/admin/mark/check/answer/saveTask', 'URL', '946', '9', 'AUTH', '1', '1', '1');
-INSERT INTO `sys_privilege` (`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `enable`, `default_auth`, `front_display`) VALUES ('961', '签到表列表', '/api/admin/mark/package/list', 'URL', '946', '10', 'AUTH', '1', '1', '1');
+INSERT INTO `sys_privilege` (`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `enable`, `default_auth`, `front_display`) VALUES ('959', '客观题检查-获取任务', '/api/admin/mark/student/check/objective/getTask', 'URL', '946', '8', 'AUTH', '1', '1', '1');
+INSERT INTO `sys_privilege` (`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `enable`, `default_auth`, `front_display`) VALUES ('960', '客观题检查-保存任务', '/api/admin/mark/student/check/objective/saveTask', 'URL', '946', '9', 'AUTH', '1', '1', '1');
+INSERT INTO `sys_privilege` (`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `enable`, `default_auth`, `front_display`) VALUES ('961', '签到表列表', '/api/admin/mark/paper/package/list', 'URL', '946', '10', 'AUTH', '1', '1', '1');
 INSERT INTO `sys_privilege` (`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `enable`, `default_auth`, `front_display`) VALUES ('962', '评卷区设置', '/api/admin/mark/group/update_picture_config', 'URL', '897', '13', 'AUTH', '1', '1', '1');
 INSERT INTO `sys_privilege` (`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `enable`, `default_auth`, `front_display`) VALUES ('963', '开启/关闭分班阅', '/api/admin/mark/group/update_open_mark_class', 'URL', '897', '14', 'AUTH', '1', '1', '1');
 INSERT INTO `sys_privilege` (`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `enable`, `default_auth`, `front_display`) VALUES ('964', '班级阅卷进度', '/api/admin/mark/group/class/summary', 'URL', '917', '20', 'AUTH', '1', '1', '1');

+ 18 - 0
distributed-print/src/main/java/com/qmth/distributed/print/api/mark/MarkPaperController.java

@@ -1,11 +1,13 @@
 package com.qmth.distributed.print.api.mark;
 
 
+import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.qmth.boot.api.constant.ApiConstant;
 import com.qmth.teachcloud.common.annotation.OperationLogDetail;
 import com.qmth.teachcloud.common.contant.SystemConstant;
 import com.qmth.teachcloud.common.enums.log.CustomizedOperationTypeEnum;
 import com.qmth.teachcloud.common.enums.mark.MarkPaperStatus;
+import com.qmth.teachcloud.mark.dto.mark.score.MarkPaperPackageDto;
 import com.qmth.teachcloud.mark.service.MarkPaperService;
 import com.qmth.teachcloud.common.util.Result;
 import com.qmth.teachcloud.common.util.ResultUtil;
@@ -19,6 +21,8 @@ import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
 import javax.annotation.Resource;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
 import java.util.List;
 
 /**
@@ -48,4 +52,18 @@ public class MarkPaperController {
                          @ApiParam(value = "状态", required = true) @RequestParam MarkPaperStatus status) {
         return ResultUtil.ok(markPaperService.finishPaper(examId, paperNumbers, status));
     }
+
+    /**
+     * 签到表列表
+     */
+    @ApiOperation(value = "签到表列表")
+    @RequestMapping(value = "/package/list", method = RequestMethod.POST)
+    public Result finish(@ApiParam(value = "考试ID", required = true) @RequestParam Long examId,
+                         @ApiParam(value = "试卷编号", required = true) @RequestParam String paperNumber,
+                         @ApiParam(value = "卷袋编号") @RequestParam(required = false) String packageCode,
+                         @RequestParam @Min(SystemConstant.PAGE_NUMBER_MIN) Integer pageNumber,
+                         @RequestParam @Min(SystemConstant.PAGE_SIZE_MIN) @Max(SystemConstant.PAGE_SIZE_MAX) Integer pageSize) {
+        IPage<MarkPaperPackageDto> markPaperPackageDtoIPage = markPaperService.listPackage(examId, paperNumber, packageCode, pageNumber, pageSize);
+        return ResultUtil.ok(markPaperPackageDtoIPage);
+    }
 }

+ 21 - 1
distributed-print/src/main/java/com/qmth/distributed/print/api/mark/MarkStudentController.java

@@ -6,7 +6,7 @@ import com.qmth.boot.api.constant.ApiConstant;
 import com.qmth.teachcloud.common.contant.SystemConstant;
 import com.qmth.teachcloud.common.util.Result;
 import com.qmth.teachcloud.common.util.ResultUtil;
-import com.qmth.teachcloud.mark.dto.mark.score.CheckScoreListDto;
+import com.qmth.teachcloud.mark.dto.mark.score.StudentObjectiveDetailDto;
 import com.qmth.teachcloud.mark.dto.mark.score.StudentScoreDetailDto;
 import com.qmth.teachcloud.mark.service.MarkStudentService;
 import io.swagger.annotations.Api;
@@ -61,4 +61,24 @@ public class MarkStudentController {
         IPage<StudentScoreDetailDto> scoreListDtoIPage = markStudentService.pageStudentScore(examId, paperNumber, college, className, teacher, filter, absent, breach, startScore, endScore, subScore, objectiveScoreRateLt, studentName, studentCode, pageNumber, pageSize);
         return ResultUtil.ok(scoreListDtoIPage);
     }
+
+    /**
+     * 客观题检查任务获取
+     */
+    @ApiOperation(value = "客观题检查任务获取")
+    @RequestMapping(value = "/check/objective/getTask", method = RequestMethod.POST)
+    public Result getCheckObjectiveTask(@ApiParam(value = "考生ID", required = true) @RequestParam Long studentId) {
+        StudentObjectiveDetailDto studentObjectiveDetailDto = markStudentService.getCheckObjectiveTask(studentId);
+        return ResultUtil.ok(studentObjectiveDetailDto);
+    }
+
+    /**
+     * 客观题检查任务保存
+     */
+    @ApiOperation(value = "客观题检查任务保存")
+    @RequestMapping(value = "/check/objective/getTask", method = RequestMethod.POST)
+    public Result saveCheckObjectiveTask(@ApiParam(value = "考生ID", required = true) @RequestParam Long studentId,
+                                         @ApiParam(value = "客观题答案", required = true) @RequestParam String answers) {
+        return ResultUtil.ok(markStudentService.saveCheckObjectiveTask(studentId, answers));
+    }
 }

+ 81 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/dto/mark/ScoreInfo.java

@@ -0,0 +1,81 @@
+package com.qmth.teachcloud.mark.dto.mark;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+
+public class ScoreInfo {
+
+    private int mainNumber;
+
+    private String subNumber;
+
+    private String mainTitle;
+
+    private BigDecimal objectiveScore;
+
+    private BigDecimal subjectiveScore;
+
+    private BigDecimal totalScore;
+
+    private List<ScoreItem> scoreList;
+
+    public ScoreInfo() {
+        this.mainNumber = 0;
+        this.subNumber = "";
+        this.objectiveScore = BigDecimal.ZERO;
+        this.subjectiveScore = BigDecimal.ZERO;
+        this.totalScore = BigDecimal.ZERO;
+        this.scoreList = new ArrayList<ScoreItem>();
+    }
+
+    public int incrMainNumber(String title) {
+        mainTitle = title;
+        mainNumber++;
+        subNumber = "";
+        return mainNumber;
+    }
+
+    public void addScore(String title, String number, double score, String answer, boolean objective) {
+
+        ScoreItem item = new ScoreItem(objective);
+        item.setMainNumber(mainNumber);
+        item.setSubNumber(number);
+        item.setTitle(title != null ? title : mainTitle + "-" + item.getSubNumber());
+        item.setAnswer(answer);
+        item.setScore(score);
+
+        scoreList.add(item);
+        totalScore = totalScore.add(BigDecimal.valueOf(item.getScore()));
+        if (item.isObjective()) {
+            objectiveScore = objectiveScore.add(BigDecimal.valueOf(item.getScore()));
+        } else {
+            subjectiveScore = subjectiveScore.add(BigDecimal.valueOf(item.getScore()));
+        }
+    }
+
+    public double getObjectiveScore() {
+        return objectiveScore.doubleValue();
+    }
+
+    public double getSubjectiveScore() {
+        return subjectiveScore.doubleValue();
+    }
+
+    public double getTotalScore() {
+        return totalScore.doubleValue();
+    }
+
+    public List<ScoreItem> getScoreList() {
+        return scoreList;
+    }
+
+    public int getTotalCount() {
+        return scoreList.size();
+    }
+
+    public int getMainCount() {
+        return mainNumber;
+    }
+
+}

+ 34 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/dto/mark/score/MarkPaperPackageDto.java

@@ -0,0 +1,34 @@
+package com.qmth.teachcloud.mark.dto.mark.score;
+
+import java.util.List;
+
+public class MarkPaperPackageDto {
+
+    private String packageCode;
+    private int count;
+    private List<String> urls;
+
+    public String getPackageCode() {
+        return packageCode;
+    }
+
+    public void setPackageCode(String packageCode) {
+        this.packageCode = packageCode;
+    }
+
+    public int getCount() {
+        return count;
+    }
+
+    public void setCount(int count) {
+        this.count = count;
+    }
+
+    public List<String> getUrls() {
+        return urls;
+    }
+
+    public void setUrls(List<String> urls) {
+        this.urls = urls;
+    }
+}

+ 50 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/dto/mark/score/StudentObjectiveAnswerDto.java

@@ -0,0 +1,50 @@
+package com.qmth.teachcloud.mark.dto.mark.score;
+
+public class StudentObjectiveAnswerDto {
+
+    private Integer mainNumber;
+    private Integer subNumber;
+    private String answer;
+    private Boolean exist;
+    private String questionType;
+
+    public Integer getMainNumber() {
+        return mainNumber;
+    }
+
+    public void setMainNumber(Integer mainNumber) {
+        this.mainNumber = mainNumber;
+    }
+
+    public Integer getSubNumber() {
+        return subNumber;
+    }
+
+    public void setSubNumber(Integer subNumber) {
+        this.subNumber = subNumber;
+    }
+
+    public String getAnswer() {
+        return answer;
+    }
+
+    public void setAnswer(String answer) {
+        this.answer = answer;
+    }
+
+    public Boolean getExist() {
+        return exist;
+    }
+
+    public void setExist(Boolean exist) {
+        this.exist = exist;
+    }
+
+    public String getQuestionType() {
+        return questionType;
+    }
+
+    public void setQuestionType(String questionType) {
+        this.questionType = questionType;
+    }
+}

+ 184 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/dto/mark/score/StudentObjectiveDetailDto.java

@@ -0,0 +1,184 @@
+package com.qmth.teachcloud.mark.dto.mark.score;
+
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+
+import java.util.List;
+import java.util.Map;
+
+public class StudentObjectiveDetailDto {
+
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long studentId;
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long examId;
+    private String studentName;
+    private String studentCode;
+    private String courseCode;
+    private String courseName;
+    private String paperNumber;
+    private String secretNumber;
+    private String college;
+    private String className;
+    private String examPlace;
+    private String examRoom;
+    private Double objectiveScore;
+    private Double subjectiveScore;
+    private Boolean upload;
+    private Boolean absent;
+    private List<SheetUrlDto> sheetUrls;
+    private List<StudentObjectiveAnswerDto> answers;
+    private Map<Integer, String> titles;
+
+    public Long getStudentId() {
+        return studentId;
+    }
+
+    public void setStudentId(Long studentId) {
+        this.studentId = studentId;
+    }
+
+    public Long getExamId() {
+        return examId;
+    }
+
+    public void setExamId(Long examId) {
+        this.examId = examId;
+    }
+
+    public String getStudentName() {
+        return studentName;
+    }
+
+    public void setStudentName(String studentName) {
+        this.studentName = studentName;
+    }
+
+    public String getStudentCode() {
+        return studentCode;
+    }
+
+    public void setStudentCode(String studentCode) {
+        this.studentCode = studentCode;
+    }
+
+    public String getCourseCode() {
+        return courseCode;
+    }
+
+    public void setCourseCode(String courseCode) {
+        this.courseCode = courseCode;
+    }
+
+    public String getCourseName() {
+        return courseName;
+    }
+
+    public void setCourseName(String courseName) {
+        this.courseName = courseName;
+    }
+
+    public String getPaperNumber() {
+        return paperNumber;
+    }
+
+    public void setPaperNumber(String paperNumber) {
+        this.paperNumber = paperNumber;
+    }
+
+    public String getSecretNumber() {
+        return secretNumber;
+    }
+
+    public void setSecretNumber(String secretNumber) {
+        this.secretNumber = secretNumber;
+    }
+
+    public String getCollege() {
+        return college;
+    }
+
+    public void setCollege(String college) {
+        this.college = college;
+    }
+
+    public String getClassName() {
+        return className;
+    }
+
+    public void setClassName(String className) {
+        this.className = className;
+    }
+
+    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 Double getObjectiveScore() {
+        return objectiveScore;
+    }
+
+    public void setObjectiveScore(Double objectiveScore) {
+        this.objectiveScore = objectiveScore;
+    }
+
+    public Double getSubjectiveScore() {
+        return subjectiveScore;
+    }
+
+    public void setSubjectiveScore(Double subjectiveScore) {
+        this.subjectiveScore = subjectiveScore;
+    }
+
+    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 List<SheetUrlDto> getSheetUrls() {
+        return sheetUrls;
+    }
+
+    public void setSheetUrls(List<SheetUrlDto> sheetUrls) {
+        this.sheetUrls = sheetUrls;
+    }
+
+    public List<StudentObjectiveAnswerDto> getAnswers() {
+        return answers;
+    }
+
+    public void setAnswers(List<StudentObjectiveAnswerDto> answers) {
+        this.answers = answers;
+    }
+
+    public Map<Integer, String> getTitles() {
+        return titles;
+    }
+
+    public void setTitles(Map<Integer, String> titles) {
+        this.titles = titles;
+    }
+}

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

@@ -152,6 +152,15 @@ public class MarkPaper implements Serializable {
     public void setPaperNumber(String paperNumber) {
         this.paperNumber = paperNumber;
     }
+
+    public String getCoursePaperId() {
+        return coursePaperId;
+    }
+
+    public void setCoursePaperId(String coursePaperId) {
+        this.coursePaperId = coursePaperId;
+    }
+
     public Double getObjectiveScore() {
         return objectiveScore;
     }

+ 4 - 3
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/entity/MarkQuestion.java

@@ -7,6 +7,7 @@ import java.io.Serializable;
 
 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
 import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.qmth.teachcloud.mark.enums.ObjectivePolicy;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
@@ -61,7 +62,7 @@ public class MarkQuestion implements Serializable {
     private Double intervalScore;
 
     @ApiModelProperty(value = "客观题判分策略")
-    private String objectivePolicy;
+    private ObjectivePolicy objectivePolicy;
 
     @ApiModelProperty(value = "题型")
     private String questionType;
@@ -145,11 +146,11 @@ public class MarkQuestion implements Serializable {
     public void setIntervalScore(Double intervalScore) {
         this.intervalScore = intervalScore;
     }
-    public String getObjectivePolicy() {
+    public ObjectivePolicy getObjectivePolicy() {
         return objectivePolicy;
     }
 
-    public void setObjectivePolicy(String objectivePolicy) {
+    public void setObjectivePolicy(ObjectivePolicy objectivePolicy) {
         this.objectivePolicy = objectivePolicy;
     }
     public String getQuestionType() {

+ 57 - 16
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/entity/MarkStudent.java

@@ -13,6 +13,8 @@ import io.swagger.annotations.ApiModelProperty;
 import org.apache.commons.lang3.StringUtils;
 
 import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.LinkedList;
 import java.util.List;
 
 /**
@@ -27,6 +29,9 @@ import java.util.List;
 @ApiModel(value = "MarkStudent对象", description = "考试考生库")
 public class MarkStudent implements Serializable {
 
+    public static final String SPLIT = ";";
+
+
     private static final long serialVersionUID = 1L;
 
     @JsonSerialize(using = ToStringSerializer.class)
@@ -81,16 +86,16 @@ public class MarkStudent implements Serializable {
     private String answers;
 
     @ApiModelProperty(value = "是否已上传")
-    private Integer isUpload;
+    private Boolean isUpload;
 
     @ApiModelProperty(value = "是否缺考")
-    private Integer isAbsent;
+    private Boolean isAbsent;
 
     @ApiModelProperty(value = "是否人工指定缺考")
-    private Integer isManualAbsent;
+    private Boolean isManualAbsent;
 
     @ApiModelProperty(value = "是否违纪")
-    private Integer isBreach;
+    private Boolean isBreach;
 
     @ApiModelProperty(value = "上传时间")
     private Long uploadTime;
@@ -286,36 +291,36 @@ public class MarkStudent implements Serializable {
         this.answers = answers;
     }
 
-    public Integer getIsUpload() {
+    public Boolean getUpload() {
         return isUpload;
     }
 
-    public void setIsUpload(Integer isUpload) {
-        this.isUpload = isUpload;
+    public void setUpload(Boolean upload) {
+        isUpload = upload;
     }
 
-    public Integer getIsAbsent() {
+    public Boolean getAbsent() {
         return isAbsent;
     }
 
-    public void setIsAbsent(Integer isAbsent) {
-        this.isAbsent = isAbsent;
+    public void setAbsent(Boolean absent) {
+        isAbsent = absent;
     }
 
-    public Integer getIsManualAbsent() {
+    public Boolean getManualAbsent() {
         return isManualAbsent;
     }
 
-    public void setIsManualAbsent(Integer isManualAbsent) {
-        this.isManualAbsent = isManualAbsent;
+    public void setManualAbsent(Boolean manualAbsent) {
+        isManualAbsent = manualAbsent;
     }
 
-    public Integer getIsBreach() {
+    public Boolean getBreach() {
         return isBreach;
     }
 
-    public void setIsBreach(Integer isBreach) {
-        this.isBreach = isBreach;
+    public void setBreach(Boolean breach) {
+        isBreach = breach;
     }
 
     public Long getUploadTime() {
@@ -507,6 +512,42 @@ public class MarkStudent implements Serializable {
         return score;
     }
 
+    public List<String> getAnswerList() {
+        String[] values = StringUtils.split(StringUtils.trimToNull(answers), SPLIT);
+        List<String> list = new ArrayList<String>();
+        if (values != null && values.length > 0) {
+            for (String answer : values) {
+                list.add(StringUtils.trim(answer));
+            }
+        }
+        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;
+    }
+
 	@Override
     public String toString() {
         return "MarkStudent{" +

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

@@ -38,6 +38,8 @@ public class ScanPackage implements Serializable {
     @ApiModelProperty(value = "卷袋编号")
     private String packageCode;
 
+    private Integer index;
+
     @ApiModelProperty(value = "签到表图片路径")
     private String path;
 
@@ -84,6 +86,15 @@ public class ScanPackage implements Serializable {
     public void setPackageCode(String packageCode) {
         this.packageCode = packageCode;
     }
+
+    public Integer getIndex() {
+        return index;
+    }
+
+    public void setIndex(Integer index) {
+        this.index = index;
+    }
+
     public String getPath() {
         return path;
     }

+ 35 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/enums/ObjectivePolicy.java

@@ -0,0 +1,35 @@
+package com.qmth.teachcloud.mark.enums;
+
+/**
+ * 客观题判断策略
+ * 
+ */
+public enum ObjectivePolicy {
+    NONE("无", 1), ALL("任选给分", 2), LEAK("漏选给分", 3);
+
+    private String name;
+
+    private int value;
+
+    private ObjectivePolicy(String name, int value) {
+        this.name = name;
+        this.value = value;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public int getValue() {
+        return value;
+    }
+
+    public static ObjectivePolicy findByValue(int value) {
+        for (ObjectivePolicy c : ObjectivePolicy.values()) {
+            if (c.getValue() == value) {
+                return c;
+            }
+        }
+        return null;
+    }
+}

+ 3 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/mapper/MarkPaperMapper.java

@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.qmth.teachcloud.common.bean.dto.mark.MarkSettingDto;
 import com.qmth.teachcloud.mark.dto.mark.score.CheckScoreListDto;
+import com.qmth.teachcloud.mark.dto.mark.score.MarkPaperPackageDto;
 import com.qmth.teachcloud.mark.entity.MarkPaper;
 import org.apache.ibatis.annotations.Param;
 
@@ -25,4 +26,6 @@ public interface MarkPaperMapper extends BaseMapper<MarkPaper> {
     List<MarkPaper> listQualityMarkPaperByStatus(@Param("status") String status, @Param("uploadCount") int uploadCount);
 
     IPage<CheckScoreListDto> listStudentScoreList(@Param("page") Page<CheckScoreListDto> page, @Param("examId") Long examId, @Param("courseCode") String courseCode, @Param("paperNumber") String paperNumber);
+
+    IPage<MarkPaperPackageDto> listPackage(@Param("page") Page<MarkPaperPackageDto> page, @Param("examId") Long examId, @Param("paperNumber") String paperNumber, @Param("packageCode") String packageCode);
 }

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

@@ -1,11 +1,12 @@
 package com.qmth.teachcloud.mark.service;
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.IService;
 import com.qmth.teachcloud.common.bean.dto.mark.MarkSettingDto;
+import com.qmth.teachcloud.common.enums.mark.MarkPaperStatus;
 import com.qmth.teachcloud.mark.dto.mark.score.CheckScoreListDto;
+import com.qmth.teachcloud.mark.dto.mark.score.MarkPaperPackageDto;
 import com.qmth.teachcloud.mark.entity.MarkPaper;
-import com.baomidou.mybatisplus.extension.service.IService;
-import com.qmth.teachcloud.common.enums.mark.MarkPaperStatus;
 
 import java.util.List;
 
@@ -29,7 +30,13 @@ public interface MarkPaperService extends IService<MarkPaper> {
 
     List<MarkPaper> listQualityMarkPaperByStatus(MarkPaperStatus formal, int uploadCount);
 
-	int getCountByExam(Long id);
+    int getCountByExam(Long id);
 
     IPage<CheckScoreListDto> listStudentScoreList(Long examId, String courseCode, String paperNumber, Integer pageNumber, Integer pageSize);
+
+    void updateStatus(Long examId, String paperNumber, MarkPaperStatus newStatus, MarkPaperStatus currentStatus);
+
+    void updateUploadCount(Long examId, String paperNumber, int countUploaded);
+
+    IPage<MarkPaperPackageDto> listPackage(Long examId, String paperNumber, String packageCode, Integer pageNumber, Integer pageSize);
 }

+ 8 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/MarkStudentService.java

@@ -11,6 +11,7 @@ import com.qmth.teachcloud.common.enums.mark.SubjectiveStatus;
 import com.qmth.teachcloud.mark.bean.scanexaminfo.ScanExamCheckInfoVo;
 import com.qmth.teachcloud.mark.bean.scanexaminfo.ScanExamInfoVo;
 import com.qmth.teachcloud.mark.dto.mark.score.SheetUrlDto;
+import com.qmth.teachcloud.mark.dto.mark.score.StudentObjectiveDetailDto;
 import com.qmth.teachcloud.mark.dto.mark.score.StudentScoreDetailDto;
 import com.qmth.teachcloud.mark.entity.MarkStudent;
 
@@ -44,4 +45,11 @@ public interface MarkStudentService extends IService<MarkStudent> {
     MarkStudent findByExamIdAndCoursePaperIdAndStudentCode(Long examId, String coursePaperId, String studentCode);
 
 
+    StudentObjectiveDetailDto getCheckObjectiveTask(Long studentId);
+
+    Boolean saveCheckObjectiveTask(Long studentId, String answers);
+
+    int countUploadedByExamIdAndPaperNumber(Long examId, String paperNumber);
+
+    boolean updateScanInfo(MarkStudent student);
 }

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

@@ -3,6 +3,8 @@ package com.qmth.teachcloud.mark.service;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.qmth.teachcloud.mark.entity.ScanPackage;
 
+import java.util.List;
+
 /**
  * <p>
  *  服务类
@@ -15,4 +17,5 @@ public interface ScanPackageService extends IService<ScanPackage> {
 
 	int getCount(Long examId);
 
+    List<ScanPackage> listByExamIdAndCoursePaperIdAndPackageCode(Long examId, String coursePaperId, String packageCode);
 }

+ 47 - 2
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkPaperServiceImpl.java

@@ -6,16 +6,22 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.qmth.teachcloud.common.bean.dto.mark.MarkSettingDto;
-import com.qmth.teachcloud.mark.dto.mark.score.CheckScoreListDto;
-import com.qmth.teachcloud.mark.entity.MarkPaper;
 import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
 import com.qmth.teachcloud.common.enums.mark.MarkPaperStatus;
+import com.qmth.teachcloud.common.service.TeachcloudCommonService;
+import com.qmth.teachcloud.mark.dto.mark.score.CheckScoreListDto;
+import com.qmth.teachcloud.mark.dto.mark.score.MarkPaperPackageDto;
+import com.qmth.teachcloud.mark.entity.MarkPaper;
+import com.qmth.teachcloud.mark.entity.ScanPackage;
 import com.qmth.teachcloud.mark.mapper.MarkPaperMapper;
 import com.qmth.teachcloud.mark.service.MarkPaperService;
+import com.qmth.teachcloud.mark.service.ScanPackageService;
 import org.springframework.stereotype.Service;
 
+import javax.annotation.Resource;
 import java.util.List;
 import java.util.Objects;
+import java.util.stream.Collectors;
 
 /**
  * <p>
@@ -28,6 +34,12 @@ import java.util.Objects;
 @Service
 public class MarkPaperServiceImpl extends ServiceImpl<MarkPaperMapper, MarkPaper> implements MarkPaperService {
 
+    @Resource
+    private ScanPackageService scanPackageService;
+    @Resource
+    private TeachcloudCommonService teachcloudCommonService;
+
+
     @Override
     public IPage<MarkSettingDto> listPaperSetting(Long examId, String courseCode, String paperNumber, Boolean groupStatus, Integer pageNumber, Integer pageSize) {
         Page<MarkSettingDto> page = new Page<>(pageNumber, pageSize);
@@ -96,4 +108,37 @@ public class MarkPaperServiceImpl extends ServiceImpl<MarkPaperMapper, MarkPaper
         return this.baseMapper.listStudentScoreList(page, examId, courseCode, paperNumber);
     }
 
+    @Override
+    public void updateStatus(Long examId, String paperNumber, MarkPaperStatus newStatus, MarkPaperStatus currentStatus) {
+        UpdateWrapper<MarkPaper> updateWrapper = new UpdateWrapper<>();
+        updateWrapper.lambda().set(MarkPaper::getStatus, newStatus)
+                .eq(MarkPaper::getExamId, examId)
+                .eq(MarkPaper::getPaperNumber, paperNumber)
+                .eq(MarkPaper::getStatus, currentStatus);
+        this.update(updateWrapper);
+    }
+
+    @Override
+    public void updateUploadCount(Long examId, String paperNumber, int countUploaded) {
+        UpdateWrapper<MarkPaper> updateWrapper = new UpdateWrapper<>();
+        updateWrapper.lambda().set(MarkPaper::getUploadCount, countUploaded)
+                .eq(MarkPaper::getExamId, examId)
+                .eq(MarkPaper::getPaperNumber, paperNumber);
+        this.update(updateWrapper);
+    }
+
+    @Override
+    public IPage<MarkPaperPackageDto> listPackage(Long examId, String paperNumber, String packageCode, Integer pageNumber, Integer pageSize) {
+        MarkPaper markPaper = this.getByExamIdAndPaperNumber(examId, paperNumber);
+        Page<MarkPaperPackageDto> page = new Page<>(pageNumber, pageSize);
+        IPage<MarkPaperPackageDto> markPaperPackageDtoIPage = this.baseMapper.listPackage(page, examId, paperNumber, packageCode);
+        for (MarkPaperPackageDto packageDto : markPaperPackageDtoIPage.getRecords()) {
+            List<ScanPackage> scanPackageList = scanPackageService.listByExamIdAndCoursePaperIdAndPackageCode(examId, markPaper.getCoursePaperId(), packageDto.getPackageCode());
+            List<String> urls = scanPackageList.stream().map(m -> teachcloudCommonService.filePreview(m.getPath())).collect(Collectors.toList());
+            packageDto.setCount(urls.size());
+            packageDto.setUrls(urls);
+        }
+        return markPaperPackageDtoIPage;
+    }
+
 }

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

@@ -151,7 +151,7 @@ public class MarkQuestionServiceImpl extends ServiceImpl<MarkQuestionMapper, Mar
             }
             UpdateWrapper<MarkQuestion> updateWrapper = new UpdateWrapper<>();
             updateWrapper.lambda().set(MarkQuestion::getAnswer, question.getAnswer());
-            if (StringUtils.isNotBlank(question.getObjectivePolicy())) {
+            if (question.getObjectivePolicy() != null) {
                 updateWrapper.lambda().set(MarkQuestion::getObjectivePolicy, question.getObjectivePolicy());
             }
             updateWrapper.lambda().eq(MarkQuestion::getId, question.getId());

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

@@ -10,19 +10,20 @@ import com.qmth.boot.core.exception.ParameterException;
 import com.qmth.teachcloud.common.entity.BasicExam;
 import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
 import com.qmth.teachcloud.common.enums.ScanStatus;
+import com.qmth.teachcloud.common.enums.mark.MarkPaperStatus;
 import com.qmth.teachcloud.common.enums.mark.SubjectiveStatus;
 import com.qmth.teachcloud.common.enums.scan.ConditionType;
 import com.qmth.teachcloud.common.service.TeachcloudCommonService;
 import com.qmth.teachcloud.mark.bean.scanexaminfo.CheckTask;
 import com.qmth.teachcloud.mark.bean.scanexaminfo.ScanExamCheckInfoVo;
 import com.qmth.teachcloud.mark.bean.scanexaminfo.ScanExamInfoVo;
-import com.qmth.teachcloud.mark.dto.mark.score.SheetUrlDto;
-import com.qmth.teachcloud.mark.dto.mark.score.StudentPaperDetailDto;
-import com.qmth.teachcloud.mark.dto.mark.score.StudentScoreDetailDto;
+import com.qmth.teachcloud.mark.dto.mark.ScoreInfo;
+import com.qmth.teachcloud.mark.dto.mark.score.*;
 import com.qmth.teachcloud.mark.entity.*;
 import com.qmth.teachcloud.mark.enums.OmrTaskStatus;
 import com.qmth.teachcloud.mark.mapper.MarkStudentMapper;
 import com.qmth.teachcloud.mark.service.*;
+import com.qmth.teachcloud.mark.utils.ScoreCalculateUtil;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -33,7 +34,9 @@ import javax.annotation.Resource;
 import javax.validation.constraints.NotNull;
 import java.text.DecimalFormat;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.stream.Collectors;
 
 /**
@@ -61,6 +64,8 @@ public class MarkStudentServiceImpl extends ServiceImpl<MarkStudentMapper, MarkS
     @Autowired
     private ScanStudentPaperService studentPaperService;
     @Resource
+    private MarkQuestionService markQuestionService;
+    @Resource
     private TeachcloudCommonService teachcloudCommonService;
 
     @Override
@@ -244,4 +249,135 @@ public class MarkStudentServiceImpl extends ServiceImpl<MarkStudentMapper, MarkS
         lw.eq(MarkStudent::getStudentCode, studentCode);
         return baseMapper.selectOne(wrapper);
     }
+
+    @Override
+    public StudentObjectiveDetailDto getCheckObjectiveTask(Long studentId) {
+        MarkStudent markStudent = this.getById(studentId);
+        StudentObjectiveDetailDto studentObjectiveDetailDto = new StudentObjectiveDetailDto();
+        if (markStudent != null) {
+            studentObjectiveDetailDto.setStudentId(markStudent.getId());
+            studentObjectiveDetailDto.setStudentName(markStudent.getStudentName());
+            studentObjectiveDetailDto.setStudentCode(markStudent.getStudentCode());
+            studentObjectiveDetailDto.setExamPlace(markStudent.getExamPlace());
+            studentObjectiveDetailDto.setExamRoom(markStudent.getExamRoom());
+            studentObjectiveDetailDto.setExamId(markStudent.getExamId());
+            studentObjectiveDetailDto.setCourseCode(markStudent.getCourseCode());
+            studentObjectiveDetailDto.setCourseName(markStudent.getCourseName());
+            studentObjectiveDetailDto.setPaperNumber(markStudent.getPaperNumber());
+            studentObjectiveDetailDto.setObjectiveScore(markStudent.getObjectiveScore() != null ? markStudent.getObjectiveScore() : 0);
+            studentObjectiveDetailDto.setSubjectiveScore(markStudent.getSubjectiveScore() != null ? markStudent.getSubjectiveScore() : 0);
+            studentObjectiveDetailDto.setUpload(markStudent.getUpload());
+            studentObjectiveDetailDto.setAbsent(markStudent.getAbsent());
+            studentObjectiveDetailDto.setSheetUrls(this.buildSheetUrls(studentId));
+
+            List<MarkQuestion> questions = markQuestionService.listQuestionByExamIdAndPaperNumberAndGroupNumber(markStudent.getExamId(), markStudent.getPaperNumber(), null, true);
+            List<String> answers = markStudent.getAnswerList();
+            int questionCount = questions.size();
+            int answerCount = answers.size();
+
+            List<StudentObjectiveAnswerDto> answerDtoList = new ArrayList<>();
+            Map<Integer, String> titles = new HashMap<>();
+            // 已设置客观题
+            int maxCount = Math.max(questionCount, answerCount);
+            for (int i = 0; i < maxCount; i++) {
+                MarkQuestion q = questionCount > i ? questions.get(i) : null;
+                String answer = answerCount > i ? answers.get(i) : "#";
+                StudentObjectiveAnswerDto studentObjectiveAnswerDto = new StudentObjectiveAnswerDto();
+                studentObjectiveAnswerDto.setMainNumber(q != null ? q.getMainNumber() : 0);
+                studentObjectiveAnswerDto.setSubNumber(q != null ? q.getSubNumber() : 0);
+                studentObjectiveAnswerDto.setAnswer(answer);
+                studentObjectiveAnswerDto.setExist(q != null && q.getTotalScore() > 0);
+                studentObjectiveAnswerDto.setQuestionType(q != null && q.getQuestionType() != null ? q.getQuestionType() : "");
+                answerDtoList.add(studentObjectiveAnswerDto);
+
+                if (q != null) {
+                    titles.put(q.getMainNumber(), q.getMainTitle());
+                }
+            }
+            studentObjectiveDetailDto.setAnswers(answerDtoList);
+            studentObjectiveDetailDto.setTitles(titles);
+        }
+
+        return studentObjectiveDetailDto;
+    }
+
+    @Override
+    public Boolean saveCheckObjectiveTask(Long studentId, String answers) {
+        MarkStudent student = this.getById(studentId);
+        answers = StringUtils.trimToEmpty(answers);
+        if (student != null) {
+            student.setAnswers(answers.toUpperCase());
+            this.updateById(student);
+            return saveUploadStudent(student);
+        } else {
+            return false;
+        }
+    }
+
+    @Override
+    public int countUploadedByExamIdAndPaperNumber(Long examId, String paperNumber) {
+        QueryWrapper<MarkStudent> queryWrapper = new QueryWrapper<>();
+        queryWrapper.lambda().eq(MarkStudent::getExamId, examId)
+                .eq(MarkStudent::getPaperNumber, paperNumber)
+                .eq(MarkStudent::getUpload, true)
+                .eq(MarkStudent::getAbsent, false)
+                .eq(MarkStudent::getBreach, false);
+        return this.count(queryWrapper);
+    }
+
+    @Override
+    public boolean updateScanInfo(MarkStudent student) {
+        UpdateWrapper<MarkStudent> updateWrapper = new UpdateWrapper<>();
+        updateWrapper.lambda().set(MarkStudent::getSheetCount, student.getSheetCount())
+                .set(MarkStudent::getAnswers, student.getAnswers())
+                .set(MarkStudent::getBatchCode, student.getBatchCode())
+                .set(MarkStudent::getAbsent, student.getAbsent())
+                .set(MarkStudent::getUpload, true)
+                .set(MarkStudent::getUploadTime, System.currentTimeMillis())
+                .set(MarkStudent::getObjectiveScore, student.getObjectiveScore())
+                .set(MarkStudent::getObjectiveScoreList, student.getObjectiveScoreList())
+                .set(MarkStudent::getCardNumber, student.getCardNumber())
+                .eq(MarkStudent::getId, student.getId());
+        return this.update(updateWrapper);
+
+    }
+
+    private boolean saveUploadStudent(MarkStudent student) {
+        MarkStudent old = this.getById(student.getId());
+        if (!student.getAbsent()) {// 正考
+            MarkPaper markPaper = markPaperService.getByExamIdAndPaperNumber(student.getExamId(), student.getPaperNumber());
+            if (markPaper.getStatus().equals(MarkPaperStatus.FINISH)) {
+                markPaperService.updateStatus(markPaper.getExamId(), markPaper.getPaperNumber(), MarkPaperStatus.FORMAL, MarkPaperStatus.FINISH);
+            }
+        }
+        calculateObjectiveScore(student);
+        if (student.getAbsent()) {// 转缺考
+            student.setObjectiveScore(0d);
+            student.setObjectiveScoreList(null);
+        }
+        if (!old.getAbsent() && student.getAbsent()) {// 正考转缺考
+            student.setSubjectiveScore(0d);
+            student.setSubjectiveScoreList(null);
+            this.updateById(student);
+            this.updateSubjectiveStatusAndScore(student.getId(), SubjectiveStatus.UNMARK, 0D, null);
+        }
+        boolean success = this.updateScanInfo(student);
+        if (success) {
+            markPaperService.updateUploadCount(
+                    student.getExamId(),
+                    student.getPaperNumber(),
+                    this.countUploadedByExamIdAndPaperNumber(student.getExamId(), student.getPaperNumber()));
+        }
+        return success;
+    }
+
+    private void calculateObjectiveScore(MarkStudent student) {
+        ScoreCalculateUtil util = ScoreCalculateUtil.instance(student);
+
+        ScoreInfo info = util.calculate(
+                markQuestionService.listQuestionByExamIdAndPaperNumberAndGroupNumber(student.getExamId(),
+                        student.getPaperNumber(), null, true), null);
+        student.setObjectiveScore(info.getObjectiveScore());
+        student.setScoreList(info.getScoreList(), true);
+    }
 }

+ 25 - 9
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/ScanPackageServiceImpl.java

@@ -1,13 +1,15 @@
 package com.qmth.teachcloud.mark.service.impl;
 
-import org.springframework.stereotype.Service;
-
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.qmth.teachcloud.mark.entity.ScanPackage;
 import com.qmth.teachcloud.mark.mapper.ScanPackageMapper;
 import com.qmth.teachcloud.mark.service.ScanPackageService;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
 
 /**
  * <p>
@@ -20,12 +22,26 @@ import com.qmth.teachcloud.mark.service.ScanPackageService;
 @Service
 public class ScanPackageServiceImpl extends ServiceImpl<ScanPackageMapper, ScanPackage> implements ScanPackageService {
 
-	@Override
-	public int getCount(Long examId) {
-		QueryWrapper<ScanPackage> wrapper = new QueryWrapper<>();
-		LambdaQueryWrapper<ScanPackage> lw = wrapper.lambda();
-		lw.eq(ScanPackage::getExamId, examId);
-		return baseMapper.selectCount(wrapper);
-	}
+    @Override
+    public int getCount(Long examId) {
+        QueryWrapper<ScanPackage> wrapper = new QueryWrapper<>();
+        LambdaQueryWrapper<ScanPackage> lw = wrapper.lambda();
+        lw.eq(ScanPackage::getExamId, examId);
+        return baseMapper.selectCount(wrapper);
+    }
+
+    @Override
+    public List<ScanPackage> listByExamIdAndCoursePaperIdAndPackageCode(Long examId, String coursePaperId, String packageCode) {
+        QueryWrapper<ScanPackage> queryWrapper = new QueryWrapper<>();
+        LambdaQueryWrapper<ScanPackage> lambdaQueryWrapper = queryWrapper.lambda();
+        lambdaQueryWrapper.eq(ScanPackage::getExamId, examId)
+                .eq(ScanPackage::getCoursePaperId, coursePaperId);
+        if (StringUtils.isNotBlank(packageCode)) {
+            lambdaQueryWrapper.eq(ScanPackage::getPackageCode, packageCode)
+                    .orderByAsc(ScanPackage::getPackageCode);
+        }
+        lambdaQueryWrapper.orderByAsc(ScanPackage::getIndex);
+        return this.list(queryWrapper);
+    }
 
 }

+ 146 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/utils/ScoreCalculateUtil.java

@@ -0,0 +1,146 @@
+package com.qmth.teachcloud.mark.utils;
+
+import com.qmth.teachcloud.mark.dto.mark.ScoreInfo;
+import com.qmth.teachcloud.mark.dto.mark.ScoreItem;
+import com.qmth.teachcloud.mark.entity.MarkQuestion;
+import com.qmth.teachcloud.mark.entity.MarkStudent;
+import com.qmth.teachcloud.mark.enums.ObjectivePolicy;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.LinkedList;
+import java.util.List;
+
+public class ScoreCalculateUtil {
+
+    protected static Logger log = LoggerFactory.getLogger(ScoreCalculateUtil.class);
+
+    private MarkStudent student;
+
+    private ScoreCalculateUtil(MarkStudent student) {
+        this.student = student;
+    }
+
+    public ScoreInfo calculate(List<MarkQuestion> oList, List<MarkQuestion> sList) {
+        // log.debug("start calculate, examId=" + student.getExamId() +
+        // ", examNumber=" + student.getExamNumber());
+
+        ScoreInfo info = new ScoreInfo();
+        if (oList != null && oList.size() > 0) {
+            calculateObjective(oList, info);
+        }
+        if (sList != null && sList.size() > 0) {
+            calculateSubjective(sList, info);
+        }
+        return info;
+    }
+
+    private void calculateObjective(List<MarkQuestion> questionList, ScoreInfo scoreInfo) {
+        // log.debug("start calculate objective score");
+        List<String> answerList = student.getAnswerList();
+        // Map<String, Integer> config = exam.getObjectiveBlockMap();
+
+        // log.debug("student answers: " + student.getAnswers());
+        // log.debug("exam objective config: " + exam.getObjectiveBlock());
+
+        int index = -1;
+        int lastMainNumber = 0;
+        for (MarkQuestion question : questionList) {
+            // log.debug("find objective block for " + block.getTitle() +
+            // ", question start=" + start);
+            if (question.getMainNumber() != lastMainNumber) {
+                scoreInfo.incrMainNumber(question.getMainTitle());
+            }
+
+            index++;
+            String answer = "#";
+            double score = 0d;
+            try {
+                answer = answerList.get(index);
+            } catch (Exception e) {
+                continue;
+            }
+
+            boolean correct = true;
+
+            // 客观题判分策略
+            // 任选给分
+            if (ObjectivePolicy.ALL.equals(question.getObjectivePolicy())) {
+                score = answer.length() == 0 || answer.equals("#") ? 0 : question.getTotalScore();
+            } else {
+                for (int i = 0; i < answer.length(); i++) {
+                    if (!question.getAnswer().contains(String.valueOf(answer.charAt(i)))) {
+                        correct = false;
+                        break;
+                    }
+                }
+                if (correct & ObjectivePolicy.LEAK.equals(question.getObjectivePolicy())) {
+                    score = answer.length() < question.getAnswer().length() ? question.getTotalScore() / 2 : question
+                            .getTotalScore();
+                }
+                if (correct
+                        & (question.getObjectivePolicy() == null || ObjectivePolicy.NONE.equals(question
+                        .getObjectivePolicy()))) {
+                    score = answer.length() < question.getAnswer().length() ? 0 : question.getTotalScore();
+                }
+            }
+
+            // log.debug("question result: " + question.getNumber() + ", " +
+            // answer + ", " + score);
+            scoreInfo.addScore(null, String.valueOf(question.getSubNumber()), score, answer, true);
+        }
+    }
+
+    private void calculateSubjective(List<MarkQuestion> sList, ScoreInfo scoreInfo) {
+
+    }
+
+    public static ScoreCalculateUtil instance(MarkStudent student) {
+        return new ScoreCalculateUtil(student);
+    }
+
+    public static void main(String[] args) {
+        MarkStudent student = new MarkStudent();
+        student.setAnswers("A,B,AB,C,#,#,#,#");
+        ScoreCalculateUtil util = ScoreCalculateUtil.instance(student);
+
+        List<MarkQuestion> oList = new LinkedList<MarkQuestion>();
+        // ExamQuestion q = new ExamQuestion();
+        // q.setMainNumber(1);
+        // q.setMainTitle("单选");
+        // q.setSubNumber(1);
+        // q.setAnswer("B");
+        // q.setTotalScore(2d);
+        // oList.add(q);
+        //
+        // q = new ExamQuestion();
+        // q.setMainNumber(1);
+        // q.setMainTitle("单选");
+        // q.setSubNumber(2);
+        // q.setAnswer("B");
+        // q.setTotalScore(2d);
+        // oList.add(q);
+        //
+        // q = new ExamQuestion();
+        // q.setMainNumber(2);
+        // q.setMainTitle("多选");
+        // q.setSubNumber(1);
+        // q.setAnswer("AC");
+        // q.setTotalScore(3d);
+        // oList.add(q);
+        //
+        // q = new ExamQuestion();
+        // q.setMainNumber(2);
+        // q.setMainTitle("多选");
+        // q.setSubNumber(2);
+        // q.setAnswer("C");
+        // q.setTotalScore(3d);
+        // oList.add(q);
+
+        ScoreInfo info = util.calculate(oList, null);
+        System.out.println(info.getObjectiveScore());
+        for (ScoreItem item : info.getScoreList()) {
+            System.out.println(item.getTitle() + ": " + item.toString());
+        }
+    }
+}

+ 13 - 0
teachcloud-mark/src/main/resources/mapper/MarkPaperMapper.xml

@@ -83,4 +83,17 @@
                 AND paper_number = #{paperNumber}
             </if>
     </select>
+    <select id="listPackage" resultType="com.qmth.teachcloud.mark.dto.mark.score.MarkPaperPackageDto">
+        SELECT DISTINCT
+            ms.package_code packageCode
+        FROM
+            mark_student ms
+        WHERE
+            ms.exam_id = #{examId}
+            AND ms.paper_number = #{paperNumber}
+            <if test="packageCode =! null and packageCode != ''">
+                AND ms.package_code = #{packageCode}
+            </if>
+        ORDER BY ms.package_code
+    </select>
 </mapper>