ting.yin há 1 ano atrás
pai
commit
5e68148a8c
19 ficheiros alterados com 610 adições e 97 exclusões
  1. 3 3
      teachcloud-common/src/main/java/com/qmth/teachcloud/common/entity/MarkStudent.java
  2. 67 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/bean/OmrTaskItem.java
  3. 27 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/bean/OmrTaskPage.java
  4. 7 5
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/dto/ScanOmrTaskDto.java
  5. 31 24
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/entity/ScanOmrTask.java
  6. 9 10
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/entity/ScanStudentPaper.java
  7. 26 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/enums/OmrTaskStatus.java
  8. 58 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/handle/ListTypeHandler.java
  9. 16 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/handle/OmrTaskPageListTypeHandler.java
  10. 10 2
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/mapper/ScanOmrTaskMapper.java
  11. 9 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/ScanOmrTaskService.java
  12. 7 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/ScanPaperPageService.java
  13. 5 0
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/ScanStudentPaperService.java
  14. 0 2
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/MarkServiceImpl.java
  15. 259 3
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/ScanOmrTaskServiceImpl.java
  16. 37 4
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/ScanPaperPageServiceImpl.java
  17. 19 4
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/ScanStudentPaperServiceImpl.java
  18. 7 39
      teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/utils/TaskLockUtil.java
  19. 13 1
      teachcloud-mark/src/main/resources/mapper/ScanOmrTaskMapper.xml

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

@@ -1,15 +1,15 @@
 package com.qmth.teachcloud.common.entity;
 
-import com.baomidou.mybatisplus.annotation.IdType;
+import java.io.Serializable;
+
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
 import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
-import java.io.Serializable;
-
 /**
  * <p>
  * 考试考生库

+ 67 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/bean/OmrTaskItem.java

@@ -0,0 +1,67 @@
+package com.qmth.teachcloud.mark.bean;
+
+import com.qmth.teachcloud.common.enums.scan.OmrField;
+
+public class OmrTaskItem {
+
+    private Integer index;
+
+    private OmrField field;
+
+    private String omrResult;
+
+    private String firstResult;
+
+    private String secondResult;
+
+    private String arbitrateResult;
+
+    public Integer getIndex() {
+        return index;
+    }
+
+    public void setIndex(Integer index) {
+        this.index = index;
+    }
+
+    public OmrField getField() {
+        return field;
+    }
+
+    public void setField(OmrField field) {
+        this.field = field;
+    }
+
+    public String getOmrResult() {
+        return omrResult;
+    }
+
+    public void setOmrResult(String omrResult) {
+        this.omrResult = omrResult;
+    }
+
+    public String getFirstResult() {
+        return firstResult;
+    }
+
+    public void setFirstResult(String firstResult) {
+        this.firstResult = firstResult;
+    }
+
+    public String getSecondResult() {
+        return secondResult;
+    }
+
+    public void setSecondResult(String secondResult) {
+        this.secondResult = secondResult;
+    }
+
+    public String getArbitrateResult() {
+        return arbitrateResult;
+    }
+
+    public void setArbitrateResult(String arbitrateResult) {
+        this.arbitrateResult = arbitrateResult;
+    }
+
+}

+ 27 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/bean/OmrTaskPage.java

@@ -0,0 +1,27 @@
+package com.qmth.teachcloud.mark.bean;
+
+import java.util.List;
+
+public class OmrTaskPage {
+
+    private Integer index;
+
+    private List<OmrTaskItem> items;
+
+    public Integer getIndex() {
+        return index;
+    }
+
+    public void setIndex(Integer index) {
+        this.index = index;
+    }
+
+    public List<OmrTaskItem> getItems() {
+        return items;
+    }
+
+    public void setItems(List<OmrTaskItem> items) {
+        this.items = items;
+    }
+
+}

+ 7 - 5
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/dto/ScanOmrTaskDto.java

@@ -6,7 +6,7 @@ public class ScanOmrTaskDto {
 
     private Long id;
 
-    private String examNumber;
+    private String studentCode;
 
     private String name;
 
@@ -21,6 +21,8 @@ public class ScanOmrTaskDto {
     private Integer paperNumber;
 
     private List<ScanOmrTaskPageDto> pages;
+    
+    
 
     public Long getId() {
         return id;
@@ -30,12 +32,12 @@ public class ScanOmrTaskDto {
         this.id = id;
     }
 
-    public String getExamNumber() {
-        return examNumber;
+    public String getStudentCode() {
+        return studentCode;
     }
 
-    public void setExamNumber(String examNumber) {
-        this.examNumber = examNumber;
+    public void setStudentCode(String studentCode) {
+        this.studentCode = studentCode;
     }
 
     public String getName() {

+ 31 - 24
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/entity/ScanOmrTask.java

@@ -1,12 +1,17 @@
 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.List;
 
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
 import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.qmth.teachcloud.mark.bean.OmrTaskPage;
+import com.qmth.teachcloud.mark.enums.OmrTaskStatus;
+import com.qmth.teachcloud.mark.handle.OmrTaskPageListTypeHandler;
+
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
@@ -40,22 +45,23 @@ public class ScanOmrTask implements Serializable {
     private Long studentId;
 
     @ApiModelProperty(value = "试卷页数")
-    private Integer paperIndex;
+    private Integer paperNumber;
 
     @JsonSerialize(using = ToStringSerializer.class)
     @ApiModelProperty(value = "试卷ID")
-    private Integer paperId;
+    private Long paperId;
 
     @ApiModelProperty(value = "题卡编号")
     private Integer cardNumber;
 
     @ApiModelProperty(value = "状态")
-    private String status;
+    private OmrTaskStatus status;
 
     @JsonSerialize(using = ToStringSerializer.class)
     private Long userId;
 
-    private String pages;
+    @TableField(value = "pages", typeHandler = OmrTaskPageListTypeHandler.class)
+    private List<OmrTaskPage> pages;
 
     @JsonSerialize(using = ToStringSerializer.class)
     private Long creatorId;
@@ -95,18 +101,18 @@ public class ScanOmrTask implements Serializable {
     public void setStudentId(Long studentId) {
         this.studentId = studentId;
     }
-    public Integer getPaperIndex() {
-        return paperIndex;
+    public Integer getPaperNumber() {
+        return paperNumber;
     }
 
-    public void setPaperIndex(Integer paperIndex) {
-        this.paperIndex = paperIndex;
+    public void setPaperNumber(Integer paperNumber) {
+        this.paperNumber = paperNumber;
     }
-    public Integer getPaperId() {
+    public Long getPaperId() {
         return paperId;
     }
 
-    public void setPaperId(Integer paperId) {
+    public void setPaperId(Long paperId) {
         this.paperId = paperId;
     }
     public Integer getCardNumber() {
@@ -116,11 +122,11 @@ public class ScanOmrTask implements Serializable {
     public void setCardNumber(Integer cardNumber) {
         this.cardNumber = cardNumber;
     }
-    public String getStatus() {
+    public OmrTaskStatus getStatus() {
         return status;
     }
 
-    public void setStatus(String status) {
+    public void setStatus(OmrTaskStatus status) {
         this.status = status;
     }
     public Long getUserId() {
@@ -130,13 +136,6 @@ public class ScanOmrTask implements Serializable {
     public void setUserId(Long userId) {
         this.userId = userId;
     }
-    public String getPages() {
-        return pages;
-    }
-
-    public void setPages(String pages) {
-        this.pages = pages;
-    }
     public Long getCreatorId() {
         return creatorId;
     }
@@ -166,14 +165,22 @@ public class ScanOmrTask implements Serializable {
         this.updateTime = updateTime;
     }
 
-    @Override
+    public List<OmrTaskPage> getPages() {
+		return pages;
+	}
+
+	public void setPages(List<OmrTaskPage> pages) {
+		this.pages = pages;
+	}
+
+	@Override
     public String toString() {
         return "ScanOmrTask{" +
             "id=" + id +
             ", examId=" + examId +
             ", conditions=" + conditions +
             ", studentId=" + studentId +
-            ", paperIndex=" + paperIndex +
+            ", paperNumber=" + paperNumber +
             ", paperId=" + paperId +
             ", cardNumber=" + cardNumber +
             ", status=" + status +

+ 9 - 10
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/entity/ScanStudentPaper.java

@@ -1,14 +1,13 @@
 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 com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
 import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+
 import io.swagger.annotations.ApiModel;
-import io.swagger.annotations.ApiModelProperty;
 
 /**
  * <p>
@@ -28,7 +27,7 @@ public class ScanStudentPaper implements Serializable {
     @TableId(value = "student_id")
     private Long studentId;
 
-    private Integer paperIndex;
+    private Integer paperNumber;
 
     @JsonSerialize(using = ToStringSerializer.class)
     private Long paperId;
@@ -44,12 +43,12 @@ public class ScanStudentPaper implements Serializable {
     public void setStudentId(Long studentId) {
         this.studentId = studentId;
     }
-    public Integer getPaperIndex() {
-        return paperIndex;
+    public Integer getPaperNumber() {
+        return paperNumber;
     }
 
-    public void setPaperIndex(Integer paperIndex) {
-        this.paperIndex = paperIndex;
+    public void setPaperIndex(Integer paperNumber) {
+        this.paperNumber = paperNumber;
     }
     public Long getPaperId() {
         return paperId;
@@ -77,7 +76,7 @@ public class ScanStudentPaper implements Serializable {
     public String toString() {
         return "ScanStudentPaper{" +
             "studentId=" + studentId +
-            ", paperIndex=" + paperIndex +
+            ", paperNumber=" + paperNumber +
             ", paperId=" + paperId +
             ", createTime=" + createTime +
             ", updateTime=" + updateTime +

+ 26 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/enums/OmrTaskStatus.java

@@ -0,0 +1,26 @@
+package com.qmth.teachcloud.mark.enums;
+
+public enum OmrTaskStatus {
+
+    WAITING("未处理"), PROCESSED("已处理");
+
+    private String name;
+
+    OmrTaskStatus(String name) {
+        this.name = name;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public static OmrTaskStatus getByName(String name) {
+        for (OmrTaskStatus r : OmrTaskStatus.values()) {
+            if (r.getName().equals(name)) {
+                return r;
+            }
+        }
+        return null;
+    }
+
+}

+ 58 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/handle/ListTypeHandler.java

@@ -0,0 +1,58 @@
+package com.qmth.teachcloud.mark.handle;
+
+import java.sql.CallableStatement;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.ibatis.type.BaseTypeHandler;
+import org.apache.ibatis.type.JdbcType;
+import org.apache.ibatis.type.MappedJdbcTypes;
+import org.apache.ibatis.type.MappedTypes;
+
+import com.github.xiaoymin.knife4j.core.util.StrUtil;
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+
+@MappedJdbcTypes(JdbcType.VARCHAR)
+@MappedTypes({List.class})
+public abstract class ListTypeHandler<T> extends BaseTypeHandler<List<T>> {
+	private static Gson gson = new Gson();
+    @Override
+    public void setNonNullParameter(PreparedStatement ps, int i, List<T> parameter, JdbcType jdbcType) throws SQLException {
+        String content = CollectionUtils.isEmpty(parameter) ? null : gson.toJson(parameter);
+        ps.setString(i, content);
+    }
+ 
+    @Override
+    public List<T> getNullableResult(ResultSet rs, String columnName) throws SQLException {
+        return this.getListByJsonArrayString(rs.getString(columnName));
+    }
+ 
+    @Override
+    public List<T> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
+        return this.getListByJsonArrayString(rs.getString(columnIndex));
+    }
+ 
+    @Override
+    public List<T> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
+        return this.getListByJsonArrayString(cs.getString(columnIndex));
+    }
+ 
+ 
+    private List<T> getListByJsonArrayString(String content) {
+        return StrUtil.isBlank(content) ? new ArrayList<>() :  gson.fromJson(content, this.specificType().getType());
+    }
+ 
+    /**
+     * 具体类型,由子类提供
+     *
+     * @return 具体类型
+     */
+    protected abstract TypeToken<List<T>> specificType();
+ 
+ 
+}

+ 16 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/handle/OmrTaskPageListTypeHandler.java

@@ -0,0 +1,16 @@
+package com.qmth.teachcloud.mark.handle;
+
+import java.util.List;
+
+import com.google.gson.reflect.TypeToken;
+import com.qmth.teachcloud.mark.entity.ScanPaperPage;
+
+public class OmrTaskPageListTypeHandler extends ListTypeHandler<ScanPaperPage> {
+
+	@Override
+	protected TypeToken<List<ScanPaperPage>> specificType() {
+		return new TypeToken<List<ScanPaperPage>>() {
+		};
+	}
+
+}

+ 10 - 2
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/mapper/ScanOmrTaskMapper.java

@@ -1,11 +1,16 @@
 package com.qmth.teachcloud.mark.mapper;
 
-import com.qmth.teachcloud.mark.entity.ScanOmrTask;
+import java.util.List;
+
+import org.apache.ibatis.annotations.Param;
+
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.qmth.teachcloud.mark.entity.ScanOmrTask;
+import com.qmth.teachcloud.mark.enums.OmrTaskStatus;
 
 /**
  * <p>
- *  Mapper 接口
+ * Mapper 接口
  * </p>
  *
  * @author xf
@@ -13,4 +18,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  */
 public interface ScanOmrTaskMapper extends BaseMapper<ScanOmrTask> {
 
+	List<ScanOmrTask> findUnMarked(@Param(value = "examId") Long examId, @Param(value = "pageNumber") int pageNumber,
+			@Param(value = "pageSize") int pageSize, @Param(value = "status") OmrTaskStatus status);
+
 }

+ 9 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/ScanOmrTaskService.java

@@ -1,5 +1,7 @@
 package com.qmth.teachcloud.mark.service;
 
+import java.util.List;
+
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.qmth.teachcloud.common.entity.SysUser;
 import com.qmth.teachcloud.common.enums.scan.ConditionType;
@@ -8,6 +10,7 @@ import com.qmth.teachcloud.mark.dto.ScanOmrTaskResultDto;
 import com.qmth.teachcloud.mark.dto.ScanOmrTaskSaveDto;
 import com.qmth.teachcloud.mark.dto.ScanOmrTaskStatusDto;
 import com.qmth.teachcloud.mark.entity.ScanOmrTask;
+import com.qmth.teachcloud.mark.enums.OmrTaskStatus;
 
 /**
  * <p>
@@ -31,4 +34,10 @@ public interface ScanOmrTaskService extends IService<ScanOmrTask> {
 
 	ScanOmrTaskDto history(Long examId, Long taskId, Long userId, Boolean next);
 
+	List<ScanOmrTask> findUnMarked(Long examId, int pageNumber, int pageSize, OmrTaskStatus status);
+
+	boolean hasApplied(ScanOmrTask task, String userId);
+
+	boolean apply(ScanOmrTask task, String userId);
+
 }

+ 7 - 0
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/ScanPaperPageService.java

@@ -1,6 +1,9 @@
 package com.qmth.teachcloud.mark.service;
 
 import com.qmth.teachcloud.mark.entity.ScanPaperPage;
+
+import java.util.List;
+
 import com.baomidou.mybatisplus.extension.service.IService;
 
 /**
@@ -13,4 +16,8 @@ import com.baomidou.mybatisplus.extension.service.IService;
  */
 public interface ScanPaperPageService extends IService<ScanPaperPage> {
 
+	ScanPaperPage findPaperIdAndIndex(Long paperId, Integer pageIndex);
+
+	List<ScanPaperPage> listByPaperId(Long paperId);
+
 }

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

@@ -1,6 +1,9 @@
 package com.qmth.teachcloud.mark.service;
 
 import com.qmth.teachcloud.mark.entity.ScanStudentPaper;
+
+import java.util.List;
+
 import com.baomidou.mybatisplus.extension.service.IService;
 
 /**
@@ -13,4 +16,6 @@ import com.baomidou.mybatisplus.extension.service.IService;
  */
 public interface ScanStudentPaperService extends IService<ScanStudentPaper> {
 
+	List<ScanStudentPaper> findByStudentId(Long studentId);
+
 }

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

@@ -83,8 +83,6 @@ public class MarkServiceImpl implements MarkService {
     public void releaseByMarkUserGroup(MarkUserGroup markUserGroup) {
         TaskLock taskLock = TaskLockUtil.getFormalTask(getGroupKey(markUserGroup));
         taskLock.clear(markUserGroup.getId());
-        TaskLock lock = TaskLockUtil.getTrialTask(getGroupKey(markUserGroup));
-        lock.clear(markUserGroup.getId());
     }
 
     @Override

+ 259 - 3
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/ScanOmrTaskServiceImpl.java

@@ -1,17 +1,44 @@
 package com.qmth.teachcloud.mark.service.impl;
 
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.collections4.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.qmth.boot.core.exception.ParameterException;
+import com.qmth.teachcloud.common.entity.MarkStudent;
 import com.qmth.teachcloud.common.entity.SysUser;
 import com.qmth.teachcloud.common.enums.scan.ConditionType;
+import com.qmth.teachcloud.common.enums.scan.OmrField;
+import com.qmth.teachcloud.common.service.MarkStudentService;
+import com.qmth.teachcloud.mark.bean.OmrTaskItem;
+import com.qmth.teachcloud.mark.bean.OmrTaskPage;
 import com.qmth.teachcloud.mark.dto.ScanOmrTaskDto;
+import com.qmth.teachcloud.mark.dto.ScanOmrTaskPageDto;
 import com.qmth.teachcloud.mark.dto.ScanOmrTaskResultDto;
 import com.qmth.teachcloud.mark.dto.ScanOmrTaskSaveDto;
 import com.qmth.teachcloud.mark.dto.ScanOmrTaskStatusDto;
 import com.qmth.teachcloud.mark.entity.ScanOmrTask;
+import com.qmth.teachcloud.mark.entity.ScanPaper;
+import com.qmth.teachcloud.mark.entity.ScanPaperPage;
+import com.qmth.teachcloud.mark.entity.ScanStudentPaper;
+import com.qmth.teachcloud.mark.enums.OmrTaskStatus;
 import com.qmth.teachcloud.mark.mapper.ScanOmrTaskMapper;
 import com.qmth.teachcloud.mark.service.ScanOmrTaskService;
+import com.qmth.teachcloud.mark.service.ScanPaperPageService;
+import com.qmth.teachcloud.mark.service.ScanPaperService;
+import com.qmth.teachcloud.mark.service.ScanStudentPaperService;
+import com.qmth.teachcloud.mark.utils.TaskLock;
+import com.qmth.teachcloud.mark.utils.TaskLockUtil;
 
 /**
  * <p>
@@ -23,17 +50,246 @@ import com.qmth.teachcloud.mark.service.ScanOmrTaskService;
  */
 @Service
 public class ScanOmrTaskServiceImpl extends ServiceImpl<ScanOmrTaskMapper, ScanOmrTask> implements ScanOmrTaskService {
+	@Autowired
+	private ScanStudentPaperService studentPaperService;
+	
+	@Autowired
+	private MarkStudentService studentService;
+	@Autowired
+	private ScanPaperService paperService;
+	@Autowired
+	private ScanPaperPageService pageService;
+	
+    private static final String OMR_SUSPECT = "?";
 
+    private static final String OMR_BLANK = "#";
+	
 	@Override
 	public ScanOmrTask buildTask(ConditionType c, Long studentId) {
-		// TODO Auto-generated method stub
 		return null;
 	}
 
+	private List<ScanStudentPaper> clearAndToDispose(ConditionType c, Long studentId) {
+        List<ScanStudentPaper> spes = studentPaperService.findByStudentId(studentId);
+        if (CollectionUtils.isEmpty(spes)) {
+            return spes;
+        }
+        List<ScanOmrTask> tasks = getByStudent(c, studentId);
+        if (CollectionUtils.isEmpty(tasks)) {
+            return spes;
+        }
+        Map<Integer, Long> speMap = new HashMap<>();
+        for (ScanStudentPaper spe : spes) {
+            speMap.put(spe.getPaperNumber(), spe.getPaperId());
+        }
+        Map<Integer, Long> taskMap = new HashMap<>();
+        for (ScanOmrTask t : tasks) {
+            taskMap.put(t.getPaperNumber(), t.getPaperId());
+        }
+        if (ConditionType.FILL_SUSPECT.equals(c)) {
+            List<ScanStudentPaper> ret = new ArrayList<>();
+            for (ScanStudentPaper spe : spes) {
+                Long paperId = taskMap.get(spe.getPaperNumber());
+                if (paperId == null) {// 没有task的直接创建
+                    ret.add(spe);
+                } else if (paperId.longValue() != spe.getPaperId().longValue()) {// 和task不一致的删除并创建
+                    delete(c, studentId, paperId);
+                    ret.add(spe);
+                }
+            }
+            for (ScanOmrTask t : tasks) {
+                if (speMap.get(t.getPaperNumber()) == null) {// 不在绑定关系的task删除
+                    delete(c, studentId, t.getPaperId());
+                }
+            }
+            return ret;
+        } else {
+            if (spes.size() != tasks.size()) {// 数量不一致的删除重建
+                delete(c, studentId);
+                return spes;
+            }
+            for (ScanOmrTask t : tasks) {
+                if (!t.getPaperId().equals(speMap.get(t.getPaperNumber()))) {// 有一个不一致的删除重建
+                    delete(c, studentId);
+                    return spes;
+                }
+            }
+            return null;// 完全一致的不处理
+        }
+	}
+	
+	 private List<ScanOmrTask> getByStudent(ConditionType c, Long studentId) {
+	        QueryWrapper<ScanOmrTask> wrapper = new QueryWrapper<>();
+	        LambdaQueryWrapper<ScanOmrTask> lw = wrapper.lambda();
+	        lw.eq(ScanOmrTask::getConditions, c);
+	        lw.eq(ScanOmrTask::getStudentId, studentId);
+	        return baseMapper.selectList(wrapper);
+	    }
+	 
+	 private void delete( ConditionType c, Long studentId, Long paperId) {
+	        UpdateWrapper<ScanOmrTask> wrapper = new UpdateWrapper<>();
+	        LambdaUpdateWrapper<ScanOmrTask> lw = wrapper.lambda();
+	        lw.eq(ScanOmrTask::getConditions, c);
+	        lw.eq(ScanOmrTask::getStudentId, studentId);
+	        lw.eq(ScanOmrTask::getPaperId, paperId);
+	        this.baseMapper.delete(wrapper);
+	    }
+	 private void delete( ConditionType c, Long studentId) {
+	        UpdateWrapper<ScanOmrTask> wrapper = new UpdateWrapper<>();
+	        LambdaUpdateWrapper<ScanOmrTask> lw = wrapper.lambda();
+	        lw.eq(ScanOmrTask::getConditions, c);
+	        lw.eq(ScanOmrTask::getStudentId, studentId);
+	        this.baseMapper.delete(wrapper);
+	    }
+	 
+	 private boolean isAllBlank(List<ScanStudentPaper> paperIds) {
+	        for (ScanStudentPaper spe : paperIds) {
+	        	ScanPaper paper = paperService.getById(spe.getPaperId());
+	            if (paper == null) {
+	                throw new ParameterException("paper不存在");
+	            }
+	            List<ScanPaperPage> pageList = pageService.listByPaperId(spe.getPaperId());
+	            for (ScanPaperPage pageEntity : pageList) {
+	                for (int i = 0; pageEntity.getQuestion() != null && pageEntity.getQuestion().getResult() != null
+	                        && i < pageEntity.getQuestion().getResult().size(); i++) {
+	                    String result = pageEntity.getQuestion().getResult().get(i);
+	                    if (!"#".equals(result)) {
+	                        return false;
+	                    }
+	                }
+	            }
+	        }
+	        return true;
+	    }
 	@Override
 	public ScanOmrTaskDto getTask(Long examId, Long userId) {
-		// TODO Auto-generated method stub
-		return null;
+		int retry = 0;
+		ScanOmrTaskDto task = null;
+		while (task == null) {
+			List<ScanOmrTask> list = this.findUnMarked(examId, retry * 20, 20, OmrTaskStatus.WAITING);
+			if (list.isEmpty()) {
+				break;
+			}
+			for (ScanOmrTask t : list) {
+				if (this.apply(t, userId.toString())) {
+					task = toTaskVo(t, false);
+					break;
+				}
+			}
+			if (task == null) {
+				retry++;
+			}
+		}
+		return task;
+	}
+
+	private ScanOmrTaskDto toTaskVo(ScanOmrTask task, boolean history) {
+		ScanOmrTaskDto vo = new ScanOmrTaskDto();
+		MarkStudent student = studentService.getById(task.getStudentId());
+		vo.setCardNumber(task.getCardNumber());
+		vo.setStudentCode(student.getStudentCode());
+		vo.setId(task.getId());
+		vo.setName(student.getStudentName());
+		vo.setPaperId(task.getPaperId());
+		vo.setPaperNumber(task.getPaperNumber());
+		vo.setSubjectCode(student.getCourseCode());
+		vo.setSubjectName(student.getCourseName());
+		List<ScanOmrTaskPageDto> pages = new ArrayList<>();
+		for (OmrTaskPage taskPage : task.getPages()) {
+			ScanOmrTaskPageDto page = new ScanOmrTaskPageDto();
+			Map<Integer, List<String>> question = new HashMap<>();
+			Map<Integer, List<String>> selective = new HashMap<>();
+			for (OmrTaskItem item : taskPage.getItems()) {
+				if (OmrField.ABSENT.equals(item.getField())) {
+					page.setAbsent(getBooleanItem(item, history));
+				}
+				if (OmrField.BREACH.equals(item.getField())) {
+					page.setBreach(getBooleanItem(item, history));
+				}
+				if (OmrField.PAPER_TYPE.equals(item.getField())) {
+					page.setPaperType(getStringItem(item, history));
+				}
+				if (OmrField.QUESTION.equals(item.getField())) {
+					List<String> content = getStringItem(item, history);
+					if (content != null) {
+						question.put(item.getIndex(), content);
+					}
+				}
+				if (OmrField.SELECTIVE.equals(item.getField())) {
+					List<String> content = getStringItem(item, history);
+					if (content != null) {
+						selective.put(item.getIndex(), content);
+					}
+				}
+			}
+			if (question.size() > 0) {
+				page.setQuestion(question);
+			}
+			if (selective.size() > 0) {
+				page.setSelective(selective);
+			}
+			// 有需要仲裁的数据才返回结构
+			if (page.getAbsent() != null || page.getBreach() != null || page.getPaperType() != null
+					|| page.getQuestion() != null || page.getSelective() != null) {
+				page.setIndex(taskPage.getIndex());
+				ScanPaperPage p = pageService.findPaperIdAndIndex(task.getPaperId(), taskPage.getIndex());
+				page.setRecogData(p.getRecogData());
+				page.setUri(p.getSheetPath());
+				pages.add(page);
+			}
+		}
+		vo.setPages(pages);
+		return vo;
+	}
+
+	private List<String> getStringItem(OmrTaskItem item, boolean history) {
+		List<String> value = new ArrayList<>();
+		value.add(item.getOmrResult());
+		if (history && item.getFirstResult() != null && item.getSecondResult() == null) {
+			value.add(item.getFirstResult());
+		} else if (history && item.getSecondResult() != null) {
+			value.add(item.getSecondResult());
+		}
+		return value;
+	}
+
+	private List<Boolean> getBooleanItem(OmrTaskItem item, boolean history) {
+		List<Boolean> value = new ArrayList<>();
+		value.add(Boolean.valueOf(item.getOmrResult()));
+		if (history && item.getFirstResult() != null && item.getSecondResult() == null) {
+			value.add(Boolean.valueOf(item.getFirstResult()));
+		} else if (history && item.getSecondResult() != null) {
+			value.add(Boolean.valueOf(item.getSecondResult()));
+		}
+		return value;
+	}
+
+	@Override
+	public List<ScanOmrTask> findUnMarked(Long examId, int pageNumber, int pageSize, OmrTaskStatus status) {
+		return this.baseMapper.findUnMarked(examId, pageNumber, pageSize, status);
+	}
+
+	@Override
+	public boolean apply(ScanOmrTask t, String userId) {
+		TaskLock taskLock = TaskLockUtil.getOmrTask(t.getExamId().toString());
+		boolean lock = taskLock.add(t.getId(), 1, userId);
+		// 上锁失败直接返回
+		if (!lock) {
+			return false;
+		}
+		// 重复校验任务状态
+		if (t.getStatus().equals(OmrTaskStatus.WAITING)) {
+			return true;
+		} else {
+			taskLock.remove(t.getId(), 1);
+			return false;
+		}
+	}
+
+	@Override
+	public boolean hasApplied(ScanOmrTask t, String userId) {
+		TaskLock taskLock = TaskLockUtil.getOmrTask(t.getExamId().toString());
+		return taskLock.exist(t.getId(), 1, userId);
 	}
 
 	@Override

+ 37 - 4
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/ScanPaperPageServiceImpl.java

@@ -1,20 +1,53 @@
 package com.qmth.teachcloud.mark.service.impl;
 
+import java.util.List;
+
+import org.springframework.stereotype.Service;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.qmth.boot.core.exception.ParameterException;
 import com.qmth.teachcloud.mark.entity.ScanPaperPage;
 import com.qmth.teachcloud.mark.mapper.ScanPaperPageMapper;
 import com.qmth.teachcloud.mark.service.ScanPaperPageService;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import org.springframework.stereotype.Service;
 
 /**
  * <p>
- *  服务实现类
+ * 服务实现类
  * </p>
  *
  * @author xf
  * @since 2023-09-22
  */
 @Service
-public class ScanPaperPageServiceImpl extends ServiceImpl<ScanPaperPageMapper, ScanPaperPage> implements ScanPaperPageService {
+public class ScanPaperPageServiceImpl extends ServiceImpl<ScanPaperPageMapper, ScanPaperPage>
+		implements ScanPaperPageService {
+
+	@Override
+	public ScanPaperPage findPaperIdAndIndex(Long paperId, Integer index) {
+		if (paperId == null) {
+			throw new ParameterException("paperId不能为空");
+		}
+		if (index == null) {
+			throw new ParameterException("index不能为空");
+		}
+		QueryWrapper<ScanPaperPage> wrapper = new QueryWrapper<>();
+		LambdaQueryWrapper<ScanPaperPage> lw = wrapper.lambda();
+		lw.eq(ScanPaperPage::getPaperId, paperId);
+		lw.eq(ScanPaperPage::getPageIndex, index);
+		return baseMapper.selectOne(wrapper);
+	}
+
+	@Override
+	public List<ScanPaperPage> listByPaperId(Long paperId) {
+		if (paperId == null) {
+			throw new ParameterException("paperId不能为空");
+		}
+		QueryWrapper<ScanPaperPage> wrapper = new QueryWrapper<>();
+		LambdaQueryWrapper<ScanPaperPage> lw = wrapper.lambda();
+		lw.eq(ScanPaperPage::getPaperId, paperId);
+		return baseMapper.selectList(wrapper);
+	}
 
 }

+ 19 - 4
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/service/impl/ScanStudentPaperServiceImpl.java

@@ -1,20 +1,35 @@
 package com.qmth.teachcloud.mark.service.impl;
 
+import java.util.List;
+
+import org.springframework.stereotype.Service;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.qmth.teachcloud.mark.entity.ScanStudentPaper;
 import com.qmth.teachcloud.mark.mapper.ScanStudentPaperMapper;
 import com.qmth.teachcloud.mark.service.ScanStudentPaperService;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import org.springframework.stereotype.Service;
 
 /**
  * <p>
- *  服务实现类
+ * 服务实现类
  * </p>
  *
  * @author xf
  * @since 2023-09-22
  */
 @Service
-public class ScanStudentPaperServiceImpl extends ServiceImpl<ScanStudentPaperMapper, ScanStudentPaper> implements ScanStudentPaperService {
+public class ScanStudentPaperServiceImpl extends ServiceImpl<ScanStudentPaperMapper, ScanStudentPaper>
+		implements ScanStudentPaperService {
+
+	@Override
+	public List<ScanStudentPaper> findByStudentId(Long studentId) {
+		QueryWrapper<ScanStudentPaper> wrapper = new QueryWrapper<>();
+		LambdaQueryWrapper<ScanStudentPaper> lw = wrapper.lambda();
+		lw.eq(ScanStudentPaper::getStudentId, studentId);
+		wrapper.orderByAsc("paper_number");
+		return this.list(wrapper);
+	}
 
 }

+ 7 - 39
teachcloud-mark/src/main/java/com/qmth/teachcloud/mark/utils/TaskLockUtil.java

@@ -8,35 +8,24 @@ public class TaskLockUtil {
     // 评卷任务并发处理互斥锁
     private static final Map<String, TaskLock> formalTaskMap = new HashMap<>();
 
-    // 试评任务并发处理互斥锁
-    private static final Map<String, TaskLock> trialTaskMap = new HashMap<>();
+    // 识别对照任务并发处理互斥锁
+    private static final Map<String, TaskLock> omrTaskMap = new HashMap<>();
 
-    // 复核整卷并发处理互斥锁
-    private static final Map<String, TaskLock> inspectedStudentMap = new HashMap<>();
-
-    // 复核评卷任务并发处理互斥锁
-    private static final Map<String, TaskLock> inspectedLibraryMap = new HashMap<>();
 
     public static void clearTimeoutTask(long timeoutMinute) {
-        for (TaskLock taskLock : trialTaskMap.values()) {
+        for (TaskLock taskLock : omrTaskMap.values()) {
             taskLock.expire(timeoutMinute);
         }
         for (TaskLock taskLock : formalTaskMap.values()) {
             taskLock.expire(timeoutMinute);
         }
-        for (TaskLock taskLock : inspectedStudentMap.values()) {
-            taskLock.expire(timeoutMinute);
-        }
-        for (TaskLock taskLock : inspectedLibraryMap.values()) {
-            taskLock.expire(timeoutMinute);
-        }
     }
 
-    public static TaskLock getTrialTask(String key) {
-        TaskLock taskLock = trialTaskMap.get(key);
+    public static TaskLock getOmrTask(String key) {
+        TaskLock taskLock = omrTaskMap.get(key);
         if (taskLock == null) {
-            synchronized (trialTaskMap) {
-                taskLock = trialTaskMap.computeIfAbsent(key, k -> new TaskLock());
+            synchronized (omrTaskMap) {
+                taskLock = omrTaskMap.computeIfAbsent(key, k -> new TaskLock());
             }
         }
         return taskLock;
@@ -51,25 +40,4 @@ public class TaskLockUtil {
         }
         return taskLock;
     }
-
-    public static TaskLock getInspectedStudentTask(String key) {
-        TaskLock taskLock = inspectedStudentMap.get(key);
-        if (taskLock == null) {
-            synchronized (inspectedStudentMap) {
-                taskLock = inspectedStudentMap.computeIfAbsent(key, k -> new TaskLock());
-            }
-        }
-        return taskLock;
-    }
-
-    public static TaskLock getInspectedLibraryTask(String key) {
-        TaskLock taskLock = inspectedLibraryMap.get(key);
-        if (taskLock == null) {
-            synchronized (inspectedLibraryMap) {
-                taskLock = inspectedLibraryMap.computeIfAbsent(key, k -> new TaskLock());
-            }
-        }
-        return taskLock;
-    }
-
 }

+ 13 - 1
teachcloud-mark/src/main/resources/mapper/ScanOmrTaskMapper.xml

@@ -13,11 +13,23 @@
         <result column="card_number" property="cardNumber" />
         <result column="status" property="status" />
         <result column="user_id" property="userId" />
-        <result column="pages" property="pages" />
         <result column="creator_id" property="creatorId" />
         <result column="updater_id" property="updaterId" />
         <result column="create_time" property="createTime" />
         <result column="update_time" property="updateTime" />
+        <result column="pages" property="pages"
+			typeHandler="com.qmth.teachcloud.mark.handle.OmrTaskPageListTypeHandler" />
     </resultMap>
+    
+    <select id="findUnMarked" resultMap="custMap">
+		select *
+		from scan_omr_task t
+		where t.exam_id=#{examId}
+		and
+		t.status=#{status}
+		order by t.id
+		limit
+		#{pageNumber},#{pageSize}
+	</select>
 
 </mapper>