Przeglądaj źródła

Merge remote-tracking branch 'origin/dev_v1.0.0' into dev_v1.0.0

# Conflicts:
#	paper-library-common/src/main/java/com/qmth/paper/library/common/enums/TaskTypeEnum.java
wangliang 2 lat temu
rodzic
commit
9d08dcf62e
41 zmienionych plików z 1845 dodań i 41 usunięć
  1. 9 0
      paper-library-business/src/main/java/com/qmth/paper/library/business/bean/dto/Temp.java
  2. 107 0
      paper-library-business/src/main/java/com/qmth/paper/library/business/bean/dto/excel/PaperScanTaskImportDto.java
  3. 47 0
      paper-library-business/src/main/java/com/qmth/paper/library/business/bean/dto/excel/ScannerBindingDto.java
  4. 67 0
      paper-library-business/src/main/java/com/qmth/paper/library/business/bean/result/PaperLibraryResult.java
  5. 78 0
      paper-library-business/src/main/java/com/qmth/paper/library/business/bean/result/PaperScanTaskDetailResult.java
  6. 49 0
      paper-library-business/src/main/java/com/qmth/paper/library/business/bean/result/SelectResult.java
  7. 6 6
      paper-library-business/src/main/java/com/qmth/paper/library/business/entity/PaperArchivesType.java
  8. 26 0
      paper-library-business/src/main/java/com/qmth/paper/library/business/entity/PaperLibrary.java
  9. 5 0
      paper-library-business/src/main/java/com/qmth/paper/library/business/mapper/PaperArchivesMapper.java
  10. 5 0
      paper-library-business/src/main/java/com/qmth/paper/library/business/mapper/PaperArchivesTypeMapper.java
  11. 17 0
      paper-library-business/src/main/java/com/qmth/paper/library/business/mapper/PaperLibraryMapper.java
  12. 16 0
      paper-library-business/src/main/java/com/qmth/paper/library/business/mapper/PaperScanTaskMapper.java
  13. 5 0
      paper-library-business/src/main/java/com/qmth/paper/library/business/service/PaperArchivesService.java
  14. 5 0
      paper-library-business/src/main/java/com/qmth/paper/library/business/service/PaperArchivesTypeService.java
  15. 15 0
      paper-library-business/src/main/java/com/qmth/paper/library/business/service/PaperLibraryService.java
  16. 25 0
      paper-library-business/src/main/java/com/qmth/paper/library/business/service/PaperScanTaskService.java
  17. 10 1
      paper-library-business/src/main/java/com/qmth/paper/library/business/service/impl/PaperArchivesServiceImpl.java
  18. 11 2
      paper-library-business/src/main/java/com/qmth/paper/library/business/service/impl/PaperArchivesTypeServiceImpl.java
  19. 95 0
      paper-library-business/src/main/java/com/qmth/paper/library/business/service/impl/PaperLibraryServiceImpl.java
  20. 79 1
      paper-library-business/src/main/java/com/qmth/paper/library/business/service/impl/PaperScanTaskServiceImpl.java
  21. 72 0
      paper-library-business/src/main/java/com/qmth/paper/library/business/templete/execute/AsyncPaperScanTaskImportService.java
  22. 9 0
      paper-library-business/src/main/java/com/qmth/paper/library/business/templete/service/TaskLogicService.java
  23. 192 5
      paper-library-business/src/main/java/com/qmth/paper/library/business/templete/service/impl/TaskLogicServiceImpl.java
  24. 15 0
      paper-library-business/src/main/resources/mapper/PaperArchivesMapper.xml
  25. 5 2
      paper-library-business/src/main/resources/mapper/PaperArchivesTypeMapper.xml
  26. 109 0
      paper-library-business/src/main/resources/mapper/PaperLibraryMapper.xml
  27. 32 0
      paper-library-business/src/main/resources/mapper/PaperScanTaskMapper.xml
  28. 35 1
      paper-library-common/src/main/java/com/qmth/paper/library/common/enums/TaskTypeEnum.java
  29. 19 0
      paper-library-common/src/main/java/com/qmth/paper/library/common/lock/LockProvider.java
  30. 106 0
      paper-library-common/src/main/java/com/qmth/paper/library/common/lock/LockService.java
  31. 16 0
      paper-library-common/src/main/java/com/qmth/paper/library/common/lock/LockType.java
  32. 99 0
      paper-library-common/src/main/java/com/qmth/paper/library/common/lock/impl/CustomLockProvider.java
  33. 100 0
      paper-library-common/src/main/java/com/qmth/paper/library/common/lock/impl/JdkLockProvider.java
  34. 134 0
      paper-library-common/src/main/java/com/qmth/paper/library/common/lock/impl/ReadWriteLock.java
  35. 0 5
      paper-library-common/src/main/java/com/qmth/paper/library/common/service/BasicStudentService.java
  36. 0 17
      paper-library-common/src/main/java/com/qmth/paper/library/common/service/impl/BasicStudentServiceImpl.java
  37. 1 1
      paper-library/src/main/java/com/qmth/paper/library/api/BasicSemesterController.java
  38. 8 0
      paper-library/src/main/java/com/qmth/paper/library/api/PaperArchivesController.java
  39. 7 0
      paper-library/src/main/java/com/qmth/paper/library/api/PaperArchivesTypeController.java
  40. 84 0
      paper-library/src/main/java/com/qmth/paper/library/api/PaperLibraryController.java
  41. 125 0
      paper-library/src/main/java/com/qmth/paper/library/api/PaperScanTaskController.java

+ 9 - 0
paper-library-business/src/main/java/com/qmth/paper/library/business/bean/dto/Temp.java

@@ -0,0 +1,9 @@
+package com.qmth.paper.library.business.bean.dto;
+
+/**
+ * @Description:
+ * @Author: CaoZixuan
+ * @Date:
+ */
+public class Temp {
+}

+ 107 - 0
paper-library-business/src/main/java/com/qmth/paper/library/business/bean/dto/excel/PaperScanTaskImportDto.java

@@ -0,0 +1,107 @@
+package com.qmth.paper.library.business.bean.dto.excel;
+
+import com.qmth.paper.library.common.annotation.ExcelImportTempleteVaild;
+import com.qmth.paper.library.common.annotation.ExcelNote;
+
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+
+/**
+ * @Description: 扫描任务导入excel
+ * @Author: CaoZixuan
+ * @Date: 2022-09-29
+ */
+@ExcelImportTempleteVaild(value = true)
+public class PaperScanTaskImportDto implements Serializable {
+    @ExcelNote(value = "任务名称")
+    @NotNull
+    private String scanTaskName;
+
+    @ExcelNote(value = "档案名称")
+    @NotNull
+    private String archivesName;
+
+    @ExcelNote(value = "档案编号")
+    @NotNull
+    private String archivesCode;
+
+    @ExcelNote(value = "课程")
+    private String courseName;
+
+    @ExcelNote(value = "任课老师")
+    private String teacherName;
+
+    @ExcelNote(value = "姓名")
+    private String studentName;
+
+    @ExcelNote(value = "学号")
+    @NotNull
+    private String studentCode;
+
+    @ExcelNote(value = "教学班")
+    private String teachClazzName;
+
+    public String getScanTaskName() {
+        return scanTaskName;
+    }
+
+    public void setScanTaskName(String scanTaskName) {
+        this.scanTaskName = scanTaskName;
+    }
+
+    public String getArchivesName() {
+        return archivesName;
+    }
+
+    public void setArchivesName(String archivesName) {
+        this.archivesName = archivesName;
+    }
+
+    public String getArchivesCode() {
+        return archivesCode;
+    }
+
+    public void setArchivesCode(String archivesCode) {
+        this.archivesCode = archivesCode;
+    }
+
+    public String getCourseName() {
+        return courseName;
+    }
+
+    public void setCourseName(String courseName) {
+        this.courseName = courseName;
+    }
+
+    public String getTeacherName() {
+        return teacherName;
+    }
+
+    public void setTeacherName(String teacherName) {
+        this.teacherName = teacherName;
+    }
+
+    public String getStudentName() {
+        return studentName;
+    }
+
+    public void setStudentName(String studentName) {
+        this.studentName = studentName;
+    }
+
+    public String getStudentCode() {
+        return studentCode;
+    }
+
+    public void setStudentCode(String studentCode) {
+        this.studentCode = studentCode;
+    }
+
+    public String getTeachClazzName() {
+        return teachClazzName;
+    }
+
+    public void setTeachClazzName(String teachClazzName) {
+        this.teachClazzName = teachClazzName;
+    }
+}

+ 47 - 0
paper-library-business/src/main/java/com/qmth/paper/library/business/bean/dto/excel/ScannerBindingDto.java

@@ -0,0 +1,47 @@
+package com.qmth.paper.library.business.bean.dto.excel;
+
+import com.qmth.paper.library.common.annotation.ExcelImportTempleteVaild;
+import com.qmth.paper.library.common.annotation.ExcelNote;
+import com.qmth.paper.library.common.annotation.ExcelProperty;
+import com.qmth.paper.library.common.annotation.excelStyle.ExcelDataStyle;
+import com.qmth.paper.library.common.annotation.excelStyle.ExcelHeaderStyle;
+
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+
+/**
+ * @Description: 扫描员绑定excel
+ * @Author: CaoZixuan
+ * @Date: 2022-09-30
+ */
+@ExcelHeaderStyle
+@ExcelImportTempleteVaild(value = true)
+public class ScannerBindingDto implements Serializable {
+
+    @ExcelNote(value = "任务名称")
+    @ExcelProperty(name = "任务名称", width = 30, index = 1)
+    @ExcelDataStyle(lock = true)
+    @NotNull
+    private String scanTaskName;
+
+    @ExcelNote(value = "扫描员")
+    @ExcelProperty(name = "扫描员", width = 30, index = 2)
+    @NotNull
+    private String scannerName;
+
+    public String getScanTaskName() {
+        return scanTaskName;
+    }
+
+    public void setScanTaskName(String scanTaskName) {
+        this.scanTaskName = scanTaskName;
+    }
+
+    public String getScannerName() {
+        return scannerName;
+    }
+
+    public void setScannerName(String scannerName) {
+        this.scannerName = scannerName;
+    }
+}

+ 67 - 0
paper-library-business/src/main/java/com/qmth/paper/library/business/bean/result/PaperLibraryResult.java

@@ -0,0 +1,67 @@
+package com.qmth.paper.library.business.bean.result;
+
+import com.qmth.paper.library.business.entity.PaperLibrary;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+
+/**
+ * 数据检查
+ */
+public class PaperLibraryResult extends PaperLibrary implements Serializable {
+
+    @ApiModelProperty(value = "学生姓名")
+    private String studentName;
+
+    @ApiModelProperty(value = "学号")
+    private String studentCode;
+
+    @ApiModelProperty(value = "课程")
+    private String courseName;
+
+    @ApiModelProperty(value = "绑定图片数量")
+    private int bindCount;
+
+    @ApiModelProperty(value = "图片访问地址")
+    private String fileUrl;
+
+    public String getStudentName() {
+        return studentName;
+    }
+
+    public void setStudentName(String studentName) {
+        this.studentName = studentName;
+    }
+
+    public String getStudentCode() {
+        return studentCode;
+    }
+
+    public void setStudentCode(String studentCode) {
+        this.studentCode = studentCode;
+    }
+
+    public String getCourseName() {
+        return courseName;
+    }
+
+    public void setCourseName(String courseName) {
+        this.courseName = courseName;
+    }
+
+    public int getBindCount() {
+        return bindCount;
+    }
+
+    public void setBindCount(int bindCount) {
+        this.bindCount = bindCount;
+    }
+
+    public String getFileUrl() {
+        return fileUrl;
+    }
+
+    public void setFileUrl(String fileUrl) {
+        this.fileUrl = fileUrl;
+    }
+}

+ 78 - 0
paper-library-business/src/main/java/com/qmth/paper/library/business/bean/result/PaperScanTaskDetailResult.java

@@ -0,0 +1,78 @@
+package com.qmth.paper.library.business.bean.result;
+
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+
+/**
+ * @Description: 扫描任务
+ * @Author: CaoZixuan
+ * @Date: 2022-09-30
+ */
+public class PaperScanTaskDetailResult implements Serializable {
+    @ApiModelProperty(value = "姓名")
+    private String studentName;
+
+    @ApiModelProperty(value = "学号")
+    private String studentCode;
+
+    @ApiModelProperty(value = "课程")
+    private String courseName;
+
+    @ApiModelProperty(value = "任课老师")
+    private String teacherName;
+
+    @ApiModelProperty(value = "教学班")
+    private String teachClazzName;
+
+    @ApiModelProperty(value = "扫描张数")
+    private int scanCount;
+
+    public String getStudentName() {
+        return studentName;
+    }
+
+    public void setStudentName(String studentName) {
+        this.studentName = studentName;
+    }
+
+    public String getStudentCode() {
+        return studentCode;
+    }
+
+    public void setStudentCode(String studentCode) {
+        this.studentCode = studentCode;
+    }
+
+    public String getCourseName() {
+        return courseName;
+    }
+
+    public void setCourseName(String courseName) {
+        this.courseName = courseName;
+    }
+
+    public String getTeacherName() {
+        return teacherName;
+    }
+
+    public void setTeacherName(String teacherName) {
+        this.teacherName = teacherName;
+    }
+
+    public String getTeachClazzName() {
+        return teachClazzName;
+    }
+
+    public void setTeachClazzName(String teachClazzName) {
+        this.teachClazzName = teachClazzName;
+    }
+
+    public int getScanCount() {
+        return scanCount;
+    }
+
+    public void setScanCount(int scanCount) {
+        this.scanCount = scanCount;
+    }
+}

+ 49 - 0
paper-library-business/src/main/java/com/qmth/paper/library/business/bean/result/SelectResult.java

@@ -0,0 +1,49 @@
+package com.qmth.paper.library.business.bean.result;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+
+/**
+ * 新增/更新返回值
+ */
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class SelectResult implements Serializable {
+
+    @JsonSerialize(using = ToStringSerializer.class)
+    @ApiModelProperty(value = "id")
+    private Long id;
+
+    @ApiModelProperty(value = "code")
+    private String code;
+
+    @ApiModelProperty(value = "name")
+    private String name;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+}

+ 6 - 6
paper-library-business/src/main/java/com/qmth/paper/library/business/entity/PaperArchivesType.java

@@ -30,8 +30,8 @@ public class PaperArchivesType extends BaseEntity implements Serializable {
      * 类型名称
      */
     @NotBlank(message = "类型名称必填")
-    @TableField("archives_type_name")
-    private String archivesTypeName;
+    @TableField("name")
+    private String name;
 
     public Long getSchoolId() {
         return schoolId;
@@ -41,11 +41,11 @@ public class PaperArchivesType extends BaseEntity implements Serializable {
         this.schoolId = schoolId;
     }
 
-    public String getArchivesTypeName() {
-        return archivesTypeName;
+    public String getName() {
+        return name;
     }
 
-    public void setArchivesTypeName(String archivesTypeName) {
-        this.archivesTypeName = archivesTypeName;
+    public void setName(String name) {
+        this.name = name;
     }
 }

+ 26 - 0
paper-library-business/src/main/java/com/qmth/paper/library/business/entity/PaperLibrary.java

@@ -59,6 +59,16 @@ public class PaperLibrary extends BaseEntity implements Serializable {
     @TableField("path")
     private String path;
 
+    @ApiModelProperty(value = "数据检验员id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    @TableField("user_id")
+    private Long userId;
+
+    @ApiModelProperty(value = "扫描任务表id")
+    @JsonSerialize(using = ToStringSerializer.class)
+    @TableField("paper_scan_task_id")
+    private Long paperScanTaskId;
+
 
     @ApiModelProperty(value = "扫描任务详情表id")
     @JsonSerialize(using = ToStringSerializer.class)
@@ -127,6 +137,22 @@ public class PaperLibrary extends BaseEntity implements Serializable {
         this.path = path;
     }
 
+    public Long getUserId() {
+        return userId;
+    }
+
+    public void setUserId(Long userId) {
+        this.userId = userId;
+    }
+
+    public Long getPaperScanTaskId() {
+        return paperScanTaskId;
+    }
+
+    public void setPaperScanTaskId(Long paperScanTaskId) {
+        this.paperScanTaskId = paperScanTaskId;
+    }
+
     public Long getPaperScanTaskDetailId() {
         return paperScanTaskDetailId;
     }

+ 5 - 0
paper-library-business/src/main/java/com/qmth/paper/library/business/mapper/PaperArchivesMapper.java

@@ -4,9 +4,12 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.qmth.paper.library.business.bean.result.PaperArchivesResult;
+import com.qmth.paper.library.business.bean.result.SelectResult;
 import com.qmth.paper.library.business.entity.PaperArchives;
 import org.apache.ibatis.annotations.Param;
 
+import java.util.List;
+
 /**
  * <p>
  * 档案管理表 Mapper 接口
@@ -17,4 +20,6 @@ public interface PaperArchivesMapper extends BaseMapper<PaperArchives> {
     IPage<PaperArchivesResult> pageData(@Param("page") Page<PaperArchivesResult> page, @Param("semesterId") Long semesterId, @Param("managerOrgId") Long managerOrgId, @Param("archivesTypeId") Long archivesTypeId, @Param("archivesName") String archivesName);
 
     PaperArchives selectByArchivesName(@Param("schoolId") Long schoolId, @Param("archivesName") String archivesName);
+
+    List<SelectResult> queryManagerOrgs(@Param("schoolId") Long schoolId, @Param("semesterId") Long semesterId);
 }

+ 5 - 0
paper-library-business/src/main/java/com/qmth/paper/library/business/mapper/PaperArchivesTypeMapper.java

@@ -1,9 +1,12 @@
 package com.qmth.paper.library.business.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.qmth.paper.library.business.bean.result.SelectResult;
 import com.qmth.paper.library.business.entity.PaperArchivesType;
 import org.apache.ibatis.annotations.Param;
 
+import java.util.List;
+
 /**
  * <p>
  * 档案类型表 Mapper 接口
@@ -12,4 +15,6 @@ import org.apache.ibatis.annotations.Param;
 public interface PaperArchivesTypeMapper extends BaseMapper<PaperArchivesType> {
 
     PaperArchivesType selectByArchivesType(@Param("schoolId") Long schoolId, @Param("archivesTypeName") String archivesTypeName);
+
+    List<SelectResult> queryData(Long schoolId);
 }

+ 17 - 0
paper-library-business/src/main/java/com/qmth/paper/library/business/mapper/PaperLibraryMapper.java

@@ -1,7 +1,13 @@
 package com.qmth.paper.library.business.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.qmth.paper.library.business.bean.result.PaperLibraryResult;
 import com.qmth.paper.library.business.entity.PaperLibrary;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
 
 /**
  * <p>
@@ -10,4 +16,15 @@ import com.qmth.paper.library.business.entity.PaperLibrary;
  */
 public interface PaperLibraryMapper extends BaseMapper<PaperLibrary> {
 
+    IPage<PaperLibraryResult> pageUnbindData(@Param("page") Page<PaperLibraryResult> page, @Param("paperScanTaskId") Long paperScanTaskId);
+
+    int countUnbindData(@Param("paperScanTaskId") Long paperScanTaskId);
+
+    IPage<PaperLibraryResult> pageBindData(@Param("page") Page<PaperLibraryResult> page, @Param("paperScanTaskId") Long paperScanTaskId);
+
+    int countBindData(@Param("paperScanTaskId") Long paperScanTaskId);
+
+    List<PaperLibrary> listUnBindData(@Param("schoolId") Long schoolId);
+
+    List<PaperLibrary> selectBatchData(@Param("schoolId") Long schoolId, @Param("userId") Long userId);
 }

+ 16 - 0
paper-library-business/src/main/java/com/qmth/paper/library/business/mapper/PaperScanTaskMapper.java

@@ -3,10 +3,12 @@ package com.qmth.paper.library.business.mapper;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.qmth.paper.library.business.bean.result.PaperScanTaskDetailResult;
 import com.qmth.paper.library.business.bean.result.PaperScanTaskResult;
 import com.qmth.paper.library.business.entity.PaperScanTask;
 import com.qmth.paper.library.common.bean.result.BasicStudentResult;
 import org.apache.ibatis.annotations.Param;
+import org.springframework.context.annotation.Primary;
 
 import java.util.Set;
 
@@ -32,4 +34,18 @@ public interface PaperScanTaskMapper extends BaseMapper<PaperScanTask> {
                                                      @Param("courseName") String courseName,
                                                      @Param("teacherName") String teacherName,
                                                      @Param("orgIds") Set<Long> orgIds);
+
+    /**
+     * 根据扫描任务id分页查询扫描任务详情
+     *
+     * @param iPage           分页参数
+     * @param schoolId        学校id
+     * @param paperScanTaskId 扫描任务id
+     * @param orgIds          数据权限
+     * @return 分页查询结果
+     */
+    IPage<PaperScanTaskDetailResult> findPaperScanTaskDetailPageByTaskId(@Param("iPage") Page<PaperScanTaskDetailResult> iPage,
+                                                                         @Param("schoolId") Long schoolId,
+                                                                         @Param("paperScanTaskId") Long paperScanTaskId,
+                                                                         @Param("orgIds") Set<Long> orgIds);
 }

+ 5 - 0
paper-library-business/src/main/java/com/qmth/paper/library/business/service/PaperArchivesService.java

@@ -3,8 +3,11 @@ package com.qmth.paper.library.business.service;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.qmth.paper.library.business.bean.result.PaperArchivesResult;
+import com.qmth.paper.library.business.bean.result.SelectResult;
 import com.qmth.paper.library.business.entity.PaperArchives;
 
+import java.util.List;
+
 /**
  * <p>
  * 档案管理表 服务类
@@ -17,4 +20,6 @@ public interface PaperArchivesService extends IService<PaperArchives> {
     boolean saveData(PaperArchives paperArchives);
 
     boolean delete(Long id);
+
+    List<SelectResult> queryManagerOrgs(Long semesterId);
 }

+ 5 - 0
paper-library-business/src/main/java/com/qmth/paper/library/business/service/PaperArchivesTypeService.java

@@ -2,8 +2,11 @@ package com.qmth.paper.library.business.service;
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.qmth.paper.library.business.bean.result.SelectResult;
 import com.qmth.paper.library.business.entity.PaperArchivesType;
 
+import java.util.List;
+
 /**
  * <p>
  * 档案管理表 服务类
@@ -16,4 +19,6 @@ public interface PaperArchivesTypeService extends IService<PaperArchivesType> {
     boolean saveData(PaperArchivesType paperArchivesType);
 
     boolean delete(Long id);
+
+    List<SelectResult> queryData();
 }

+ 15 - 0
paper-library-business/src/main/java/com/qmth/paper/library/business/service/PaperLibraryService.java

@@ -1,8 +1,12 @@
 package com.qmth.paper.library.business.service;
 
+import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.qmth.paper.library.business.bean.result.PaperLibraryResult;
 import com.qmth.paper.library.business.entity.PaperLibrary;
 
+import java.util.List;
+
 /**
  * <p>
  * 图片库 服务类
@@ -10,4 +14,15 @@ import com.qmth.paper.library.business.entity.PaperLibrary;
  */
 public interface PaperLibraryService extends IService<PaperLibrary> {
 
+    IPage<PaperLibraryResult> pageUnbindData(Long paperScanTaskId, Integer pageNumber, Integer pageSize);
+
+    int countUnbindData(Long paperScanTaskId);
+
+    IPage<PaperLibraryResult> pageBindData(Long paperScanTaskId, Integer pageNumber, Integer pageSize);
+
+    boolean bind(Long paperLibraryId, Long paperScanTaskDetailId);
+
+    int countBindData(Long paperScanTaskId);
+
+    List<PaperLibraryResult> toBindPaper();
 }

+ 25 - 0
paper-library-business/src/main/java/com/qmth/paper/library/business/service/PaperScanTaskService.java

@@ -3,6 +3,7 @@ package com.qmth.paper.library.business.service;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.qmth.paper.library.business.bean.params.PaperScanTaskParam;
+import com.qmth.paper.library.business.bean.result.PaperScanTaskDetailResult;
 import com.qmth.paper.library.business.bean.result.PaperScanTaskResult;
 import com.qmth.paper.library.business.entity.PaperScanTask;
 import com.qmth.paper.library.common.entity.SysUser;
@@ -44,6 +45,30 @@ public interface PaperScanTaskService extends IService<PaperScanTask> {
      */
     void deletePaperScanTaskByIdList(List<Long> idList, SysUser requestUser);
 
+    /**
+     * 扫描员模板导出
+     *
+     * @param requestUser 请求的用户
+     */
+    void exportScanner(SysUser requestUser) throws Exception;
+
+    /**
+     * 根据扫描任务id分页查询扫描任务详情
+     *
+     * @param paperScanTaskId 扫描任务id
+     * @param requestUser     请求的用户
+     * @return 扫描任务详情分页结果
+     */
+    IPage<PaperScanTaskDetailResult> findPaperScanTaskDetailPageByTaskId(Long paperScanTaskId, int pageNumber, int pageSize, SysUser requestUser);
+
+    /**
+     * 清除扫描任务数据
+     *
+     * @param paperScanTaskId 扫描任务id
+     * @param requestUser     请求用户
+     */
+    void clearScanData(Long paperScanTaskId, SysUser requestUser);
+
 
     List<PaperScanTask> listByPaperArchivesId(Long id);
 }

+ 10 - 1
paper-library-business/src/main/java/com/qmth/paper/library/business/service/impl/PaperArchivesServiceImpl.java

@@ -1,9 +1,11 @@
 package com.qmth.paper.library.business.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.qmth.paper.library.business.bean.result.PaperArchivesResult;
+import com.qmth.paper.library.business.bean.result.SelectResult;
 import com.qmth.paper.library.business.entity.PaperArchives;
 import com.qmth.paper.library.business.entity.PaperScanTask;
 import com.qmth.paper.library.business.mapper.PaperArchivesMapper;
@@ -38,7 +40,6 @@ public class PaperArchivesServiceImpl extends ServiceImpl<PaperArchivesMapper, P
     public boolean saveData(PaperArchives paperArchives) {
         SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
         Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
-        // todo 生成档案编号
 
         PaperArchives archives = this.baseMapper.selectByArchivesName(schoolId, paperArchives.getArchivesName());
         if (archives != null) {
@@ -46,6 +47,8 @@ public class PaperArchivesServiceImpl extends ServiceImpl<PaperArchivesMapper, P
         }
         paperArchives.setId(SystemConstant.getDbUuid());
         paperArchives.setSchoolId(schoolId);
+        // 档案编号(时间戳)
+        paperArchives.setArchivesCode(String.valueOf(System.currentTimeMillis()));
         paperArchives.setCreateId(sysUser.getId());
         paperArchives.setCreateTime(System.currentTimeMillis());
         return this.save(paperArchives);
@@ -65,4 +68,10 @@ public class PaperArchivesServiceImpl extends ServiceImpl<PaperArchivesMapper, P
         return this.removeById(id);
     }
 
+    @Override
+    public List<SelectResult> queryManagerOrgs(Long semesterId) {
+        Long schoolId = SystemConstant.convertIdToLong(String.valueOf(ServletUtil.getRequestHeaderSchoolId()));
+        return this.baseMapper.queryManagerOrgs(schoolId, semesterId);
+    }
+
 }

+ 11 - 2
paper-library-business/src/main/java/com/qmth/paper/library/business/service/impl/PaperArchivesTypeServiceImpl.java

@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.qmth.paper.library.business.bean.result.SelectResult;
 import com.qmth.paper.library.business.entity.PaperArchivesType;
 import com.qmth.paper.library.business.mapper.PaperArchivesTypeMapper;
 import com.qmth.paper.library.business.service.PaperArchivesTypeService;
@@ -13,6 +14,8 @@ import com.qmth.paper.library.common.enums.ExceptionResultEnum;
 import com.qmth.paper.library.common.util.ServletUtil;
 import org.springframework.stereotype.Service;
 
+import java.util.List;
+
 /**
  * <p>
  * 档案类型表 服务实现类
@@ -33,7 +36,7 @@ public class PaperArchivesTypeServiceImpl extends ServiceImpl<PaperArchivesTypeM
         SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
         Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
 
-        PaperArchivesType archivesType = this.baseMapper.selectByArchivesType(schoolId, paperArchivesType.getArchivesTypeName());
+        PaperArchivesType archivesType = this.baseMapper.selectByArchivesType(schoolId, paperArchivesType.getName());
 
         // 新增
         if (paperArchivesType.getId() == null) {
@@ -53,7 +56,7 @@ public class PaperArchivesTypeServiceImpl extends ServiceImpl<PaperArchivesTypeM
             } else if (!paperArchivesType.getId().equals(archivesType.getId())) {
                 throw ExceptionResultEnum.ERROR.exception("类型名称已存在");
             }
-            archivesType.setArchivesTypeName(paperArchivesType.getArchivesTypeName());
+            archivesType.setName(paperArchivesType.getName());
             archivesType.setUpdateId(sysUser.getId());
             archivesType.setUpdateTime(System.currentTimeMillis());
             return this.updateById(archivesType);
@@ -68,4 +71,10 @@ public class PaperArchivesTypeServiceImpl extends ServiceImpl<PaperArchivesTypeM
         }
         return this.removeById(id);
     }
+
+    @Override
+    public List<SelectResult> queryData() {
+        Long schoolId = SystemConstant.convertIdToLong(String.valueOf(ServletUtil.getRequestHeaderSchoolId()));
+        return this.baseMapper.queryData(schoolId);
+    }
 }

+ 95 - 0
paper-library-business/src/main/java/com/qmth/paper/library/business/service/impl/PaperLibraryServiceImpl.java

@@ -1,11 +1,28 @@
 package com.qmth.paper.library.business.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.qmth.paper.library.business.bean.result.PaperLibraryResult;
 import com.qmth.paper.library.business.entity.PaperLibrary;
+import com.qmth.paper.library.business.entity.PaperScanTaskDetail;
 import com.qmth.paper.library.business.mapper.PaperLibraryMapper;
 import com.qmth.paper.library.business.service.PaperLibraryService;
+import com.qmth.paper.library.business.service.PaperScanTaskDetailService;
+import com.qmth.paper.library.common.contant.SystemConstant;
+import com.qmth.paper.library.common.entity.SysUser;
+import com.qmth.paper.library.common.enums.ExceptionResultEnum;
+import com.qmth.paper.library.common.lock.LockService;
+import com.qmth.paper.library.common.lock.LockType;
+import com.qmth.paper.library.common.util.ServletUtil;
+import org.springframework.beans.BeanUtils;
 import org.springframework.stereotype.Service;
 
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * <p>
  * 图片库 服务实现类
@@ -14,4 +31,82 @@ import org.springframework.stereotype.Service;
 @Service
 public class PaperLibraryServiceImpl extends ServiceImpl<PaperLibraryMapper, PaperLibrary> implements PaperLibraryService {
 
+    @Resource
+    PaperScanTaskDetailService paperScanTaskDetailService;
+
+    @Resource
+    LockService lockService;
+
+    @Override
+    public IPage<PaperLibraryResult> pageUnbindData(Long paperScanTaskId, Integer pageNumber, Integer pageSize) {
+        return this.baseMapper.pageUnbindData(new Page<>(pageNumber, pageSize), paperScanTaskId);
+    }
+
+    @Override
+    public int countUnbindData(Long paperScanTaskId) {
+        return this.baseMapper.countUnbindData(paperScanTaskId);
+    }
+
+    @Override
+    public IPage<PaperLibraryResult> pageBindData(Long paperScanTaskId, Integer pageNumber, Integer pageSize) {
+        return this.baseMapper.pageBindData(new Page<>(pageNumber, pageSize), paperScanTaskId);
+    }
+
+    @Override
+    public int countBindData(Long paperScanTaskId) {
+        return this.baseMapper.countBindData(paperScanTaskId);
+    }
+
+    @Override
+    public boolean bind(Long paperLibraryId, Long paperScanTaskDetailId) {
+        PaperScanTaskDetail paperScanTaskDetail = paperScanTaskDetailService.getById(paperScanTaskDetailId);
+        if (paperScanTaskDetail == null) {
+            throw ExceptionResultEnum.ERROR.exception("绑定对象有误,任务下无该考生,请刷新数据再试");
+        }
+        UpdateWrapper<PaperLibrary> updateWrapper = new UpdateWrapper<>();
+        updateWrapper.lambda().set(PaperLibrary::getPaperScanTaskDetailId, paperScanTaskDetailId)
+                .eq(PaperLibrary::getId, paperLibraryId);
+        return this.update(updateWrapper);
+    }
+
+    @Override
+    public List<PaperLibraryResult> toBindPaper() {
+        SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
+        Long schoolId = SystemConstant.convertIdToLong(String.valueOf(ServletUtil.getRequestHeaderSchoolId()));
+
+        // 查询下一个待绑定任务
+        List<PaperLibrary> waitPaperLibraryList = this.baseMapper.selectBatchData(schoolId, sysUser.getId());
+        if (waitPaperLibraryList.isEmpty()) {
+            waitPaperLibraryList = createBindData(sysUser.getId(), schoolId);
+        }
+
+        List<PaperLibraryResult> paperLibraryResultList = new ArrayList<>();
+        if (!waitPaperLibraryList.isEmpty()) {
+            for (PaperLibrary paperLibrary : waitPaperLibraryList) {
+                PaperLibraryResult paperLibraryResult = new PaperLibraryResult();
+                BeanUtils.copyProperties(paperLibrary, paperLibraryResult);
+                // todo 图片地址
+                paperLibraryResult.setFileUrl("");
+            }
+        }
+        return paperLibraryResultList;
+    }
+
+    private List<PaperLibrary> createBindData(Long userId, Long schoolId) {
+        try {
+            lockService.waitlock(LockType.BIND_PAPER_TASK, schoolId);
+            List<PaperLibrary> paperLibraryList = this.baseMapper.listUnBindData(schoolId);
+            if (!paperLibraryList.isEmpty()) {
+                paperLibraryList.forEach(m -> m.setUserId(userId));
+                this.updateBatchById(paperLibraryList);
+            }
+            return paperLibraryList;
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            lockService.unlock(LockType.BIND_PAPER_TASK, schoolId);
+        }
+        return new ArrayList<>();
+    }
+
 }

+ 79 - 1
paper-library-business/src/main/java/com/qmth/paper/library/business/service/impl/PaperScanTaskServiceImpl.java

@@ -4,7 +4,9 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.qmth.paper.library.business.bean.dto.excel.ScannerBindingDto;
 import com.qmth.paper.library.business.bean.params.PaperScanTaskParam;
+import com.qmth.paper.library.business.bean.result.PaperScanTaskDetailResult;
 import com.qmth.paper.library.business.bean.result.PaperScanTaskResult;
 import com.qmth.paper.library.business.entity.PaperLibrary;
 import com.qmth.paper.library.business.entity.PaperScanTask;
@@ -16,6 +18,8 @@ import com.qmth.paper.library.common.contant.SystemConstant;
 import com.qmth.paper.library.common.entity.SysUser;
 import com.qmth.paper.library.common.enums.ExceptionResultEnum;
 import com.qmth.paper.library.common.service.SysUserService;
+import com.qmth.paper.library.common.util.ExcelUtil;
+import com.qmth.paper.library.common.util.ServletUtil;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -23,6 +27,7 @@ import javax.annotation.Resource;
 import java.util.List;
 import java.util.Objects;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 /**
  * <p>
@@ -112,7 +117,7 @@ public class PaperScanTaskServiceImpl extends ServiceImpl<PaperScanTaskMapper, P
             List<PaperLibrary> paperLibraryList = paperLibraryService.list(new QueryWrapper<PaperLibrary>()
                     .lambda()
                     .eq(PaperLibrary::getSchoolId, schoolId)
-                    .in(PaperLibrary::getPaperScanTaskDetailId, idList));
+                    .in(PaperLibrary::getPaperScanTaskId, idList));
 
             if (paperLibraryList.size() > 0) {
                 // 所选择要删除的扫描任务中出现了已经开始扫描的,不能被删除
@@ -131,6 +136,79 @@ public class PaperScanTaskServiceImpl extends ServiceImpl<PaperScanTaskMapper, P
         this.removeByIds(idList);
     }
 
+    @Override
+    public void exportScanner(SysUser requestUser) throws Exception {
+        Long schoolId = requestUser.getSchoolId();
+        // 已经开始扫描的任务id
+        List<Long> alreadyScannedTaskIdList = paperLibraryService.list(new QueryWrapper<PaperLibrary>().lambda()
+                        .eq(PaperLibrary::getSchoolId, schoolId))
+                .stream()
+                .map(PaperLibrary::getPaperScanTaskId)
+                .collect(Collectors.toList());
+
+        QueryWrapper<PaperScanTask> paperScanTaskQueryWrapper = new QueryWrapper<>();
+        paperScanTaskQueryWrapper.lambda().eq(PaperScanTask::getSchoolId, schoolId);
+        if (alreadyScannedTaskIdList.size() > 0) {
+            paperScanTaskQueryWrapper.lambda().notIn(PaperScanTask::getId, alreadyScannedTaskIdList);
+        }
+        List<PaperScanTask> paperScanTaskList = this.list(paperScanTaskQueryWrapper);
+        List<ScannerBindingDto> scannerBindingDtoList = paperScanTaskList.stream().flatMap(e -> {
+            String scanTaskName = e.getScanTaskName();
+            String scannerName = "";
+            Long scanUserId = e.getScanUserId();
+            if (SystemConstant.longNotNull(scanUserId)) {
+                SysUser scanner = sysUserService.getById(scanUserId);
+                if (Objects.isNull(scanner)) {
+                    throw ExceptionResultEnum.ERROR.exception("未找到扫描员");
+                }
+                scannerName = scanner.getRealName();
+            }
+            ScannerBindingDto scannerBindingDto = new ScannerBindingDto();
+            scannerBindingDto.setScannerName(scannerName);
+            scannerBindingDto.setScanTaskName(scanTaskName);
+            return Stream.of(scannerBindingDto);
+        }).collect(Collectors.toList());
+        ExcelUtil.excelExport("绑定扫描员导入模板", ScannerBindingDto.class, scannerBindingDtoList, ServletUtil.getResponse());
+    }
+
+    @Override
+    public IPage<PaperScanTaskDetailResult> findPaperScanTaskDetailPageByTaskId(Long paperScanTaskId, int pageNumber, int pageSize, SysUser requestUser) {
+        Long schoolId = requestUser.getSchoolId();
+        return this.baseMapper.findPaperScanTaskDetailPageByTaskId(new Page<>(pageNumber, pageSize), paperScanTaskId, schoolId, null);
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void clearScanData(Long paperScanTaskId, SysUser requestUser) {
+        Long schoolId = requestUser.getSchoolId();
+
+        // 扫描任务校验
+        PaperScanTask paperScanTask = this.getById(paperScanTaskId);
+        if (Objects.isNull(paperScanTask)) {
+            throw ExceptionResultEnum.ERROR.exception("扫描任务不存在");
+        }
+        // 要删除的图片数据集合
+        List<PaperLibrary> willDeletePaperLibraryList = paperLibraryService.list(new QueryWrapper<PaperLibrary>()
+                .lambda()
+                .eq(PaperLibrary::getSchoolId, schoolId)
+                .eq(PaperLibrary::getPaperScanTaskId, paperScanTaskId));
+
+        if (willDeletePaperLibraryList.size() > 0) {
+            // 已绑定的扫描任务校验
+            List<PaperLibrary> cantDeleteList = willDeletePaperLibraryList
+                    .stream()
+                    .filter(e -> SystemConstant.longNotNull(e.getPaperScanTaskDetailId()))
+                    .collect(Collectors.toList());
+
+            if (cantDeleteList.size() > 0) {
+                throw ExceptionResultEnum.ERROR.exception("所选的扫描任务已经进行了数据检验,不能删除");
+            }
+
+            // 删除该任务扫描的的数据
+            paperLibraryService.removeByIds(willDeletePaperLibraryList);
+        }
+    }
+
     @Override
     public List<PaperScanTask> listByPaperArchivesId(Long paperArchivesId) {
         QueryWrapper<PaperScanTask> queryWrapper = new QueryWrapper<>();

+ 72 - 0
paper-library-business/src/main/java/com/qmth/paper/library/business/templete/execute/AsyncPaperScanTaskImportService.java

@@ -0,0 +1,72 @@
+package com.qmth.paper.library.business.templete.execute;
+
+import cn.hutool.core.date.DateUtil;
+import com.qmth.boot.api.exception.ApiException;
+import com.qmth.paper.library.business.templete.importData.AsyncImportTaskTemplete;
+import com.qmth.paper.library.business.templete.service.TaskLogicService;
+import com.qmth.paper.library.common.contant.SpringContextHolder;
+import com.qmth.paper.library.common.contant.SystemConstant;
+import com.qmth.paper.library.common.entity.TBTask;
+import com.qmth.paper.library.common.enums.TaskResultEnum;
+import com.qmth.paper.library.common.enums.TaskStatusEnum;
+import com.qmth.paper.library.common.service.TBTaskService;
+import com.qmth.paper.library.common.util.Result;
+import com.qmth.paper.library.common.util.ResultUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.text.MessageFormat;
+import java.util.Date;
+import java.util.Map;
+import java.util.StringJoiner;
+
+/**
+ * @Description: 扫描任务批量导入
+ * @Author: CaoZixuan
+ * @Date: 2022-09-29
+ */
+@Service
+public class AsyncPaperScanTaskImportService extends AsyncImportTaskTemplete {
+
+    private final static Logger log = LoggerFactory.getLogger(AsyncPaperScanTaskImportService.class);
+
+    public static final String SCAN_TASK_TITLE = "扫描任务";
+
+    @Override
+    public Result importTask(Map<String, Object> map) throws IOException, Exception {
+        TBTask tbTask = (TBTask) map.get(SystemConstant.TASK);
+        InputStream inputStream = super.getUploadFileInputStream(tbTask);
+        map.put("inputStream", inputStream);
+
+        StringJoiner stringJoinerSummary = new StringJoiner("\n")
+                .add(MessageFormat.format("{0}{1}{2}", DateUtil.format(new Date(), SystemConstant.DEFAULT_DATE_PATTERN), BEGIN_TITLE, SCAN_TASK_TITLE));
+        tbTask.setStatus(TaskStatusEnum.RUNNING);
+        TBTaskService tbTaskService = SpringContextHolder.getBean(TBTaskService.class);
+        tbTaskService.updateById(tbTask);
+
+        try {
+            TaskLogicService taskLogicService = SpringContextHolder.getBean(TaskLogicService.class);
+
+            // 执行导入扫描任务数据
+            Map<String, Object> result = taskLogicService.executeImportPaperScanTaskDetailLogic(map);
+            stringJoinerSummary.add(MessageFormat.format("{0}{1}{2}{3}", DateUtil.format(new Date(), SystemConstant.DEFAULT_DATE_PATTERN), FINISH_TITLE, Long.valueOf(String.valueOf(result.get("dataCount"))), FINISH_SIZE));
+            tbTask.setResult(TaskResultEnum.SUCCESS);
+        } catch (Exception e) {
+            log.error(SystemConstant.LOG_ERROR, e);
+            stringJoinerSummary.add(MessageFormat.format("{0}{1}{2}{3}", DateUtil.format(new Date(), SystemConstant.DEFAULT_DATE_PATTERN), EXCEPTION_TITLE, EXCEPTION_DATA, e.getMessage()));
+            tbTask.setResult(TaskResultEnum.ERROR);
+            if (e instanceof ApiException) {
+                ResultUtil.error((ApiException) e, e.getMessage());
+            } else {
+                ResultUtil.error(e.getMessage());
+            }
+        } finally {//生成txt文件
+            tbTask.setSummary(stringJoinerSummary.toString());
+            super.createTxt(tbTask);
+        }
+        return ResultUtil.ok(map);
+    }
+}

+ 9 - 0
paper-library-business/src/main/java/com/qmth/paper/library/business/templete/service/TaskLogicService.java

@@ -20,4 +20,13 @@ public interface TaskLogicService {
      */
     Map<String, Object> executeImportSysOrgLogic(Map<String, Object> map) throws Exception;
 
+    /**
+     * 处理导入扫描任务详情
+     *
+     * @param map 数据源
+     * @return 结果
+     * @throws Exception 异常
+     */
+    Map<String, Object> executeImportPaperScanTaskDetailLogic(Map<String, Object> map) throws Exception;
+
 }

+ 192 - 5
paper-library-business/src/main/java/com/qmth/paper/library/business/templete/service/impl/TaskLogicServiceImpl.java

@@ -1,11 +1,23 @@
 package com.qmth.paper.library.business.templete.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.google.common.collect.Lists;
+import com.qmth.paper.library.business.bean.dto.excel.PaperScanTaskImportDto;
+import com.qmth.paper.library.business.bean.params.PaperScanTaskParam;
+import com.qmth.paper.library.business.entity.PaperArchives;
+import com.qmth.paper.library.business.entity.PaperScanTask;
+import com.qmth.paper.library.business.entity.PaperScanTaskDetail;
+import com.qmth.paper.library.business.service.PaperArchivesService;
+import com.qmth.paper.library.business.service.PaperScanTaskDetailService;
+import com.qmth.paper.library.business.service.PaperScanTaskService;
 import com.qmth.paper.library.business.templete.service.TaskLogicService;
 import com.qmth.paper.library.common.bean.dto.excel.DescribeImportDto;
 import com.qmth.paper.library.common.bean.dto.excel.SysOrgImportDto;
 import com.qmth.paper.library.common.contant.SystemConstant;
+import com.qmth.paper.library.common.entity.BasicStudent;
 import com.qmth.paper.library.common.entity.SysUser;
+import com.qmth.paper.library.common.enums.ExceptionResultEnum;
+import com.qmth.paper.library.common.service.BasicStudentService;
 import com.qmth.paper.library.common.service.SysOrgService;
 import com.qmth.paper.library.common.util.ExcelUtil;
 import org.slf4j.Logger;
@@ -18,11 +30,9 @@ import org.springframework.util.LinkedMultiValueMap;
 import javax.annotation.Resource;
 import java.io.IOException;
 import java.io.InputStream;
-import java.security.NoSuchAlgorithmException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 /**
  * @Description: 任务处理逻辑impl
@@ -37,11 +47,19 @@ public class TaskLogicServiceImpl implements TaskLogicService {
 
     @Resource
     private SysOrgService sysOrgService;
+    @Resource
+    private PaperArchivesService paperArchivesService;
+    @Resource
+    private PaperScanTaskService paperScanTaskService;
+    @Resource
+    private PaperScanTaskDetailService paperScanTaskDetailService;
+    @Resource
+    private BasicStudentService basicStudentService;
 
 
     @Transactional
     @Override
-    public Map<String, Object> executeImportSysOrgLogic(Map<String, Object> map) throws IOException, NoSuchFieldException, NoSuchAlgorithmException {
+    public Map<String, Object> executeImportSysOrgLogic(Map<String, Object> map) throws IOException, NoSuchFieldException {
         InputStream inputStream = (InputStream) map.get("inputStream");
         List<LinkedMultiValueMap<Integer, Object>> finalList = ExcelUtil.excelReader(inputStream, Lists.newArrayList(SysOrgImportDto.class, DescribeImportDto.class), (finalExcelList, finalColumnNameList, finalExcelErrorList) -> finalExcelList);
         List<String> orgInfoList = new ArrayList<>();
@@ -71,4 +89,173 @@ public class TaskLogicServiceImpl implements TaskLogicService {
         }
         return map;
     }
+
+    @Transactional
+    @Override
+    public Map<String, Object> executeImportPaperScanTaskDetailLogic(Map<String, Object> map) throws Exception {
+        SysUser requestUser = (SysUser) map.get(SystemConstant.SYS_USER);
+        Long schoolId = requestUser.getSchoolId();
+        InputStream inputStream = (InputStream) map.get("inputStream");
+
+        List<LinkedMultiValueMap<Integer, Object>> finalList = ExcelUtil.excelReader(inputStream, Lists.newArrayList(PaperScanTaskImportDto.class, DescribeImportDto.class), (finalExcelList, finalColumnNameList, finalExcelErrorList) -> finalExcelList);
+        List<PaperScanTaskImportDto> datasource = new ArrayList<>();
+        for (int i = 0; i < finalList.size(); i++) {
+            LinkedMultiValueMap<Integer, Object> excelMap = finalList.get(i);
+            List<Object> paperScanTaskImportDtoList = excelMap.get(i);
+            assert paperScanTaskImportDtoList != null;
+            if (paperScanTaskImportDtoList.get(0) instanceof DescribeImportDto) {
+                continue;
+            }
+            map.put("dataCount", paperScanTaskImportDtoList.size());
+            //  处理机构
+            if (paperScanTaskImportDtoList.get(0) instanceof PaperScanTaskImportDto) {
+                datasource = paperScanTaskImportDtoList.stream().map(e -> {
+                    PaperScanTaskImportDto paperScanTaskImportDto = new PaperScanTaskImportDto();
+                    BeanUtils.copyProperties(e, paperScanTaskImportDto);
+                    return paperScanTaskImportDto;
+                }).collect(Collectors.toList());
+            }
+        }
+        if (datasource.size() > 0) {
+            // 选择的扫描档案id
+            Long paperArchivesId = SystemConstant.convertIdToLong(String.valueOf(map.get("paperArchivesId")));
+            List<Map<String, String>> archivesCheckMapList = datasource.stream().flatMap(e -> {
+                Map<String, String> checkMap = new HashMap<>();
+                checkMap.put("archivesName", e.getArchivesName());
+                checkMap.put("archivesCode", e.getArchivesCode());
+                return Stream.of(checkMap);
+            }).distinct().collect(Collectors.toList());
+
+            if (archivesCheckMapList.size() != 1) {
+                throw ExceptionResultEnum.ERROR.exception("excel中的档案信息异常(导入扫描任务数据必须是一个档案下的)");
+            }
+            Map<String, String> archivesCheckMap = archivesCheckMapList.get(0);
+            String archivesName = archivesCheckMap.get("archivesName");
+            String archivesCode = archivesCheckMap.get("archivesCode");
+
+            // 判断选择的档案和导入的是同一个
+            PaperArchives paperArchives = paperArchivesService.getOne(new QueryWrapper<PaperArchives>()
+                    .lambda()
+                    .eq(PaperArchives::getId, paperArchivesId)
+                    .eq(PaperArchives::getArchivesCode, archivesCode)
+                    .eq(PaperArchives::getArchivesName, archivesName));
+            if (Objects.nonNull(paperArchives)) {
+                throw ExceptionResultEnum.ERROR.exception("excel中的档案信息和选择的档案不符");
+            }
+
+            // 归纳 - 扫描任务集合
+            // 扫描任务唯一信息
+            Map<String, PaperScanTask> paperScanTaskMap = new HashMap<>();
+            for (PaperScanTaskImportDto paperScanTaskImportDto : datasource) {
+                String scanTaskName = paperScanTaskImportDto.getScanTaskName();
+                String courseName = paperScanTaskImportDto.getCourseName();
+                String teacherName = paperScanTaskImportDto.getTeacherName();
+                String teachClazzName = paperScanTaskImportDto.getTeachClazzName();
+
+                if (paperScanTaskMap.containsKey(scanTaskName)) {
+                    // 如果试卷任务map中包含该任务名称 - 检验其他信息是否一致(课程,任课教师,教学班 为空的不检验)
+                    PaperScanTask v = paperScanTaskMap.get(scanTaskName);
+                    String vCourseName = v.getCourseName();
+                    String vTeacherName = v.getTeacherName();
+                    String vTeachClazzName = v.getTeachClazzName();
+
+                    // 同一任务课程名称检验
+                    if (!SystemConstant.strNotNull(vCourseName)) {
+                        v.setCourseName(courseName);
+                    } else if (SystemConstant.strNotNull(courseName) && !vCourseName.equals(courseName)) {
+                        throw ExceptionResultEnum.ERROR.exception("excel数据异常:导入的任务【" + scanTaskName + "】存在不同的课程名称【" + vCourseName + "," + courseName + "】");
+                    }
+
+                    // 同一任务任课教师检验
+                    if (!SystemConstant.strNotNull(vTeacherName)) {
+                        v.setTeacherName(teacherName);
+                    } else if (SystemConstant.strNotNull(teacherName) && !vTeacherName.equals(teacherName)) {
+                        throw ExceptionResultEnum.ERROR.exception("excel数据异常:导入的任务【" + scanTaskName + "】存在不同的任课教师【" + vTeacherName + "," + teacherName + "】");
+                    }
+
+                    // 同一任务教学班检验
+                    if (!SystemConstant.strNotNull(vTeachClazzName)) {
+                        v.setTeachClazzName(teachClazzName);
+                    } else if (SystemConstant.strNotNull(teachClazzName) && !vTeachClazzName.equals(teachClazzName)) {
+                        throw ExceptionResultEnum.ERROR.exception("excel数据异常:导入的任务【" + scanTaskName + "】存在不同的教学班【" + vTeachClazzName + "," + teachClazzName + "】");
+                    }
+                } else {
+                    // 没包含直接put
+                    PaperScanTask v = new PaperScanTask();
+                    v.setScanTaskName(scanTaskName);
+                    v.setCourseName(courseName);
+                    v.setTeacherName(teacherName);
+                    v.setTeachClazzName(teachClazzName);
+                    paperScanTaskMap.put(scanTaskName, v);
+                }
+            }
+
+            // 创建扫描任务并把编辑后的任务id放回map中
+            List<Long> paperScanTaskIdList = new ArrayList<>();
+            for (String k : paperScanTaskMap.keySet()) {
+                PaperScanTask v = paperScanTaskMap.get(k);
+                PaperScanTask db = paperScanTaskService.getOne(new QueryWrapper<PaperScanTask>()
+                        .lambda()
+                        .eq(PaperScanTask::getSchoolId, requestUser.getSchoolId())
+                        .eq(PaperScanTask::getScanTaskName, k)
+                        .eq(PaperScanTask::getPaperArchivesId, paperArchivesId));
+                PaperScanTaskParam paperScanTaskParam = new PaperScanTaskParam();
+                if (Objects.nonNull(db)) {
+                    // 编辑
+                    paperScanTaskParam.setPaperScanTaskId(db.getId());
+                    paperScanTaskIdList.add(db.getId());
+                }
+                paperScanTaskParam.setPaperArchivesId(paperArchivesId);
+                paperScanTaskParam.setCourseName(v.getCourseName());
+                paperScanTaskParam.setTeacherName(v.getTeacherName());
+                paperScanTaskParam.setTeachClazzName(v.getTeachClazzName());
+                paperScanTaskParam.setScanTaskName(k);
+                Long paperScanTaskId = paperScanTaskService.editPaperScanTask(paperScanTaskParam, requestUser);
+                v.setId(paperScanTaskId);
+            }
+
+            // 归纳 - 扫描任务详情
+            // 上面编辑的任务绑定的扫描详情集合
+            List<PaperScanTaskDetail> paperScanTaskDetailDbList = paperScanTaskDetailService.list(new QueryWrapper<PaperScanTaskDetail>()
+                    .lambda()
+                    .in(PaperScanTaskDetail::getPaperScanTaskId, paperScanTaskIdList)
+                    .eq(PaperScanTaskDetail::getSchoolId, schoolId));
+            // 学生基础数据集合
+            List<BasicStudent> basicStudentDbList = basicStudentService.list(new QueryWrapper<BasicStudent>().lambda().eq(BasicStudent::getSchoolId, schoolId));
+
+            List<PaperScanTaskDetail> paperScanTaskDetailList = datasource.stream().flatMap(e -> {
+
+                String scanTaskName = e.getScanTaskName();
+                PaperScanTask paperScanTask = paperScanTaskMap.get(scanTaskName);
+                if (Objects.isNull(paperScanTask)) {
+                    throw ExceptionResultEnum.ERROR.exception("扫描任务数据异常");
+                }
+                Long paperScanTaskId = paperScanTask.getId();
+
+                String studentCode = e.getStudentCode();
+                List<BasicStudent> studentList = basicStudentDbList.stream().filter(s -> s.getStudentCode().equals(studentCode)).collect(Collectors.toList());
+                if (studentList.size() != 1) {
+                    throw ExceptionResultEnum.ERROR.exception("学号为【" + studentCode + "】的学生不存在或异常");
+                }
+                // 目标学生
+                BasicStudent targetStudent = studentList.get(0);
+                Long studentId = targetStudent.getId();
+
+                PaperScanTaskDetail paperScanTaskDetail = new PaperScanTaskDetail();
+                List<PaperScanTaskDetail> paperScanTaskDetailCellList = paperScanTaskDetailDbList.stream()
+                        .filter(d -> d.getPaperScanTaskId().equals(paperScanTaskId) && d.getStudentId().equals(studentId) && d.getSchoolId().equals(schoolId))
+                        .collect(Collectors.toList());
+                if (paperScanTaskDetailCellList.size() == 1) {
+                    paperScanTaskDetail.setId(paperScanTaskDetailCellList.get(0).getId());
+                }
+                paperScanTaskDetail.setPaperScanTaskId(paperScanTaskId);
+                paperScanTaskDetail.setSchoolId(schoolId);
+                paperScanTaskDetail.setStudentId(studentId);
+                return Stream.of(paperScanTaskDetail);
+            }).collect(Collectors.toList());
+
+            paperScanTaskDetailService.saveOrUpdateBatch(paperScanTaskDetailList);
+        }
+        return map;
+    }
 }

+ 15 - 0
paper-library-business/src/main/resources/mapper/PaperArchivesMapper.xml

@@ -73,4 +73,19 @@
             and archives_name = #{archivesName}
         </where>
     </select>
+    <select id="queryManagerOrgs" resultType="com.qmth.paper.library.business.bean.result.SelectResult">
+        SELECT
+            distinct pa.manager_id id, so.name
+        FROM
+            paper_archives pa
+                LEFT JOIN
+            sys_org so ON pa.school_id = so.school_id
+                AND pa.manager_org_id = so.id
+        <where>
+            and pa.school_id = #{schoolId}
+            <if test="semesterId != null">
+                and pa.semester_id = #{semesterId}
+            </if>
+        </where>
+    </select>
 </mapper>

+ 5 - 2
paper-library-business/src/main/resources/mapper/PaperArchivesTypeMapper.xml

@@ -5,7 +5,7 @@
     <resultMap id="BaseResultMap" type="com.qmth.paper.library.business.entity.PaperArchivesType">
         <result column="id" property="id"/>
         <result column="school_id" property="schoolId"/>
-        <result column="archives_type_name" property="archivesTypeName"/>
+        <result column="name" property="name"/>
         <result column="create_id" property="createId"/>
         <result column="create_time" property="createTime"/>
         <result column="update_id" property="updateId"/>
@@ -14,7 +14,7 @@
 
     <!-- 通用查询结果列 -->
     <sql id="Base_Column_List">
-       select id, school_id, archives_type_name, create_id, create_time, update_id, update_time from paper_archives_type
+       select id, school_id, name, create_id, create_time, update_id, update_time from paper_archives_type
     </sql>
 
     <select id="selectByArchivesType" resultMap="BaseResultMap">
@@ -24,4 +24,7 @@
             and archives_type = #{archivesTypeName}
         </where>
     </select>
+    <select id="queryData" resultType="com.qmth.paper.library.business.bean.result.SelectResult">
+        select id, name from paper_archives_type
+    </select>
 </mapper>

+ 109 - 0
paper-library-business/src/main/resources/mapper/PaperLibraryMapper.xml

@@ -1,4 +1,113 @@
 <?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.paper.library.business.mapper.PaperLibraryMapper">
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.qmth.paper.library.business.entity.PaperLibrary">
+        <result column="id" property="id"/>
+        <result column="school_id" property="schoolId"/>
+        <result column="org_id" property="orgId"/>
+        <result column="name" property="name"/>
+        <result column="type" property="type"/>
+        <result column="size" property="size"/>
+        <result column="md5" property="md5"/>
+        <result column="path" property="path"/>
+        <result column="paper_scan_task_id" property="paperScanTaskId"/>
+        <result column="paper_scan_task_detail_id" property="paperScanTaskDetailId"/>
+        <result column="sequence" property="sequence"/>
+        <result column="create_id" property="createId"/>
+        <result column="create_time" property="createTime"/>
+        <result column="update_id" property="updateId"/>
+        <result column="update_time" property="updateTime"/>
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        select id, school_id, org_id, `name`,`type`, `size`, `md5`, `path`, paper_scan_task_id,paper_scan_task_detail_id, sequence,create_id, create_time, update_id, update_time from paper_library
+    </sql>
+
+    <select id="pageUnbindData" resultMap="BaseResultMap">
+        <include refid="Base_Column_List"></include>
+        <where>
+            paper_scan_task_detail_id is null
+            <if test="paperScanTaskId != null">
+                and paper_scan_task_id = #{paperScanTaskId}
+            </if>
+        </where>
+    </select>
+    <select id="countUnbindData" resultType="java.lang.Integer">
+        select count(1) from paper_library
+        <where>
+            paper_scan_task_detail_id is null
+            <if test="paperScanTaskId != null">
+                and paper_scan_task_id = #{paperScanTaskId}
+            </if>
+        </where>
+    </select>
+    <select id="pageBindData" resultType="com.qmth.paper.library.business.bean.result.PaperLibraryResult">
+        SELECT
+            pstd.paper_scan_task_id paperScanTaskId,
+            bs.student_name studentName,
+            bs.student_code studentCode,
+            pst.course_name courseName,
+            pst.create_time createTime,
+            pl.bind_count bindCount
+        FROM
+            (SELECT
+                 school_id, paper_scan_task_detail_id, COUNT(1) bind_count
+             FROM
+                 paper_library
+             WHERE
+                 paper_scan_task_detail_id IS NOT NULL) pl
+                JOIN
+            paper_scan_task_detail pstd ON pl.school_id = pstd.school_id
+                AND pl.paper_scan_task_detail_id = pstd.id
+                LEFT JOIN
+            paper_scan_task pst ON pstd.school_id = pst.school_id
+                AND pstd.paper_scan_task_id = pst.id
+                LEFT JOIN
+            basic_student bs ON pstd.school_id = bs.school_id
+                AND pstd.student_id = bs.id
+        <where>
+            <if test="paperScanTaskId != null">
+                and pstd.paper_scan_task_id = #{paperScanTaskId}
+            </if>
+        </where>
+    </select>
+    <select id="countBindData" resultType="java.lang.Integer">
+        SELECT
+            COUNT(1)
+        FROM
+            (SELECT
+                 school_id, paper_scan_task_detail_id, COUNT(1) bind_count
+             FROM
+                 paper_library
+             WHERE
+                 paper_scan_task_detail_id IS NOT NULL
+             GROUP BY school_id , paper_scan_task_detail_id) pl
+                JOIN
+            paper_scan_task_detail pstd ON pl.school_id = pstd.school_id
+                AND pl.paper_scan_task_detail_id = pstd.id
+        <where>
+            <if test="paperScanTaskId != null">
+                AND pstd.paper_scan_task_id = #{paperScanTaskId}
+            </if>
+        </where>
+    </select>
+    <select id="listUnBindData" resultMap="BaseResultMap">
+        <include refid="Base_Column_List"></include>
+        <where>
+            school_id = #{schoolId}
+            AND user_id is null limit 10
+        </where>
+        ORDER BY paper_scan_task_id, crate_time
+    </select>
+    <select id="selectBatchData" resultMap="BaseResultMap">
+        <include refid="Base_Column_List"></include>
+        <where>
+            school_id = #{schoolId}
+            AND user_id = #{userId}
+            AND paper_scan_task_detail_id is null
+            limit 10
+        </where>
+    </select>
 </mapper>

+ 32 - 0
paper-library-business/src/main/resources/mapper/PaperScanTaskMapper.xml

@@ -42,4 +42,36 @@
             </if>
         </where>
     </select>
+
+    <select id="findPaperScanTaskDetailPageByTaskId"
+            resultType="com.qmth.paper.library.business.bean.result.PaperScanTaskDetailResult">
+        SELECT
+            bs.student_name AS studentName,
+            bs.student_code AS studentCode,
+            pst.course_name AS courseName,
+            pst.teacher_name AS teacherName,
+            pst.teach_clazz_name AS teachClazzName,
+            pl.scan_count AS scanCount
+        FROM
+            paper_scan_task pst
+                LEFT JOIN
+            paper_scan_task_detail pstd ON pst.id = pstd.paper_scan_task_id
+                LEFT JOIN
+            basic_student bs ON bs.id = pstd.student_id
+                LEFT JOIN
+            (SELECT
+                 COUNT(*) AS scan_count, paper_scan_task_detail_id
+             FROM
+                 paper_library
+             GROUP BY paper_scan_task_detail_id) pl ON pl.paper_scan_task_detail_id = pstd.id
+        <where>
+            <if test="schoolId != null and schoolId != ''">
+                AND pst.school_id = #{schoolId}
+            </if>
+            <if test="paperScanTaskId != null and paperScanTaskId != ''">
+                AND pst.id = #{paperScanTaskId}
+            </if>
+        </where>
+        ORDER BY scanCount desc
+    </select>
 </mapper>

+ 35 - 1
paper-library-common/src/main/java/com/qmth/paper/library/common/enums/TaskTypeEnum.java

@@ -12,7 +12,41 @@ import java.util.Objects;
 public enum TaskTypeEnum {
     ORG_IMPORT("机构导入"),
 
-    USER_IMPORT("用户导入");
+    USER_IMPORT("用户导入"),
+
+    STUDENT_IMPORT("学生导入"),
+
+    COURSE_IMPORT("课程导入"),
+
+    CLAZZ_IMPORT("班级导入"),
+
+    QUESTION_MISSION_BATCH_CREATE("批量新建命题任务"),
+
+    SAMPLE_EXPORT("导出审核样本"),
+
+    EXAMINATION_IMPORT("考务数据导入"),
+
+    EXAMINATION_EXPORT("考务数据导出"),
+
+    PRINT_PDF_DOWNLOAD("批量下载pdf"),
+
+    PAPER_AND_CARD_PDF_DOWNLOAD("卷库查询管理试卷、空白题卡批量下载pdf"),
+
+    CREATE_PDF("生成pdf"),
+
+    DATA_CALCULATE("数据计算"),
+
+    CREATE_TASK_PRINT("发布印刷任务"),
+
+    STATISTICS_IMPORT("命题统计导入"),
+
+    SCORE_EXPORT("成绩导出"),
+
+    SCORE_DOWNLOAD("成绩轨迹下载"),
+
+    DOWNLOAD_PAPER_FILE_BATCH("批量下载试卷文件"),
+
+    PAPER_SCAN_TASK_IMPORT("批量导入扫描任务");
 
     private String title;
 

+ 19 - 0
paper-library-common/src/main/java/com/qmth/paper/library/common/lock/LockProvider.java

@@ -0,0 +1,19 @@
+package com.qmth.paper.library.common.lock;
+
+
+public interface LockProvider {
+
+    void waitLock(LockType type, String key);
+
+    boolean tryLock(LockType type, String key);
+
+    void unlock(LockType type, String key);
+
+    boolean isLocked(LockType type, String key);
+
+    void watch(LockType type, String key);
+
+    void unwatch(LockType type, String key);
+
+    void clear();
+}

+ 106 - 0
paper-library-common/src/main/java/com/qmth/paper/library/common/lock/LockService.java

@@ -0,0 +1,106 @@
+package com.qmth.paper.library.common.lock;
+
+import com.qmth.paper.library.common.lock.impl.CustomLockProvider;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Component;
+
+@Component("lockService")
+public class LockService implements InitializingBean, ApplicationContextAware {
+
+    protected static final Logger log = LoggerFactory.getLogger(LockService.class);
+
+    private static final String KEY_JOINER = "\t";
+
+    private ApplicationContext context;
+
+    private LockProvider provider;
+
+    /**
+     * 尝试获取排他锁,立即返回获取结果
+     *
+     * @param type
+     * @param keys
+     * @return
+     */
+    public boolean trylock(LockType type, Object... keys) {
+        return provider.tryLock(type, getKeys(keys));
+    }
+
+    /**
+     * 等待获取排他锁,线程阻塞直到成功获取
+     *
+     * @param type
+     * @param keys
+     */
+    public void waitlock(LockType type, Object... keys) {
+        provider.waitLock(type, getKeys(keys));
+    }
+
+    /**
+     * 释放已获取的排他锁
+     *
+     * @param type
+     * @param keys
+     */
+    public void unlock(LockType type, Object... keys) {
+        provider.unlock(type, getKeys(keys));
+    }
+
+    /**
+     * 检测排他锁是否已被获取
+     *
+     * @param type
+     * @param keys
+     * @return
+     */
+    public boolean isLocked(LockType type, Object... keys) {
+        return provider.isLocked(type, getKeys(keys));
+    }
+
+    /**
+     * 等待获取可重入的读锁
+     *
+     * @param type
+     * @param keys
+     */
+    public void watch(LockType type, Object... keys) {
+        provider.watch(type, getKeys(keys));
+    }
+
+    /**
+     * 释放已获取的读锁
+     *
+     * @param type
+     * @param keys
+     */
+    public void unwatch(LockType type, Object... keys) {
+        provider.unwatch(type, getKeys(keys));
+    }
+
+    /**
+     * 释放长时间未使用的锁
+     */
+    public void clear() {
+        provider.clear();
+    }
+
+    private String getKeys(Object... keys) {
+        return StringUtils.join(keys, KEY_JOINER);
+    }
+
+    @Override
+    public void afterPropertiesSet() throws Exception {
+        this.provider = this.context.getBean(CustomLockProvider.class);
+    }
+
+    @Override
+    public void setApplicationContext(ApplicationContext context) throws BeansException {
+        this.context = context;
+    }
+}

+ 16 - 0
paper-library-common/src/main/java/com/qmth/paper/library/common/lock/LockType.java

@@ -0,0 +1,16 @@
+package com.qmth.paper.library.common.lock;
+
+public enum LockType {
+    BIND_SCAN_USER("绑定扫描员"), BIND_PAPER_TASK("绑定图片任务");
+
+    private String name;
+
+    private LockType(String name) {
+        this.name = name;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+}

+ 99 - 0
paper-library-common/src/main/java/com/qmth/paper/library/common/lock/impl/CustomLockProvider.java

@@ -0,0 +1,99 @@
+package com.qmth.paper.library.common.lock.impl;
+
+import com.qmth.paper.library.common.lock.LockProvider;
+import com.qmth.paper.library.common.lock.LockType;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+/**
+ * 自己实现的内存锁控制
+ *
+ * @author luoshi
+ */
+@Component("customLockProvider")
+public class CustomLockProvider implements LockProvider {
+
+    private Map<LockType, Map<String, ReadWriteLock>> lockMap = new HashMap<>();
+
+    @Override
+    public void waitLock(LockType type, String key) {
+        getLock(type, key).write();
+    }
+
+    @Override
+    public boolean tryLock(LockType type, String key) {
+        return getLock(type, key).tryWrite();
+    }
+
+    @Override
+    public boolean isLocked(LockType type, String key) {
+        return getLock(type, key).writing();
+    }
+
+    @Override
+    public void unlock(LockType type, String key) {
+        getLock(type, key).unWrite();
+    }
+
+    @Override
+    public void watch(LockType type, String key) {
+        getLock(type, key).read();
+    }
+
+    @Override
+    public void unwatch(LockType type, String key) {
+        getLock(type, key).unRead();
+    }
+
+    private ReadWriteLock getLock(LockType type, String key) {
+        Map<String, ReadWriteLock> map = lockMap.get(type);
+        if (map == null) {
+            synchronized (lockMap) {
+                map = lockMap.get(type);
+                if (map == null) {
+                    map = new HashMap<>();
+                    lockMap.put(type, map);
+                }
+            }
+        }
+
+        ReadWriteLock lock = map.get(key);
+        if (lock == null) {
+            synchronized (map) {
+                lock = map.get(key);
+                if (lock == null) {
+                    lock = new ReadWriteLock();
+                    map.put(key, lock);
+                }
+            }
+        }
+
+        return lock;
+    }
+
+    public void clear() {
+        if (lockMap.isEmpty()) {
+            return;
+        }
+        synchronized (lockMap) {
+            for (Map<String, ReadWriteLock> map : lockMap.values()) {
+                Set<String> keys = new HashSet<>();
+                for (Entry<String, ReadWriteLock> entry : map.entrySet()) {
+                    if (!entry.getValue().writing() && entry.getValue().readCount() == 0) {
+                        keys.add(entry.getKey());
+                    }
+                }
+                for (String key : keys) {
+                    map.remove(key);
+                }
+                keys.clear();
+            }
+        }
+    }
+
+}

+ 100 - 0
paper-library-common/src/main/java/com/qmth/paper/library/common/lock/impl/JdkLockProvider.java

@@ -0,0 +1,100 @@
+package com.qmth.paper.library.common.lock.impl;
+
+import com.qmth.paper.library.common.lock.LockProvider;
+import com.qmth.paper.library.common.lock.LockType;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+/**
+ * JVM内存实现的锁控制
+ *
+ * @author luoshi
+ */
+@Component("jdkLockProvider")
+public class JdkLockProvider implements LockProvider {
+
+    private Map<LockType, Map<String, ReentrantReadWriteLock>> lockMap = new HashMap<>();
+
+    @Override
+    public void waitLock(LockType type, String key) {
+        getLock(type, key).writeLock().lock();
+    }
+
+    @Override
+    public boolean tryLock(LockType type, String key) {
+        return getLock(type, key).writeLock().tryLock();
+    }
+
+    @Override
+    public boolean isLocked(LockType type, String key) {
+        return getLock(type, key).isWriteLocked();
+    }
+
+    @Override
+    public void unlock(LockType type, String key) {
+        getLock(type, key).writeLock().unlock();
+    }
+
+    @Override
+    public void watch(LockType type, String key) {
+        getLock(type, key).readLock().lock();
+    }
+
+    @Override
+    public void unwatch(LockType type, String key) {
+        getLock(type, key).readLock().unlock();
+    }
+
+    private ReentrantReadWriteLock getLock(LockType type, String key) {
+        Map<String, ReentrantReadWriteLock> map = lockMap.get(type);
+        if (map == null) {
+            synchronized (lockMap) {
+                map = lockMap.get(type);
+                if (map == null) {
+                    map = new HashMap<>();
+                    lockMap.put(type, map);
+                }
+            }
+        }
+
+        ReentrantReadWriteLock lock = map.get(key);
+        if (lock == null) {
+            synchronized (map) {
+                lock = map.get(key);
+                if (lock == null) {
+                    lock = new ReentrantReadWriteLock();
+                    map.put(key, lock);
+                }
+            }
+        }
+
+        return lock;
+    }
+
+    public void clear() {
+        if (lockMap.isEmpty()) {
+            return;
+        }
+        synchronized (lockMap) {
+            for (Map<String, ReentrantReadWriteLock> map : lockMap.values()) {
+                Set<String> keys = new HashSet<>();
+                for (Entry<String, ReentrantReadWriteLock> entry : map.entrySet()) {
+                    if (!entry.getValue().isWriteLocked() && entry.getValue().getReadLockCount() == 0) {
+                        keys.add(entry.getKey());
+                    }
+                }
+                for (String key : keys) {
+                    map.remove(key);
+                }
+                keys.clear();
+            }
+        }
+    }
+
+}

+ 134 - 0
paper-library-common/src/main/java/com/qmth/paper/library/common/lock/impl/ReadWriteLock.java

@@ -0,0 +1,134 @@
+package com.qmth.paper.library.common.lock.impl;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.IntUnaryOperator;
+
+/**
+ * 简单读写锁实现<br>
+ * 0表示空闲状态,-1表示正在写,>0表示正在读
+ *
+ * @author luoshi
+ */
+public class ReadWriteLock {
+
+    private static ReadOperator readOperator = new ReadOperator();
+
+    private static UnReadOperator unreadOperator = new UnReadOperator();
+
+    private AtomicInteger value;
+
+    public ReadWriteLock() {
+        this.value = new AtomicInteger(0);
+    }
+
+    public int read() {
+        int result = 0;
+        while ((result = value.updateAndGet(readOperator)) < 1) {
+            ;
+        }
+        return result;
+    }
+
+    public int unRead() {
+        if (value.get() < 1) {
+            throw new RuntimeException("unread error");
+        }
+        return value.updateAndGet(unreadOperator);
+    }
+
+    public int readCount() {
+        return Math.max(0, value.get());
+    }
+
+    public int write() {
+        while (!value.compareAndSet(0, -1)) {
+            ;
+        }
+        return -1;
+    }
+
+    public boolean tryWrite() {
+        return value.compareAndSet(0, -1);
+    }
+
+    public int unWrite() {
+        while (!value.compareAndSet(-1, 0)) {
+            ;
+        }
+        return 0;
+    }
+
+    public boolean writing() {
+        return value.get() == -1;
+    }
+
+    static class ReadOperator implements IntUnaryOperator {
+
+        @Override
+        public int applyAsInt(int operand) {
+            return operand >= 0 ? operand + 1 : operand;
+        }
+
+    }
+
+    static class UnReadOperator implements IntUnaryOperator {
+
+        @Override
+        public int applyAsInt(int operand) {
+            return operand >= 1 ? operand - 1 : operand;
+        }
+
+    }
+
+    static class LockTestThread implements Runnable {
+
+        private ReadWriteLock lock;
+
+        private int number;
+
+        public LockTestThread(int number, ReadWriteLock lock) {
+            this.lock = lock;
+            this.number = number;
+        }
+
+        @Override
+        public void run() {
+            for (int i = 0; i < 10000; i++) {
+                if (Math.random() < 0.7) {
+                    System.out.println(
+                            "[thread-" + number + "]   read: " + lock.read() + "[" + System.currentTimeMillis() + "]");
+                    try {
+                        Thread.sleep(100 * ((i % 10) + 1));
+                    } catch (InterruptedException e) {
+                        e.printStackTrace();
+                    }
+                    System.out.println("[thread-" + number + "] unread: " + lock.unRead() + "["
+                            + System.currentTimeMillis() + "]");
+                } else {
+                    System.out.println(
+                            "[thread-" + number + "]  write:" + lock.write() + "[" + System.currentTimeMillis() + "]");
+                    try {
+                        Thread.sleep(100 * ((i % 10) + 1));
+                    } catch (InterruptedException e) {
+                        e.printStackTrace();
+                    }
+                    System.out.println("[thread-" + number + "]unwrite: " + lock.unWrite() + "["
+                            + System.currentTimeMillis() + "]");
+                }
+            }
+        }
+    }
+
+    public static void main(String[] args) {
+        ExecutorService executor = Executors.newFixedThreadPool(5);
+        final ReadWriteLock lock = new ReadWriteLock();
+        for (int i = 0; i < 5; i++) {
+            executor.submit(new LockTestThread(i + 1, lock));
+        }
+
+        executor.shutdown();
+    }
+
+}

+ 0 - 5
paper-library-common/src/main/java/com/qmth/paper/library/common/service/BasicStudentService.java

@@ -24,11 +24,6 @@ import java.util.Set;
  * @since 2021-08-02
  */
 public interface BasicStudentService extends IService<BasicStudent> {
-
-    IPage<BasicStudent> listPage(Page<BasicStudent> page, String classId);
-
-    List<TaskPrintClassDto> listByClass(Long schoolId, Set<String> stringList);
-
     /**
      * 学生基础信息分页查询
      *

+ 0 - 17
paper-library-common/src/main/java/com/qmth/paper/library/common/service/impl/BasicStudentServiceImpl.java

@@ -65,23 +65,6 @@ public class BasicStudentServiceImpl extends ServiceImpl<BasicStudentMapper, Bas
         return this.baseMapper.findBasicStudentList(schoolId, collegeId, majorId, clazzId, studentCodeList);
     }
 
-    @Override
-    public IPage<BasicStudent> listPage(Page<BasicStudent> page, String classId) {
-        List<String> classIds = Arrays.asList(classId.split(","));
-        QueryWrapper<BasicStudent> queryWrapper = new QueryWrapper<>();
-        queryWrapper.lambda().in(BasicStudent::getClazzId, classIds)
-                .orderByAsc(BasicStudent::getClazzId)
-                .orderByAsc(BasicStudent::getStudentCode);
-        return this.baseMapper.selectPage(page, queryWrapper);
-    }
-
-    @Override
-    public List<TaskPrintClassDto> listByClass(Long schoolId, Set<String> stringList) {
-        return this.baseMapper.listByClass(schoolId, stringList).stream()
-                .peek(e -> e.setTeachBasicEnum(TeachBasicEnum.BASIC_CLAZZ))
-                .collect(Collectors.toList());
-    }
-
     @Transactional(rollbackFor = Exception.class)
     @Override
     public Long saveBasicStudent(BasicStudentParams basicStudentParams, SysUser requestUser) {

+ 1 - 1
paper-library/src/main/java/com/qmth/paper/library/api/BasicSemesterController.java

@@ -34,7 +34,7 @@ public class BasicSemesterController {
     private BasicSemesterService basicSemesterService;
 
     @ApiOperation(value = "学期管理-查询")
-    @RequestMapping(value = "/query", method = RequestMethod.POST)
+    @RequestMapping(value = "/page", method = RequestMethod.POST)
     @ApiResponses({@ApiResponse(code = 200, message = "查询成功", response = Result.class)})
     public Result findBasicSemesterList(@ApiParam(value = "分页页码", required = true) @RequestParam @Min(SystemConstant.PAGE_NUMBER_MIN) Integer pageNumber,
                                         @ApiParam(value = "分页数", required = true) @RequestParam @Min(SystemConstant.PAGE_SIZE_MIN) @Max(SystemConstant.PAGE_SIZE_MAX) Integer pageSize) {

+ 8 - 0
paper-library/src/main/java/com/qmth/paper/library/api/PaperArchivesController.java

@@ -10,6 +10,7 @@ import com.qmth.paper.library.business.service.PaperArchivesService;
 import com.qmth.paper.library.common.contant.SystemConstant;
 import com.qmth.paper.library.common.util.Result;
 import com.qmth.paper.library.common.util.ResultUtil;
+import com.qmth.paper.library.common.util.ServletUtil;
 import io.swagger.annotations.*;
 import org.springframework.validation.BindingResult;
 import org.springframework.validation.annotation.Validated;
@@ -64,4 +65,11 @@ public class PaperArchivesController {
         return ResultUtil.ok(paperArchivesService.delete(id));
     }
 
+    @ApiOperation(value = "档案管理部门查询")
+    @PostMapping("/_manager_orgs/query")
+    @ApiResponses({@ApiResponse(code = 200, message = "查询成功", response = Result.class)})
+    public Result queryManagerOrgs(@RequestParam(value = "semesterId", required = false) Long semesterId) {
+        return ResultUtil.ok(paperArchivesService.queryManagerOrgs(semesterId));
+    }
+
 }

+ 7 - 0
paper-library/src/main/java/com/qmth/paper/library/api/PaperArchivesTypeController.java

@@ -42,6 +42,13 @@ public class PaperArchivesTypeController {
         return ResultUtil.ok(paperArchivesTypeService.pageData(pageNumber, pageSize));
     }
 
+    @ApiOperation(value = "查询-不分页")
+    @PostMapping("/query")
+    @ApiResponses({@ApiResponse(code = 200, message = "查询成功", response = Result.class)})
+    public Result query() {
+        return ResultUtil.ok(paperArchivesTypeService.queryData());
+    }
+
     @ApiOperation(value = "新增")
     @PostMapping("/save")
     @ApiResponses({@ApiResponse(code = 200, message = "保存/更新成功", response = EditResult.class)})

+ 84 - 0
paper-library/src/main/java/com/qmth/paper/library/api/PaperLibraryController.java

@@ -0,0 +1,84 @@
+package com.qmth.paper.library.api;
+
+
+import com.qmth.boot.api.annotation.Aac;
+import com.qmth.boot.api.annotation.BOOL;
+import com.qmth.boot.api.constant.ApiConstant;
+import com.qmth.paper.library.business.bean.result.EditResult;
+import com.qmth.paper.library.business.service.PaperLibraryService;
+import com.qmth.paper.library.common.contant.SystemConstant;
+import com.qmth.paper.library.common.util.Result;
+import com.qmth.paper.library.common.util.ResultUtil;
+import io.swagger.annotations.*;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+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>
+ */
+@Api(tags = "数据检查Controller")
+@RestController
+@RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + "/${prefix.url.paper}/paper_library")
+@Validated
+@Aac(strict = BOOL.FALSE, auth = BOOL.FALSE)
+public class PaperLibraryController {
+    @Resource
+    private PaperLibraryService paperLibraryService;
+
+    @ApiOperation(value = "分页查询-未绑定")
+    @PostMapping("/page_unbind")
+    @ApiResponses({@ApiResponse(code = 200, message = "查询成功", response = Result.class)})
+    public Result pageUnbind(@ApiParam(value = "任务") @RequestParam(required = false) Long paperScanTaskId,
+                             @ApiParam(value = "分页页码", required = true) @RequestParam @Min(SystemConstant.PAGE_NUMBER_MIN) Integer pageNumber,
+                             @ApiParam(value = "分页数", required = true) @RequestParam @Min(SystemConstant.PAGE_SIZE_MIN) @Max(SystemConstant.PAGE_SIZE_MAX) Integer pageSize) {
+        return ResultUtil.ok(paperLibraryService.pageUnbindData(paperScanTaskId, pageNumber, pageSize));
+    }
+
+    @ApiOperation(value = "分页查询-未绑定数量")
+    @PostMapping("/count_unbind")
+    @ApiResponses({@ApiResponse(code = 200, message = "查询成功", response = Result.class)})
+    public Result countUnbind(@ApiParam(value = "任务") @RequestParam(required = false) Long paperScanTaskId) {
+        return ResultUtil.ok(paperLibraryService.countUnbindData(paperScanTaskId));
+    }
+
+    @ApiOperation(value = "分页查询-已绑定")
+    @PostMapping("/page_bind")
+    @ApiResponses({@ApiResponse(code = 200, message = "查询成功", response = Result.class)})
+    public Result pageBind(@ApiParam(value = "任务") @RequestParam(required = false) Long paperScanTaskId,
+                           @ApiParam(value = "分页页码", required = true) @RequestParam @Min(SystemConstant.PAGE_NUMBER_MIN) Integer pageNumber,
+                           @ApiParam(value = "分页数", required = true) @RequestParam @Min(SystemConstant.PAGE_SIZE_MIN) @Max(SystemConstant.PAGE_SIZE_MAX) Integer pageSize) {
+        return ResultUtil.ok(paperLibraryService.pageBindData(paperScanTaskId, pageNumber, pageSize));
+    }
+
+    @ApiOperation(value = "分页查询-已绑定数量")
+    @PostMapping("/count_bind")
+    @ApiResponses({@ApiResponse(code = 200, message = "查询成功", response = Result.class)})
+    public Result countBind(@ApiParam(value = "任务") @RequestParam(required = false) Long paperScanTaskId) {
+        return ResultUtil.ok(paperLibraryService.countBindData(paperScanTaskId));
+    }
+
+    @ApiOperation(value = "绑定")
+    @PostMapping("/bind")
+    @ApiResponses({@ApiResponse(code = 200, message = "绑定成功", response = EditResult.class)})
+    public Result save(@RequestParam Long paperLibraryId,
+                       @RequestParam Long paperScanTaskDetailId) {
+        return ResultUtil.ok(paperLibraryService.bind(paperLibraryId, paperScanTaskDetailId));
+    }
+
+    @ApiOperation(value = "处理")
+    @PostMapping("/to_bind")
+    @ApiResponses({@ApiResponse(code = 200, message = "确定成功", response = Result.class)})
+    public Result next() {
+        return ResultUtil.ok(paperLibraryService.toBindPaper());
+    }
+
+}

+ 125 - 0
paper-library/src/main/java/com/qmth/paper/library/api/PaperScanTaskController.java

@@ -0,0 +1,125 @@
+package com.qmth.paper.library.api;
+
+import com.qmth.boot.api.annotation.Aac;
+import com.qmth.boot.api.annotation.BOOL;
+import com.qmth.boot.api.constant.ApiConstant;
+import com.qmth.paper.library.business.bean.params.PaperScanTaskParam;
+import com.qmth.paper.library.business.bean.result.EditResult;
+import com.qmth.paper.library.business.service.PaperLibraryCommonService;
+import com.qmth.paper.library.business.service.PaperScanTaskService;
+import com.qmth.paper.library.business.templete.execute.AsyncPaperScanTaskImportService;
+import com.qmth.paper.library.common.contant.SystemConstant;
+import com.qmth.paper.library.common.entity.SysUser;
+import com.qmth.paper.library.common.entity.TBTask;
+import com.qmth.paper.library.common.enums.TaskTypeEnum;
+import com.qmth.paper.library.common.util.Result;
+import com.qmth.paper.library.common.util.ResultUtil;
+import com.qmth.paper.library.common.util.ServletUtil;
+import io.swagger.annotations.*;
+import org.springframework.validation.BindingResult;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
+import javax.validation.Valid;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+/**
+ * @Description: 试卷扫描任务管理
+ * @Author: CaoZixuan
+ * @Date: 2022-09-29
+ */
+
+@Api(tags = "扫描任务管理controller")
+@RestController
+@RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + "/${prefix.url.paper}/scan_task")
+@Validated
+@Aac(strict = BOOL.FALSE, auth = BOOL.FALSE)
+public class PaperScanTaskController {
+    @Resource
+    private PaperScanTaskService paperScanTaskService;
+    @Resource
+    private PaperLibraryCommonService paperLibraryCommonService;
+    @Resource
+    private AsyncPaperScanTaskImportService asyncPaperScanTaskImportService;
+
+    @ApiOperation(value = "扫描任务管理-查询")
+    @RequestMapping(value = "/query", method = RequestMethod.POST)
+    @ApiResponses({@ApiResponse(code = 200, message = "查询成功", response = Result.class)})
+    public Result findPaperScanTaskPage(@ApiParam(value = "课程名称") @RequestParam(required = false) String courseName,
+                                        @ApiParam(value = "任课教师") @RequestParam(required = false) String teacherName,
+                                        @ApiParam(value = "分页页码", required = true) @RequestParam @Min(SystemConstant.PAGE_NUMBER_MIN) Integer pageNumber,
+                                        @ApiParam(value = "分页数", required = true) @RequestParam @Min(SystemConstant.PAGE_SIZE_MIN) @Max(SystemConstant.PAGE_SIZE_MAX) Integer pageSize) {
+        SysUser requestUser = (SysUser) ServletUtil.getRequestUser();
+        return ResultUtil.ok(paperScanTaskService.paperScanTaskPage(courseName, teacherName, pageNumber, pageSize, requestUser));
+    }
+
+    @ApiOperation(value = "扫描任务管理-新增/编辑")
+    @RequestMapping(value = "/save", method = RequestMethod.POST)
+    @ApiResponses({@ApiResponse(code = 200, message = "更新成功", response = EditResult.class)})
+    public Result savePaperScanTask(@Valid @RequestBody PaperScanTaskParam paperScanTaskParam, BindingResult bindingResult) {
+        if (bindingResult.hasErrors()) {
+            return ResultUtil.error(bindingResult.getAllErrors().get(0).getDefaultMessage());
+        }
+        SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
+        return ResultUtil.ok(paperScanTaskService.editPaperScanTask(paperScanTaskParam, sysUser));
+    }
+
+    @ApiOperation(value = "扫描任务管理-批量删除(物理)")
+    @RequestMapping(value = "/delete_batch", method = RequestMethod.POST)
+    @ApiResponses({@ApiResponse(code = 200, message = "删除成功", response = EditResult.class)})
+    public Result deletePaperScanTask(@ApiParam(value = "选择的要删除的学生id集合", required = true) @RequestParam List<String> idList) {
+        SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
+        paperScanTaskService.deletePaperScanTaskByIdList(idList.stream().map(SystemConstant::convertIdToLong).collect(Collectors.toList()), sysUser);
+        return ResultUtil.ok();
+    }
+
+    @ApiOperation(value = "扫描任务管理-批量导入(异步)")
+    @RequestMapping(value = "/scan_task_import", method = RequestMethod.POST)
+    @ApiResponses({@ApiResponse(code = 200, message = "返回信息", response = EditResult.class)})
+    public Result paperScanTaskImportAsync(@ApiParam(value = "上传文件", required = true) @RequestParam MultipartFile file,
+                                           @ApiParam(value = "档案id", required = true) @RequestParam Long paperArchivesId) throws Exception {
+        SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
+        Map<String, Object> map = paperLibraryCommonService.saveTask(file, TaskTypeEnum.PAPER_SCAN_TASK_IMPORT);
+        map.put(SystemConstant.SYS_USER, sysUser);
+        map.put("paperArchivesId", paperArchivesId);
+        asyncPaperScanTaskImportService.importTask(map);
+        TBTask tbTask = Objects.nonNull(map.get(SystemConstant.TASK)) ? (TBTask) map.get(SystemConstant.TASK) : null;
+        return Objects.nonNull(tbTask) ? ResultUtil.ok(tbTask.getId()) : ResultUtil.error("创建任务失败");
+    }
+
+    @ApiOperation(value = "扫描任务管理-绑定扫描员导入模板下载")
+    @RequestMapping(value = "/scanner_export", method = RequestMethod.POST)
+    @ApiResponses({@ApiResponse(code = 200, message = "{\"success\":true}", response = Result.class)})
+    public Result scannerExport() throws Exception {
+
+        SysUser requestUser = (SysUser) ServletUtil.getRequestUser();
+        paperScanTaskService.exportScanner(requestUser);
+        return ResultUtil.ok();
+    }
+
+    @ApiOperation(value = "扫描任务管理-任务详情查询")
+    @RequestMapping(value = "/task_detail_page", method = RequestMethod.POST)
+    @ApiResponses({@ApiResponse(code = 200, message = "查询成功", response = Result.class)})
+    public Result findPaperScanTaskDetailPage(@ApiParam(value = "扫描任务id", required = true) @RequestParam String paperScanTaskId,
+                                              @ApiParam(value = "分页页码", required = true) @RequestParam @Min(SystemConstant.PAGE_NUMBER_MIN) Integer pageNumber,
+                                              @ApiParam(value = "分页数", required = true) @RequestParam @Min(SystemConstant.PAGE_SIZE_MIN) @Max(SystemConstant.PAGE_SIZE_MAX) Integer pageSize) {
+        SysUser requestUser = (SysUser) ServletUtil.getRequestUser();
+        return ResultUtil.ok(paperScanTaskService.findPaperScanTaskDetailPageByTaskId(SystemConstant.convertIdToLong(paperScanTaskId), pageNumber, pageSize, requestUser));
+    }
+
+    @ApiOperation(value = "扫描任务管理-清除数据")
+    @RequestMapping(value = "/clear_scan_data", method = RequestMethod.POST)
+    @ApiResponses({@ApiResponse(code = 200, message = "删除成功", response = EditResult.class)})
+    public Result clearScanData(@ApiParam(value = "扫描任务id", required = true) @RequestParam String paperScanTaskId) {
+        SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
+        paperScanTaskService.clearScanData(SystemConstant.convertIdToLong(paperScanTaskId), sysUser);
+        return ResultUtil.ok();
+    }
+}