xiaofei 1 рік тому
батько
коміт
0d7549fde8
22 змінених файлів з 269 додано та 54 видалено
  1. 1 1
      distributed-print-business/src/main/resources/mapper/ExamDetailMapper.xml
  2. 8 3
      distributed-print/install/mysql/init/teachcloud_db.sql
  3. 1 1
      distributed-print/src/main/java/com/qmth/distributed/print/api/mark/MarkController.java
  4. 10 1
      distributed-print/src/main/java/com/qmth/distributed/print/api/mark/MarkStudentController.java
  5. 14 1
      distributed-print/src/main/java/com/qmth/distributed/print/api/mark/ScanStudentController.java
  6. 9 1
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/dto/mark/mark/MarkSettingDto.java
  7. 1 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/entity/MarkPaper.java
  8. 6 6
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/mapper/MarkStudentMapper.java
  9. 21 10
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/MarkService.java
  10. 13 5
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/MarkStudentService.java
  11. 3 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/MarkSyncService.java
  12. 2 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/MarkTaskService.java
  13. 2 1
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkGroupServiceImpl.java
  14. 0 6
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkPaperServiceImpl.java
  15. 2 1
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkQuestionServiceImpl.java
  16. 85 10
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkServiceImpl.java
  17. 47 6
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkStudentServiceImpl.java
  18. 15 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkSyncServiceImpl.java
  19. 10 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkTaskServiceImpl.java
  20. 4 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/utils/ScoreCalculateUtil.java
  21. 15 0
      teachcloud-mark/src/main/resources/mapper/MarkStudentMapper.xml
  22. 0 1
      teachcloud-mark/src/main/resources/mapper/MarkTaskMapper.xml

+ 1 - 1
distributed-print-business/src/main/resources/mapper/ExamDetailMapper.xml

@@ -723,6 +723,6 @@
                               ed.exam_id = mp.exam_id
                             AND edc.paper_number = mp.paper_number
                             AND mp.status = #{markStatus})
-        GROUP BY ed.school_id , ed.exam_id , edc.course_code , edc.course_name , edc.paper_number , edc.course_paper_id , edcpt.paper_type , ed.create_id, ed.exam_start_time, ed.exam_end_time
+        GROUP BY ed.school_id , ed.exam_id , edc.course_code , edc.course_name , edc.paper_number , edc.course_paper_id , edcpt.paper_type , et.user_id, ed.exam_start_time, ed.exam_end_time
     </select>
 </mapper>

+ 8 - 3
distributed-print/install/mysql/init/teachcloud_db.sql

@@ -1520,13 +1520,13 @@ CREATE TABLE IF NOT EXISTS `mark_student` (
         `scan_status` varchar(20) DEFAULT NULL COMMENT '扫描状态',
         `question_filled` bit(1) DEFAULT NULL,
         `assigned` bit(1) DEFAULT NULL,
+        `assign_confirmed` bit(1) DEFAULT 0 COMMENT '人工绑定确认',
         `absent_suspect` bit(1) DEFAULT NULL,
         `incomplete` bit(1) DEFAULT NULL,
         `breach_code` varchar(32) DEFAULT NULL,
         `omr_absent` bit(1) DEFAULT NULL COMMENT '识别缺考',
         `omr_absent_checked` bit(1) DEFAULT NULL COMMENT '识别缺考检查',
         `card_number` int DEFAULT NULL,
-        `assign_confirmed` bit(1) DEFAULT NULL COMMENT '人工绑定确认',
         `exam_start_time` BIGINT(20) NULL COMMENT '考试开始时间',
         `exam_end_time` BIGINT(20) NULL COMMENT '考试结束时间',
         `create_id` BIGINT(20) NULL COMMENT '创建人ID',
@@ -2907,7 +2907,7 @@ INSERT INTO `sys_privilege` (`id`, `name`, `url`, `type`, `parent_id`, `sequence
 INSERT INTO `sys_privilege` (`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `related`, `enable`, `default_auth`, `front_display`) VALUES (947, '列表', 'List', 'LIST', 946, 1, 'AUTH', '952', 1, 0, 1);
 INSERT INTO `sys_privilege` (`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `related`, `enable`, `default_auth`, `front_display`) VALUES (948, '查询条件', 'Condition', 'CONDITION', 946, 2, 'AUTH', NULL, 1, 0, 1);
 INSERT INTO `sys_privilege` (`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `related`, `enable`, `default_auth`, `front_display`) VALUES (949, '查询', 'Select', 'BUTTON', 946, 3, 'AUTH', '952', 1, 0, 1);
-INSERT INTO `sys_privilege` (`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `related`, `enable`, `default_auth`, `front_display`) VALUES (950, '查看详情', 'Detail', 'LINK', 946, 4, 'AUTH', '953,954,955,956,957,958,959,960', 1, 0, 1);
+INSERT INTO `sys_privilege` (`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `related`, `enable`, `default_auth`, `front_display`) VALUES (950, '查看详情', 'Detail', 'LINK', 946, 4, 'AUTH', '953,954,955,956,957,958,959,960,969', 1, 0, 1);
 INSERT INTO `sys_privilege` (`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `related`, `enable`, `default_auth`, `front_display`) VALUES (951, '查看签到表', 'PackageDetail', 'LINK', 946, 5, 'AUTH', '961', 1, 0, 1);
 INSERT INTO `sys_privilege` (`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `related`, `enable`, `default_auth`, `front_display`) VALUES (952, '列表获取', '/api/admin/mark/setting/scoreList', 'URL', 946, 1, 'AUTH', NULL, 1, 1, 1);
 INSERT INTO `sys_privilege` (`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `related`, `enable`, `default_auth`, `front_display`) VALUES (953, '详情列表', '/api/admin/mark/student/score', 'URL', 946, 2, 'AUTH', NULL, 1, 1, 1);
@@ -2926,7 +2926,8 @@ INSERT INTO `sys_privilege` (`id`, `name`, `url`, `type`, `parent_id`, `sequence
 INSERT INTO `sys_privilege` (`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `related`, `enable`, `default_auth`, `front_display`) VALUES (966, '评卷质量重新计算', '/api/admin/mark/quality/update', 'URL', 917, 22, 'AUTH', NULL, 1, 1, 1);
 INSERT INTO `sys_privilege` (`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `related`, `enable`, `default_auth`, `front_display`) VALUES (967, '评卷质量给分曲线', '/api/admin/mark/quality/chart', 'URL', 917, 23, 'AUTH', NULL, 1, 1, 1);
 INSERT INTO `sys_privilege` (`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `enable`, `default_auth`, `front_display`) VALUES ('968', '绑定评卷员-已绑定评卷员集合', '/api/admin/mark/marker/list_bind_marker', 'URL', '917', '20', 'AUTH', '1', '1', '1');
-INSERT INTO `sys_privilege` (`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `related`, `enable`, `default_auth`, `front_display`) VALUES (970, '扫描端', 'scan', 'MENU', NULL, 11, NULL, '971,972,973,974,975,976,977,978,979,980,981,982,983,984,985,986,987,988,989,990,991,992,993,994,995,996,997,998,999,1000,1001,1002,1003,1004,1005,1007,1009', 1, 0, 0);
+INSERT INTO `sys_privilege` (`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `enable`, `default_auth`, `front_display`) VALUES ('969', '客观题统分', '/api/admin/mark/student/objective/calculate', 'URL', '946', '11', 'AUTH', '1', '1', '1');
+INSERT INTO `sys_privilege` (`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `related`, `enable`, `default_auth`, `front_display`) VALUES (970, '扫描端', 'scan', 'MENU', NULL, 11, NULL, '971,972,973,974,975,976,977,978,979,980,981,982,983,984,985,986,987,988,989,990,991,992,993,994,995,996,997,998,999,1000,1001,1002,1003,1004,1005,1007,1009,1010', 1, 0, 0);
 INSERT INTO `sys_privilege` (`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `related`, `enable`, `default_auth`, `front_display`) VALUES (971, '心跳接口', '/api/scan/server/heartbeat', 'URL', 970, 1, 'AUTH', NULL, 1, 1, 1);
 INSERT INTO `sys_privilege` (`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `related`, `enable`, `default_auth`, `front_display`) VALUES (972, '登出接口', '/api/scan/logout', 'URL', 970, 2, 'AUTH', NULL, 1, 1, 1);
 INSERT INTO `sys_privilege` (`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `related`, `enable`, `default_auth`, `front_display`) VALUES (973, '获取学期、考试列表', '/api/admin/basic/condition/scan/semester/list', 'URL', 970, 3, 'AUTH', NULL, 1, 1, 1);
@@ -2966,6 +2967,7 @@ INSERT INTO `sys_privilege` (`id`, `name`, `url`, `type`, `parent_id`, `sequence
 INSERT INTO `sys_privilege` (`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `related`, `enable`, `default_auth`, `front_display`) VALUES (1007, '未扫描-导出', '/api/scan/student/unexist/export', 'URL', 970, 36, 'AUTH', NULL, 1, 1, 1);
 INSERT INTO `sys_privilege` (`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `related`, `enable`, `default_auth`, `front_display`) VALUES (1008, '仲裁-评卷历史', '/api/admin/mark/arbitrate/getHistory', 'URL', 917, 20, 'AUTH', NULL, 1, 1, 1);
 INSERT INTO `sys_privilege` (`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `related`, `enable`, `default_auth`, `front_display`) VALUES (1009, '任务列表', '/api/scan/task/omr/list', 'URL', 970, 37, 'AUTH', NULL, 1, 1, 1);
+INSERT INTO `sys_privilege` (`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `enable`, `default_auth`, `front_display`) VALUES ('1010', '人工绑定确认', '/api/scan/student/assign/confirm', 'URL', '970', '38', 'AUTH', '1', '1', '1');
 
 -- ----------------------------
 -- Table structure for sys_role
@@ -3633,6 +3635,7 @@ INSERT INTO `sys_role_privilege` (`id`, `role_id`, `privilege_id`, `enable`, `sc
 INSERT INTO `sys_role_privilege` (`id`, `role_id`, `privilege_id`, `enable`, `school_id`) VALUES (1726860848045035523, 2, 966, 1, NULL);
 INSERT INTO `sys_role_privilege` (`id`, `role_id`, `privilege_id`, `enable`, `school_id`) VALUES (1726860848045035524, 2, 967, 1, NULL);
 INSERT INTO `sys_role_privilege` (`id`, `role_id`, `privilege_id`, `enable`, `school_id`) VALUES (1626860847045035525, 2, 968, 1, NULL);
+INSERT INTO `sys_role_privilege` (`id`, `role_id`, `privilege_id`, `enable`, `school_id`) VALUES (1626860847045035526, 2, 969, 1, NULL);
 INSERT INTO `sys_role_privilege` (`id`, `role_id`, `privilege_id`, `enable`, `school_id`) VALUES (1726860848045035525, 2, 1008, 1, NULL);
 INSERT INTO `sys_role_privilege` (`id`, `role_id`, `privilege_id`, `enable`, `school_id`) VALUES (1726861309665939457, 3, 280, 1, NULL);
 INSERT INTO `sys_role_privilege` (`id`, `role_id`, `privilege_id`, `enable`, `school_id`) VALUES (1726861309691105281, 3, 281, 1, NULL);
@@ -3785,6 +3788,7 @@ INSERT INTO `sys_role_privilege` (`id`, `role_id`, `privilege_id`, `enable`, `sc
 INSERT INTO `sys_role_privilege` (`id`, `role_id`, `privilege_id`, `enable`, `school_id`) VALUES (1726861309900820482, 3, 966, 1, NULL);
 INSERT INTO `sys_role_privilege` (`id`, `role_id`, `privilege_id`, `enable`, `school_id`) VALUES (1726861309900820483, 3, 967, 1, NULL);
 INSERT INTO `sys_role_privilege` (`id`, `role_id`, `privilege_id`, `enable`, `school_id`) VALUES (1716811119900820483, 3, 968, 1, NULL);
+INSERT INTO `sys_role_privilege` (`id`, `role_id`, `privilege_id`, `enable`, `school_id`) VALUES (1716811119900820484, 3, 969, 1, NULL);
 INSERT INTO `sys_role_privilege` (`id`, `role_id`, `privilege_id`, `enable`, `school_id`) VALUES (1726861309900820484, 3, 463, 1, NULL);
 INSERT INTO `sys_role_privilege` (`id`, `role_id`, `privilege_id`, `enable`, `school_id`) VALUES (1726861309900820485, 3, 464, 1, NULL);
 INSERT INTO `sys_role_privilege` (`id`, `role_id`, `privilege_id`, `enable`, `school_id`) VALUES (1726861309905014786, 3, 465, 1, NULL);
@@ -3933,6 +3937,7 @@ INSERT INTO `sys_role_privilege` (`id`, `role_id`, `privilege_id`, `enable`, `sc
 INSERT INTO `sys_role_privilege` (`id`, `role_id`, `privilege_id`, `enable`, `school_id`) VALUES (1726861744371994627, 6, 1006, 1, NULL);
 INSERT INTO `sys_role_privilege` (`id`, `role_id`, `privilege_id`, `enable`, `school_id`) VALUES (1726861744371994628, 6, 1007, 1, NULL);
 INSERT INTO `sys_role_privilege` (`id`, `role_id`, `privilege_id`, `enable`, `school_id`) VALUES (1726861744376188929, 6, 1009, 1, NULL);
+INSERT INTO `sys_role_privilege` (`id`, `role_id`, `privilege_id`, `enable`, `school_id`) VALUES (1626767744376188929, 6, 1010, 1, NULL);
 INSERT INTO `sys_role_privilege` (`id`, `role_id`, `privilege_id`, `enable`, `school_id`) VALUES (1726862011016482818, 7, 896, 1, NULL);
 INSERT INTO `sys_role_privilege` (`id`, `role_id`, `privilege_id`, `enable`, `school_id`) VALUES (1726862011029065729, 7, 483, 1, NULL);
 INSERT INTO `sys_role_privilege` (`id`, `role_id`, `privilege_id`, `enable`, `school_id`) VALUES (1726862011033260034, 7, 486, 1, NULL);

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

@@ -67,7 +67,6 @@ public class MarkController extends BaseController {
     @RequestMapping(value = "/getSetting", method = RequestMethod.POST)
     public Result getSetting(@RequestParam Long examId, @RequestParam String paperNumber,
                              @RequestParam Integer groupNumber) {
-        validMarkPaperForMark(examId, paperNumber);
         SysUser user = (SysUser) ServletUtil.getRequestUser();
         return ResultUtil.ok(markService.getSetting(user, examId, paperNumber, groupNumber));
     }
@@ -75,6 +74,7 @@ public class MarkController extends BaseController {
     @RequestMapping(value = "/getStatus", method = RequestMethod.POST)
     public Result status(@RequestParam Long examId, @RequestParam String paperNumber,
                          @RequestParam Integer groupNumber) {
+        validMarkPaperForMark(examId, paperNumber);
         SysUser user = (SysUser) ServletUtil.getRequestUser();
         return ResultUtil.ok(markService.getStatus(user.getId(), examId, paperNumber, groupNumber));
     }

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

@@ -56,10 +56,19 @@ public class MarkStudentController {
                                    @ApiParam(value = "客观题分小于x%") @RequestParam(required = false) Integer objectiveScoreRateLt,
                                    @ApiParam(value = "姓名") @RequestParam(required = false) String studentName,
                                    @ApiParam(value = "学号") @RequestParam(required = false) String studentCode,
+                                   @ApiParam(value = "排序方式") @RequestParam(required = false) String orderType,
+                                   @ApiParam(value = "排序字段") @RequestParam(required = false) String orderField,
                                    @RequestParam @Min(SystemConstant.PAGE_NUMBER_MIN) Integer pageNumber,
                                    @RequestParam @Min(SystemConstant.PAGE_SIZE_MIN) @Max(SystemConstant.PAGE_SIZE_MAX) Integer pageSize) {
-        IPage<StudentScoreDetailDto> scoreListDtoIPage = markStudentService.pageStudentScore(examId, paperNumber, college, className, teacher, filter, absent, breach, startScore, endScore, subScore, objectiveScoreRateLt, studentName, studentCode, pageNumber, pageSize);
+        IPage<StudentScoreDetailDto> scoreListDtoIPage = markStudentService.pageStudentScore(examId, paperNumber, college, className, teacher, filter, absent, breach, startScore, endScore, subScore, objectiveScoreRateLt, studentName, studentCode, orderType, orderField, pageNumber, pageSize);
         return ResultUtil.ok(scoreListDtoIPage);
     }
 
+    @ApiOperation(value = "客观题统分")
+    @RequestMapping(value = "/objective/calculate", method = RequestMethod.POST)
+    public Result calcObjectiveScore(@ApiParam(value = "考试ID", required = true) @RequestParam Long examId,
+                                   @ApiParam(value = "试卷编号", required = true) @RequestParam String paperNumber) {
+        return ResultUtil.ok(markStudentService.calcObjectiveScore(examId, paperNumber));
+    }
+
 }

+ 14 - 1
distributed-print/src/main/java/com/qmth/distributed/print/api/mark/ScanStudentController.java

@@ -2,11 +2,13 @@ package com.qmth.distributed.print.api.mark;
 
 import com.qmth.boot.api.constant.ApiConstant;
 import com.qmth.teachcloud.common.contant.SystemConstant;
+import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
 import com.qmth.teachcloud.common.util.Result;
 import com.qmth.teachcloud.common.util.ResultUtil;
 import com.qmth.teachcloud.mark.bean.UpdateTimeVo;
 import com.qmth.teachcloud.mark.bean.student.AbsentManualUpdateVo;
 import com.qmth.teachcloud.mark.bean.student.StudentQuery;
+import com.qmth.teachcloud.mark.entity.MarkStudent;
 import com.qmth.teachcloud.mark.service.MarkStudentService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
@@ -46,7 +48,18 @@ public class ScanStudentController extends BaseController {
         return markStudentService.absentManualUpdate(examId, coursePaperId, studentCode);
     }
 
-    @ApiOperation(value = "任务确认")
+    @ApiOperation(value = "人工绑定-任务确认")
+    @PostMapping("/assign/confirm")
+    public Result confirm(@RequestParam Long studentId) {
+        MarkStudent markStudent = markStudentService.getById(studentId);
+        if (markStudent == null) {
+            throw ExceptionResultEnum.ERROR.exception("考生不存在");
+        }
+        validMarkPaperForScan(markStudent.getExamId(), markStudent.getCoursePaperId());
+        return ResultUtil.ok(markStudentService.updateAssignConfirm(studentId, true));
+    }
+
+    @ApiOperation(value = "识别缺考-任务确认")
     @PostMapping("confirm")
     public UpdateTimeVo confirm(@RequestParam Long examId, @RequestParam String coursePaperId,
                                 @RequestParam String studentCode, @RequestParam(required = false) Boolean omrAbsent) {

+ 9 - 1
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/dto/mark/mark/MarkSettingDto.java

@@ -30,7 +30,8 @@ public class MarkSettingDto {
 	private Boolean selective;
 	private Boolean autoScroll;
 	private Boolean enableSplit;
-	
+	private Boolean showObjectScore;
+
 	public MarkSettingDto() {
 		subject =new MarkSubjectDto();
 	}
@@ -168,4 +169,11 @@ public class MarkSettingDto {
 		this.enableSplit = enableSplit;
 	}
 
+	public Boolean getShowObjectScore() {
+		return showObjectScore;
+	}
+
+	public void setShowObjectScore(Boolean showObjectScore) {
+		this.showObjectScore = showObjectScore;
+	}
 }

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

@@ -148,6 +148,7 @@ public class MarkPaper implements Serializable {
         this.passScore = 60D;
         this.excellentScore = 80D;
         this.forceMode = true;
+        this.showObjectScore = false;
     }
 
     public Long getId() {

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

@@ -27,12 +27,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("className") String className, @Param("teacher") String teacher, @Param("filter") Integer filter,
-			@Param("absent") Boolean absent, @Param("breach") Boolean breach, @Param("startScore") Double startScore,
-			@Param("endScore") Double endScore, @Param("subScore") Double subScore,
-			@Param("objectiveScoreLt") Double objectiveScoreLt, @Param("studentName") String studentName,
-			@Param("studentCode") String studentCode);
+												  @Param("examId") Long examId, @Param("paperNumber") String paperNumber, @Param("college") String college,
+												  @Param("className") String className, @Param("teacher") String teacher, @Param("filter") Integer filter,
+												  @Param("absent") Boolean absent, @Param("breach") Boolean breach, @Param("startScore") Double startScore,
+												  @Param("endScore") Double endScore, @Param("subScore") Double subScore,
+												  @Param("objectiveScoreLt") Double objectiveScoreLt, @Param("studentName") String studentName,
+												  @Param("studentCode") String studentCode, @Param("orderType") String orderType, @Param("orderField") String orderField);
 
 	List<MarkStudent> listAbsentOrBreachMarkTaskStudent(@Param("examId") Long examId,
 			@Param("paperNumber") String paperNumber);

+ 21 - 10
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/MarkService.java

@@ -21,6 +21,14 @@ import io.lettuce.core.GeoArgs.Sort;
  */
 public interface MarkService {
 
+    /**
+     * 释放某个评卷员已完成的评卷任务
+     *
+     * @param submitResult  评卷结果
+     * @param markUserGroup 评卷员
+     */
+    void releaseTask(SubmitResult submitResult, MarkUserGroup markUserGroup);
+
     int applyCurrentCount(MarkGroup markGroup);
 
     void releaseByMarkUserGroup(MarkUserGroup markUserGroup);
@@ -49,13 +57,13 @@ public interface MarkService {
 
     void updateGroupAllCount(Long examId, String paperNumber);
 
-	MarkSettingDto getSetting(SysUser user, Long examId, String paperNumber, Integer groupNumber);
+    MarkSettingDto getSetting(SysUser user, Long examId, String paperNumber, Integer groupNumber);
 
-	MarkStatusDto getStatus(Long userId, Long examId, String paperNumber, Integer groupNumber);
+    MarkStatusDto getStatus(Long userId, Long examId, String paperNumber, Integer groupNumber);
 
-	List<MarkGroupDto> getGroup(Long userId, Long examId, String paperNumber);
+    List<MarkGroupDto> getGroup(Long userId, Long examId, String paperNumber);
 
-	Task getTask(Long userId, Long examId, String paperNumber, Integer groupNumber);
+    Task getTask(Long userId, Long examId, String paperNumber, Integer groupNumber);
 
     void deleteMarkGroup(MarkGroup markGroup, boolean deleteGroupInfo);
 
@@ -65,6 +73,7 @@ public interface MarkService {
      * @param markGroup
      */
     void releaseByMarkGroup(MarkGroup markGroup);
+
     void releaseByStudent(MarkStudent student);
 
     /**
@@ -74,16 +83,18 @@ public interface MarkService {
 
     void submitHeaderTask(List<MarkHeaderGroupResult> markResult, MarkStudent markUserGroup);
 
-	IPage<Task> getHistory(Long userId, int pageNumber, int pageSize, Sort sort,String order, Long examId, String paperNumber,
-			Integer groupNumber, String secretNumber, Double markerScore);
+    IPage<Task> getHistory(Long userId, int pageNumber, int pageSize, Sort sort, String order, Long examId, String paperNumber,
+                           Integer groupNumber, String secretNumber, Double markerScore);
 
-	SubmitResult saveTask(Long examId, String paperNumber, Integer groupNumber, Long userId, MarkResult markResult);
+    SubmitResult saveTask(Long examId, String paperNumber, Integer groupNumber, Long userId, MarkResult markResult);
 
-	void clear(Long userId, Long examId, String paperNumber, Integer groupNumber);
+    void clear(Long userId, Long examId, String paperNumber, Integer groupNumber);
 
-	boolean applyTask(MarkTask t, Long userId);
+    boolean applyTask(MarkTask t, Long userId);
 
-	boolean hasApplied(MarkTask t, Long userId);
+    boolean hasApplied(MarkTask t, Long userId);
 
     void deleteInitMarkData(Long examId, String paperNumber);
+
+    void calcObjectiveScore(MarkPaper markPaper);
 }

+ 13 - 5
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/MarkStudentService.java

@@ -49,7 +49,7 @@ public interface MarkStudentService extends IService<MarkStudent> {
 
     ScanExamInfoVo getScanExamInfo(BasicExam exam, String courseCode, String coursePaperId);
 
-    IPage<StudentScoreDetailDto> pageStudentScore(Long examId, String paperNumber, String college, String className, String teacher, Integer filter, Boolean absent, Boolean breach, Double startScore, Double endScore, Double subScore, Integer objectiveScoreRateLt, String studentName, String studentCode, Integer pageNumber, Integer pageSize);
+    IPage<StudentScoreDetailDto> pageStudentScore(Long examId, String paperNumber, String college, String className, String teacher, Integer filter, Boolean absent, Boolean breach, Double startScore, Double endScore, Double subScore, Integer objectiveScoreRateLt, String studentName, String studentCode, String orderType, String orderField, Integer pageNumber, Integer pageSize);
 
     List<SheetUrlDto> buildSheetUrls(Long studentId);
 
@@ -77,7 +77,7 @@ public interface MarkStudentService extends IService<MarkStudent> {
 
     boolean saveUploadStudent(MarkStudent student);
 
-     void calculateObjectiveScore(MarkStudent student);
+    void calculateObjectiveScore(MarkStudent student);
 
     void updateStudentAndPaper(SysUser user, Long studentId, List<ScanStudentPaper> studentPaperList);
 
@@ -105,11 +105,11 @@ public interface MarkStudentService extends IService<MarkStudent> {
 
     void saveSubjectiveInspectedTask(MarkHeaderResult markResult);
 
-	IPage<ArchiveStudentVo> studentList(ArchiveStudentQuery query);
+    IPage<ArchiveStudentVo> studentList(ArchiveStudentQuery query);
 
-	void scoreExport(ArchiveStudentQuery query, HttpServletResponse response);
+    void scoreExport(ArchiveStudentQuery query, HttpServletResponse response);
 
-	ScoreReportVo scoreReport(Long examId, String paperNumber);
+    ScoreReportVo scoreReport(Long examId, String paperNumber);
 
     void exportUnexist(Long examId, HttpServletResponse response);
 
@@ -122,4 +122,12 @@ public interface MarkStudentService extends IService<MarkStudent> {
     void scoreReportDownload(JSONObject jsonObject, HttpServletResponse response);
 
     void deleteByExamIdAndPaperNumber(Long examId, String paperNumber);
+
+    boolean calcObjectiveScore(Long examId, String paperNumber);
+
+    IPage<MarkStudent> pageByExamAndPaperNumber(Long examId, String paperNumber, int pageNumber, int pageSize);
+
+    void updateObjectiveScoreAndScoreList(MarkStudent markStudent);
+
+    boolean updateAssignConfirm(Long studentId, boolean assignConfirm);
 }

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

@@ -1,6 +1,7 @@
 package com.qmth.teachcloud.mark.service;
 
 import com.qmth.teachcloud.mark.entity.MarkGroup;
+import com.qmth.teachcloud.mark.entity.MarkPaper;
 import com.qmth.teachcloud.mark.entity.MarkUserGroup;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -16,4 +17,6 @@ public interface MarkSyncService {
     void updateQuality(List<MarkUserGroup> markUserGroups, String lockKey);
 
     void deleteMarkGroup(MarkGroup markGroup, boolean deleteGroupInfo);
+
+    void calcObjectiveScore(MarkPaper markPaper);
 }

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

@@ -75,4 +75,6 @@ public interface MarkTaskService extends IService<MarkTask> {
 
 	boolean updateMarkerResult(Long taskId, MarkTaskStatus marked, Long userId, Double markerScore, String scoreList,
 			Long now, int spent,MarkTaskStatus... inStatus);
+
+    int countByExamIdAndPaperNumberAndGroupNumberAndTaskNumber(Long examId, String paperNumber, Integer groupNumber, int taskNumber);
 }

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

@@ -278,6 +278,7 @@ public class MarkGroupServiceImpl extends MppServiceImpl<MarkGroupMapper, MarkGr
         markGroup.setPicList(CardFile.getMarkConfigAdd(markGroupDto.getPictureConfigs(), 0.015));
         Double totalScore = questions.stream().collect(Collectors.summingDouble(MarkQuestion::getTotalScore));
         markGroup.setTotalScore(totalScore);
+        markGroup.setDoubleEnable(markGroupDto.getDoubleEnable());
         if (markGroupDto.getDoubleEnable()) {
             if (markGroupDto.getDoubleRate() == null) {
                 throw ExceptionResultEnum.ERROR.exception("开启双评,双评比例必填");
@@ -290,7 +291,7 @@ public class MarkGroupServiceImpl extends MppServiceImpl<MarkGroupMapper, MarkGr
             if (markGroupDto.getScorePolicy() == null) {
                 throw ExceptionResultEnum.ERROR.exception("开启双评,合分规则必填");
             }
-            String format = new DecimalFormat("####.##").format(markGroupDto.getDoubleRate() / 100);
+            String format = new DecimalFormat("####.##").format(markGroupDto.getDoubleRate());
             markGroup.setDoubleRate(Double.parseDouble(format));
             markGroup.setArbitrateThreshold(markGroupDto.getArbitrateThreshold());
             markGroup.setScorePolicy(markGroupDto.getScorePolicy());

+ 0 - 6
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkPaperServiceImpl.java

@@ -148,12 +148,6 @@ public class MarkPaperServiceImpl extends ServiceImpl<MarkPaperMapper, MarkPaper
                 List<MarkStudent> markStudentList = markStudentService.listByExamIdAndCoursePaperId(examId, markPaper.getCoursePaperId());
                 for (MarkStudent markStudent : markStudentList) {
                     markStudentService.calculateObjectiveScore(markStudent);
-                    UpdateWrapper<MarkStudent> objectiveUpdateWrapper = new UpdateWrapper<>();
-                    objectiveUpdateWrapper.lambda().set(MarkStudent::getObjectiveScore, markStudent.getObjectiveScore())
-                            .set(MarkStudent::getObjectiveScoreList, markStudent.getObjectiveScoreList())
-                            .eq(MarkStudent::getId, markStudent.getId());
-                    markStudentService.update(objectiveUpdateWrapper);
-
                 }
             }
 

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

@@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.qmth.teachcloud.common.entity.MarkQuestion;
 import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
+import com.qmth.teachcloud.common.enums.QuestionType;
 import com.qmth.teachcloud.common.enums.UploadFileEnum;
 import com.qmth.teachcloud.common.service.TeachcloudCommonService;
 import com.qmth.teachcloud.common.util.FileStoreUtil;
@@ -110,7 +111,7 @@ public class MarkQuestionServiceImpl extends ServiceImpl<MarkQuestionMapper, Mar
                         if (question.getTotalScore() <= 0) {
                             throw ExceptionResultEnum.ERROR.exception("小题满分必须大于0");
                         }
-                        if (question.getIntervalScore() <= 0) {
+                        if (!QuestionType.findByValue(question.getQuestionType()).getObjective() && question.getIntervalScore() <= 0) {
                             throw ExceptionResultEnum.ERROR.exception("间隔分必须大于0");
                         }
                         markQuestion.setTotalScore(question.getTotalScore());

+ 85 - 10
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkServiceImpl.java

@@ -88,6 +88,21 @@ public class MarkServiceImpl implements MarkService {
     @Resource
     TeachcloudCommonService teachcloudCommonService;
 
+    /**
+     * 释放某个评卷员已完成的评卷任务
+     *
+     * @param submitResult  评卷结果
+     * @param markUserGroup 评卷员
+     */
+    @Override
+    public void releaseTask(SubmitResult submitResult, MarkUserGroup markUserGroup) {
+        if (submitResult.getMarkLibrary() != null) {
+            TaskLock taskLock = TaskLockUtil.getFormalTask(getGroupKey(markUserGroup));
+            taskLock.remove(submitResult.getMarkLibrary().getStudentId(), submitResult.getMarkLibrary().getTaskNumber(), markUserGroup.getId());
+            taskLock.refresh(markUserGroup.getId());
+        }
+    }
+
     /**
      * 某个评卷分组已申请的评卷任务数量
      *
@@ -412,9 +427,12 @@ public class MarkServiceImpl implements MarkService {
                 return;
             }
             int count = 0;
-            List<MarkStudent> studentList = markStudentService.listUnMarkTaskStudent(group.getExamId(),
-                    group.getPaperNumber(), group.getNumber(), pageSize);
+            List<MarkStudent> studentList = markStudentService.listUnMarkTaskStudent(group.getExamId(), group.getPaperNumber(), group.getNumber(), pageSize);
             while (CollectionUtils.isNotEmpty(studentList)) {
+                // 已生成的双评任务总数的第一组任务数
+                int doubleMarkTaskCount1 = markTaskService.countByExamIdAndPaperNumberAndGroupNumberAndTaskNumber(group.getExamId(), group.getPaperNumber(), group.getNumber(), 1);
+                // 已生成的双评任务总数的第二组任务数
+                int doubleMarkTaskCount2 = markTaskService.countByExamIdAndPaperNumberAndGroupNumberAndTaskNumber(group.getExamId(), group.getPaperNumber(), group.getNumber(), 2);
                 List<MarkTask> taskList = new ArrayList<>();
                 int doubleCount = 0;
                 int studentCount = studentList.size();
@@ -439,11 +457,11 @@ public class MarkServiceImpl implements MarkService {
                             needDouble = true;
                         } else {
                             double libraryCount = taskList.size();
-                            int expectCount = (int) (studentCount * group.getDoubleRate() / 100);
+                            int expectCount = (int) ((doubleMarkTaskCount1 + studentCount) * group.getDoubleRate() / 100);
                             // 随机数判断加入当前已经生成双评任务的比例加权
                             // 实际双评任务数小于理论生成数 &&(剩余未生成双评的考生数量小于剩余应生成的数量||随机比例)
-                            needDouble = doubleCount < expectCount
-                                    && ((studentCount - libraryCount + doubleCount) <= (expectCount - doubleCount)
+                            needDouble = (doubleMarkTaskCount2 + doubleCount) < expectCount
+                                    && ((studentCount - libraryCount + doubleCount) <= (expectCount - doubleMarkTaskCount2 - doubleCount)
                                     || Math.random() < group.getDoubleRate() / 100 + 0.1);
                         }
                         if (needDouble) {
@@ -477,8 +495,7 @@ public class MarkServiceImpl implements MarkService {
                         this.updateMarkedCount(group.getExamId(), group.getPaperNumber(), group.getNumber());
                     }
                 }
-                studentList = markStudentService.listUnMarkTaskStudent(group.getExamId(), group.getPaperNumber(),
-                        group.getNumber(), pageSize);
+                studentList = markStudentService.listUnMarkTaskStudent(group.getExamId(), group.getPaperNumber(), group.getNumber(), pageSize);
             }
             if (count != 0) {
                 log.info("finish create " + count + " markTask for examId=" + group.getExamId() + ", paperNumber="
@@ -707,7 +724,7 @@ public class MarkServiceImpl implements MarkService {
 
         MarkSettingDto dto = new MarkSettingDto();
         dto.setExamType(ExamType.SCAN_IMAGE);
-        dto.setMode(markUserGroup.getMode() != null ? markUserGroup.getMode() : MarkMode.UNLIMITED.equals(markPaper.getMarkMode()) ? MarkMode.TRACK : markPaper.getMarkMode());
+        dto.setMode(markUserGroup != null && markUserGroup.getMode() != null ? markUserGroup.getMode() : MarkMode.UNLIMITED.equals(markPaper.getMarkMode()) ? MarkMode.TRACK : markPaper.getMarkMode());
         dto.setForceMode(markPaper.getForceMode());
         dto.setSheetView(markPaper.getSheetView());
         dto.setSheetConfig(markPaper.getSheetConfig());
@@ -723,7 +740,7 @@ public class MarkServiceImpl implements MarkService {
         dto.setStatusValue(markPaper.getStatus());
         dto.setProblemTypes(MarkProblemType.listTypes());
         dto.setGroupNumber(groupNumber);
-        dto.setTopCount(markUserGroup.getTopCount());
+        dto.setTopCount(markUserGroup != null && markUserGroup.getTopCount() != null ? markUserGroup.getTopCount() : 0);
         dto.setSplitConfig(new Double[0]);
         dto.setPrefetchCount(3);
         dto.setStartTime(markPaper.getMarkStartTime());
@@ -731,6 +748,7 @@ public class MarkServiceImpl implements MarkService {
         dto.setSelective(false);
         dto.setAutoScroll(markPaper.getAutoScroll());
         dto.setEnableSplit(false);
+        dto.setShowObjectScore(markPaper.getShowObjectScore());
         return dto;
     }
 
@@ -954,7 +972,7 @@ public class MarkServiceImpl implements MarkService {
         }
         MarkUserGroup markUserGroup = markUserGroupService.getByExamIdAndPaperNumberAndGroupNumberAndUserId(examId, paperNumber, groupNumber, userId);
         Task task = null;
-        List<MarkTask> list = new ArrayList<MarkTask>();
+        List<MarkTask> list;
         int pageNumber = 1;
         while (task == null) {
             if (markPaper.getOpenMarkClass()) {
@@ -1014,6 +1032,36 @@ public class MarkServiceImpl implements MarkService {
         markQuestionService.deleteByExamIdAndPaperNumber(examId, paperNumber);
     }
 
+    @Override
+    public void calcObjectiveScore(MarkPaper markPaper) {
+        int pageNumber = 1;
+        int pageSize = 1000;
+        IPage<MarkStudent> iPage = markStudentService.pageByExamAndPaperNumber(markPaper.getExamId(), markPaper.getPaperNumber(), pageNumber, pageSize);
+        while (CollectionUtils.isNotEmpty(iPage.getRecords())) {
+            for (MarkStudent student : iPage.getRecords()) {
+                calculate(student);
+            }
+            pageNumber++;
+            iPage = markStudentService.pageByExamAndPaperNumber(markPaper.getExamId(), markPaper.getPaperNumber(), pageNumber, pageSize);
+        }
+    }
+
+    private void calculate(MarkStudent student) {
+        // 未上传、缺考、违纪的考生不统分
+        if (!student.getUpload() || student.getAbsent() || student.getBreach()) {
+            return;
+        }
+        try {
+            // 更新客观题得分
+            markStudentService.calculateObjectiveScore(student);
+            // 增加主观题总分统计
+            // markService.scoreCalculate(student,
+            // findMarkGroup(student.getSubjectCode()));
+        } catch (Exception e) {
+            log.error("calculate error for studentId=" + student.getId(), e);
+        }
+    }
+
     @Override
     public SubmitResult saveTask(Long examId, String paperNumber, Integer groupNumber, Long userId, MarkResult result) {
         MarkUserGroup markUserGroup = markUserGroupService.getByExamIdAndPaperNumberAndGroupNumberAndUserId(examId, paperNumber, groupNumber, userId);
@@ -1025,6 +1073,33 @@ public class MarkServiceImpl implements MarkService {
         if (group == null) {
             throw ExceptionResultEnum.ERROR.exception("评卷分组不存在");
         }
+        SubmitResult sr = null;
+        try {
+            lockService.watch(LockType.EXAM_SUBJECT, markUserGroup.getExamId(), markUserGroup.getPaperNumber());
+            lockService.watch(LockType.GROUP, markUserGroup.getExamId(), markUserGroup.getPaperNumber(), markUserGroup.getGroupNumber());
+            lockService.watch(LockType.MARK_USER_GROUP, markUserGroup.getId());
+            lockService.waitlock(LockType.STUDENT, result.getStudentId());
+            sr = submitResult(markUserGroup, group, userId, result);
+            if (sr.isSuccess()) {
+                releaseTask(sr, markUserGroup);
+            }
+        } catch (Exception e) {
+            log.error("save task error", e);
+        } finally {
+            lockService.unlock(LockType.STUDENT, result.getStudentId());
+            lockService.unwatch(LockType.MARK_USER_GROUP, markUserGroup.getId());
+            lockService.unwatch(LockType.GROUP, markUserGroup.getExamId(), markUserGroup.getPaperNumber(), markUserGroup.getGroupNumber());
+            lockService.unwatch(LockType.EXAM_SUBJECT, markUserGroup.getExamId(), markUserGroup.getPaperNumber());
+        }
+
+        if (sr == null || !sr.isSuccess()) {
+            throw ExceptionResultEnum.ERROR.exception("评卷任务提交失败,请刷新页面");
+        }
+        return sr;
+    }
+
+    private SubmitResult submitResult(MarkUserGroup markUserGroup, MarkGroup group, Long userId, MarkResult result) {
+
         MarkTask task = markTaskService.getById(result.getTaskId());
         if (task != null && task.getExamId().equals(group.getExamId())
                 && task.getPaperNumber().equals(group.getPaperNumber())

+ 47 - 6
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkStudentServiceImpl.java

@@ -109,6 +109,8 @@ public class MarkStudentServiceImpl extends ServiceImpl<MarkStudentMapper, MarkS
 
     @Autowired
     private MarkSubjectiveScoreService markSubjectiveScoreService;
+    @Resource
+    private MarkSyncService markSyncService;
 
     @Override
     public List<String> listClassByExamIdAndCourseCode(Long examId, String paperNumber) {
@@ -164,7 +166,7 @@ public class MarkStudentServiceImpl extends ServiceImpl<MarkStudentMapper, MarkS
     public IPage<StudentScoreDetailDto> pageStudentScore(Long examId, String paperNumber, String college,
                                                          String className, String teacher, Integer filter, Boolean absent, Boolean breach, Double startScore,
                                                          Double endScore, Double subScore, Integer objectiveScoreRateLt, String studentName, String studentCode,
-                                                         Integer pageNumber, Integer pageSize) {
+                                                         String orderType, String orderField, Integer pageNumber, Integer pageSize) {
         if (startScore != null && endScore == null) {
             throw ExceptionResultEnum.ERROR.exception("请输入结束分数值");
         }
@@ -175,7 +177,7 @@ public class MarkStudentServiceImpl extends ServiceImpl<MarkStudentMapper, MarkS
                 .format(markPaper.getObjectiveScore() * objectiveScoreRateLt / 100));
         IPage<StudentScoreDetailDto> studentScoreDetailDtoIPage = this.baseMapper.pageStudentScore(page, examId,
                 paperNumber, college, className, teacher, filter, absent, breach, startScore, endScore, subScore,
-                objectiveScoreLt, studentName, studentCode);
+                objectiveScoreLt, studentName, studentCode, orderType, orderField);
         for (StudentScoreDetailDto scoreDetailDto : studentScoreDetailDtoIPage.getRecords()) {
             // 原图
             scoreDetailDto.setSheetUrls(buildSheetUrls(scoreDetailDto.getStudentId()));
@@ -432,8 +434,6 @@ public class MarkStudentServiceImpl extends ServiceImpl<MarkStudentMapper, MarkS
                 .set(MarkStudent::getBatchCode, student.getBatchCode())
                 .set(MarkStudent::getAbsent, student.getAbsent())
                 .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);
@@ -496,6 +496,7 @@ public class MarkStudentServiceImpl extends ServiceImpl<MarkStudentMapper, MarkS
                 student.getExamId(), student.getPaperNumber(), null, true), null);
         student.setObjectiveScore(info.getObjectiveScore());
         student.setScoreList(info.getScoreList(), true);
+        this.updateObjectiveScoreAndScoreList(student);
     }
 
     @Override
@@ -747,8 +748,8 @@ public class MarkStudentServiceImpl extends ServiceImpl<MarkStudentMapper, MarkS
         }
         MarkPaper markPaper = markPaperService.getByExamIdAndPaperNumber(markStudent.getExamId(), markStudent.getPaperNumber());
         // 评卷是否结束
-        if (markPaper == null || !MarkPaperStatus.FINISH.equals(markPaper.getStatus())) {
-            throw ExceptionResultEnum.ERROR.exception("科目结束评卷,无法打分");
+        if (markPaper == null || MarkPaperStatus.FINISH.equals(markPaper.getStatus())) {
+            throw ExceptionResultEnum.ERROR.exception("科目结束评卷,无法打分");
         }
         try {
             lockService.watch(LockType.EXAM_SUBJECT, markStudent.getExamId(), markStudent.getPaperNumber());
@@ -953,6 +954,46 @@ public class MarkStudentServiceImpl extends ServiceImpl<MarkStudentMapper, MarkS
         this.remove(updateWrapper);
     }
 
+    @Override
+    public boolean calcObjectiveScore(Long examId, String paperNumber) {
+        MarkPaper markPaper = markPaperService.getByExamIdAndPaperNumber(examId, paperNumber);
+        if (markPaper != null) {
+            if (lockService.trylock(LockType.SCORE_CALCULATE, markPaper.getId())) {
+                markSyncService.calcObjectiveScore(markPaper);
+                return true;
+            } else {
+                throw ExceptionResultEnum.ERROR.exception("评卷员正在重置");
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public IPage<MarkStudent> pageByExamAndPaperNumber(Long examId, String paperNumber, int pageNumber, int pageSize) {
+        QueryWrapper<MarkStudent> queryWrapper = new QueryWrapper<>();
+        queryWrapper.lambda().eq(MarkStudent::getExamId, examId)
+                .eq(MarkStudent::getPaperNumber, paperNumber)
+                .orderByAsc(MarkStudent::getId);
+        return this.page(new Page<>(pageNumber, pageSize), queryWrapper);
+    }
+
+    @Override
+    public void updateObjectiveScoreAndScoreList(MarkStudent markStudent) {
+        UpdateWrapper<MarkStudent> objectiveUpdateWrapper = new UpdateWrapper<>();
+        objectiveUpdateWrapper.lambda().set(MarkStudent::getObjectiveScore, markStudent.getObjectiveScore())
+                .set(MarkStudent::getObjectiveScoreList, markStudent.getObjectiveScoreList())
+                .eq(MarkStudent::getId, markStudent.getId());
+        this.update(objectiveUpdateWrapper);
+    }
+
+    @Override
+    public boolean updateAssignConfirm(Long studentId, boolean assignConfirm) {
+        UpdateWrapper<MarkStudent> updateWrapper = new UpdateWrapper<>();
+        updateWrapper.lambda().set(MarkStudent::getAssignConfirmed, assignConfirm)
+                .eq(MarkStudent::getId, studentId);
+        return this.update(updateWrapper);
+    }
+
     private void fillObjective(ScoreReportVo ret, Long examId, String paperNumber) {
         List<MarkQuestion> qs = markQuestionService.listQuestionByExamIdAndPaperNumber(examId, paperNumber);
         List<MarkStudent> students = listByExamIdAndPaperNumberAndAbsent(examId, paperNumber, false);

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

@@ -1,6 +1,7 @@
 package com.qmth.teachcloud.mark.service.impl;
 
 import com.qmth.teachcloud.mark.entity.MarkGroup;
+import com.qmth.teachcloud.mark.entity.MarkPaper;
 import com.qmth.teachcloud.mark.entity.MarkUserGroup;
 import com.qmth.teachcloud.mark.enums.LockType;
 import com.qmth.teachcloud.mark.lock.LockService;
@@ -79,4 +80,18 @@ public class MarkSyncServiceImpl implements MarkSyncService {
             lockService.unlock(LockType.GROUP_DELETE, markGroup.getExamId(), markGroup.getPaperNumber(), markGroup.getNumber());
         }
     }
+
+    @Async
+    @Override
+    public void calcObjectiveScore(MarkPaper markPaper) {
+        try {
+            if (markPaper != null) {
+                markService.calcObjectiveScore(markPaper);
+            }
+        } catch (Exception e) {
+            log.error("reset marker error", e);
+        } finally {
+            lockService.unlock(LockType.SCORE_CALCULATE, markPaper.getId());
+        }
+    }
 }

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

@@ -320,4 +320,14 @@ public class MarkTaskServiceImpl extends ServiceImpl<MarkTaskMapper, MarkTask> i
                 .set(MarkTask::getMarkerSpent, spent);
         return this.update(updateWrapper);
     }
+
+    @Override
+    public int countByExamIdAndPaperNumberAndGroupNumberAndTaskNumber(Long examId, String paperNumber, Integer groupNumber, int taskNumber) {
+        QueryWrapper<MarkTask> queryWrapper = new QueryWrapper<>();
+        queryWrapper.lambda().eq(MarkTask::getExamId, examId)
+                .eq(MarkTask::getPaperNumber, paperNumber)
+                .eq(MarkTask::getGroupNumber, groupNumber)
+                .eq(MarkTask::getTaskNumber, taskNumber);
+        return this.count(queryWrapper);
+    }
 }

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

@@ -5,6 +5,7 @@ import com.qmth.teachcloud.mark.dto.mark.ScoreItem;
 import com.qmth.teachcloud.common.entity.MarkQuestion;
 import com.qmth.teachcloud.mark.entity.MarkStudent;
 import com.qmth.teachcloud.common.enums.ObjectivePolicy;
+import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -46,6 +47,9 @@ public class ScoreCalculateUtil {
         int index = -1;
         int lastMainNumber = 0;
         for (MarkQuestion question : questionList) {
+            if(StringUtils.isBlank(question.getAnswer())){
+                continue;
+            }
             // log.debug("find objective block for " + block.getTitle() +
             // ", question start=" + start);
             if (question.getMainNumber() != lastMainNumber) {

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

@@ -129,6 +129,21 @@
             <if test="studentCode != null and studentCode != ''">
                 AND ms.student_code = #{studentCode}
             </if>
+            <if test="orderType != null and orderType != '' and orderField != null and orderField != ''">
+                <choose>
+                    <when test="orderField == 'totalScore'">
+                        <if test="orderType == 'ASC'">
+                            order by (ifnull(ms.objective_score, 0) +  ifnull(ms.subjective_score, 0)) ASC
+                        </if>
+                        <if test="orderType == 'DESC'">
+                            order by (ifnull(ms.objective_score, 0) +  ifnull(ms.subjective_score, 0)) DESC
+                        </if>
+                    </when>
+                    <otherwise>
+                        order by #{orderField} #{orderType}
+                    </otherwise>
+                </choose>
+            </if>
     </select>
     <select id="listAbsentOrBreachMarkTaskStudent" resultMap="BaseResultMap">
         SELECT

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

@@ -156,7 +156,6 @@
 			mark_task t
 			WHERE
 			t.student_id = mt.student_id
-			AND t.id = mt.id
             AND t.exam_id = mt.exam_id
             AND t.paper_number = mt.paper_number
             AND t.group_number = mt.group_number