Kaynağa Gözat

Merge branch 'dev' into release
update

wangliang 4 yıl önce
ebeveyn
işleme
3762c22506
63 değiştirilmiş dosya ile 2032 ekleme ve 162 silme
  1. 80 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/dto/ClientExamStudentDto.java
  2. 108 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/dto/ClientExamTaskDto.java
  3. 71 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/dto/ClientPrintDataDto.java
  4. 170 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/dto/ClientPrintTaskDto.java
  5. 10 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/dto/ExamTaskImportDto.java
  6. 5 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/dto/OrgDto.java
  7. 4 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/dto/PrivilegeDto.java
  8. 4 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/dto/TemplateDto.java
  9. 9 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/params/RelatePaperParam.java
  10. 7 11
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/entity/ClientStatus.java
  11. 1 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/enums/EnumType.java
  12. 45 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/enums/ExaminationDBFieldsEnum.java
  13. 16 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/mapper/ClientStatusMapper.java
  14. 7 3
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/mapper/ExamDetailMapper.java
  15. 3 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/mapper/ExamTaskDetailMapper.java
  16. 2 1
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/mapper/ExamTaskMapper.java
  17. 25 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ClientService.java
  18. 16 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ClientStatusService.java
  19. 8 1
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/CommonService.java
  20. 2 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ExamDetailCourseService.java
  21. 7 4
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ExamDetailService.java
  22. 1 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ExamPrintPlanService.java
  23. 5 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ExamTaskDetailService.java
  24. 1 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ExamTaskService.java
  25. 3 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/OrgCenterDataDisposeService.java
  26. 5 2
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/BasicCardRuleServiceImpl.java
  27. 16 10
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/BasicCourseServiceImpl.java
  28. 168 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ClientServiceImpl.java
  29. 40 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ClientStatusServiceImpl.java
  30. 44 9
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/CommonServiceImpl.java
  31. 7 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamDetailCourseServiceImpl.java
  32. 25 2
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamDetailServiceImpl.java
  33. 9 2
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamPrintPlanServiceImpl.java
  34. 44 5
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamTaskDetailServiceImpl.java
  35. 101 24
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamTaskServiceImpl.java
  36. 1 1
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/SysUserServiceImpl.java
  37. 1 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/execute/AsyncDownloadPdfTempleteService.java
  38. 2 2
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/execute/AsyncExaminationExportTemplateService.java
  39. 2 4
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/execute/AsyncExaminationImportTemplateService.java
  40. 64 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/execute/AsyncTaskReviewSampleExportService.java
  41. 7 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/service/TaskLogicService.java
  42. 181 19
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/service/impl/TaskLogicServiceImpl.java
  43. 74 26
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/util/ConvertUtil.java
  44. 14 3
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/util/CreatePdfUtil.java
  45. 2 2
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/util/FreemarkerUtil.java
  46. 12 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/util/OssUtil.java
  47. 3 3
      distributed-print-business/src/main/resources/db/init-table.sql
  48. 2 0
      distributed-print-business/src/main/resources/mapper/BasicCardRuleMapper.xml
  49. 1 0
      distributed-print-business/src/main/resources/mapper/BasicCourseMapper.xml
  50. 1 1
      distributed-print-business/src/main/resources/mapper/BasicSchoolMapper.xml
  51. 1 0
      distributed-print-business/src/main/resources/mapper/BasicTemplateMapper.xml
  52. 3 0
      distributed-print-business/src/main/resources/mapper/ExamCardMapper.xml
  53. 55 0
      distributed-print-business/src/main/resources/mapper/ExamDetailMapper.xml
  54. 21 0
      distributed-print-business/src/main/resources/mapper/ExamTaskDetailMapper.xml
  55. 65 2
      distributed-print-business/src/main/resources/mapper/ExamTaskMapper.xml
  56. 1 0
      distributed-print-business/src/main/resources/mapper/ExamTaskReviewLogMapper.xml
  57. 314 2
      distributed-print/src/main/java/com/qmth/distributed/print/api/ClientController.java
  58. 3 0
      distributed-print/src/main/java/com/qmth/distributed/print/api/EnumsController.java
  59. 17 4
      distributed-print/src/main/java/com/qmth/distributed/print/api/ExamPrintPlanController.java
  60. 26 13
      distributed-print/src/main/java/com/qmth/distributed/print/api/ExamTaskController.java
  61. 80 4
      distributed-print/src/main/java/com/qmth/distributed/print/auth/DistributedPrintAuthenticationService.java
  62. 9 1
      distributed-print/src/main/java/com/qmth/distributed/print/interceptor/AuthInterceptor.java
  63. 1 1
      distributed-print/src/main/resources/application.properties

+ 80 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/dto/ClientExamStudentDto.java

@@ -0,0 +1,80 @@
+package com.qmth.distributed.print.business.bean.dto;
+
+/**
+ * @Date: 2021/3/31.
+ */
+public class ClientExamStudentDto {
+
+    private String examDetailId;
+    private String courseCode;
+    private String courseName;
+    private String paperNumber;
+    private String studentCode;
+    private String ticketNumber;
+    private String studentName;
+    private String siteNumber;
+
+    public String getExamDetailId() {
+        return examDetailId;
+    }
+
+    public void setExamDetailId(String examDetailId) {
+        this.examDetailId = examDetailId;
+    }
+
+    public String getCourseCode() {
+        return courseCode;
+    }
+
+    public void setCourseCode(String courseCode) {
+        this.courseCode = courseCode;
+    }
+
+    public String getCourseName() {
+        return courseName;
+    }
+
+    public void setCourseName(String courseName) {
+        this.courseName = courseName;
+    }
+
+    public String getPaperNumber() {
+        return paperNumber;
+    }
+
+    public void setPaperNumber(String paperNumber) {
+        this.paperNumber = paperNumber;
+    }
+
+    public String getStudentCode() {
+        return studentCode;
+    }
+
+    public void setStudentCode(String studentCode) {
+        this.studentCode = studentCode;
+    }
+
+    public String getTicketNumber() {
+        return ticketNumber;
+    }
+
+    public void setTicketNumber(String ticketNumber) {
+        this.ticketNumber = ticketNumber;
+    }
+
+    public String getStudentName() {
+        return studentName;
+    }
+
+    public void setStudentName(String studentName) {
+        this.studentName = studentName;
+    }
+
+    public String getSiteNumber() {
+        return siteNumber;
+    }
+
+    public void setSiteNumber(String siteNumber) {
+        this.siteNumber = siteNumber;
+    }
+}

+ 108 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/dto/ClientExamTaskDto.java

@@ -0,0 +1,108 @@
+package com.qmth.distributed.print.business.bean.dto;
+
+/**
+ * @Date: 2021/3/31.
+ */
+public class ClientExamTaskDto {
+
+    private String examTaskId;
+    private String printPlanName;
+    private String paperNumber;
+    private String courseCode;
+    private String courseName;
+    private String specialty;
+    private String userId;
+    private String userName;
+    private Boolean isTry;
+    private Boolean isPass;
+    private Long tryTime;
+
+
+    public String getExamTaskId() {
+        return examTaskId;
+    }
+
+    public void setExamTaskId(String examTaskId) {
+        this.examTaskId = examTaskId;
+    }
+
+    public String getPrintPlanName() {
+        return printPlanName;
+    }
+
+    public void setPrintPlanName(String printPlanName) {
+        this.printPlanName = printPlanName;
+    }
+
+    public String getPaperNumber() {
+        return paperNumber;
+    }
+
+    public void setPaperNumber(String paperNumber) {
+        this.paperNumber = paperNumber;
+    }
+
+    public String getCourseCode() {
+        return courseCode;
+    }
+
+    public void setCourseCode(String courseCode) {
+        this.courseCode = courseCode;
+    }
+
+    public String getCourseName() {
+        return courseName;
+    }
+
+    public void setCourseName(String courseName) {
+        this.courseName = courseName;
+    }
+
+    public String getSpecialty() {
+        return specialty;
+    }
+
+    public void setSpecialty(String specialty) {
+        this.specialty = specialty;
+    }
+
+    public String getUserId() {
+        return userId;
+    }
+
+    public void setUserId(String userId) {
+        this.userId = userId;
+    }
+
+    public String getUserName() {
+        return userName;
+    }
+
+    public void setUserName(String userName) {
+        this.userName = userName;
+    }
+
+    public Boolean getTry() {
+        return isTry;
+    }
+
+    public void setTry(Boolean aTry) {
+        isTry = aTry;
+    }
+
+    public Boolean getPass() {
+        return isPass;
+    }
+
+    public void setPass(Boolean pass) {
+        isPass = pass;
+    }
+
+    public Long getTryTime() {
+        return tryTime;
+    }
+
+    public void setTryTime(Long tryTime) {
+        this.tryTime = tryTime;
+    }
+}

+ 71 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/dto/ClientPrintDataDto.java

@@ -0,0 +1,71 @@
+package com.qmth.distributed.print.business.bean.dto;
+
+/**
+ * @Date: 2021/3/31.
+ */
+public class ClientPrintDataDto {
+
+    private String courseCode;
+    private String courseName;
+    private String paperNumber;
+    private String studentName;
+    private String studentCode;
+    private String paperType;
+    private String url;
+
+    public String getCourseCode() {
+        return courseCode;
+    }
+
+    public void setCourseCode(String courseCode) {
+        this.courseCode = courseCode;
+    }
+
+    public String getCourseName() {
+        return courseName;
+    }
+
+    public void setCourseName(String courseName) {
+        this.courseName = courseName;
+    }
+
+    public String getPaperNumber() {
+        return paperNumber;
+    }
+
+    public void setPaperNumber(String paperNumber) {
+        this.paperNumber = paperNumber;
+    }
+
+    public String 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 getPaperType() {
+        return paperType;
+    }
+
+    public void setPaperType(String paperType) {
+        this.paperType = paperType;
+    }
+
+    public String getUrl() {
+        return url;
+    }
+
+    public void setUrl(String url) {
+        this.url = url;
+    }
+}

+ 170 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/dto/ClientPrintTaskDto.java

@@ -0,0 +1,170 @@
+package com.qmth.distributed.print.business.bean.dto;
+
+/**
+ * @Date: 2021/3/29.
+ */
+public class ClientPrintTaskDto {
+
+    private String examDetailId;
+    private String printPlanId;
+    private String printPlanName;
+    private Long examStartTime;
+    private Long examEndTime;
+    private String courseNameCode;
+    private String paperNumber;
+    private String examPlace;
+    private String examRoom;
+    private String singlePagesA3;
+    private Integer pagesA3;
+    private Integer pagesA4;
+    private Integer totalSubjects;
+    private String status;
+    private Boolean validate;
+    private Long printStartTime;
+    private Long printEndTime;
+    private String packageCode;
+
+    public String getExamDetailId() {
+        return examDetailId;
+    }
+
+    public void setExamDetailId(String examDetailId) {
+        this.examDetailId = examDetailId;
+    }
+
+    public String getPrintPlanId() {
+        return printPlanId;
+    }
+
+    public void setPrintPlanId(String printPlanId) {
+        this.printPlanId = printPlanId;
+    }
+
+    public String getPrintPlanName() {
+        return printPlanName;
+    }
+
+    public void setPrintPlanName(String printPlanName) {
+        this.printPlanName = printPlanName;
+    }
+
+    public Long getExamStartTime() {
+        return examStartTime;
+    }
+
+    public void setExamStartTime(Long examStartTime) {
+        this.examStartTime = examStartTime;
+    }
+
+    public Long getExamEndTime() {
+        return examEndTime;
+    }
+
+    public void setExamEndTime(Long examEndTime) {
+        this.examEndTime = examEndTime;
+    }
+
+    public String getCourseNameCode() {
+        return courseNameCode;
+    }
+
+    public void setCourseNameCode(String courseNameCode) {
+        this.courseNameCode = courseNameCode;
+    }
+
+    public String getPaperNumber() {
+        return paperNumber;
+    }
+
+    public void setPaperNumber(String paperNumber) {
+        this.paperNumber = paperNumber;
+    }
+
+    public String getExamPlace() {
+        return examPlace;
+    }
+
+    public void setExamPlace(String examPlace) {
+        this.examPlace = examPlace;
+    }
+
+    public String getExamRoom() {
+        return examRoom;
+    }
+
+    public void setExamRoom(String examRoom) {
+        this.examRoom = examRoom;
+    }
+
+    public String getSinglePagesA3() {
+        return singlePagesA3;
+    }
+
+    public void setSinglePagesA3(String singlePagesA3) {
+        this.singlePagesA3 = singlePagesA3;
+    }
+
+    public Integer getPagesA3() {
+        return pagesA3;
+    }
+
+    public void setPagesA3(Integer pagesA3) {
+        this.pagesA3 = pagesA3;
+    }
+
+    public Integer getPagesA4() {
+        return pagesA4;
+    }
+
+    public void setPagesA4(Integer pagesA4) {
+        this.pagesA4 = pagesA4;
+    }
+
+    public Integer getTotalSubjects() {
+        return totalSubjects;
+    }
+
+    public void setTotalSubjects(Integer totalSubjects) {
+        this.totalSubjects = totalSubjects;
+    }
+
+    public String getStatus() {
+        return status;
+    }
+
+    public void setStatus(String status) {
+        this.status = status;
+    }
+
+    public Boolean getValidate() {
+        return validate;
+    }
+
+    public void setValidate(Boolean validate) {
+        this.validate = validate;
+    }
+
+    public Long getPrintStartTime() {
+        return printStartTime;
+    }
+
+    public void setPrintStartTime(Long printStartTime) {
+        this.printStartTime = printStartTime;
+    }
+
+    public Long getPrintEndTime() {
+        return printEndTime;
+    }
+
+    public void setPrintEndTime(Long printEndTime) {
+        this.printEndTime = printEndTime;
+    }
+
+    public String getPackageCode() {
+        return packageCode;
+    }
+
+    public void setPackageCode(String packageCode) {
+        this.packageCode = packageCode;
+    }
+}

+ 10 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/dto/ExamTaskImportDto.java

@@ -9,6 +9,8 @@ public class ExamTaskImportDto {
 
     private String batchNo;
 
+    private String errorMsg;
+
     private List<ExamTaskDto> tasks;
 
     public String getBatchNo() {
@@ -19,6 +21,14 @@ public class ExamTaskImportDto {
         this.batchNo = batchNo;
     }
 
+    public String getErrorMsg() {
+        return errorMsg;
+    }
+
+    public void setErrorMsg(String errorMsg) {
+        this.errorMsg = errorMsg;
+    }
+
     public List<ExamTaskDto> getTasks() {
         return tasks;
     }

+ 5 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/dto/OrgDto.java

@@ -1,5 +1,8 @@
 package com.qmth.distributed.print.business.bean.dto;
 
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+
 import java.util.ArrayList;
 import java.util.List;
 
@@ -12,6 +15,8 @@ public class OrgDto {
     private String schoolId;
     private String code;
     private String name;
+
+    @JsonSerialize(using = ToStringSerializer.class)
     private Long parentId;
     private Boolean enable;
     private List<OrgDto> children = new ArrayList<>();

+ 4 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/dto/PrivilegeDto.java

@@ -1,5 +1,7 @@
 package com.qmth.distributed.print.business.bean.dto;
 
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
 import com.qmth.distributed.print.business.enums.PrivilegeEnum;
 
 import java.util.ArrayList;
@@ -14,6 +16,8 @@ public class PrivilegeDto {
     private String name;
     private String url;
     private PrivilegeEnum type;
+
+    @JsonSerialize(using = ToStringSerializer.class)
     private Long parentId;
     private Integer sequence;
     private List<PrivilegeDto> children = new ArrayList<>();

+ 4 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/dto/TemplateDto.java

@@ -1,5 +1,7 @@
 package com.qmth.distributed.print.business.bean.dto;
 
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
 import com.qmth.distributed.print.business.entity.SysOrg;
 import com.qmth.distributed.print.business.enums.ClassifyEnum;
 import com.qmth.distributed.print.business.enums.TemplateTypeEnum;
@@ -16,6 +18,8 @@ public class TemplateDto {
     private String name;
     private TemplateTypeEnum type;
     private ClassifyEnum classify;
+
+    @JsonSerialize(using = ToStringSerializer.class)
     private Long attachmentId;
     private Boolean enable;
     private String remark;

+ 9 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/params/RelatePaperParam.java

@@ -9,6 +9,7 @@ public class RelatePaperParam extends BasePage {
 
     private Long printPlanId;
     private Long examTaskId;
+    private String paperNumber;
     private String relatePaperType;
 
     public Long getPrintPlanId() {
@@ -27,6 +28,14 @@ public class RelatePaperParam extends BasePage {
         this.examTaskId = examTaskId;
     }
 
+    public String getPaperNumber() {
+        return paperNumber;
+    }
+
+    public void setPaperNumber(String paperNumber) {
+        this.paperNumber = paperNumber;
+    }
+
     public String getRelatePaperType() {
         return relatePaperType;
     }

+ 7 - 11
distributed-print-business/src/main/java/com/qmth/distributed/print/business/entity/ClientStatus.java

@@ -5,12 +5,8 @@ import com.baomidou.mybatisplus.annotation.TableName;
 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
 import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
 import com.qmth.distributed.print.business.base.BaseEntity;
-import com.qmth.distributed.print.business.enums.ExamStatusEnum;
-import com.qmth.distributed.print.business.enums.ReviewStatusEnum;
 
 import java.io.Serializable;
-import java.util.List;
-import java.util.Map;
 
 /**
  * <p>
@@ -35,11 +31,11 @@ public class ClientStatus extends BaseEntity implements Serializable {
     @TableField("machine_code")
     private String machineCode;
     /**
-     * 考场ID
+     * 命题任务ID
      */
     @JsonSerialize(using = ToStringSerializer.class)
-    @TableField("exam_detail_id")
-    private Long examDetailId;
+    @TableField("exam_task_id")
+    private Long examTaskId;
     /**
      * 是否打样
      */
@@ -78,12 +74,12 @@ public class ClientStatus extends BaseEntity implements Serializable {
         this.machineCode = machineCode;
     }
 
-    public Long getExamDetailId() {
-        return examDetailId;
+    public Long getExamTaskId() {
+        return examTaskId;
     }
 
-    public void setExamDetailId(Long examDetailId) {
-        this.examDetailId = examDetailId;
+    public void setExamTaskId(Long examTaskId) {
+        this.examTaskId = examTaskId;
     }
 
     public Boolean getTry() {

+ 1 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/enums/EnumType.java

@@ -24,6 +24,7 @@ public enum EnumType {
     MAKE_METHOD("题卡制作方式"),
     PRINT_PLAN_STATUS_ENUM("印刷计划状态类型"),
     EXAM_DETAIL_STATUS_ENUM("考场状态类型"),
+    EXAMINATION_DB_FIELDS_ENUM("考务数据导入-数据库所必须字段枚举"),
     CARD_TYPE("题卡类型");
 
     EnumType(String desc) {

+ 45 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/enums/ExaminationDBFieldsEnum.java

@@ -0,0 +1,45 @@
+package com.qmth.distributed.print.business.enums;
+
+import com.qmth.distributed.print.business.enums.result.EnumResult;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @Description: 考务数据导入-数据库所必须字段枚举
+ * @Author: CaoZixuan
+ * @Date: 2021-04-20
+ */
+public enum ExaminationDBFieldsEnum {
+    STUDENT_CODE("学号"),
+    STUDENT_NAME("姓名"),
+    COURSE_CODE("课程代码"),
+    COURSE_NAME("课程名称"),
+    EXAM_PLACE("考点"),
+    EXAM_ROOM("考场"),
+    EXAM_DATE("考试日期"),
+    EXAM_TIME("考试时间"),
+    PAPER_NUMBER("试卷编号");
+    private final String desc;
+
+    ExaminationDBFieldsEnum(String desc) {
+        this.desc = desc;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+
+    public static List<EnumResult> listTypes() {
+        List<EnumResult> list = new ArrayList<>();
+        for (ExaminationDBFieldsEnum value : ExaminationDBFieldsEnum.values()) {
+            EnumResult result = new EnumResult();
+            result.setName(value.name());
+            result.setOrdinal(value.ordinal());
+            result.setCode(null);
+            result.setDesc(value.getDesc());
+            list.add(result);
+        }
+        return list;
+    }
+}

+ 16 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/mapper/ClientStatusMapper.java

@@ -0,0 +1,16 @@
+package com.qmth.distributed.print.business.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.qmth.distributed.print.business.entity.ClientStatus;
+
+/**
+ * <p>
+ * 客户端状态 Mapper 接口
+ * </p>
+ *
+ * @author xf
+ * @since 2021-04-19
+ */
+public interface ClientStatusMapper extends BaseMapper<ClientStatus> {
+
+}

+ 7 - 3
distributed-print-business/src/main/java/com/qmth/distributed/print/business/mapper/ExamDetailMapper.java

@@ -3,14 +3,14 @@ package com.qmth.distributed.print.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.distributed.print.business.bean.dto.PrintTaskDto;
-import com.qmth.distributed.print.business.bean.dto.PrintTaskTotalDto;
-import com.qmth.distributed.print.business.bean.dto.TaskTotalLeftDto;
+import com.qmth.distributed.print.business.bean.dto.*;
 import com.qmth.distributed.print.business.bean.result.ExaminationDetailResult;
 import com.qmth.distributed.print.business.bean.result.ExaminationResult;
 import com.qmth.distributed.print.business.entity.ExamDetail;
 import org.apache.ibatis.annotations.Param;
 
+import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 /**
@@ -48,4 +48,8 @@ public interface ExamDetailMapper extends BaseMapper<ExamDetail> {
     PrintTaskTotalDto taskTotalData(@Param("schoolId") Long schoolId, @Param("printPlanId") Long printPlanId, @Param("status") String status, @Param("courseCode") String courseCode, @Param("paperNumber") String paperNumber, @Param("examPlace") String examPlace, @Param("examRoom") String examRoom, @Param("examStartTime") Long examStartTime, @Param("examEndTime") Long examEndTime);
 
     TaskTotalLeftDto calcLeftA3(Long schoolId);
+
+    IPage<ClientExamStudentDto> listClientExamStudentPage(Page<ClientExamStudentDto> page, @Param("schoolId") Long schoolId, @Param("examDetailId") Long examDetailId, @Param("ticketNumber") String ticketNumber, @Param("studentName") String studentName, @Param("courseCode") String courseCode);
+
+    List<Map<String, String>> listStudentByExamDetailId(@Param("schoolId") Long schoolId, @Param("examDetailId") Long examDetailId, @Param("ticketNumber") String ticketNumber, @Param("type") String type);
 }

+ 3 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/mapper/ExamTaskDetailMapper.java

@@ -8,6 +8,7 @@ import com.qmth.distributed.print.business.entity.ExamTaskDetail;
 import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 /**
@@ -22,4 +23,6 @@ public interface ExamTaskDetailMapper extends BaseMapper<ExamTaskDetail> {
     IPage<ExamTaskDetailDto> listPage(Page<ExamTaskDetailDto> page, @Param("schoolId") Long schoolId, @Param("relateType") String relateType, @Param("printPlanId") Long printPlanId, @Param("courseCode") String courseCode, @Param("paperNumber") String paperNumber, @Param("orgIds") Set<Long> orgIds);
 
     List<ExamTaskDetail> listByTemplateId(Long templateId);
+
+    List<Map<String, String>> listByExamDetailId(@Param("schoolId") Long schoolId, @Param("examDetailId") Long examDetailId);
 }

+ 2 - 1
distributed-print-business/src/main/java/com/qmth/distributed/print/business/mapper/ExamTaskMapper.java

@@ -26,7 +26,7 @@ public interface ExamTaskMapper extends BaseMapper<ExamTask> {
 
     List<BlurryUserDto> listUser(@Param("schoolId") Long schoolId, @Param("param") String param);
 
-    IPage<ExamTaskDto> listTaskApply(Page<ExamTaskDto> page, @Param("schoolId") Long schoolId, @Param("auditStatus") String auditStatus, @Param("reviewStatus") String reviewStatus, @Param("cardRuleId") Long cardRuleId, @Param("courseCode") String courseCode, @Param("paperNumber") String paperNumber, @Param("startTime") Long startTime, @Param("endTime") Long endTime, @Param("status") String[] status, @Param("userId") Long userId);
+    IPage<ExamTaskDto> listTaskApply(Page<ExamTaskDto> page, @Param("schoolId") Long schoolId, @Param("auditStatus") String auditStatus, @Param("reviewStatus") String reviewStatus, @Param("cardRuleId") Long cardRuleId, @Param("courseCode") String courseCode, @Param("paperNumber") String paperNumber, @Param("startTime") Long startTime, @Param("endTime") Long endTime, @Param("status") String[] status, @Param("userId") Long userId, @Param("orgIds") Set<Long> orgIds);
 
     IPage<ExamTaskDto> listTaskReviewUnaudited(Page<ExamTaskDto> page, @Param("schoolId") Long schoolId, @Param("courseCode") String courseCode, @Param("paperNumber") String paperNumber, @Param("userId") Long userId, @Param("cardRuleId") Long cardRuleId, @Param("startTime") Long startTime, @Param("endTime") Long endTime, @Param("orgIds") Set<Long> orgIds);
 
@@ -71,4 +71,5 @@ public interface ExamTaskMapper extends BaseMapper<ExamTask> {
                                           @Param("schoolId") Long schoolId,
                                           @Param("status") String...status);
 
+    IPage<ClientExamTaskDto> listClientExamTaskPage(Page<ClientExamTaskDto> page, @Param("schoolId") Long schoolId, @Param("machineCode") String machineCode, @Param("printPlanId") Long printPlanId, @Param("courseCode") String courseCode, @Param("paperNumber") String paperNumber, @Param("isTry") Boolean isTry, @Param("isPass") Boolean isPass, @Param("orgIds") Set<Long> orgIds);
 }

+ 25 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ClientService.java

@@ -0,0 +1,25 @@
+package com.qmth.distributed.print.business.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.qmth.distributed.print.business.bean.dto.ClientExamStudentDto;
+import com.qmth.distributed.print.business.bean.dto.ClientExamTaskDto;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Date: 2021/4/20.
+ */
+public interface ClientService {
+    IPage<ClientExamTaskDto> listTryTask(Long schoolId, String machineCode, Long orgId, Long printPlanId, String courseCode, String paperNumber, Boolean isTry, Boolean isPass, Integer pageNumber, Integer pageSize);
+
+    String getUrl(Long schoolId, Long examTaskId);
+
+    Boolean tagPass(Long schoolId, Long examTaskId, String machineCode, Boolean isPass, Long userId);
+
+    Boolean updatePrintProgress(Long schoolId, Long examDetailId, Integer printProgress);
+
+    IPage<ClientExamStudentDto> listStudent(Long schoolId, Long examDetailId, String ticketNumber, String studentName, String courseCode, Integer pageNumber, Integer pageSize);
+
+    Map<String, Object> getReprintData(Long schoolId, Long examDetailId, String ticketNumber, String type);
+}

+ 16 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ClientStatusService.java

@@ -0,0 +1,16 @@
+package com.qmth.distributed.print.business.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.qmth.distributed.print.business.entity.ClientStatus;
+
+/**
+ * <p>
+ * 客户端下载状态 服务类
+ * </p>
+ *
+ * @author xf
+ * @since 2021-04-19
+ */
+public interface ClientStatusService extends IService<ClientStatus> {
+    Boolean tagPass(Long schoolId, Long examTaskId, String machineCode, Boolean isPass, Long userId);
+}

+ 8 - 1
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/CommonService.java

@@ -97,6 +97,13 @@ public interface CommonService {
      */
     public String filePreview(String path);
 
+    /**
+     * 文件预览
+     * @param attachmentId
+     * @return
+     */
+    public String filePreview(String attachmentId, Boolean isExpire);
+
     /**
      * 题卡html文件上传,读取文件内容
      *
@@ -161,5 +168,5 @@ public interface CommonService {
      * 根据orgId查询所有子机构ID集合
      * @return
      */
-    public Set<Long> listSubOrgIds();
+    public Set<Long> listSubOrgIds(Long orgId);
 }

+ 2 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ExamDetailCourseService.java

@@ -25,4 +25,6 @@ public interface ExamDetailCourseService extends IService<ExamDetailCourse> {
     List<ExamDetailCourse> listByExamDetailId(Long examDetailId);
 
     List<ExamDetailCourse> listDetailCourseByCourseCodeAndPaperNumber(Long schoolId, String courseCode, String paperNumber);
+
+    void updatePaperNumber(List<ExamDetailCourse> examDetailCourses, String paperNumber);
 }

+ 7 - 4
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ExamDetailService.java

@@ -2,10 +2,7 @@ package com.qmth.distributed.print.business.service;
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.IService;
-import com.qmth.distributed.print.business.bean.dto.ExaminationExportDto;
-import com.qmth.distributed.print.business.bean.dto.FieldsDto;
-import com.qmth.distributed.print.business.bean.dto.PrintTaskDto;
-import com.qmth.distributed.print.business.bean.dto.PrintTaskTotalDto;
+import com.qmth.distributed.print.business.bean.dto.*;
 import com.qmth.distributed.print.business.bean.params.SerialNumberParams;
 import com.qmth.distributed.print.business.bean.result.ExaminationDetailResult;
 import com.qmth.distributed.print.business.bean.result.ExaminationResult;
@@ -169,4 +166,10 @@ public interface ExamDetailService extends IService<ExamDetail> {
      * @return 导出数据源
      */
     List<ExaminationExportDto> findExaminationExportDtoDatasource(Map<String, Object> map);
+
+    Boolean updatePrintProgress(Long schoolId, Long examDetailId, Integer printProgress);
+
+    IPage<ClientExamStudentDto> listStudent(Long schoolId, Long examDetailId, String ticketNumber, String studentName, String courseCode, Integer pageNumber, Integer pageSize);
+
+    List<Map<String, String>> listStudentByExamDetailId(Long schoolId, Long examDetailId, String ticketNumber, String type);
 }

+ 1 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ExamPrintPlanService.java

@@ -69,4 +69,5 @@ public interface ExamPrintPlanService extends IService<ExamPrintPlan> {
      */
     Boolean removePrintPlan(DeleteParams deleteParams);
 
+    List<Map<String, String>> tempalteView(Long printPlanId);
 }

+ 5 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ExamTaskDetailService.java

@@ -8,6 +8,7 @@ import com.qmth.distributed.print.business.entity.ExamTaskDetail;
 
 import java.io.IOException;
 import java.util.List;
+import java.util.Map;
 
 /**
  * <p>
@@ -32,4 +33,8 @@ public interface ExamTaskDetailService extends IService<ExamTaskDetail> {
     void resetCardId(Long id);
 
     List<ExamTaskDetail> listByTemplateId(Long templateId);
+
+    String getUrl(Long schoolId, Long examTaskId);
+
+    List<Map<String, String>> listByExamDetailId(Long schoolId, Long examDetailId);
 }

+ 1 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ExamTaskService.java

@@ -92,4 +92,5 @@ public interface ExamTaskService extends IService<ExamTask> {
 
     ExamTask getByCourseCodeAndPaperNumber(Long schoolId, String courseCode, String paperNumber);
 
+    IPage<ClientExamTaskDto> listTryTask(Long schoolId, String machineCode, Long orgId, Long printPlanId, String courseCode, String paperNumber, Boolean isTry, Boolean isPass, Integer pageNumber, Integer pageSize);
 }

+ 3 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/OrgCenterDataDisposeService.java

@@ -1,5 +1,7 @@
 package com.qmth.distributed.print.business.service;
 
+import org.springframework.scheduling.annotation.Async;
+
 import java.io.IOException;
 
 /**
@@ -9,5 +11,6 @@ import java.io.IOException;
  */
 public interface OrgCenterDataDisposeService {
 
+    @Async
     void updateSchoolInfo() throws IOException;
 }

+ 5 - 2
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/BasicCardRuleServiceImpl.java

@@ -67,8 +67,7 @@ public class BasicCardRuleServiceImpl extends ServiceImpl<BasicCardRuleMapper, B
         if (StringUtils.isNotBlank(param)) {
             queryWrapper.lambda().like(BasicCardRule::getName, param);
         }
-//        return this.list(queryWrapper);
-        Set<Long> orgIds = commonService.listSubOrgIds();
+        Set<Long> orgIds = commonService.listSubOrgIds(null);
         return this.baseMapper.list(schoolId, param, orgIds);
     }
 
@@ -86,6 +85,10 @@ public class BasicCardRuleServiceImpl extends ServiceImpl<BasicCardRuleMapper, B
         cardRule.setSchoolId(schoolId);
         SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
 
+        if(cardRule.getTitleRule().length() > 200){
+            throw ExceptionResultEnum.ERROR.exception("题卡标题规则长度不能超过200字符");
+        }
+
         // todo 校验是否有必选字段已使用
         QueryWrapper<BasicCardRule> queryWrapper = new QueryWrapper<>();
         queryWrapper.lambda().eq(BasicCardRule::getSchoolId, cardRule.getSchoolId()).eq(BasicCardRule::getName, cardRule.getName());

+ 16 - 10
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/BasicCourseServiceImpl.java

@@ -55,7 +55,7 @@ public class BasicCourseServiceImpl extends ServiceImpl<BasicCourseMapper, Basic
     }
 
     @Override
-    public boolean saveCourse(BasicCourse course,Long userId) {
+    public boolean saveCourse(BasicCourse course, Long userId) {
         Long schoolId = course.getSchoolId();
         course.setSchoolId(schoolId);
 
@@ -108,19 +108,25 @@ public class BasicCourseServiceImpl extends ServiceImpl<BasicCourseMapper, Basic
 
     @Transactional(rollbackFor = Exception.class)
     @Override
-    public void verifyCourseInfo(Long schoolId,String courseCode, String courseName,Long userId) {
-        int count = this.count(new QueryWrapper<BasicCourse>().lambda()
-                .eq(BasicCourse::getSchoolId,schoolId)
-                .eq(BasicCourse::getCode,courseCode)
-                .eq(BasicCourse::getName,courseName));
-        if (count > 1){
-            throw ExceptionResultEnum.ERROR.exception("学校id为 : " + schoolId +  " 课程代码为 : " + courseCode + " 课程名称为 : " + courseName + " 的课程信息异常");
-        }else if (count < 1){
+    public void verifyCourseInfo(Long schoolId, String courseCode, String courseName, Long userId) {
+        QueryWrapper<BasicCourse> queryWrapper = new QueryWrapper<>();
+        queryWrapper.lambda().eq(BasicCourse::getSchoolId, schoolId).eq(BasicCourse::getCode, courseCode);
+
+        BasicCourse tmp = this.getOne(queryWrapper);
+        if (tmp != null) {
+            if (!courseName.equals(tmp.getName())) {
+                throw ExceptionResultEnum.ERROR
+                        .exception("课程代码和课程名称不匹配,课程代码为 :'" + courseCode + "',输入的课程名称 :'" + courseName + "',实际该代码对应的课程名称 :'" + tmp.getName() + "'。");
+            }
+        } else {
             BasicCourse basicCourse = new BasicCourse();
             basicCourse.setName(courseName);
             basicCourse.setCode(courseCode);
             basicCourse.setSchoolId(schoolId);
-            this.saveCourse(basicCourse,userId);
+            basicCourse.setId(SystemConstant.getDbUuid());
+            basicCourse.setCreateId(userId);
+            basicCourse.setCreateTime(System.currentTimeMillis());
+            this.saveOrUpdate(basicCourse);
         }
     }
 }

+ 168 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ClientServiceImpl.java

@@ -0,0 +1,168 @@
+package com.qmth.distributed.print.business.service.impl;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.qmth.distributed.print.business.bean.dto.ClientExamStudentDto;
+import com.qmth.distributed.print.business.bean.dto.ClientExamTaskDto;
+import com.qmth.distributed.print.business.bean.dto.ClientPrintDataDto;
+import com.qmth.distributed.print.business.entity.BasicAttachment;
+import com.qmth.distributed.print.business.entity.ExamDetail;
+import com.qmth.distributed.print.business.entity.ExamPrintPlan;
+import com.qmth.distributed.print.business.service.*;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * @Date: 2021/4/20.
+ */
+@Service
+public class ClientServiceImpl implements ClientService {
+
+    @Autowired
+    private ExamTaskService examTaskService;
+
+    @Autowired
+    private ExamTaskDetailService examTaskDetailService;
+
+    @Autowired
+    private ClientStatusService clientStatusService;
+
+    @Autowired
+    private ExamDetailService examDetailService;
+
+    @Autowired
+    private BasicAttachmentService basicAttachmentService;
+
+    @Autowired
+    private CommonService commonService;
+
+    @Autowired
+    private ExamPrintPlanService examPrintPlanService;
+
+    @Override
+    public IPage<ClientExamTaskDto> listTryTask(Long schoolId, String machineCode, Long orgId, Long printPlanId, String courseCode, String paperNumber, Boolean isTry, Boolean isPass, Integer pageNumber, Integer pageSize) {
+        return examTaskService.listTryTask(schoolId, machineCode, orgId, printPlanId, courseCode, paperNumber, isTry, isPass, pageNumber, pageSize);
+    }
+
+    @Override
+    public String getUrl(Long schoolId, Long examTaskId) {
+        return examTaskDetailService.getUrl(schoolId, examTaskId);
+    }
+
+    @Override
+    public Boolean tagPass(Long schoolId, Long examTaskId, String machineCode, Boolean isPass, Long userId) {
+        return clientStatusService.tagPass(schoolId, examTaskId, machineCode, isPass, userId);
+    }
+
+    @Override
+    public Boolean updatePrintProgress(Long schoolId, Long examDetailId, Integer printProgress) {
+        return examDetailService.updatePrintProgress(schoolId, examDetailId, printProgress);
+    }
+
+    @Override
+    public IPage<ClientExamStudentDto> listStudent(Long schoolId, Long examDetailId, String ticketNumber, String studentName, String courseCode, Integer pageNumber, Integer pageSize) {
+        return examDetailService.listStudent(schoolId, examDetailId, ticketNumber, studentName, courseCode, pageNumber, pageSize);
+    }
+
+    @Override
+    public Map<String, Object> getReprintData(Long schoolId, Long examDetailId, String ticketNumber, String type) {
+        Map<String, Object> finalMap = new HashMap<>();
+        // 取试卷
+        Map<String, String> map = mapCourseUrl(schoolId, examDetailId);
+        // 取考生
+        List<Map<String, String>> studentList = examDetailService.listStudentByExamDetailId(schoolId, examDetailId, ticketNumber, type);
+        // 生成试卷List
+        List<ClientPrintDataDto> paperList = studentList.stream().map(m -> {
+            ClientPrintDataDto printDataDto = new ClientPrintDataDto();
+            String courseCode = m.get("courseCode");
+            String courseName = m.get("courseName");
+            String paperNumber = m.get("paperNumber");
+            String studentName = m.get("studentName");
+            String studentCode = m.get("studentCode");
+            String paperType = m.get("paperType");
+            printDataDto.setCourseCode(courseCode);
+            printDataDto.setCourseName(courseName);
+            printDataDto.setStudentName(studentName);
+            printDataDto.setStudentCode(studentCode);
+            printDataDto.setPaperType(paperType);
+
+            StringJoiner sj = new StringJoiner(":");
+            String key = sj.add(courseCode).add(paperNumber).add(paperType).toString();
+            printDataDto.setUrl(map.get(key));
+            return printDataDto;
+        }).collect(Collectors.toList());
+        finalMap.put("paper", paperList);
+        // 生成题卡List
+        List<ClientPrintDataDto> cardList = studentList.stream().map(m -> {
+            ClientPrintDataDto printDataDto = new ClientPrintDataDto();
+            String courseCode = m.get("courseCode");
+            String courseName = m.get("courseName");
+            String studentName = m.get("studentName");
+            String studentCode = m.get("studentCode");
+            String paperType = m.get("paperType");
+            String attachmentId = m.get("attachmentId");
+            printDataDto.setCourseCode(courseCode);
+            printDataDto.setCourseName(courseName);
+            printDataDto.setStudentName(studentName);
+            printDataDto.setStudentCode(studentCode);
+            printDataDto.setPaperType(paperType);
+            printDataDto.setUrl(commonService.filePreview(attachmentId, false));
+            return printDataDto;
+        }).collect(Collectors.toList());
+        finalMap.put("card", cardList);
+        //
+        ExamDetail examDetail = examDetailService.getById(examDetailId);
+        ExamPrintPlan examPrintPlan = examPrintPlanService.getById(examDetail.getPrintPlanId());
+        String variableContent = examPrintPlan.getVariableContent();
+        String ordinaryContent = examPrintPlan.getOrdinaryContent();
+        List<Map> variableList = JSONObject.parseArray(variableContent, Map.class);
+        List<Map> otherList = new ArrayList<>();
+        // todo 签到表、卷袋贴生成html路径
+        for (Map variable : variableList) {
+            Map vMap = new HashMap();
+            vMap.put("type", variable.get("type"));
+            vMap.put("url", commonService.filePreview(variable.get("attachmentId").toString()));
+            otherList.add(vMap);
+        }
+        List<Map> ordinaryList = JSONObject.parseArray(ordinaryContent, Map.class);
+        for (Map ordinary : ordinaryList) {
+            Map vMap = new HashMap();
+            vMap.put("type", ordinary.get("type"));
+            vMap.put("url", commonService.filePreview(ordinary.get("attachmentId").toString()));
+            otherList.add(vMap);
+        }
+        finalMap.put("other", otherList);
+        return finalMap;
+    }
+
+    /**
+     * 根据考场生成试卷map
+     *
+     * @param schoolId
+     * @param examDetailId
+     * @return
+     */
+    public Map<String, String> mapCourseUrl(Long schoolId, Long examDetailId) {
+        List<Map<String, String>> taskDetails = examTaskDetailService.listByExamDetailId(schoolId, examDetailId);
+        Map<String, String> map = new HashMap<>();
+        for (Map<String, String> taskDetail : taskDetails) {
+            String courseCode = taskDetail.get("courseCode");
+            String paperNumber = taskDetail.get("paperNumber");
+            String paperAttachmentIds = taskDetail.get("paperAttachmentIds");
+            List<Map> attachementIds = JSONObject.parseArray(paperAttachmentIds, Map.class);
+            for (Map attaMap : attachementIds) {
+                String name = attaMap.get("name").toString();
+                String attachmentId = attaMap.get("attachmentId").toString();
+                BasicAttachment attachment = basicAttachmentService.getById(attachmentId);
+                String url = commonService.filePreview(attachment.getPath());
+                StringJoiner sj = new StringJoiner(":");
+                String key = sj.add(courseCode).add(paperNumber).add(name).toString();
+                map.put(key, url);
+            }
+        }
+        return map;
+    }
+}

+ 40 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ClientStatusServiceImpl.java

@@ -0,0 +1,40 @@
+package com.qmth.distributed.print.business.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.qmth.distributed.print.business.entity.ClientStatus;
+import com.qmth.distributed.print.business.mapper.ClientStatusMapper;
+import com.qmth.distributed.print.business.service.ClientStatusService;
+import com.qmth.distributed.print.common.contant.SystemConstant;
+import org.springframework.stereotype.Service;
+
+/**
+ * @Date: 2021/4/19.
+ */
+@Service
+public class ClientStatusServiceImpl extends ServiceImpl<ClientStatusMapper, ClientStatus> implements ClientStatusService {
+    @Override
+    public Boolean tagPass(Long schoolId, Long examTaskId, String machineCode, Boolean isPass, Long userId) {
+        QueryWrapper<ClientStatus> queryWrapper = new QueryWrapper<>();
+        queryWrapper.lambda().eq(ClientStatus::getSchoolId, schoolId).eq(ClientStatus::getExamTaskId, examTaskId).eq(ClientStatus::getMachineCode, machineCode);
+        ClientStatus clientStatus = this.getOne(queryWrapper);
+        if(clientStatus != null){
+            clientStatus.setPass(isPass);
+            clientStatus.setUpdateId(userId);
+            clientStatus.setUpdateTime(System.currentTimeMillis());
+            return this.updateById(clientStatus);
+        } else {
+            clientStatus = new ClientStatus();
+            clientStatus.setId(SystemConstant.getDbUuid());
+            clientStatus.setSchoolId(schoolId);
+            clientStatus.setMachineCode(machineCode);
+            clientStatus.setExamTaskId(examTaskId);
+            clientStatus.setTry(true);
+            clientStatus.setTryTime(System.currentTimeMillis());
+            clientStatus.setPass(isPass);
+            clientStatus.setCreateId(userId);
+            clientStatus.setCreateTime(System.currentTimeMillis());
+            return this.save(clientStatus);
+        }
+    }
+}

+ 44 - 9
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/CommonServiceImpl.java

@@ -93,6 +93,9 @@ public class CommonServiceImpl implements CommonService {
     @Autowired
     private SysOrgService sysOrgService;
 
+    @Autowired
+    private BasicAttachmentService basicAttachmentService;
+
     /**
      * 新增用户权限
      *
@@ -316,7 +319,6 @@ public class CommonServiceImpl implements CommonService {
 
     /**
      * 文件预览
-     *
      * @param path
      * @return
      */
@@ -339,6 +341,40 @@ public class CommonServiceImpl implements CommonService {
         return url;
     }
 
+    /**
+     * 文件预览
+     * @param attachmentId 附件ID
+     * @param isExpire url是否带过期时间
+     * @return
+     */
+    @Override
+    public String filePreview(String attachmentId, Boolean isExpire) {
+        BasicAttachment attachment = basicAttachmentService.getById(attachmentId);
+        if(attachment == null){
+            return  null;
+        }
+
+        String url;
+        JSONObject jsonObject = JSONObject.parseObject(attachment.getPath());
+        String attachmentType = (String) jsonObject.get(SystemConstant.TYPE);
+        String filePath = (String) jsonObject.get(SystemConstant.PATH);
+        UploadFileEnum uploadFileEnum = UploadFileEnum.valueOf((String) jsonObject.get(SystemConstant.UPLOAD_TYPE));
+        if (Objects.equals(attachmentType, SystemConstant.LOCAL)) {
+            url = SystemConstant.HTTP + dictionaryConfig.sysDomain().getFileHost() + File.separator + filePath;
+        } else {
+            if (uploadFileEnum == UploadFileEnum.PAPER) {
+                if(isExpire){
+                    url = ossUtil.getPrivateUrl(filePath);
+                } else {
+                    url = ossUtil.getPrivateUrlNotExpire(filePath);
+                }
+            } else {
+                url = dictionaryConfig.aliYunOssDomain().getUrl() + File.separator + filePath;
+            }
+        }
+        return url;
+    }
+
     @Override
     public String readFileContent(String path) {
         // 解析path
@@ -528,25 +564,24 @@ public class CommonServiceImpl implements CommonService {
     }
 
     @Override
-    public Set<Long> listSubOrgIds() {
+    public Set<Long> listSubOrgIds(Long id) {
         SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
-        Long orgId = sysUser.getOrgId();
+        Long orgId;
+        if(id == null){
+            orgId = sysUser.getOrgId();
+        } else {
+            orgId = id;
+        }
         if (orgId == null) {
             return null;
         }
         List<OrgDto> orgDtos = sysOrgService.listOrgTree();
-//        String string = "[{\"id\":\"114751029785919488\",\"schoolId\":\"1\",\"code\":\"012453\",\"name\":\"计算机学院\",\"parentId\":null,\"enable\":true,\"children\":[{\"id\":\"114751144823095296\",\"schoolId\":\"1\",\"code\":\"451245\",\"name\":\"硬件学院\",\"parentId\":114751029785919488,\"enable\":true,\"children\":[]}]},{\"id\":\"114751249978490880\",\"schoolId\":\"1\",\"code\":\"42152\",\"name\":\"化学学院\",\"parentId\":null,\"enable\":true,\"children\":[]},{\"id\":\"114751303661387776\",\"schoolId\":\"1\",\"code\":\"en1254\",\"name\":\"外国语学院\",\"parentId\":null,\"enable\":true,\"children\":[]},{\"id\":\"1\",\"schoolId\":\"1\",\"code\":\"O00001\",\"name\":\"物理学院\",\"parentId\":null,\"enable\":true,\"children\":[{\"id\":\"114751422234361856\",\"schoolId\":\"1\",\"code\":\"784512\",\"name\":\"光电系\",\"parentId\":1,\"enable\":true,\"children\":[{\"id\":\"114751422234361857\",\"schoolId\":\"1\",\"code\":\"784512\",\"name\":\"光电系\",\"parentId\":114751422234361856,\"enable\":true,\"children\":[]},{\"id\":\"114751422234361858\",\"schoolId\":\"1\",\"code\":\"784512\",\"name\":\"光电系\",\"parentId\":114751422234361856,\"enable\":true,\"children\":[]}]}]}]";
-//        List<OrgDto> orgDtos = JSONObject.parseArray(string, OrgDto.class);
         Set<Long> stringSet = new HashSet<>();
         stringSet.add(orgId);
         stringSet = getOrgIds(stringSet, orgDtos, orgId);
         return stringSet;
     }
 
-    public static void main(String[] args) {
-        new CommonServiceImpl().listSubOrgIds();
-    }
-
     private Set<Long> getOrgIds(Set<Long> stringSet, List<OrgDto> orgDtos, Long parentId) {
         for (OrgDto orgDto : orgDtos) {
             Long tempParentId = orgDto.getParentId();

+ 7 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamDetailCourseServiceImpl.java

@@ -1,6 +1,7 @@
 package com.qmth.distributed.print.business.service.impl;
 
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.qmth.distributed.print.business.entity.ExamDetailCourse;
 import com.qmth.distributed.print.business.enums.ExamDetailStatusEnum;
@@ -43,4 +44,10 @@ public class ExamDetailCourseServiceImpl extends ServiceImpl<ExamDetailCourseMap
         List<ExamDetailCourse> examDetailCourses = this.list(examDetailCourseQueryWrapper);
         return examDetailCourses;
     }
+
+    @Override
+    public void updatePaperNumber(List<ExamDetailCourse> examDetailCourses, String paperNumber) {
+        UpdateWrapper<ExamDetailCourse> updateWrapper = new UpdateWrapper<>();
+        updateWrapper.lambda().set(ExamDetailCourse::getPaperNumber, paperNumber).in(ExamDetailCourse::getId, examDetailCourses);
+    }
 }

+ 25 - 2
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamDetailServiceImpl.java

@@ -98,7 +98,7 @@ public class ExamDetailServiceImpl extends ServiceImpl<ExamDetailMapper, ExamDet
     @Override
     public IPage<PrintTaskDto> listPrintTask(Long printPlanId, String status, String courseCode, String paperNumber, String examPlace, String examRoom, Long examStartTime, Long examEndTime, Integer pageNumber, Integer pageSize) {
         Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
-        Set<Long> orgIds = commonService.listSubOrgIds();
+        Set<Long> orgIds = commonService.listSubOrgIds(null);
         Page<PrintTaskDto> page = new Page<>(pageNumber, pageSize);
         IPage<PrintTaskDto> pirntTaskDtoIPage = this.baseMapper.listPrintTask(page, schoolId, printPlanId, status, courseCode, paperNumber, examPlace, examRoom, examStartTime, examEndTime, orgIds);
         return pirntTaskDtoIPage;
@@ -375,7 +375,7 @@ public class ExamDetailServiceImpl extends ServiceImpl<ExamDetailMapper, ExamDet
             System.out.println("totalSubjects" + totalSubjects);
             ExamDetail examDetail = new ExamDetail();
             examDetail.setId(SystemConstant.getDbUuid());
-            examDetail.setPackageCode(convertUtil.getIncre(serialNumberParams.getPrefix(),serialNumberParams.getModel(),serialNumberParams.getDigit()));
+            examDetail.setPackageCode(convertUtil.getIncre(serialNumberParams.getPrefix(), serialNumberParams.getModel(), serialNumberParams.getDigit()));
             examDetail.setSchoolId(Long.valueOf(String.valueOf(map.get("schoolId"))));
             examDetail.setPrintPlanId(Long.valueOf(String.valueOf(map.get("printPlanId"))));
             examDetail.setPrintPlanName(String.valueOf(map.get("printPlanName")));
@@ -574,6 +574,29 @@ public class ExamDetailServiceImpl extends ServiceImpl<ExamDetailMapper, ExamDet
         return examinationExportDtoList;
     }
 
+    //    @Transactional
+    @Override
+    public Boolean updatePrintProgress(Long schoolId, Long examDetailId, Integer printProgress) {
+        // 更新考场进度、状态
+        UpdateWrapper<ExamDetail> updateWrapper = new UpdateWrapper<>();
+        updateWrapper.lambda().set(ExamDetail::getPrintProgress, printProgress).set(ExamDetail::getStatus, ExamDetailStatusEnum.FINISH).eq(ExamDetail::getId, examDetailId);
+        return this.update(updateWrapper);
+        // todo 更新考生(是否需要这个字段,待定)
+
+    }
+
+    @Override
+    public IPage<ClientExamStudentDto> listStudent(Long schoolId, Long examDetailId, String ticketNumber, String studentName, String courseCode, Integer pageNumber, Integer pageSize) {
+        Page<ClientExamStudentDto> page = new Page<>(pageNumber, pageSize);
+        IPage<ClientExamStudentDto> examStudentDtoIPage = this.baseMapper.listClientExamStudentPage(page, schoolId, examDetailId, ticketNumber, studentName, courseCode);
+        return examStudentDtoIPage;
+    }
+
+    @Override
+    public List<Map<String, String>> listStudentByExamDetailId(Long schoolId, Long examDetailId, String ticketNumber, String type) {
+        return this.baseMapper.listStudentByExamDetailId(schoolId, examDetailId, ticketNumber, type);
+    }
+
     @Transactional(rollbackFor = Exception.class)
     @Override
     public void deleteExaminationData(Long printPlanId) {

+ 9 - 2
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamPrintPlanServiceImpl.java

@@ -21,6 +21,7 @@ import com.qmth.distributed.print.business.service.*;
 import com.qmth.distributed.print.business.util.ServletUtil;
 import com.qmth.distributed.print.common.contant.SystemConstant;
 import com.qmth.distributed.print.common.enums.ExceptionResultEnum;
+import io.swagger.annotations.Example;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -60,7 +61,7 @@ public class ExamPrintPlanServiceImpl extends ServiceImpl<ExamPrintPlanMapper, E
     @Transactional(rollbackFor = Exception.class)
     @Override
     public IPage<PrintPlanResult> printPlanPage(Long schoolId, Long printPlanId, PrintPlanStatusEnum status, Long startTime, Long endTime, int pageNumber, int pageSize) {
-        Set<Long> orgIds = commonService.listSubOrgIds();
+        Set<Long> orgIds = commonService.listSubOrgIds(null);
         IPage<PrintPlanResult> page = examPrintPlanMapper.findPrintPlanPage(new Page<>(pageNumber, pageSize), schoolId, printPlanId, status, startTime, endTime, orgIds);
         List<PrintPlanResult> list = page.getRecords();
         for (PrintPlanResult printPlanResult : list) {
@@ -89,7 +90,7 @@ public class ExamPrintPlanServiceImpl extends ServiceImpl<ExamPrintPlanMapper, E
             printPlanBriefList.add(new PrintPlanBrief(id, name ,status));
         }*/
         Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
-        Set<Long> orgIds = commonService.listSubOrgIds();
+        Set<Long> orgIds = commonService.listSubOrgIds(null);
         List<PrintPlanBrief> list = this.baseMapper.list(schoolId, orgIds);
         return list;
     }
@@ -235,6 +236,12 @@ public class ExamPrintPlanServiceImpl extends ServiceImpl<ExamPrintPlanMapper, E
         return this.removeById(id);
     }
 
+    @Override
+    public List<Map<String, String>> tempalteView(Long printPlanId) {
+        ExamPrintPlan examPrintPlan = this.getById(printPlanId);
+        return null;
+    }
+
     /**
      * 查找子机构
      *

+ 44 - 5
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamTaskDetailServiceImpl.java

@@ -1,5 +1,6 @@
 package com.qmth.distributed.print.business.service.impl;
 
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -15,6 +16,7 @@ import com.qmth.distributed.print.business.service.*;
 import com.qmth.distributed.print.business.templete.execute.AsyncCreatePdfTempleteService;
 import com.qmth.distributed.print.business.util.ServletUtil;
 import com.qmth.distributed.print.common.enums.ExceptionResultEnum;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -55,6 +57,9 @@ public class ExamTaskDetailServiceImpl extends ServiceImpl<ExamTaskDetailMapper,
     @Resource
     private AsyncCreatePdfTempleteService asyncCreatePdfTempleteService;
 
+    @Autowired
+    private BasicAttachmentService basicAttachmentService;
+
     @Resource
     TBTaskService tbTaskService;
 
@@ -77,17 +82,20 @@ public class ExamTaskDetailServiceImpl extends ServiceImpl<ExamTaskDetailMapper,
             throw ExceptionResultEnum.ERROR.exception("有考场已开始打印,不能修改");
         }
 
-        /* // 异常任务中修改类型
         // 更新关联卷型
+        ExamTask newExamTask = examTaskService.getByCourseCodeAndPaperNumber(examTask.getSchoolId(), examTask.getCourseCode(), paperParam.getPaperNumber());
         UpdateWrapper<ExamTaskDetail> updateWrapper = new UpdateWrapper<>();
-        updateWrapper.lambda().set(ExamTaskDetail::getRelatePaperType, paperParam.getRelatePaperType()).eq(ExamTaskDetail::getExamTaskId, paperParam.getExamTaskId());
+        updateWrapper.lambda().set(ExamTaskDetail::getRelatePaperType, paperParam.getRelatePaperType()).eq(ExamTaskDetail::getExamTaskId, newExamTask.getId());
         this.update(updateWrapper);
 
+        // 更新试卷编号
+        List<ExamDetailCourse> examDetailCourses = examDetailCourseService.listDetailCourseByCourseCodeAndPaperNumber(examTask.getSchoolId(), examTask.getCourseCode(), examTask.getPaperNumber());
+        examDetailCourseService.updatePaperNumber(examDetailCourses, paperParam.getPaperNumber());
+
         // 更新考生关联类型
-        examStudentService.updatePaperType(examDetailCourses, paperParam.getRelatePaperType());*/
+        examStudentService.updatePaperType(examDetailCourses, paperParam.getRelatePaperType());
 
         // 重新生成pdf
-        List<ExamDetailCourse> examDetailCourses = examDetailCourseService.listDetailCourseByCourseCodeAndPaperNumber(examTask.getSchoolId(), examTask.getCourseCode(), examTask.getPaperNumber());
         List<Long> examDetailCourseIds = examDetailCourses.stream().map(m -> m.getId()).collect(Collectors.toList());
         SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
         Map<String, Object> map = tbTaskService.saveTask(TaskTypeEnum.CREATE_PDF, paperParam.getPrintPlanId(), sysUser);
@@ -100,7 +108,7 @@ public class ExamTaskDetailServiceImpl extends ServiceImpl<ExamTaskDetailMapper,
     @Override
     public IPage<ExamTaskDetailDto> list(String relateType, Long printPlanId, String courseCode, String paperNumber, Integer pageNumber, Integer pageSize) {
         Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
-        Set<Long> orgIds = commonService.listSubOrgIds();
+        Set<Long> orgIds = commonService.listSubOrgIds(null);
         Page<ExamTaskDetailDto> page = new Page<>(pageNumber, pageSize);
         IPage<ExamTaskDetailDto> examDetailDtoIPage = this.baseMapper.listPage(page, schoolId, relateType, printPlanId, courseCode, paperNumber, orgIds);
         return examDetailDtoIPage;
@@ -132,4 +140,35 @@ public class ExamTaskDetailServiceImpl extends ServiceImpl<ExamTaskDetailMapper,
         return this.baseMapper.listByTemplateId(templateId);
     }
 
+    @Override
+    public String getUrl(Long schoolId, Long examTaskId) {
+        QueryWrapper<ExamTaskDetail> examTaskDetailQueryWrapper = new QueryWrapper<>();
+        examTaskDetailQueryWrapper.lambda().eq(ExamTaskDetail::getExamTaskId, examTaskId);
+        ExamTaskDetail examTaskDetail = this.getById(examTaskDetailQueryWrapper);
+        if(examTaskDetail != null){
+            String relatePaperType = examTaskDetail.getRelatePaperType();
+            if(StringUtils.isNotBlank(relatePaperType)){
+                String paperAttachmentIds = examTaskDetail.getPaperAttachmentIds();
+                List<Map> list = JSONObject.parseArray(paperAttachmentIds, Map.class);
+                String attachmentId = null;
+                for (Map map : list) {
+                    String name = map.get("name").toString();
+                    if(relatePaperType.equals(name)){
+                        attachmentId = map.get("attachmentId").toString();
+                    }
+                }
+                if(StringUtils.isNotBlank(attachmentId)){
+                    BasicAttachment attachment = basicAttachmentService.getById(attachmentId);
+                    return attachment == null ? null : commonService.filePreview(attachment.getPath());
+                }
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public List<Map<String, String>> listByExamDetailId(Long schoolId, Long examDetailId) {
+        return this.baseMapper.listByExamDetailId(schoolId, examDetailId);
+    }
+
 }

+ 101 - 24
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamTaskServiceImpl.java

@@ -1,5 +1,6 @@
 package com.qmth.distributed.print.business.service.impl;
 
+import cn.hutool.core.date.DateUtil;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
@@ -17,6 +18,7 @@ import com.qmth.distributed.print.business.enums.ExamStatusEnum;
 import com.qmth.distributed.print.business.enums.ReviewStatusEnum;
 import com.qmth.distributed.print.business.mapper.ExamTaskMapper;
 import com.qmth.distributed.print.business.service.*;
+import com.qmth.distributed.print.business.util.ConvertUtil;
 import com.qmth.distributed.print.business.util.ExcelUtil;
 import com.qmth.distributed.print.business.util.ServletUtil;
 import com.qmth.distributed.print.business.util.excel.ExcelError;
@@ -83,6 +85,9 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
     @Autowired
     private ExamPrintPlanService examPrintPlanService;
 
+    @Autowired
+    private ConvertUtil convertUtil;
+
     @Override
     public List<ExamTask> listByCourseCode(Long schoolId, String code) {
         QueryWrapper<ExamTask> queryWrapper = new QueryWrapper<>();
@@ -93,7 +98,7 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
     @Override
     public IPage<ExamTaskDto> list(Boolean enable, String status, Long cardRuleId, String courseCode, String paperNumber, Long startTime, Long endTime, Integer pageNumber, Integer pageSize) {
         Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
-        Set<Long> orgIds = commonService.listSubOrgIds();
+        Set<Long> orgIds = commonService.listSubOrgIds(null);
         Page<ExamTaskDto> page = new Page<>(pageNumber, pageSize);
         IPage<ExamTaskDto> examTaskDtoIPage = this.baseMapper.listPage(page, schoolId, enable, status, cardRuleId, courseCode, paperNumber, startTime, endTime, orgIds);
         return examTaskDtoIPage;
@@ -178,7 +183,7 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
         if (examTask.getEnable()) {
             updateWrapper.lambda().set(ExamTask::getEnable, examTask.getEnable()) // 修改启用状态
                     .set(ExamTask::getReviewStatus, null) // 清空审核状态
-                    .set(ExamTask::getStatus, ExamStatusEnum.STAGE) // 更新为命题中
+                    .set(ExamTask::getStatus, task.getStatus().equals(ExamStatusEnum.NEW) || task.getStatus().equals(ExamStatusEnum.READY) ? task.getStatus() : ExamStatusEnum.STAGE) // 更新为命题中
                     .eq(ExamTask::getId, examTask.getId());
         } else {
             updateWrapper.lambda().set(ExamTask::getEnable, examTask.getEnable()).eq(ExamTask::getId, examTask.getId());
@@ -197,16 +202,18 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
         examTask.setSchoolId(schoolId);
         SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
 
-        if(StringUtils.isNotBlank(examTask.getPaperNumber())){
+        if (StringUtils.isNotBlank(examTask.getPaperNumber())) {
             QueryWrapper<ExamTask> taskQueryWrapper = new QueryWrapper<>();
             taskQueryWrapper.lambda().eq(ExamTask::getSchoolId, schoolId).eq(ExamTask::getPaperNumber, examTask.getPaperNumber());
             ExamTask task = this.getOne(taskQueryWrapper);
-            if(task != null){
+            if (task != null) {
                 throw ExceptionResultEnum.ERROR.exception("试卷编号已存在");
             }
         } else {
-            // todo paperNumber生成问题, 必填字段校验
-
+            // 试卷编号生成规则:年月日(例如:20100419)+0000(例如:0001)顺序编号
+            String date = DateUtil.today().replace("-", "");
+            String paperNumber = convertUtil.getIncre(date, "paperNumber" + schoolId, 5);
+            examTask.setPaperNumber(paperNumber);
         }
 
         QueryWrapper<BasicExamRule> queryWrapper = new QueryWrapper<>();
@@ -253,13 +260,9 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
                     BasicCourse course = basicCourseService.getOne(queryWrapper);
                     if (course == null) {
                         excelErrorTemp.add(new ExcelError(y + 1, "excel第" + (i + 1) + "个sheet第" + (y + 1) + "行[课程代码]在系统中不存在"));
-                    } else if (!userImportDto.getCourseName().equals(course.getName())) {
+                    } else if (!course.getName().equals(userImportDto.getCourseName())) {
                         excelErrorTemp.add(new ExcelError(y + 1, "excel第" + (i + 1) + "个sheet第" + (y + 1) + "行[课程名称]与系统中不匹配"));
                     }
-
-                    if (StringUtils.isBlank(userImportDto.getPaperNumber())) {
-                        excelErrorTemp.add(new ExcelError(y + 1, "excel第" + (i + 1) + "个sheet第" + (y + 1) + "行[试卷编号]必填"));
-                    }
                 }
             }
             if (excelErrorTemp.size() > 0) {
@@ -282,6 +285,9 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
         ExamTaskImportDto examTaskImportDto = new ExamTaskImportDto();
         examTaskImportDto.setBatchNo(batchNo);
         List<ExamTaskDto> tasks = new ArrayList<>();
+        Set<String> paperNumbers = new HashSet<>();
+        // 错误信息
+        StringJoiner stringJoiner = new StringJoiner(";");
         for (int i = 0; i < finalList.size(); i++) {
             LinkedMultiValueMap<Integer, Object> excelMap = finalList.get(i);
             List<Object> examTaskTempList = excelMap.get(i);
@@ -296,6 +302,25 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
                 //保存
                 examTaskTempService.save(examTaskTemp);
 
+                if (StringUtils.isNotBlank(examTaskTemp.getPaperNumber())) {
+                    if (paperNumbers.contains(examTaskTemp.getPaperNumber())) {
+                        // 试卷编号在文件内重复,跳过
+                        String error = examTaskTemp.getPaperNumber() + "文件中重复";
+                        stringJoiner.add(error);
+                        continue;
+                    }
+                    QueryWrapper<ExamTask> taskQueryWrapper = new QueryWrapper<>();
+                    taskQueryWrapper.lambda().eq(ExamTask::getSchoolId, schoolId).eq(ExamTask::getPaperNumber, examTaskTemp.getPaperNumber());
+                    ExamTask task1 = this.getOne(taskQueryWrapper);
+                    if (task1 != null) {
+                        // 试卷编号已存在,直接跳过
+                        String error = examTaskTemp.getPaperNumber() + "已存在";
+                        stringJoiner.add(error);
+                        continue;
+                    }
+                    paperNumbers.add(examTaskTemp.getPaperNumber());
+                }
+
                 ExamTaskDto examTaskDto = new ExamTaskDto();
                 examTaskDto.setCourseCode(examTaskTemp.getCourseCode());
                 examTaskDto.setCourseName(examTaskTemp.getCourseName());
@@ -317,6 +342,8 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
                 tasks.add(examTaskDto);
             }
         }
+        // 设置重复信息,页面做二次校验
+        examTaskImportDto.setErrorMsg(stringJoiner.toString());
         examTaskImportDto.setTasks(tasks);
         return examTaskImportDto;
     }
@@ -337,17 +364,46 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
         QueryWrapper<ExamTaskTemp> queryWrapper = new QueryWrapper<>();
         queryWrapper.lambda().eq(ExamTaskTemp::getBatchNo, task.getBatchNo());
         List<ExamTaskTemp> examTaskTemps = examTaskTempService.list(queryWrapper);
+
+        QueryWrapper<BasicExamRule> examQueryWrapper = new QueryWrapper<>();
+        examQueryWrapper.lambda().eq(BasicExamRule::getSchoolId, schoolId);
+        BasicExamRule basicExamRule = basicExamRuleService.getOne(examQueryWrapper);
+        if (basicExamRule == null) {
+            throw ExceptionResultEnum.ERROR.exception("通用规则未设置");
+        }
+
         if (examTaskTemps.isEmpty()) {
             throw ExceptionResultEnum.ERROR.exception("没有可保存数据");
         }
         List<ExamTask> list = new ArrayList<>();
+        Set<String> paperNumbers = new HashSet<>();
         for (ExamTaskTemp examTaskTemp : examTaskTemps) {
             ExamTask examTask = new ExamTask();
             examTask.setSchoolId(task.getSchoolId());
             examTask.setCourseCode(examTaskTemp.getCourseCode());
             examTask.setCourseName(examTaskTemp.getCourseName());
             examTask.setSpecialty(examTaskTemp.getSpecialty());
-            // todo paperNumber自动生成。校验paperNumber是否重复
+
+            if (StringUtils.isNotBlank(examTaskTemp.getPaperNumber())) {
+                if (paperNumbers.contains(examTaskTemp.getPaperNumber())) {
+                    // 试卷编号在文件内重复,跳过
+                    continue;
+                }
+                QueryWrapper<ExamTask> taskQueryWrapper = new QueryWrapper<>();
+                taskQueryWrapper.lambda().eq(ExamTask::getSchoolId, schoolId).eq(ExamTask::getPaperNumber, examTaskTemp.getPaperNumber());
+                ExamTask task1 = this.getOne(taskQueryWrapper);
+                if (task1 != null) {
+//                    throw ExceptionResultEnum.ERROR.exception("试卷编号已存在");
+                    // 试卷编号已存在,直接跳过
+                    continue;
+                }
+                paperNumbers.add(examTaskTemp.getPaperNumber());
+            } else {
+                // 试卷编号生成规则:年月日(例如:20100419)+0000(例如:0001)顺序编号
+                String date = DateUtil.today().replace("-", "");
+                String paperNumber = convertUtil.getIncre(date, "paperNumber" + schoolId, 5);
+                examTask.setPaperNumber(paperNumber);
+            }
             examTask.setPaperNumber(examTaskTemp.getPaperNumber());
             examTask.setStartTime(task.getStartTime());
             examTask.setEndTime(task.getEndTime());
@@ -356,18 +412,30 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
             examTask.setBatchNo(task.getBatchNo());
             examTask.setCreateId(sysUser.getId());
             examTask.setCreateTime(System.currentTimeMillis());
-            String userId = task.getUsers().stream().map(m -> {
-                if (examTaskTemp.getCourseCode().equals(m.get("courseCode"))) {
+            /*String userId = task.getUsers().stream().map(m -> {
+                if (examTaskTemp.getCourseCode().equals(m.get("courseCode")) && examTaskTemp.getPaperNumber().equals(m.get("paperNumber"))) {
                     return m.get("userId");
                 }
                 return "";
-            }).findFirst().get();
+            }).findFirst().get();*/
+            String userId = null;
+            String specialty = null;
+            for (Map<String, String> user : task.getUsers()) {
+                String ucourseCode = user.get("courseCode");
+                String upaperNumber = user.get("paperNumber");
+                if (examTaskTemp.getCourseCode().equals(ucourseCode) && examTaskTemp.getPaperNumber().equals(upaperNumber)) {
+                    userId = user.get("userId");
+                    specialty = user.get("specialty");
+                }
+            }
+            examTask.setSpecialty(specialty);
             if (StringUtils.isNotBlank(userId)) {
                 examTask.setUserId(Long.valueOf(userId));
                 examTask.setStatus(ExamStatusEnum.READY);
             } else {
                 examTask.setStatus(ExamStatusEnum.NEW);
             }
+            examTask.setReview(basicExamRule.getReview());
             list.add(examTask);
         }
         return this.saveBatch(list);
@@ -377,16 +445,17 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
     public IPage<ExamTaskDto> listTaskApply(String auditStatus, String reviewStatus, Long cardRuleId, String courseCode, String paperNumber, Long startTime, Long endTime, Integer pageNumber, Integer pageSize) {
         Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
         SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
+        Set<Long> orgIds = commonService.listSubOrgIds(null);
         Page<ExamTaskDto> page = new Page<>(pageNumber, pageSize);
-        String[] strings = new String[]{ExamStatusEnum.NEW.name(), ExamStatusEnum.SUBMIT.name(), ExamStatusEnum.FINISH.name()};
-        IPage<ExamTaskDto> examTaskDtoIPage = this.baseMapper.listTaskApply(page, schoolId, auditStatus, reviewStatus, cardRuleId, courseCode, paperNumber, startTime, endTime, strings, sysUser.getId());
+        String[] strings = new String[]{ExamStatusEnum.NEW.name(), ExamStatusEnum.SUBMIT.name()};
+        IPage<ExamTaskDto> examTaskDtoIPage = this.baseMapper.listTaskApply(page, schoolId, auditStatus, reviewStatus, cardRuleId, courseCode, paperNumber, startTime, endTime, strings, sysUser.getId(), orgIds);
         return examTaskDtoIPage;
     }
 
     @Override
     public IPage<ExamTaskDto> listTaskReviewUnaudited(String courseCode, String paperNumber, Long userId, Long cardRuleId, Long startTime, Long endTime, Integer pageNumber, Integer pageSize) {
         Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
-        Set<Long> orgIds = commonService.listSubOrgIds();
+        Set<Long> orgIds = commonService.listSubOrgIds(null);
         Page<ExamTaskDto> page = new Page<>(pageNumber, pageSize);
         IPage<ExamTaskDto> examTaskDtoIPage = this.baseMapper.listTaskReviewUnaudited(page, schoolId, courseCode, paperNumber, userId, cardRuleId, startTime, endTime, orgIds);
         return examTaskDtoIPage;
@@ -395,7 +464,7 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
     @Override
     public IPage<ExamTaskDto> listTaskReviewAudited(String reviewStatus, String courseCode, String paperNumber, Long userId, Long cardRuleId, Long startTime, Long endTime, Integer pageNumber, Integer pageSize) {
         Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
-        Set<Long> orgIds = commonService.listSubOrgIds();
+        Set<Long> orgIds = commonService.listSubOrgIds(null);
         Page<ExamTaskDto> page = new Page<>(pageNumber, pageSize);
         IPage<ExamTaskDto> examTaskDtoIPage = this.baseMapper.listTaskReviewAudited(page, schoolId, reviewStatus, courseCode, paperNumber, userId, cardRuleId, startTime, endTime, orgIds);
         return examTaskDtoIPage;
@@ -418,7 +487,7 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
             statusEnum = ExamStatusEnum.FINISH;
             // 校验是否可以提交打印状态
             ExamTask examTask = this.getById(taskReviewLog.getExamTaskId());
-            commonService.checkData(examTask.getSchoolId(), examTask.getCourseCode(), examTask.getPaperNumber(),sysUser);
+            commonService.checkData(examTask.getSchoolId(), examTask.getCourseCode(), examTask.getPaperNumber(), sysUser);
         } else {
             statusEnum = ExamStatusEnum.STAGE;
         }
@@ -455,7 +524,7 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
     @Override
     public IPage<ExamTaskDetailDto> listTaskPaper(String courseCode, String paperNumber, Long startTime, Long endTime, Integer pageNumber, Integer pageSize) {
         Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
-        Set<Long> orgIds = commonService.listSubOrgIds();
+        Set<Long> orgIds = commonService.listSubOrgIds(null);
         Page<ExamTaskDetailDto> page = new Page<>(pageNumber, pageSize);
         IPage<ExamTaskDetailDto> examTaskDtoIPage = this.baseMapper.listTaskPaper(page, schoolId, courseCode, paperNumber, startTime, endTime, orgIds);
         return examTaskDtoIPage;
@@ -488,7 +557,7 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
             RelatePaperDto relatePaperDto = new RelatePaperDto();
             // 抽取一次
             String paperTypes;
-            if (DrawRuleEnum.ONE.equals(drawRule)){
+            if (DrawRuleEnum.ONE.equals(drawRule)) {
                 // 未曝光类型
                 paperTypes = examTaskDetail.getUnexposedPaperType();
             } else {
@@ -527,7 +596,7 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
 
             // 校验题卡是否提交
             ExamCard examCard = examCardService.getById(examTaskDetail.getCardId());
-            if(!ExamCardStatusEnum.SUBMIT.name().equals(examCard.getStatus().name())){
+            if (!ExamCardStatusEnum.SUBMIT.name().equals(examCard.getStatus().name())) {
                 throw ExceptionResultEnum.ERROR.exception("请先提交题卡");
             }
         }
@@ -537,7 +606,7 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
         if (examTask.getStatus().name().equals(ExamStatusEnum.SUBMIT.name()) && !examTask.getReview()) {
             examTask.setStatus(ExamStatusEnum.FINISH);
             // 校验是否可以提交打印状态
-            commonService.checkData(examTask.getSchoolId(), examTask.getCourseCode(), examTask.getPaperNumber(),(SysUser) ServletUtil.getRequestUser());
+            commonService.checkData(examTask.getSchoolId(), examTask.getCourseCode(), examTask.getPaperNumber(), (SysUser) ServletUtil.getRequestUser());
         }
 
         UpdateWrapper<ExamTask> updateWrapper = new UpdateWrapper<>();
@@ -662,4 +731,12 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
                 .eq(ExamTask::getPaperNumber, paperNumber);
         return this.getOne(queryWrapper);
     }
+
+    @Override
+    public IPage<ClientExamTaskDto> listTryTask(Long schoolId, String machineCode, Long orgId, Long printPlanId, String courseCode, String paperNumber, Boolean isTry, Boolean isPass, Integer pageNumber, Integer pageSize) {
+        Set<Long> orgIds = commonService.listSubOrgIds(orgId);
+        Page<ClientExamTaskDto> page = new Page<>(pageNumber, pageSize);
+        IPage<ClientExamTaskDto> examTaskDtoIPage = this.baseMapper.listClientExamTaskPage(page, schoolId, machineCode, printPlanId, courseCode, paperNumber, isTry, isPass, orgIds);
+        return examTaskDtoIPage;
+    }
 }

+ 1 - 1
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/SysUserServiceImpl.java

@@ -256,7 +256,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
     @Override
     public List<BlurryUserDto> listUser(String courseCode, String param) {
         Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
-        Set<Long> orgIds = commonService.listSubOrgIds();
+        Set<Long> orgIds = commonService.listSubOrgIds(null);
         return this.baseMapper.listUser(schoolId, RoleTypeEnum.QUESTION_TEACHER.name(), courseCode, param, orgIds);
     }
 

+ 1 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/execute/AsyncDownloadPdfTempleteService.java

@@ -31,6 +31,7 @@ public class AsyncDownloadPdfTempleteService extends AsyncExportTaskTemplete {
     private final static Logger log = LoggerFactory.getLogger(AsyncCreatePdfTempleteService.class);
 
     static final String OBJ_TITLE = "zip数据";
+
     /**
      * 下载pdf
      *

+ 2 - 2
distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/execute/AsyncExaminationExportTemplateService.java

@@ -7,6 +7,7 @@ import com.qmth.distributed.print.business.enums.TaskStatusEnum;
 import com.qmth.distributed.print.business.enums.TaskTypeEnum;
 import com.qmth.distributed.print.business.templete.export.AsyncExportTaskTemplete;
 import com.qmth.distributed.print.business.templete.service.TaskLogicService;
+import com.qmth.distributed.print.common.contant.SpringContextHolder;
 import com.qmth.distributed.print.common.contant.SystemConstant;
 import com.qmth.distributed.print.common.util.Result;
 import com.qmth.distributed.print.common.util.ResultUtil;
@@ -26,8 +27,6 @@ import java.util.StringJoiner;
  */
 @Service
 public class AsyncExaminationExportTemplateService extends AsyncExportTaskTemplete {
-    @Resource
-    TaskLogicService taskLogicService;
 
     public static final String OBJ_TITLE = "考务数据";
     private final static Logger log = LoggerFactory.getLogger(AsyncExaminationExportTemplateService.class);
@@ -42,6 +41,7 @@ public class AsyncExaminationExportTemplateService extends AsyncExportTaskTemple
 
 
         try {
+            TaskLogicService taskLogicService = SpringContextHolder.getBean(TaskLogicService.class);
             Map<String, Object> result = taskLogicService.executeExaminationLogic(map);
             stringJoinerSummary.add(MessageFormat.format("{0}{1}{2}{3}", FORMAT_TIME, FINISH_TITLE, result.size(), FINISH_SIZE));
             String path = String.valueOf(result.get("path"));

+ 2 - 4
distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/execute/AsyncExaminationImportTemplateService.java

@@ -6,6 +6,7 @@ import com.qmth.distributed.print.business.enums.TaskResultEnum;
 import com.qmth.distributed.print.business.enums.TaskStatusEnum;
 import com.qmth.distributed.print.business.templete.importData.AsyncImportTaskTemplete;
 import com.qmth.distributed.print.business.templete.service.TaskLogicService;
+import com.qmth.distributed.print.common.contant.SpringContextHolder;
 import com.qmth.distributed.print.common.contant.SystemConstant;
 import com.qmth.distributed.print.common.util.Result;
 import com.qmth.distributed.print.common.util.ResultUtil;
@@ -13,7 +14,6 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Service;
 
-import javax.annotation.Resource;
 import java.io.InputStream;
 import java.text.MessageFormat;
 import java.util.Map;
@@ -26,9 +26,6 @@ import java.util.StringJoiner;
  */
 @Service
 public class AsyncExaminationImportTemplateService extends AsyncImportTaskTemplete {
-    @Resource
-    private TaskLogicService taskLogicService;
-
     private final static Logger log = LoggerFactory.getLogger(AsyncExaminationImportTemplateService.class);
 
     public static final String OBJ_TITLE = "考务数据";
@@ -44,6 +41,7 @@ public class AsyncExaminationImportTemplateService extends AsyncImportTaskTemple
         tbTask.setStatus(TaskStatusEnum.RUNNING);
 
         try {
+            TaskLogicService taskLogicService = SpringContextHolder.getBean(TaskLogicService.class);
             Map<String,Object> result = taskLogicService.executeImportExaminationLogic(map);
             stringJoinerSummary.add(MessageFormat.format("{0}{1}{2}{3}", FORMAT_TIME, FINISH_TITLE, Long.valueOf(String.valueOf(result.get("dataCount"))), FINISH_SIZE));
             tbTask.setResult(TaskResultEnum.SUCCESS);

+ 64 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/execute/AsyncTaskReviewSampleExportService.java

@@ -0,0 +1,64 @@
+package com.qmth.distributed.print.business.templete.execute;
+
+import com.qmth.boot.api.exception.ApiException;
+import com.qmth.distributed.print.business.entity.TBTask;
+import com.qmth.distributed.print.business.enums.TaskResultEnum;
+import com.qmth.distributed.print.business.enums.TaskStatusEnum;
+import com.qmth.distributed.print.business.enums.TaskTypeEnum;
+import com.qmth.distributed.print.business.templete.export.AsyncExportTaskTemplete;
+import com.qmth.distributed.print.business.templete.service.TaskLogicService;
+import com.qmth.distributed.print.common.contant.SpringContextHolder;
+import com.qmth.distributed.print.common.contant.SystemConstant;
+import com.qmth.distributed.print.common.util.Result;
+import com.qmth.distributed.print.common.util.ResultUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.text.MessageFormat;
+import java.util.Map;
+import java.util.StringJoiner;
+
+/**
+ * @Description: 异步任务-命题任务审核样本导出
+ * @Author: CaoZixuan
+ * @Date: 2021-04-19
+ */
+@Service
+public class AsyncTaskReviewSampleExportService extends AsyncExportTaskTemplete {
+    @Resource
+    TaskLogicService taskLogicService;
+
+    public static final String OBJ_TITLE = "审核样本导出";
+    private final static Logger log = LoggerFactory.getLogger(AsyncTaskReviewSampleExportService.class);
+
+    @Override
+    public Result exportTask(Map<String, Object> map) throws Exception {
+        TBTask tbTask = (TBTask) map.get(SystemConstant.TASK);
+
+        StringJoiner stringJoinerSummary = new StringJoiner("\n")
+                .add(MessageFormat.format("{0}{1}{2}", FORMAT_TIME, BEGIN_TITLE, OBJ_TITLE));
+        tbTask.setStatus(TaskStatusEnum.RUNNING);
+
+        try {
+            TaskLogicService taskLogicService = SpringContextHolder.getBean(TaskLogicService.class);
+            Map<String, Object> result = taskLogicService.executeExportSampleLogic(map);
+            stringJoinerSummary.add(MessageFormat.format("{0}{1}{2}{3}", FORMAT_TIME, FINISH_TITLE, Long.valueOf(String.valueOf(result.get("count"))), FINISH_SIZE));
+            tbTask.setResult(TaskResultEnum.SUCCESS);
+        } catch (Exception e) {
+            log.error("请求出错", e);
+            stringJoinerSummary.add(MessageFormat.format("{0}{1}{2}{3}", FORMAT_TIME, 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();
+    }
+}

+ 7 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/service/TaskLogicService.java

@@ -38,4 +38,11 @@ public interface TaskLogicService {
      * @throws IOException
      */
     public Map<String, Object> executeDownloadPdfLogic(Map<String, Object> map) throws Exception;
+
+    /**
+     * 处理导出命题任务审核文件
+     * @param map
+     * @return
+     */
+    public Map<String,Object> executeExportSampleLogic(Map<String,Object> map) throws IOException;
 }

+ 181 - 19
distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/service/impl/TaskLogicServiceImpl.java

@@ -1,5 +1,6 @@
 package com.qmth.distributed.print.business.templete.service.impl;
 
+import cn.hutool.core.util.ZipUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
@@ -12,9 +13,7 @@ import com.qmth.distributed.print.business.bean.dto.PdfDto;
 import com.qmth.distributed.print.business.bean.params.ArraysParams;
 import com.qmth.distributed.print.business.bean.params.SerialNumberParams;
 import com.qmth.distributed.print.business.entity.*;
-import com.qmth.distributed.print.business.enums.ExamStatusEnum;
-import com.qmth.distributed.print.business.enums.PrintPlanStatusEnum;
-import com.qmth.distributed.print.business.enums.UploadFileEnum;
+import com.qmth.distributed.print.business.enums.*;
 import com.qmth.distributed.print.business.service.*;
 import com.qmth.distributed.print.business.templete.service.TaskLogicService;
 import com.qmth.distributed.print.business.util.ConvertUtil;
@@ -39,6 +38,7 @@ import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.data.redis.support.atomic.RedisAtomicLong;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.FileCopyUtils;
 
 import javax.annotation.Resource;
 import java.io.*;
@@ -103,6 +103,9 @@ public class TaskLogicServiceImpl implements TaskLogicService {
     @Resource
     CreatePdfUtil createPdfUtil;
 
+    @Resource
+    BasicTemplateService basicTemplateService;
+
     @Resource
     RedisTemplate<String, Object> redisTemplate;
 
@@ -252,7 +255,7 @@ public class TaskLogicServiceImpl implements TaskLogicService {
                                         BasicAttachment basicAttachment = basicAttachmentService.getById(attachmentId);
                                         ftlList.add(commonService.getFile(basicAttachment.getPath(), false));
                                         if (Objects.nonNull(type) && Objects.equals(type.toUpperCase(), "SIGN")) {//签到表
-                                            createPdfUtil.createSignBook(basicAttachment, basicSchool.getName(), examDetailCourse, examStudentList, variablePdfList, (Integer) jsonObjectVariable.get("backupCount"));
+                                            createPdfUtil.createSignBook(basicAttachment, basicSchool.getName(), examDetail, examDetailCourse, examStudentList, variablePdfList, (Integer) jsonObjectVariable.get("backupCount"));
                                         } else if (Objects.nonNull(type) && Objects.equals(type.toUpperCase(), "PACKAGE")) {//卷袋贴
                                             createPdfUtil.createPaperPackage(basicAttachment, basicSchool.getName(), examDetailCourse, examStudentList, variablePdfList, (Integer) jsonObjectVariable.get("backupCount"));
                                         }
@@ -425,25 +428,32 @@ public class TaskLogicServiceImpl implements TaskLogicService {
 
                 Cell cell = row.getCell(index);
                 String cellValue = String.valueOf(ExcelUtil.convert(cell));
-
-                if ("学号".equals(name)) {
+                // TODO: 2021/4/20 可以优化 
+                if (ExaminationDBFieldsEnum.STUDENT_CODE.getDesc().equals(name)) {
                     studentCode = cellValue;
-                } else if ("姓名".equals(name)) {
+                    ConvertUtil.verifyLength(studentCode, 10, ExaminationDBFieldsEnum.STUDENT_CODE.getDesc());
+                } else if (ExaminationDBFieldsEnum.STUDENT_NAME.getDesc().equals(name)) {
                     studentName = cellValue;
-                } else if ("课程代码".equals(name)) {
+                    ConvertUtil.verifyLength(studentName, 15, ExaminationDBFieldsEnum.STUDENT_NAME.getDesc());
+                } else if (ExaminationDBFieldsEnum.COURSE_CODE.getDesc().equals(name)) {
                     courseCode = cellValue;
-                } else if ("课程名称".equals(name)) {
+                    ConvertUtil.verifyLength(courseCode, 10, ExaminationDBFieldsEnum.COURSE_CODE.getDesc());
+                } else if (ExaminationDBFieldsEnum.COURSE_NAME.getDesc().equals(name)) {
                     courseName = cellValue;
-                } else if ("考点".equals(name)) {
+                    ConvertUtil.verifyLength(courseName, 20, ExaminationDBFieldsEnum.COURSE_NAME.getDesc());
+                } else if (ExaminationDBFieldsEnum.EXAM_PLACE.getDesc().equals(name)) {
                     examPlace = cellValue;
-                } else if ("考场".equals(name)) {
+                    ConvertUtil.verifyLength(examPlace, 10, ExaminationDBFieldsEnum.EXAM_PLACE.getDesc());
+                } else if (ExaminationDBFieldsEnum.EXAM_ROOM.getDesc().equals(name)) {
                     examRoom = cellValue;
-                } else if ("考试日期".equals(name)) {
+                    ConvertUtil.verifyLength(examRoom, 10, ExaminationDBFieldsEnum.EXAM_ROOM.getDesc());
+                } else if (ExaminationDBFieldsEnum.EXAM_DATE.getDesc().equals(name)) {
                     examDate = cellValue;
-                } else if ("考试时间".equals(name)) {
+                } else if (ExaminationDBFieldsEnum.EXAM_TIME.getDesc().equals(name)) {
                     examTime = cellValue;
-                } else if ("试卷编号".equals(name)) {
+                } else if (ExaminationDBFieldsEnum.PAPER_NUMBER.getDesc().equals(name)) {
                     paperNumber = cellValue;
+                    ConvertUtil.verifyLength(paperNumber, 15, ExaminationDBFieldsEnum.PAPER_NUMBER.getDesc());
                 } else {
                     if ("primary".equals(level)) {
                         throw ExceptionResultEnum.ERROR.exception("有数据库不需要的必选字段 : " + name);
@@ -484,7 +494,23 @@ public class TaskLogicServiceImpl implements TaskLogicService {
             dataMap.put("printPlanName", printPlanName);
             dataList.add(dataMap);
         }
-        System.out.println("dataList = " + JSON.toJSONString(dataList));
+        // 校验课程代码和试卷编号在印刷计划下是1对1的关系
+        List<String> courseCodeList = dataList.stream().map(e -> String.valueOf(e.get("courseCode"))).distinct().collect(Collectors.toList());
+        List<String> paperNumberList = dataList.stream().map(e -> String.valueOf(e.get("paperNumber"))).distinct().collect(Collectors.toList());
+        for (String courseCode : courseCodeList) {
+            List<String> tmp = dataList.stream().filter(e -> courseCode.equals(String.valueOf(e.get("courseCode"))))
+                    .map(e -> String.valueOf(e.get("paperNumber"))).distinct().collect(Collectors.toList());
+            if (tmp.size() != 1) {
+                throw ExceptionResultEnum.ERROR.exception("课程代码为 " + courseCode + ",对应多个试卷编号 : " + tmp);
+            }
+        }
+        for (String paperNumber : paperNumberList) {
+            List<String> tmp = dataList.stream().filter(e -> paperNumber.equals(String.valueOf(e.get("paperNumber"))))
+                    .map(e -> String.valueOf(e.get("courseCode"))).distinct().collect(Collectors.toList());
+            if (tmp.size() != 1) {
+                throw ExceptionResultEnum.ERROR.exception("试卷编号为 " + paperNumber + ",对应多个课程代码 : " + tmp);
+            }
+        }
 
         // 删除印刷计划下的考务数据
         examDetailService.deleteExaminationData(printPlanId);
@@ -545,14 +571,12 @@ public class TaskLogicServiceImpl implements TaskLogicService {
             }
 
             //查询examDetail
-            QueryWrapper<ExamDetail> examDetailQueryWrapper = new QueryWrapper<>();
-            examDetailQueryWrapper.lambda().in(ExamDetail::getPrintPlanId, arraysParams.getIds());
-            List<ExamDetail> examDetailList = examDetailService.list(examDetailQueryWrapper);
+            List<ExamDetail> examDetailList = examDetailService.listByIds(Arrays.asList(arraysParams.getIds()));
             if (Objects.nonNull(examDetailList)) {
                 Set<Long> attachmentIds = examDetailList.stream().map(ExamDetail::getAttachmentId).collect(Collectors.toSet());
                 List<BasicAttachment> basicAttachmentList = basicAttachmentService.listByIds(attachmentIds);
 
-                if (Objects.nonNull(basicAttachmentList)) {
+                if (Objects.nonNull(basicAttachmentList) && basicAttachmentList.size() > 0) {
                     LocalDateTime nowTime = LocalDateTime.now();
                     StringJoiner stringJoiner = new StringJoiner("")
                             .add(SystemConstant.TEMP_FILES_DIR).add(File.separator);
@@ -599,4 +623,142 @@ public class TaskLogicServiceImpl implements TaskLogicService {
         }
         return map;
     }
+
+    @Override
+    @Transactional
+    public Map<String, Object> executeExportSampleLogic(Map<String, Object> map) throws IOException {
+        int count = 0;
+        TBTask tbTask = (TBTask) map.get(SystemConstant.TASK);
+        LocalDateTime nowTime = LocalDateTime.now();
+        StringJoiner zipJoiner = new StringJoiner("")
+                .add(SystemConstant.TEMP_FILES_DIR).add(File.separator);
+        StringJoiner dirName = new StringJoiner("")
+                .add(UploadFileEnum.FILE.getTitle()).add(File.separator)
+                .add(String.valueOf(nowTime.getYear())).add(File.separator)
+                .add(String.format("%02d", nowTime.getMonthValue())).add(File.separator)
+                .add(String.format("%02d", nowTime.getDayOfMonth()))
+                .add(File.separator).add(SystemConstant.getUuid()).add(SystemConstant.ZIP_PREFIX);
+        String dirNameTmp = dirName.toString().replaceAll("\\\\", "/");
+        File zipFile = new File(zipJoiner.toString() + dirNameTmp);
+        if (!zipFile.getParentFile().exists()) {
+            zipFile.getParentFile().mkdirs();
+            zipFile.createNewFile();
+        }
+
+        // 跟文件路径
+        String zipLocalRootPath = SystemConstant.TEMP_FILES_DIR + File.separator + System.currentTimeMillis();
+        Long[] ids = (Long[]) map.get("ids");
+        for (Long id : ids) {
+            ExamTask examTask = examTaskService.getById(id);
+            if (Objects.isNull(examTask)) {
+                throw ExceptionResultEnum.ERROR.exception("未找到命题任务");
+            }
+            String examTaskSign = examTask.getSchoolId() + "-" + examTask.getCourseName() + "-" + examTask.getPaperNumber();
+            String firstPath = zipLocalRootPath + File.separator + examTaskSign;
+            List<ExamTaskDetail> examTaskDetailList = examTaskDetailService.list(new QueryWrapper<ExamTaskDetail>().lambda().eq(ExamTaskDetail::getExamTaskId, id));
+            if (examTaskDetailList.size() != 1) {
+                throw ExceptionResultEnum.ERROR.exception("获取命题任务详情失败 命题任务id : " + id);
+            }
+            ExamTaskDetail examTaskDetail = examTaskDetailList.get(0);
+
+
+            // 处理试卷样品
+            List<Map> paperInfo = JSONObject.parseArray(examTaskDetail.getPaperAttachmentIds(), Map.class);
+            System.out.println("paperInfo = " + JSON.toJSONString(paperInfo));
+            Set<Long> attPaperIds = new HashSet<>();
+            for (Map paperMap : paperInfo) {
+                if (Objects.isNull(paperMap.get("attachmentId"))) {
+                    throw ExceptionResultEnum.ERROR.exception("未找到附件id");
+                }
+                Long attachmentId = Long.valueOf(String.valueOf(paperMap.get("attachmentId")));
+                attPaperIds.add(attachmentId);
+            }
+            List<BasicAttachment> paperAttachmentList = basicAttachmentService.listByIds(attPaperIds);
+            if (Objects.nonNull(paperAttachmentList)) {
+                for (BasicAttachment paperAttachment : paperAttachmentList) {
+                    JSONObject jsonObject = JSONObject.parseObject(paperAttachment.getPath());
+                    String paperPath = firstPath + File.separator + "试卷" + File.separator + paperAttachment.getName() + paperAttachment.getType();
+                    ossUtil.ossDownload((String) jsonObject.get("path"), paperPath);
+                    count++;
+                }
+            }
+
+            // 处理审核样品
+            List<Map> confirmInfo = JSONObject.parseArray(examTaskDetail.getPaperConfirmAttachmentIds(), Map.class);
+            System.out.println("confirmInfo = " + JSON.toJSONString(confirmInfo));
+            Set<Long> attConfirmIds = new HashSet<>();
+            for (Map confirmMap : confirmInfo) {
+                if (Objects.isNull(confirmMap.get("attachmentId"))) {
+                    throw ExceptionResultEnum.ERROR.exception("未找到附件id");
+                }
+                Long attachmentId = Long.valueOf(String.valueOf(confirmMap.get("attachmentId")));
+                attConfirmIds.add(attachmentId);
+            }
+            List<BasicAttachment> confirmAttachmentList = basicAttachmentService.listByIds(attConfirmIds);
+            if (Objects.nonNull(confirmAttachmentList)) {
+                for (BasicAttachment confirmAttachment : confirmAttachmentList) {
+                    JSONObject jsonObject = JSONObject.parseObject(confirmAttachment.getPath());
+                    String confirmPath = firstPath + File.separator + "审核样本" + File.separator + confirmAttachment.getName() + confirmAttachment.getType();
+                    ossUtil.ossDownload((String) jsonObject.get("path"), confirmPath);
+                    count++;
+                }
+            }
+
+            // 处理题卡
+            Long cardId = examTaskDetail.getCardId();
+            ExamCard examCard = examCardService.getById(cardId);
+            if (Objects.isNull(examCard)) {
+                throw ExceptionResultEnum.ERROR.exception("找不到答题卡 cardId = " + cardId);
+            }
+            MakeMethodEnum makeMethodEnum = examCard.getMakeMethod();
+            if (MakeMethodEnum.SELECT.equals(makeMethodEnum)) {
+                Long templateId = examCard.getTemplateId();
+                if (templateId == null || templateId == 0) {
+                    throw ExceptionResultEnum.ERROR.exception("找不到题卡对应的模板 templateId = " + templateId);
+                }
+                BasicTemplate basicTemplate = basicTemplateService.getById(templateId);
+                if (Objects.isNull(basicTemplate)) {
+                    throw ExceptionResultEnum.ERROR.exception("找不到模板信息 templateId = " + templateId);
+                }
+                Long attachmentId = basicTemplate.getAttachmentId();
+                if (attachmentId == null || attachmentId == 0) {
+                    throw ExceptionResultEnum.ERROR.exception("找不到模板对应的附件 templateId = " + templateId);
+                }
+                BasicAttachment cardAttachment = basicAttachmentService.getById(attachmentId);
+                if (Objects.isNull(cardAttachment)) {
+                    throw ExceptionResultEnum.ERROR.exception("找不到附件 attachmentId = " + attachmentId);
+                }
+                JSONObject jsonObject = JSONObject.parseObject(cardAttachment.getPath());
+                String cardPath = firstPath + File.separator + "题卡" + File.separator + cardAttachment.getName() + cardAttachment.getType();
+                ossUtil.ossDownload((String) jsonObject.get("path"), cardPath);
+                count++;
+            } else {
+                List<ExamCardDetail> examCardDetailList = examCardDetailService.list(new QueryWrapper<ExamCardDetail>().lambda().eq(ExamCardDetail::getCardId, cardId));
+                if (examCardDetailList.size() != 1) {
+                    throw ExceptionResultEnum.ERROR.exception("题卡明细信息异常 card_id = " + cardId);
+                }
+                ExamCardDetail examCardDetail = examCardDetailService.getByCardId(cardId);
+                String htmlContent = examCardDetail.getHtmlContent();
+                byte[] bytes = htmlContent.getBytes();
+                String cardPath = firstPath + File.separator + "题卡" + File.separator + examCard.getTitle() + SystemConstant.HTML_PREFIX;
+                File localFile = new File(cardPath);
+                if (!localFile.getParentFile().exists()) {
+                    localFile.getParentFile().mkdirs();
+                }
+                FileCopyUtils.copy(bytes, localFile);
+                count++;
+            }
+        }
+        ZipUtil.zip(zipLocalRootPath, zipFile.getPath(), true);
+        ossUtil.ossUpload(dirNameTmp, zipFile, BinaryUtil.toBase64String(HexUtils.decodeHex(DigestUtils.md5Hex(new FileInputStream(zipFile)))));
+        JSONObject jsonObject = new JSONObject();
+        jsonObject.put(SystemConstant.PATH, dirNameTmp);
+        jsonObject.put(SystemConstant.TYPE, SystemConstant.OSS);
+        jsonObject.put(SystemConstant.UPLOAD_TYPE, UploadFileEnum.FILE);
+        tbTask.setResultFilePath(jsonObject.toJSONString());
+        ConvertUtil.delFolder(zipLocalRootPath);
+        zipFile.delete();
+        map.put("count", count);
+        return map;
+    }
 }

+ 74 - 26
distributed-print-business/src/main/java/com/qmth/distributed/print/business/util/ConvertUtil.java

@@ -5,7 +5,6 @@ import org.apache.poi.hssf.usermodel.HSSFDateUtil;
 import org.apache.poi.ss.usermodel.Cell;
 import org.apache.poi.ss.usermodel.CellType;
 import org.springframework.data.redis.core.RedisTemplate;
-import org.springframework.data.redis.support.atomic.RedisAtomicInteger;
 import org.springframework.data.redis.support.atomic.RedisAtomicLong;
 import org.springframework.stereotype.Component;
 
@@ -44,7 +43,7 @@ public class ConvertUtil {
         return new ByteArrayInputStream(baos.toByteArray());
     }
 
-    public static void inputStream2File (InputStream is, File file) throws IOException {
+    public static void inputStream2File(InputStream is, File file) throws IOException {
         OutputStream os = null;
         try {
             os = new FileOutputStream(file);
@@ -62,42 +61,40 @@ public class ConvertUtil {
 
     /**
      * 转换,解析时间
+     *
      * @param date 日期(考试日期,必须是同一天     example: 2021-04-13)
      * @param time 时间(考试时间,必须使用‘-’隔开  example: 18:00-20:00)
-     * @return 开始时间和结束时间键值对("startTime":1618308000000 ,"endTime":1618315200000)
+     * @return 开始时间和结束时间键值对(" startTime " : 1618308000000, " endTime " : 1618315200000)
      */
-    public static Map<String,Object> analyzeStartAndEndTime(String date,String time){
-        time = time.replaceAll(" ",""); // 去掉所有空格
+    public static Map<String, Object> analyzeStartAndEndTime(String date, String time) {
+        time = time.replaceAll(" ", ""); // 去掉所有空格
         String[] arr = time.split("-");
-        if (arr.length != 2){
+        if (arr.length != 2) {
             // 不能使用'-'拆分成两个时间的报错
-            System.out.println("提供的时间格式异常 时间 : " + time);
+            throw ExceptionResultEnum.ERROR.exception("提供的时间格式异常 时间 : " + time + " 应该使用如下的格式 '考试时间' :18:00-20:00");
         }
         String startTimeStr = date + " " + arr[0];
         String endTimeStr = date + " " + arr[1];
         long startTime = DateDisposeUtils.parseDate(startTimeStr).getTime();
         long endTime = DateDisposeUtils.parseDate(endTimeStr).getTime();
-        if (startTime >= endTime){
+        if (startTime >= endTime) {
             System.out.println("开始时间要小于结束时间 时间: " + time);
         }
 
-        System.out.println("开始时间 : " + startTimeStr + " 结束时间 : " + endTimeStr);
-        System.out.println("开始时间 : " + startTime + " 结束时间 : " + endTime);
-        System.out.println(new Date().getTime());
-
-        Map<String,Object> timeMap = new HashMap<>();
-        timeMap.put("startTime",startTime);
-        timeMap.put("endTime",endTime);
+        Map<String, Object> timeMap = new HashMap<>();
+        timeMap.put("startTime", startTime);
+        timeMap.put("endTime", endTime);
         return timeMap;
     }
 
     /**
      * 根据开始时间和结束时间解析日期和时间
+     *
      * @param startTime 开始时间
-     * @param endTime 结束时间
+     * @param endTime   结束时间
      * @return 键值对
      */
-    public static Map<String,Object> analyzeDateAndTime(Long startTime,Long endTime){
+    public static Map<String, Object> analyzeDateAndTime(Long startTime, Long endTime) {
         String tmpDateStart;
         String tmpDateEnd;
         String tmpTimeStart;
@@ -106,7 +103,7 @@ public class ConvertUtil {
         String time;
 
 
-        Map<String,Object> map = new HashMap<>();
+        Map<String, Object> map = new HashMap<>();
 
         Calendar calendar = Calendar.getInstance();
         calendar.setTime(new Date(startTime));
@@ -117,14 +114,14 @@ public class ConvertUtil {
         tmpDateEnd = (new SimpleDateFormat("yyyy-MM-dd")).format(calendar.getTime());
         tmpTimeEnd = (new SimpleDateFormat("HH:mm:ss")).format(calendar.getTime());
 
-        if (!tmpDateStart.equals(tmpDateEnd)){
+        if (!tmpDateStart.equals(tmpDateEnd)) {
             throw ExceptionResultEnum.ERROR.exception("开始时间和结束时间不在同一天");
         }
 
         date = tmpDateStart;
         time = tmpTimeStart + " - " + tmpTimeEnd;
-        map.put("date",date);
-        map.put("time",time);
+        map.put("date", date);
+        map.put("time", time);
 
         return map;
     }
@@ -132,14 +129,15 @@ public class ConvertUtil {
 
     /**
      * 获取递增序列号
+     *
      * @param prefix 前缀
-     * @param model 模块
-     * @param digit 补齐位数
+     * @param model  模块
+     * @param digit  补齐位数
      * @return 序列号
      */
-    public String getIncre(String prefix,String model,int digit) {
+    public String getIncre(String prefix, String model, int digit) {
         StringBuilder temp = new StringBuilder();
-        for (int i = 0;i < digit;i ++){
+        for (int i = 0; i < digit; i++) {
             temp.append("0");
         }
         //序列号前缀加特定标识,如系统模块名之类的 防止重复
@@ -164,10 +162,11 @@ public class ConvertUtil {
 
     /**
      * 解析excel单元格类型
+     *
      * @param cell 单元格
      * @return 转换成字符串后的值
      */
-    public static String analyzeExcelCellValue(Cell cell){
+    public static String analyzeExcelCellValue(Cell cell) {
         String cellValue;
         CellType cellType = cell.getCellTypeEnum();
         switch (cellType) {
@@ -212,4 +211,53 @@ public class ConvertUtil {
         }
         return cellValue;
     }
+
+    public static void delFolder(String folderPath) {
+        try {
+            delAllFile(folderPath); //删除完里面所有内容
+            String filePath = folderPath;
+            filePath = filePath.toString();
+            java.io.File myFilePath = new java.io.File(filePath);
+            myFilePath.delete(); //删除空文件夹
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public static void delAllFile(String path) {
+        boolean flag = false;
+        File file = new File(path);
+        if (!file.exists()) {
+            return;
+        }
+        if (!file.isDirectory()) {
+            return;
+        }
+        String[] tempList = file.list();
+        File temp = null;
+        for (int i = 0; i < Objects.requireNonNull(tempList).length; i++) {
+            if (path.endsWith(File.separator)) {
+                temp = new File(path + tempList[i]);
+            } else {
+                temp = new File(path + File.separator + tempList[i]);
+            }
+            if (temp.isFile()) {
+                temp.delete();
+            }
+            if (temp.isDirectory()) {
+                delAllFile(path + "/" + tempList[i]);//先删除文件夹里面的文件
+                delFolder(path + "/" + tempList[i]);//再删除空文件夹
+                flag = true;
+            }
+        }
+    }
+
+    public static void verifyLength(String str,int length,String name){
+        if (str == null || str.length() == 0 || str.equals("null")){
+            throw ExceptionResultEnum.ERROR.exception(name + "不能为空");
+        }
+        if (str.length() > length){
+            throw ExceptionResultEnum.ERROR.exception("内容'" + str + "' 超过长度限制 : " + length);
+        }
+    }
 }

+ 14 - 3
distributed-print-business/src/main/java/com/qmth/distributed/print/business/util/CreatePdfUtil.java

@@ -67,6 +67,9 @@ public class CreatePdfUtil {
      * @param printCount
      */
     public void createCheckIn(BasicAttachment basicAttachment, List<PdfDto> ordinaryPdfList, Integer printCount) throws IOException, DocumentException {
+        if (Objects.isNull(basicAttachment)) {
+            throw ExceptionResultEnum.ERROR.exception("找不到附件");
+        }
         String type = basicAttachment.getType();
         JSONObject jsonObject = JSONObject.parseObject(basicAttachment.getPath());
         if (Objects.nonNull(type) && Objects.equals(type, SystemConstant.PDF_PREFIX)) {
@@ -94,6 +97,9 @@ public class CreatePdfUtil {
      * @throws IOException
      */
     public void createPaperPackage(BasicAttachment basicAttachment, String schoolName, ExamDetailCourse examDetailCourse, List<ExamStudent> examStudentList, List<PdfDto> variablePdfList, Integer printCount) throws IOException {
+        if (Objects.isNull(basicAttachment)) {
+            throw ExceptionResultEnum.ERROR.exception("找不到附件");
+        }
         Map<String, Object> htmlMap = new HashMap<>();
         htmlMap.put("examDetailCourseId", examDetailCourse.getId());
         htmlMap.put("schoolName", schoolName);
@@ -134,14 +140,16 @@ public class CreatePdfUtil {
      * @param variablePdfList
      * @param printCount
      */
-    public void createSignBook(BasicAttachment basicAttachment, String schoolName, ExamDetailCourse examDetailCourse, List<ExamStudent> examStudentList, List<PdfDto> variablePdfList, Integer printCount) throws IOException {
+    public void createSignBook(BasicAttachment basicAttachment, String schoolName, ExamDetail examDetail, ExamDetailCourse examDetailCourse, List<ExamStudent> examStudentList, List<PdfDto> variablePdfList, Integer printCount) throws IOException {
+        if (Objects.isNull(basicAttachment)) {
+            throw ExceptionResultEnum.ERROR.exception("找不到附件");
+        }
         Map<String, Object> htmlMap = new HashMap<>();
         htmlMap.put("examDetailCourseId", examDetailCourse.getId());
         htmlMap.put("schoolName", schoolName);
         htmlMap.put("courseName", examDetailCourse.getCourseName());
         htmlMap.put("courseCode", examDetailCourse.getCourseCode());
-        htmlMap.put("examName", "测试exam1");
-        htmlMap.put("examRoom", "测试examRoom1");
+        htmlMap.put("examRoom", examDetail.getExamRoom());
         htmlMap.put("classTeacher", "测试老师1");
         htmlMap.put("startTime", "2021-04-13 00:00:00");
         htmlMap.put("endTime", "2021-04-14 00:00:00");
@@ -250,6 +258,9 @@ public class CreatePdfUtil {
             if (Objects.nonNull(object.get("attachmentId"))) {
                 Long attachmentId = Long.parseLong((String) (object.get("attachmentId")));
                 BasicAttachment basicAttachment = basicAttachmentService.getById(attachmentId);
+                if (Objects.isNull(basicAttachment)) {
+                    throw ExceptionResultEnum.ERROR.exception("找不到附件");
+                }
                 File file = commonService.getFile(basicAttachment.getPath(), false);
                 int pageCount = PdfUtil.addPdfPage(file);
                 pdfList[0].add(new PdfDto(file.getPath(), PageSizeEnum.A3, pageCount));

+ 2 - 2
distributed-print-business/src/main/java/com/qmth/distributed/print/business/util/FreemarkerUtil.java

@@ -91,7 +91,7 @@ public class FreemarkerUtil {
             Template template = configuration.getTemplate(ftlName + SystemConstant.FTL_PREFIX);
             // step2 生成数据
             StringJoiner localStringJoiner = new StringJoiner("");
-            localStringJoiner.add(SystemConstant.TEMP_FILES_DIR + File.separator + ftlPath.replaceAll(UploadFileEnum.FILE.getTitle(), UploadFileEnum.HTML.getTitle()))
+            localStringJoiner.add(SystemConstant.TEMP_FILES_DIR + File.separator + ftlPath.replaceAll(UploadFileEnum.FILE.getTitle(), UploadFileEnum.HTML.getTitle()).replaceAll(UploadFileEnum.UPLOAD.getTitle(), UploadFileEnum.HTML.getTitle()))
                     .add(File.separator)
                     .add(ftlName)
                     .add(SystemConstant.HTML_PREFIX);
@@ -107,7 +107,7 @@ public class FreemarkerUtil {
             boolean oss = dictionaryConfig.sysDomain().isOss();
             if (oss) {
                 StringJoiner stringJoiner = new StringJoiner("");
-                stringJoiner.add(ftlPath.replaceAll(UploadFileEnum.FILE.getTitle(), UploadFileEnum.HTML.getTitle()))
+                stringJoiner.add(ftlPath.replaceAll(UploadFileEnum.FILE.getTitle(), UploadFileEnum.HTML.getTitle()).replaceAll(UploadFileEnum.UPLOAD.getTitle(), UploadFileEnum.HTML.getTitle()))
                         .add(File.separator).add(ftlName).add(SystemConstant.HTML_PREFIX);
                 ossUtil.ossUpload(stringJoiner.toString(), htmlFile, DigestUtils.md5Hex(new FileInputStream(htmlFile)));
                 jsonObject.put(SystemConstant.HTML_PATH, stringJoiner.toString());

+ 12 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/util/OssUtil.java

@@ -172,4 +172,16 @@ public class OssUtil {
         generatePresignedUrlRequest.setExpiration(calendar.getTime());
         return ossClient.generatePresignedUrl(generatePresignedUrlRequest).toString();
     }
+
+    /**
+     * 获取私有bucket文件访问url
+     *
+     * @param objectPath
+     * @return
+     */
+    public String getPrivateUrlNotExpire(String objectPath) {
+        GeneratePresignedUrlRequest generatePresignedUrlRequest;
+        generatePresignedUrlRequest = new GeneratePresignedUrlRequest(this.aliYunOssDomain.getBucket(), objectPath);
+        return ossClient.generatePresignedUrl(generatePresignedUrlRequest).toString();
+    }
 }

+ 3 - 3
distributed-print-business/src/main/resources/db/init-table.sql

@@ -48,7 +48,7 @@ CREATE TABLE `basic_card_rule`  (
   `write_sign` tinyint(4) NOT NULL COMMENT '0-禁用,1-启用',
   `required_fields` text CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '必选字段',
   `extend_fields` text CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '扩展字段',
-  `title_rule` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '题卡标题规则',
+  `title_rule` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '题卡标题规则',
   `attention` text CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '注意事项',
   `objective_attention` text CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '客观题注意事项',
   `subjective_attention` text CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '主观题注意事项',
@@ -196,7 +196,7 @@ CREATE TABLE `client_status`  (
   `id` bigint(20) NOT NULL AUTO_INCREMENT,
   `school_id` bigint(20) NULL DEFAULT NULL,
   `machine_code` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '机器唯一码',
-  `exam_detail_id` bigint(20) NOT NULL COMMENT '考场ID',
+  `exam_task_id` bigint(20) NOT NULL COMMENT '命题任务ID',
   `is_try` tinyint(1) NULL DEFAULT NULL COMMENT '是否打样:true-是,false-否',
   `try_time` bigint(20) NULL DEFAULT NULL COMMENT '打样时间',
   `is_pass` tinyint(1) NULL DEFAULT NULL COMMENT '是否合格:true-合格,false-不合格',
@@ -424,7 +424,7 @@ CREATE TABLE `exam_task_temp`  (
   `batch_no` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '本次导入数据临时ID',
   `course_code` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '课程代码',
   `course_name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '课程名称',
-  `paper_number` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '试卷编号',
+  `paper_number` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '试卷编号',
   `specialty` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '适用专业',
   `user_account` varchar(45) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '命题老师账号',
   `user_name` varchar(45) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '命题老师姓名',

+ 2 - 0
distributed-print-business/src/main/resources/mapper/BasicCardRuleMapper.xml

@@ -45,6 +45,7 @@
                 and create_time = #{createTime}
             </if>
         </where>
+        order by create_time desc
     </select>
     <select id="list" resultMap="BaseResultMap">
         SELECT
@@ -66,6 +67,7 @@
                     </foreach>
                 </if>
                 )
+        order by create_time desc
     </select>
 
 </mapper>

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

@@ -41,6 +41,7 @@
                 and name like concat('%',#{name} ,'%')
             </if>
         </where>
+        order by create_time desc
     </select>
 
 </mapper>

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

@@ -21,7 +21,7 @@
         code, name, enable, access_key, access_secret, remark, create_time, update_time
     </sql>
     <select id="listSchool" resultType="com.qmth.distributed.print.business.bean.dto.SchoolDto">
-        select id, name, enable, logo from basic_school where enable = true
+        select id, name, enable, logo from basic_school where enable = true order by create_time desc
     </select>
 
 </mapper>

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

@@ -57,6 +57,7 @@
                 and create_time &lt;= #{endTime}
             </if>
         </where>
+        order by create_time desc
     </select>
 
 </mapper>

+ 3 - 0
distributed-print-business/src/main/resources/mapper/ExamCardMapper.xml

@@ -76,6 +76,7 @@
                 and a.update_time &lt; #{finishEndTime}
             </if>
         </where>
+        order by a.create_time desc
     </select>
     <select id="getCardDetail" resultType="com.qmth.distributed.print.business.bean.dto.CardDetailDto">
         SELECT
@@ -113,6 +114,7 @@
             AND a.type = #{type}
             AND b.enable = TRUE
             AND c.org_id = #{orgId}
+        order by a.create_time desc
     </select>
     <select id="listCustom" resultType="com.qmth.distributed.print.business.entity.ExamCard">
         SELECT
@@ -129,5 +131,6 @@
                 exam_task_detail b
             WHERE
                 a.id = b.card_id)
+        order by a.create_time desc
     </select>
 </mapper>

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

@@ -306,5 +306,60 @@
             </if>
         </where>
     </select>
+    <select id="listClientExamStudentPage"
+            resultType="com.qmth.distributed.print.business.bean.dto.ClientExamStudentDto">
+        SELECT
+            a.id examDetailId,
+            b.course_code courseCode,
+            b.course_name courseName,
+            b.paper_number paperNumber,
+            c.student_code studentCode,
+            c.ticket_number ticketNumber,
+            c.student_name studentName,
+            c.site_number siteNumber
+        FROM
+            exam_detail a
+                JOIN
+            exam_detail_course b ON a.id = b.exam_detail_id
+                JOIN
+            exam_student c ON b.id = c.exam_detail_course_id
+        <where>
+            and a.school_id = #{schoolId}
+            and a.id = #{examDetailId}
+            <if test="ticketNumber != null and ticketNumber != ''">
+                and c.ticket_number like concat('%', #{ticketNumber}, '%')
+            </if>
+            <if test="studentName != null and studentName != ''">
+                and c.student_name like concat('%', #{studentName}, '%')
+            </if>
+            <if test="courseCode != null and courseCode != ''">
+                and b.course_code = #{courseCode}
+            </if>
+        </where>
+    </select>
+    <select id="listStudentByExamDetailId" resultType="java.util.Map">
+        SELECT
+            b.course_code courseCode,
+            b.course_name courseName,
+            b.paper_number paperNumber,
+            c.student_name studentName,
+            c.student_code studentCode,
+            c.attachment_id attachmentId,
+            c.paper_type paperType
+        FROM
+            exam_detail a
+                JOIN
+            exam_detail_course b ON a.id = b.exam_detail_id
+                JOIN
+            exam_student c ON b.id = c.exam_detail_course_id
+        WHERE
+            a.id = #{examDetailId}
+        <if test="type == 'ONE'">
+            and c.ticket_number = #{ticketNumber}
+        </if>
+        <if test="type == 'MORE'">
+            and c.ticket_number > 0+cast(#{ticketNumber} as char)
+        </if>
+    </select>
 
 </mapper>

+ 21 - 0
distributed-print-business/src/main/resources/mapper/ExamTaskDetailMapper.xml

@@ -108,4 +108,25 @@
                     a.card_id = b.id
                         AND b.template_id = #{templateId})
     </select>
+    <select id="listByExamDetailId" resultType="java.util.Map">
+        SELECT
+            a.course_code courseCode,
+            a.paper_number paperNumber,
+            b.paper_attachment_ids paperAttachmentIds
+        FROM
+            exam_task a
+                LEFT JOIN
+            exam_task_detail b ON a.id = b.exam_task_id
+        WHERE
+            a.school_id = #{schoolId}
+                AND EXISTS( SELECT
+                    1
+                FROM
+                    exam_detail_course b
+                WHERE
+                    b.exam_detail_id = #{examDetailId}
+                        AND a.school_id = b.school_id
+                        AND a.course_code = b.course_code
+                        AND a.paper_number = b.paper_number)
+    </select>
 </mapper>

+ 65 - 2
distributed-print-business/src/main/resources/mapper/ExamTaskMapper.xml

@@ -88,6 +88,7 @@
                 and a.start_time &lt;= #{endTime}
             </if>
         </where>
+        order by a.create_time desc
     </select>
     <select id="listUser" resultType="com.qmth.distributed.print.business.bean.dto.BlurryUserDto">
         SELECT
@@ -140,11 +141,11 @@
                 LEFT JOIN
             sys_user c ON a.user_id = c.id
             <where>
-                <if test="userId != null and userId != ''">
+                <if test="orgIds != null and userId != null and userId != ''">
                     and a.user_id = #{userId}
                 </if>
             </where>
-            ) a
+            order by a.create_time desc) a
         <where>
             a.enable = true and a.status not in
             <foreach item="item" collection="status" separator="," open="(" close=")" index="">
@@ -242,6 +243,7 @@
                 </foreach>
             </if>
         </where>
+        order by a.create_time desc
     </select>
     <select id="listTaskReviewAudited" resultType="com.qmth.distributed.print.business.bean.dto.ExamTaskDto">
         SELECT
@@ -313,6 +315,7 @@
                 </foreach>
             </if>
         </where>
+        order by a.create_time desc
     </select>
     <select id="listTaskPaper" resultType="com.qmth.distributed.print.business.bean.dto.ExamTaskDetailDto">
         SELECT
@@ -365,6 +368,7 @@
                 </foreach>
             </if>
         </where>
+        order by a.create_time desc
     </select>
     <select id="listPaperNumbers" resultType="com.qmth.distributed.print.business.bean.dto.RelatePaperDto">
         SELECT
@@ -419,6 +423,65 @@
             <include refid="myworkSubmitCommonFoot" />
         </where>
     </select>
+    <select id="listClientExamTaskPage"
+            resultType="com.qmth.distributed.print.business.bean.dto.ClientExamTaskDto">
+        SELECT
+            a.school_id schoolId,
+            a.id printPlanId,
+            a.name printPlanName,
+            c.course_code courseCode,
+            c.course_name courseName,
+            c.paper_number paperNumber,
+            d.id examTaskId,
+            d.specialty,
+            d.user_id userId,
+            f.real_name userName,
+            e.is_try isTry,
+            e.is_pass isPass,
+            e.try_time tryTime
+        FROM
+            exam_print_plan a
+                JOIN
+            exam_detail b ON a.id = b.print_plan_id
+                JOIN
+            exam_detail_course c ON b.id = c.exam_detail_id
+                JOIN
+            exam_task d ON d.school_id = c.school_id
+                AND d.course_code = c.course_code
+                AND d.paper_number = c.paper_number
+                LEFT JOIN
+            client_status e ON e.school_id = d.school_id
+                AND e.exam_task_id = d.id
+                LEFT JOIN
+            sys_user f ON d.user_id = f.id
+                LEFT JOIN
+            sys_user g ON a.create_id = g.id
+        <where>
+            and a.status = 'READY'
+            and e.machine_code = #{machineCode}
+            <if test="printPlanId != null and printPlanId != ''">
+                and a.id = #{printPlanId}
+            </if>
+            <if test="courseCode != null and courseCode != ''">
+                and c.course_code = #{courseCode}
+            </if>
+            <if test="paperNumber != null and paperNumber != ''">
+                and c.paper_number = #{paperNumber}
+            </if>
+            <if test="isTry != null and isTry != ''">
+                and e.is_try = #{isTry}
+            </if>
+            <if test="isPass != null and isPass != ''">
+                and e.is_pass = #{isPass}
+            </if>
+            <if test="orgIds != null">
+                AND g.org_id IN
+                <foreach collection="orgIds" item="item" index="index" open="(" separator="," close=")">
+                    #{item}
+                </foreach>
+            </if>
+        </where>
+    </select>
 
     <sql id="myworkCommonHead">
         SELECT

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

@@ -31,6 +31,7 @@
             sys_user b ON a.operate_id = b.id
         WHERE
             a.exam_task_id = #{examTaskId}
+        order by a.create_time desc
     </select>
 
 </mapper>

+ 314 - 2
distributed-print/src/main/java/com/qmth/distributed/print/api/ClientController.java

@@ -1,11 +1,22 @@
 package com.qmth.distributed.print.api;
 
+import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.qmth.boot.api.annotation.Aac;
 import com.qmth.boot.api.annotation.BOOL;
 import com.qmth.boot.api.constant.ApiConstant;
+import com.qmth.distributed.print.business.bean.dto.ClientExamStudentDto;
+import com.qmth.distributed.print.business.bean.dto.ClientExamTaskDto;
+import com.qmth.distributed.print.business.entity.SysUser;
+import com.qmth.distributed.print.business.service.*;
+import com.qmth.distributed.print.common.util.Result;
+import com.qmth.distributed.print.common.util.ResultUtil;
 import io.swagger.annotations.Api;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+import java.util.Map;
 
 /**
  * @Date: 2021/4/19.
@@ -15,4 +26,305 @@ import org.springframework.web.bind.annotation.RestController;
 @RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + "/${prefix.url.client}")
 @Aac(auth = BOOL.FALSE)
 public class ClientController {
+
+    @Autowired
+    private ClientService clientService;
+
+    /**
+     * 登录
+     *
+     * @param sysUser
+     * @return
+     */
+    @ApiOperation(value = "登录")
+    @RequestMapping(value = "/user/login", method = RequestMethod.POST)
+    public Result login(@RequestBody SysUser sysUser) {
+
+        return null;
+    }
+
+    /**
+     * 试卷打样-列表
+     *
+     * @param schoolId    学校ID
+     * @param machineCode 机器唯一码
+     * @param orgId       机构ID
+     * @param printPlanId 印刷计划ID
+     * @param courseCode  课程代码
+     * @param paperNumber 试卷编号
+     * @param isTry       是否打样
+     * @param isPass      是否合格
+     * @param pageNumber
+     * @param pageSize
+     * @return
+     */
+    @ApiOperation(value = "试卷打样-列表")
+    @RequestMapping(value = "/paper_try/list", method = RequestMethod.POST)
+    public Result paperTryList(@RequestParam("schoolId") Long schoolId,
+                               @RequestParam("machineCode") String machineCode,
+                               @RequestParam("orgId") Long orgId,
+                               @RequestParam(value = "printPlanId", required = false) Long printPlanId,
+                               @RequestParam(value = "courseCode", required = false) String courseCode,
+                               @RequestParam(value = "paperNumber", required = false) String paperNumber,
+                               @RequestParam(value = "isTry", required = false) Boolean isTry,
+                               @RequestParam(value = "isPass", required = false) Boolean isPass,
+                               @RequestParam("pageNumber") Integer pageNumber,
+                               @RequestParam("pageSize") Integer pageSize) {
+        IPage<ClientExamTaskDto> examTasks = clientService.listTryTask(schoolId, machineCode, orgId, printPlanId, courseCode, paperNumber, isTry, isPass, pageNumber, pageSize);
+        return ResultUtil.ok(examTasks);
+    }
+
+    /**
+     * 试卷打样-查看/试印/重印
+     *
+     * @param schoolId
+     * @param examTaskId
+     * @return
+     */
+    @ApiOperation(value = "试卷打样-查看/试印/重印")
+    @RequestMapping(value = "/paper_try/print", method = RequestMethod.POST)
+    public Result paperTryPrint(@RequestParam("schoolId") Long schoolId,
+                                @RequestParam("examTaskId") Long examTaskId) {
+        String url = clientService.getUrl(schoolId, examTaskId);
+        return ResultUtil.ok(url);
+    }
+
+    /**
+     * 试卷打样-标记合格状态
+     *
+     * @param schoolId
+     * @param examTaskId
+     * @param machineCode
+     * @param isPass
+     * @param userId
+     * @return
+     */
+    @ApiOperation(value = "试卷打样-标记合格状态")
+    @RequestMapping(value = "/paper_try/tag_pass", method = RequestMethod.POST)
+    public Result paperTryTagPass(@RequestParam("schoolId") Long schoolId,
+                                  @RequestParam("examTaskId") Long examTaskId,
+                                  @RequestParam("machineCode") String machineCode,
+                                  @RequestParam("isPass") Boolean isPass,
+                                  @RequestParam("userId") Long userId) {
+        Boolean isSuccess = clientService.tagPass(schoolId, examTaskId, machineCode, isPass, userId);
+        return ResultUtil.ok(isSuccess);
+    }
+
+    /**
+     * 印刷管理-查询列表
+     *
+     * @param schoolId
+     * @param machineCode
+     * @param orgId
+     * @param printPlanId
+     * @param status
+     * @param courseCode
+     * @param paperNumber
+     * @param examPlace
+     * @param examRoom
+     * @param examStartTime
+     * @param examEndTime
+     * @param isDownload
+     * @param validate
+     * @param pageNumber
+     * @param pageSize
+     * @return
+     */
+    @ApiOperation(value = "印刷管理-查询列表")
+    @RequestMapping(value = "/print/task_list", method = RequestMethod.POST)
+    public Result printTaskList(@RequestParam("schoolId") Long schoolId,
+                                @RequestParam("machineCode") Long machineCode,
+                                @RequestParam("orgId") String orgId,
+                                @RequestParam(value = "printPlanId", required = false) String printPlanId,
+                                @RequestParam(value = "status", required = false) String status,
+                                @RequestParam(value = "courseCode", required = false) String courseCode,
+                                @RequestParam(value = "paperNumber", required = false) String paperNumber,
+                                @RequestParam(value = "examPlace", required = false) String examPlace,
+                                @RequestParam(value = "examRoom", required = false) String examRoom,
+                                @RequestParam(value = "examStartTime", required = false) Long examStartTime,
+                                @RequestParam(value = "examEndTime", required = false) Long examEndTime,
+                                @RequestParam(value = "isDownload", required = false) Boolean isDownload,
+                                @RequestParam(value = "validate", required = false) Boolean validate,
+                                @RequestParam("pageNumber") Integer pageNumber,
+                                @RequestParam("pageSize") Integer pageSize) {
+
+        return null;
+    }
+
+    /**
+     * 印刷管理-汇总数据查询
+     *
+     * @param schoolId
+     * @param machineCode
+     * @param orgId
+     * @param printPlanId
+     * @param status
+     * @param courseCode
+     * @param paperNumber
+     * @param examPlace
+     * @param examRoom
+     * @param examStartTime
+     * @param examEndTime
+     * @param isDownload
+     * @param validate
+     * @return
+     */
+    @ApiOperation(value = "印刷管理-汇总数据查询")
+    @RequestMapping(value = "/print/task_total_data", method = RequestMethod.POST)
+    public Result printTaskTotalData(@RequestParam("schoolId") Long schoolId,
+                                     @RequestParam("machineCode") Long machineCode,
+                                     @RequestParam("orgId") String orgId,
+                                     @RequestParam(value = "printPlanId", required = false) String printPlanId,
+                                     @RequestParam(value = "status", required = false) String status,
+                                     @RequestParam(value = "courseCode", required = false) String courseCode,
+                                     @RequestParam(value = "paperNumber", required = false) String paperNumber,
+                                     @RequestParam(value = "examPlace", required = false) String examPlace,
+                                     @RequestParam(value = "examRoom", required = false) String examRoom,
+                                     @RequestParam(value = "examStartTime", required = false) Long examStartTime,
+                                     @RequestParam(value = "examEndTime", required = false) Long examEndTime,
+                                     @RequestParam(value = "isDownload", required = false) Boolean isDownload,
+                                     @RequestParam(value = "validate", required = false) Boolean validate) {
+
+        return null;
+    }
+
+
+    /**
+     * 印刷管理-查看
+     *
+     * @param schoolId
+     * @param orgId
+     * @param examDetailId
+     * @return
+     */
+    @ApiOperation(value = "印刷管理-查看")
+    @RequestMapping(value = "/print/preview", method = RequestMethod.POST)
+    public Result printPreview(@RequestParam("schoolId") Long schoolId,
+                               @RequestParam("orgId") Long orgId,
+                               @RequestParam("examDetailId") Long examDetailId) {
+
+        return null;
+    }
+
+    /**
+     * 印刷管理-印刷/缓存数据
+     *
+     * @param schoolId
+     * @param orgId
+     * @param examDetailId
+     * @param machineCode
+     * @param printUser
+     * @return
+     */
+    @ApiOperation(value = "印刷管理-印刷/缓存数据")
+    @RequestMapping(value = "/print/get_print_data", method = RequestMethod.POST)
+    public Result printGetPrintData(@RequestParam("schoolId") Long schoolId,
+                                    @RequestParam("orgId") Long orgId,
+                                    @RequestParam("examDetailId") Long examDetailId,
+                                    @RequestParam("machineCode") String machineCode,
+                                    @RequestParam("printUser") String printUser) {
+
+        return null;
+    }
+
+    /**
+     * 印刷管理-批量缓存数据
+     *
+     * @param schoolId
+     * @param orgId
+     * @param examDetailId
+     * @param machineCode
+     * @return
+     */
+    @ApiOperation(value = "印刷管理-批量缓存数据")
+    @RequestMapping(value = "/print/get_print_data_batch", method = RequestMethod.POST)
+    public Result printGetPrintDataBatch(@RequestParam("schoolId") Long schoolId,
+                                         @RequestParam("orgId") Long orgId,
+                                         @RequestParam("examDetailId") Long examDetailId,
+                                         @RequestParam("machineCode") String machineCode) {
+
+        return null;
+    }
+
+    /**
+     * 印刷管理-校验
+     *
+     * @param schoolId
+     * @param orgId
+     * @param examDetailId
+     * @param machineCode
+     * @param packageCode
+     * @param lastCode
+     * @return
+     */
+    @ApiOperation(value = "印刷管理-校验")
+    @RequestMapping(value = "/print/data_check", method = RequestMethod.POST)
+    public Result dataCheck(@RequestParam("schoolId") Long schoolId,
+                            @RequestParam("orgId") Long orgId,
+                            @RequestParam("examDetailId") Long examDetailId,
+                            @RequestParam("machineCode") String machineCode,
+                            @RequestParam("packageCode") String packageCode,
+                            @RequestParam("lastCode") String lastCode) {
+
+        return null;
+    }
+
+    /**
+     * 印刷管理-更新打印进度
+     *
+     * @param schoolId
+     * @param examDetailId
+     * @param printProgress
+     * @return
+     */
+    @ApiOperation(value = "印刷管理-更新打印进度")
+    @RequestMapping(value = "/print/update_progress", method = RequestMethod.POST)
+    public Result updateProgress(@RequestParam("schoolId") Long schoolId,
+                                 @RequestParam("examDetailId") Long examDetailId,
+                                 @RequestParam("printProgress") Integer printProgress) {
+        Boolean isSuccess = clientService.updatePrintProgress(schoolId, examDetailId, printProgress);
+        return ResultUtil.ok(isSuccess);
+    }
+
+    /**
+     * 重打-查询考生列表
+     *
+     * @param schoolId
+     * @param examDetailId
+     * @param ticketNumber
+     * @param studentName
+     * @param courseCode
+     * @return
+     */
+    @ApiOperation(value = "重打-查询考生列表")
+    @RequestMapping(value = "/print/list_student", method = RequestMethod.POST)
+    public Result listStudent(@RequestParam("schoolId") Long schoolId,
+                              @RequestParam("examDetailId") Long examDetailId,
+                              @RequestParam(value = "ticketNumber", required = false) String ticketNumber,
+                              @RequestParam(value = "studentName", required = false) String studentName,
+                              @RequestParam(value = "courseCode", required = false) String courseCode,
+                              @RequestParam("pageNumber") Integer pageNumber,
+                              @RequestParam("pageSize") Integer pageSize) {
+        IPage<ClientExamStudentDto> examStudentDtoIPage = clientService.listStudent(schoolId, examDetailId, ticketNumber, studentName, courseCode, pageNumber, pageSize);
+        return ResultUtil.ok(examStudentDtoIPage);
+    }
+
+    /**
+     * 重打-内容查询
+     *
+     * @param schoolId
+     * @param examDetailId
+     * @param ticketNumber
+     * @param type
+     * @return
+     */
+    @ApiOperation(value = "重打-内容查询")
+    @RequestMapping(value = "/print/get_reprint_data", method = RequestMethod.POST)
+    public Result getReprintData(@RequestParam("schoolId") Long schoolId,
+                                 @RequestParam("examDetailId") Long examDetailId,
+                                 @RequestParam("ticketNumber") String ticketNumber,
+                                 @RequestParam("type") String type) {
+        Map<String, Object> map = clientService.getReprintData(schoolId, examDetailId, ticketNumber, type);
+        return ResultUtil.ok(map);
+    }
 }

+ 3 - 0
distributed-print/src/main/java/com/qmth/distributed/print/api/EnumsController.java

@@ -101,6 +101,9 @@ public class EnumsController {
         } else if (type.equals(EnumType.EXAM_DETAIL_STATUS_ENUM.name())){
             // 考场状态
             list = ExamDetailStatusEnum.listTypes();
+        } else if (type.equals(EnumType.EXAMINATION_DB_FIELDS_ENUM.name())){
+            // 考场状态
+            list = ExaminationDBFieldsEnum.listTypes();
         }
         return ResultUtil.ok(list);
     }

+ 17 - 4
distributed-print/src/main/java/com/qmth/distributed/print/api/ExamPrintPlanController.java

@@ -270,22 +270,35 @@ public class ExamPrintPlanController {
         return ResultUtil.ok(printTaskTotalDto);
     }
 
+    /**
+     * 印刷任务管理-查看印品
+     *
+     * @param map
+     * @return
+     */
+    @ApiOperation(value = "印刷任务管理-查看印品")
+    @RequestMapping(value = "/template_view", method = RequestMethod.POST)
+    public Result tempalteViewPDF(@RequestBody  Map<String, Long> map) {
+        List<Map<String, String>> list = examPrintPlanService.tempalteView(map.get("printPlanId"));
+        return ResultUtil.ok(list);
+    }
+
     /**
      * 印刷任务管理-查看PDF
      *
-     * @param examDetailId
+     * @param map
      * @return
      */
     @ApiOperation(value = "印刷任务管理-查看PDF")
     @RequestMapping(value = "/task_view_pdf", method = RequestMethod.POST)
-    public Result taskViewPDF(@RequestParam Long examDetailId) {
-        String path = examDetailService.taskViewPDF(examDetailId);
+    public Result taskViewPDF(@RequestBody  Map<String, Long> map) {
+        String path = examDetailService.taskViewPDF(map.get("examDetailId"));
         return ResultUtil.ok(path);
     }
 
     @ApiOperation(value = "印刷任务管理-批量下载PDF")
     @RequestMapping(value = "/task_download_pdf", method = RequestMethod.POST)
-    @ApiResponses({@ApiResponse(code = 200, message = "用户信息", response = EditResult.class)})
+    @ApiResponses({@ApiResponse(code = 200, message = "返回信息", response = EditResult.class)})
     public Result taskDownloadPdf(@ApiParam(value = "id数组", required = true) @Valid @RequestBody ArraysParams arraysParams, BindingResult bindingResult) throws Exception {
         if (bindingResult.hasErrors()) {
             return ResultUtil.error(bindingResult.getAllErrors().get(0).getDefaultMessage());

+ 26 - 13
distributed-print/src/main/java/com/qmth/distributed/print/api/ExamTaskController.java

@@ -7,15 +7,14 @@ import com.qmth.boot.api.annotation.BOOL;
 import com.qmth.boot.api.constant.ApiConstant;
 import com.qmth.boot.api.exception.ApiException;
 import com.qmth.distributed.print.business.bean.dto.*;
-import com.qmth.distributed.print.business.entity.BasicAttachment;
-import com.qmth.distributed.print.business.entity.ExamTask;
-import com.qmth.distributed.print.business.entity.ExamTaskDetail;
-import com.qmth.distributed.print.business.entity.ExamTaskReviewLog;
+import com.qmth.distributed.print.business.bean.params.ArraysParams;
+import com.qmth.distributed.print.business.bean.params.PrintPlanParams;
+import com.qmth.distributed.print.business.bean.result.EditResult;
+import com.qmth.distributed.print.business.entity.*;
+import com.qmth.distributed.print.business.enums.TaskTypeEnum;
 import com.qmth.distributed.print.business.enums.UploadFileEnum;
-import com.qmth.distributed.print.business.service.BasicAttachmentService;
-import com.qmth.distributed.print.business.service.ExamTaskDetailService;
-import com.qmth.distributed.print.business.service.ExamTaskReviewLogService;
-import com.qmth.distributed.print.business.service.ExamTaskService;
+import com.qmth.distributed.print.business.service.*;
+import com.qmth.distributed.print.business.templete.execute.AsyncTaskReviewSampleExportService;
 import com.qmth.distributed.print.business.util.ServletUtil;
 import com.qmth.distributed.print.common.contant.SystemConstant;
 import com.qmth.distributed.print.common.enums.ExceptionResultEnum;
@@ -25,14 +24,18 @@ import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiParam;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.BindingResult;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
 
+import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import javax.validation.Valid;
 import java.io.IOException;
 import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
 
 /**
@@ -61,6 +64,11 @@ public class ExamTaskController {
     @Autowired
     private BasicAttachmentService basicAttachmentService;
 
+    @Resource
+    private TBTaskService tbTaskService;
+
+    @Resource
+    private AsyncTaskReviewSampleExportService asyncTaskReviewSampleExportService;
     /**
      * 查询
      *
@@ -368,11 +376,16 @@ public class ExamTaskController {
 
     @ApiOperation(value = "导出审核样本")
     @RequestMapping(value = "/review_export", method = RequestMethod.POST)
-    public Result taskReviewExport(HttpServletRequest request,
-                                   @RequestBody ExamTaskReviewLog taskReviewLog) {
-//        boolean isSuccess = examTaskService.taskReviewSaveBatch(taskReviewLog);
-        // todo 导出
-        return ResultUtil.ok(true);
+    public Result taskReviewExport(@Valid @RequestBody ArraysParams arraysParams, BindingResult bindingResult) throws Exception {
+        if (bindingResult.hasErrors()) {
+            return ResultUtil.error(bindingResult.getAllErrors().get(0).getDefaultMessage());
+        }
+        Long[] ids = arraysParams.getIds();
+        Map<String, Object> map = tbTaskService.saveTask(TaskTypeEnum.SAMPLE_EXPORT);
+        map.put("ids",ids);
+        asyncTaskReviewSampleExportService.exportTask(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("创建任务失败");
     }
 
     /**

+ 80 - 4
distributed-print/src/main/java/com/qmth/distributed/print/auth/DistributedPrintAuthenticationService.java

@@ -3,15 +3,36 @@ package com.qmth.distributed.print.auth;
 import com.qmth.boot.core.security.model.AccessEntity;
 import com.qmth.boot.core.security.service.AuthorizationService;
 import com.qmth.boot.tools.signature.SignatureType;
+import com.qmth.distributed.print.business.bean.auth.AuthBean;
+import com.qmth.distributed.print.business.entity.SysUser;
+import com.qmth.distributed.print.business.entity.TBSession;
+import com.qmth.distributed.print.business.enums.PrivilegePropertyEnum;
+import com.qmth.distributed.print.business.enums.RoleTypeEnum;
+import com.qmth.distributed.print.business.service.CacheService;
+import com.qmth.distributed.print.business.service.TBSessionService;
+import com.qmth.distributed.print.business.util.ServletUtil;
+import com.qmth.distributed.print.common.contant.SystemConstant;
+import com.qmth.distributed.print.common.enums.ExceptionResultEnum;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Component;
 
-import java.util.Arrays;
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
 import java.util.List;
+import java.util.Objects;
+import java.util.Set;
 
 @Component
 public class DistributedPrintAuthenticationService implements AuthorizationService {
+    private final static Logger log = LoggerFactory.getLogger(DistributedPrintAuthenticationService.class);
 
-    List<String> list = Arrays.asList("/api/admin/test", "/api/exam/test");
+    @Resource
+    TBSessionService tbSessionService;
+
+    @Resource
+    CacheService cacheService;
 
     @Override
     public AccessEntity findByIdentity(String identity, SignatureType signatureType, String path) {
@@ -20,11 +41,66 @@ public class DistributedPrintAuthenticationService implements AuthorizationServi
 
     @Override
     public boolean hasPermission(AccessEntity accessEntity, String path) {
-        for (String s : list) {
-            if (s.contains(path)) {
+        if (Objects.nonNull(accessEntity) && Objects.nonNull(accessEntity.getIdentity())) {
+            TBSession tbSession = tbSessionService.getById(accessEntity.getIdentity());
+            List<String> privilegeUrl = cacheService.privilegeUrlCache(PrivilegePropertyEnum.NO_AUTH);
+            //无需鉴权的url
+            int noAuthCount = Objects.nonNull(privilegeUrl) ? (int) privilegeUrl.stream().filter(s -> s.equalsIgnoreCase(path)).count() : 0;
+            if (noAuthCount > 0) {
                 return true;
             }
+            Long userId = Long.parseLong(tbSession.getIdentity());
+            SysUser sysUser = cacheService.userCache(userId);
+            HttpServletRequest request = ServletUtil.getRequest();
+            HttpServletResponse response = ServletUtil.getResponse();
+            request.setAttribute(SystemConstant.SESSION, tbSession);
+            request.setAttribute(SystemConstant.USER, sysUser);
+            return authFootCommon(userId, SystemConstant.USER_OAUTH_CACHE, path, request, response);
         }
         return false;
     }
+
+    /**
+     * 鉴权尾公用
+     *
+     * @param userId
+     * @param type
+     * @param path
+     * @param request
+     * @param response
+     * @return
+     */
+    public boolean authFootCommon(Long userId,
+                                  String type,
+                                  String path,
+                                  HttpServletRequest request,
+                                  HttpServletResponse response) {
+        //验证权限
+        AuthBean authBean = type.contains(SystemConstant.USER_OAUTH_CACHE) ? authBean = cacheService.userAuthCache(userId) : null;
+        if (Objects.isNull(authBean)) {
+            throw ExceptionResultEnum.ROLE_ENABLE_AUTHORIZATION.exception();
+        }
+        request.setAttribute(SystemConstant.SCHOOL, authBean.getSchool());
+        request.setAttribute(SystemConstant.ORG, authBean.getOrg());
+
+        //超级系统管理员拥有所有权限
+        int count = Objects.nonNull(authBean) ? (int) authBean.getRoleList().stream().filter(s -> s.getType() == RoleTypeEnum.ADMIN).count() : 0;
+        if (count > 0) {
+            return true;
+        }
+        //系统公用接口不拦截
+        List<String> sysUrls = cacheService.privilegeUrlCache(PrivilegePropertyEnum.SYS);
+        int sysCount = Objects.nonNull(sysUrls) ? (int) sysUrls.stream().filter(s -> s.equalsIgnoreCase(path)).count() : 0;
+        if (sysCount > 0) {
+            return true;
+        }
+        Set<String> urls = authBean.getUrls();
+        int privilegeCount = Objects.nonNull(urls) ? (int) urls.stream().filter(s -> s.equalsIgnoreCase(path)).count() : 0;
+        if (privilegeCount == 0) {
+            log.warn("Authorization faile: url cannot access");
+            throw ExceptionResultEnum.UN_AUTHORIZATION.exception();
+        }
+        response.setStatus(ExceptionResultEnum.SUCCESS.getCode());
+        return true;
+    }
 }

+ 9 - 1
distributed-print/src/main/java/com/qmth/distributed/print/interceptor/AuthInterceptor.java

@@ -4,6 +4,7 @@ import com.qmth.boot.api.interceptor.ExtendInterceptor;
 import com.qmth.distributed.print.business.util.AuthUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.lang.Nullable;
 import org.springframework.stereotype.Component;
 import org.springframework.web.servlet.ModelAndView;
@@ -15,10 +16,17 @@ import javax.servlet.http.HttpServletResponse;
 public class AuthInterceptor extends ExtendInterceptor {
     private final static Logger log = LoggerFactory.getLogger(AuthInterceptor.class);
 
+    @Value("${com.qmth.api.metrics-endpoint}")
+    String endpoint;
+
     @Override
     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
         log.info("preHandle is come in");
-        return AuthUtil.adminAuthInterceptor(request, response);
+        if (request.getServletPath().contains(endpoint)) {
+            return true;
+        } else {
+            return AuthUtil.adminAuthInterceptor(request, response);
+        }
     }
 
     @Override

+ 1 - 1
distributed-print/src/main/resources/application.properties

@@ -80,7 +80,7 @@ prefix.url.basic=admin/basic
 prefix.url.exam=admin/exam
 prefix.url.data=admin/data
 prefix.url.work=admin/work
-prefix.url.client=client
+prefix.url.client=admin/client
 
 #\u65E5\u5FD7\u914D\u7F6E
 com.qmth.logging.root-level=info