Просмотр исходного кода

3.4.1 评卷管理-任务管理、打回历史

xiaofei 10 месяцев назад
Родитель
Сommit
019b325d5d
26 измененных файлов с 980 добавлено и 26 удалено
  1. 11 0
      distributed-print-business/src/main/resources/db/log/xf.sql
  2. 57 0
      distributed-print/src/main/java/com/qmth/distributed/print/api/mark/MarkRejectController.java
  3. 73 0
      distributed-print/src/main/java/com/qmth/distributed/print/api/mark/MarkTaskController.java
  4. 88 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/dto/mark/manage/MarkRejectHistoryDto.java
  5. 97 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/dto/mark/manage/MarkTaskDto.java
  6. 255 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/entity/MarkRejectHistory.java
  7. 11 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/entity/MarkSubjectiveScore.java
  8. 25 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/entity/MarkTask.java
  9. 12 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/entity/MarkUserGroup.java
  10. 21 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/mapper/MarkRejectHistoryMapper.java
  11. 3 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/mapper/MarkTaskMapper.java
  12. 2 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/mapper/MarkUserGroupMapper.java
  13. 19 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/MarkRejectHistoryService.java
  14. 4 3
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/MarkService.java
  15. 2 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/MarkSubjectiveScoreService.java
  16. 6 1
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/MarkTaskService.java
  17. 2 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/MarkUserGroupService.java
  18. 1 1
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkProblemHistoryServiceImpl.java
  19. 38 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkRejectHistoryServiceImpl.java
  20. 31 2
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkServiceImpl.java
  21. 25 15
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkSubjectiveScoreServiceImpl.java
  22. 46 4
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkTaskServiceImpl.java
  23. 5 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkUserGroupServiceImpl.java
  24. 77 0
      teachcloud-mark/src/main/resources/mapper/MarkRejectHistoryMapper.xml
  25. 58 0
      teachcloud-mark/src/main/resources/mapper/MarkTaskMapper.xml
  26. 11 0
      teachcloud-mark/src/main/resources/mapper/MarkUserGroupMapper.xml

+ 11 - 0
distributed-print-business/src/main/resources/db/log/xf.sql

@@ -15,3 +15,14 @@ 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 ('1011', '主观题检查-确认任务', '/api/admin/mark/inspected/subjective/confirmTask', 'URL', '946', '14', 'AUTH', '1', '1', '1');
 UPDATE `sys_privilege` SET `related` = '956,957,958,1011' WHERE (`id` = '1176');
 UPDATE `sys_privilege` SET `related` = '888,894,956,957,958,1011' WHERE (`id` = '1179');
+
+ALTER TABLE `mark_task` ADD COLUMN `reject_reason` VARCHAR(128) NULL COMMENT '打回原因' AFTER `header_score_list`;
+ALTER TABLE `mark_user_group` ADD COLUMN `reject_count` INT NULL COMMENT '打回次数' AFTER `min_score`;
+ALTER TABLE `mark_subjective_score` ADD COLUMN `rejected` TINYINT(1) NULL DEFAULT 0 COMMENT '是否打回' AFTER `uncalculate`;
+ALTER TABLE `mark_task` ADD COLUMN `basic_student_id` BIGINT(20) NULL COMMENT '考生管理ID' AFTER `student_id`;
+
+INSERT INTO `sys_privilege` (`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `related`, `enable`, `default_auth`, `front_display`) VALUES ('1184', '打回', 'MarkTaskReject', 'LINK', '917', '10', 'AUTH', '1185', '1', '0', '1');
+INSERT INTO `sys_privilege` (`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `enable`, `default_auth`, `front_display`) VALUES ('1183', '任务管理列表查询', '/api/admin/mark/task/list', 'URL', '917', '24', 'AUTH', '1', '1', '1');
+INSERT INTO `sys_privilege` (`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `enable`, `default_auth`, `front_display`) VALUES ('1185', '打回', '/api/admin/mark/task/reject', 'URL', '917', '25', 'AUTH', '1', '1', '1');
+INSERT INTO `sys_privilege` (`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `enable`, `default_auth`, `front_display`) VALUES ('1186', '打回历史列表查询', '/api/admin/mark/reject/list', 'URL', '917', '26', 'AUTH', '1', '1', '1');
+UPDATE `sys_privilege` SET `related` = '928,929,932,933,934,935,936,937,938,939,940,941,942,943,964,965,966,967,968,1008,1183,1186' WHERE (`id` = '944');

+ 57 - 0
distributed-print/src/main/java/com/qmth/distributed/print/api/mark/MarkRejectController.java

@@ -0,0 +1,57 @@
+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.contant.SystemConstant;
+import com.qmth.teachcloud.common.util.Result;
+import com.qmth.teachcloud.common.util.ResultUtil;
+import com.qmth.teachcloud.mark.dto.mark.manage.*;
+import com.qmth.teachcloud.mark.params.MarkResult;
+import com.qmth.teachcloud.mark.service.MarkArbitrateHistoryService;
+import com.qmth.teachcloud.mark.service.MarkRejectHistoryService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import java.util.List;
+
+/**
+ * <p>
+ * 打回记录表 前端控制器
+ * </p>
+ *
+ * @author xf
+ * @since 2024-08-22
+ */
+@Api(tags = "评卷-打回历史")
+@RestController
+@RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + SystemConstant.PREFIX_URL_MARK + "/reject")
+public class MarkRejectController {
+
+    @Resource
+    private MarkRejectHistoryService markRejectHistoryService;
+
+    /**
+     * 仲裁列表查询
+     */
+    @ApiOperation(value = "打回历史列表")
+    @RequestMapping(value = "/list", method = RequestMethod.POST)
+    public Result list(@ApiParam(value = "考试ID", required = true) @RequestParam Long examId,
+                       @ApiParam(value = "试卷编号", required = true) @RequestParam String paperNumber,
+                       @ApiParam(value = "分组号") @RequestParam(required = false) Integer groupNumber,
+                       @ApiParam(value = "教学班") @RequestParam(required = false) String teachClassName,
+                       @ApiParam(value = "评卷员") @RequestParam(required = false) String loginName,
+                       @ApiParam(value = "学号") @RequestParam(required = false) String studentCode,
+                       @ApiParam(value = "密号") @RequestParam(required = false) String secretNumber,
+                       @RequestParam @Min(SystemConstant.PAGE_NUMBER_MIN) Integer pageNumber,
+                       @RequestParam @Min(SystemConstant.PAGE_SIZE_MIN) @Max(SystemConstant.PAGE_SIZE_MAX) Integer pageSize) {
+        IPage<MarkRejectHistoryDto> rejectHistoryDtoIPage = markRejectHistoryService.pageRejectHistory(examId, paperNumber, groupNumber,loginName, studentCode, secretNumber, teachClassName, pageNumber, pageSize);
+        return ResultUtil.ok(rejectHistoryDtoIPage);
+    }
+
+}

+ 73 - 0
distributed-print/src/main/java/com/qmth/distributed/print/api/mark/MarkTaskController.java

@@ -0,0 +1,73 @@
+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.contant.SystemConstant;
+import com.qmth.teachcloud.common.util.Result;
+import com.qmth.teachcloud.common.util.ResultUtil;
+import com.qmth.teachcloud.mark.dto.mark.manage.MarkRejectHistoryDto;
+import com.qmth.teachcloud.mark.dto.mark.manage.MarkTaskDto;
+import com.qmth.teachcloud.mark.enums.MarkTaskStatus;
+import com.qmth.teachcloud.mark.service.MarkRejectHistoryService;
+import com.qmth.teachcloud.mark.service.MarkTaskService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+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;
+
+/**
+ * <p>
+ * 任务管理 前端控制器
+ * </p>
+ *
+ * @author xf
+ * @since 2024-08-22
+ */
+@Api(tags = "评卷-任务管理")
+@RestController
+@RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + SystemConstant.PREFIX_URL_MARK + "/task")
+public class MarkTaskController {
+
+    @Resource
+    private MarkTaskService markTaskService;
+
+    /**
+     * 任务列表查询
+     */
+    @ApiOperation(value = "任务列表")
+    @RequestMapping(value = "/list", method = RequestMethod.POST)
+    public Result list(@ApiParam(value = "考试ID", required = true) @RequestParam Long examId,
+                       @ApiParam(value = "试卷编号", required = true) @RequestParam String paperNumber,
+                       @ApiParam(value = "分组号") @RequestParam(required = false) Integer groupNumber,
+                       @ApiParam(value = "评卷员") @RequestParam(required = false) String loginName,
+                       @ApiParam(value = "状态") @RequestParam(required = false) MarkTaskStatus status,
+                       @ApiParam(value = "学号") @RequestParam(required = false) String studentCode,
+                       @ApiParam(value = "密号") @RequestParam(required = false) String secretNumber,
+                       @ApiParam(value = "教学班") @RequestParam(required = false) String teachClassName,
+                       @ApiParam(value = "小题得分") @RequestParam(required = false) Double subScore,
+                       @RequestParam @Min(SystemConstant.PAGE_NUMBER_MIN) Integer pageNumber,
+                       @RequestParam @Min(SystemConstant.PAGE_SIZE_MIN) @Max(SystemConstant.PAGE_SIZE_MAX) Integer pageSize) {
+        IPage<MarkTaskDto> markTaskDtoIPage = markTaskService.pageMarkTask(examId, paperNumber, groupNumber, loginName, status, studentCode, secretNumber, teachClassName, subScore, pageNumber, pageSize);
+        return ResultUtil.ok(markTaskDtoIPage);
+    }
+
+    /**
+     * 打回
+     */
+    @ApiOperation(value = "打回")
+    @RequestMapping(value = "/reject", method = RequestMethod.POST)
+    public Result reject(@ApiParam(value = "任务ID", required = true) @RequestParam Long id,
+                         @ApiParam(value = "试卷编号", required = true) @RequestParam String rejectReason) {
+        markTaskService.rejectMarkTask(id, rejectReason);
+        return ResultUtil.ok(true);
+    }
+
+}

+ 88 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/dto/mark/manage/MarkRejectHistoryDto.java

@@ -0,0 +1,88 @@
+package com.qmth.teachcloud.mark.dto.mark.manage;
+
+import com.qmth.teachcloud.mark.entity.MarkRejectHistory;
+
+public class MarkRejectHistoryDto extends MarkRejectHistory {
+
+    private String studentName;
+    private String className;
+    private String teachClassName;
+    private String loginName;
+    private String userName;
+    private String rejectLoginName;
+    private String rejectUserName;
+    private String orgName;
+    private String groupQuestions;
+
+    public String getStudentName() {
+        return studentName;
+    }
+
+    public void setStudentName(String studentName) {
+        this.studentName = studentName;
+    }
+
+    public String getClassName() {
+        return className;
+    }
+
+    public void setClassName(String className) {
+        this.className = className;
+    }
+
+    public String getTeachClassName() {
+        return teachClassName;
+    }
+
+    public void setTeachClassName(String teachClassName) {
+        this.teachClassName = teachClassName;
+    }
+
+    public String getLoginName() {
+        return loginName;
+    }
+
+    public void setLoginName(String loginName) {
+        this.loginName = loginName;
+    }
+
+    public String getUserName() {
+        return userName;
+    }
+
+    public void setUserName(String userName) {
+        this.userName = userName;
+    }
+
+    public String getOrgName() {
+        return orgName;
+    }
+
+    public void setOrgName(String orgName) {
+        this.orgName = orgName;
+    }
+
+    public String getGroupQuestions() {
+        return groupQuestions;
+    }
+
+    public void setGroupQuestions(String groupQuestions) {
+        this.groupQuestions = groupQuestions;
+    }
+
+    public String getRejectLoginName() {
+        return rejectLoginName;
+    }
+
+    public void setRejectLoginName(String rejectLoginName) {
+        this.rejectLoginName = rejectLoginName;
+    }
+
+    public String getRejectUserName() {
+        return rejectUserName;
+    }
+
+    public void setRejectUserName(String rejectUserName) {
+        this.rejectUserName = rejectUserName;
+    }
+}

+ 97 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/dto/mark/manage/MarkTaskDto.java

@@ -0,0 +1,97 @@
+package com.qmth.teachcloud.mark.dto.mark.manage;
+
+import com.qmth.teachcloud.mark.entity.MarkTask;
+
+public class MarkTaskDto extends MarkTask {
+
+    private String studentName;
+    private String className;
+    private String teachClassName;
+    private String loginName;
+    private String userName;
+    private String rejectLoginName;
+    private String rejectUserName;
+    private String orgName;
+    private String statusDisplay;
+    private String groupQuestions;
+
+    public String getStudentName() {
+        return studentName;
+    }
+
+    public void setStudentName(String studentName) {
+        this.studentName = studentName;
+    }
+
+    public String getClassName() {
+        return className;
+    }
+
+    public void setClassName(String className) {
+        this.className = className;
+    }
+
+    public String getTeachClassName() {
+        return teachClassName;
+    }
+
+    public void setTeachClassName(String teachClassName) {
+        this.teachClassName = teachClassName;
+    }
+
+    public String getLoginName() {
+        return loginName;
+    }
+
+    public void setLoginName(String loginName) {
+        this.loginName = loginName;
+    }
+
+    public String getUserName() {
+        return userName;
+    }
+
+    public void setUserName(String userName) {
+        this.userName = userName;
+    }
+
+    public String getRejectLoginName() {
+        return rejectLoginName;
+    }
+
+    public void setRejectLoginName(String rejectLoginName) {
+        this.rejectLoginName = rejectLoginName;
+    }
+
+    public String getRejectUserName() {
+        return rejectUserName;
+    }
+
+    public void setRejectUserName(String rejectUserName) {
+        this.rejectUserName = rejectUserName;
+    }
+
+    public String getOrgName() {
+        return orgName;
+    }
+
+    public void setOrgName(String orgName) {
+        this.orgName = orgName;
+    }
+
+    public String getStatusDisplay() {
+        return statusDisplay;
+    }
+
+    public void setStatusDisplay(String statusDisplay) {
+        this.statusDisplay = statusDisplay;
+    }
+
+    public String getGroupQuestions() {
+        return groupQuestions;
+    }
+
+    public void setGroupQuestions(String groupQuestions) {
+        this.groupQuestions = groupQuestions;
+    }
+}

+ 255 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/entity/MarkRejectHistory.java

@@ -0,0 +1,255 @@
+package com.qmth.teachcloud.mark.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import java.io.Serializable;
+import java.util.Date;
+
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.qmth.teachcloud.common.contant.SystemConstant;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author xf
+ * @since 2024-08-22
+ */
+@TableName("mark_reject_history")
+@ApiModel(value="MarkRejectHistory对象", description="")
+public class MarkRejectHistory implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @JsonSerialize(using = ToStringSerializer.class)
+    @TableId(value = "id", type = IdType.INPUT)
+    private Long id;
+
+    @JsonSerialize(using = ToStringSerializer.class)
+    @ApiModelProperty(value = "考试ID")
+    private Long examId;
+
+    @ApiModelProperty(value = "试卷编号")
+    private String paperNumber;
+
+    @ApiModelProperty(value = "分组号")
+    private Integer groupNumber;
+
+    @JsonSerialize(using = ToStringSerializer.class)
+    @ApiModelProperty(value = "任务ID")
+    private Long taskId;
+
+    @JsonSerialize(using = ToStringSerializer.class)
+    @ApiModelProperty(value = "考生ID")
+    private Long studentId;
+
+    @JsonSerialize(using = ToStringSerializer.class)
+    @ApiModelProperty(value = "考生管理ID")
+    private Long basicStudentId;
+
+    @ApiModelProperty(value = "考号")
+    private String studentCode;
+
+    @ApiModelProperty(value = "任务密号")
+    private String secretNumber;
+
+    @JsonSerialize(using = ToStringSerializer.class)
+    @ApiModelProperty(value = "评卷用户ID")
+    private Long userId;
+
+    @ApiModelProperty(value = "打回原因")
+    private String rejectReason;
+
+    @ApiModelProperty(value = "打回后分数列表")
+    private String rejectScoreList;
+
+    @ApiModelProperty(value = "打回前分数列表")
+    private String markerScoreList;
+
+    @ApiModelProperty(value = "总分")
+    private Double markerScore;
+
+    @ApiModelProperty(value = "评卷时间")
+    private Long markerTime;
+
+    @JsonSerialize(using = ToStringSerializer.class)
+    @ApiModelProperty(value = "打回用户ID")
+    private Long rejectUserId;
+
+    @ApiModelProperty(value = "打回时间")
+    private Long rejectTime;
+
+    public MarkRejectHistory() {
+    }
+
+    public MarkRejectHistory(MarkTask markTask) {
+        this.id = SystemConstant.getDbUuid();
+        this.examId = markTask.getExamId();
+        this.paperNumber = markTask.getPaperNumber();
+        this.groupNumber = markTask.getGroupNumber();
+        this.taskId = markTask.getId();
+        this.studentId = markTask.getStudentId();
+        this.studentCode = markTask.getStudentCode();
+        this.secretNumber = markTask.getSecretNumber();
+        this.userId = markTask.getUserId();
+        this.markerScoreList = markTask.getMarkerScoreList();
+        this.markerScore = markTask.getMarkerScore();
+        this.markerTime = markTask.getMarkerTime();
+        this.rejectTime = System.currentTimeMillis();
+    }
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+    public Long getExamId() {
+        return examId;
+    }
+
+    public void setExamId(Long examId) {
+        this.examId = examId;
+    }
+    public String getPaperNumber() {
+        return paperNumber;
+    }
+
+    public void setPaperNumber(String paperNumber) {
+        this.paperNumber = paperNumber;
+    }
+    public Integer getGroupNumber() {
+        return groupNumber;
+    }
+
+    public void setGroupNumber(Integer groupNumber) {
+        this.groupNumber = groupNumber;
+    }
+    public Long getTaskId() {
+        return taskId;
+    }
+
+    public void setTaskId(Long taskId) {
+        this.taskId = taskId;
+    }
+    public Long getStudentId() {
+        return studentId;
+    }
+
+    public void setStudentId(Long studentId) {
+        this.studentId = studentId;
+    }
+
+    public Long getBasicStudentId() {
+        return basicStudentId;
+    }
+
+    public void setBasicStudentId(Long basicStudentId) {
+        this.basicStudentId = basicStudentId;
+    }
+
+    public String getStudentCode() {
+        return studentCode;
+    }
+
+    public void setStudentCode(String studentCode) {
+        this.studentCode = studentCode;
+    }
+    public String getSecretNumber() {
+        return secretNumber;
+    }
+
+    public void setSecretNumber(String secretNumber) {
+        this.secretNumber = secretNumber;
+    }
+    public Long getUserId() {
+        return userId;
+    }
+
+    public void setUserId(Long userId) {
+        this.userId = userId;
+    }
+
+    public String getRejectReason() {
+        return rejectReason;
+    }
+
+    public void setRejectReason(String rejectReason) {
+        this.rejectReason = rejectReason;
+    }
+
+    public String getRejectScoreList() {
+        return rejectScoreList;
+    }
+
+    public void setRejectScoreList(String rejectScoreList) {
+        this.rejectScoreList = rejectScoreList;
+    }
+
+    public String getMarkerScoreList() {
+        return markerScoreList;
+    }
+
+    public void setMarkerScoreList(String markerScoreList) {
+        this.markerScoreList = markerScoreList;
+    }
+
+    public Double getMarkerScore() {
+        return markerScore;
+    }
+
+    public void setMarkerScore(Double markerScore) {
+        this.markerScore = markerScore;
+    }
+
+    public Long getMarkerTime() {
+        return markerTime;
+    }
+
+    public void setMarkerTime(Long markerTime) {
+        this.markerTime = markerTime;
+    }
+
+    public Long getRejectUserId() {
+        return rejectUserId;
+    }
+
+    public void setRejectUserId(Long rejectUserId) {
+        this.rejectUserId = rejectUserId;
+    }
+
+    public Long getRejectTime() {
+        return rejectTime;
+    }
+
+    public void setRejectTime(Long rejectTime) {
+        this.rejectTime = rejectTime;
+    }
+
+    @Override
+    public String toString() {
+        return "MarkRejectHistory{" +
+            "id=" + id +
+            ", examId=" + examId +
+            ", paperNumber=" + paperNumber +
+            ", groupNumber=" + groupNumber +
+            ", taskId=" + taskId +
+            ", studentId=" + studentId +
+            ", studentCode=" + studentCode +
+            ", secretNumber=" + secretNumber +
+            ", userId=" + userId +
+            ", rejectReason=" + rejectReason +
+            ", rejectScoreList=" + rejectScoreList +
+            ", markerScoreList=" + markerScoreList +
+            ", markerScore=" + markerScore +
+            ", markerTime=" + markerTime +
+            ", rejectUserId=" + rejectUserId +
+            ", rejectTime=" + rejectTime +
+        "}";
+    }
+}

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

@@ -59,6 +59,9 @@ public class MarkSubjectiveScore implements Serializable {
     @ApiModelProperty(value = "是否合分")
     private Boolean uncalculate;
 
+    @ApiModelProperty(value = "是否打回")
+    private Boolean rejected;
+
     public Long getStudentId() {
         return studentId;
     }
@@ -130,6 +133,14 @@ public class MarkSubjectiveScore implements Serializable {
         this.uncalculate = uncalculate;
     }
 
+    public Boolean getRejected() {
+        return rejected;
+    }
+
+    public void setRejected(Boolean rejected) {
+        this.rejected = rejected;
+    }
+
     @Override
     public String toString() {
         return "MarkSubjectiveScore{" +

+ 25 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/entity/MarkTask.java

@@ -54,6 +54,10 @@ public class MarkTask implements Serializable {
     @ApiModelProperty(value = "考生ID")
     private Long studentId;
 
+    @JsonSerialize(using = ToStringSerializer.class)
+    @ApiModelProperty(value = "考生管理ID")
+    private Long basicStudentId;
+
     @ApiModelProperty(value = "学号")
     private String studentCode;
 
@@ -101,6 +105,10 @@ public class MarkTask implements Serializable {
     @TableField(updateStrategy = FieldStrategy.IGNORED)
     private String headerScoreList;
 
+    @ApiModelProperty(value = "打回原因")
+    @TableField(updateStrategy = FieldStrategy.IGNORED)
+    private String rejectReason;
+
     public Long getId() {
         return id;
     }
@@ -161,6 +169,15 @@ public class MarkTask implements Serializable {
     public void setStudentId(Long studentId) {
         this.studentId = studentId;
     }
+
+    public Long getBasicStudentId() {
+        return basicStudentId;
+    }
+
+    public void setBasicStudentId(Long basicStudentId) {
+        this.basicStudentId = basicStudentId;
+    }
+
     public String getStudentCode() {
         return studentCode;
     }
@@ -253,6 +270,14 @@ public class MarkTask implements Serializable {
         this.headerScoreList = headerScoreList;
     }
 
+    public String getRejectReason() {
+        return rejectReason;
+    }
+
+    public void setRejectReason(String rejectReason) {
+        this.rejectReason = rejectReason;
+    }
+
     public List<ScoreItem> getScoreList() {
         List<ScoreItem> list = new LinkedList<ScoreItem>();
         String scoreList = null;

+ 12 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/entity/MarkUserGroup.java

@@ -78,6 +78,10 @@ public class MarkUserGroup implements Serializable {
     @TableField(updateStrategy = FieldStrategy.IGNORED)
     private Double stdevScore;
 
+    @ApiModelProperty(value = "打回次数")
+    @TableField(updateStrategy = FieldStrategy.IGNORED)
+    private Integer rejectCount;
+
     public MarkUserGroup() {
     }
 
@@ -201,6 +205,14 @@ public class MarkUserGroup implements Serializable {
         this.stdevScore = stdevScore;
     }
 
+    public Integer getRejectCount() {
+        return rejectCount;
+    }
+
+    public void setRejectCount(Integer rejectCount) {
+        this.rejectCount = rejectCount;
+    }
+
     @Override
     public String toString() {
         return "MarkUserGroup{" +

+ 21 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/mapper/MarkRejectHistoryMapper.java

@@ -0,0 +1,21 @@
+package com.qmth.teachcloud.mark.mapper;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.qmth.teachcloud.mark.dto.mark.manage.MarkRejectHistoryDto;
+import com.qmth.teachcloud.mark.entity.MarkRejectHistory;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author xf
+ * @since 2024-08-22
+ */
+public interface MarkRejectHistoryMapper extends BaseMapper<MarkRejectHistory> {
+
+    IPage<MarkRejectHistoryDto> pageRejectHistory(@Param("page") Page<MarkRejectHistoryDto> page, @Param("examId") Long examId, @Param("paperNumber") String paperNumber, @Param("groupNumber") Integer groupNumber, @Param("loginName") String loginName, @Param("studentCode") String studentCode, @Param("secretNumber") String secretNumber, @Param("teachClassName") String teachClassName);
+}

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

@@ -2,6 +2,7 @@ package com.qmth.teachcloud.mark.mapper;
 
 import java.util.List;
 
+import com.qmth.teachcloud.mark.dto.mark.manage.MarkTaskDto;
 import com.qmth.teachcloud.mark.enums.MarkTaskStatus;
 import org.apache.ibatis.annotations.Param;
 
@@ -41,4 +42,6 @@ public interface MarkTaskMapper extends BaseMapper<MarkTask> {
     List<MarkTask> listByExamIdAndPaperNumberAndGroupNumberAndUserIdAndClassName(@Param("examId") Long examId, @Param("paperNumber") String paperNumber, @Param("groupNumber") Integer groupNumber, @Param("userId") Long userId, @Param("className") String className);
 
     int countByExamIdAndPaperNumberAndGroupNumberAndUserIdAndAndClassNameStatusIn(@Param("examId") Long examId, @Param("paperNumber") String paperNumber, @Param("groupNumber") Integer groupNumber, @Param("userId") Long userId, @Param("classNames") List<String> classNames, @Param("statusList") MarkTaskStatus[] statusList);
+
+    IPage<MarkTaskDto> pageMarkTask(@Param("page") Page<Object> page, @Param("examId") Long examId, @Param("paperNumber") String paperNumber, @Param("groupNumber") Integer groupNumber, @Param("loginName") String loginName, @Param("status") MarkTaskStatus status, @Param("studentCode") String studentCode, @Param("secretNumber") String secretNumber, @Param("teachClassName") String teachClassName, @Param("subScore") Double subScore);
 }

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

@@ -32,4 +32,6 @@ public interface MarkUserGroupMapper extends BaseMapper<MarkUserGroup> {
     IPage<MarkQualityDto> pageQuality(@Param("page") Page<MarkQualityDto> page, @Param("examId") Long examId, @Param("paperNumber") String paperNumber, @Param("groupNumber") Integer groupNumber, @Param("loginName") String loginName);
 
     int countByMarkTask(@Param("userId") Long userId, @Param("status") String status);
+
+    void updateRejectCountByExamIdAndPaperNumberAndGroupNumberAndUserId(@Param("examId") Long examId, @Param("paperNumber") String paperNumber, @Param("groupNumber") Integer groupNumber, @Param("userId") Long userId);
 }

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

@@ -0,0 +1,19 @@
+package com.qmth.teachcloud.mark.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.qmth.teachcloud.mark.dto.mark.manage.MarkRejectHistoryDto;
+import com.qmth.teachcloud.mark.entity.MarkRejectHistory;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author xf
+ * @since 2024-08-22
+ */
+public interface MarkRejectHistoryService extends IService<MarkRejectHistory> {
+
+    IPage<MarkRejectHistoryDto> pageRejectHistory(Long examId, String paperNumber, Integer groupNumber, String loginName, String studentCode, String secretNumber, String teachClassName, Integer pageNumber, Integer pageSize);
+}

+ 4 - 3
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/MarkService.java

@@ -1,7 +1,5 @@
 package com.qmth.teachcloud.mark.service;
 
-import java.util.List;
-
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.qmth.teachcloud.common.entity.SysUser;
 import com.qmth.teachcloud.mark.dto.mark.manage.Task;
@@ -12,9 +10,10 @@ import com.qmth.teachcloud.mark.dto.mark.mark.SubmitResult;
 import com.qmth.teachcloud.mark.entity.*;
 import com.qmth.teachcloud.mark.params.MarkHeaderGroupResult;
 import com.qmth.teachcloud.mark.params.MarkResult;
-
 import io.lettuce.core.GeoArgs.Sort;
 
+import java.util.List;
+
 /**
  * <p>
  * 评卷相关 服务类
@@ -101,4 +100,6 @@ public interface MarkService {
     void updateMarkGroupStatus(Long examId, String paperNumber);
 
     void checkStudentSubjectiveScore(Long examId, String coursePaperId, long groupCount, long unGroupQuestionCount);
+
+    boolean rejectMarkTask(MarkTask markTask, Long userId, String reason);
 }

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

@@ -30,4 +30,6 @@ public interface MarkSubjectiveScoreService extends IMppService<MarkSubjectiveSc
 	List<QuestionVo> getSubjectiveVo(List<Long> studentIds);
 	
 	  List<MarkSubjectiveScore> listByStudentId(Long studentId);
+
+    void updateRejected(Long studentId, Integer groupNumber, boolean rejectd);
 }

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

@@ -8,6 +8,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.qmth.teachcloud.mark.dto.mark.manage.MarkManageDto;
+import com.qmth.teachcloud.mark.dto.mark.manage.MarkTaskDto;
 import com.qmth.teachcloud.mark.entity.MarkTask;
 import com.qmth.teachcloud.mark.enums.MarkTaskStatus;
 
@@ -33,7 +34,7 @@ public interface MarkTaskService extends IService<MarkTask> {
 
     List<MarkTask> listByExamIdAndPaperNumberAndGroupNumberAndUserIdAndStatusNotIn(Long examId, String paperNumber, Integer groupNumber, Long userId, List<MarkTaskStatus> statusList);
 
-    boolean resetById(Long markTaskId, Long userId, Long rejecterId, Long date, MarkTaskStatus newStatus);
+    boolean resetById(Long markTaskId, Long userId, String rejectReason, Long rejectId, Long date, MarkTaskStatus newStatus);
 
     int countByExamIdAndPaperNumberAndGroupNumberAndStatusIn(Long examId, String paperNumber, Integer groupNumber, List<MarkTaskStatus> statusList);
 
@@ -81,4 +82,8 @@ public interface MarkTaskService extends IService<MarkTask> {
     int countByStudentId(Long studentId);
 
     int countByExamIdAndPaperNumber(Long examId, String paperNumber);
+
+    IPage<MarkTaskDto> pageMarkTask(Long examId, String paperNumber, Integer groupNumber, String loginName, MarkTaskStatus status, String studentCode, String secretNumber, String teachClassName, Double subScore, Integer pageNumber, Integer pageSize);
+
+    void rejectMarkTask(Long id, String rejectReason);
 }

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

@@ -74,4 +74,6 @@ public interface MarkUserGroupService extends IService<MarkUserGroup> {
      * @return 任务数量
      */
     int countByMarkTask(Long userId, MarkPaperStatus status);
+
+    void updateRejectCountByExamIdAndPaperNumberAndGroupNumberAndUserId(Long examId, String paperNumber, Integer groupNumber, Long userId);
 }

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

@@ -106,7 +106,7 @@ public class MarkProblemHistoryServiceImpl extends ServiceImpl<MarkProblemHistor
 						markService.rejectMarkTask(markProblemHistory, markTask, sysUser.getId());
 					}
 				} catch (Exception e) {
-					log.error("back library error", e);
+					log.error("问题卷打回失败", e);
 				} finally {
 					lockService.unwatch(LockType.GROUP, markTask.getExamId(), markTask.getPaperNumber(),
 							markTask.getGroupNumber());

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

@@ -0,0 +1,38 @@
+package com.qmth.teachcloud.mark.service.impl;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.qmth.teachcloud.mark.dto.mark.manage.MarkRejectHistoryDto;
+import com.qmth.teachcloud.mark.entity.MarkRejectHistory;
+import com.qmth.teachcloud.mark.mapper.MarkRejectHistoryMapper;
+import com.qmth.teachcloud.mark.service.MarkQuestionService;
+import com.qmth.teachcloud.mark.service.MarkRejectHistoryService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+
+/**
+ * <p>
+ * 服务实现类
+ * </p>
+ *
+ * @author xf
+ * @since 2024-08-22
+ */
+@Service
+public class MarkRejectHistoryServiceImpl extends ServiceImpl<MarkRejectHistoryMapper, MarkRejectHistory> implements MarkRejectHistoryService {
+
+    @Resource
+    private MarkQuestionService markQuestionService;
+
+    @Override
+    public IPage<MarkRejectHistoryDto> pageRejectHistory(Long examId, String paperNumber, Integer groupNumber, String loginName, String studentCode, String secretNumber, String teachClassName, Integer pageNumber, Integer pageSize) {
+        IPage<MarkRejectHistoryDto> rejectHistoryDtoIPage = this.baseMapper.pageRejectHistory(new Page<>(pageNumber, pageSize), examId, paperNumber, groupNumber, loginName, studentCode, secretNumber, teachClassName);
+        for (MarkRejectHistoryDto record : rejectHistoryDtoIPage.getRecords()) {
+            // 分组题目
+            record.setGroupQuestions(markQuestionService.assembleGroupQuestionsByExamIdAndPaperNumberAndNumber(record.getExamId(), record.getPaperNumber(), record.getGroupNumber()));
+        }
+        return rejectHistoryDtoIPage;
+    }
+}

+ 31 - 2
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkServiceImpl.java

@@ -115,6 +115,8 @@ public class MarkServiceImpl implements MarkService {
     TeachcloudCommonService teachcloudCommonService;
     @Resource
     private SysUserService sysUserService;
+    @Resource
+    private MarkRejectHistoryService markRejectHistoryService;
 
     /**
      * 释放某个评卷员已完成的评卷任务
@@ -199,7 +201,7 @@ public class MarkServiceImpl implements MarkService {
                 Long studentId = markTask.getStudentId();
                 markTrackService.deleteByTaskId(markTask.getId());
                 markSpecialTagService.deleteByTaskId(markTask.getId());
-                markTaskService.resetById(markTask.getId(), null, null, null, MarkTaskStatus.WAITING);
+                markTaskService.resetById(markTask.getId(), null, null, null, null, MarkTaskStatus.WAITING);
                 lockService.waitlock(LockType.STUDENT, markTask.getStudentId());
                 updateStudentGroupStatus(studentId, examId, paperNumber, groupNumber, SubjectiveStatus.UNMARK);
                 markStudentService.updateSubjectiveStatusAndScore(studentId, SubjectiveStatus.UNMARK, null, null);
@@ -227,7 +229,7 @@ public class MarkServiceImpl implements MarkService {
             return false;
         }
         Long now = System.currentTimeMillis();
-        if (markTaskService.resetById(markTask.getId(), null, userId, now, MarkTaskStatus.WAITING)) {
+        if (markTaskService.resetById(markTask.getId(), null, null, userId, now, MarkTaskStatus.WAITING)) {
             markTrackService.deleteByTaskId(markTask.getId());
             resetStudentGroup(markTask.getStudentId(), markTask.getExamId(), markTask.getPaperNumber(),
                     markTask.getGroupNumber());
@@ -1394,4 +1396,31 @@ public class MarkServiceImpl implements MarkService {
         }
     }
 
+    @Override
+    @Transactional
+    public boolean rejectMarkTask(MarkTask markTask, Long userId, String reason) {
+        MarkPaper markPaper = markPaperService.getByExamIdAndPaperNumber(markTask.getExamId(), markTask.getPaperNumber());
+        if (MarkPaperStatus.FINISH.equals(markPaper.getStatus())) {
+            return false;
+        }
+        MarkRejectHistory history = new MarkRejectHistory(markTask);
+        MarkStudent markStudent = markStudentService.getById(markTask.getStudentId());
+        history.setBasicStudentId(markStudent.getBasicStudentId());
+        history.setRejectUserId(userId);
+        history.setRejectReason(reason);
+        Long now = System.currentTimeMillis();
+        if (markTaskService.resetById(markTask.getId(), null, reason, userId, now, MarkTaskStatus.REJECTED)) {
+            markUserGroupService.updateRejectCountByExamIdAndPaperNumberAndGroupNumberAndUserId(markTask.getExamId(), markTask.getPaperNumber(), markTask.getGroupNumber(), markTask.getUserId());
+            markRejectHistoryService.save(history);
+            markTrackService.deleteByTaskId(markTask.getId());
+            markSpecialTagService.deleteByTaskId(markTask.getId());
+            markSubjectiveScoreService.updateRejected(markTask.getStudentId(), markTask.getGroupNumber(), true);
+            resetStudentGroup(markTask.getStudentId(), markTask.getExamId(), markTask.getPaperNumber(), markTask.getGroupNumber());
+            updateMarkedCount(markTask.getExamId(), markTask.getPaperNumber(), markTask.getGroupNumber());
+            return true;
+        } else {
+            return false;
+        }
+    }
+
 }

+ 25 - 15
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkSubjectiveScoreServiceImpl.java

@@ -29,8 +29,8 @@ public class MarkSubjectiveScoreServiceImpl extends MppServiceImpl<MarkSubjectiv
     public List<MarkSubjectiveScore> listByStudentIdAndGroupNumber(Long studentId, Integer groupNumber) {
         QueryWrapper<MarkSubjectiveScore> queryWrapper = new QueryWrapper<>();
         queryWrapper.lambda().eq(MarkSubjectiveScore::getStudentId, studentId)
-        .orderByAsc(MarkSubjectiveScore::getMainNumber)
-        .orderByAsc(MarkSubjectiveScore::getSubNumber);
+                .orderByAsc(MarkSubjectiveScore::getMainNumber)
+                .orderByAsc(MarkSubjectiveScore::getSubNumber);
         if (groupNumber != null) {
             queryWrapper.lambda().eq(MarkSubjectiveScore::getGroupNumber, groupNumber);
         }
@@ -97,21 +97,31 @@ public class MarkSubjectiveScoreServiceImpl extends MppServiceImpl<MarkSubjectiv
 //        });
 //    }
 
-	@Override
-	public List<QuestionVo> getSubjectiveVo(List<Long> studentIds) {
-        if(CollectionUtils.isEmpty(studentIds)){
+    @Override
+    public List<QuestionVo> getSubjectiveVo(List<Long> studentIds) {
+        if (CollectionUtils.isEmpty(studentIds)) {
             return null;
         }
-		return this.baseMapper.getSubjectiveVo(studentIds);
-	}
+        return this.baseMapper.getSubjectiveVo(studentIds);
+    }
 
-	@Override
-	public List<MarkSubjectiveScore> listByStudentId(Long studentId) {
-		 QueryWrapper<MarkSubjectiveScore> queryWrapper = new QueryWrapper<>();
-	        queryWrapper.lambda().eq(MarkSubjectiveScore::getStudentId, studentId).orderByAsc(MarkSubjectiveScore::getMainNumber)
-            .orderByAsc(MarkSubjectiveScore::getSubNumber);;
-	        List<MarkSubjectiveScore> list = this.list(queryWrapper);
-	        return list;
-	}
+    @Override
+    public List<MarkSubjectiveScore> listByStudentId(Long studentId) {
+        QueryWrapper<MarkSubjectiveScore> queryWrapper = new QueryWrapper<>();
+        queryWrapper.lambda().eq(MarkSubjectiveScore::getStudentId, studentId).orderByAsc(MarkSubjectiveScore::getMainNumber)
+                .orderByAsc(MarkSubjectiveScore::getSubNumber);
+        ;
+        List<MarkSubjectiveScore> list = this.list(queryWrapper);
+        return list;
+    }
+
+    @Override
+    public void updateRejected(Long studentId, Integer groupNumber, boolean rejectd) {
+        UpdateWrapper<MarkSubjectiveScore> updateWrapper = new UpdateWrapper<>();
+        updateWrapper.lambda().set(MarkSubjectiveScore::getRejected, rejectd)
+                .eq(MarkSubjectiveScore::getStudentId, studentId)
+                .eq(MarkSubjectiveScore::getGroupNumber, groupNumber);
+        this.update(updateWrapper);
+    }
 
 }

+ 46 - 4
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkTaskServiceImpl.java

@@ -13,10 +13,14 @@ import com.qmth.teachcloud.common.service.BasicRoleDataPermissionService;
 import com.qmth.teachcloud.common.util.ExcelUtil;
 import com.qmth.teachcloud.common.util.ServletUtil;
 import com.qmth.teachcloud.mark.dto.mark.manage.MarkManageDto;
+import com.qmth.teachcloud.mark.dto.mark.manage.MarkRejectHistoryDto;
+import com.qmth.teachcloud.mark.dto.mark.manage.MarkTaskDto;
 import com.qmth.teachcloud.mark.dto.mark.manage.MarkerInfoDto;
 import com.qmth.teachcloud.mark.entity.MarkGroup;
 import com.qmth.teachcloud.mark.entity.MarkTask;
+import com.qmth.teachcloud.mark.enums.LockType;
 import com.qmth.teachcloud.mark.enums.MarkTaskStatus;
+import com.qmth.teachcloud.mark.lock.LockService;
 import com.qmth.teachcloud.mark.mapper.MarkTaskMapper;
 import com.qmth.teachcloud.mark.service.*;
 import com.qmth.teachcloud.mark.utils.Calculator;
@@ -39,13 +43,15 @@ import java.util.List;
 @Service
 public class MarkTaskServiceImpl extends ServiceImpl<MarkTaskMapper, MarkTask> implements MarkTaskService {
 
-    @Resource
-    private MarkStudentService markStudentService;
     @Resource
     private MarkGroupService markGroupService;
     @Resource
     private MarkQuestionService markQuestionService;
     @Resource
+    private MarkService markService;
+    @Resource
+    private LockService lockService;
+    @Resource
     private BasicRoleDataPermissionService basicRoleDataPermissionService;
 
     @Override
@@ -117,7 +123,7 @@ public class MarkTaskServiceImpl extends ServiceImpl<MarkTaskMapper, MarkTask> i
     }
 
     @Override
-    public boolean resetById(Long markTaskId, Long userId, Long rejecterId, Long date, MarkTaskStatus newStatus) {
+    public boolean resetById(Long markTaskId, Long userId, String rejectReason, Long rejectId, Long date, MarkTaskStatus newStatus) {
         UpdateWrapper<MarkTask> updateWrapper = new UpdateWrapper<>();
         updateWrapper.lambda().set(MarkTask::getStatus, newStatus)
                 .set(MarkTask::getUserId, userId)
@@ -125,10 +131,11 @@ public class MarkTaskServiceImpl extends ServiceImpl<MarkTaskMapper, MarkTask> i
                 .set(MarkTask::getMarkerScore, null)
                 .set(MarkTask::getMarkerScoreList, null)
                 .set(MarkTask::getMarkerSpent, null)
-                .set(MarkTask::getHeaderId, rejecterId)
+                .set(MarkTask::getHeaderId, rejectId)
                 .set(MarkTask::getHeaderTime, date)
                 .set(MarkTask::getHeaderScore, null)
                 .set(MarkTask::getHeaderScoreList, null)
+                .set(MarkTask::getRejectReason, rejectReason)
                 .eq(MarkTask::getId, markTaskId);
         return this.update(updateWrapper);
     }
@@ -330,4 +337,39 @@ public class MarkTaskServiceImpl extends ServiceImpl<MarkTaskMapper, MarkTask> i
                 .eq(MarkTask::getPaperNumber, paperNumber);
         return this.count(queryWrapper);
     }
+
+    @Override
+    public IPage<MarkTaskDto> pageMarkTask(Long examId, String paperNumber, Integer groupNumber, String loginName, MarkTaskStatus status, String studentCode, String secretNumber, String teachClassName, Double subScore, Integer pageNumber, Integer pageSize) {
+        IPage<MarkTaskDto> markTaskDtoIPage = this.baseMapper.pageMarkTask(new Page<>(pageNumber, pageSize), examId, paperNumber, groupNumber, loginName, status, studentCode, secretNumber, teachClassName, subScore);
+        for (MarkTaskDto record : markTaskDtoIPage.getRecords()) {
+            record.setStatusDisplay(record.getStatus().getName());
+            // 分组题目
+            record.setGroupQuestions(markQuestionService.assembleGroupQuestionsByExamIdAndPaperNumberAndNumber(record.getExamId(), record.getPaperNumber(), record.getGroupNumber()));
+        }
+        return markTaskDtoIPage;
+    }
+
+    @Override
+    public void rejectMarkTask(Long id, String rejectReason) {
+        SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
+        MarkTask markTask = this.getById(id);
+        if (markTask == null) {
+            throw ExceptionResultEnum.ERROR.exception("任务不存在");
+        }
+        try {
+            lockService.watch(LockType.EXAM_SUBJECT, markTask.getExamId(), markTask.getPaperNumber());
+            lockService.watch(LockType.GROUP, markTask.getExamId(), markTask.getPaperNumber(), markTask.getGroupNumber());
+            lockService.waitlock(LockType.STUDENT, markTask.getStudentId());
+            if (!markTask.getStatus().equals(MarkTaskStatus.MARKED)) {
+                throw ExceptionResultEnum.ERROR.exception("当前任务不允许打回");
+            }
+            markService.rejectMarkTask(markTask, sysUser.getId(), rejectReason);
+        } catch (Exception e) {
+            log.error("打回失败", e);
+        } finally {
+            lockService.unlock(LockType.STUDENT, markTask.getStudentId());
+            lockService.unwatch(LockType.GROUP, markTask.getExamId(), markTask.getPaperNumber(), markTask.getGroupNumber());
+            lockService.unwatch(LockType.EXAM_SUBJECT, markTask.getExamId(), markTask.getPaperNumber());
+        }
+    }
 }

+ 5 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkUserGroupServiceImpl.java

@@ -352,4 +352,9 @@ public class MarkUserGroupServiceImpl extends ServiceImpl<MarkUserGroupMapper, M
     public int countByMarkTask(Long userId, MarkPaperStatus status) {
         return this.baseMapper.countByMarkTask(userId, status.name());
     }
+
+    @Override
+    public void updateRejectCountByExamIdAndPaperNumberAndGroupNumberAndUserId(Long examId, String paperNumber, Integer groupNumber, Long userId) {
+        this.baseMapper.updateRejectCountByExamIdAndPaperNumberAndGroupNumberAndUserId(examId, paperNumber, groupNumber, userId);
+    }
 }

+ 77 - 0
teachcloud-mark/src/main/resources/mapper/MarkRejectHistoryMapper.xml

@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.qmth.teachcloud.mark.mapper.MarkRejectHistoryMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.qmth.teachcloud.mark.entity.MarkRejectHistory">
+        <id column="id" property="id" />
+        <result column="exam_id" property="examId" />
+        <result column="paper_number" property="paperNumber" />
+        <result column="group_number" property="groupNumber" />
+        <result column="task_id" property="taskId" />
+        <result column="student_id" property="studentId" />
+        <result column="student_code" property="studentCode" />
+        <result column="secret_number" property="secretNumber" />
+        <result column="user_id" property="userId" />
+        <result column="reason" property="reason" />
+        <result column="reject_score_list" property="rejectScoreList" />
+        <result column="score_list" property="scoreList" />
+        <result column="total_score" property="totalScore" />
+        <result column="marker_time" property="markerTime" />
+        <result column="reject_user_id" property="rejectUserId" />
+        <result column="reject_time" property="rejectTime" />
+    </resultMap>
+    <select id="pageRejectHistory" resultType="com.qmth.teachcloud.mark.dto.mark.manage.MarkRejectHistoryDto">
+        SELECT
+            mrh.*,
+            bes.student_name,
+            bes.class_name,
+            bes.teach_class_name,
+            su.login_name,
+            su.real_name,
+            so.name orgName,
+            su1.login_name rejectLoginName,
+            su1.real_name rejectUserName
+        FROM
+            (SELECT
+                 *
+             FROM
+                 mark_reject_history
+             WHERE
+                 exam_id = #{examId} AND paper_number = #{paperNumber}
+                <where>
+                    <if test="groupNumber != null">
+                        and group_number = #{groupNumber}
+                    </if>
+                    <if test="studentCode != null and studentCode != ''">
+                        and student_code = #{studentCode}
+                    </if>
+                    <if test="secretNumber != null and secretNumber != ''">
+                        and secret_number = #{secretNumber}
+                    </if>
+                </where>
+             ) mrh
+                LEFT JOIN
+            (SELECT
+                 id, student_name, class_name, teach_class_name
+             FROM
+                 basic_exam_student
+             WHERE
+                 exam_id = #{examId} AND paper_number = #{paperNumber}) bes ON mrh.basic_student_id = bes.id
+                LEFT JOIN
+            sys_user su ON mrh.user_id = su.id
+                LEFT JOIN
+            sys_user su1 ON mrh.reject_user_id = su1.id
+                LEFT JOIN
+            sys_org so ON su.org_id = so.id
+            <where>
+                <if test="loginName != null and loginName != ''">
+                    and su.login_name = #{loginName}
+                </if>
+                <if test="teachClassName != null and teachClassName != ''">
+                    and bes.teach_class_name = #{teachClassName}
+                </if>
+            </where>
+    </select>
+
+</mapper>

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

@@ -294,4 +294,62 @@
             mt.student_id = ms.id)
         </if>
     </select>
+    <select id="pageMarkTask" resultType="com.qmth.teachcloud.mark.dto.mark.manage.MarkTaskDto">
+        SELECT
+            mt.*,
+            bes.student_name,
+            bes.class_name,
+            bes.teach_class_name,
+            su.login_name,
+            su.real_name,
+            so.name orgName,
+            su1.login_name rejectLoginName,
+            su1.real_name rejectUserName
+        FROM
+            (SELECT
+                 *
+             FROM
+                 mark_task
+             WHERE
+                 exam_id = #{examId} AND paper_number = #{paperNumber}
+                <where>
+                    <if test="groupNumber != null and groupNumber != ''">
+                        and group_number = #{groupNumber}
+                    </if>
+                    <if test="studentCode != null and studentCode != ''">
+                        and student_code = #{studentCode}
+                    </if>
+                    <if test="secretNumber != null and secretNumber != ''">
+                        and secret_number = #{secretNumber}
+                    </if>
+                    <if test="status != null">
+                        and status = #{status}
+                    </if>
+                    <if test="subScore != null">
+                        and (marker_score_list like concat(#{subScore}, ',%') or marker_score_list like concat('%,', #{subScore}) or marker_score_list like concat('%,', #{subScore}, ',%'))
+                    </if>
+                </where>
+             ) mt
+                LEFT JOIN
+            (SELECT
+                 id, student_name, class_name, teach_class_name
+             FROM
+                 basic_exam_student
+             WHERE
+                 exam_id = #{examId} AND paper_number = #{paperNumber}) bes ON mt.basic_student_id = bes.id
+                LEFT JOIN
+            sys_user su ON mt.user_id = su.id
+                LEFT JOIN
+            sys_user su1 ON mt.header_id = su1.id
+                LEFT JOIN
+            sys_org so ON su.org_id = so.id
+        <where>
+            <if test="loginName != null and loginName != ''">
+                and su.login_name = #{loginName}
+            </if>
+            <if test="teachClassName != null and teachClassName != ''">
+                and bes.teach_class_name = #{teachClassName}
+            </if>
+        </where>
+    </select>
 </mapper>

+ 11 - 0
teachcloud-mark/src/main/resources/mapper/MarkUserGroupMapper.xml

@@ -170,4 +170,15 @@
             </if>
         </where>
     </select>
+
+    <update id="updateRejectCountByExamIdAndPaperNumberAndGroupNumberAndUserId">
+        UPDATE mark_user_group mug
+        SET
+            mug.reject_count = IFNULL(mug.reject_count, 0) + 1
+        WHERE
+            mug.exam_id = #{examId}
+          AND mug.paper_number = #{paperNumber}
+          AND mug.group_number = #{groupNumber}
+          AND mug.user_id = #{userId}
+    </update>
 </mapper>