فهرست منبع

Merge branch 'dev' into release
update

wangliang 4 سال پیش
والد
کامیت
e32ba38588
100فایلهای تغییر یافته به همراه3724 افزوده شده و 1615 حذف شده
  1. 15 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/annotation/ExcelDBFieldDesc.java
  2. 18 1
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/dto/ClientExamTaskDto.java
  3. 9 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/dto/ClientPrintBackupDataDto.java
  4. 9 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/dto/ClientPrintDataDto.java
  5. 18 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/dto/ClientPrintTaskDto.java
  6. 27 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/dto/CourseInfoDto.java
  7. 215 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/dto/ExaminationImportDto.java
  8. 47 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/dto/PaperPdfDto.java
  9. 39 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/dto/PdfDto.java
  10. 9 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/dto/PrintTaskTotalDto.java
  11. 43 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/dto/ReviewSampleDto.java
  12. 43 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/params/ClientLoginParam.java
  13. 9 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/params/ExamCardParams.java
  14. 6 30
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/params/LoginParam.java
  15. 22 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/params/UserSaveParams.java
  16. 22 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/result/ExaminationDetailResult.java
  17. 27 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/cache/CreatePdfCacheUtil.java
  18. 17 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/cache/RedisKeyHelper.java
  19. 11 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/entity/ExamCardDetail.java
  20. 12 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/entity/ExamDetail.java
  21. 13 1
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/entity/ExamDetailCourse.java
  22. 1 1
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/entity/ExamStudent.java
  23. 116 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/entity/ExamTaskPaperLog.java
  24. 24 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/entity/SysUser.java
  25. 12 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/entity/TBTask.java
  26. 3 6
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/enums/CardRequiredFieldsEnum.java
  27. 0 45
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/enums/ExaminationDBFieldsEnum.java
  28. 55 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/enums/FieldUniqueEnum.java
  29. 3 1
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/enums/RequiredFieldsEnum.java
  30. 3 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/mapper/BasicCourseMapper.java
  31. 3 1
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/mapper/ExamCardMapper.java
  32. 8 1
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/mapper/ExamDetailCourseMapper.java
  33. 9 6
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/mapper/ExamDetailMapper.java
  34. 2 2
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/mapper/ExamPrintPlanMapper.java
  35. 3 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/mapper/ExamStudentMapper.java
  36. 0 2
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/mapper/ExamTaskDetailMapper.java
  37. 14 3
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/mapper/ExamTaskMapper.java
  38. 16 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/mapper/ExamTaskPaperLogMapper.java
  39. 1 1
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/mapper/SysUserMapper.java
  40. 1 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/mapper/TBTaskMapper.java
  41. 17 1
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/BasicAttachmentService.java
  42. 10 1
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/BasicCourseService.java
  43. 20 9
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ClientService.java
  44. 1 2
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ClientStatusService.java
  45. 39 3
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/CommonService.java
  46. 5 1
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ExamCardService.java
  47. 9 2
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ExamDetailCourseService.java
  48. 19 13
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ExamDetailService.java
  49. 5 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ExamStudentService.java
  50. 2 3
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ExamTaskDetailService.java
  51. 17 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ExamTaskPaperLogService.java
  52. 19 7
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ExamTaskService.java
  53. 8 6
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/SysUserService.java
  54. 2 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/TBTaskService.java
  55. 96 28
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/BasicAttachmentServiceImpl.java
  56. 29 6
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/BasicCourseServiceImpl.java
  57. 5 4
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/BasicExamRuleServiceImpl.java
  58. 2 2
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/BasicTemplateServiceImpl.java
  59. 360 160
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ClientServiceImpl.java
  60. 5 7
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ClientStatusServiceImpl.java
  61. 147 50
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/CommonServiceImpl.java
  62. 55 15
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamCardServiceImpl.java
  63. 24 3
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamDetailCourseServiceImpl.java
  64. 149 92
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamDetailServiceImpl.java
  65. 44 26
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamPrintPlanServiceImpl.java
  66. 28 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamStudentServiceImpl.java
  67. 77 12
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamTaskDetailServiceImpl.java
  68. 27 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamTaskPaperLogServiceImpl.java
  69. 405 153
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamTaskServiceImpl.java
  70. 114 144
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/SysUserServiceImpl.java
  71. 3 2
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/TBTaskServiceImpl.java
  72. 1 1
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/execute/AsyncExaminationExportTemplateService.java
  73. 7 4
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/execute/AsyncExaminationImportTemplateService.java
  74. 165 158
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/service/impl/TaskLogicServiceImpl.java
  75. 1 1
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/util/ConvertUtil.java
  76. 174 60
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/util/CreatePdfUtil.java
  77. 3 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/util/ExcelUtil.java
  78. 20 14
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/util/FreemarkerUtil.java
  79. 7 3
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/util/PdfUtil.java
  80. 10 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/util/RedisUtil.java
  81. 8 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/util/ServletUtil.java
  82. 337 336
      distributed-print-business/src/main/resources/db/init-table.sql
  83. 14 0
      distributed-print-business/src/main/resources/mapper/BasicCourseMapper.xml
  84. 17 0
      distributed-print-business/src/main/resources/mapper/ExamCardMapper.xml
  85. 52 2
      distributed-print-business/src/main/resources/mapper/ExamDetailCourseMapper.xml
  86. 91 61
      distributed-print-business/src/main/resources/mapper/ExamDetailMapper.xml
  87. 21 9
      distributed-print-business/src/main/resources/mapper/ExamPrintPlanMapper.xml
  88. 23 0
      distributed-print-business/src/main/resources/mapper/ExamStudentMapper.xml
  89. 4 23
      distributed-print-business/src/main/resources/mapper/ExamTaskDetailMapper.xml
  90. 85 19
      distributed-print-business/src/main/resources/mapper/ExamTaskMapper.xml
  91. 4 0
      distributed-print-business/src/main/resources/mapper/ExamTaskPaperLogMapper.xml
  92. 3 2
      distributed-print-business/src/main/resources/mapper/SysUserMapper.xml
  93. 4 1
      distributed-print-business/src/main/resources/mapper/TBTaskMapper.xml
  94. 7 0
      distributed-print-common/src/main/java/com/qmth/distributed/print/common/contant/SystemConstant.java
  95. 1 1
      distributed-print-task/src/main/java/com/qmth/distributed/print/task/job/TimedSyncSchoolJob.java
  96. 14 2
      distributed-print-task/src/main/java/com/qmth/distributed/print/task/job/service/impl/JobServiceImpl.java
  97. 3 2
      distributed-print/src/main/java/com/qmth/distributed/print/api/BasicCourseController.java
  98. 0 21
      distributed-print/src/main/java/com/qmth/distributed/print/api/BasicTemplateOrgController.java
  99. 0 21
      distributed-print/src/main/java/com/qmth/distributed/print/api/BasicUserCourseController.java
  100. 0 21
      distributed-print/src/main/java/com/qmth/distributed/print/api/BasicVerifyCodeController.java

+ 15 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/annotation/ExcelDBFieldDesc.java

@@ -0,0 +1,15 @@
+package com.qmth.distributed.print.business.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * @Description: excel导入考务数据数据库必填属性描述
+ * @Author: CaoZixuan
+ * @Date: 2021-04-26
+ */
+@Retention(RetentionPolicy.RUNTIME) //定义注解运行策略
+public @interface ExcelDBFieldDesc {
+    String name(); //属性名称
+    int length() default 0; //属性接收长度限制默认0,为0的不校验长度
+}

+ 18 - 1
distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/dto/ClientExamTaskDto.java

@@ -6,6 +6,8 @@ package com.qmth.distributed.print.business.bean.dto;
 public class ClientExamTaskDto {
 
     private String examTaskId;
+    private String schoolId;
+    private String printPlanId;
     private String printPlanName;
     private String paperNumber;
     private String courseCode;
@@ -17,7 +19,6 @@ public class ClientExamTaskDto {
     private Boolean isPass;
     private Long tryTime;
 
-
     public String getExamTaskId() {
         return examTaskId;
     }
@@ -26,6 +27,22 @@ public class ClientExamTaskDto {
         this.examTaskId = examTaskId;
     }
 
+    public String getSchoolId() {
+        return schoolId;
+    }
+
+    public void setSchoolId(String schoolId) {
+        this.schoolId = schoolId;
+    }
+
+    public String getPrintPlanId() {
+        return printPlanId;
+    }
+
+    public void setPrintPlanId(String printPlanId) {
+        this.printPlanId = printPlanId;
+    }
+
     public String getPrintPlanName() {
         return printPlanName;
     }

+ 9 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/dto/ClientPrintBackupDataDto.java

@@ -9,6 +9,7 @@ public class ClientPrintBackupDataDto {
     private String courseName;
     private String paperNumber;
     private String paperType;
+    private String md5;
     private String url;
 
     public String getCourseCode() {
@@ -43,6 +44,14 @@ public class ClientPrintBackupDataDto {
         this.paperType = paperType;
     }
 
+    public String getMd5() {
+        return md5;
+    }
+
+    public void setMd5(String md5) {
+        this.md5 = md5;
+    }
+
     public String getUrl() {
         return url;
     }

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

@@ -11,6 +11,7 @@ public class ClientPrintDataDto {
     private String studentName;
     private String studentCode;
     private String paperType;
+    private String md5;
     private String url;
 
     public String getCourseCode() {
@@ -61,6 +62,14 @@ public class ClientPrintDataDto {
         this.paperType = paperType;
     }
 
+    public String getMd5() {
+        return md5;
+    }
+
+    public void setMd5(String md5) {
+        this.md5 = md5;
+    }
+
     public String getUrl() {
         return url;
     }

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

@@ -1,5 +1,7 @@
 package com.qmth.distributed.print.business.bean.dto;
 
+import com.qmth.distributed.print.business.annotation.ExcelProperty;
+
 /**
  * @Date: 2021/3/29.
  */
@@ -7,25 +9,41 @@ public class ClientPrintTaskDto {
 
     private String examDetailId;
     private String printPlanId;
+    @ExcelProperty(name = "印刷计划", width = 30, index = 2)
     private String printPlanName;
+    @ExcelProperty(name = "考试开始日期", width = 30, index = 3)
     private Long examStartTime;
+    @ExcelProperty(name = "考试结束日期", width = 30, index = 4)
     private Long examEndTime;
+    @ExcelProperty(name = "课程(代码)", width = 30, index = 5)
     private String courseNameCode;
+    @ExcelProperty(name = "试卷编号", width = 30, index = 6)
     private String paperNumber;
+    @ExcelProperty(name = "考点", width = 30, index = 7)
     private String examPlace;
+    @ExcelProperty(name = "考场", width = 30, index = 8)
     private String examRoom;
+    @ExcelProperty(name = "单科次A3(页)", width = 30, index = 9)
     private String singlePagesA3;
     private Integer pagesA3;
     private Integer pagesA4;
+    @ExcelProperty(name = "科次", width = 30, index = 10)
     private Integer totalSubjects;
+    @ExcelProperty(name = "印刷状态", width = 30, index = 11)
     private String status;
+    @ExcelProperty(name = "是否校验", width = 30, index = 13)
     private Boolean validate;
+    @ExcelProperty(name = "是否缓存", width = 30, index = 12)
     private Boolean isDownload;
     private Boolean isTry;
     private Boolean isPass;
+    @ExcelProperty(name = "印刷员", width = 30, index = 14)
     private String printUser;
+    @ExcelProperty(name = "印刷开始时间", width = 30, index = 15)
     private Long printStartTime;
+    @ExcelProperty(name = "印刷完成时间", width = 30, index = 16)
     private Long printEndTime;
+    @ExcelProperty(name = "卷袋编号", width = 30, index = 1)
     private String packageCode;
     private Long createId;
     private Long createTime;

+ 27 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/dto/CourseInfoDto.java

@@ -0,0 +1,27 @@
+package com.qmth.distributed.print.business.bean.dto;
+
+/**
+ * @Description: 根据用户账号和用户名称查询他可命题的课程
+ * @Author: CaoZixuan
+ * @Date: 2021-04-22
+ */
+public class CourseInfoDto {
+    private String courseCode;
+    private String courseName;
+
+    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;
+    }
+}

+ 215 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/dto/ExaminationImportDto.java

@@ -0,0 +1,215 @@
+package com.qmth.distributed.print.business.bean.dto;
+
+import com.qmth.distributed.print.business.annotation.ExcelDBFieldDesc;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.util.List;
+
+/**
+ * @Description: 考务数据导入Dto(对应 ExaminationDBFieldsEnum 同时作为考务数据表所需要的的字段,来接收excel导入的考务数据)
+ * @Author: CaoZixuan
+ * @Date: 2021-04-25
+ */
+public class ExaminationImportDto {
+
+    @ApiModelProperty(value = "学号")
+    @ExcelDBFieldDesc(name = "学号",length = 20)
+    private String studentCode;
+
+    @ApiModelProperty(value = "考号")
+    @ExcelDBFieldDesc(name = "考号",length = 20)
+    private String ticketNumber;
+
+    @ApiModelProperty(value = "座位号")
+    @ExcelDBFieldDesc(name = "座位号",length = 15)
+    private String siteNumber;
+
+    @ApiModelProperty(value = "姓名")
+    @ExcelDBFieldDesc(name = "姓名",length = 15)
+    private String studentName;
+
+    @ApiModelProperty(value = "课程代码")
+    @ExcelDBFieldDesc(name = "课程代码",length = 10)
+    private String courseCode;
+
+    @ApiModelProperty(value = "课程名称")
+    @ExcelDBFieldDesc(name = "课程名称",length = 20)
+    private String courseName;
+
+    @ApiModelProperty(value = "考点")
+    @ExcelDBFieldDesc(name = "考点",length = 10)
+    private String examPlace;
+
+    @ApiModelProperty(value = "考场")
+    @ExcelDBFieldDesc(name = "考场",length = 10)
+    private String examRoom;
+
+    @ApiModelProperty(value = "考试日期")
+    @ExcelDBFieldDesc(name = "考试日期")
+    private String examDate;
+
+    @ApiModelProperty(value = "考试时间")
+    @ExcelDBFieldDesc(name = "考试时间")
+    private String examTime;
+
+    @ApiModelProperty(value = "试卷编号")
+    @ExcelDBFieldDesc(name = "试卷编号",length = 15)
+    private String paperNumber;
+
+    @ApiModelProperty(value = "备选字段集合")
+    private List<FieldsDto> secondaryFieldList;
+
+    @ApiModelProperty(value = "考试开始时间")
+    private String examStartTime;
+
+    @ApiModelProperty(value = "考试结束时间")
+    private String examEndTime;
+
+    @ApiModelProperty(value = "学校id")
+    private Long schoolId;
+
+    @ApiModelProperty(value = "印刷计划id")
+    private Long printPlanId;
+
+    @ApiModelProperty(value = "印刷计划名称")
+    private String printPlanName;
+
+    public ExaminationImportDto() {
+    }
+
+    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 getSiteNumber() {
+        return siteNumber;
+    }
+
+    public void setSiteNumber(String siteNumber) {
+        this.siteNumber = siteNumber;
+    }
+
+    public String getStudentName() {
+        return studentName;
+    }
+
+    public void setStudentName(String studentName) {
+        this.studentName = studentName;
+    }
+
+    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 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 getExamDate() {
+        return examDate;
+    }
+
+    public void setExamDate(String examDate) {
+        this.examDate = examDate;
+    }
+
+    public String getExamTime() {
+        return examTime;
+    }
+
+    public void setExamTime(String examTime) {
+        this.examTime = examTime;
+    }
+
+    public String getPaperNumber() {
+        return paperNumber;
+    }
+
+    public void setPaperNumber(String paperNumber) {
+        this.paperNumber = paperNumber;
+    }
+
+    public List<FieldsDto> getSecondaryFieldList() {
+        return secondaryFieldList;
+    }
+
+    public void setSecondaryFieldList(List<FieldsDto> secondaryFieldList) {
+        this.secondaryFieldList = secondaryFieldList;
+    }
+
+    public String getExamStartTime() {
+        return examStartTime;
+    }
+
+    public void setExamStartTime(String examStartTime) {
+        this.examStartTime = examStartTime;
+    }
+
+    public String getExamEndTime() {
+        return examEndTime;
+    }
+
+    public void setExamEndTime(String examEndTime) {
+        this.examEndTime = examEndTime;
+    }
+
+    public Long getSchoolId() {
+        return schoolId;
+    }
+
+    public void setSchoolId(Long schoolId) {
+        this.schoolId = schoolId;
+    }
+
+    public Long getPrintPlanId() {
+        return printPlanId;
+    }
+
+    public void setPrintPlanId(Long printPlanId) {
+        this.printPlanId = printPlanId;
+    }
+
+    public String getPrintPlanName() {
+        return printPlanName;
+    }
+
+    public void setPrintPlanName(String printPlanName) {
+        this.printPlanName = printPlanName;
+    }
+}

+ 47 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/dto/PaperPdfDto.java

@@ -0,0 +1,47 @@
+package com.qmth.distributed.print.business.bean.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.File;
+import java.io.Serializable;
+
+/**
+ * @Description: 试卷pdf dto
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2021/4/26
+ */
+public class PaperPdfDto implements Serializable {
+
+    @ApiModelProperty(name = "文件")
+    File file;
+
+    @ApiModelProperty(name = "页面大小")
+    int pages;
+
+    public PaperPdfDto() {
+
+    }
+
+    public PaperPdfDto(File file, int pages) {
+        this.file = file;
+        this.pages = pages;
+    }
+
+    public File getFile() {
+        return file;
+    }
+
+    public void setFile(File file) {
+        this.file = file;
+    }
+
+    public int getPages() {
+        return pages;
+    }
+
+    public void setPages(int pages) {
+        this.pages = pages;
+    }
+}

+ 39 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/dto/PdfDto.java

@@ -18,12 +18,18 @@ public class PdfDto {
     @ApiModelProperty(name = "页数")
     Integer pageCount = 0;
 
+    @ApiModelProperty(name = "实际页数")
+    Integer actualPageCount = 0;
+
     @ApiModelProperty(name = "页面大小")
     PageSizeEnum pageSize;
 
     @ApiModelProperty(name = "序号")
     Integer sequence = 0;
 
+    @ApiModelProperty(name = "tag")
+    boolean tag = true;
+
     public PdfDto() {
 
     }
@@ -46,6 +52,39 @@ public class PdfDto {
         this.sequence = sequence;
     }
 
+    public PdfDto(PageSizeEnum pageSize, Integer pageCount, boolean tag) {
+        this.pageSize = pageSize;
+        this.pageCount = pageCount;
+        this.tag = tag;
+    }
+
+    public PdfDto(PageSizeEnum pageSize, Integer pageCount) {
+        this.pageSize = pageSize;
+        this.pageCount = pageCount;
+    }
+
+    public PdfDto(PageSizeEnum pageSize, Integer pageCount, Integer actualPageCount) {
+        this.pageSize = pageSize;
+        this.pageCount = pageCount;
+        this.actualPageCount = actualPageCount;
+    }
+
+    public Integer getActualPageCount() {
+        return actualPageCount;
+    }
+
+    public void setActualPageCount(Integer actualPageCount) {
+        this.actualPageCount = actualPageCount;
+    }
+
+    public boolean isTag() {
+        return tag;
+    }
+
+    public void setTag(boolean tag) {
+        this.tag = tag;
+    }
+
     public Integer getSequence() {
         return sequence;
     }

+ 9 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/dto/PrintTaskTotalDto.java

@@ -7,6 +7,7 @@ public class PrintTaskTotalDto {
 
     private Integer totalSubjects;
     private Integer packageCount;
+    private Integer paperCount;
     private Integer pagesA3;
     private Integer pagesA4;
     private Integer pagesA3Left;
@@ -28,6 +29,14 @@ public class PrintTaskTotalDto {
         this.packageCount = packageCount;
     }
 
+    public Integer getPaperCount() {
+        return paperCount;
+    }
+
+    public void setPaperCount(Integer paperCount) {
+        this.paperCount = paperCount;
+    }
+
     public Integer getPagesA3() {
         return pagesA3;
     }

+ 43 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/dto/ReviewSampleDto.java

@@ -0,0 +1,43 @@
+package com.qmth.distributed.print.business.bean.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * @Description: 审核样品Dto(来自 exam_task_detail 和 exam_task_paper_log)
+ * @Author: CaoZixuan
+ * @Date: 2021-04-27
+ */
+public class ReviewSampleDto {
+    @ApiModelProperty(value = "试卷副本信息")
+    private String paperAttachmentIds;
+
+    @ApiModelProperty(value = "题卡副本信息")
+    private Long cardId;
+
+    @ApiModelProperty(value = "审核副本信息")
+    private String paperConfirmAttachmentIds;
+
+    public String getPaperAttachmentIds() {
+        return paperAttachmentIds;
+    }
+
+    public void setPaperAttachmentIds(String paperAttachmentIds) {
+        this.paperAttachmentIds = paperAttachmentIds;
+    }
+
+    public Long getCardId() {
+        return cardId;
+    }
+
+    public void setCardId(Long cardId) {
+        this.cardId = cardId;
+    }
+
+    public String getPaperConfirmAttachmentIds() {
+        return paperConfirmAttachmentIds;
+    }
+
+    public void setPaperConfirmAttachmentIds(String paperConfirmAttachmentIds) {
+        this.paperConfirmAttachmentIds = paperConfirmAttachmentIds;
+    }
+}

+ 43 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/params/ClientLoginParam.java

@@ -0,0 +1,43 @@
+package com.qmth.distributed.print.business.bean.params;
+
+import io.swagger.annotations.ApiModelProperty;
+import org.hibernate.validator.constraints.Length;
+
+import javax.validation.constraints.NotBlank;
+
+/**
+ * @Description: 客户端登录
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2021/4/23
+ */
+public class ClientLoginParam {
+
+    @ApiModelProperty(value = "登录名")
+    @NotBlank(message = "请输入登录名")
+    @Length(message = "登录名不能超过{max}个字符", max = 50)
+    private String loginName;
+
+    @ApiModelProperty(value = "密码")
+    @NotBlank(message = "请输入密码")
+    @Length(message = "密码不能少于{min}位", min = 6)
+    @Length(message = "密码不能超过{max}位", max = 30)
+    private String password;
+
+    public String getLoginName() {
+        return loginName;
+    }
+
+    public void setLoginName(String loginName) {
+        this.loginName = loginName;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+}

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

@@ -19,6 +19,7 @@ public class ExamCardParams {
     private String content;
     private String htmlContent;
     private String attachmentId;
+    private String custAttachmentId;
     private CardTypeEnum type;
     private Long templateId;
 
@@ -102,6 +103,14 @@ public class ExamCardParams {
         this.attachmentId = attachmentId;
     }
 
+    public String getCustAttachmentId() {
+        return custAttachmentId;
+    }
+
+    public void setCustAttachmentId(String custAttachmentId) {
+        this.custAttachmentId = custAttachmentId;
+    }
+
     public CardTypeEnum getType() {
         return type;
     }

+ 6 - 30
distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/params/LoginParam.java

@@ -1,25 +1,17 @@
 package com.qmth.distributed.print.business.bean.params;
 
 import io.swagger.annotations.ApiModelProperty;
-import org.hibernate.validator.constraints.Length;
 
 import javax.validation.constraints.NotBlank;
 
 /**
- * @Date: 2021/3/30.
+ * @Description: 用户登录
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2021/4/23
  */
-public class LoginParam {
-
-    @ApiModelProperty(value = "登录名")
-    @NotBlank(message = "请输入登录名")
-    @Length(message = "登录名不能超过{max}个字符", max = 25)
-    private String loginName;
-
-    @ApiModelProperty(value = "密码")
-    @NotBlank(message = "请输入密码")
-    @Length(message = "密码不能少于{min}位", min = 6)
-    @Length(message = "密码不能超过{max}位", max = 30)
-    private String password;
+public class LoginParam extends ClientLoginParam {
 
     @ApiModelProperty(value = "验证码")
     @NotBlank(message = "请输入验证码")
@@ -37,22 +29,6 @@ public class LoginParam {
         this.schoolCode = schoolCode;
     }
 
-    public String getLoginName() {
-        return loginName;
-    }
-
-    public void setLoginName(String loginName) {
-        this.loginName = loginName;
-    }
-
-    public String getPassword() {
-        return password;
-    }
-
-    public void setPassword(String password) {
-        this.password = password;
-    }
-
     public String getCode() {
         return code;
     }

+ 22 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/params/UserSaveParams.java

@@ -0,0 +1,22 @@
+package com.qmth.distributed.print.business.bean.params;
+
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.qmth.distributed.print.business.entity.SysUser;
+import io.swagger.annotations.ApiModelProperty;
+import org.hibernate.validator.constraints.Length;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+
+/**
+ * @Description: 用户保存/编辑params
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2021/3/24
+ */
+public class UserSaveParams extends SysUser implements Serializable {
+
+}

+ 22 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/result/ExaminationDetailResult.java

@@ -46,6 +46,12 @@ public class ExaminationDetailResult {
     @ApiModelProperty(value = "座位号")
     private String siteNumber;
 
+    @ApiModelProperty(value = "考试开始时间")
+    private Long examStartTime;
+
+    @ApiModelProperty(value = "考试结束时间")
+    private Long examEndTime;
+
     @JsonSerialize(using = ToStringSerializer.class)
     @ApiModelProperty(value = "创建人主键")
     private Long createId;
@@ -141,6 +147,22 @@ public class ExaminationDetailResult {
         this.siteNumber = siteNumber;
     }
 
+    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 Long getCreateId() {
         return createId;
     }

+ 27 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/cache/CreatePdfCacheUtil.java

@@ -0,0 +1,27 @@
+package com.qmth.distributed.print.business.cache;
+
+import com.qmth.distributed.print.business.util.RedisUtil;
+import com.qmth.distributed.print.common.contant.SpringContextHolder;
+
+/**
+ * @Description: 生成pdf cache
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2021/4/26
+ */
+public class CreatePdfCacheUtil {
+    private static RedisUtil redisUtil = SpringContextHolder.getBean(RedisUtil.class);
+
+    public static void setPaperType(String key, String paperType) {
+        redisUtil.set(RedisKeyHelper.paperTypeKey(key), paperType);
+    }
+
+    public static String getPaperType(String key) {
+        return (String) redisUtil.get(RedisKeyHelper.paperTypeKey(key));
+    }
+
+    public static void deletePaperType(String key) {
+        redisUtil.delete(RedisKeyHelper.paperTypeKey(key));
+    }
+}

+ 17 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/cache/RedisKeyHelper.java

@@ -0,0 +1,17 @@
+package com.qmth.distributed.print.business.cache;
+
+/**
+ * @Description: redis cache helper
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2021/4/26
+ */
+public class RedisKeyHelper {
+
+    private static String paperTypePrefix = "paper_type:";
+
+    public static String paperTypeKey(String key) {
+        return paperTypePrefix + key;
+    }
+}

+ 11 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/entity/ExamCardDetail.java

@@ -34,6 +34,9 @@ public class ExamCardDetail extends BaseEntity implements Serializable {
     @TableField("attachment_id")
     private String attachmentId;
 
+    @TableField("cust_attachment_id")
+    private String custAttachmentId;
+
     public Long getCardId() {
         return cardId;
     }
@@ -65,4 +68,12 @@ public class ExamCardDetail extends BaseEntity implements Serializable {
     public void setAttachmentId(String attachmentId) {
         this.attachmentId = attachmentId;
     }
+
+    public String getCustAttachmentId() {
+        return custAttachmentId;
+    }
+
+    public void setCustAttachmentId(String custAttachmentId) {
+        this.custAttachmentId = custAttachmentId;
+    }
 }

+ 12 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/entity/ExamDetail.java

@@ -84,6 +84,18 @@ public class ExamDetail extends BaseEntity implements Serializable {
     @TableField(value = "attachment_id")
     private Long attachmentId;
 
+    @ApiModelProperty(value = "附件路径")
+    @TableField("attachment_path")
+    private String attachmentPath;
+
+    public String getAttachmentPath() {
+        return attachmentPath;
+    }
+
+    public void setAttachmentPath(String attachmentPath) {
+        this.attachmentPath = attachmentPath;
+    }
+
     public static long getSerialVersionUID() {
         return serialVersionUID;
     }

+ 13 - 1
distributed-print-business/src/main/java/com/qmth/distributed/print/business/entity/ExamDetailCourse.java

@@ -1,11 +1,11 @@
 package com.qmth.distributed.print.business.entity;
 
 import com.baomidou.mybatisplus.annotation.TableField;
-import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
 import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
 import com.qmth.distributed.print.business.base.BaseEntity;
+import io.swagger.annotations.ApiModelProperty;
 
 import java.io.Serializable;
 
@@ -45,6 +45,18 @@ public class ExamDetailCourse extends BaseEntity implements Serializable {
     @TableField("card_pages_a3")
     private Integer cardPagesA3;
 
+    @ApiModelProperty(value = "当前试卷类型")
+    @TableField("paper_type")
+    private String paperType;
+
+    public String getPaperType() {
+        return paperType;
+    }
+
+    public void setPaperType(String paperType) {
+        this.paperType = paperType;
+    }
+
     public Long getSchoolId() {
         return schoolId;
     }

+ 1 - 1
distributed-print-business/src/main/java/com/qmth/distributed/print/business/entity/ExamStudent.java

@@ -104,7 +104,7 @@ public class ExamStudent extends BaseEntity implements Serializable {
     }
 
     public String getSiteNumber() {
-        return Objects.isNull(siteNumber) ? "" : null;
+        return siteNumber;
     }
 
     public void setSiteNumber(String siteNumber) {

+ 116 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/entity/ExamTaskPaperLog.java

@@ -0,0 +1,116 @@
+package com.qmth.distributed.print.business.entity;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+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.ReviewStatusEnum;
+
+import java.io.Serializable;
+
+/**
+ * <p>
+ * 卷库修改审核临时表
+ * </p>
+ *
+ * @author xf
+ * @since 2021-03-23
+ */
+@TableName("exam_task_paper_log")
+public class ExamTaskPaperLog extends BaseEntity implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 命题任务ID
+     */
+    @JsonSerialize(using = ToStringSerializer.class)
+    @TableField("exam_task_id")
+    private Long examTaskId;
+    /**
+     * 试卷类型,多个以”/“分隔,如A/B/C/D
+     */
+    @TableField("paper_type")
+    private String paperType;
+    /**
+     * [
+     * {
+     * "type": "A",
+     * "attachmentId": 12,
+     * "totalPages": 3
+     * },
+     * {
+     * "type": "B",
+     * "attachmentId": 13,
+     * "totalPages": 2
+     * }
+     * ]
+     */
+    @TableField("paper_attachment_ids")
+    private String paperAttachmentIds;
+    /**
+     * 题卡ID
+     */
+    @JsonSerialize(using = ToStringSerializer.class)
+    @TableField("card_id")
+    private Long cardId;
+
+    /**
+     * 0-禁用,1-启用
+     */
+    private Boolean review;
+    /**
+     * 审核状态:PASS-审核通过,NOT_PASS-审核不通过,默认为空-未审核
+     */
+    @TableField("review_status")
+    private ReviewStatusEnum reviewStatus;
+
+    public Long getExamTaskId() {
+        return examTaskId;
+    }
+
+    public void setExamTaskId(Long examTaskId) {
+        this.examTaskId = examTaskId;
+    }
+
+    public String getPaperType() {
+        return paperType;
+    }
+
+    public void setPaperType(String paperType) {
+        this.paperType = paperType;
+    }
+
+    public String getPaperAttachmentIds() {
+        return paperAttachmentIds;
+    }
+
+    public void setPaperAttachmentIds(String paperAttachmentIds) {
+        this.paperAttachmentIds = paperAttachmentIds;
+    }
+
+    public Long getCardId() {
+        return cardId;
+    }
+
+    public void setCardId(Long cardId) {
+        this.cardId = cardId;
+    }
+
+    public Boolean getReview() {
+        return review;
+    }
+
+    public void setReview(Boolean review) {
+        this.review = review;
+    }
+
+    public ReviewStatusEnum getReviewStatus() {
+        return reviewStatus;
+    }
+
+    public void setReviewStatus(ReviewStatusEnum reviewStatus) {
+        this.reviewStatus = reviewStatus;
+    }
+}

+ 24 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/entity/SysUser.java

@@ -5,8 +5,16 @@ 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.service.SysConfigService;
+import com.qmth.distributed.print.common.contant.SpringContextHolder;
 import com.qmth.distributed.print.common.contant.SystemConstant;
+import org.apache.commons.lang3.StringUtils;
+import org.hibernate.validator.constraints.Length;
+import org.springframework.boot.SpringApplication;
+import sun.misc.BASE64Encoder;
 
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
 import java.io.Serializable;
 
 /**
@@ -32,11 +40,15 @@ public class SysUser extends BaseEntity implements Serializable {
      * 用户名
      */
     @TableField("login_name")
+    @NotBlank(message = "请输入登录名")
+    @Length(message = "登录名不能超过{max}个字符", max = 50)
     private String loginName;
     /**
      * 姓名
      */
     @TableField("real_name")
+    @NotBlank(message = "请输入姓名")
+    @Length(message = "姓名不能超过{max}个字符", max = 50)
     private String realName;
     /**
      * 密码
@@ -46,6 +58,8 @@ public class SysUser extends BaseEntity implements Serializable {
      * 手机号
      */
     @TableField("mobile_number")
+    @NotBlank(message = "请输入手机号码")
+    @Length(message = "手机号码不能超过{max}个字符", max = 25)
     private String mobileNumber;
 
     @JsonSerialize(using = ToStringSerializer.class)
@@ -70,6 +84,7 @@ public class SysUser extends BaseEntity implements Serializable {
 
     @JsonSerialize(using = ToStringSerializer.class)
     @TableField(exist = false)
+    @NotNull(message = "请选择角色")
     private Long[] roleIds;
 
     @JsonSerialize(using = ToStringSerializer.class)
@@ -82,6 +97,15 @@ public class SysUser extends BaseEntity implements Serializable {
         setUpdateId(userId);
         setCreateTime(System.currentTimeMillis());
         setUpdateTime(System.currentTimeMillis());
+        SysConfigService sysConfigService = SpringContextHolder.getBean(SysConfigService.class);
+        SysConfig sysConfig = sysConfigService.getByKey("sys.user.initPassword");
+        BASE64Encoder encoder = new BASE64Encoder();
+        setPassword(encoder.encode(StringUtils.isNoneBlank(sysConfig.getConfigValue()) ? sysConfig.getConfigValue().getBytes() : "123456".getBytes()));
+    }
+
+    public void setUpdateInfo(Long userId) {
+        setUpdateId(userId);
+        setUpdateTime(System.currentTimeMillis());
     }
 
     public Long getSchoolId() {

+ 12 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/entity/TBTask.java

@@ -105,6 +105,18 @@ public class TBTask implements Serializable {
     @TableField(value = "remark")
     private String remark;
 
+    @ApiModelProperty(value = "实体名称")
+    @TableField(value = "obj_name")
+    private String objName;
+
+    public String getObjName() {
+        return objName;
+    }
+
+    public void setObjName(String objName) {
+        this.objName = objName;
+    }
+
     public String getRemark() {
         return remark;
     }

+ 3 - 6
distributed-print-business/src/main/java/com/qmth/distributed/print/business/enums/CardRequiredFieldsEnum.java

@@ -12,13 +12,10 @@ import java.util.List;
  */
 public enum CardRequiredFieldsEnum {
 
-    STUDENT_CODE("studentCode", "学号"),
+    TICKET_NUMBER("ticketNumber", "考号"),
+    SITE_NUMBER("siteNumber", "座位号"),
     STUDENT_NAME("studentName","姓名"),
-    COURSE_CODE("courseCode","课程代码"),
-    COURSE_NAME("courseName","课程名称"),
-    EXAM_PLACE("examPlace","考点"),
-    EXAM_ROOM("examRoom","考场"),
-    PAPER_NUMBER("paperNumber","试卷编号");
+    COURSE_NAME("courseName","课程名称");
 
     private String code;
     private String desc;

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

@@ -1,45 +0,0 @@
-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;
-    }
-}

+ 55 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/enums/FieldUniqueEnum.java

@@ -0,0 +1,55 @@
+package com.qmth.distributed.print.business.enums;
+
+import java.util.Objects;
+
+/**
+ * @Description: 唯一约束字段转换
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2020/7/13
+ */
+public enum FieldUniqueEnum {
+
+    user_schoolId_orgId_loginName_idx("登录名");
+
+    private String title;
+
+    private FieldUniqueEnum(String title) {
+        this.title = title;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    /**
+     * 状态转换 toName
+     *
+     * @param value
+     * @return
+     */
+    public static String convertToName(String value) {
+        for (FieldUniqueEnum e : FieldUniqueEnum.values()) {
+            if (Objects.equals(value.trim(), e.getTitle())) {
+                return e.name();
+            }
+        }
+        return null;
+    }
+
+    /**
+     * 状态转换 toTitle
+     *
+     * @param value
+     * @return
+     */
+    public static String convertToTitle(String value) {
+        for (FieldUniqueEnum e : FieldUniqueEnum.values()) {
+            if (value.trim().contains(e.name())) {
+                return e.getTitle();
+            }
+        }
+        return null;
+    }
+}

+ 3 - 1
distributed-print-business/src/main/java/com/qmth/distributed/print/business/enums/RequiredFieldsEnum.java

@@ -6,12 +6,14 @@ import java.util.ArrayList;
 import java.util.List;
 
 /**
- * 考务必选字段
+ * 考务必选字段(此枚举类中的字段必须在ExaminationImportDto类中有对应的属性code作为属性名,同时该属性必须加@ExcelDBFieldDesc注解,且name必须和desc对应)
  * @Date: 2021/3/29.
  */
 public enum RequiredFieldsEnum {
 
     STUDENT_CODE("studentCode", "学号"),
+    TICKET_NUMBER("ticketNumber", "考号"),
+    SITE_NUMBER("siteNumber", "座位号"),
     STUDENT_NAME("studentName","姓名"),
     COURSE_CODE("courseCode","课程代码"),
     COURSE_NAME("courseName","课程名称"),

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

@@ -3,6 +3,7 @@ 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.CourseInfoDto;
 import com.qmth.distributed.print.business.bean.params.CourseParam;
 import com.qmth.distributed.print.business.entity.BasicCourse;
 import org.apache.ibatis.annotations.Param;
@@ -22,4 +23,6 @@ public interface BasicCourseMapper extends BaseMapper<BasicCourse> {
     List<BasicCourse> listCoursesByUserId(Long id);
 
     IPage<BasicCourse> listPage(Page<BasicCourse> page, @Param("schoolId") Long schoolId, @Param("code") String code, @Param("name") String name);
+
+    List<CourseInfoDto> findByUserLoginNameAndRealName(@Param("loginName")String loginName,@Param("realName") String realName);
 }

+ 3 - 1
distributed-print-business/src/main/java/com/qmth/distributed/print/business/mapper/ExamCardMapper.java

@@ -20,11 +20,13 @@ import java.util.List;
  */
 public interface ExamCardMapper extends BaseMapper<ExamCard> {
 
-    IPage<CardCustDto> listCardCust(Page<CardCustDto> page, @Param("status") String status, @Param("paperNumber") String paperNumber, @Param("userId") String userId, @Param("applyStartTime") Long applyStartTime, @Param("applyEndTime") Long applyEndTime, @Param("finishStartTime") Long finishStartTime, @Param("finishEndTime") Long finishEndTime);
+    IPage<CardCustDto> listCardCust(Page<CardCustDto> page, @Param("schoolId") String schoolId, @Param("status") String status, @Param("paperNumber") String paperNumber, @Param("userId") String userId, @Param("applyStartTime") Long applyStartTime, @Param("applyEndTime") Long applyEndTime, @Param("finishStartTime") Long finishStartTime, @Param("finishEndTime") Long finishEndTime);
 
     CardDetailDto getCardDetail(Long cardId);
 
     List<ExamCard> listGenericCard(@Param("schoolId") Long schoolId, @Param("orgId") Long orgId, @Param("type") String type);
 
     List<ExamCard> listCustom(@Param("schoolId") Long schoolId, @Param("orgId") Long orgId, @Param("courseCode") String courseCode, @Param("type") String type);
+
+    CardDetailDto getCardDetailBySelect(Long cardId);
 }

+ 8 - 1
distributed-print-business/src/main/java/com/qmth/distributed/print/business/mapper/ExamDetailCourseMapper.java

@@ -1,6 +1,7 @@
 package com.qmth.distributed.print.business.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.qmth.distributed.print.business.entity.BasicCourse;
 import com.qmth.distributed.print.business.entity.ExamDetailCourse;
 import org.apache.ibatis.annotations.Param;
 
@@ -17,5 +18,11 @@ import java.util.Map;
  */
 public interface ExamDetailCourseMapper extends BaseMapper<ExamDetailCourse> {
 
-    List<Map<String, String>> listByExamDetailId(@Param("examDetailId") Long examDetailId, @Param("status") String status);
+    List<Map<String, Object>> listByExamDetailId(@Param("examDetailId") Long examDetailId, @Param("status") String status);
+
+    List<ExamDetailCourse> listByExamDetailIdAndStatus(@Param("examDetailId") Long examDetailId, @Param("status") String status);
+
+    List<BasicCourse> listCoursesByPrintPlanId(@Param("param") String param, @Param("printPlanId") Long printPlanId);
+
+    List<String> listPaperNumberByPrintPlanId(@Param("param") String param, @Param("printPlanId") Long printPlanId);
 }

+ 9 - 6
distributed-print-business/src/main/java/com/qmth/distributed/print/business/mapper/ExamDetailMapper.java

@@ -32,24 +32,27 @@ public interface ExamDetailMapper extends BaseMapper<ExamDetail> {
                                            @Param("paperNumber") String paperNumber,
                                            @Param("examPlace") String examPlace,
                                            @Param("examRoom") String examRoom,
-                                           @Param("packageCode") String packageCode);
+                                           @Param("packageCode") String packageCode,
+                                           @Param("orgIds") Set<Long> orgIds);
 
     IPage<ExaminationDetailResult> findDetailPage(@Param("page") Page<ExaminationDetailResult> page,
+                                                  @Param("schoolId") Long schoolId,
                                                   @Param("printPlanId") Long printPlanId,
                                                   @Param("courseCode") String courseCode,
                                                   @Param("paperNumber") String paperNumber,
                                                   @Param("examPlace") String examPlace,
                                                   @Param("examRoom") String examRoom,
-                                                  @Param("studentParam") String studentParam);
+                                                  @Param("studentParams") String studentParams,
+                                                  @Param("orgIds") Set<Long> orgIds);
 
     IPage<ExaminationDetailResult> findDetailPageById(@Param("page") Page<ExaminationDetailResult> page,
                                                   @Param("examDetailId") Long examDetailId);
 
-    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);
+    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, @Param("orgIds") Set<Long> orgIds);
 
     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);
+    List<Map> listStudentByExamDetailId(@Param("schoolId") Long schoolId, @Param("examDetailId") Long examDetailId, @Param("ticketNumber") String ticketNumber, @Param("type") String type);
+
+    Integer selectPaperCount(@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, @Param("orgIds") Set<Long> orgIds);
 }

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

@@ -32,7 +32,7 @@ public interface ExamPrintPlanMapper extends BaseMapper<ExamPrintPlan> {
 
     List<PrintPlanBrief> list(@Param("schoolId") Long schoolId, @Param("orgIds") Set<Long> orgIds);
 
-    IPage<ClientPrintTaskDto> listClientPrintTask(Page<ClientPrintTaskDto> page, @Param("schoolId") Long schoolId, @Param("machineCode") Long machineCode, @Param("printPlanId") String 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, @Param("isDownload") Boolean isDownload, @Param("validate") Boolean validate, @Param("orgIds") Set<Long> orgIds);
+    IPage<ClientPrintTaskDto> listClientPrintTask(Page<ClientPrintTaskDto> page, @Param("schoolId") Long schoolId, @Param("machineCode") Long machineCode, @Param("printPlanId") String 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, @Param("isDownload") Boolean isDownload, @Param("validate") Boolean validate, @Param("orgIds") Set<Long> orgIds, @Param("examDetailStatus") String[] examDetailStatus);
 
-    List<ClientPrintTaskDto> listClientPrintTask(@Param("schoolId") Long schoolId, @Param("machineCode") Long machineCode, @Param("printPlanId") String 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, @Param("isDownload") Boolean isDownload, @Param("validate") Boolean validate, @Param("orgIds") Set<Long> orgIds);
+    List<ClientPrintTaskDto> listClientPrintTask(@Param("schoolId") Long schoolId, @Param("machineCode") Long machineCode, @Param("printPlanId") String 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, @Param("isDownload") Boolean isDownload, @Param("validate") Boolean validate, @Param("orgIds") Set<Long> orgIds, @Param("examDetailStatus") String[] examDetailStatus);
 }

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

@@ -3,6 +3,8 @@ package com.qmth.distributed.print.business.mapper;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.qmth.distributed.print.business.entity.ExamStudent;
 
+import java.util.Map;
+
 /**
  * <p>
  * 考生 Mapper 接口
@@ -13,4 +15,5 @@ import com.qmth.distributed.print.business.entity.ExamStudent;
  */
 public interface ExamStudentMapper extends BaseMapper<ExamStudent> {
 
+    Map<String, Object> getStudentDetail(Long id);
 }

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

@@ -24,6 +24,4 @@ public interface ExamTaskDetailMapper extends BaseMapper<ExamTaskDetail> {
 
     List<ExamTaskDetail> listByTemplateId(Long templateId);
 
-    List<Map<String, String>> listByExamDetailId(@Param("schoolId") Long schoolId, @Param("examDetailId") Long examDetailId);
-
 }

+ 14 - 3
distributed-print-business/src/main/java/com/qmth/distributed/print/business/mapper/ExamTaskMapper.java

@@ -32,9 +32,9 @@ public interface ExamTaskMapper extends BaseMapper<ExamTask> {
 
     IPage<ExamTaskDto> listTaskReviewAudited(Page<ExamTaskDto> page, @Param("schoolId") Long schoolId, @Param("reviewStatus") String reviewStatus, @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);
 
-    IPage<ExamTaskDetailDto> listTaskPaper(Page<ExamTaskDetailDto> page, @Param("schoolId") Long schoolId, @Param("courseCode") String courseCode, @Param("paperNumber") String paperNumber, @Param("startTime") Long startTime, @Param("endTime") Long endTime, @Param("orgIds") Set<Long> orgIds);
+    IPage<ExamTaskDetailDto> listTaskPaper(Page<ExamTaskDetailDto> page, @Param("schoolId") Long schoolId, @Param("courseCode") String courseCode, @Param("paperNumber") String paperNumber, @Param("startTime") Long startTime, @Param("endTime") Long endTime, @Param("orgIds") Set<Long> orgIds, @Param("containsQuestionTeacher") boolean containsQuestionTeacher, @Param("userId") Long userId);
 
-    List<RelatePaperDto> listPaperNumbers(@Param("schoolId") Long schoolId, @Param("courseCode") String courseCode);
+    List<RelatePaperDto> listPaperNumbers(@Param("schoolId") Long schoolId, @Param("courseCode") String courseCode, @Param("status") String status);
 
     ExamTaskDetailCardDto applyGetOne(Long examTaskId);
 
@@ -71,5 +71,16 @@ 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);
+    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, @Param("printPlanStatus") String printPlanStatus, @Param("examDetailStatus") String examDetailStatus);
+
+    List<ClientExamTaskDto> listClientExamTaskPage(@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, @Param("printPlanStatus") String printPlanStatus, @Param("examDetailStatus") String examDetailStatus);
+
+    List<ExamTask> listExamTaskByCardId(Long cardId);
+
+    /**
+     * 查询审核样品
+     * @param examTaskId 命题任务id
+     * @return 结果
+     */
+    List<ReviewSampleDto> listReviewSampleInfoByExamTaskId(@Param("examTaskId") Long examTaskId);
 }

+ 16 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/mapper/ExamTaskPaperLogMapper.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.ExamTaskPaperLog;
+
+/**
+ * <p>
+ * 卷库修改审核临时表 Mapper 接口
+ * </p>
+ *
+ * @author xf
+ * @since 2021-03-23
+ */
+public interface ExamTaskPaperLogMapper extends BaseMapper<ExamTaskPaperLog> {
+
+}

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

@@ -21,7 +21,7 @@ import java.util.Set;
  */
 public interface SysUserMapper extends BaseMapper<SysUser> {
 
-    IPage<UserDto> listPage(Page<UserDto> page, @Param("schoolId") Long schoolId, @Param("realName") String realName, @Param("roleId") String roleId, @Param("enable") Boolean enable);
+    IPage<UserDto> listPage(Page<UserDto> page, @Param("schoolId") Long schoolId, @Param("loginName") String loginName, @Param("roleId") String roleId, @Param("enable") Boolean enable);
 
     List<BlurryUserDto> listUser(@Param("schoolId") Long schoolId, @Param("type") String type, @Param("courseCode") String courseCode, @Param("param") String param, @Param("orgIds") Set<Long> orgIds);
 

+ 1 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/mapper/TBTaskMapper.java

@@ -19,6 +19,7 @@ import java.util.Map;
 public interface TBTaskMapper extends BaseMapper<TBTask> {
 
     public IPage<TaskListResult> query(IPage<Map> iPage,
+                                       @Param("schoolId") Long schoolId,
                                        @Param("printPlanId") Long printPlanId,
                                        @Param("status") String status,
                                        @Param("type") String type,

+ 17 - 1
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/BasicAttachmentService.java

@@ -4,9 +4,13 @@ import com.baomidou.mybatisplus.extension.service.IService;
 import com.itextpdf.text.DocumentException;
 import com.qmth.distributed.print.business.bean.dto.PdfDto;
 import com.qmth.distributed.print.business.entity.BasicAttachment;
+import com.qmth.distributed.print.business.entity.ExamDetail;
+import com.qmth.distributed.print.business.entity.ExamDetailCourse;
+import com.qmth.distributed.print.business.enums.ClassifyEnum;
 import com.qmth.distributed.print.business.enums.UploadFileEnum;
 import org.springframework.web.multipart.MultipartFile;
 
+import java.io.File;
 import java.io.IOException;
 import java.util.List;
 
@@ -53,6 +57,16 @@ public interface BasicAttachmentService extends IService<BasicAttachment> {
      */
     public BasicAttachment saveAttachmentHtml(String fileName, String htmlContent, Long userId, List<PdfDto> localFileList) throws IOException;
 
+    /**
+     * 保存html文件
+     *
+     * @param rootPath    文件路径
+     * @param fileName    文件名
+     * @param htmlContent 文件内容
+     * @return
+     */
+    public File saveAttachmentHtml(String rootPath, String fileName, String htmlContent);
+
     /**
      * 保存附件
      *
@@ -66,6 +80,8 @@ public interface BasicAttachmentService extends IService<BasicAttachment> {
     /**
      * 保存附件
      *
+     * @param classifyEnum
+     * @param examDetail
      * @param basicAttachment
      * @param pdfList
      * @param printCount
@@ -73,7 +89,7 @@ public interface BasicAttachmentService extends IService<BasicAttachment> {
      * @return
      * @throws IOException
      */
-    public BasicAttachment saveAttachmentPdf(BasicAttachment basicAttachment, List<PdfDto> pdfList, Integer printCount, Integer sequence) throws IOException, DocumentException;
+    public BasicAttachment saveAttachmentPdf(ClassifyEnum classifyEnum, ExamDetail examDetail, BasicAttachment basicAttachment, List<PdfDto> pdfList, Integer printCount, Integer sequence) throws IOException, DocumentException;
 
     /**
      * 删除附件

+ 10 - 1
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/BasicCourseService.java

@@ -2,6 +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.CourseInfoDto;
 import com.qmth.distributed.print.business.bean.params.BlurryParam;
 import com.qmth.distributed.print.business.bean.params.CourseParam;
 import com.qmth.distributed.print.business.entity.BasicCourse;
@@ -20,7 +21,7 @@ public interface BasicCourseService extends IService<BasicCourse> {
 
     IPage<BasicCourse> list(String code, String name, Integer pageNumber, Integer pageSize);
 
-    List<BasicCourse> list(String param);
+    List<BasicCourse> list(String param, Long printPlanId);
 
     boolean saveCourse(BasicCourse course,Long userId);
 
@@ -36,4 +37,12 @@ public interface BasicCourseService extends IService<BasicCourse> {
      * @param userId 当前用户id
      */
     void verifyCourseInfo(Long schoolId,String courseCode,String courseName,Long userId);
+
+    /**
+     * 根据用户登录名和真实名称查找其可命的课程
+     * @param loginName 登录名
+     * @param realName 真实名
+     * @return 课程集合
+     */
+    List<CourseInfoDto> findByUserLoginNameAndRealName(String loginName,String realName);
 }

+ 20 - 9
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ClientService.java

@@ -5,6 +5,7 @@ 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.ClientPrintTaskDto;
 
+import javax.servlet.http.HttpServletResponse;
 import java.util.List;
 import java.util.Map;
 
@@ -12,21 +13,31 @@ 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);
+    IPage<ClientExamTaskDto> listTryTask(String machineCode, Long orgId, Long printPlanId, String courseCode, String paperNumber, Boolean isTry, Boolean isPass, Integer pageNumber, Integer pageSize);
 
-    String getUrl(Long schoolId, Long examTaskId);
+    Map<String, String> getUrl(Long examTaskId);
 
-    Boolean tagPass(Long schoolId, Long examTaskId, String machineCode, Boolean isPass, Long userId);
+    Boolean tagPass(String courseCode, String courseName, String paperNumber, String machineCode, Boolean isPass, Long userId);
 
-    Boolean updatePrintProgress(Long schoolId, Long examDetailId, Integer printProgress);
+    Boolean updatePrintProgress(Long examDetailId, Integer printProgress);
 
-    IPage<ClientExamStudentDto> listStudent(Long schoolId, Long examDetailId, String ticketNumber, String studentName, String courseCode, Integer pageNumber, Integer pageSize);
+    IPage<ClientExamStudentDto> listStudent(Long examDetailId, String ticketNumber, String studentName, String courseCode, Integer pageNumber, Integer pageSize);
 
-    Map<String, Object> getReprintData(Long schoolId, Long examDetailId, String ticketNumber, String type);
+    Map<String, Object> getReprintData(Long examDetailId, String ticketNumber, String type);
 
-    IPage<ClientPrintTaskDto> listClientPrintTask(Long schoolId, Long machineCode, String orgId, String printPlanId, String status, String courseCode, String paperNumber, String examPlace, String examRoom, Long examStartTime, Long examEndTime, Boolean isDownload, Boolean validate, Integer pageNumber, Integer pageSize);
+    IPage<ClientPrintTaskDto> listClientPrintTask(Long machineCode, String orgId, String printPlanId, String status, String courseCode, String paperNumber, String examPlace, String examRoom, Long examStartTime, Long examEndTime, Boolean isDownload, Boolean validate, Integer pageNumber, Integer pageSize);
 
-    Map<String, Object> getPrintData(Long schoolId, Long examDetailId, String machineCode, String printUser);
+    Map<String, Object> getPrintData(Long examDetailId, String machineCode, Boolean isPrint, String printUser);
 
-    List<Map<String, Object>> getPrintDataBatch(Long schoolId, Long machineCode, String orgId, String printPlanId, String status, String courseCode, String paperNumber, String examPlace, String examRoom, Long examStartTime, Long examEndTime, Boolean isDownload, Boolean validate);
+    List<Map<String, Object>> getPrintDataBatch(Long machineCode, String orgId, String printPlanId, String status, String courseCode, String paperNumber, String examPlace, String examRoom, Long examStartTime, Long examEndTime, Boolean isDownload, Boolean validate);
+
+    Map<String, String> getUrlByExamDetailId(Long examDetailId);
+
+    Boolean updateDownload(Long examDetailId, String machineCode, Boolean isDownload);
+
+    Boolean validateData(Long examDetailId, String packageCode, String lastCode);
+
+    List<Map<String, String>> getBatchUrl(String machineCode, Long orgId, Long printPlanId, String courseCode, String paperNumber, Boolean isTry, Boolean isPass);
+
+    void exportClientPrintTask(HttpServletResponse response, Long machineCode, String orgId, String printPlanId, String status, String courseCode, String paperNumber, String examPlace, String examRoom, Long examStartTime, Long examEndTime, Boolean isDownload, Boolean validate) throws Exception;
 }

+ 1 - 2
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ClientStatusService.java

@@ -14,6 +14,5 @@ import java.util.List;
  * @since 2021-04-19
  */
 public interface ClientStatusService extends IService<ClientStatus> {
-    Boolean tagPass(Long schoolId, Long examTaskId, String machineCode, Boolean isPass, Long userId);
-
+    Boolean tagPass(Long schoolId, String courseCode, String courseName, String paperNumber, String machineCode, Boolean isPass, Long userId);
 }

+ 39 - 3
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/CommonService.java

@@ -2,6 +2,7 @@ package com.qmth.distributed.print.business.service;
 
 import com.qmth.distributed.print.business.bean.auth.AuthBean;
 import com.qmth.distributed.print.business.bean.dto.PrivilegeCacheDto;
+import com.qmth.distributed.print.business.bean.result.LoginResult;
 import com.qmth.distributed.print.business.bean.result.RolePrivilegeResult;
 import com.qmth.distributed.print.business.entity.BasicAttachment;
 import com.qmth.distributed.print.business.entity.SysRolePrivilege;
@@ -100,10 +101,19 @@ public interface CommonService {
 
     /**
      * 文件预览
+     *
+     * @param path
+     * @return
+     */
+    public String filePreviewByPathAndType(String path, String type, Boolean isExpire);
+
+    /**
+     * 文件预览
+     *
      * @param attachmentId
      * @return
      */
-    public Map<String, String> filePreview(String attachmentId, Boolean isExpire);
+    public Map<String, String> filePreviewByAttachmentId(Long attachmentId, Boolean isExpire);
 
     /**
      * 题卡html文件上传,读取文件内容
@@ -147,7 +157,7 @@ public interface CommonService {
      * @param attachment 附件表对象
      * @return
      */
-    public File copyFile(String rootPath, BasicAttachment attachment);
+    public File copyFile(String rootPath, String fileName, BasicAttachment attachment);
 
     /**
      * 下载文件到本地并压缩返回
@@ -157,17 +167,43 @@ public interface CommonService {
      */
     public void downloadFileAndZip(HttpServletResponse response, String filePath, List<File> files);
 
+    /**
+     * 下载文件到本地并压缩返回
+     *
+     * @param filePath 文件根目录
+     * @param time     zip文件名(时间戳)
+     */
+    public void downloadFileAndZip(HttpServletResponse response, String filePath, long time);
+
     /**
      * 校验是否可以提交
+     *
      * @param schoolId
      * @param courseCode
      * @param paperNumber
      */
-    public void checkData(Long schoolId, String courseCode, String paperNumber,SysUser user) throws IOException;
+    public void checkData(Long schoolId, String courseCode, String paperNumber, SysUser user) throws IOException;
 
     /**
      * 根据orgId查询所有子机构ID集合
+     *
      * @return
      */
     public Set<Long> listSubOrgIds(Long orgId);
+
+    /**
+     * 登录公用
+     *
+     * @param password
+     * @param sysUser
+     * @return
+     */
+    public LoginResult login(String password, SysUser sysUser) throws NoSuchAlgorithmException;
+
+    /**
+     * 生成唯一的试卷编号
+     * @param schoolId
+     * @return
+     */
+    public String createPaperNumber(Long schoolId);
 }

+ 5 - 1
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ExamCardService.java

@@ -4,9 +4,11 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.qmth.distributed.print.business.bean.dto.CardCustDto;
 import com.qmth.distributed.print.business.bean.dto.CardDetailDto;
+import com.qmth.distributed.print.business.bean.params.ArraysParams;
 import com.qmth.distributed.print.business.bean.params.ExamCardParams;
 import com.qmth.distributed.print.business.entity.ExamCard;
 
+import javax.servlet.http.HttpServletResponse;
 import java.util.List;
 
 /**
@@ -21,7 +23,7 @@ public interface ExamCardService extends IService<ExamCard> {
 
     String saveExamCard(ExamCardParams examCardParams);
 
-    IPage<CardCustDto> listCardCust(String status, String paperNumber, String userId, Long applyStartTime, Long applyEndTime, Long finishStartTime, Long finishEndTime, Integer pageNumber, Integer pageSize);
+    IPage<CardCustDto> listCardCust(String schoolId, String status, String paperNumber, String userId, Long applyStartTime, Long applyEndTime, Long finishStartTime, Long finishEndTime, Integer pageNumber, Integer pageSize);
 
     String saveExamCardCust(ExamCardParams examCardParams);
 
@@ -32,4 +34,6 @@ public interface ExamCardService extends IService<ExamCard> {
     boolean usedCardByTemplateId(Long id);
 
     List<ExamCard> listSelectCard(String courseCode, Long cardRuleId, String paperType);
+
+    void downloadFiles(HttpServletResponse response, ArraysParams arraysParams);
 }

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

@@ -1,6 +1,7 @@
 package com.qmth.distributed.print.business.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.qmth.distributed.print.business.entity.BasicCourse;
 import com.qmth.distributed.print.business.entity.ExamDetailCourse;
 
 import java.util.List;
@@ -23,9 +24,15 @@ public interface ExamDetailCourseService extends IService<ExamDetailCourse> {
      */
     double calculatePackagesByDetailId(Long examDetailId);
 
-    List<Map<String, String>> listByExamDetailId(Long examDetailId);
+    List<Map<String, Object>> listByExamDetailId(Long examDetailId);
 
     List<ExamDetailCourse> listDetailCourseByCourseCodeAndPaperNumber(Long schoolId, String courseCode, String paperNumber);
 
-    void updatePaperNumber(List<ExamDetailCourse> examDetailCourses, String paperNumber);
+    void updatePaperNumber(List<ExamDetailCourse> examDetailCourses, String paperNumber, String relatePaperType);
+
+    List<ExamDetailCourse> listByExamDetailIdAndStatus(Long examDetailId);
+
+    List<BasicCourse> listCoursesByPrintPlanId(String param, Long printPlanId);
+
+    List<String> listPaperNumberByPrintPlanId(String param, Long printPlanId);
 }

+ 19 - 13
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ExamDetailService.java

@@ -8,12 +8,12 @@ import com.qmth.distributed.print.business.bean.result.ExaminationDetailResult;
 import com.qmth.distributed.print.business.bean.result.ExaminationResult;
 import com.qmth.distributed.print.business.bean.result.SummarizedDataResult;
 import com.qmth.distributed.print.business.entity.ExamDetail;
-import com.qmth.distributed.print.business.entity.ExamDetailCourse;
 
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 /**
  * <p>
@@ -70,10 +70,11 @@ public interface ExamDetailService extends IService<ExamDetail> {
      * @param packageCode 卷袋编号
      * @param pageNumber 分页页码
      * @param pageSize 分页数量
+     * @param orgIds 权限控制参数
      * @return 查询结果
      */
-    IPage<ExaminationResult> findExaminationBriefPage(Long schoolId,Long printPlanId,String courseCode,String paperNumber,
-                                                      String examPlace,String examRoom,String packageCode,int pageNumber,int pageSize);
+    IPage<ExaminationResult> findExaminationBriefPage(Long schoolId, Long printPlanId, String courseCode, String paperNumber,
+                                                      String examPlace, String examRoom, String packageCode, int pageNumber, int pageSize, Set<Long> orgIds);
 
     /**
      * 查询考务数据-汇总数据查询
@@ -84,10 +85,11 @@ public interface ExamDetailService extends IService<ExamDetail> {
      * @param examPlace 考点
      * @param examRoom 考场
      * @param packageCode 卷袋编号
+     * @param orgIds 权限控制参数
      * @return 查询结果
      */
     SummarizedDataResult findSummarizedData(Long schoolId,Long printPlanId,String courseCode,String paperNumber,
-                                            String examPlace,String examRoom,String packageCode);
+                                            String examPlace,String examRoom,String packageCode,Set<Long> orgIds);
 
 
     /**
@@ -97,27 +99,31 @@ public interface ExamDetailService extends IService<ExamDetail> {
      * @param paperNumber 试卷编号
      * @param examPlace 考点
      * @param examRoom 考场
-     * @param studentParam 学生查询参数
+     * @param studentParams 学生查询参数
      * @param pageNumber 分页页码
      * @param pageSize 分页数量
      * @return 查询结果
      */
-    IPage<ExaminationDetailResult> findExaminationDetail(Long printPlanId,String courseCode,String paperNumber,String examPlace,
-                                                         String examRoom,String studentParam,int pageNumber,int pageSize);
+    IPage<ExaminationDetailResult> findExaminationDetail(Long schoolId, Long printPlanId,String courseCode,String paperNumber,String examPlace,
+                                                         String examRoom,String studentParams,int pageNumber,int pageSize);
 
     IPage<ExaminationDetailResult> findExaminationDetail(Long convertIdToLong, int pageNumber, int pageSize);
 
     /**
      * 查询印刷计划下考点数据源
      * @return 考点集合
+     * @param param
+     * @param printPlanId
      */
-    List<String> findExamPlaceDatasource();
+    List<String> findExamPlaceDatasource(String param, Long printPlanId);
 
     /**
      * 查询印刷计划下考场数据源
      * @return 考场集合
+     * @param param
+     * @param printPlanId
      */
-    List<String> findExamRoomDatasource();
+    List<String> findExamRoomDatasource(String param, Long printPlanId);
 
     boolean submitTask(ExamDetail examDetail) throws IOException;
 
@@ -131,21 +137,21 @@ public interface ExamDetailService extends IService<ExamDetail> {
      * @param userId 当前用户id
      * @param serialNumberParams 序列号生成参数
      */
-    List<Long> disposeExamDetailByExaminationExcel(List<Map<String, Object>> dataList, Long userId, SerialNumberParams serialNumberParams);
+    List<Long> disposeExamDetailByExaminationExcel(List<ExaminationImportDto> dataList, Long userId, SerialNumberParams serialNumberParams);
 
     /**
      * 根据考务数据Excel数据处理考务-科目表
      * @param dataList Excel处理后的数据
      * @param userId 当前用户id
      */
-    void disposeExamDetailCourseByExaminationExcel(List<Map<String, Object>> dataList,Long userId);
+    void disposeExamDetailCourseByExaminationExcel(List<ExaminationImportDto> dataList,Long userId);
 
     /**
      * 根据考务数据Excel数据处理考务-学生表
      * @param dataList Excel处理后的数据
      * @param userId 当前用户id
      */
-    void disposeExamStudentByExaminationExcel(List<Map<String, Object>> dataList,Long userId);
+    void disposeExamStudentByExaminationExcel(List<ExaminationImportDto> dataList,Long userId);
 
     /**
      * 删除考务数据
@@ -171,5 +177,5 @@ public interface ExamDetailService extends IService<ExamDetail> {
 
     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);
+    List<Map> listStudentByExamDetailId(Long schoolId, Long examDetailId, String ticketNumber, String type);
 }

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

@@ -5,6 +5,7 @@ import com.qmth.distributed.print.business.entity.ExamDetailCourse;
 import com.qmth.distributed.print.business.entity.ExamStudent;
 
 import java.util.List;
+import java.util.Map;
 
 /**
  * <p>
@@ -17,4 +18,8 @@ import java.util.List;
 public interface ExamStudentService extends IService<ExamStudent> {
 
     void updatePaperType(List<ExamDetailCourse> examDetailCourses, String relatePaperType);
+
+    List<String> listByExamDetailCourseId(String examDetailCourseId);
+
+    Map<String, Object> getStudentDetail(Long id);
 }

+ 2 - 3
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ExamTaskDetailService.java

@@ -34,8 +34,7 @@ public interface ExamTaskDetailService extends IService<ExamTaskDetail> {
 
     List<ExamTaskDetail> listByTemplateId(Long templateId);
 
-    String getUrl(Long schoolId, Long examTaskId);
-
-    List<Map<String, String>> listByExamDetailId(Long schoolId, Long examDetailId);
+    Map<String, String>  getUrl(Long schoolId, Long examTaskId);
 
+    boolean paperUpdate(ExamTaskDetail examTaskDetail);
 }

+ 17 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ExamTaskPaperLogService.java

@@ -0,0 +1,17 @@
+package com.qmth.distributed.print.business.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.qmth.distributed.print.business.entity.ExamTaskPaperLog;
+
+/**
+ * <p>
+ * 卷库修改审核临时表 服务类
+ * </p>
+ *
+ * @author xf
+ * @since 2021-03-23
+ */
+public interface ExamTaskPaperLogService extends IService<ExamTaskPaperLog> {
+
+    ExamTaskPaperLog getByExamTaskIdAndReview(Long examTaskId, boolean review);
+}

+ 19 - 7
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ExamTaskService.java

@@ -1,7 +1,6 @@
 package com.qmth.distributed.print.business.service;
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.qmth.distributed.print.business.bean.dto.*;
 import com.qmth.distributed.print.business.bean.result.WorkResult;
@@ -31,7 +30,7 @@ public interface ExamTaskService extends IService<ExamTask> {
 
     IPage<ExamTaskDto> list(Boolean enable, String status, Long cardRuleId, String courseCode, String paperNumber, Long startTime, Long endTime, Integer pageNumber, Integer pageSize);
 
-    List<String> listPaperNumber(String param);
+    List<String> listPaperNumber(String param, Long printPlanId);
 
     List<BlurryUserDto> listUser(String param);
 
@@ -53,7 +52,7 @@ public interface ExamTaskService extends IService<ExamTask> {
 
     boolean taskReviewSave(ExamTaskReviewLog taskReviewLog) throws IOException;
 
-    boolean taskReviewSaveBatch(ExamTaskReviewLog taskReviewLog);
+    boolean taskReviewSaveBatch(ExamTaskReviewLog taskReviewLog) throws IOException;
 
     IPage<ExamTaskDetailDto> listTaskPaper(String courseCode, String paperNumber, Long startTime, Long endTime, Integer pageNumber, Integer pageSize);
 
@@ -95,18 +94,31 @@ public interface ExamTaskService extends IService<ExamTask> {
 
     IPage<ClientExamTaskDto> listTryTask(Long schoolId, String machineCode, Long orgId, Long printPlanId, String courseCode, String paperNumber, Boolean isTry, Boolean isPass, Integer pageNumber, Integer pageSize);
 
+    List<ClientExamTaskDto> listTryTask(Long schoolId, String machineCode, Long orgId, Long printPlanId, String courseCode, String paperNumber, Boolean isTry, Boolean isPass);
+
     /**
      * 检测考务数据的试卷编号和课程代码的正确性(根据试卷编号查询命题任务的试卷编号,如果存在,查询该命题任务记录对应的课程代码和考务数据导入的该条课程代码是否一致)
-     * @param schoolId 考务数据导入的学校代码
+     *
+     * @param schoolId    考务数据导入的学校代码
      * @param paperNumber 考务数据导入的试卷编号
-     * @param courseCode 考务数据导入的课程代码
+     * @param courseCode  考务数据导入的课程代码
      */
-    void verifyCourseCodeByPaperNumber(Long schoolId,String paperNumber,String courseCode);
+    void verifyCourseCodeByPaperNumber(Long schoolId, String paperNumber, String courseCode);
 
     /**
      * 根据考务-考场检验该考场下的所有命题任务是否已经完成,全部完成则生成pdf
+     *
      * @param examDetailId 考务考场id
-     * @param user 用户id
+     * @param user         用户id
      */
     void checkDataByExamination(Long examDetailId, SysUser user) throws IOException;
+
+    List<ExamTask> listExamTaskByCardId(Long cardId);
+
+    /**
+     * 根据命题任务id从('exam_task_detail'表和'exam_task_paper_log'表查找审核样品信息)
+     * @param examTaskId 命题任务主键
+     * @return 命题任务信息
+     */
+    ReviewSampleDto findReviewSampleInfoByExamTaskId(Long examTaskId);
 }

+ 8 - 6
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/SysUserService.java

@@ -5,8 +5,10 @@ import com.baomidou.mybatisplus.extension.service.IService;
 import com.qmth.distributed.print.business.bean.dto.BlurryUserDto;
 import com.qmth.distributed.print.business.bean.dto.LoginDto;
 import com.qmth.distributed.print.business.bean.dto.UserDto;
+import com.qmth.distributed.print.business.bean.params.UserSaveParams;
 import com.qmth.distributed.print.business.entity.SysUser;
 
+import java.security.NoSuchAlgorithmException;
 import java.util.List;
 
 /**
@@ -19,15 +21,15 @@ import java.util.List;
  */
 public interface SysUserService extends IService<SysUser> {
 
-    IPage<UserDto> list(String realName, String roleId, Boolean enable, Integer pageNumber, Integer pageSize);
+    IPage<UserDto> list(String loginName, String roleId, Boolean enable, Integer pageNumber, Integer pageSize);
 
-    boolean saveUser(SysUser user);
+    boolean saveUser(UserSaveParams userSaveParams);
 
-    boolean enable(SysUser user);
+    boolean enable(SysUser user) throws NoSuchAlgorithmException;
 
-    boolean resetPassword(Long id);
+    boolean resetPassword(Long id) throws NoSuchAlgorithmException;
 
-    boolean updatePassword(SysUser user);
+    boolean updatePassword(SysUser user) throws NoSuchAlgorithmException;
 
     boolean bindRoles(SysUser sysUser);
 
@@ -37,7 +39,7 @@ public interface SysUserService extends IService<SysUser> {
 
     List<SysUser> listByOrgId(Long id);
 
-    boolean saveCustomer(SysUser user);
+    boolean saveCustomer(UserSaveParams userSaveParams);
 
     IPage<UserDto> listCustomer(String realName, Boolean enable, Integer pageNumber, Integer pageSize);
 }

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

@@ -114,6 +114,7 @@ public interface TBTaskService extends IService<TBTask> {
      * 查询任务列表
      *
      * @param iPage
+     * @param schoolId
      * @param printPlanId
      * @param status
      * @param type
@@ -121,6 +122,7 @@ public interface TBTaskService extends IService<TBTask> {
      * @return
      */
     public IPage<TaskListResult> query(IPage<Map> iPage,
+                                       Long schoolId,
                                        Long printPlanId,
                                        TaskStatusEnum status,
                                        TaskTypeEnum type,

+ 96 - 28
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/BasicAttachmentServiceImpl.java

@@ -1,5 +1,6 @@
 package com.qmth.distributed.print.business.service.impl;
 
+import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.aliyun.oss.common.utils.BinaryUtil;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -9,7 +10,9 @@ import com.qmth.boot.api.exception.ApiException;
 import com.qmth.distributed.print.business.bean.dto.PdfDto;
 import com.qmth.distributed.print.business.config.DictionaryConfig;
 import com.qmth.distributed.print.business.entity.BasicAttachment;
+import com.qmth.distributed.print.business.entity.ExamDetail;
 import com.qmth.distributed.print.business.entity.SysUser;
+import com.qmth.distributed.print.business.enums.ClassifyEnum;
 import com.qmth.distributed.print.business.enums.PageSizeEnum;
 import com.qmth.distributed.print.business.enums.UploadFileEnum;
 import com.qmth.distributed.print.business.mapper.BasicAttachmentMapper;
@@ -103,6 +106,7 @@ public class BasicAttachmentServiceImpl extends ServiceImpl<BasicAttachmentMappe
     @Transactional
     public BasicAttachment saveAttachmentHtml(String fileName, String htmlContent, Long userId, List<PdfDto> localFileList) throws IOException {
         BasicAttachment basicAttachment = null;
+        PdfDto pdfDto = null;
         try {
             byte[] bytes = htmlContent.getBytes();
             int size = bytes.length;
@@ -127,15 +131,28 @@ public class BasicAttachmentServiceImpl extends ServiceImpl<BasicAttachmentMappe
                 jsonObject.put(SystemConstant.PATH, dirName);
                 String url = SystemConstant.TEMP_FILES_DIR + File.separator + dirName;
                 File localHtmlFile = ossUtil.ossDownload(dirName, url);
-                String pdfDirName = dirName.replaceAll(SystemConstant.HTML_PREFIX, SystemConstant.PDF_PREFIX).replaceAll(UploadFileEnum.HTML.name().toLowerCase(), UploadFileEnum.PDF.name().toLowerCase());
+                StringJoiner pdfStringJoiner = new StringJoiner("");
+                pdfStringJoiner.add(UploadFileEnum.PDF.getTitle()).add(File.separator);
+                pdfStringJoiner.add(String.valueOf(nowTime.getYear())).add(File.separator)
+                        .add(String.format("%02d", nowTime.getMonthValue())).add(File.separator)
+                        .add(String.format("%02d", nowTime.getDayOfMonth()));
+                pdfStringJoiner.add(File.separator).add(SystemConstant.getUuid()).add(SystemConstant.PDF_PREFIX);
+
+                String pdfDirName = pdfStringJoiner.toString();
                 String destUrl = SystemConstant.PDF_TEMP_FILES_DIR + File.separator + pdfDirName;
+//                destUrl = destUrl.replaceAll("\\\\","/");
                 HtmlToPdfUtil.convert(localHtmlFile.getPath(), destUrl, PageSizeEnum.A3);
                 File pdfFile = new File(destUrl);
-                int pageCount = PdfUtil.addPdfPage(pdfFile);
-                localFileList.add(new PdfDto(pdfFile.getPath(), PageSizeEnum.A3, pageCount));
+                if (!pdfFile.exists()) {
+                    pdfFile.getParentFile().mkdirs();
+                    pdfFile.createNewFile();
+                }
+
+                pdfDto = PdfUtil.addPdfPage(pdfFile);
+                localFileList.add(new PdfDto(pdfFile.getPath(), PageSizeEnum.A3, pdfDto.getPageCount()));
                 fileMd5 = DigestUtils.md5Hex(new FileInputStream(pdfFile));
                 ossUtil.ossUpload(pdfDirName, pdfFile, BinaryUtil.toBase64String(HexUtils.decodeHex(fileMd5)));
-                localHtmlFile.delete();
+//                localHtmlFile.delete();
                 jsonObject.put(SystemConstant.PDF_PATH, pdfDirName);
             } else {//上传至服务器
                 File finalFile = new File(stringJoiner.toString());
@@ -155,6 +172,7 @@ public class BasicAttachmentServiceImpl extends ServiceImpl<BasicAttachmentMappe
                     UploadFileEnum.HTML, UploadFileEnum.PDF
             });
             basicAttachment = new BasicAttachment(jsonObject.toJSONString(), fileName, SystemConstant.HTML_PREFIX, new BigDecimal(size), fileMd5, userId);
+            basicAttachment.setPages(pdfDto.getActualPageCount());
             save(basicAttachment);
         } catch (Exception e) {
             log.error("请求出错", e);
@@ -168,6 +186,33 @@ public class BasicAttachmentServiceImpl extends ServiceImpl<BasicAttachmentMappe
         return basicAttachment;
     }
 
+    /**
+     * 保存html附件
+     *
+     * @param fileName
+     * @param htmlContent
+     * @return
+     * @throws IOException
+     */
+    @Override
+    public File saveAttachmentHtml(String rootPath, String fileName, String htmlContent) {
+        File file = null;
+        try {
+            byte[] bytes = htmlContent.getBytes();
+            //上传至服务器
+            File mkdir = new File(rootPath);
+            if (!mkdir.exists()) {
+                mkdir.mkdirs();
+            }
+            file = new File(rootPath, fileName);
+            FileCopyUtils.copy(bytes, file);
+            //计算html文件md5
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return file;
+    }
+
     /**
      * 保存附件
      *
@@ -208,6 +253,8 @@ public class BasicAttachmentServiceImpl extends ServiceImpl<BasicAttachmentMappe
     /**
      * 保存附件
      *
+     * @param classifyEnum
+     * @param examDetail
      * @param basicAttachment
      * @param pdfList
      * @param printCount
@@ -217,7 +264,7 @@ public class BasicAttachmentServiceImpl extends ServiceImpl<BasicAttachmentMappe
      */
     @Override
     @Transactional
-    public BasicAttachment saveAttachmentPdf(BasicAttachment basicAttachment, List<PdfDto> pdfList, Integer printCount, Integer sequence) throws IOException, DocumentException {
+    public BasicAttachment saveAttachmentPdf(ClassifyEnum classifyEnum, ExamDetail examDetail, BasicAttachment basicAttachment, List<PdfDto> pdfList, Integer printCount, Integer sequence) throws IOException, DocumentException {
         try {
             boolean oss = dictionaryConfig.sysDomain().isOss();
             JSONObject jsonObject = JSONObject.parseObject(basicAttachment.getPath());
@@ -234,35 +281,56 @@ public class BasicAttachmentServiceImpl extends ServiceImpl<BasicAttachmentMappe
                 url = SystemConstant.TEMP_FILES_DIR + File.separator + filePath;
                 htmlFile = ossUtil.ossDownload(filePath, url);
             }
-            String pdfDirName = filePath.replaceAll(SystemConstant.HTML_PREFIX, SystemConstant.PDF_PREFIX).replaceAll(UploadFileEnum.HTML.name().toLowerCase(), UploadFileEnum.PDF.name().toLowerCase());
+            LocalDateTime nowTime = LocalDateTime.now();
+            StringJoiner pdfStringJoiner = new StringJoiner("");
+            if (!oss) {
+                pdfStringJoiner.add(SystemConstant.TEMP_FILES_DIR).add(File.separator);
+            }
+            pdfStringJoiner.add(UploadFileEnum.PDF.getTitle()).add(File.separator);
+            pdfStringJoiner.add(String.valueOf(nowTime.getYear())).add(File.separator)
+                    .add(String.format("%02d", nowTime.getMonthValue())).add(File.separator)
+                    .add(String.format("%02d", nowTime.getDayOfMonth()));
+            pdfStringJoiner.add(File.separator).add(SystemConstant.getUuid()).add(SystemConstant.PDF_PREFIX);
+
+            String pdfDirName = pdfStringJoiner.toString();
             String destUrl = SystemConstant.PDF_TEMP_FILES_DIR + File.separator + pdfDirName;
-            HtmlToPdfUtil.convert(htmlFile.getPath(), destUrl, PageSizeEnum.A4);
             File pdfFile = new File(destUrl);
-            String fileMd5 = DigestUtils.md5Hex(new FileInputStream(pdfFile));
-            int pageCount = 0;
+            if (!pdfFile.exists()) {
+                pdfFile.getParentFile().mkdirs();
+                pdfFile.createNewFile();
+            }
+
+            HtmlToPdfUtil.convert(htmlFile.getPath(), destUrl, PageSizeEnum.A4);
+            String htmlFileMd5 = DigestUtils.md5Hex(new FileInputStream(htmlFile));
+            String pdfFileMd5 = DigestUtils.md5Hex(new FileInputStream(pdfFile));
+            PdfDto pdfDto = null;
             if (oss) {//上传至oss
-                pageCount = PdfUtil.addPdfPage(pdfFile);
-                ossUtil.ossUpload(pdfDirName, pdfFile, BinaryUtil.toBase64String(HexUtils.decodeHex(fileMd5)));
-                jsonObject.put(SystemConstant.PDF_PATH, pdfDirName);
-                if (Objects.nonNull(type) && Objects.equals(type, SystemConstant.FTL_PREFIX)) {
-                    jsonObject.put(SystemConstant.UPLOAD_TYPE, new UploadFileEnum[]{
-                            UploadFileEnum.FILE,
-                            UploadFileEnum.HTML,
-                            UploadFileEnum.PDF
-                    });
-                } else {
-                    jsonObject.put(SystemConstant.UPLOAD_TYPE, new UploadFileEnum[]{
-                            UploadFileEnum.FILE,
-                            UploadFileEnum.PDF
-                    });
-                    htmlFile.delete();
-                }
+                pdfDto = PdfUtil.addPdfPage(pdfFile);
+                ossUtil.ossUpload(pdfDirName, pdfFile, BinaryUtil.toBase64String(HexUtils.decodeHex(pdfFileMd5)));
+//                htmlFile.delete();
             }
-            basicAttachment.setPath(jsonObject.toJSONString());
+            JSONObject attachmentPath = JSONObject.parseObject(examDetail.getAttachmentPath());
+            attachmentPath = Objects.isNull(attachmentPath) ? new JSONObject() : attachmentPath;
+            JSONArray jsonArray = (JSONArray) attachmentPath.get(SystemConstant.PATH);
+            jsonArray = Objects.isNull(jsonArray) ? new JSONArray() : jsonArray;
+            JSONObject object = new JSONObject();
+            object.put("printType", classifyEnum.name());
+            object.put(SystemConstant.HTML_PATH, filePath);
+            object.put("htmlMd5", htmlFileMd5);
+            object.put("pdfMd5", pdfFileMd5);
+            object.put(SystemConstant.PDF_PATH, pdfDirName);
+            object.put(SystemConstant.TYPE, SystemConstant.OSS);
+            object.put(SystemConstant.UPLOAD_TYPE, new UploadFileEnum[]{
+                    UploadFileEnum.HTML,
+                    UploadFileEnum.PDF
+            });
+            jsonArray.add(object);
+            attachmentPath.put(SystemConstant.PATH, jsonArray);
+            examDetail.setAttachmentPath(attachmentPath.toJSONString());
+            basicAttachment.setPages(pdfDto.getActualPageCount());
             for (int i = 0; i < printCount; i++) {
-                pdfList.add(new PdfDto(pdfFile.getPath(), PageSizeEnum.A4, pageCount, sequence));
+                pdfList.add(new PdfDto(pdfFile.getPath(), PageSizeEnum.A4, pdfDto.getPageCount(), sequence));
             }
-            this.updateById(basicAttachment);
         } catch (Exception e) {
             log.error("请求出错", e);
             if (e instanceof ApiException) {

+ 29 - 6
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/BasicCourseServiceImpl.java

@@ -4,11 +4,13 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.qmth.distributed.print.business.bean.dto.CourseInfoDto;
 import com.qmth.distributed.print.business.entity.BasicCourse;
 import com.qmth.distributed.print.business.entity.ExamTask;
 import com.qmth.distributed.print.business.entity.SysUser;
 import com.qmth.distributed.print.business.mapper.BasicCourseMapper;
 import com.qmth.distributed.print.business.service.BasicCourseService;
+import com.qmth.distributed.print.business.service.ExamDetailCourseService;
 import com.qmth.distributed.print.business.service.ExamTaskService;
 import com.qmth.distributed.print.business.util.ServletUtil;
 import com.qmth.distributed.print.common.contant.SystemConstant;
@@ -18,6 +20,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import javax.annotation.Resource;
 import java.util.List;
 import java.util.Objects;
 
@@ -34,6 +37,10 @@ public class BasicCourseServiceImpl extends ServiceImpl<BasicCourseMapper, Basic
 
     @Autowired
     private ExamTaskService examTaskService;
+    @Resource
+    private BasicCourseMapper basicCourseMapper;
+    @Autowired
+    private ExamDetailCourseService examDetailCourseService;
 
     @Override
     public IPage<BasicCourse> list(String code, String name, Integer pageNumber, Integer pageSize) {
@@ -44,14 +51,18 @@ public class BasicCourseServiceImpl extends ServiceImpl<BasicCourseMapper, Basic
     }
 
     @Override
-    public List<BasicCourse> list(String param) {
+    public List<BasicCourse> list(String param, Long printPlanId) {
         Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
-        QueryWrapper<BasicCourse> queryWrapper = new QueryWrapper<>();
-        if (StringUtils.isNotBlank(param)) {
-            queryWrapper.lambda().eq(BasicCourse::getSchoolId, schoolId)
-                    .and(i -> i.like(BasicCourse::getCode, param).or().like(BasicCourse::getName, param));
+        if(printPlanId == null) {
+            QueryWrapper<BasicCourse> queryWrapper = new QueryWrapper<>();
+            queryWrapper.lambda().eq(BasicCourse::getSchoolId, schoolId);
+            if (StringUtils.isNotBlank(param)) {
+                queryWrapper.lambda().and(i -> i.like(BasicCourse::getCode, param).or().like(BasicCourse::getName, param));
+            }
+            return this.list(queryWrapper);
+        } else {
+            return examDetailCourseService.listCoursesByPrintPlanId(param, printPlanId);
         }
-        return this.list(queryWrapper);
     }
 
     @Override
@@ -129,4 +140,16 @@ public class BasicCourseServiceImpl extends ServiceImpl<BasicCourseMapper, Basic
             this.saveOrUpdate(basicCourse);
         }
     }
+
+    @Override
+    public List<CourseInfoDto> findByUserLoginNameAndRealName(String loginName, String realName) {
+        System.out.println("---");
+        if (loginName == null){
+            loginName = "";
+        }
+        if (realName == null){
+            realName = "";
+        }
+        return basicCourseMapper.findByUserLoginNameAndRealName(loginName, realName);
+    }
 }

+ 5 - 4
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/BasicExamRuleServiceImpl.java

@@ -67,7 +67,7 @@ public class BasicExamRuleServiceImpl extends ServiceImpl<BasicExamRuleMapper, B
         else {
             // 查询未结束的印刷计划
             QueryWrapper<ExamPrintPlan> queryWrapper = new QueryWrapper<>();
-            queryWrapper.lambda().ne(ExamPrintPlan::getStatus, PrintPlanStatusEnum.END);
+            queryWrapper.lambda().eq(ExamPrintPlan::getSchoolId, schoolId).ne(ExamPrintPlan::getStatus, PrintPlanStatusEnum.END);
             List<ExamPrintPlan> examPrintPlanList = examPrintPlanService.list(queryWrapper);
             if (examPrintPlanList != null && examPrintPlanList.size() > 0) {
                 BasicExamRule basicExamRule = this.getById(examRule.getId());
@@ -91,10 +91,11 @@ public class BasicExamRuleServiceImpl extends ServiceImpl<BasicExamRuleMapper, B
                         String enable1 = String.valueOf(map1.get("enable"));
                         if (code.equals(code1) && name.equals(name1) && enable.equals(enable1)) {
                             flag = false;
+                            break;
                         }
-                        if (flag) {
-                            throw ExceptionResultEnum.ERROR.exception("有未结束的印刷计划,不能修改扩展字段");
-                        }
+                    }
+                    if (flag) {
+                        throw ExceptionResultEnum.ERROR.exception("有未结束的印刷计划,不能修改扩展字段");
                     }
                 }
             }

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

@@ -119,7 +119,7 @@ public class BasicTemplateServiceImpl extends ServiceImpl<BasicTemplateMapper, B
                 ExamCard examCard = examCardService.getOneByTemplateId(template.getId());
                 ExamCardParams examCardParams = new ExamCardParams();
                 examCardParams.setId(examCard == null ? null : examCard.getId());
-                examCardParams.setTitle(attachment.getName());
+                examCardParams.setTitle(template.getName());
                 examCardParams.setMakeMethod(MakeMethodEnum.SELECT);// 默认SELECT
                 examCardParams.setType(CardTypeEnum.GENERIC); // 默认GENERIC
                 examCardParams.setTemplateId(template.getId());
@@ -127,7 +127,7 @@ public class BasicTemplateServiceImpl extends ServiceImpl<BasicTemplateMapper, B
                 examCardParams.setHtmlContent(commonService.readFileContent(attachment.getPath()));
                 examCardService.saveExamCard(examCardParams);
             } else {
-                examCard1.setTitle(attachment.getName());
+                examCard1.setTitle(template.getName());
                 examCardService.updateById(examCard1);
 
                 ExamCardDetail examCardDetail = examCardDetailService.getByCardId(examCard1.getId());

+ 360 - 160
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ClientServiceImpl.java

@@ -2,18 +2,23 @@ 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;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.google.gson.JsonObject;
 import com.qmth.distributed.print.business.bean.dto.*;
 import com.qmth.distributed.print.business.entity.*;
+import com.qmth.distributed.print.business.enums.ExamDetailStatusEnum;
 import com.qmth.distributed.print.business.service.*;
+import com.qmth.distributed.print.business.util.ExcelUtil;
+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.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
+import javax.servlet.http.HttpServletResponse;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -47,80 +52,56 @@ public class ClientServiceImpl implements ClientService {
     @Autowired
     private ExamPrintPlanService examPrintPlanService;
 
+    @Autowired
+    private ExamCardDetailService examCardDetailService;
+
+    @Autowired
+    private ExamStudentService examStudentService;
+
     @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) {
+    public IPage<ClientExamTaskDto> listTryTask(String machineCode, Long orgId, Long printPlanId, String courseCode, String paperNumber, Boolean isTry, Boolean isPass, Integer pageNumber, Integer pageSize) {
+        Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
         return examTaskService.listTryTask(schoolId, machineCode, orgId, printPlanId, courseCode, paperNumber, isTry, isPass, pageNumber, pageSize);
     }
 
     @Override
-    public String getUrl(Long schoolId, Long examTaskId) {
+    public Map<String, String> getUrl(Long examTaskId) {
+        Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
         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);
+    public Boolean tagPass(String courseCode, String courseName, String paperNumber, String machineCode, Boolean isPass, Long userId) {
+        Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
+        return clientStatusService.tagPass(schoolId, courseCode, courseName, paperNumber, machineCode, isPass, userId);
     }
 
     @Override
-    public Boolean updatePrintProgress(Long schoolId, Long examDetailId, Integer printProgress) {
+    public Boolean updatePrintProgress(Long examDetailId, Integer printProgress) {
+        Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
         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) {
+    public IPage<ClientExamStudentDto> listStudent(Long examDetailId, String ticketNumber, String studentName, String courseCode, Integer pageNumber, Integer pageSize) {
+        Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
         return examDetailService.listStudent(schoolId, examDetailId, ticketNumber, studentName, courseCode, pageNumber, pageSize);
     }
 
 
     @Override
-    public Map<String, Object> getReprintData(Long schoolId, Long examDetailId, String ticketNumber, String type) {
+    public Map<String, Object> getReprintData(Long examDetailId, String ticketNumber, String type) {
+        Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
         Map<String, Object> finalMap = new HashMap<>();
         // 取试卷
-        List<Map<String, String>> examDetailCourses = examDetailCourseService.listByExamDetailId(examDetailId);
-        Map<String, String> map = mapCourseUrl(examDetailCourses);
+        List<Map<String, Object>> examDetailCourses = examDetailCourseService.listByExamDetailId(examDetailId);
+        Map<String, Map<String, String>> map = mapCourseUrl(examDetailCourses);
         // 取考生
-        List<Map<String, String>> studentList = examDetailService.listStudentByExamDetailId(schoolId, examDetailId, ticketNumber, type);
+        List<Map> 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(SystemConstant.DELIMITER);
-            String key = sj.add(courseCode).add(paperNumber).add(paperType).toString();
-            printDataDto.setUrl(map.get(key));
-            return printDataDto;
-        }).collect(Collectors.toList());
-        finalMap.put("paper", paperList);
+        finalMap.put("paper", splicePaperContent(studentList, map));
         // 生成题卡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);
-            Map<String, String> urlMap = commonService.filePreview(attachmentId, false);
-            printDataDto.setUrl(urlMap.get("pathUrl"));
-            return printDataDto;
-        }).collect(Collectors.toList());
-        finalMap.put("card", cardList);
+        finalMap.put("card", spliceCardContent(studentList));
         //
         ExamDetail examDetail = examDetailService.getById(examDetailId);
         ExamPrintPlan examPrintPlan = examPrintPlanService.getById(examDetail.getPrintPlanId());
@@ -128,53 +109,61 @@ public class ClientServiceImpl implements ClientService {
         String ordinaryContent = examPrintPlan.getOrdinaryContent();
         List<Map> variableList = JSONObject.parseArray(variableContent, Map.class);
         List<Map> otherList = new ArrayList<>();
-        for (Map variable : variableList) {
-            Map vMap = new HashMap();
-            vMap.put("type", variable.get("type"));
-            Map<String, String> urlMap = commonService.filePreview(variable.get("attachmentId").toString(), false);
-            vMap.put("htmlUrl", urlMap.get("htmlUrl"));
-            vMap.put("pdfUrl", urlMap.get("pdfUrl"));
-            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"));
-            Map<String, String> urlMap = commonService.filePreview(ordinary.get("attachmentId").toString(), false);
-            vMap.put("htmlUrl", urlMap.get("htmlUrl"));
-            vMap.put("pdfUrl", urlMap.get("pdfUrl"));
-            otherList.add(vMap);
+        //印品附件信息
+        String attachmentPath = examDetail.getAttachmentPath();
+        if (StringUtils.isNotBlank(attachmentPath)) {
+            JSONObject jsonObject = JSONObject.parseObject(attachmentPath);
+            String pathString = jsonObject.getString("path");
+            List<Map> pathList = JSONObject.parseArray(pathString, Map.class);
+            if (!pathList.isEmpty()) {
+                for (Map contentMap : variableList) {
+                    spliceOtherContent(otherList, pathList, contentMap);
+                }
+                List<Map> ordinaryList = JSONObject.parseArray(ordinaryContent, Map.class);
+                for (Map contentMap : ordinaryList) {
+                    spliceOtherContent(otherList, pathList, contentMap);
+                }
+            }
         }
         finalMap.put("other", otherList);
         return finalMap;
     }
 
     @Override
-    public IPage<ClientPrintTaskDto> listClientPrintTask(Long schoolId, Long machineCode, String orgId, String printPlanId, String status, String courseCode, String paperNumber, String examPlace, String examRoom, Long examStartTime, Long examEndTime, Boolean isDownload, Boolean validate, Integer pageNumber, Integer pageSize) {
+    public IPage<ClientPrintTaskDto> listClientPrintTask(Long machineCode, String orgId, String printPlanId, String status, String courseCode, String paperNumber, String examPlace, String examRoom, Long examStartTime, Long examEndTime, Boolean isDownload, Boolean validate, Integer pageNumber, Integer pageSize) {
+        Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
         Set<Long> orgIds = commonService.listSubOrgIds(null);
         Page<ClientPrintTaskDto> page = new Page<>(pageNumber, pageSize);
-        IPage<ClientPrintTaskDto> pirntTaskDtoIPage = examPrintPlanService.listClientPrintTask(page, schoolId,machineCode, printPlanId, status, courseCode, paperNumber, examPlace, examRoom, examStartTime, examEndTime,isDownload,validate, orgIds);
+        IPage<ClientPrintTaskDto> pirntTaskDtoIPage = examPrintPlanService.listClientPrintTask(page, schoolId, machineCode, printPlanId, status, courseCode, paperNumber, examPlace, examRoom, examStartTime, examEndTime, isDownload, validate, orgIds);
         return pirntTaskDtoIPage;
     }
 
+    @Transactional
     @Override
-    public Map<String, Object> getPrintData(Long schoolId, Long examDetailId, String machineCode, String printUser) {
-        List<Map<String, String>> examDetailCourses = examDetailCourseService.listByExamDetailId(examDetailId);
+    public Map<String, Object> getPrintData(Long examDetailId, String machineCode, Boolean isPrint, String printUser) {
+        if(isPrint && StringUtils.isBlank(printUser)){
+            throw ExceptionResultEnum.ERROR.exception("打印员不能为空");
+        }
+        ExamDetail examDetail = examDetailService.getById(examDetailId);
+        if(StringUtils.isNotBlank(examDetail.getPrintUser()) && !examDetail.getPrintUser().equals(printUser)){
+            throw ExceptionResultEnum.ERROR.exception("该任务已被["+printUser+"]占用");
+        }
+
+        Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
+        List<Map<String, Object>> examDetailCourses = examDetailCourseService.listByExamDetailId(examDetailId);
         Map<String, Object> finalMap = new HashMap<>();
         // 2.取生成的完整的pdf
-        ExamDetail examDetail = examDetailService.getById(examDetailId);
-        if(examDetail.getAttachmentId() == null) {
+        if (examDetail.getAttachmentId() == null) {
             throw ExceptionResultEnum.ERROR.exception("考场pdf未生成");
         }
 
         BasicAttachment attachment = basicAttachmentService.getById(examDetail.getAttachmentId());
-        if(attachment == null){
+        if (attachment == null) {
             throw ExceptionResultEnum.ERROR.exception("考场pdf文件记录异常");
         }
 
-        Map<String, String> attachMap = commonService.filePreview(examDetail.getAttachmentId().toString(), false);
-        String totalPathUrl = attachMap.get("pathUrl");
-        if(StringUtils.isNotBlank(totalPathUrl)) {
+        Map<String, String> totalPathUrl = commonService.filePreviewByAttachmentId(examDetail.getAttachmentId(), false);
+        if (StringUtils.isBlank(totalPathUrl.get("url"))) {
             throw ExceptionResultEnum.ERROR.exception("考场pdf文件丢失");
         }
 
@@ -183,61 +172,27 @@ public class ClientServiceImpl implements ClientService {
         // 3.取学生试卷、题卡、备用试卷、题卡,印品
         Map<String, Object> detailMap = new HashMap<>();
         // 3.1取试卷
-        Map<String, String> map = mapCourseUrl(examDetailCourses);
+        Map<String, Map<String, String>> map = mapCourseUrl(examDetailCourses);
         // 3.2取考生
-        List<Map<String, String>> studentList = examDetailService.listStudentByExamDetailId(schoolId, examDetailId, "1", "1");
+        List<Map> studentList = examDetailService.listStudentByExamDetailId(schoolId, examDetailId, "1", "1");
         // 3.3生成试卷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(SystemConstant.DELIMITER);
-            String key = sj.add(courseCode).add(paperNumber).add(paperType).toString();
-            printDataDto.setUrl(map.get(key));
-            return printDataDto;
-        }).collect(Collectors.toList());
-        detailMap.put("paper", paperList);
+        detailMap.put("paper", splicePaperContent(studentList, map));
         // 3.4生成题卡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);
-            Map<String, String> urlMap = commonService.filePreview(attachmentId, false);
-            printDataDto.setUrl(urlMap.get("pathUrl"));
-            return printDataDto;
-        }).collect(Collectors.toList());
-        detailMap.put("card", cardList);
+
+        detailMap.put("card", spliceCardContent(studentList));
 
         //3.4备用试卷、题卡
         ExamPrintPlan examPrintPlan = examPrintPlanService.getById(examDetail.getPrintPlanId());
         Map<String, Object> backupMap = new HashMap<>();
         int backupCount = examPrintPlan.getBackupCount().intValue();
         //试卷
-        List<Map<String, String>> keyMaps = studentList.stream().map(m->{
+        List<Map<String, String>> keyMaps = studentList.stream().map(m -> {
             Map<String, String> stringMap = new HashMap<>();
-            stringMap.put("courseCode", m.get("courseCode"));
-            stringMap.put("courseName", m.get("courseName"));
-            stringMap.put("paperNumber", m.get("paperNumber"));
-            stringMap.put("paperType", m.get("paperType"));
+            stringMap.put("courseCode", m.get("courseCode").toString());
+            stringMap.put("courseName", m.get("courseName").toString());
+            stringMap.put("paperNumber", m.get("paperNumber").toString());
+            stringMap.put("paperType", m.get("paperType").toString());
             return stringMap;
         }).distinct().collect(Collectors.toList());
         List<ClientPrintBackupDataDto> paperBackupList = new ArrayList<>();
@@ -250,7 +205,8 @@ public class ClientServiceImpl implements ClientService {
                 clientPrintBackupDataDto.setPaperType(keyMap.get("paperType"));
                 StringJoiner sj = new StringJoiner(SystemConstant.DELIMITER);
                 String key = sj.add(keyMap.get("courseCode")).add(keyMap.get("paperNumber")).add(keyMap.get("paperType")).toString();
-                clientPrintBackupDataDto.setUrl(map.get(key));
+                clientPrintBackupDataDto.setMd5(map.get(key).get("md5"));
+                clientPrintBackupDataDto.setUrl(map.get(key).get("url"));
                 paperBackupList.add(clientPrintBackupDataDto);
             }
         }
@@ -259,90 +215,334 @@ public class ClientServiceImpl implements ClientService {
 
         // 备用题卡
         List<ClientPrintBackupDataDto> cardBackupList = new ArrayList<>();
-        for (Map<String, String> examDetailCours : examDetailCourses) {
-            String attachmentIds = examDetailCours.get("attachmentIds");
+        for (Map<String, Object> examDetailCours : examDetailCourses) {
+            String attachmentIds = examDetailCours.get("attachmentIds").toString();
             JSONObject jsonObject = JSONObject.parseObject(attachmentIds);
             List<Map> backupCards = JSONObject.parseArray(JSONObject.toJSONString(jsonObject.get("card")), Map.class);
             for (Map backupCard : backupCards) {
                 ClientPrintBackupDataDto clientPrintBackupDataDto = new ClientPrintBackupDataDto();
-                clientPrintBackupDataDto.setCourseCode(backupCard.get("courseCode").toString());
-                clientPrintBackupDataDto.setCourseName(backupCard.get("courseName").toString());
-                clientPrintBackupDataDto.setPaperNumber(backupCard.get("paperNumber").toString());
+                clientPrintBackupDataDto.setCourseCode(examDetailCours.get("courseCode").toString());
+                clientPrintBackupDataDto.setCourseName(examDetailCours.get("courseName").toString());
+                clientPrintBackupDataDto.setPaperNumber(examDetailCours.get("paperNumber").toString());
                 clientPrintBackupDataDto.setPaperType(backupCard.get("name").toString());
-                Map<String, String> urlMap = commonService.filePreview(backupCard.get("attachmentId").toString(), false);
-                clientPrintBackupDataDto.setUrl(urlMap.get("pathUrl"));
+                Map<String, String> urlMap = commonService.filePreviewByAttachmentId(Long.valueOf(backupCard.get("attachmentId").toString()), false);
+                clientPrintBackupDataDto.setMd5(urlMap.get("md5"));
+                clientPrintBackupDataDto.setUrl(urlMap.get("url"));
                 cardBackupList.add(clientPrintBackupDataDto);
             }
         }
         backupMap.put("card", cardBackupList);
+        detailMap.put("backup", backupMap);
+        finalMap.put("detail", detailMap);
 
         //3.5
         String variableContent = examPrintPlan.getVariableContent();
         String ordinaryContent = examPrintPlan.getOrdinaryContent();
         List<Map> variableList = JSONObject.parseArray(variableContent, Map.class);
         List<Map> otherList = new ArrayList<>();
-        for (Map variable : variableList) {
-            int count = Integer.parseInt(variable.get("backupCount").toString());
-            for (int i = 0; i < count; i++) {
-                Map vMap = new HashMap();
-                vMap.put("type", variable.get("type"));
-                Map<String, String> urlMap = commonService.filePreview(variable.get("attachmentId").toString(), false);
-                vMap.put("htmlUrl", urlMap.get("htmlUrl"));
-                vMap.put("pdfUrl", urlMap.get("pdfUrl"));
-                otherList.add(vMap);
+        //印品附件信息
+        String attachmentPath = examDetail.getAttachmentPath();
+        if (StringUtils.isNotBlank(attachmentPath)) {
+            JSONObject jsonObject = JSONObject.parseObject(attachmentPath);
+            String pathString = jsonObject.getString("path");
+            List<Map> pathList = JSONObject.parseArray(pathString, Map.class);
+            if (!pathList.isEmpty()) {
+                for (Map contentMap : variableList) {
+                    int count = Integer.parseInt(contentMap.get("backupCount").toString());
+                    for (int i = 0; i < count; i++) {
+                        spliceOtherContent(otherList, pathList, contentMap);
+                    }
+                }
+                List<Map> ordinaryList = JSONObject.parseArray(ordinaryContent, Map.class);
+                for (Map contentMap : ordinaryList) {
+                    int count = Integer.parseInt(contentMap.get("backupCount").toString());
+                    for (int i = 0; i < count; i++) {
+                        spliceOtherContent(otherList, pathList, contentMap);
+                    }
+
+                }
             }
         }
-        List<Map> ordinaryList = JSONObject.parseArray(ordinaryContent, Map.class);
-        for (Map ordinary : ordinaryList) {
-            int count = Integer.parseInt(ordinary.get("backupCount").toString());
-            for (int i = 0; i < count; i++) {
-                Map vMap = new HashMap();
-                vMap.put("type", ordinary.get("type"));
-                Map<String, String> urlMap = commonService.filePreview(ordinary.get("attachmentId").toString(), false);
-                vMap.put("htmlUrl", urlMap.get("htmlUrl"));
-                vMap.put("pdfUrl", urlMap.get("pdfUrl"));
-                otherList.add(vMap);
-            }
+        finalMap.put("other", otherList);
 
+        // 更新印刷中状态,更新曝光卷型、未曝光卷型,打印开始时间
+        if (isPrint) {
+            // 更新exam_detail状态为印刷中
+            UpdateWrapper<ExamDetail> examDetailUpdateWrapper = new UpdateWrapper<>();
+            examDetailUpdateWrapper.lambda().set(ExamDetail::getStatus, ExamDetailStatusEnum.PRINTING).set(ExamDetail::getPrintStartTime, System.currentTimeMillis()).set(ExamDetail::getPrintUser, printUser).eq(ExamDetail::getId, examDetailId);
+            examDetailService.update(examDetailUpdateWrapper);
+
+            // 更新曝光卷型、未曝光卷型
+            for (Map<String, Object> examDetailCours : examDetailCourses) {
+                String examDetailCourseId = examDetailCours.get("examDetailCourseId").toString();
+                // 考生使用卷型
+                List<String> studentPaperTypes = examStudentService.listByExamDetailCourseId(examDetailCourseId);
+                Object exposedPaperType = examDetailCours.get("exposedPaperType");
+                Set<String> exposedPaperSet = Objects.isNull(exposedPaperType) ? new HashSet<>() : new HashSet<>(Arrays.asList(exposedPaperType.toString().split(",")));
+                Object unexposedPaperType = examDetailCours.get("unexposedPaperType").toString();
+                Set<String> unexposedPaperSet = Objects.isNull(unexposedPaperType) ? new HashSet<>() : new HashSet<>(Arrays.asList(unexposedPaperType.toString().split(",")));
+                if (!studentPaperTypes.isEmpty()) {
+                    for (String studentPaperType : studentPaperTypes) {
+                        exposedPaperSet.add(studentPaperType);
+                        unexposedPaperSet.remove(studentPaperType);
+                    }
+                }
+                String examTaskId = examDetailCours.get("examTaskId").toString();
+                UpdateWrapper<ExamTaskDetail> examTaskDetailUpdateWrapper = new UpdateWrapper<>();
+                examTaskDetailUpdateWrapper.lambda()
+                        .set(ExamTaskDetail::getExposedPaperType, String.join(",", exposedPaperSet))
+                        .set(ExamTaskDetail::getUnexposedPaperType, String.join(",", unexposedPaperSet))
+                        .eq(ExamTaskDetail::getExamTaskId, examTaskId);
+                examTaskDetailService.update(examTaskDetailUpdateWrapper);
+            }
         }
-        finalMap.put("other", otherList);
         return finalMap;
     }
 
     @Override
-    public List<Map<String, Object>> getPrintDataBatch(Long schoolId, Long machineCode, String orgId, String printPlanId, String status, String courseCode, String paperNumber, String examPlace, String examRoom, Long examStartTime, Long examEndTime, Boolean isDownload, Boolean validate) {
+    public List<Map<String, Object>> getPrintDataBatch(Long machineCode, String orgId, String printPlanId, String status, String courseCode, String paperNumber, String examPlace, String examRoom, Long examStartTime, Long examEndTime, Boolean isDownload, Boolean validate) {
+        Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
         Set<Long> orgIds = commonService.listSubOrgIds(null);
-        List<ClientPrintTaskDto> pirntTaskDtoList = examPrintPlanService.listClientPrintTask(schoolId,machineCode, printPlanId, status, courseCode, paperNumber, examPlace, examRoom, examStartTime, examEndTime,isDownload,validate, orgIds);
+        List<ClientPrintTaskDto> pirntTaskDtoList = examPrintPlanService.listClientPrintTask(schoolId, machineCode, printPlanId, status, courseCode, paperNumber, examPlace, examRoom, examStartTime, examEndTime, isDownload, validate, orgIds);
         List<Map<String, Object>> finalList = new ArrayList<>();
         for (ClientPrintTaskDto clientPrintTaskDto : pirntTaskDtoList) {
-            Map<String, Object> map = getPrintData(schoolId, Long.valueOf(clientPrintTaskDto.getExamDetailId()), null, null);
+            Map<String, Object> map = getPrintData(Long.valueOf(clientPrintTaskDto.getExamDetailId()), null, false, null);
+            map.put("examDetailId", clientPrintTaskDto.getExamDetailId());
             finalList.add(map);
         }
         return finalList;
     }
 
+    @Override
+    public Map<String, String> getUrlByExamDetailId(Long examDetailId) {
+        Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
+        ExamDetail examDetail = examDetailService.getById(examDetailId);
+        BasicAttachment attachment = basicAttachmentService.getById(examDetail.getAttachmentId());
+        return attachment == null ? null : commonService.filePreviewByAttachmentId(attachment.getId(), false);
+    }
+
+    @Override
+    public Boolean updateDownload(Long examDetailId, String machineCode, Boolean isDownload) {
+        Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
+        QueryWrapper<ExamDetailCourse> examDetailCourseQueryWrapper = new QueryWrapper<>();
+        examDetailCourseQueryWrapper.lambda().eq(ExamDetailCourse::getSchoolId, schoolId).eq(ExamDetailCourse::getExamDetailId, examDetailId);
+        List<ExamDetailCourse> examDetailCourses = examDetailCourseService.list(examDetailCourseQueryWrapper);
+        for (ExamDetailCourse examDetailCours : examDetailCourses) {
+            QueryWrapper<ClientStatus> clientStatusQueryWrapper = new QueryWrapper<>();
+            clientStatusQueryWrapper.lambda().eq(ClientStatus::getSchoolId, schoolId).eq(ClientStatus::getCourseCode, examDetailCours.getCourseCode()).eq(ClientStatus::getPaperNumber, examDetailCours.getPaperNumber()).eq(ClientStatus::getMachineCode, machineCode);
+            ClientStatus clientStatus = clientStatusService.getOne(clientStatusQueryWrapper);
+            if (clientStatus == null) {
+                clientStatus = new ClientStatus();
+                clientStatus.setId(SystemConstant.getDbUuid());
+                clientStatus.setSchoolId(schoolId);
+                clientStatus.setMachineCode(machineCode);
+                clientStatus.setCourseCode(examDetailCours.getCourseCode());
+                clientStatus.setCourseName(examDetailCours.getCourseName());
+                clientStatus.setPaperNumber(examDetailCours.getPaperNumber());
+                clientStatus.setTry(false);
+                clientStatus.setPass(false);
+                clientStatus.setDownload(isDownload);
+                clientStatusService.save(clientStatus);
+            } else {
+                clientStatus.setDownload(isDownload);
+                clientStatusService.updateById(clientStatus);
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public Boolean validateData(Long examDetailId, String packageCode, String lastCode) {
+        Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
+        ExamDetail examDetail = examDetailService.getById(examDetailId);
+        if (examDetail == null) {
+            throw ExceptionResultEnum.ERROR.exception("考场数据有误");
+        }
+        if (StringUtils.isBlank(packageCode)) {
+            throw ExceptionResultEnum.ERROR.exception("卷袋编号不能为空");
+        }
+        if (!packageCode.equals(examDetail.getPackageCode())) {
+            throw ExceptionResultEnum.ERROR.exception("卷袋编号与系统数据不一致");
+        }
+        // 取最后一张备卡
+        QueryWrapper<ExamDetailCourse> courseQueryWrapper = new QueryWrapper<>();
+        courseQueryWrapper.lambda().eq(ExamDetailCourse::getExamDetailId, examDetailId).orderByDesc(ExamDetailCourse::getPaperNumber);
+        List<ExamDetailCourse> examDetailCourses = examDetailCourseService.list(courseQueryWrapper);
+        if (examDetailCourses.isEmpty()) {
+            throw ExceptionResultEnum.ERROR.exception("考场下课程数据异常");
+        }
+        ExamDetailCourse examDetailCourse = examDetailCourses.get(0);
+
+        QueryWrapper<ExamTask> taskQueryWrapper = new QueryWrapper<>();
+        taskQueryWrapper.lambda().eq(ExamTask::getSchoolId, schoolId).eq(ExamTask::getCourseCode, examDetailCourse.getCourseCode()).eq(ExamTask::getPaperNumber, examDetailCourse.getPaperNumber());
+        ExamTask examTask = examTaskService.getOne(taskQueryWrapper);
+        if (examTask == null) {
+            throw ExceptionResultEnum.ERROR.exception("命题任务数据异常");
+        }
+
+        QueryWrapper<ExamTaskDetail> taskDetailQueryWrapper = new QueryWrapper<>();
+        taskDetailQueryWrapper.lambda().eq(ExamTaskDetail::getExamTaskId, examTask.getId());
+        ExamTaskDetail examTaskDetail = examTaskDetailService.getOne(taskDetailQueryWrapper);
+        if (examTaskDetail == null) {
+            throw ExceptionResultEnum.ERROR.exception("命题任务数据异常");
+        }
+        ExamCardDetail examCardDetail = examCardDetailService.getByCardId(examTaskDetail.getCardId());
+        if (examCardDetail == null) {
+            throw ExceptionResultEnum.ERROR.exception("题卡数据异常");
+        }
+        String attachmentIds = examCardDetail.getAttachmentId();
+        if (StringUtils.isBlank(attachmentIds)) {
+            throw ExceptionResultEnum.ERROR.exception("备卡数据异常");
+        }
+        JSONObject jsonObject = JSONObject.parseObject(attachmentIds);
+        String backupAttachmentIds = JSONObject.toJSONString(jsonObject.get("card"));
+        List<Map> list = JSONObject.parseArray(backupAttachmentIds, Map.class);
+        Map map = list.get(list.size() - 1);
+        String backupPackageCode = map.get("packageCode").toString();
+        if (StringUtils.isBlank(lastCode)) {
+            throw ExceptionResultEnum.ERROR.exception("最后一张备卡数据异常");
+        }
+        if (!lastCode.equals(backupPackageCode)) {
+            throw ExceptionResultEnum.ERROR.exception("最后一张备卡条码与系统数据不一致");
+        }
+
+        String lastCodeSub = lastCode.substring(0, lastCode.length() - 2);
+        if (!packageCode.equals(lastCodeSub)) {
+            throw ExceptionResultEnum.ERROR.exception("最后一张备卡条码与试卷编号不一致");
+        }
+
+        UpdateWrapper<ExamDetail> updateWrapper = new UpdateWrapper<>();
+        updateWrapper.lambda().set(ExamDetail::getValidate, true).eq(ExamDetail::getId, examDetailId);
+
+        return examDetailService.update(updateWrapper);
+    }
+
+    @Override
+    public List<Map<String, String>> getBatchUrl(String machineCode, Long orgId, Long printPlanId, String courseCode, String paperNumber, Boolean isTry, Boolean isPass) {
+        Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
+        List<ClientExamTaskDto> clientExamTaskDtos = examTaskService.listTryTask(schoolId, machineCode, orgId, printPlanId, courseCode, paperNumber, isTry, isPass);
+        List<Map<String, String>> list = new ArrayList<>();
+        for (ClientExamTaskDto clientExamTaskDto : clientExamTaskDtos) {
+            Map<String, String> map = new HashMap<>();
+            map.put("courseCode", clientExamTaskDto.getCourseCode());
+            map.put("courseName", clientExamTaskDto.getCourseName());
+            map.put("paperNumber", clientExamTaskDto.getPaperNumber());
+            Map<String, String> stringMap = examTaskDetailService.getUrl(schoolId, Long.valueOf(clientExamTaskDto.getExamTaskId()));
+            map.putAll(stringMap);
+            list.add(map);
+        }
+        return list;
+    }
+
+    @Override
+    public void exportClientPrintTask(HttpServletResponse response, Long machineCode, String orgId, String printPlanId, String status, String courseCode, String paperNumber, String examPlace, String examRoom, Long examStartTime, Long examEndTime, Boolean isDownload, Boolean validate) throws Exception {
+        Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
+        Set<Long> orgIds = commonService.listSubOrgIds(null);
+        List<ClientPrintTaskDto> printTaskDtoIList = examPrintPlanService.listClientPrintTask(schoolId, machineCode, printPlanId, status, courseCode, paperNumber, examPlace, examRoom, examStartTime, examEndTime, isDownload, validate, orgIds);
+        ExcelUtil.excelExport("印刷管理", ClientPrintTaskDto.class, printTaskDtoIList, response);
+    }
+
     /**
      * 根据考场生成试卷map
      *
      * @return
      */
-    public Map<String, String> mapCourseUrl(List<Map<String, String>> mapList) {
-        Map<String, String> map = new HashMap<>();
-        for (Map<String, String> taskDetail : mapList) {
-            String courseCode = taskDetail.get("courseCode");
-            String paperNumber = taskDetail.get("paperNumber");
-            String paperAttachmentIds = taskDetail.get("paperAttachmentIds");
+    public Map<String, Map<String, String>> mapCourseUrl(List<Map<String, Object>> mapList) {
+        Map<String, Map<String, String>> map = new HashMap<>();
+        for (Map<String, Object> taskDetail : mapList) {
+            String courseCode = taskDetail.get("courseCode").toString();
+            String paperNumber = taskDetail.get("paperNumber").toString();
+            String paperAttachmentIds = taskDetail.get("paperAttachmentIds").toString();
             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());
+                Map<String, String> stringMap = commonService.filePreviewByAttachmentId(Long.valueOf(attachmentId), false);
                 StringJoiner sj = new StringJoiner(SystemConstant.DELIMITER);
                 String key = sj.add(courseCode).add(paperNumber).add(name).toString();
-                map.put(key, url);
+                map.put(key, stringMap);
             }
         }
         return map;
     }
+
+
+    /**
+     * 生成印品url公共方法
+     *
+     * @param otherList
+     * @param pathList
+     * @param contentMap
+     */
+    private void spliceOtherContent(List<Map> otherList, List<Map> pathList, Map contentMap) {
+        Map vMap = new HashMap();
+        vMap.put("type", contentMap.get("type"));
+        for (Map path : pathList) {
+            String printType = path.get("printType").toString();
+            if (printType.equals(contentMap.get("type").toString())) {
+                vMap.put("htmlUrl", commonService.filePreviewByPathAndType(path.get("htmlPath").toString(), path.get("type").toString(), false));
+                vMap.put("htmlMd5", path.get("htmlMd5"));
+                vMap.put("pdfUrl", commonService.filePreviewByPathAndType(path.get("pdfPath").toString(), path.get("type").toString(), false));
+                vMap.put("pdfMd5", path.get("pdfMd5"));
+            }
+        }
+        otherList.add(vMap);
+    }
+
+    /**
+     * 生成试卷url公共方法
+     *
+     * @param studentList
+     * @param map
+     * @return
+     */
+    private List<ClientPrintDataDto> splicePaperContent(List<Map> studentList, Map<String, Map<String, String>> map) {
+        List<ClientPrintDataDto> paperList = studentList.stream().map(m -> {
+            ClientPrintDataDto printDataDto = newClientPrintDataDto(m);
+            StringJoiner sj = new StringJoiner(SystemConstant.DELIMITER);
+            String key = sj.add(printDataDto.getCourseCode()).add(m.get("paperNumber").toString()).add(printDataDto.getPaperType()).toString();
+            printDataDto.setMd5(map.get(key).get("md5"));
+            printDataDto.setUrl(map.get(key).get("url"));
+            return printDataDto;
+        }).collect(Collectors.toList());
+        return paperList;
+    }
+
+    /**
+     * 生成题卡url公共方法
+     *
+     * @param studentList
+     * @return
+     */
+    private List<ClientPrintDataDto> spliceCardContent(List<Map> studentList) {
+        List<ClientPrintDataDto> cardList = studentList.stream().map(m -> {
+            ClientPrintDataDto printDataDto = newClientPrintDataDto(m);
+            Map<String, String> urlMap = commonService.filePreviewByAttachmentId(Long.valueOf(m.get("attachmentId").toString()), false);
+            printDataDto.setMd5(urlMap.get("md5"));
+            printDataDto.setUrl(urlMap.get("url"));
+            return printDataDto;
+        }).collect(Collectors.toList());
+        return cardList;
+    }
+
+    /**
+     * new ClientPrintDataDto
+     *
+     * @param m
+     * @return
+     */
+    private ClientPrintDataDto newClientPrintDataDto(Map m) {
+        ClientPrintDataDto printDataDto = new ClientPrintDataDto();
+        String courseCode = m.get("courseCode").toString();
+        String courseName = m.get("courseName").toString();
+        String studentName = m.get("studentName").toString();
+        String studentCode = m.get("studentCode").toString();
+        String paperType = m.get("paperType").toString();
+        printDataDto.setCourseCode(courseCode);
+        printDataDto.setCourseName(courseName);
+        printDataDto.setStudentName(studentName);
+        printDataDto.setStudentCode(studentCode);
+        printDataDto.setPaperType(paperType);
+        return printDataDto;
+    }
 }

+ 5 - 7
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ClientStatusServiceImpl.java

@@ -3,7 +3,6 @@ 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.entity.ExamTask;
 import com.qmth.distributed.print.business.mapper.ClientStatusMapper;
 import com.qmth.distributed.print.business.service.ClientStatusService;
 import com.qmth.distributed.print.business.service.ExamTaskService;
@@ -21,9 +20,9 @@ public class ClientStatusServiceImpl extends ServiceImpl<ClientStatusMapper, Cli
     private ExamTaskService examTaskService;
 
     @Override
-    public Boolean tagPass(Long schoolId, Long examTaskId, String machineCode, Boolean isPass, Long userId) {
+    public Boolean tagPass(Long schoolId, String courseCode, String courseName, String paperNumber, 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);
+        queryWrapper.lambda().eq(ClientStatus::getSchoolId, schoolId).eq(ClientStatus::getCourseCode, courseCode).eq(ClientStatus::getPaperNumber, paperNumber).eq(ClientStatus::getMachineCode, machineCode);
         ClientStatus clientStatus = this.getOne(queryWrapper);
         if(clientStatus != null){
             clientStatus.setPass(isPass);
@@ -35,10 +34,9 @@ public class ClientStatusServiceImpl extends ServiceImpl<ClientStatusMapper, Cli
             clientStatus.setId(SystemConstant.getDbUuid());
             clientStatus.setSchoolId(schoolId);
             clientStatus.setMachineCode(machineCode);
-            ExamTask examTask = examTaskService.getById(examTaskId);
-            clientStatus.setExamTaskId(examTaskId);
-            clientStatus.setCourseCode(examTask.getCourseCode());
-            clientStatus.setCourseName(examTask.getCourseName());
+            clientStatus.setCourseCode(courseCode);
+            clientStatus.setCourseName(courseName);
+            clientStatus.setPaperNumber(paperNumber);
             clientStatus.setTry(true);
             clientStatus.setTryTime(System.currentTimeMillis());
             clientStatus.setPass(isPass);

+ 147 - 50
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/CommonServiceImpl.java

@@ -1,14 +1,18 @@
 package com.qmth.distributed.print.business.service.impl;
 
+import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.io.FileUtil;
 import cn.hutool.core.util.ZipUtil;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.qmth.boot.core.enums.Platform;
+import com.qmth.boot.tools.signature.SignatureType;
 import com.qmth.distributed.print.business.bean.auth.AuthBean;
+import com.qmth.distributed.print.business.bean.auth.ExpireTimeBean;
 import com.qmth.distributed.print.business.bean.dto.OrgDto;
 import com.qmth.distributed.print.business.bean.dto.PrivilegeCacheDto;
+import com.qmth.distributed.print.business.bean.result.LoginResult;
 import com.qmth.distributed.print.business.bean.result.PrivilegeResult;
 import com.qmth.distributed.print.business.bean.result.RolePrivilegeResult;
 import com.qmth.distributed.print.business.config.DictionaryConfig;
@@ -16,9 +20,8 @@ import com.qmth.distributed.print.business.entity.*;
 import com.qmth.distributed.print.business.enums.*;
 import com.qmth.distributed.print.business.service.*;
 import com.qmth.distributed.print.business.templete.execute.AsyncCreatePdfTempleteService;
-import com.qmth.distributed.print.business.util.OssUtil;
-import com.qmth.distributed.print.business.util.RedisUtil;
-import com.qmth.distributed.print.business.util.ServletUtil;
+import com.qmth.distributed.print.business.util.*;
+import com.qmth.distributed.print.common.SignatureEntityTest;
 import com.qmth.distributed.print.common.contant.SpringContextHolder;
 import com.qmth.distributed.print.common.contant.SystemConstant;
 import com.qmth.distributed.print.common.enums.ExceptionResultEnum;
@@ -83,19 +86,25 @@ public class CommonServiceImpl implements CommonService {
     private ExamDetailService examDetailService;
 
     @Autowired
-    private ExamDetailCourseService examDetailCourseService;
+    private SysOrgService sysOrgService;
 
-    @Resource
-    TBTaskService tbTaskService;
+    @Autowired
+    private BasicAttachmentService basicAttachmentService;
 
     @Resource
-    AsyncCreatePdfTempleteService asyncCreatePdfTempleteService;
+    CommonService commonService;
 
     @Autowired
-    private SysOrgService sysOrgService;
+    private ExamDetailCourseService examDetailCourseService;
 
     @Autowired
-    private BasicAttachmentService basicAttachmentService;
+    private TBTaskService tbTaskService;
+
+    @Autowired
+    private AsyncCreatePdfTempleteService asyncCreatePdfTempleteService;
+
+    @Autowired
+    private ConvertUtil convertUtil;
 
     /**
      * 新增用户权限
@@ -346,12 +355,40 @@ public class CommonServiceImpl implements CommonService {
     /**
      * 文件预览
      *
-     * @param attachmentId 附件ID
+     * @param path 附件路径
+     * @param type 保存类型:本地、OSS
+     * @param isExpire     url是否带过期时间
+     * @return
+     */
+    @Override
+    public String filePreviewByPathAndType(String path, String type, Boolean isExpire) {
+        if (StringUtils.isBlank(path)) {
+            return null;
+        }
+
+        String pathUrl;
+        if (Objects.equals(type, SystemConstant.LOCAL)) {
+            pathUrl = SystemConstant.HTTP + dictionaryConfig.sysDomain().getFileHost() + File.separator + path;
+        } else {
+            if (isExpire) {
+                pathUrl = ossUtil.getPrivateUrl(path);
+            } else {
+                pathUrl = dictionaryConfig.aliYunOssDomain().getUrl() + File.separator + path;
+            }
+
+        }
+        return pathUrl;
+    }
+
+    /**
+     * 文件预览
+     *
+     * @param attachmentId 附件路径
      * @param isExpire     url是否带过期时间
      * @return
      */
     @Override
-    public Map<String, String> filePreview(String attachmentId, Boolean isExpire) {
+    public Map<String, String> filePreviewByAttachmentId(Long attachmentId, Boolean isExpire) {
         BasicAttachment attachment = basicAttachmentService.getById(attachmentId);
         if (attachment == null) {
             return null;
@@ -359,49 +396,22 @@ public class CommonServiceImpl implements CommonService {
 
         Map<String, String> map = new HashMap<>();
 
-        String pathUrl, htmlPath = null, htmlUrl = null, pdfPath = null, pdfUrl = null;
+        String pathUrl;
         JSONObject jsonObject = JSONObject.parseObject(attachment.getPath());
         String attachmentType = (String) jsonObject.get(SystemConstant.TYPE);
         String filePath = (String) jsonObject.get(SystemConstant.PATH);
-        // 有htmlPath
-        if(jsonObject.containsKey(SystemConstant.HTML_PATH)){
-            htmlPath = (String) jsonObject.get(SystemConstant.HTML_PATH);
-        }
-        // 有pdfPath
-        if(jsonObject.containsKey(SystemConstant.PDF_PATH)){
-            pdfPath = (String) jsonObject.get(SystemConstant.PDF_PATH);
-        }
         if (Objects.equals(attachmentType, SystemConstant.LOCAL)) {
             pathUrl = SystemConstant.HTTP + dictionaryConfig.sysDomain().getFileHost() + File.separator + filePath;
-            if(StringUtils.isNotBlank(htmlPath)){
-                htmlUrl = SystemConstant.HTTP + dictionaryConfig.sysDomain().getFileHost() + File.separator + htmlPath;
-            }
-            if(StringUtils.isNotBlank(pdfPath)){
-                pdfUrl = SystemConstant.HTTP + dictionaryConfig.sysDomain().getFileHost() + File.separator + pdfPath;
-            }
         } else {
             if (isExpire) {
                 pathUrl = ossUtil.getPrivateUrl(filePath);
-                if(StringUtils.isNotBlank(htmlPath)){
-                    htmlUrl = ossUtil.getPrivateUrl(htmlPath);
-                }
-                if(StringUtils.isNotBlank(pdfPath)){
-                    pdfUrl = ossUtil.getPrivateUrl(pdfPath);
-                }
             } else {
-                    pathUrl = dictionaryConfig.aliYunOssDomain().getUrl() + File.separator + filePath;
-                if(StringUtils.isNotBlank(htmlPath)){
-                    htmlUrl = dictionaryConfig.aliYunOssDomain().getUrl() + File.separator + htmlPath;
-                }
-                if(StringUtils.isNotBlank(pdfPath)){
-                    pdfUrl = dictionaryConfig.aliYunOssDomain().getUrl() + File.separator + pdfPath;
-                }
+                pathUrl = dictionaryConfig.aliYunOssDomain().getUrl() + File.separator + filePath;
             }
 
         }
-        map.put("pathUrl", pathUrl);
-        map.put("htmlUrl", htmlUrl);
-        map.put("pdfUrl", pdfUrl);
+        map.put("url", pathUrl);
+        map.put("md5", attachment.getMd5());
         return map;
     }
 
@@ -411,7 +421,7 @@ public class CommonServiceImpl implements CommonService {
         JSONObject object = JSONObject.parseObject(path);
         String filePath = object.getString(SystemConstant.PATH);
         String type = object.getString(SystemConstant.TYPE);
-        if (filePath.endsWith(SystemConstant.HTML_PREFIX) || filePath.endsWith(SystemConstant.FTL_PREFIX) ) {
+        if (filePath.endsWith(SystemConstant.HTML_PREFIX) || filePath.endsWith(SystemConstant.FTL_PREFIX)) {
             StringBuffer sb = new StringBuffer();
             try {
                 InputStream fis;
@@ -512,12 +522,12 @@ public class CommonServiceImpl implements CommonService {
     }
 
     @Override
-    public File copyFile(String rootPath, BasicAttachment attachment) {
+    public File copyFile(String rootPath, String fileName, BasicAttachment attachment) {
         JSONObject object = JSONObject.parseObject(attachment.getPath());
         String filePath = object.getString(SystemConstant.PATH);
         String type = object.getString(SystemConstant.TYPE);
         if (type.equals(SystemConstant.OSS)) {
-            File localPath = new File(rootPath, attachment.getName() + attachment.getType());
+            File localPath = new File(rootPath, fileName);
             try {
                 File file = ossUtil.ossDownload(filePath, localPath.getPath());
                 return file;
@@ -544,7 +554,7 @@ public class CommonServiceImpl implements CommonService {
         }
         File zipFile = null;
         try {
-            zipFile = FileUtil.file(SystemConstant.DOWNLOAD_TEMP + File.separator + schoolId, time + ".zip");
+            zipFile = FileUtil.file(SystemConstant.TEMP_FILES_DIR + File.separator + schoolId, time + ".zip");
             // 压缩文件
             if (!zipFile.exists()) {
                 zipFile.createNewFile();
@@ -552,7 +562,33 @@ public class CommonServiceImpl implements CommonService {
             File[] srcFiles = files.toArray(new File[files.size()]);
 //            ZipUtil.zip(rootFile.getAbsolutePath(), zipFile.getAbsolutePath(), false);
 
-            ZipUtil.zip(zipFile, false, srcFiles);
+            ZipUtil.zip(zipFile, true, srcFiles);
+            outputFile(response, zipFile, String.valueOf(time));
+        } catch (Exception e) {
+            throw ExceptionResultEnum.ERROR.exception("下载失败");
+        } finally {
+            // 删除zip文件
+            FileUtil.del(zipFile);
+            // 删除压缩内容
+            FileUtil.del(rootPath);
+        }
+    }
+
+    @Override
+    public void downloadFileAndZip(HttpServletResponse response, String rootPath, long time) {
+        File rootFile = new File(rootPath);
+        // 创建保存目录
+        if (!rootFile.exists()) {
+            rootFile.mkdirs();
+        }
+        File zipFile = null;
+        try {
+            zipFile = FileUtil.file(SystemConstant.TEMP_FILES_DIR, time + ".zip");
+            // 压缩文件
+            if (!zipFile.exists()) {
+                zipFile.createNewFile();
+            }
+            ZipUtil.zip(rootPath, zipFile.getAbsolutePath(), true);
             outputFile(response, zipFile, String.valueOf(time));
         } catch (Exception e) {
             throw ExceptionResultEnum.ERROR.exception("下载失败");
@@ -577,8 +613,8 @@ public class CommonServiceImpl implements CommonService {
             List<ExamDetail> examDetails = examDetailService.listByCourseCodeAndPaperNumber(schoolId, courseCode, paperNumber);
             if (examDetails != null && examDetails.size() > 0) {
                 // 3.检查examDetailId下有无其它课程
-                /*for (ExamDetail examDetail : examDetails) {
-                    List<ExamDetailCourse> examDetailCourses = examDetailCourseService.listByExamDetailId(examDetail.getId());
+                for (ExamDetail examDetail : examDetails) {
+                    List<ExamDetailCourse> examDetailCourses = examDetailCourseService.listByExamDetailIdAndStatus(examDetail.getId());
                     // 4.没有未完成的命题任务
                     if (examDetailCourses.isEmpty()) {
                         Map<String, Object> map = tbTaskService.saveTask(TaskTypeEnum.CREATE_PDF, examDetail.getPrintPlanId(), user);
@@ -588,7 +624,7 @@ public class CommonServiceImpl implements CommonService {
                         map.computeIfAbsent("schoolId", v -> schoolId);
                         asyncCreatePdfTempleteService.createPdf(map, null);
                     }
-                }*/
+                }
             }
         }
     }
@@ -612,6 +648,67 @@ public class CommonServiceImpl implements CommonService {
         return stringSet;
     }
 
+    /**
+     * 登录公用
+     *
+     * @param password
+     * @param sysUser
+     * @return
+     * @throws NoSuchAlgorithmException
+     */
+    @Override
+    public LoginResult login(String password, SysUser sysUser) throws NoSuchAlgorithmException {
+        //密码不正确
+        if (!Objects.equals(password, sysUser.getPassword())) {
+            throw ExceptionResultEnum.PASSWORD_ERROR.exception();
+        }
+        //停用
+        if (!sysUser.getEnable()) {
+            throw ExceptionResultEnum.USER_ENABLE.exception();
+        }
+
+        Platform platform = ServletUtil.getRequestPlatform();
+        String deviceId = ServletUtil.getRequestDeviceId();
+        AuthBean authBean = commonService.getUserAuth(sysUser.getId());
+        //添加用户鉴权缓存
+        if (Objects.isNull(authBean)) {
+            throw ExceptionResultEnum.ROLE_ENABLE_AUTHORIZATION.exception();
+        }
+        //生成token
+        String token = SystemConstant.getUuid();
+        cacheService.userCache(sysUser.getId());
+        //添加用户会话缓存
+        Set<RoleTypeEnum> roleType = authBean.getRoleList().stream().map(s -> s.getType()).collect(Collectors.toSet());
+        String sessionId = SessionUtil.digest(sysUser.getId(), Math.abs(roleType.toString().hashCode()), platform.name());
+        //TODO 测试用
+        String test = SignatureEntityTest.build(SignatureType.TOKEN, sessionId, token);
+        ExpireTimeBean expireTime = AuthUtil.getExpireTime(platform);
+        TBSession tbSession = new TBSession(sessionId, String.valueOf(sysUser.getId()), roleType.toString(),
+                platform.name(), platform.name(), deviceId, ServletUtil.getRequest().getLocalAddr(), token,
+                expireTime.getDate().getTime());
+        tbSessionService.saveOrUpdate(tbSession);
+        redisUtil.setUserSession(sessionId, tbSession, expireTime.getExpireSeconds());
+
+        LoginResult loginResult = new LoginResult(sysUser, sessionId, test, roleType);
+        loginResult.setSchoolInfo(Objects.nonNull(authBean.getSchool()) ? loginResult.new SchoolNativeBean(authBean.getSchool()) : null);
+        loginResult.setOrgInfo(Objects.nonNull(authBean.getOrg()) ? loginResult.new OrgNativeBean(authBean.getOrg()) : null);
+        return loginResult;
+    }
+
+    @Override
+    public String createPaperNumber(Long schoolId) {
+        String date = DateUtil.today().replace("-", "");
+        String paperNumber = convertUtil.getIncre(date, "paperNumber" + schoolId, 5);
+        QueryWrapper<ExamTask> queryWrapper = new QueryWrapper<>();
+        queryWrapper.lambda().eq(ExamTask::getSchoolId, schoolId).eq(ExamTask::getPaperNumber, paperNumber);
+        ExamTask examTask = examTaskService.getOne(queryWrapper);
+        if(examTask!= null){
+            return createPaperNumber(schoolId);
+        } else{
+            return paperNumber;
+        }
+    }
+
     private Set<Long> getOrgIds(Set<Long> stringSet, List<OrgDto> orgDtos, Long parentId) {
         for (OrgDto orgDto : orgDtos) {
             Long tempParentId = orgDto.getParentId();

+ 55 - 15
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamCardServiceImpl.java

@@ -6,16 +6,14 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.qmth.distributed.print.business.bean.dto.CardCustDto;
 import com.qmth.distributed.print.business.bean.dto.CardDetailDto;
+import com.qmth.distributed.print.business.bean.params.ArraysParams;
 import com.qmth.distributed.print.business.bean.params.ExamCardParams;
 import com.qmth.distributed.print.business.entity.*;
 import com.qmth.distributed.print.business.enums.CardStatusEnum;
 import com.qmth.distributed.print.business.enums.CardTypeEnum;
 import com.qmth.distributed.print.business.enums.MakeMethodEnum;
 import com.qmth.distributed.print.business.mapper.ExamCardMapper;
-import com.qmth.distributed.print.business.service.BasicExamRuleService;
-import com.qmth.distributed.print.business.service.ExamCardDetailService;
-import com.qmth.distributed.print.business.service.ExamCardService;
-import com.qmth.distributed.print.business.service.ExamTaskDetailService;
+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;
@@ -24,11 +22,9 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-import java.util.stream.Collectors;
+import javax.servlet.http.HttpServletResponse;
+import java.io.File;
+import java.util.*;
 
 /**
  * <p>
@@ -50,6 +46,15 @@ public class ExamCardServiceImpl extends ServiceImpl<ExamCardMapper, ExamCard> i
     @Autowired
     private ExamTaskDetailService examTaskDetailService;
 
+    @Autowired
+    private ExamTaskService examTaskService;
+
+    @Autowired
+    private CommonService commonService;
+
+    @Autowired
+    private BasicAttachmentService basicAttachmentService;
+
     @Transactional
     @Override
     public String saveExamCard(ExamCardParams examCardParams) {
@@ -61,6 +66,9 @@ public class ExamCardServiceImpl extends ServiceImpl<ExamCardMapper, ExamCard> i
         // 新增
         ExamCard examCard;
         ExamCardDetail examCardDetail;
+        if(examCardParams.getTitle().getBytes().length > 80){
+            throw ExceptionResultEnum.ERROR.exception("标题最长只能输入80个字符");
+        }
         if (examCardParams.getId() == null) {
             examCard = new ExamCard();
             examCard.setId(SystemConstant.getDbUuid());
@@ -120,9 +128,9 @@ public class ExamCardServiceImpl extends ServiceImpl<ExamCardMapper, ExamCard> i
     }
 
     @Override
-    public IPage<CardCustDto> listCardCust(String status, String paperNumber, String userId, Long applyStartTime, Long applyEndTime, Long finishStartTime, Long finishEndTime, Integer pageNumber, Integer pageSize) {
+    public IPage<CardCustDto> listCardCust(String schoolId, String status, String paperNumber, String userId, Long applyStartTime, Long applyEndTime, Long finishStartTime, Long finishEndTime, Integer pageNumber, Integer pageSize) {
         Page<CardCustDto> page = new Page<>(pageNumber, pageSize);
-        IPage<CardCustDto> cardCustDtoIPage = this.baseMapper.listCardCust(page, status, paperNumber, userId, applyStartTime, applyEndTime, finishStartTime, finishEndTime);
+        IPage<CardCustDto> cardCustDtoIPage = this.baseMapper.listCardCust(page, schoolId, status, paperNumber, userId, applyStartTime, applyEndTime, finishStartTime, finishEndTime);
         return cardCustDtoIPage;
     }
 
@@ -135,7 +143,7 @@ public class ExamCardServiceImpl extends ServiceImpl<ExamCardMapper, ExamCard> i
         if (!MakeMethodEnum.CUST.name().equals(examCardParams.getMakeMethod().name())) {
             throw ExceptionResultEnum.ERROR.exception("题卡制作类型错误");
         }
-        if (StringUtils.isBlank(examCardParams.getAttachmentId())) {
+        if (StringUtils.isBlank(examCardParams.getCustAttachmentId())) {
             throw ExceptionResultEnum.ERROR.exception("客户制卡时,附件未上传");
         }
 
@@ -155,7 +163,7 @@ public class ExamCardServiceImpl extends ServiceImpl<ExamCardMapper, ExamCard> i
         ExamCardDetail examCardDetail = new ExamCardDetail();
         examCardDetail.setId(SystemConstant.getDbUuid());
         examCardDetail.setCardId(examCard.getId());
-        examCardDetail.setAttachmentId(examCardParams.getAttachmentId());
+        examCardDetail.setCustAttachmentId(examCardParams.getCustAttachmentId());
         examCardDetail.setCreateId(user.getId());
         examCardDetail.setCreateTime(System.currentTimeMillis());
         examCardDetailService.save(examCardDetail);
@@ -168,7 +176,12 @@ public class ExamCardServiceImpl extends ServiceImpl<ExamCardMapper, ExamCard> i
 
     @Override
     public CardDetailDto getCardDetail(Long cardId) {
-        return this.baseMapper.getCardDetail(cardId);
+        ExamCard examCard = this.getById(cardId);
+        if (!MakeMethodEnum.SELECT.equals(examCard.getMakeMethod())) {
+            return this.baseMapper.getCardDetail(cardId);
+        } else {
+            return this.baseMapper.getCardDetailBySelect(cardId);
+        }
     }
 
     @Override
@@ -198,7 +211,7 @@ public class ExamCardServiceImpl extends ServiceImpl<ExamCardMapper, ExamCard> i
         // 专卡
         if (SystemConstant.ALL_CARD != cardRuleId) {
             List<ExamCard> customCards = this.baseMapper.listCustom(schoolId, sysUser.getOrgId(), courseCode, CardTypeEnum.CUSTOM.name());
-            if(!customCards.isEmpty()){
+            if (!customCards.isEmpty()) {
                 list.addAll(customCards);
             }
         }
@@ -206,6 +219,33 @@ public class ExamCardServiceImpl extends ServiceImpl<ExamCardMapper, ExamCard> i
         return list;
     }
 
+    @Override
+    public void downloadFiles(HttpServletResponse response, ArraysParams arraysParams) {
+        // 路径规则:download-temp/{time}/{schoolId}/{courseCode}-{couseName}/{paperNumber}/{fileName}
+        long time = System.nanoTime();
+        String rootPath = SystemConstant.TEMP_FILES_DIR + File.separator + time;
+
+        Long[] cardIds = arraysParams.getIds();
+        // 根据题卡取命题任务
+        for (Long cardId : cardIds) {
+            List<ExamTask> examTasks = examTaskService.listExamTaskByCardId(cardId);
+            if (examTasks.isEmpty() || examTasks.size() > 1) {
+                throw ExceptionResultEnum.ERROR.exception("题卡数据异常");
+            }
+            ExamTask examTask = examTasks.get(0);
+            StringJoiner sj = new StringJoiner(File.separator);
+            sj.add(rootPath).add(examTask.getSchoolId().toString()).add(examTask.getCourseCode() + "-" + examTask.getCourseName()).add(examTask.getPaperNumber());
+
+            // 附件ID
+            ExamCardDetail examCardDetail = examCardDetailService.getByCardId(cardId);
+            BasicAttachment attachment = basicAttachmentService.getById(examCardDetail.getCustAttachmentId());
+            String fileName = attachment.getName() + attachment.getType();
+            commonService.copyFile(sj.toString(),fileName, attachment);
+        }
+        // 压缩
+        commonService.downloadFileAndZip(response, rootPath, time);
+    }
+
 
     /**
      * 数据验证

+ 24 - 3
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamDetailCourseServiceImpl.java

@@ -3,6 +3,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.BasicCourse;
 import com.qmth.distributed.print.business.entity.ExamDetailCourse;
 import com.qmth.distributed.print.business.enums.ExamDetailStatusEnum;
 import com.qmth.distributed.print.business.mapper.ExamDetailCourseMapper;
@@ -12,6 +13,7 @@ import org.springframework.transaction.annotation.Transactional;
 
 import java.util.List;
 import java.util.Map;
+import java.util.stream.Collectors;
 
 /**
  * <p>
@@ -32,7 +34,7 @@ public class ExamDetailCourseServiceImpl extends ServiceImpl<ExamDetailCourseMap
     }
 
     @Override
-    public List<Map<String, String>> listByExamDetailId(Long examDetailId) {
+    public List<Map<String, Object>> listByExamDetailId(Long examDetailId) {
         return this.baseMapper.listByExamDetailId(examDetailId, ExamDetailStatusEnum.FINISH.name());
     }
 
@@ -47,8 +49,27 @@ public class ExamDetailCourseServiceImpl extends ServiceImpl<ExamDetailCourseMap
     }
 
     @Override
-    public void updatePaperNumber(List<ExamDetailCourse> examDetailCourses, String paperNumber) {
+    public void updatePaperNumber(List<ExamDetailCourse> examDetailCourses, String paperNumber, String relatePaperType) {
+        List<Long> examDetailCourseIds = examDetailCourses.stream().map(m->m.getId()).collect(Collectors.toList());
         UpdateWrapper<ExamDetailCourse> updateWrapper = new UpdateWrapper<>();
-        updateWrapper.lambda().set(ExamDetailCourse::getPaperNumber, paperNumber).in(ExamDetailCourse::getId, examDetailCourses);
+        updateWrapper.lambda().set(ExamDetailCourse::getPaperNumber, paperNumber)
+                .set(ExamDetailCourse::getPaperType, relatePaperType)
+                .in(ExamDetailCourse::getId, examDetailCourseIds);
+        this.update(updateWrapper);
+    }
+
+    @Override
+    public List<ExamDetailCourse> listByExamDetailIdAndStatus(Long examDetailId) {
+        return this.baseMapper.listByExamDetailIdAndStatus(examDetailId, ExamDetailStatusEnum.FINISH.name());
+    }
+
+    @Override
+    public List<BasicCourse> listCoursesByPrintPlanId(String param, Long printPlanId) {
+        return this.baseMapper.listCoursesByPrintPlanId(param, printPlanId);
+    }
+
+    @Override
+    public List<String> listPaperNumberByPrintPlanId(String param, Long printPlanId) {
+        return this.baseMapper.listPaperNumberByPrintPlanId(param, printPlanId);
     }
 }

+ 149 - 92
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamDetailServiceImpl.java

@@ -7,7 +7,6 @@ import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.qmth.distributed.print.business.base.BaseEntity;
 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;
@@ -24,6 +23,7 @@ import com.qmth.distributed.print.business.util.ConvertUtil;
 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.apache.commons.lang3.StringUtils;
 import org.apache.poi.ss.usermodel.HorizontalAlignment;
 import org.apache.poi.xssf.usermodel.*;
 import org.slf4j.Logger;
@@ -109,27 +109,13 @@ public class ExamDetailServiceImpl extends ServiceImpl<ExamDetailMapper, ExamDet
     @Override
     public PrintTaskTotalDto taskTotalData(Long printPlanId, String status, String courseCode, String paperNumber, String examPlace, String examRoom, Long examStartTime, Long examEndTime) {
         Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
-        PrintTaskTotalDto printTaskTotalDto = this.baseMapper.taskTotalData(schoolId, printPlanId, status, courseCode, paperNumber, examPlace, examRoom, examStartTime, examEndTime);
+        Set<Long> orgIds = commonService.listSubOrgIds(null);
+        PrintTaskTotalDto printTaskTotalDto = this.baseMapper.taskTotalData(schoolId, printPlanId, status, courseCode, paperNumber, examPlace, examRoom, examStartTime, examEndTime, orgIds);
 
-        // 计算A3剩余
-        TaskTotalLeftDto totalLeftDto = this.baseMapper.calcLeftA3(schoolId);
         if (printTaskTotalDto != null) {
-            // 分别计算张数
-            // 试卷
-            int paperPagesA3 = totalLeftDto == null ? 0 : totalLeftDto.getPaperPagesA3();
-            int printPaperCount = totalLeftDto == null ? 0 : totalLeftDto.getPrintPaperCount();
-            int paperPages = paperPagesA3 % 2 == 0 ? paperPagesA3 / 2 : paperPagesA3 / 2 + 1;
-            int totalPaperPages = paperPages * printPaperCount;
-
-            // 题卡
-            int cardPagesA3 = totalLeftDto == null ? 0 : totalLeftDto.getCardPagesA3();
-            int printCardCount = totalLeftDto == null ? 0 : totalLeftDto.getPrintCardCount();
-            int cardPages = cardPagesA3 % 2 == 0 ? cardPagesA3 / 2 : cardPagesA3 / 2 + 1;
-            int totalCardPages = cardPages * printCardCount;
-            printTaskTotalDto.setPagesA3Left(totalPaperPages + totalCardPages);
-
-            // todo A4剩余
-            printTaskTotalDto.setPagesA4Left(0);
+            // 试卷总计
+            Integer paperCount = this.baseMapper.selectPaperCount(schoolId, printPlanId, status, courseCode, paperNumber, examPlace, examRoom, examStartTime, examEndTime, orgIds);
+            printTaskTotalDto.setPaperCount(paperCount == null ? 0 : paperCount.intValue());
         }
         return printTaskTotalDto;
     }
@@ -149,14 +135,14 @@ public class ExamDetailServiceImpl extends ServiceImpl<ExamDetailMapper, ExamDet
     public List<FieldsDto> findExaminationFields(Long schoolId) {
         BasicExamRule basicExamRule = basicExamRuleService.list(new QueryWrapper<BasicExamRule>().lambda().eq(BasicExamRule::getSchoolId, schoolId)).get(0);
         if (basicExamRule == null) {
-            throw ExceptionResultEnum.ERROR.exception("找不到该学校考务字段信息 + schoolId" + schoolId);
+            throw ExceptionResultEnum.ERROR.exception("找不到该学校考务字段信息");
         }
         String requiredFields = basicExamRule.getRequiredFields();
         String extendFields = basicExamRule.getExtendFields();
         // 必选字段
         List<FieldsDto> requiredFieldsList = JSONObject.parseArray(requiredFields, FieldsDto.class);
         if (requiredFieldsList.stream().anyMatch(e -> !e.getEnable())) {
-            throw ExceptionResultEnum.ERROR.exception("该学校考务字段设置存在必选字段禁用的情况 schoolId = " + schoolId);
+            throw ExceptionResultEnum.ERROR.exception("该学校考务字段设置存在必选字段禁用的情况");
         }
         for (FieldsDto fieldsDto : requiredFieldsList) {
             fieldsDto.setLevel("primary");
@@ -166,7 +152,7 @@ public class ExamDetailServiceImpl extends ServiceImpl<ExamDetailMapper, ExamDet
         List<FieldsDto> extendFieldsList = JSONObject.parseArray(extendFields, FieldsDto.class);
         List<String> extendCodeList = extendFieldsList.stream().map(FieldsDto::getCode).collect(Collectors.toList());
         if (extendCodeList.stream().anyMatch(e -> requiredFieldsList.stream().map(FieldsDto::getCode).collect(Collectors.toList()).contains(e))) {
-            throw ExceptionResultEnum.ERROR.exception("该学校考务字段设置存在相同的code schoolId = " + schoolId);
+            throw ExceptionResultEnum.ERROR.exception("该学校考务字段设置存在相同的代码");
         }
         // 有效的扩展字段
         List<FieldsDto> validExtendList = extendFieldsList.stream().filter(FieldsDto::getEnable).collect(Collectors.toList());
@@ -178,12 +164,8 @@ public class ExamDetailServiceImpl extends ServiceImpl<ExamDetailMapper, ExamDet
         List<FieldsDto> validExaminationFieldList = new ArrayList<>();
         validExaminationFieldList.addAll(requiredFieldsList);
         validExaminationFieldList.addAll(validExtendList);
-        System.out.println("---" + validExaminationFieldList);
 
         List<String> fieldsName = validExaminationFieldList.stream().map(FieldsDto::getName).collect(Collectors.toList());
-        for (String s : fieldsName) {
-            System.out.println(s);
-        }
         return validExaminationFieldList;
     }
 
@@ -225,8 +207,8 @@ public class ExamDetailServiceImpl extends ServiceImpl<ExamDetailMapper, ExamDet
 
     @Transactional(rollbackFor = Exception.class)
     @Override
-    public IPage<ExaminationResult> findExaminationBriefPage(Long schoolId, Long printPlanId, String courseCode, String paperNumber, String examPlace, String examRoom, String packageCode, int pageNumber, int pageSize) {
-        IPage<ExaminationResult> page = examDetailMapper.findBriefPage(new Page<>(pageNumber, pageSize), schoolId, printPlanId, courseCode, paperNumber, examPlace, examRoom, packageCode);
+    public IPage<ExaminationResult> findExaminationBriefPage(Long schoolId, Long printPlanId, String courseCode, String paperNumber, String examPlace, String examRoom, String packageCode, int pageNumber, int pageSize, Set<Long> orgIds) {
+        IPage<ExaminationResult> page = examDetailMapper.findBriefPage(new Page<>(pageNumber, pageSize), schoolId, printPlanId, courseCode, paperNumber, examPlace, examRoom, packageCode, orgIds);
         List<ExaminationResult> list = page.getRecords();
         for (ExaminationResult examinationResult : list) {
             String examDetailCourseIds = examinationResult.getExamDetailCourseIds();
@@ -266,8 +248,8 @@ public class ExamDetailServiceImpl extends ServiceImpl<ExamDetailMapper, ExamDet
 
     @Transactional(rollbackFor = Exception.class)
     @Override
-    public SummarizedDataResult findSummarizedData(Long schoolId, Long printPlanId, String courseCode, String paperNumber, String examPlace, String examRoom, String packageCode) {
-        IPage<ExaminationResult> page = this.findExaminationBriefPage(schoolId, printPlanId, courseCode, paperNumber, examPlace, examRoom, packageCode, SystemConstant.PAGE_NUMBER, SystemConstant.PAGE_SIZE);
+    public SummarizedDataResult findSummarizedData(Long schoolId, Long printPlanId, String courseCode, String paperNumber, String examPlace, String examRoom, String packageCode, Set<Long> orgIds) {
+        IPage<ExaminationResult> page = this.findExaminationBriefPage(schoolId, printPlanId, courseCode, paperNumber, examPlace, examRoom, packageCode, SystemConstant.PAGE_NUMBER, SystemConstant.PAGE_SIZE, orgIds);
         List<ExaminationResult> list = page.getRecords();
         int totalSubjects = 0;
         for (ExaminationResult examinationResult : list) {
@@ -283,8 +265,9 @@ public class ExamDetailServiceImpl extends ServiceImpl<ExamDetailMapper, ExamDet
 
     @Transactional(rollbackFor = Exception.class)
     @Override
-    public IPage<ExaminationDetailResult> findExaminationDetail(Long printPlanId, String courseCode, String paperNumber, String examPlace, String examRoom, String studentParam, int pageNumber, int pageSize) {
-        return examDetailMapper.findDetailPage(new Page<>(pageNumber, pageSize), printPlanId, courseCode, paperNumber, examPlace, examRoom, studentParam);
+    public IPage<ExaminationDetailResult> findExaminationDetail(Long schoolId, Long printPlanId, String courseCode, String paperNumber, String examPlace, String examRoom, String studentParams, int pageNumber, int pageSize) {
+        Set<Long> orgIds = commonService.listSubOrgIds(null);
+        return examDetailMapper.findDetailPage(new Page<>(pageNumber, pageSize), schoolId, printPlanId, courseCode, paperNumber, examPlace, examRoom, studentParams, orgIds);
     }
 
     @Transactional(rollbackFor = Exception.class)
@@ -295,27 +278,71 @@ public class ExamDetailServiceImpl extends ServiceImpl<ExamDetailMapper, ExamDet
 
     @Transactional(rollbackFor = Exception.class)
     @Override
-    public List<String> findExamPlaceDatasource() {
-        List<ExamDetail> examDetail = this.list();
+    public List<String> findExamPlaceDatasource(String param, Long printPlanId) {
+        Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
+        QueryWrapper<ExamDetail> queryWrapper = new QueryWrapper<>();
+        queryWrapper.lambda().eq(ExamDetail::getSchoolId, schoolId);
+        if(StringUtils.isNotBlank(param)){
+            queryWrapper.lambda().like(ExamDetail::getExamPlace, param);
+        }
+        if(printPlanId != null){
+            queryWrapper.lambda().like(ExamDetail::getPrintPlanId, printPlanId);
+        }
+        List<ExamDetail> examDetail = this.list(queryWrapper);
         return examDetail.stream().map(ExamDetail::getExamPlace).distinct().collect(Collectors.toList());
     }
 
     @Transactional(rollbackFor = Exception.class)
     @Override
-    public List<String> findExamRoomDatasource() {
-        List<ExamDetail> examDetail = this.list();
+    public List<String> findExamRoomDatasource(String param, Long printPlanId) {
+        Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
+        QueryWrapper<ExamDetail> queryWrapper = new QueryWrapper<>();
+        queryWrapper.lambda().eq(ExamDetail::getSchoolId, schoolId);
+        if(StringUtils.isNotBlank(param)){
+            queryWrapper.lambda().like(ExamDetail::getExamRoom, param);
+        }
+        if(printPlanId != null){
+            queryWrapper.lambda().like(ExamDetail::getPrintPlanId, printPlanId);
+        }
+        List<ExamDetail> examDetail = this.list(queryWrapper);
         return examDetail.stream().map(ExamDetail::getExamRoom).distinct().collect(Collectors.toList());
     }
 
+    @Transactional
     @Override
-    public boolean submitTask(ExamDetail examDetail) throws IOException {
-        // 检查前置操作是否完成 todo
+    public boolean submitTask(ExamDetail examDetail) {
+        // 检查前置操作是否完成(是否生成pdf)
+        ExamDetail detail = this.getById(examDetail.getId());
+        if (detail == null) {
+            throw ExceptionResultEnum.ERROR.exception("考场数据异常");
+        }
+
+        // 印刷计划必须为就绪才可提交印刷
+        ExamPrintPlan examPrintPlan = examPrintPlanService.getById(detail.getPrintPlanId());
+        if (!PrintPlanStatusEnum.READY.equals(examPrintPlan.getStatus()) && !PrintPlanStatusEnum.PRINTING.equals(examPrintPlan.getStatus())) {
+            throw ExceptionResultEnum.ERROR.exception("印刷计划就绪、印刷中状态才可提交印刷");
+        }
+
+        // 只有就绪状态并且附件生成才可提交
+        if (!ExamDetailStatusEnum.READY.equals(detail.getStatus())) {
+            throw ExceptionResultEnum.ERROR.exception("考场就绪状态才可提交印刷");
+        } else if (detail.getAttachmentId() == null) {
+            throw ExceptionResultEnum.ERROR.exception("考场文件未生成");
+        }
+
+        // 修改印刷计划状态为印刷中
+        UpdateWrapper<ExamPrintPlan> examPrintPlanUpdateWrapper = new UpdateWrapper<>();
+        examPrintPlanUpdateWrapper.lambda().set(ExamPrintPlan::getStatus, PrintPlanStatusEnum.PRINTING).eq(ExamPrintPlan::getId, detail.getPrintPlanId());
+        examPrintPlanService.update(examPrintPlanUpdateWrapper);
+
+        // 修改考场状态为待印刷
         UpdateWrapper<ExamDetail> updateWrapper = new UpdateWrapper<>();
         updateWrapper.lambda().set(ExamDetail::getStatus, ExamDetailStatusEnum.WAITING).eq(ExamDetail::getId, examDetail.getId());
 
         return this.update(updateWrapper);
     }
 
+    @Transactional
     @Override
     public boolean taskCancel(ExamDetail examDetail) {
         ExamDetail detail = this.getById(examDetail.getId());
@@ -324,7 +351,18 @@ public class ExamDetailServiceImpl extends ServiceImpl<ExamDetailMapper, ExamDet
         }
         UpdateWrapper<ExamDetail> updateWrapper = new UpdateWrapper<>();
         updateWrapper.lambda().set(ExamDetail::getStatus, ExamDetailStatusEnum.READY).eq(ExamDetail::getId, examDetail.getId());
-        return this.update(updateWrapper);
+        this.update(updateWrapper);
+
+        //所有考场都撤回,印刷任务状态改为就绪
+        QueryWrapper<ExamDetail> queryWrapper = new QueryWrapper<>();
+        queryWrapper.lambda().eq(ExamDetail::getPrintPlanId, detail.getPrintPlanId()).notIn(ExamDetail::getStatus, ExamDetailStatusEnum.NEW, ExamDetailStatusEnum.READY);
+        List<ExamDetail> examDetails = this.list(queryWrapper);
+        if (examDetails.isEmpty()) {
+            UpdateWrapper<ExamPrintPlan> printPlanUpdateWrapper = new UpdateWrapper<>();
+            printPlanUpdateWrapper.lambda().set(ExamPrintPlan::getStatus, PrintPlanStatusEnum.READY).eq(ExamPrintPlan::getId, detail.getPrintPlanId());
+            examPrintPlanService.update(printPlanUpdateWrapper);
+        }
+        return true;
     }
 
     @Override
@@ -345,16 +383,16 @@ public class ExamDetailServiceImpl extends ServiceImpl<ExamDetailMapper, ExamDet
 
     @Transactional(rollbackFor = Exception.class)
     @Override
-    public List<Long> disposeExamDetailByExaminationExcel(List<Map<String, Object>> dataList, Long userId, SerialNumberParams serialNumberParams) {
+    public List<Long> disposeExamDetailByExaminationExcel(List<ExaminationImportDto> dataList, Long userId, SerialNumberParams serialNumberParams) {
         List<Map<String, Object>> examDetailKeyList = dataList.stream().flatMap(e -> {
             Map<String, Object> map = new HashMap<>();
-            map.put("schoolId", e.get("schoolId"));
-            map.put("printPlanId", e.get("printPlanId"));
-            map.put("printPlanName", e.get("printPlanName"));
-            map.put("examPlace", e.get("examPlace"));
-            map.put("examRoom", e.get("examRoom"));
-            map.put("examStartTime", e.get("examStartTime"));
-            map.put("examEndTime", e.get("examEndTime"));
+            map.put("schoolId", e.getSchoolId());
+            map.put("printPlanId", e.getPrintPlanId());
+            map.put("printPlanName", e.getPrintPlanName());
+            map.put("examPlace", e.getExamPlace());
+            map.put("examRoom", e.getExamRoom());
+            map.put("examStartTime", e.getExamStartTime());
+            map.put("examEndTime", e.getExamEndTime());
             return Stream.of(map);
         }).distinct().collect(Collectors.toList());
 
@@ -366,15 +404,13 @@ public class ExamDetailServiceImpl extends ServiceImpl<ExamDetailMapper, ExamDet
             String examRoom = String.valueOf(map.get("examRoom"));
             String examStartTime = String.valueOf(map.get("examStartTime"));
             String examEndTime = String.valueOf(map.get("examEndTime"));
-            System.out.println("dataList : " + JSON.toJSONString(dataList));
-            System.out.println(examPlace + examRoom + examStartTime + examEndTime);
+
             long totalSubjects = dataList.stream()
-                    .filter(e -> String.valueOf(e.get("examPlace")).equals(examPlace) &&
-                            String.valueOf(e.get("examRoom")).equals(examRoom) &&
-                            String.valueOf(e.get("examStartTime")).equals(examStartTime) &&
-                            String.valueOf(e.get("examEndTime")).equals(examEndTime)).count();
+                    .filter(e -> e.getExamPlace().equals(examPlace) &&
+                            e.getExamRoom().equals(examRoom) &&
+                            e.getExamStartTime().equals(examStartTime) &&
+                            e.getExamEndTime().equals(examEndTime)).count();
 
-            System.out.println("totalSubjects" + totalSubjects);
             ExamDetail examDetail = new ExamDetail();
             examDetail.setId(SystemConstant.getDbUuid());
             examDetail.setPackageCode(convertUtil.getIncre(serialNumberParams.getPrefix(), serialNumberParams.getModel(), serialNumberParams.getDigit()));
@@ -397,19 +433,19 @@ public class ExamDetailServiceImpl extends ServiceImpl<ExamDetailMapper, ExamDet
 
     @Transactional(rollbackFor = Exception.class)
     @Override
-    public void disposeExamDetailCourseByExaminationExcel(List<Map<String, Object>> dataList, Long userId) {
+    public void disposeExamDetailCourseByExaminationExcel(List<ExaminationImportDto> dataList, Long userId) {
 
         List<Map<String, Object>> examDetailKeyList = dataList.stream().flatMap(e -> {
             Map<String, Object> map = new HashMap<>();
-            map.put("schoolId", e.get("schoolId"));
-            map.put("printPlanId", e.get("printPlanId"));
-            map.put("examPlace", e.get("examPlace"));
-            map.put("examRoom", e.get("examRoom"));
-            map.put("examStartTime", e.get("examStartTime"));
-            map.put("examEndTime", e.get("examEndTime"));
-            map.put("courseCode", e.get("courseCode"));
-            map.put("courseName", e.get("courseName"));
-            map.put("paperNumber", e.get("paperNumber"));
+            map.put("schoolId", e.getSchoolId());
+            map.put("printPlanId", e.getPrintPlanId());
+            map.put("examPlace", e.getExamPlace());
+            map.put("examRoom", e.getExamRoom());
+            map.put("examStartTime", e.getExamStartTime());
+            map.put("examEndTime", e.getExamEndTime());
+            map.put("courseCode", e.getCourseCode());
+            map.put("courseName", e.getCourseName());
+            map.put("paperNumber", e.getPaperNumber());
             return Stream.of(map);
         }).distinct().collect(Collectors.toList());
 
@@ -424,6 +460,23 @@ public class ExamDetailServiceImpl extends ServiceImpl<ExamDetailMapper, ExamDet
             String courseCode = String.valueOf(map.get("courseCode"));
             String courseName = String.valueOf(map.get("courseName"));
             String paperNumber = String.valueOf(map.get("paperNumber"));
+
+            // 获取该科目下的考生人数
+            List<ExaminationImportDto> sameCourseList = dataList.stream().filter(e -> e.getSchoolId().equals(schoolId) &&
+                    e.getPrintPlanId().equals(printPlanId) &&
+                    e.getExamPlace().equals(examPlace) &&
+                    e.getExamRoom().equals(examRoom) &&
+                    Long.valueOf(e.getExamStartTime()).equals(examStartTime) &&
+                    Long.valueOf(e.getExamEndTime()).equals(examEndTime) &&
+                    e.getCourseCode().equals(courseCode) &&
+                    e.getCourseName().equals(courseName) &&
+                    e.getPaperNumber().equals(paperNumber)).collect(Collectors.toList());
+
+            System.out.println(JSON.toJSONString(sameCourseList));
+
+            int totalSubjects = sameCourseList.size();
+
+
             List<ExamDetail> examDetailList = this.list(new QueryWrapper<ExamDetail>().lambda()
                     .eq(ExamDetail::getPrintPlanId, printPlanId)
                     .eq(ExamDetail::getExamPlace, examPlace)
@@ -441,6 +494,7 @@ public class ExamDetailServiceImpl extends ServiceImpl<ExamDetailMapper, ExamDet
             examDetailCourse.setCourseCode(courseCode);
             examDetailCourse.setCourseName(courseName);
             examDetailCourse.setPaperNumber(paperNumber);
+            examDetailCourse.setTotalSubjects(totalSubjects);
             examDetailCourse.setCreateId(userId);
             examDetailCourse.setUpdateId(userId);
             examDetailCourseList.add(examDetailCourse);
@@ -450,22 +504,24 @@ public class ExamDetailServiceImpl extends ServiceImpl<ExamDetailMapper, ExamDet
 
     @Transactional(rollbackFor = Exception.class)
     @Override
-    public void disposeExamStudentByExaminationExcel(List<Map<String, Object>> dataList, Long userId) {
+    public void disposeExamStudentByExaminationExcel(List<ExaminationImportDto> dataList, Long userId) {
         List<ExamStudent> examStudentList = new ArrayList<>();
-        for (Map<String, Object> map : dataList) {
-            Long schoolId = Long.valueOf(String.valueOf(map.get("schoolId")));
-            Long printPlanId = Long.valueOf(String.valueOf(map.get("printPlanId")));
-            String examPlace = String.valueOf(map.get("examPlace"));
-            String examRoom = String.valueOf(map.get("examRoom"));
-            Long examStartTime = SystemConstant.convertIdToLong(String.valueOf(map.get("examStartTime")));
-            Long examEndTime = SystemConstant.convertIdToLong(String.valueOf(map.get("examEndTime")));
-            String courseCode = String.valueOf(map.get("courseCode"));
-            String courseName = String.valueOf(map.get("courseName"));
-            String paperNumber = String.valueOf(map.get("paperNumber"));
-            String studentName = String.valueOf(map.get("studentName"));
-            String studentCode = String.valueOf(map.get("studentCode"));
-
-            List<FieldsDto> fieldsDtoList = (List<FieldsDto>) map.get("secondaryFieldList");
+        for (ExaminationImportDto examinationImportDto : dataList) {
+            Long schoolId = examinationImportDto.getSchoolId();
+            Long printPlanId = examinationImportDto.getPrintPlanId();
+            String examPlace = examinationImportDto.getExamPlace();
+            String examRoom = examinationImportDto.getExamRoom();
+            Long examStartTime = SystemConstant.convertIdToLong(examinationImportDto.getExamStartTime());
+            Long examEndTime = SystemConstant.convertIdToLong(examinationImportDto.getExamEndTime());
+            String courseCode = examinationImportDto.getCourseCode();
+            String courseName = examinationImportDto.getCourseName();
+            String paperNumber = examinationImportDto.getPaperNumber();
+            String studentName = examinationImportDto.getStudentName();
+            String studentCode = examinationImportDto.getStudentCode();
+            String ticketNumber = examinationImportDto.getTicketNumber();
+            String siteNumber = examinationImportDto.getSiteNumber();
+
+            List<FieldsDto> fieldsDtoList = examinationImportDto.getSecondaryFieldList();
             List<ExtendFieldsDto> extendFieldsDtoList = this.getExtendFieldsByFields(fieldsDtoList);
             List<ExamDetail> examDetailList = this.list(new QueryWrapper<ExamDetail>().lambda()
                     .eq(ExamDetail::getPrintPlanId, printPlanId)
@@ -493,9 +549,9 @@ public class ExamDetailServiceImpl extends ServiceImpl<ExamDetailMapper, ExamDet
             examStudent.setExamDetailCourseId(examDetailCourseId);
             examStudent.setStudentName(studentName);
             examStudent.setStudentCode(studentCode);
-            examStudent.setTicketNumber(studentCode);
+            examStudent.setTicketNumber(ticketNumber);
             examStudent.setExtendFields(JSON.toJSONString(extendFieldsDtoList));
-            examStudent.setSiteNumber("");
+            examStudent.setSiteNumber(siteNumber);
             examStudent.setCreateId(userId);
             examStudent.setUpdateId(userId);
             examStudentList.add(examStudent);
@@ -553,6 +609,10 @@ public class ExamDetailServiceImpl extends ServiceImpl<ExamDetailMapper, ExamDet
         if (map.get("packageCode") != null) {
             packageCode = String.valueOf(map.get("packageCode"));
         }
+        Set<Long> orgIds = new HashSet<>();
+        if (Objects.nonNull(map.get("orgIds"))) {
+            orgIds = (Set<Long>) map.get("orgIds");
+        }
 
         TBTask tbTask = (TBTask) map.get(SystemConstant.TASK);
         Long userId = tbTask.getCreateId();
@@ -560,7 +620,7 @@ public class ExamDetailServiceImpl extends ServiceImpl<ExamDetailMapper, ExamDet
 
         List<ExaminationResult> examinationResultList = this.findExaminationBriefPage(schoolId,
                 printPlanId, courseCode, paperNumber, examPlace, examRoom, packageCode,
-                SystemConstant.PAGE_NUMBER, SystemConstant.PAGE_SIZE).getRecords();
+                SystemConstant.PAGE_NUMBER, SystemConstant.PAGE_SIZE, orgIds).getRecords();
         int index = 0;
         List<ExaminationExportDto> examinationExportDtoList = new ArrayList<>();
         for (ExaminationResult examinationResult : examinationResultList) {
@@ -581,15 +641,12 @@ 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);
+        updateWrapper.lambda().set(ExamDetail::getPrintProgress, printProgress).set(ExamDetail::getPrintEndTime, System.currentTimeMillis()).set(ExamDetail::getStatus, ExamDetailStatusEnum.FINISH).eq(ExamDetail::getId, examDetailId);
         return this.update(updateWrapper);
-        // todo 更新考生(是否需要这个字段,待定)
-
     }
 
     @Override
@@ -600,7 +657,7 @@ public class ExamDetailServiceImpl extends ServiceImpl<ExamDetailMapper, ExamDet
     }
 
     @Override
-    public List<Map<String, String>> listStudentByExamDetailId(Long schoolId, Long examDetailId, String ticketNumber, String type) {
+    public List<Map> listStudentByExamDetailId(Long schoolId, Long examDetailId, String ticketNumber, String type) {
         return this.baseMapper.listStudentByExamDetailId(schoolId, examDetailId, ticketNumber, type);
     }
 
@@ -609,7 +666,7 @@ public class ExamDetailServiceImpl extends ServiceImpl<ExamDetailMapper, ExamDet
     public void deleteExaminationData(Long printPlanId) {
         ExamPrintPlan examPrintPlan = examPrintPlanService.getById(printPlanId);
         if (examPrintPlan.getId() == null || examPrintPlan.getId() <= 0) {
-            throw ExceptionResultEnum.ERROR.exception("未找主键为 '" + printPlanId + "' 的印刷计划信息");
+            throw ExceptionResultEnum.ERROR.exception("未找印刷计划信息");
         }
         PrintPlanStatusEnum status = examPrintPlan.getStatus();
         if (PrintPlanStatusEnum.NEW != status && PrintPlanStatusEnum.READY != status) {
@@ -643,11 +700,11 @@ public class ExamDetailServiceImpl extends ServiceImpl<ExamDetailMapper, ExamDet
         examStudentService.remove(new QueryWrapper<ExamStudent>().lambda().in(ExamStudent::getId, examStudentIds));
     }
 
-    private List<ExtendFieldsDto> getExtendFieldsByFields(List<FieldsDto> fieldsDtoList){
+    private List<ExtendFieldsDto> getExtendFieldsByFields(List<FieldsDto> fieldsDtoList) {
         List<ExtendFieldsDto> extendFieldsDtoList = new ArrayList<>();
         for (FieldsDto fieldsDto : fieldsDtoList) {
             ExtendFieldsDto extendFieldsDto = new ExtendFieldsDto();
-            BeanUtils.copyProperties(fieldsDto,extendFieldsDto);
+            BeanUtils.copyProperties(fieldsDto, extendFieldsDto);
             extendFieldsDtoList.add(extendFieldsDto);
         }
         return extendFieldsDtoList;

+ 44 - 26
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamPrintPlanServiceImpl.java

@@ -64,6 +64,9 @@ public class ExamPrintPlanServiceImpl extends ServiceImpl<ExamPrintPlanMapper, E
     @Autowired
     private BasicAttachmentService basicAttachmentService;
 
+    @Resource
+    private BasicExamRuleService basicExamRuleService;
+
     @Transactional(rollbackFor = Exception.class)
     @Override
     public IPage<PrintPlanResult> printPlanPage(Long schoolId, Long printPlanId, PrintPlanStatusEnum status, Long startTime, Long endTime, int pageNumber, int pageSize) {
@@ -72,7 +75,7 @@ public class ExamPrintPlanServiceImpl extends ServiceImpl<ExamPrintPlanMapper, E
         List<PrintPlanResult> list = page.getRecords();
         for (PrintPlanResult printPlanResult : list) {
             List<Map> variableContent = JSONObject.parseArray(printPlanResult.getVariableContentTemp(), Map.class);
-            List<Map> ordinaryContent = JSONObject.parseArray(printPlanResult.getOrdinaryContentTemp(),Map.class);
+            List<Map> ordinaryContent = JSONObject.parseArray(printPlanResult.getOrdinaryContentTemp(), Map.class);
             printPlanResult.setVariableContent(variableContent);
             printPlanResult.setOrdinaryContent(ordinaryContent);
 
@@ -139,7 +142,7 @@ public class ExamPrintPlanServiceImpl extends ServiceImpl<ExamPrintPlanMapper, E
         for (ClassifyEnum value : ClassifyEnum.values()) {
             Map<String, Object> variableMap = new HashMap<>();
             List<TemplatePrintInfoResult> sourceList = variableList.stream().filter(e -> value.equals(e.getTemplateClassify())).collect(Collectors.toList());
-            List<Map<String,Object>> templateList = new ArrayList<>();
+            List<Map<String, Object>> templateList = new ArrayList<>();
             for (TemplatePrintInfoResult templatePrintInfoResult : sourceList) {
                 Map<String, Object> printMap = new HashMap<>();
                 printMap.put("id", String.valueOf(templatePrintInfoResult.getTemplateId()));
@@ -147,9 +150,9 @@ public class ExamPrintPlanServiceImpl extends ServiceImpl<ExamPrintPlanMapper, E
                 printMap.put("attachmentId", templatePrintInfoResult.getAttachmentId().toString());
                 templateList.add(printMap);
             }
-            if (templateList.size() > 0){
-                variableMap.put("type",value);
-                variableMap.put("template",templateList);
+            if (templateList.size() > 0) {
+                variableMap.put("type", value);
+                variableMap.put("template", templateList);
                 variable.add(variableMap);
             }
         }
@@ -162,7 +165,7 @@ public class ExamPrintPlanServiceImpl extends ServiceImpl<ExamPrintPlanMapper, E
         Map<String, Object> ordinaryMap = new HashMap<>();
         for (ClassifyEnum value : ClassifyEnum.values()) {
             List<TemplatePrintInfoResult> sourceList = ordinaryList.stream().filter(e -> value.equals(e.getTemplateClassify())).collect(Collectors.toList());
-            List<Map<String,Object>> templateList = new ArrayList<>();
+            List<Map<String, Object>> templateList = new ArrayList<>();
             for (TemplatePrintInfoResult templatePrintInfoResult : sourceList) {
                 Map<String, Object> printMap = new HashMap<>();
                 printMap.put("id", String.valueOf(templatePrintInfoResult.getTemplateId()));
@@ -170,9 +173,9 @@ public class ExamPrintPlanServiceImpl extends ServiceImpl<ExamPrintPlanMapper, E
                 printMap.put("attachmentId", templatePrintInfoResult.getAttachmentId().toString());
                 templateList.add(printMap);
             }
-            if (templateList.size() > 0){
-                ordinaryMap.put("type",value);
-                ordinaryMap.put("template",templateList);
+            if (templateList.size() > 0) {
+                ordinaryMap.put("type", value);
+                ordinaryMap.put("template", templateList);
                 ordinary.add(ordinaryMap);
             }
         }
@@ -190,11 +193,19 @@ public class ExamPrintPlanServiceImpl extends ServiceImpl<ExamPrintPlanMapper, E
         SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
         Long id = printPlanParams.getId();
         Long schoolId = printPlanParams.getSchoolId();
-        if (basicSchoolService.list(new QueryWrapper<BasicSchool>().lambda().eq(BasicSchool::getId,schoolId).eq(BasicSchool::getEnable,true)).size() != 1) {
-            throw ExceptionResultEnum.ERROR.exception("输入的学校id不满足条件 schoolId = " + schoolId);
+        if (basicSchoolService.list(new QueryWrapper<BasicSchool>().lambda().eq(BasicSchool::getId, schoolId).eq(BasicSchool::getEnable, true)).size() != 1) {
+            throw ExceptionResultEnum.ERROR.exception("输入的学校id不满足条件");
         }
 
+        // 校验是否印试卷和题卡
         List<String> printContentList = printPlanParams.getPrintContent();
+        BasicExamRule basicExamRule = basicExamRuleService.getBySchoolId(schoolId);
+        if (Objects.isNull(basicExamRule)) {
+            throw ExceptionResultEnum.ERROR.exception("未找到学校的通用规则");
+        }
+        /*if (basicExamRule.getIncludePaper() && !printContentList.contains("PAPER")) {
+            throw ExceptionResultEnum.ERROR.exception("学校通用规则设置了强制包含试卷的必须选择试卷印品!");
+        }*/
         if (printContentList.contains("PAPER") && !printContentList.contains("CARD")) {
             throw ExceptionResultEnum.ERROR.exception("如果试卷题卡印品选择了试卷,题卡必须被选择");
         }
@@ -213,8 +224,8 @@ public class ExamPrintPlanServiceImpl extends ServiceImpl<ExamPrintPlanMapper, E
         } else {
             // 包含印刷计划id -> 编辑印刷计划
             ExamPrintPlan tmp = this.getById(id);
-            if (tmp == null){
-                throw ExceptionResultEnum.ERROR.exception("印刷计划id不存在 id= " + id);
+            if (tmp == null) {
+                throw ExceptionResultEnum.ERROR.exception("印刷计划id不存在");
             }
             PrintPlanStatusEnum status = tmp.getStatus();
             if (!PrintPlanStatusEnum.NEW.equals(status) && !PrintPlanStatusEnum.READY.equals(status)) {
@@ -232,12 +243,16 @@ public class ExamPrintPlanServiceImpl extends ServiceImpl<ExamPrintPlanMapper, E
     public Boolean removePrintPlan(DeleteParams deleteParams) {
         Long id = deleteParams.getId();
         ExamPrintPlan examPrintPlan = this.getById(id);
-        if (examPrintPlan == null){
-            throw ExceptionResultEnum.ERROR.exception("要删除的项目计划不存在 id = " + id);
+        if (examPrintPlan == null) {
+            throw ExceptionResultEnum.ERROR.exception("要删除的项目计划不存在");
         }
-        if (!PrintPlanStatusEnum.NEW.equals(examPrintPlan.getStatus())){
-            throw ExceptionResultEnum.ERROR.exception("只有'新建'状态的项目计划可以被删除 status = " + examPrintPlan.getStatus());
+        // TODO: 2021/4/23 只有新建能删除  && !PrintPlanStatusEnum.READY.equals(examPrintPlan.getStatus())
+        if (!PrintPlanStatusEnum.NEW.equals(examPrintPlan.getStatus())) {
+            throw ExceptionResultEnum.ERROR.exception("只有'新建'状态的项目计划可以被删除");
         }
+//        if (!PrintPlanStatusEnum.NEW.equals(examPrintPlan.getStatus()) && !PrintPlanStatusEnum.READY.equals(examPrintPlan.getStatus())){
+//            throw ExceptionResultEnum.ERROR.exception("只有'新建'和就绪状态的项目计划可以被删除");
+//        }
         examDetailService.deleteExaminationData(id);
         return this.removeById(id);
     }
@@ -262,13 +277,17 @@ public class ExamPrintPlanServiceImpl extends ServiceImpl<ExamPrintPlanMapper, E
 
     @Override
     public IPage<ClientPrintTaskDto> listClientPrintTask(Page<ClientPrintTaskDto> page, Long schoolId, Long machineCode, String printPlanId, String status, String courseCode, String paperNumber, String examPlace, String examRoom, Long examStartTime, Long examEndTime, Boolean isDownload, Boolean validate, Set<Long> orgIds) {
-        return this.baseMapper.listClientPrintTask(page, schoolId,machineCode, printPlanId, status, courseCode, paperNumber, examPlace, examRoom, examStartTime, examEndTime,isDownload,validate, orgIds);
+        // 以下状态考场状态不可查询
+        String[] examDetailStatus = new String[]{ExamDetailStatusEnum.NEW.name(),PrintPlanStatusEnum.READY.name()};
+        return this.baseMapper.listClientPrintTask(page, schoolId, machineCode, printPlanId, status, courseCode, paperNumber, examPlace, examRoom, examStartTime, examEndTime, isDownload, validate, orgIds, examDetailStatus);
     }
 
 
     @Override
     public List<ClientPrintTaskDto> listClientPrintTask(Long schoolId, Long machineCode, String printPlanId, String status, String courseCode, String paperNumber, String examPlace, String examRoom, Long examStartTime, Long examEndTime, Boolean isDownload, Boolean validate, Set<Long> orgIds) {
-        return this.baseMapper.listClientPrintTask(schoolId,machineCode, printPlanId, status, courseCode, paperNumber, examPlace, examRoom, examStartTime, examEndTime,isDownload,validate, orgIds);
+        // 以下状态考场状态不可查询
+        String[] examDetailStatus = new String[]{ExamDetailStatusEnum.NEW.name(),PrintPlanStatusEnum.READY.name()};
+        return this.baseMapper.listClientPrintTask(schoolId, machineCode, printPlanId, status, courseCode, paperNumber, examPlace, examRoom, examStartTime, examEndTime, isDownload, validate, orgIds, examDetailStatus);
     }
 
 
@@ -292,21 +311,20 @@ public class ExamPrintPlanServiceImpl extends ServiceImpl<ExamPrintPlanMapper, E
         return resultList;
     }
 
-    public Map<String, String> getAttachment(Map map){
+    public Map<String, String> getAttachment(Map map) {
         Map<String, String> fMap = new HashMap<>();
-        fMap.put("type",map.get("type").toString());
+        fMap.put("type", map.get("type").toString());
         String attachmentId = map.get("attachmentId").toString();
         BasicAttachment attachment = basicAttachmentService.getById(attachmentId);
-        if(attachment.getType().equals(".ftl") || attachment.getType().equals(".html")){
+        if (attachment.getType().equals(".ftl") || attachment.getType().equals(".html")) {
             String content = commonService.readFileContent(attachment.getPath());
             fMap.put("content", content);
             fMap.put("utl", null);
         } else if (attachment.getType().equals(".pdf")) {
             fMap.put("content", null);
-
-            Map<String, String> urlMap = commonService.filePreview(attachmentId, false);
-            fMap.put("url", urlMap.get("pathUrl"));
-        } else{
+            Map<String, String> stringMap = commonService.filePreviewByAttachmentId(Long.valueOf(attachmentId), false);
+            fMap.putAll(stringMap);
+        } else {
             throw ExceptionResultEnum.ERROR.exception("不支持的类型");
         }
         return fMap;

+ 28 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamStudentServiceImpl.java

@@ -1,14 +1,19 @@
 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.extension.service.impl.ServiceImpl;
 import com.qmth.distributed.print.business.entity.ExamDetailCourse;
 import com.qmth.distributed.print.business.entity.ExamStudent;
 import com.qmth.distributed.print.business.mapper.ExamStudentMapper;
 import com.qmth.distributed.print.business.service.ExamStudentService;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.stereotype.Service;
 
 import java.util.List;
+import java.util.Map;
+import java.util.Objects;
 import java.util.stream.Collectors;
 
 /**
@@ -29,4 +34,27 @@ public class ExamStudentServiceImpl extends ServiceImpl<ExamStudentMapper, ExamS
         updateWrapper.lambda().set(ExamStudent::getPaperType, relatePaperType).in(ExamStudent::getExamDetailCourseId, examDetailCourseIds);
         this.update(updateWrapper);
     }
+
+    @Override
+    public List<String> listByExamDetailCourseId(String examDetailCourseId) {
+        QueryWrapper<ExamStudent> queryWrapper = new QueryWrapper<>();
+        queryWrapper.lambda().eq(ExamStudent::getExamDetailCourseId, examDetailCourseId);
+        List<ExamStudent> examStudents = this.list(queryWrapper);
+        if(!examStudents.isEmpty()){
+            List<String> strings = examStudents.stream().filter(m-> StringUtils.isNotBlank(m.getPaperType())).map(m->m.getPaperType()).distinct().collect(Collectors.toList());
+            return strings;
+        }
+        return null;
+    }
+
+    @Override
+    public Map<String, Object> getStudentDetail(Long id) {
+        Map<String, Object> map = this.baseMapper.getStudentDetail(id);
+        Object extendFields = map.get("extendFields");
+        if(Objects.nonNull(extendFields)){
+            List<Map> list = JSONObject.parseArray(extendFields.toString(), Map.class);
+            map.put("extendFields", list);
+        }
+        return map;
+    }
 }

+ 77 - 12
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamTaskDetailServiceImpl.java

@@ -15,6 +15,7 @@ import com.qmth.distributed.print.business.mapper.ExamTaskDetailMapper;
 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.contant.SystemConstant;
 import com.qmth.distributed.print.common.enums.ExceptionResultEnum;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -63,10 +64,13 @@ public class ExamTaskDetailServiceImpl extends ServiceImpl<ExamTaskDetailMapper,
     @Resource
     TBTaskService tbTaskService;
 
+    @Autowired
+    private ExamTaskPaperLogService examTaskPaperLogService;
+
     @Override
     public boolean enable(ExamTaskDetail examTaskDetail) {
         UpdateWrapper<ExamTaskDetail> updateWrapper = new UpdateWrapper<>();
-        updateWrapper.lambda().set(ExamTaskDetail::getEnable, examTaskDetail.getEnable()).eq(ExamTaskDetail::getId, examTaskDetail.getId());
+        updateWrapper.lambda().set(ExamTaskDetail::getEnable, examTaskDetail.getEnable()).eq(ExamTaskDetail::getExamTaskId, examTaskDetail.getId());
         return this.update(updateWrapper);
     }
 
@@ -90,7 +94,7 @@ public class ExamTaskDetailServiceImpl extends ServiceImpl<ExamTaskDetailMapper,
 
         // 更新试卷编号
         List<ExamDetailCourse> examDetailCourses = examDetailCourseService.listDetailCourseByCourseCodeAndPaperNumber(examTask.getSchoolId(), examTask.getCourseCode(), examTask.getPaperNumber());
-        examDetailCourseService.updatePaperNumber(examDetailCourses, paperParam.getPaperNumber());
+        examDetailCourseService.updatePaperNumber(examDetailCourses, paperParam.getPaperNumber(), paperParam.getRelatePaperType());
 
         // 更新考生关联类型
         examStudentService.updatePaperType(examDetailCourses, paperParam.getRelatePaperType());
@@ -100,6 +104,7 @@ public class ExamTaskDetailServiceImpl extends ServiceImpl<ExamTaskDetailMapper,
         SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
         Map<String, Object> map = tbTaskService.saveTask(TaskTypeEnum.CREATE_PDF, paperParam.getPrintPlanId(), sysUser);
         map.computeIfAbsent("examDetailCourseIds", v -> examDetailCourseIds);
+        map.computeIfAbsent("schoolId", v-> examTask.getSchoolId());
         map.computeIfAbsent("paperType", v -> paperParam.getRelatePaperType());
         asyncCreatePdfTempleteService.createPdf(map, null);
         return true;
@@ -141,25 +146,24 @@ public class ExamTaskDetailServiceImpl extends ServiceImpl<ExamTaskDetailMapper,
     }
 
     @Override
-    public String getUrl(Long schoolId, Long examTaskId) {
+    public Map<String, 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){
+        ExamTaskDetail examTaskDetail = this.getOne(examTaskDetailQueryWrapper);
+        if (examTaskDetail != null) {
             String relatePaperType = examTaskDetail.getRelatePaperType();
-            if(StringUtils.isNotBlank(relatePaperType)){
+            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)){
+                    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());
+                if (StringUtils.isNotBlank(attachmentId)) {
+                    return commonService.filePreviewByAttachmentId(Long.valueOf(attachmentId), false);
                 }
             }
         }
@@ -167,8 +171,69 @@ public class ExamTaskDetailServiceImpl extends ServiceImpl<ExamTaskDetailMapper,
     }
 
     @Override
-    public List<Map<String, String>> listByExamDetailId(Long schoolId, Long examDetailId) {
-        return this.baseMapper.listByExamDetailId(schoolId, examDetailId);
+    public boolean paperUpdate(ExamTaskDetail examTaskDetail) {
+        SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
+        // todo 前置校验条件,如打印中不能修改
+        QueryWrapper<ExamTaskDetail> queryWrapper = new QueryWrapper<>();
+        queryWrapper.lambda().eq(ExamTaskDetail::getExamTaskId, examTaskDetail.getExamTaskId());
+        ExamTaskDetail examTaskDetailTemp = this.getOne(queryWrapper);
+        if (examTaskDetailTemp == null) {
+            throw ExceptionResultEnum.ERROR.exception("命题任务数据异常");
+        }
+        // 已曝光试卷不能修改
+        String exposedPaperType = examTaskDetailTemp.getExposedPaperType();
+        if (StringUtils.isNotBlank(exposedPaperType)) {
+            List<Map> oldPaperAttachmentIdsList = JSONObject.parseArray(examTaskDetailTemp.getPaperAttachmentIds(), Map.class);
+            Map<String, String> oldPaperAttachmentIdMap = oldPaperAttachmentIdsList.stream().collect(Collectors.toMap(m -> m.get("name").toString(), m -> m.get("attachmentId").toString()));
+            String[] exposedPaperTypes = exposedPaperType.split(",");
+            String newPaperAttachmentIds = examTaskDetail.getPaperAttachmentIds();
+            if (StringUtils.isBlank(newPaperAttachmentIds)) {
+                throw ExceptionResultEnum.ERROR.exception("已曝光试卷不能删除");
+            } else {
+                List<Map> newPaperAttachmentIdsList = JSONObject.parseArray(newPaperAttachmentIds, Map.class);
+                Map<String, String> newPaperAttachmentIdMap = newPaperAttachmentIdsList.stream().collect(Collectors.toMap(m -> m.get("name").toString(), m -> m.get("attachmentId").toString()));
+                for (String paperType : exposedPaperTypes) {
+                    if (!newPaperAttachmentIdMap.containsKey(paperType)) {
+                        throw ExceptionResultEnum.ERROR.exception("已曝光试卷不能删除");
+                    } else {
+                        if (!oldPaperAttachmentIdMap.containsKey(paperType)) {
+                            throw ExceptionResultEnum.ERROR.exception("原试卷卷型有误");
+                        }
+                        String newAttachmentId = newPaperAttachmentIdMap.get(paperType);
+                        String oldAttachmentId = oldPaperAttachmentIdMap.get(paperType);
+                        if (!newAttachmentId.equals(oldAttachmentId)) {
+                            throw ExceptionResultEnum.ERROR.exception("已曝光试卷不能修改");
+                        }
+                    }
+                }
+
+            }
+
+        }
+
+        // 不需要审核,直接更新
+        ExamTask examTask = examTaskService.getById(examTaskDetail.getExamTaskId());
+        if (examTask.getReview()) {
+            // 加入临时审核表
+            ExamTaskPaperLog examTaskPaperLog = examTaskPaperLogService.getByExamTaskIdAndReview(examTaskDetail.getExamTaskId(), false);
+            if (examTaskPaperLog == null) {
+                examTaskPaperLog = new ExamTaskPaperLog();
+                examTaskPaperLog.setId(SystemConstant.getDbUuid());
+                examTaskPaperLog.setExamTaskId(examTaskDetail.getExamTaskId());
+                examTaskPaperLog.setReview(false);
+            }
+            examTaskPaperLog.setPaperType(examTaskDetail.getPaperType());
+            examTaskPaperLog.setPaperAttachmentIds(examTaskDetail.getPaperAttachmentIds());
+            examTaskPaperLog.setCardId(examTaskDetail.getCardId());
+            examTaskPaperLog.setCreateId(sysUser.getId());
+            examTaskPaperLog.setCreateTime(System.currentTimeMillis());
+            examTaskPaperLogService.saveOrUpdate(examTaskPaperLog);
+        } else {
+            UpdateWrapper<ExamTaskDetail> updateWrapper = new UpdateWrapper<>();
+            updateWrapper.lambda().set(ExamTaskDetail::getPaperAttachmentIds, examTaskDetail.getPaperAttachmentIds()).eq(ExamTaskDetail::getExamTaskId, examTaskDetail.getExamTaskId());
+            this.update(updateWrapper);
+        }
+        return true;
     }
 
 }

+ 27 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamTaskPaperLogServiceImpl.java

@@ -0,0 +1,27 @@
+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.ExamTaskPaperLog;
+import com.qmth.distributed.print.business.mapper.ExamTaskPaperLogMapper;
+import com.qmth.distributed.print.business.service.ExamTaskPaperLogService;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 卷库修改审核临时表 服务实现类
+ * </p>
+ *
+ * @author xf
+ * @since 2021-03-23
+ */
+@Service
+public class ExamTaskPaperLogServiceImpl extends ServiceImpl<ExamTaskPaperLogMapper, ExamTaskPaperLog> implements ExamTaskPaperLogService {
+
+    @Override
+    public ExamTaskPaperLog getByExamTaskIdAndReview(Long examTaskId, boolean review) {
+        QueryWrapper<ExamTaskPaperLog> queryWrapper = new QueryWrapper<>();
+        queryWrapper.lambda().eq(ExamTaskPaperLog::getExamTaskId, examTaskId).eq(ExamTaskPaperLog::getReview, review);
+        return this.getOne(queryWrapper);
+    }
+}

+ 405 - 153
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamTaskServiceImpl.java

@@ -1,6 +1,5 @@
 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;
@@ -16,14 +15,12 @@ import com.qmth.distributed.print.business.enums.*;
 import com.qmth.distributed.print.business.mapper.ExamTaskMapper;
 import com.qmth.distributed.print.business.service.*;
 import com.qmth.distributed.print.business.templete.execute.AsyncCreatePdfTempleteService;
-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;
 import com.qmth.distributed.print.common.contant.SystemConstant;
 import com.qmth.distributed.print.common.enums.ExceptionResultEnum;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.velocity.runtime.directive.contrib.For;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -75,27 +72,37 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
     @Autowired
     private SysUserService sysUserService;
 
+    @Autowired
+    private SysUserRoleService sysUserRoleService;
+
     @Autowired
     private ExamCardService examCardService;
 
     @Autowired
-    private ExamDetailCourseService examDetailCourseService;
+    private ExamCardDetailService examCardDetailService;
 
     @Autowired
-    private ExamPrintPlanService examPrintPlanService;
+    private ExamDetailCourseService examDetailCourseService;
 
     @Autowired
-    private ConvertUtil convertUtil;
+    private ExamPrintPlanService examPrintPlanService;
 
     @Resource
     private ExamDetailService examDetailService;
 
+    @Autowired
+    private BasicTemplateService basicTemplateService;
+
     @Resource
     TBTaskService tbTaskService;
 
     @Resource
     AsyncCreatePdfTempleteService asyncCreatePdfTempleteService;
 
+    @Autowired
+    private ExamTaskPaperLogService examTaskPaperLogService;
+
+
     @Override
     public List<ExamTask> listByCourseCode(Long schoolId, String code) {
         QueryWrapper<ExamTask> queryWrapper = new QueryWrapper<>();
@@ -113,33 +120,37 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
     }
 
     @Override
-    public List<String> listPaperNumber(String param) {
+    public List<String> listPaperNumber(String param, Long printPlanId) {
         Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
-        // 查询命题任务中的试卷编号
-        QueryWrapper<ExamTask> queryWrapperExamTask = new QueryWrapper<>();
-        List<String> list = new ArrayList<>();
-        if (StringUtils.isNotBlank(param)) {
-            queryWrapperExamTask.lambda().eq(ExamTask::getSchoolId, schoolId)
-                    .and(i -> i.like(ExamTask::getCourseCode, param).or().like(ExamTask::getCourseName, param));
-        }
-        List<ExamTask> examTasks = this.list(queryWrapperExamTask);
-        if (examTasks != null && examTasks.size() > 0) {
-            list = examTasks.stream().map(ExamTask::getPaperNumber).distinct().collect(Collectors.toList());
-        }
+        if(printPlanId == null) {
+            // 查询命题任务中的试卷编号
+            QueryWrapper<ExamTask> queryWrapperExamTask = new QueryWrapper<>();
+            queryWrapperExamTask.lambda().eq(ExamTask::getSchoolId, schoolId);
+            List<String> list = new ArrayList<>();
+            if (StringUtils.isNotBlank(param)) {
+                queryWrapperExamTask.lambda().and(i -> i.like(ExamTask::getCourseCode, param).or().like(ExamTask::getCourseName, param));
+            }
+            List<ExamTask> examTasks = this.list(queryWrapperExamTask);
+            if (examTasks != null && examTasks.size() > 0) {
+                list = examTasks.stream().map(ExamTask::getPaperNumber).distinct().collect(Collectors.toList());
+            }
 
-        // 查询考务-科目中的试卷编号
-        QueryWrapper<ExamDetailCourse> queryWrapperExamDetailCourse = new QueryWrapper<>();
-        List<String> list2 = new ArrayList<>();
-        if (StringUtils.isNotBlank(param)) {
-            queryWrapperExamDetailCourse.lambda().eq(ExamDetailCourse::getSchoolId, schoolId)
-                    .and(i -> i.like(ExamDetailCourse::getCourseCode, param).or().like(ExamDetailCourse::getCourseName, param));
-        }
-        List<ExamDetailCourse> ExamDetailCourses = examDetailCourseService.list(queryWrapperExamDetailCourse);
-        if (ExamDetailCourses != null && ExamDetailCourses.size() > 0) {
-            list2 = ExamDetailCourses.stream().map(ExamDetailCourse::getPaperNumber).distinct().collect(Collectors.toList());
+            // 查询考务-科目中的试卷编号
+            QueryWrapper<ExamDetailCourse> queryWrapperExamDetailCourse = new QueryWrapper<>();
+            queryWrapperExamDetailCourse.lambda().eq(ExamDetailCourse::getSchoolId, schoolId);
+            List<String> list2 = new ArrayList<>();
+            if (StringUtils.isNotBlank(param)) {
+                queryWrapperExamDetailCourse.lambda().and(i -> i.like(ExamDetailCourse::getCourseCode, param).or().like(ExamDetailCourse::getCourseName, param));
+            }
+            List<ExamDetailCourse> ExamDetailCourses = examDetailCourseService.list(queryWrapperExamDetailCourse);
+            if (ExamDetailCourses != null && ExamDetailCourses.size() > 0) {
+                list2 = ExamDetailCourses.stream().map(ExamDetailCourse::getPaperNumber).distinct().collect(Collectors.toList());
+            }
+            list.addAll(list2);
+            return list.stream().distinct().collect(Collectors.toList());
+        } else {
+            return examDetailCourseService.listPaperNumberByPrintPlanId(param, printPlanId);
         }
-        list.addAll(list2);
-        return list.stream().distinct().collect(Collectors.toList());
     }
 
     @Override
@@ -169,7 +180,13 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
             if (task.getEnable()) {
                 throw ExceptionResultEnum.ERROR.exception("命题任务禁用后,才能更改命题老师");
             }
-            updateWrapper.lambda().set(ExamTask::getUserId, examTask.getUserId()).eq(ExamTask::getId, examTask.getId());
+            ExamStatusEnum examStatusEnum;
+            if (examTask.getUserId() == null) {
+                examStatusEnum = ExamStatusEnum.NEW;
+            } else {
+                examStatusEnum = ExamStatusEnum.READY;
+            }
+            updateWrapper.lambda().set(ExamTask::getUserId, examTask.getUserId()).set(ExamTask::getStatus, examStatusEnum).eq(ExamTask::getId, examTask.getId());
         }
 
         return this.update(updateWrapper);
@@ -219,8 +236,7 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
             }
         } else {
             // 试卷编号生成规则:年月日(例如:20100419)+0000(例如:0001)顺序编号
-            String date = DateUtil.today().replace("-", "");
-            String paperNumber = convertUtil.getIncre(date, "paperNumber" + schoolId, 5);
+            String paperNumber = commonService.createPaperNumber(schoolId);
             examTask.setPaperNumber(paperNumber);
         }
 
@@ -245,7 +261,7 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
     @Override
     public ExamTaskImportDto importFile(MultipartFile file) throws IOException, NoSuchFieldException {
         List<LinkedMultiValueMap<Integer, Object>> finalList = ExcelUtil.excelReader(file.getInputStream(), Lists.newArrayList(ExamTaskTempDto.class), (finalExcelList, finalColumnNameList, finalExcelErrorList) -> {
-            Map<String,String> courseCodePaperNumberMap = new HashMap<>();
+            Map<String, String> courseCodePaperNumberMap = new HashMap<>();
             List<ExcelError> excelErrorTemp = new ArrayList<>();
             // 只允许导入一个sheet
             if (finalExcelList.size() > 1) {
@@ -272,14 +288,27 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
                     } else if (!course.getName().equals(userImportDto.getCourseName())) {
                         excelErrorTemp.add(new ExcelError(y + 1, "excel第" + (i + 1) + "个sheet第" + (y + 1) + "行[课程名称]与系统中不匹配"));
                     }
-                    if (courseCodePaperNumberMap.containsKey(userImportDto.getCourseCode())){
-                         String paperNumber = courseCodePaperNumberMap.get(userImportDto.getCourseCode());
-                         if (paperNumber != null &&  !paperNumber.equals(userImportDto.getPaperNumber())){
-                             excelErrorTemp.add(new ExcelError(y + 1, "excel第" + (i + 1) + "个sheet第" + (y + 1) + "行[课程代码]与[试卷编号]不唯一"));
-                         }
-                    }else {
-                        courseCodePaperNumberMap.put(userImportDto.getCourseCode(),userImportDto.getPaperNumber());
+                    if (courseCodePaperNumberMap.containsKey(userImportDto.getCourseCode())) {
+                        String paperNumber = courseCodePaperNumberMap.get(userImportDto.getCourseCode());
+                        if (paperNumber != null && paperNumber.equals(userImportDto.getPaperNumber())) {
+                            excelErrorTemp.add(new ExcelError(y + 1, "excel第" + (i + 1) + "个sheet第" + (y + 1) + "行[课程代码]与[试卷编号]不唯一"));
+                        }
+                    } else {
+                        courseCodePaperNumberMap.put(userImportDto.getCourseCode(), userImportDto.getPaperNumber());
+                    }
+
+                    // 校验命题老师
+                    String excelCourseCode = userImportDto.getCourseCode();
+                    String excelTeacherAccount = userImportDto.getUserAccount();
+                    String excelTeacherName = userImportDto.getUserName();
+
+                    if (Objects.nonNull(excelTeacherAccount) || Objects.nonNull(excelTeacherName)) {
+                        List<CourseInfoDto> courseInfoDtoList = basicCourseService.findByUserLoginNameAndRealName(excelTeacherAccount, excelTeacherName);
+                        if (!courseInfoDtoList.stream().map(CourseInfoDto::getCourseCode).collect(Collectors.toList()).contains(excelCourseCode)) {
+                            excelErrorTemp.add(new ExcelError(y + 1, "excel第" + (i + 1) + "个sheet第" + (y + 1) + "行[命题教师]身份信息有误"));
+                        }
                     }
+
                 }
             }
             if (excelErrorTemp.size() > 0) {
@@ -343,25 +372,37 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
                 examTaskDto.setCourseName(examTaskTemp.getCourseName());
                 examTaskDto.setPaperNumber(examTaskTemp.getPaperNumber());
                 examTaskDto.setSpecialty(examTaskTemp.getSpecialty());
-                // 校验命题老师
-                if (StringUtils.isBlank(examTaskTemp.getUserAccount())) {
-                    examTaskDto.setUsers(listUsers(examTaskTemp.getCourseCode(), null));
-                } else {
-                    QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
-                    queryWrapper.lambda().eq(SysUser::getLoginName, examTaskTemp.getUserAccount());
-                    SysUser sysUser1 = sysUserService.getOne(queryWrapper);
-                    if (sysUser1 == null) {
-                        examTaskDto.setUsers(listUsers(examTaskTemp.getCourseCode(), null));
-                    } else {
-                        List<BlurryUserDto> blurryUserDtoList = listUsers(examTaskTemp.getCourseCode(), String.valueOf(sysUser1.getId()));
+                List<BlurryUserDto> blurryUserDtoList;
 
-                        if (blurryUserDtoList.size() == 0){
-                            //如果没有查询到模糊用户数据 可能是excel中命题老师没有该课程权限,则舍弃该用户再次查询该科目-试卷的模糊用户
-                            blurryUserDtoList = listUsers(examTaskTemp.getCourseCode(), null);
-                        }
-                        examTaskDto.setUsers(blurryUserDtoList);
-                    }
+                QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
+                queryWrapper.lambda().eq(SysUser::getLoginName, examTaskTemp.getUserAccount());
+                SysUser sysUser1 = sysUserService.getOne(queryWrapper);
+                if (sysUser1 != null) {
+                    blurryUserDtoList = listUsers(examTaskTemp.getCourseCode(), String.valueOf(sysUser1.getId()));
+                } else {
+                    blurryUserDtoList = listUsers(examTaskTemp.getCourseCode(), null);
                 }
+                examTaskDto.setUsers(blurryUserDtoList);
+
+//                // 校验命题老师
+//                if (StringUtils.isBlank(examTaskTemp.getUserAccount())) {
+//                    examTaskDto.setUsers(listUsers(examTaskTemp.getCourseCode(), null));
+//                } else {
+//                    QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
+//                    queryWrapper.lambda().eq(SysUser::getLoginName, examTaskTemp.getUserAccount());
+//                    SysUser sysUser1 = sysUserService.getOne(queryWrapper);
+//                    if (sysUser1 == null) {
+//                        examTaskDto.setUsers(listUsers(examTaskTemp.getCourseCode(), null));
+//                    } else {
+//                        List<BlurryUserDto> blurryUserDtoList = listUsers(examTaskTemp.getCourseCode(), String.valueOf(sysUser1.getId()));
+//
+//                        if (blurryUserDtoList.size() == 0){
+//                            //如果没有查询到模糊用户数据 可能是excel中命题老师没有该课程权限,则舍弃该用户再次查询该科目-试卷的模糊用户
+//                            blurryUserDtoList = listUsers(examTaskTemp.getCourseCode(), null);
+//                        }
+//                        examTaskDto.setUsers(blurryUserDtoList);
+//                    }
+//                }
                 tasks.add(examTaskDto);
             }
         }
@@ -384,9 +425,6 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
         if (StringUtils.isBlank(task.getBatchNo())) {
             throw ExceptionResultEnum.ERROR.exception("batchNo不能为空");
         }
-        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);
@@ -395,39 +433,37 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
             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) {
+        List<Map<String, String>> userList = task.getUsers();
+
+        for (Map<String, String> userMap : userList) {
             ExamTask examTask = new ExamTask();
             examTask.setSchoolId(task.getSchoolId());
-            examTask.setCourseCode(examTaskTemp.getCourseCode());
-            examTask.setCourseName(examTaskTemp.getCourseName());
-            examTask.setSpecialty(examTaskTemp.getSpecialty());
+            examTask.setCourseCode(userMap.get("courseCode"));
+            examTask.setCourseName(userMap.get("courseName"));
+            examTask.setSpecialty(userMap.get("specialty"));
 
-            if (StringUtils.isNotBlank(examTaskTemp.getPaperNumber())) {
-                if (paperNumbers.contains(examTaskTemp.getPaperNumber())) {
+            if (StringUtils.isNotBlank(userMap.get("paperNumber"))) {
+                if (paperNumbers.contains(userMap.get("paperNumber"))) {
                     // 试卷编号在文件内重复,跳过
                     continue;
                 }
                 QueryWrapper<ExamTask> taskQueryWrapper = new QueryWrapper<>();
-                taskQueryWrapper.lambda().eq(ExamTask::getSchoolId, schoolId).eq(ExamTask::getPaperNumber, examTaskTemp.getPaperNumber());
+                taskQueryWrapper.lambda().eq(ExamTask::getSchoolId, schoolId).eq(ExamTask::getPaperNumber, userMap.get("paperNumber"));
                 ExamTask task1 = this.getOne(taskQueryWrapper);
                 if (task1 != null) {
 //                    throw ExceptionResultEnum.ERROR.exception("试卷编号已存在");
                     // 试卷编号已存在,直接跳过
                     continue;
                 }
-                paperNumbers.add(examTaskTemp.getPaperNumber());
+                paperNumbers.add(userMap.get("paperNumber"));
             } else {
                 // 试卷编号生成规则:年月日(例如:20100419)+0000(例如:0001)顺序编号
-                String date = DateUtil.today().replace("-", "");
-                String paperNumber = convertUtil.getIncre(date, "paperNumber" + schoolId, 5);
-                examTaskTemp.setPaperNumber(paperNumber);
+                String paperNumber = commonService.createPaperNumber(schoolId);
+                userMap.put("paperNumber", paperNumber);
             }
-            examTask.setPaperNumber(examTaskTemp.getPaperNumber());
+            examTask.setPaperNumber(userMap.get("paperNumber"));
             examTask.setStartTime(task.getStartTime());
             examTask.setEndTime(task.getEndTime());
             examTask.setEnable(true);
@@ -435,25 +471,14 @@ 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")) && examTaskTemp.getPaperNumber().equals(m.get("paperNumber"))) {
-                    return m.get("userId");
-                }
-                return "";
-            }).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)) {
-                    userId = user.get("userId");
-                    specialty = user.get("specialty");
-                }
+
+            String userId = userMap.get("userId");
+            String specialty = userMap.get("specialty");
+            if (specialty != null && specialty.length() > 0 && !specialty.equals("null")) {
+                examTask.setSpecialty(specialty);
             }
-            examTask.setSpecialty(specialty);
-            if (StringUtils.isNotBlank(userId)) {
-                examTask.setUserId(Long.valueOf(userId));
+            if (userId != null && userId.length() > 0 && !userId.equals("null")) {
+                examTask.setUserId(SystemConstant.convertIdToLong(userId));
                 examTask.setStatus(ExamStatusEnum.READY);
             } else {
                 examTask.setStatus(ExamStatusEnum.NEW);
@@ -464,13 +489,101 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
         return this.saveBatch(list);
     }
 
+//    @Override
+//    public boolean saveBatch(ExamTask task) {
+//        Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
+//        task.setSchoolId(schoolId);
+//        SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
+//
+//        if (StringUtils.isBlank(task.getBatchNo())) {
+//            throw ExceptionResultEnum.ERROR.exception("batchNo不能为空");
+//        }
+//        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());
+//
+//            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 paperNumber = commonService.createPaperNumber(schoolId);
+//                examTaskTemp.setPaperNumber(paperNumber);
+//            }
+//            examTask.setPaperNumber(examTaskTemp.getPaperNumber());
+//            examTask.setStartTime(task.getStartTime());
+//            examTask.setEndTime(task.getEndTime());
+//            examTask.setEnable(true);
+//            examTask.setCardRuleId(task.getCardRuleId());
+//            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")) && examTaskTemp.getPaperNumber().equals(m.get("paperNumber"))) {
+//                    return m.get("userId");
+//                }
+//                return "";
+//            }).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)) {
+//                    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);
+//    }
+
     @Override
     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()};
+        String[] strings = new String[]{ExamStatusEnum.NEW.name(), ExamStatusEnum.FINISH.name()};
         IPage<ExamTaskDto> examTaskDtoIPage = this.baseMapper.listTaskApply(page, schoolId, auditStatus, reviewStatus, cardRuleId, courseCode, paperNumber, startTime, endTime, strings, sysUser.getId(), orgIds);
         return examTaskDtoIPage;
     }
@@ -498,24 +611,49 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
     public boolean taskReviewSave(ExamTaskReviewLog taskReviewLog) throws IOException {
         SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
 
+        // 校验状态,可能被撤回
+        ExamTask examTask = this.getById(taskReviewLog.getExamTaskId());
+
         taskReviewLog.setOperateId(sysUser.getId());
         taskReviewLog.setOperateTime(System.currentTimeMillis());
         // 审核日志
         examTaskReviewLogService.save(taskReviewLog);
 
-        // 更新命题任务状态
-        UpdateWrapper<ExamTask> updateWrapper = new UpdateWrapper<>();
-        ExamStatusEnum statusEnum;
-        if (taskReviewLog.getReviewStatus().name().equals(ReviewStatusEnum.PASS.name())) {
-            statusEnum = ExamStatusEnum.FINISH;
-            // 校验是否可以提交打印状态
-            ExamTask examTask = this.getById(taskReviewLog.getExamTaskId());
-            commonService.checkData(examTask.getSchoolId(), examTask.getCourseCode(), examTask.getPaperNumber(), sysUser);
+        ExamTaskPaperLog examTaskPaperLog = examTaskPaperLogService.getByExamTaskIdAndReview(taskReviewLog.getExamTaskId(), false);
+        if (examTaskPaperLog == null) {
+            if (!ExamStatusEnum.SUBMIT.equals(examTask.getStatus())) {
+                throw ExceptionResultEnum.ERROR.exception("当前状态不能审核");
+            }
+
+            // 更新命题任务状态
+            UpdateWrapper<ExamTask> updateWrapper = new UpdateWrapper<>();
+            ExamStatusEnum statusEnum;
+            if (taskReviewLog.getReviewStatus().name().equals(ReviewStatusEnum.PASS.name())) {
+                statusEnum = ExamStatusEnum.FINISH;
+            } else {
+                statusEnum = ExamStatusEnum.STAGE;
+            }
+            updateWrapper.lambda().set(ExamTask::getStatus, statusEnum).set(ExamTask::getReviewStatus, taskReviewLog.getReviewStatus()).eq(ExamTask::getId, taskReviewLog.getExamTaskId());
+            return this.update(updateWrapper);
         } else {
-            statusEnum = ExamStatusEnum.STAGE;
+            // 更新记录表状态
+            examTaskPaperLog.setReview(true);
+            examTaskPaperLog.setReviewStatus(taskReviewLog.getReviewStatus());
+            examTaskPaperLog.setUpdateId(sysUser.getId());
+            examTaskPaperLog.setUpdateTime(System.currentTimeMillis());
+            examTaskPaperLogService.updateById(examTaskPaperLog);
+
+            if (taskReviewLog.getReviewStatus().name().equals(ReviewStatusEnum.PASS.name())) {
+                // 通过,更新正式表数据
+                UpdateWrapper<ExamTaskDetail> examTaskDetailUpdateWrapper = new UpdateWrapper<>();
+                examTaskDetailUpdateWrapper.lambda().set(ExamTaskDetail::getPaperType, examTaskPaperLog.getPaperType())
+                        .set(ExamTaskDetail::getPaperAttachmentIds, examTaskPaperLog.getPaperAttachmentIds())
+                        .set(ExamTaskDetail::getCardId, examTaskPaperLog.getCardId())
+                        .eq(ExamTaskDetail::getExamTaskId, taskReviewLog.getExamTaskId());
+                examTaskDetailService.update(examTaskDetailUpdateWrapper);
+            }
+            return true;
         }
-        updateWrapper.lambda().set(ExamTask::getStatus, statusEnum).set(ExamTask::getReviewStatus, taskReviewLog.getReviewStatus()).eq(ExamTask::getId, taskReviewLog.getExamTaskId());
-        return this.update(updateWrapper);
     }
 
     @Transactional
@@ -530,33 +668,63 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
             statusEnum = ExamStatusEnum.STAGE;
         }
         for (Long examTaskId : taskReviewLog.getExamTaskIds()) {
-            // 审核日志
-            taskReviewLog.setOperateId(sysUser.getId());
-            taskReviewLog.setOperateTime(System.currentTimeMillis());
-            taskReviewLog.setExamTaskId(examTaskId);
-            examTaskReviewLogService.save(taskReviewLog);
-
-            // 更新命题任务状态
-            UpdateWrapper<ExamTask> updateWrapper = new UpdateWrapper<>();
-            updateWrapper.lambda().set(ExamTask::getStatus, statusEnum).set(ExamTask::getReviewStatus, taskReviewLog.getReviewStatus()).eq(ExamTask::getId, taskReviewLog.getExamTaskId());
-            this.update(updateWrapper);
+            ExamTaskPaperLog examTaskPaperLog = examTaskPaperLogService.getByExamTaskIdAndReview(examTaskId, false);
+            if (examTaskPaperLog == null) {
+                // 校验状态,可能被撤回
+                ExamTask examTask = this.getById(examTaskId);
+                if (!ExamStatusEnum.SUBMIT.equals(examTask.getStatus())) {
+                    throw ExceptionResultEnum.ERROR.exception("当前状态不能审核");
+                }
+                // 审核日志
+                taskReviewLog.setOperateId(sysUser.getId());
+                taskReviewLog.setOperateTime(System.currentTimeMillis());
+                taskReviewLog.setExamTaskId(examTaskId);
+                taskReviewLog.setId(SystemConstant.getDbUuid());
+                examTaskReviewLogService.save(taskReviewLog);
+
+                // 更新命题任务状态
+                UpdateWrapper<ExamTask> updateWrapper = new UpdateWrapper<>();
+                updateWrapper.lambda().set(ExamTask::getStatus, statusEnum).set(ExamTask::getReviewStatus, taskReviewLog.getReviewStatus()).eq(ExamTask::getId, taskReviewLog.getExamTaskId());
+                this.update(updateWrapper);
+            } else {
+                // 更新记录表状态
+                examTaskPaperLog.setReview(true);
+                examTaskPaperLog.setReviewStatus(taskReviewLog.getReviewStatus());
+                examTaskPaperLog.setUpdateId(sysUser.getId());
+                examTaskPaperLog.setUpdateTime(System.currentTimeMillis());
+                examTaskPaperLogService.updateById(examTaskPaperLog);
+
+                if (taskReviewLog.getReviewStatus().name().equals(ReviewStatusEnum.PASS.name())) {
+                    // 通过,更新正式表数据
+                    UpdateWrapper<ExamTaskDetail> examTaskDetailUpdateWrapper = new UpdateWrapper<>();
+                    examTaskDetailUpdateWrapper.lambda().set(ExamTaskDetail::getPaperType, examTaskPaperLog.getPaperType())
+                            .set(ExamTaskDetail::getPaperAttachmentIds, examTaskPaperLog.getPaperAttachmentIds())
+                            .set(ExamTaskDetail::getCardId, examTaskPaperLog.getCardId())
+                            .eq(ExamTaskDetail::getExamTaskId, taskReviewLog.getExamTaskId());
+                    examTaskDetailService.update(examTaskDetailUpdateWrapper);
+                }
+            }
         }
         return true;
     }
 
     @Override
     public IPage<ExamTaskDetailDto> listTaskPaper(String courseCode, String paperNumber, Long startTime, Long endTime, Integer pageNumber, Integer pageSize) {
+        SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
+        // 查询用户角色是否包含命题老师
+        List<SysRole> list = sysUserRoleService.listRoleByUserId(sysUser.getId());
+        boolean containsQuestionTeacher = list.stream().filter(m-> RoleTypeEnum.QUESTION_TEACHER.equals(m.getType())).count() > 0;
         Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
         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);
+        IPage<ExamTaskDetailDto> examTaskDtoIPage = this.baseMapper.listTaskPaper(page, schoolId, courseCode, paperNumber, startTime, endTime, orgIds, containsQuestionTeacher, sysUser.getId());
         return examTaskDtoIPage;
     }
 
     @Override
     public List<RelatePaperDto> listPaperTypes(Long examTaskId, Long printPlanId, String courseCode) {
         Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
-        List<RelatePaperDto> list = this.baseMapper.listPaperNumbers(schoolId, courseCode);
+        List<RelatePaperDto> list = this.baseMapper.listPaperNumbers(schoolId, courseCode, ExamStatusEnum.FINISH.name());
         for (RelatePaperDto relatePaperDto : list) {
             QueryWrapper<ExamTaskDetail> queryWrapper = new QueryWrapper<>();
             queryWrapper.lambda().eq(ExamTaskDetail::getExamTaskId, relatePaperDto.getId()).eq(ExamTaskDetail::getEnable, true);
@@ -597,6 +765,7 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
     @Transactional
     @Override
     public boolean saveExamTaskDetail(ExamTaskDetail examTaskDetail) throws IOException {
+        SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
         if (examTaskDetail.getExamTaskId() == null) {
             throw ExceptionResultEnum.ERROR.exception("命题任务ID不能为空");
         }
@@ -623,18 +792,45 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
             if (!ExamCardStatusEnum.SUBMIT.name().equals(examCard.getStatus().name())) {
                 throw ExceptionResultEnum.ERROR.exception("请先提交题卡");
             }
+
+            // 是否强制包含试卷
+            BasicExamRule basicExamRule = basicExamRuleService.getBySchoolId();
+            List<Map> paperAttachmentIds = JSONObject.parseArray(examTaskDetail.getPaperAttachmentIds(), Map.class);
+            // 未上传试卷的类型个数
+            long count = paperAttachmentIds.stream().filter(m -> StringUtils.isBlank(m.get("attachmentId").toString())).count();
+            if (basicExamRule.getIncludePaper()) {
+                if (StringUtils.isBlank(examTaskDetail.getPaperAttachmentIds())) {
+                    throw ExceptionResultEnum.ERROR.exception("试卷文件未上传");
+                }
+                if (count > 0) {
+                    throw ExceptionResultEnum.ERROR.exception("所有类型的试卷文件必须全部上传");
+                }
+            } else {
+                // count == 0为全部上传
+                // paperAttachmentIds.size() == count 为全部未上传
+                if (count != 0 && paperAttachmentIds.size() != count) {
+                    throw ExceptionResultEnum.ERROR.exception("所有类型的试卷文件必须全部上传或全部不上传");
+                }
+            }
         }
 
         // 更新examTask状态status
         ExamTask examTask = this.getById(examTaskDetail.getExamTaskId());
-        if (examTask.getStatus().name().equals(ExamStatusEnum.SUBMIT.name()) && !examTask.getReview()) {
+        if (examTaskDetail.getOperateType().equals(ExamStatusEnum.SUBMIT.name()) && !examTask.getReview()) {
             examTask.setStatus(ExamStatusEnum.FINISH);
             // 校验是否可以提交打印状态
             commonService.checkData(examTask.getSchoolId(), examTask.getCourseCode(), examTask.getPaperNumber(), (SysUser) ServletUtil.getRequestUser());
+        } else {
+            examTask.setStatus(ExamStatusEnum.valueOf(examTaskDetail.getOperateType()));
         }
 
         UpdateWrapper<ExamTask> updateWrapper = new UpdateWrapper<>();
-        updateWrapper.lambda().set(ExamTask::getStatus, ExamStatusEnum.valueOf(examTaskDetail.getOperateType())).set(ExamTask::getReviewStatus, null).eq(ExamTask::getId, examTask.getId());
+        updateWrapper.lambda()
+                .set(ExamTask::getStatus, examTask.getStatus())
+                .set(ExamTask::getUpdateId, sysUser.getId())
+                .set(ExamTask::getUpdateTime, System.currentTimeMillis())
+                .set(ExamTask::getReviewStatus, null)
+                .eq(ExamTask::getId, examTask.getId());
         this.update(updateWrapper);
 
         QueryWrapper<ExamTaskDetail> queryWrapper = new QueryWrapper<>();
@@ -644,11 +840,13 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
             examTaskDetail.setId(detail.getId());
             // 已曝光试卷和未曝光试卷赋值
             examTaskDetail.setExposedPaperType(detail.getExposedPaperType());
-            examTaskDetail.setUnexposedPaperType(detail.getUnexposedPaperType());
+            examTaskDetail.setUnexposedPaperType(examTaskDetail.getPaperType());
         } else {
             // 已曝光试卷和未曝光试卷赋值(新增时,已曝光试卷为null,未曝光试卷为paper_type)
             examTaskDetail.setUnexposedPaperType(examTaskDetail.getPaperType());
         }
+        examTaskDetail.setUpdateId(sysUser.getId());
+        examTaskDetail.setUpdateTime(System.currentTimeMillis());
 
         return examTaskDetailService.saveOrUpdate(examTaskDetail);
     }
@@ -665,7 +863,12 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
             /*if (!task.getStatus().name().equals(ExamStatusEnum.FINISH.name())) {
                 throw ExceptionResultEnum.ERROR.exception("命题任务状态为已完成,才能撤回");
             }*/
-            updateWrapper.lambda().set(ExamTask::getStatus, examTask.getStatus()).eq(ExamTask::getId, examTask.getId());
+            updateWrapper.lambda().set(ExamTask::getStatus, ExamStatusEnum.STAGE).eq(ExamTask::getId, examTask.getId());
+            return this.update(updateWrapper);
+        }
+        // 重新申请
+        else if (examTask.getStatus().name().equals(ExamStatusEnum.STAGE.name())) {
+            updateWrapper.lambda().set(ExamTask::getStatus, ExamStatusEnum.STAGE).set(ExamTask::getReviewStatus, null).eq(ExamTask::getId, examTask.getId());
             return this.update(updateWrapper);
         }
         return false;
@@ -722,24 +925,50 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
         String paperAttachmentIds = examTaskDetail.getPaperAttachmentIds();
         List<JSONObject> jsonObjectList = JSONObject.parseArray(paperAttachmentIds, JSONObject.class);
         // 本地保存目录
-        String rootPath = SystemConstant.DOWNLOAD_TEMP + File.separator + schoolId + File.separator + examTaskDetail.getId();
+        String rootPath = SystemConstant.TEMP_FILES_DIR + File.separator + schoolId + File.separator + examTaskDetail.getId();
         List<File> fileList = new ArrayList<>();
         // 试卷
         for (JSONObject jsonObject : jsonObjectList) {
-            Long id = jsonObject.getLongValue("attachmentId");
-            BasicAttachment attachment = basicAttachmentService.getById(id);
-            if (attachment == null) {
-                throw ExceptionResultEnum.ERROR.exception("附件数据异常");
+            String id = jsonObject.get("attachmentId").toString();
+            String name = jsonObject.get("name").toString();
+            if (StringUtils.isNotBlank(id)) {
+                BasicAttachment attachment = basicAttachmentService.getById(id);
+                if (attachment == null) {
+                    throw ExceptionResultEnum.ERROR.exception("附件数据异常");
+                }
+                String fileName = attachment.getName() + "-" + name + attachment.getType();
+                File file = commonService.copyFile(rootPath, fileName, attachment);
+                fileList.add(file);
             }
-            File file = commonService.copyFile(rootPath, attachment);
-            fileList.add(file);
         }
 
-        // 题卡 todo
-//        Long cardId = examTaskDetail.getCardId();
-//        if (cardId != null){
-//
-//        }
+        // 题卡
+        Long cardId = examTaskDetail.getCardId();
+        if (cardId != null) {
+            ExamCard examCard = examCardService.getById(cardId);
+            // 通用模板
+            if (MakeMethodEnum.SELECT.equals(examCard.getMakeMethod())) {
+                if (examCard.getTemplateId() != null) {
+                    BasicTemplate basicTemplate = basicTemplateService.getById(examCard.getTemplateId());
+                    if (basicTemplate == null) {
+                        throw ExceptionResultEnum.ERROR.exception("题卡文件异常");
+                    }
+                    BasicAttachment attachment = basicAttachmentService.getById(basicTemplate.getAttachmentId());
+                    String fileName = attachment.getName() + attachment.getType();
+                    File file = commonService.copyFile(rootPath, fileName, attachment);
+                    fileList.add(file);
+                }
+            }
+            // 自制题卡或者客服制卡
+            else {
+                ExamCardDetail examCardDetail = examCardDetailService.getByCardId(cardId);
+                if (StringUtils.isBlank(examCardDetail.getHtmlContent())) {
+                    throw ExceptionResultEnum.ERROR.exception("题卡内容有误");
+                }
+                File file = basicAttachmentService.saveAttachmentHtml(rootPath, examCard.getTitle() + ".html", examCardDetail.getHtmlContent());
+                fileList.add(file);
+            }
+        }
         if (fileList.size() == 0) {
             throw ExceptionResultEnum.ERROR.exception("没有可导出文件");
         }
@@ -760,36 +989,45 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
     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);
+        // 印刷任务状态为印刷中(PRINTING),考场状态为待打印(WAITING)
+        IPage<ClientExamTaskDto> examTaskDtoIPage = this.baseMapper.listClientExamTaskPage(page, schoolId, machineCode, printPlanId, courseCode, paperNumber, isTry, isPass, orgIds, PrintPlanStatusEnum.PRINTING.name(), ExamDetailStatusEnum.WAITING.name());
+        return examTaskDtoIPage;
+    }
+
+    @Override
+    public List<ClientExamTaskDto> listTryTask(Long schoolId, String machineCode, Long orgId, Long printPlanId, String courseCode, String paperNumber, Boolean isTry, Boolean isPass) {
+        Set<Long> orgIds = commonService.listSubOrgIds(orgId);
+        // 印刷任务状态为印刷中(PRINTING),考场状态为待打印(WAITING)
+        List<ClientExamTaskDto> examTaskDtoIPage = this.baseMapper.listClientExamTaskPage(schoolId, machineCode, printPlanId, courseCode, paperNumber, isTry, isPass, orgIds, PrintPlanStatusEnum.PRINTING.name(), ExamDetailStatusEnum.WAITING.name());
         return examTaskDtoIPage;
     }
 
     @Transactional
     @Override
-    public void verifyCourseCodeByPaperNumber(Long schoolId,String paperNumber, String courseCode) {
+    public void verifyCourseCodeByPaperNumber(Long schoolId, String paperNumber, String courseCode) {
         List<ExamTask> examTaskList = this.list(new QueryWrapper<ExamTask>().lambda()
-                .eq(ExamTask::getPaperNumber,paperNumber).eq(ExamTask::getSchoolId,schoolId));
-        if (examTaskList.size() > 1){
-            throw ExceptionResultEnum.ERROR.exception("异常 : 有多条命题任务记录 schoolId = " + schoolId + " paperNumber = " + paperNumber);
-        }else if (examTaskList.size() == 1){
+                .eq(ExamTask::getPaperNumber, paperNumber).eq(ExamTask::getSchoolId, schoolId));
+        if (examTaskList.size() > 1) {
+            throw ExceptionResultEnum.ERROR.exception("异常 :[试卷编号]" + paperNumber + "有多条命题任务记录");
+        } else if (examTaskList.size() == 1) {
             ExamTask examTask = examTaskList.get(0);
-            if (!courseCode.equals(examTask.getCourseCode())){
-                throw ExceptionResultEnum.ERROR.exception("要导入的考务数据的试卷编号在命题任务中已存在,但该试卷编号对应的考务数据课程代码和命题任务中的课程代码不匹配  试卷编号 : " + paperNumber);
+            if (!courseCode.equals(examTask.getCourseCode())) {
+                throw ExceptionResultEnum.ERROR.exception("要导入的考务数据的试卷编号在命题任务中已存在,但该试卷编号对应的考务数据课程代码和命题任务中的课程代码不匹配  [试卷编号] : " + paperNumber);
             }
         }
     }
 
     @Override
-    public void checkDataByExamination(Long examDetailId,SysUser user) throws IOException {
+    public void checkDataByExamination(Long examDetailId, SysUser user) throws IOException {
         boolean judge = true;
         ExamDetail examDetail = examDetailService.getById(examDetailId);
-        if (Objects.isNull(examDetail)){
+        if (Objects.isNull(examDetail)) {
             throw ExceptionResultEnum.ERROR.exception("考务-考场不存在");
         }
         List<ExamDetailCourse> examDetailCourseList = examDetailCourseService.list(new QueryWrapper<ExamDetailCourse>().lambda()
-                .eq(ExamDetailCourse::getExamDetailId,examDetailId)
-                .eq(ExamDetailCourse::getSchoolId,examDetail.getSchoolId()));
-        if (examDetailCourseList.size() < 1){
+                .eq(ExamDetailCourse::getExamDetailId, examDetailId)
+                .eq(ExamDetailCourse::getSchoolId, examDetail.getSchoolId()));
+        if (examDetailCourseList.size() < 1) {
             throw ExceptionResultEnum.ERROR.exception("考务-课程不存在");
         }
         for (ExamDetailCourse examDetailCourse : examDetailCourseList) {
@@ -797,16 +1035,16 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
             String paperNumber = examDetailCourse.getPaperNumber();
             Long schoolId = examDetailCourse.getSchoolId();
             ExamTask examTask = this.getOne(new QueryWrapper<ExamTask>().lambda()
-                    .eq(ExamTask::getSchoolId,schoolId)
-                    .eq(ExamTask::getCourseCode,courseCode)
-                    .eq(ExamTask::getPaperNumber,paperNumber));
-            if (examTask == null){
+                    .eq(ExamTask::getSchoolId, schoolId)
+                    .eq(ExamTask::getCourseCode, courseCode)
+                    .eq(ExamTask::getPaperNumber, paperNumber));
+            if (examTask == null) {
                 judge = false;
-            }else if (!ExamStatusEnum.FINISH.equals(examTask.getStatus())){
+            } else if (!ExamStatusEnum.FINISH.equals(examTask.getStatus())) {
                 judge = false;
             }
         }
-        if (judge){
+        if (judge) {
             Map<String, Object> map = tbTaskService.saveTask(TaskTypeEnum.CREATE_PDF, examDetail.getPrintPlanId(), user);
             if (Objects.nonNull(examDetail.getId())) {
                 map.computeIfAbsent("examDetailId", v -> examDetail.getId());
@@ -815,4 +1053,18 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
             asyncCreatePdfTempleteService.createPdf(map, null);
         }
     }
+
+    @Override
+    public List<ExamTask> listExamTaskByCardId(Long cardId) {
+        return this.baseMapper.listExamTaskByCardId(cardId);
+    }
+
+    @Override
+    public ReviewSampleDto findReviewSampleInfoByExamTaskId(Long examTaskId) {
+        List<ReviewSampleDto> reviewSampleDtoList = examTaskMapper.listReviewSampleInfoByExamTaskId(examTaskId);
+        if (reviewSampleDtoList.size() != 1){
+            throw ExceptionResultEnum.ERROR.exception("不能找到所选命题任务[" + examTaskId + "]的审核样本信息");
+        }
+        return reviewSampleDtoList.get(0);
+    }
 }

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

@@ -5,24 +5,29 @@ import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.google.gson.Gson;
+import com.qmth.boot.api.exception.ApiException;
 import com.qmth.distributed.print.business.bean.dto.BlurryUserDto;
 import com.qmth.distributed.print.business.bean.dto.LoginDto;
 import com.qmth.distributed.print.business.bean.dto.UserDto;
+import com.qmth.distributed.print.business.bean.params.UserSaveParams;
 import com.qmth.distributed.print.business.entity.*;
+import com.qmth.distributed.print.business.enums.FieldUniqueEnum;
 import com.qmth.distributed.print.business.enums.RoleTypeEnum;
 import com.qmth.distributed.print.business.mapper.SysUserMapper;
 import com.qmth.distributed.print.business.service.*;
 import com.qmth.distributed.print.business.util.ServletUtil;
-import com.qmth.distributed.print.business.util.security.Md5Utils;
-import com.qmth.distributed.print.common.contant.SystemConstant;
 import com.qmth.distributed.print.common.enums.ExceptionResultEnum;
+import com.qmth.distributed.print.common.util.ResultUtil;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.dao.DuplicateKeyException;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import sun.misc.BASE64Encoder;
 
 import javax.annotation.Resource;
+import java.security.NoSuchAlgorithmException;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -55,21 +60,21 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
     @Autowired
     private SysRolePrivilegeService sysRolePrivilegeService;
 
-    @Resource
-    SysUserMapper sysUserMapper;
-
     @Autowired
     CacheService cacheService;
 
     @Autowired
     private CommonService commonService;
 
+    @Resource
+    SysUserService sysUserService;
+
     @Override
-    public IPage<UserDto> list(String realName, String roleId, Boolean enable, Integer pageNumber, Integer pageSize) {
+    public IPage<UserDto> list(String loginName, String roleId, Boolean enable, Integer pageNumber, Integer pageSize) {
         Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
 
         Page<UserDto> page = new Page<>(pageNumber, pageSize);
-        IPage<UserDto> userDtoIPage = this.baseMapper.listPage(page, schoolId, realName, roleId, enable);
+        IPage<UserDto> userDtoIPage = this.baseMapper.listPage(page, schoolId, loginName, roleId, enable);
         if (userDtoIPage.getRecords().size() > 0) {
             userDtoIPage.getRecords().forEach(m -> {
                 //角色
@@ -84,105 +89,44 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
         return userDtoIPage;
     }
 
-
     @Transactional
     @Override
-    public boolean saveUser(SysUser user) {
-        Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
-        user.setSchoolId(schoolId);
-        SysUser sysUser1 = (SysUser) ServletUtil.getRequestUser();
-
-        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
-        queryWrapper.lambda().eq(SysUser::getLoginName, user.getLoginName());
-        SysUser sysUser = this.getOne(queryWrapper);
-        boolean isSuccess;
-        // 新增
-        if (Objects.isNull(user.getId())) {
-            if (sysUser != null) {
-                throw ExceptionResultEnum.ERROR.exception("用户名已存在");
-            }
-            SysConfig sysConfig = sysConfigService.getByKey("sys.user.initPassword");
-            BASE64Encoder encoder = new BASE64Encoder();
-            user.setPassword(encoder.encode(StringUtils.isNoneBlank(sysConfig.getConfigValue()) ? sysConfig.getConfigValue().getBytes() : "123456".getBytes()));
-            user.setId(SystemConstant.getDbUuid());
-            user.setCreateId(sysUser1.getId());
-            user.setCreateTime(System.currentTimeMillis());
-            isSuccess = this.save(user);
-        }
-        // 修改
-        else {
-            if (sysUser != null && user.getId().longValue() != sysUser.getId().longValue()) {
-                throw ExceptionResultEnum.ERROR.exception("用户名已存在");
-            }
-            sysUser.setRealName(user.getRealName());
-            sysUser.setMobileNumber(user.getMobileNumber());
-            sysUser.setOrgId(user.getOrgId());
-            sysUser.setUpdateId(sysUser1.getId());
-            sysUser.setUpdateTime(System.currentTimeMillis());
-            isSuccess = this.updateById(sysUser);
-
-            //删除角色
-            UpdateWrapper<SysUserRole> updateWrapper = new UpdateWrapper<>();
-            updateWrapper.lambda().eq(SysUserRole::getUserId, sysUser.getId());
-
-            //删除课程
-            basicUserCourseService.removeByUserId(sysUser.getId());
-
-            sysUserRoleService.remove(updateWrapper);
-        }
-
-        //新增用户-角色
-        for (Long roleId : user.getRoleIds()) {
-            List<SysRolePrivilege> rolePrivileges = sysRolePrivilegeService.listByRoleId(roleId);
-            for (SysRolePrivilege rolePrivilege : rolePrivileges) {
-                SysUserRole userRole = new SysUserRole();
-                userRole.setUserId(user.getId());
-                userRole.setRoleId(roleId);
-                userRole.setPrivilegeId(rolePrivilege.getPrivilegeId());
-                sysUserRoleService.save(userRole);
-            }
-            cacheService.removeRolePrivilegeCache(roleId);
-        }
-
-        // 角色里是否有考务老师角色
-        List<SysRole> sysRoles = sysRoleService.list(user.getRoleIds(), RoleTypeEnum.QUESTION_TEACHER.name());
-        if (sysRoles != null && sysRoles.size() > 0) {
-            Long[] courseIds = user.getCourseIds();
-            if (courseIds.length == 0) {
-                throw ExceptionResultEnum.ERROR.exception("请选择课程");
-            }
-
-            basicUserCourseService.saveBatch(user);
-
-        }
-
-        // 清除缓存
-        cacheService.removeUserAuthCache(user.getId());
-
-        return isSuccess;
+    public boolean saveUser(UserSaveParams userSaveParams) {
+        return saveUserCommon(userSaveParams);
     }
 
     @Override
-    public boolean enable(SysUser user) {
+    public boolean enable(SysUser user) throws NoSuchAlgorithmException {
         UpdateWrapper<SysUser> updateWrapper = new UpdateWrapper<>();
         updateWrapper.lambda().set(SysUser::getEnable, user.getEnable()).eq(SysUser::getId, user.getId());
-        return this.update(updateWrapper);
+
+        boolean success = this.update(updateWrapper);
+        //如果状态为禁用,需要踢下线重新登录
+        if (!user.getEnable()) {
+            commonService.removeUserInfo(user.getId());
+        }
+        return success;
     }
 
     @Override
-    public boolean resetPassword(Long id) {
+    public boolean resetPassword(Long id) throws NoSuchAlgorithmException {
         SysConfig sysConfig = sysConfigService.getByKey("sys.user.initPassword");
         BASE64Encoder encoder = new BASE64Encoder();
         String md5Password = encoder.encode(StringUtils.isNoneBlank(sysConfig.getConfigValue()) ? sysConfig.getConfigValue().getBytes() : "123456".getBytes());
 
         SysUser user = this.getById(id);
+        String oldPassword = user.getPassword();
         user.setPassword(md5Password);
 
+        //如果原密码和旧密码不一致,需要重新登录
+        if (!Objects.equals(user.getPassword(), oldPassword)) {
+            commonService.removeUserInfo(user.getId());
+        }
         return this.updateById(user);
     }
 
     @Override
-    public boolean updatePassword(SysUser user) {
+    public boolean updatePassword(SysUser user) throws NoSuchAlgorithmException {
         SysUser sysUser = this.getById(user.getId());
         if (sysUser == null) {
             throw ExceptionResultEnum.ERROR.exception("用户不存在");
@@ -191,7 +135,12 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
             throw ExceptionResultEnum.ERROR.exception("原密码不正确");
         }
         sysUser.setPassword(user.getPassword());
-        return this.updateById(sysUser);
+        boolean success = this.updateById(sysUser);
+        //如果原密码和旧密码不一致,需要重新登录
+        if (!Objects.equals(user.getOldPassword(), sysUser.getPassword())) {
+            commonService.removeUserInfo(sysUser.getId());
+        }
+        return success;
     }
 
     @Transactional
@@ -269,64 +218,8 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
 
     @Transactional
     @Override
-    public boolean saveCustomer(SysUser user) {
-        SysUser sysUser1 = (SysUser) ServletUtil.getRequestUser();
-
-        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
-        queryWrapper.lambda().eq(SysUser::getLoginName, user.getLoginName());
-        SysUser sysUser = this.getOne(queryWrapper);
-        boolean isSuccess;
-        // 新增
-        if (Objects.isNull(user.getId())) {
-            if (sysUser != null) {
-                throw ExceptionResultEnum.ERROR.exception("用户名已存在");
-            }
-            SysConfig sysConfig = sysConfigService.getByKey("sys.user.initPassword");
-            BASE64Encoder encoder = new BASE64Encoder();
-            user.setPassword(encoder.encode(StringUtils.isNoneBlank(sysConfig.getConfigValue()) ? sysConfig.getConfigValue().getBytes() : "123456".getBytes()));
-            user.setId(SystemConstant.getDbUuid());
-            user.setCreateId(sysUser1.getId());
-            user.setCreateTime(System.currentTimeMillis());
-            isSuccess = this.save(user);
-        }
-        // 修改
-        else {
-            if (sysUser != null && user.getId().longValue() != sysUser.getId().longValue()) {
-                throw ExceptionResultEnum.ERROR.exception("用户名已存在");
-            }
-            sysUser.setRealName(user.getRealName());
-            sysUser.setMobileNumber(user.getMobileNumber());
-            sysUser.setUpdateId(sysUser1.getId());
-            sysUser.setUpdateTime(System.currentTimeMillis());
-            isSuccess = this.updateById(sysUser);
-
-            //删除角色
-            UpdateWrapper<SysUserRole> updateWrapper = new UpdateWrapper<>();
-            updateWrapper.lambda().eq(SysUserRole::getUserId, sysUser.getId());
-            sysUserRoleService.remove(updateWrapper);
-        }
-
-        //新增用户-角色
-        for (Long roleId : user.getRoleIds()) {
-            SysRole sysRole = sysRoleService.getById(roleId);
-            if(!RoleTypeEnum.CUSTOMER.name().equals(sysRole.getType().name())){
-                throw ExceptionResultEnum.ERROR.exception("只能添加客服角色的用户");
-            }
-            List<SysRolePrivilege> rolePrivileges = sysRolePrivilegeService.listByRoleId(roleId);
-            for (SysRolePrivilege rolePrivilege : rolePrivileges) {
-                SysUserRole userRole = new SysUserRole();
-                userRole.setUserId(user.getId());
-                userRole.setRoleId(roleId);
-                userRole.setPrivilegeId(rolePrivilege.getPrivilegeId());
-                sysUserRoleService.save(userRole);
-            }
-            cacheService.removeRolePrivilegeCache(roleId);
-        }
-
-        // 清除缓存
-        cacheService.removeUserAuthCache(user.getId());
-
-        return isSuccess;
+    public boolean saveCustomer(UserSaveParams userSaveParams) {
+        return saveUserCommon(userSaveParams);
     }
 
     @Override
@@ -346,4 +239,81 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
         }
         return userDtoIPage;
     }
+
+    /**
+     * 保存用户公用
+     *
+     * @param userSaveParams
+     * @return
+     */
+    public boolean saveUserCommon(UserSaveParams userSaveParams) {
+        boolean isSuccess = true;
+        try {
+            Long schoolId = Objects.nonNull(ServletUtil.getRequestHeaderSchoolIdByNotVaild()) ? Long.valueOf(ServletUtil.getRequestHeaderSchoolIdByNotVaild().toString()) : null;
+            SysUser requestUser = (SysUser) ServletUtil.getRequestUser();
+            Gson gson = new Gson();
+            userSaveParams.setSchoolId(schoolId);
+            SysUser sysUser = gson.fromJson(gson.toJson(userSaveParams), SysUser.class);
+            if (Objects.isNull(sysUser.getId())) {//新增用户
+                sysUser.setInsertInfo(requestUser.getId());
+                sysUserService.save(sysUser);
+                for (Long roleId : userSaveParams.getRoleIds()) {
+                    commonService.addUserRolePrivilege(sysUser, roleId);
+                }
+            } else {//修改用户
+                List<SysUserRole> sysUserRoleList = cacheService.userRolePrivilegeCache(sysUser.getId());
+                List<Long> userRolesList = Arrays.asList(userSaveParams.getRoleIds());
+                Set<Long> dbUserRolesList = sysUserRoleList.stream().map(SysUserRole::getRoleId).collect(Collectors.toSet());
+                int count = (int) dbUserRolesList.stream().filter(s -> userRolesList.contains(s)).count();
+                SysUser dbUser = sysUserService.getById(sysUser.getId());
+                sysUser.setUpdateInfo(requestUser.getId());
+                sysUserService.updateById(sysUser);
+                if (count == 0 || dbUserRolesList.size() != userRolesList.size()) {
+                    QueryWrapper<SysUserRole> sysUserRoleQueryWrapper = new QueryWrapper<>();
+                    sysUserRoleQueryWrapper.lambda().eq(SysUserRole::getUserId, sysUser.getId());
+                    sysUserRoleService.remove(sysUserRoleQueryWrapper);
+
+                    cacheService.removeUserRolePrivilegeCache(sysUser.getId());
+                    for (Long roleId : userSaveParams.getRoleIds()) {
+                        commonService.addUserRolePrivilege(sysUser, roleId);
+                    }
+                }
+                //如果修改了角色,需要重新登录
+                if (count == 0 || dbUserRolesList.size() != userRolesList.size()) {
+                    commonService.removeUserInfo(sysUser.getId());
+                }
+                //如果修改了机构,需更新用户缓存
+                if (dbUser.getOrgId().longValue() != sysUser.getOrgId().longValue()) {
+                    cacheService.updateUserCache(sysUser.getId());
+                    cacheService.updateUserAuthCache(sysUser.getId());
+                }
+            }
+            //用户科目全量删除全量增加
+            QueryWrapper<BasicUserCourse> basicUserCourseQueryWrapper = new QueryWrapper<>();
+            basicUserCourseQueryWrapper.lambda().eq(BasicUserCourse::getUserId, sysUser.getId());
+            basicUserCourseService.remove(basicUserCourseQueryWrapper);
+
+            List<SysRole> sysRoles = sysRoleService.list(sysUser.getRoleIds(), RoleTypeEnum.QUESTION_TEACHER.name());
+            if (sysRoles != null && sysRoles.size() > 0) {
+                Long[] courseIds = sysUser.getCourseIds();
+                if (courseIds.length == 0) {
+                    throw ExceptionResultEnum.ERROR.exception("请选择课程");
+                }
+                basicUserCourseService.saveBatch(sysUser);
+            }
+        } catch (Exception e) {
+            log.error("请求出错", e);
+            isSuccess = false;
+            if (e instanceof DuplicateKeyException) {
+                String errorColumn = e.getCause().toString();
+                String columnStr = errorColumn.substring(errorColumn.lastIndexOf("key") + 3, errorColumn.length()).replaceAll("'", "");
+                throw ExceptionResultEnum.SQL_ERROR.exception("[" + FieldUniqueEnum.convertToTitle(columnStr) + "]数据不允许重复插入");
+            } else if (e instanceof ApiException) {
+                ResultUtil.error((ApiException) e, e.getMessage());
+            } else {
+                ResultUtil.error(e.getMessage());
+            }
+        }
+        return isSuccess;
+    }
 }

+ 3 - 2
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/TBTaskServiceImpl.java

@@ -251,6 +251,7 @@ public class TBTaskServiceImpl extends ServiceImpl<TBTaskMapper, TBTask> impleme
      * 查询任务列表
      *
      * @param iPage
+     * @param schoolId
      * @param printPlanId
      * @param status
      * @param type
@@ -258,8 +259,8 @@ public class TBTaskServiceImpl extends ServiceImpl<TBTaskMapper, TBTask> impleme
      * @return
      */
     @Override
-    public IPage<TaskListResult> query(IPage<Map> iPage, Long printPlanId, TaskStatusEnum status, TaskTypeEnum type, TaskResultEnum result) {
-        return tbTaskMapper.query(iPage, printPlanId, Objects.nonNull(status) ? status.name() : null, Objects.nonNull(type) ? type.name() : null, Objects.nonNull(result) ? result.name() : null);
+    public IPage<TaskListResult> query(IPage<Map> iPage, Long schoolId, Long printPlanId, TaskStatusEnum status, TaskTypeEnum type, TaskResultEnum result) {
+        return tbTaskMapper.query(iPage, schoolId,printPlanId, Objects.nonNull(status) ? status.name() : null, Objects.nonNull(type) ? type.name() : null, Objects.nonNull(result) ? result.name() : null);
     }
 
     /**

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

@@ -44,7 +44,7 @@ public class AsyncExaminationExportTemplateService extends AsyncExportTaskTemple
             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"));
+            String path = String.valueOf(result.get(SystemConstant.PATH));
             System.out.println("path = " + path);
             tbTask.setImportFileName(TaskTypeEnum.EXAMINATION_EXPORT.getTitle());
             tbTask.setResultFilePath(path);

+ 7 - 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.entity.TBTask;
 import com.qmth.distributed.print.business.enums.TaskResultEnum;
 import com.qmth.distributed.print.business.enums.TaskStatusEnum;
 import com.qmth.distributed.print.business.service.ExamTaskService;
+import com.qmth.distributed.print.business.templete.callback.CallbackCreatePdf;
 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;
@@ -44,7 +45,7 @@ public class AsyncExaminationImportTemplateService extends AsyncImportTaskTemple
     public Result importTask(Map<String, Object> map) throws Exception {
         TBTask tbTask = (TBTask) map.get(SystemConstant.TASK);
         InputStream inputStream = super.getUploadFileInputStream(tbTask);
-        map.put("inputStream",inputStream);
+        map.put("inputStream", inputStream);
 
         StringJoiner stringJoinerSummary = new StringJoiner("\n")
                 .add(MessageFormat.format("{0}{1}{2}", FORMAT_TIME, BEGIN_TITLE, OBJ_TITLE));
@@ -52,10 +53,12 @@ public class AsyncExaminationImportTemplateService extends AsyncImportTaskTemple
 
         try {
             TaskLogicService taskLogicService = SpringContextHolder.getBean(TaskLogicService.class);
-            Map<String,Object> result = taskLogicService.executeImportExaminationLogic(map);
+
+            // 执行导入考务数据
+            Map<String, Object> result = taskLogicService.executeImportExaminationLogic(map);
 
             // 检测是否去生成pdf
-            if (Objects.isNull(map.get("examDetailIdList"))){
+            if (Objects.isNull(map.get("examDetailIdList"))) {
                 throw ExceptionResultEnum.ERROR.exception("不能获取考务-场次id集合");
             }
             List<Long> examDetailIdList = (List<Long>) map.get("examDetailIdList");
@@ -67,7 +70,7 @@ public class AsyncExaminationImportTemplateService extends AsyncImportTaskTemple
 
             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);
-        }catch (Exception e){
+        } 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);

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

@@ -7,9 +7,8 @@ import com.alibaba.fastjson.JSONObject;
 import com.aliyun.oss.common.utils.BinaryUtil;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.qmth.boot.api.exception.ApiException;
-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.PdfDto;
+import com.qmth.distributed.print.business.annotation.ExcelDBFieldDesc;
+import com.qmth.distributed.print.business.bean.dto.*;
 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.*;
@@ -24,7 +23,6 @@ import com.qmth.distributed.print.common.contant.SystemConstant;
 import com.qmth.distributed.print.common.enums.ExceptionResultEnum;
 import com.qmth.distributed.print.common.util.FileUtil;
 import com.qmth.distributed.print.common.util.HexUtils;
-import com.qmth.distributed.print.common.util.JacksonUtil;
 import com.qmth.distributed.print.common.util.ResultUtil;
 import org.apache.commons.codec.digest.DigestUtils;
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
@@ -43,10 +41,10 @@ import org.springframework.util.FileCopyUtils;
 
 import javax.annotation.Resource;
 import java.io.*;
+import java.lang.reflect.Field;
 import java.time.LocalDateTime;
 import java.util.*;
 import java.util.stream.Collectors;
-import java.util.stream.Stream;
 
 /**
  * @Description: 任务处理逻辑impl
@@ -110,6 +108,8 @@ public class TaskLogicServiceImpl implements TaskLogicService {
     @Resource
     RedisTemplate<String, Object> redisTemplate;
 
+    @Resource
+    BasicExamRuleService basicExamRuleService;
 
     /**
      * 创建pdf逻辑
@@ -125,6 +125,7 @@ public class TaskLogicServiceImpl implements TaskLogicService {
             TBTask tbTask = (TBTask) map.get(SystemConstant.TASK);
             SysUser sysUser = (SysUser) map.get(SystemConstant.USER);
             Long examDetailId = Objects.nonNull(map.get("examDetailId")) ? (Long) map.get("examDetailId") : null;
+            List<Long> examDetailIds = Objects.nonNull(map.get("examDetailIds")) ? (List<Long>) map.get("examDetailIds") : null;
             Long schoolId = (Long) map.get("schoolId");
             List<Long> examDetailCourseIds = Objects.nonNull(map.get("examDetailCourseIds")) ? (List<Long>) map.get("examDetailCourseIds") : null;
             String paperTypeParam = Objects.nonNull(map.get("paperType")) ? (String) map.get("paperType") : null;
@@ -141,6 +142,11 @@ public class TaskLogicServiceImpl implements TaskLogicService {
             }
 
             BasicSchool basicSchool = cacheService.schoolCache(examPrintPlan.getSchoolId());
+            schoolId = Objects.isNull(schoolId) ? basicSchool.getId() : schoolId;
+            BasicExamRule basicExamRule = basicExamRuleService.getBySchoolId(schoolId);
+            if (Objects.isNull(basicExamRule)) {
+                throw ExceptionResultEnum.ERROR.exception("考务规则为空");
+            }
 
             //查询examDetail
             QueryWrapper<ExamDetail> examDetailQueryWrapper = new QueryWrapper<>();
@@ -148,6 +154,8 @@ public class TaskLogicServiceImpl implements TaskLogicService {
                     .eq(ExamDetail::getPrintPlanId, tbTask.getPrintPlanId());
             if (Objects.nonNull(examDetailId)) {
                 examDetailQueryWrapper.lambda().eq(ExamDetail::getId, examDetailId);
+            } else if (Objects.nonNull(examDetailIds)) {
+                examDetailQueryWrapper.lambda().in(ExamDetail::getId, examDetailIds);
             }
             List<ExamDetail> examDetailList = detailService.list(examDetailQueryWrapper);
             if (Objects.isNull(examDetailList) || examDetailList.size() == 0) {
@@ -156,6 +164,7 @@ public class TaskLogicServiceImpl implements TaskLogicService {
             attachmentIds = Objects.isNull(attachmentIds) ? attachmentIds = new HashSet<>() : attachmentIds;
             ftlList = Objects.isNull(ftlList) ? ftlList = new HashSet<>() : ftlList;
             for (ExamDetail examDetail : examDetailList) {
+                tbTask.setObjName(examDetail.getExamRoom() + "-" + examDetail.getExamPlace());
                 //查询examDetailCourse
                 QueryWrapper<ExamDetailCourse> examDetailCourseQueryWrapper = new QueryWrapper<>();
                 if (Objects.nonNull(examDetailCourseIds) && examDetailCourseIds.size() > 0) {
@@ -172,18 +181,20 @@ public class TaskLogicServiceImpl implements TaskLogicService {
                     List<PdfDto> backupPaperPdfList = new ArrayList<>();//备份试卷
                     List<PdfDto> cardPdfList = new ArrayList<>();//备份题卡
 
-                    if (Objects.nonNull(examPrintPlan.getOrdinaryContent())) {
-                        //获取普通印品
-                        JSONArray jsonArrayOrdinary = JSONArray.parseArray(examPrintPlan.getOrdinaryContent());
-                        for (int i = 0; i < jsonArrayOrdinary.size(); i++) {
-                            JSONObject jsonObjectOrdinary = jsonArrayOrdinary.getJSONObject(i);
-                            Long attachmentId = Long.parseLong((String) jsonObjectOrdinary.get("attachmentId"));
-                            BasicAttachment basicAttachment = basicAttachmentService.getById(attachmentId);
-                            createPdfUtil.createCheckIn(basicAttachment, ordinaryPdfList, (Integer) jsonObjectOrdinary.get("backupCount"));
+                    for (ExamDetailCourse examDetailCourse : examDetailCourseList) {
+                        if (Objects.nonNull(examPrintPlan.getOrdinaryContent())) {
+                            //获取普通印品
+                            JSONArray jsonArrayOrdinary = JSONArray.parseArray(examPrintPlan.getOrdinaryContent());
+                            for (int i = 0; i < jsonArrayOrdinary.size(); i++) {
+                                JSONObject jsonObjectOrdinary = jsonArrayOrdinary.getJSONObject(i);
+                                if (Objects.nonNull(jsonObjectOrdinary.get("attachmentId")) && !Objects.equals("", jsonObjectOrdinary.get("attachmentId"))) {
+                                    Long attachmentId = Long.parseLong((String) jsonObjectOrdinary.get("attachmentId"));
+                                    BasicAttachment basicAttachment = basicAttachmentService.getById(attachmentId);
+                                    createPdfUtil.createCheckIn(examDetail, basicAttachment, ordinaryPdfList, (Integer) jsonObjectOrdinary.get("backupCount"));
+                                }
+                            }
                         }
-                    }
 
-                    for (ExamDetailCourse examDetailCourse : examDetailCourseList) {
                         List<PdfDto> paperPdfTempList = new ArrayList<>();//所有试卷
                         List<PdfDto> examStudentTempPdfList = new ArrayList<>();//所有题卡
                         List<PdfDto> backupPaperTempPdfList = new ArrayList<>();//备份试卷
@@ -196,7 +207,8 @@ public class TaskLogicServiceImpl implements TaskLogicService {
                                 .eq(ExamTask::getCourseName, examDetailCourse.getCourseName())
                                 .eq(ExamTask::getPaperNumber, examDetailCourse.getPaperNumber())
                                 .eq(ExamTask::getEnable, true)
-                                .eq(ExamTask::getStatus, ExamStatusEnum.FINISH);
+                                .eq(ExamTask::getStatus, ExamStatusEnum.FINISH)
+                                .orderByAsc(ExamTask::getPaperNumber);
                         List<ExamTask> examTaskList = examTaskService.list(examTaskQueryWrapper);
                         if (Objects.isNull(examTaskList) || examTaskList.size() == 0) {
                             throw ExceptionResultEnum.ERROR.exception("命题任务为空");
@@ -220,12 +232,15 @@ public class TaskLogicServiceImpl implements TaskLogicService {
                             List<ExamCardDetail> examCardDetailList = examCardDetailService.list(examCardDetailQueryWrapper);
 
                             //抽取卷型
-                            String paperType = Objects.nonNull(paperTypeParam) ? paperTypeParam : createPdfUtil.getPaperType(examPrintPlan, examTaskDetail);
+                            String paperType = Objects.nonNull(paperTypeParam) ? paperTypeParam : createPdfUtil.getPaperType(examPrintPlan, examTaskDetail, examDetail, examDetailCourse);
                             examTaskDetail.setRelatePaperType(paperType);
+                            examDetailCourse.setPaperType(paperType);
+
+                            PaperPdfDto paperPdfDto = createPdfUtil.getPaperPdfFile(paperType, examTaskDetail);
 
                             //获取试卷pdf
-                            boolean tag = createPdfUtil.getPaperPdf(paperType, examTaskDetail, examPrintPlan.getBackupCount(), paperPdfTempList, backupPaperTempPdfList);
-                            paperPdfList.addAll(paperPdfTempList);
+                            PdfDto pdfDto = createPdfUtil.getPaperPdf(paperPdfDto, examPrintPlan.getBackupCount(), backupPaperTempPdfList);
+                            examDetailCourse.setPaperPagesA3(Objects.nonNull(pdfDto) ? pdfDto.getPageCount() : examDetailCourse.getPaperPagesA3());
                             backupPaperPdfList.addAll(backupPaperTempPdfList);
 
                             basicAttachmentList = Objects.isNull(basicAttachmentList) ? basicAttachmentList = new ArrayList<>() : basicAttachmentList;
@@ -237,7 +252,9 @@ public class TaskLogicServiceImpl implements TaskLogicService {
                                 String studentContent = cardContent;
 
                                 for (int i = 1; i <= examPrintPlan.getBackupCount(); i++) {
-                                    basicAttachmentList.add(createPdfUtil.cardHtml(cardContent, paperType, examDetail, examDetailCourse, examCard, jsonArray, sysUser.getId(), cardPdfTempList));
+                                    BasicAttachment basicAttachment = createPdfUtil.cardHtml(String.format("%02d", i), cardContent, examDetail, examDetailCourse, examCard, jsonArray, sysUser.getId(), cardPdfTempList);
+                                    examDetailCourse.setCardPagesA3(basicAttachment.getPages());
+                                    basicAttachmentList.add(basicAttachment);
                                 }
                                 cardPdfList.addAll(cardPdfTempList);
 
@@ -253,13 +270,17 @@ public class TaskLogicServiceImpl implements TaskLogicService {
                                     for (int i = 0; i < jsonArrayVariable.size(); i++) {
                                         JSONObject jsonObjectVariable = jsonArrayVariable.getJSONObject(i);
                                         String type = (String) jsonObjectVariable.get("type");
-                                        Long attachmentId = Long.parseLong((String) jsonObjectVariable.get("attachmentId"));
-                                        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(), examDetail, examDetailCourse, examStudentList, variablePdfList, (Integer) jsonObjectVariable.get("backupCount"));
-                                        } else if (Objects.nonNull(type) && Objects.equals(type.toUpperCase(), "PACKAGE")) {//卷袋贴
-                                            createPdfUtil.createPaperPackage(tag, basicAttachment, basicSchool.getName(), examDetail, examDetailCourse, examStudentList, variablePdfList, (Integer) jsonObjectVariable.get("backupCount"));
+                                        if (Objects.nonNull(jsonObjectVariable.get("attachmentId")) && !Objects.equals("", jsonObjectVariable.get("attachmentId"))) {
+                                            Long attachmentId = Long.parseLong((String) jsonObjectVariable.get("attachmentId"));
+                                            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(), examDetail, examDetailCourse, examStudentList, variablePdfList, (Integer) jsonObjectVariable.get("backupCount"));
+                                            } else if (Objects.nonNull(type) && Objects.equals(type.toUpperCase(), "PACKAGE")) {//卷袋贴
+                                                if (Objects.nonNull(pdfDto)) {
+                                                    createPdfUtil.createPaperPackage(pdfDto.isTag(), basicAttachment, basicSchool.getName(), examDetail, examDetailCourse, examStudentList, variablePdfList, (Integer) jsonObjectVariable.get("backupCount"));
+                                                }
+                                            }
                                         }
                                     }
                                 }
@@ -272,8 +293,12 @@ public class TaskLogicServiceImpl implements TaskLogicService {
                                 });
 
                                 for (ExamStudent t : examStudentList) {
-                                    basicAttachmentList.add(createPdfUtil.examStudentHtml(attachmentIds, studentContent, t, paperType, examCard, sysUser.getId(), examStudentTempPdfList));
+                                    if (Objects.nonNull(pdfDto)) {
+                                        createPdfUtil.getExamStudentPaperPdf(paperPdfDto, paperPdfTempList);
+                                    }
+                                    basicAttachmentList.add(createPdfUtil.examStudentHtml(attachmentIds, studentContent, t, examDetail, examDetailCourse, sysUser.getId(), examStudentTempPdfList));
                                 }
+                                paperPdfList.addAll(paperPdfTempList);
                                 examStudentPdfList.addAll(examStudentTempPdfList);
                                 examStudentService.saveOrUpdateBatch(examStudentList);
                                 jsonObject.put("card", jsonArray);
@@ -282,22 +307,19 @@ public class TaskLogicServiceImpl implements TaskLogicService {
                             examCardDetailService.saveOrUpdateBatch(examCardDetailList);
                         }
                         examTaskDetailService.saveOrUpdateBatch(examTaskDetailList);
-
-                        Integer paperPageA3 = 0;
-                        Integer cardPageA3 = 0;
-                        paperPageA3 = paperPageA3 + paperPdfTempList.stream().mapToInt(PdfDto::getPageCount).sum() + backupPaperTempPdfList.stream().mapToInt(PdfDto::getPageCount).sum();
-                        cardPageA3 = cardPageA3 + examStudentTempPdfList.stream().mapToInt(PdfDto::getPageCount).sum() + cardPdfTempList.stream().mapToInt(PdfDto::getPageCount).sum();
-                        examDetailCourse.setPaperPagesA3(paperPageA3);
-                        examDetailCourse.setCardPagesA3(cardPageA3);
                     }
                     detailCourseService.saveOrUpdateBatch(examDetailCourseList);
                     //合并pdf
-                    basicAttachmentList.add(createPdfUtil.mergePdf(tbTask, examDetail, sysUser.getId(), schoolId, variablePdfList, ordinaryPdfList, paperPdfList, examStudentPdfList, backupPaperPdfList, cardPdfList));
+                    basicAttachmentList.add(createPdfUtil.mergePdf(basicExamRule, tbTask, examDetail, sysUser.getId(), schoolId, variablePdfList, ordinaryPdfList, paperPdfList, examStudentPdfList, backupPaperPdfList, cardPdfList));
                 }
             }
+            if (PrintMethodEnum.AUTO == basicExamRule.getPrintMethod()) {
+                examPrintPlan.setStatus(PrintPlanStatusEnum.PRINTING);
+                examPrintPlanService.updateById(examPrintPlan);
+            }
             map.computeIfAbsent("size", v -> examDetailList.size());
             //最后一步删除附件
-            createPdfUtil.deleteAttachment(attachmentIds, ftlList);
+//            createPdfUtil.deleteAttachment(attachmentIds, ftlList);
         } catch (Exception e) {
             log.error("请求出错", e);
             basicAttachmentService.batchDeleteAttachment(basicAttachmentList);
@@ -315,8 +337,6 @@ public class TaskLogicServiceImpl implements TaskLogicService {
     public Map<String, Object> executeExaminationLogic(Map<String, Object> map) throws Exception {
         List<ExaminationExportDto> examinationExportDtoList = examDetailService.findExaminationExportDtoDatasource(map);
 
-        System.out.println("examinationResultList = " + JSON.toJSONString(examinationExportDtoList));
-
         ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
         ExcelUtil.excelMake(ExaminationExportDto.class, examinationExportDtoList, outputStream);
         InputStream in = new ByteArrayInputStream(outputStream.toByteArray());
@@ -339,7 +359,7 @@ public class TaskLogicServiceImpl implements TaskLogicService {
         jsonObject.put(SystemConstant.TYPE, SystemConstant.OSS);
         jsonObject.put(SystemConstant.PATH, dirName);
         jsonObject.put(SystemConstant.UPLOAD_TYPE, UploadFileEnum.FILE);
-        map.put("path", jsonObject.toString());
+        map.put(SystemConstant.PATH, jsonObject.toString());
         return map;
     }
 
@@ -353,7 +373,7 @@ public class TaskLogicServiceImpl implements TaskLogicService {
         ExamPrintPlan examPrintPlan = examPrintPlanService.getById(printPlanId);
 
         if (examPrintPlan == null) {
-            throw ExceptionResultEnum.ERROR.exception("印刷计划不存在printPlanId : " + printPlanId);
+            throw ExceptionResultEnum.ERROR.exception("[印刷计划]不存在");
         }
 
         PrintPlanStatusEnum printPlanStatus = examPrintPlan.getStatus();
@@ -370,18 +390,20 @@ public class TaskLogicServiceImpl implements TaskLogicService {
         }
         String importFilePath = tbTask.getImportFilePath();
         Map importFilePathMap = JSONObject.parseObject(importFilePath);
-        String path = String.valueOf(importFilePathMap.get("path"));
-        System.out.println("path = " + path);
+        String path = String.valueOf(importFilePathMap.get(SystemConstant.PATH));
         Workbook workbook;
         if (path.endsWith(SystemConstant.XLSX)) {
             workbook = new XSSFWorkbook(inputStream);
-        } else if (path.endsWith("xls")) {
+        } else if (path.endsWith(SystemConstant.XLS)) {
             workbook = new HSSFWorkbook(inputStream);
         } else {
             throw ExceptionResultEnum.ERROR.exception("文件格式异常");
         }
         // 读取第一个工作表
         Sheet sheet = workbook.getSheetAt(0);
+        if (sheet.getLastRowNum() == 0 && sheet.getPhysicalNumberOfRows() == 0) {
+            throw ExceptionResultEnum.ERROR.exception("第一个sheet为空,考务数据必须放在第一个sheet(工作表)内");
+        }
         // 获取sheet行数
         int totalRows = sheet.getPhysicalNumberOfRows();
         // 获取sheet列数
@@ -389,14 +411,14 @@ public class TaskLogicServiceImpl implements TaskLogicService {
         if (totalRows > 1 && sheet.getRow(0) != null) {
             totalCells = sheet.getRow(0).getPhysicalNumberOfCells();
         }
-        System.out.println("行 : " + totalRows + "\n列 : " + totalCells);
         Row head = sheet.getRow(0);
         List<String> headList = new ArrayList<>();
         // 将必填字段匹配excel解析的表头索引
         for (int i = 0; i < totalCells; i++) {
-            String cellValue = head.getCell(i).getStringCellValue();
+            String cellValue = String.valueOf(ExcelUtil.convert(head.getCell(i)));
             for (FieldsDto fieldsDto : fieldsDtoList) {
                 if (cellValue.equals(fieldsDto.getName())) {
+                    // 如果通用规则必填字段和excel表头匹配上了,则为该必选字段设置其在excel中的索引
                     fieldsDto.setIndex(i);
                 }
             }
@@ -406,120 +428,99 @@ public class TaskLogicServiceImpl implements TaskLogicService {
         // 搜索所有有效字段 excel中的表头是否包含
         for (FieldsDto fieldsDto : fieldsDtoList) {
             if (!headList.contains(fieldsDto.getName())) {
-                System.out.println("exception " + fieldsDto.getName());
                 throw ExceptionResultEnum.ERROR.exception("学校考务必填字段 :'" + fieldsDto.getName() + "' 不存在");
             }
         }
-
-        System.out.println("headList : " + headList);
-        System.out.println("fieldsDtoList : " + JSONObject.toJSONString(fieldsDtoList));
-
-        List<Map<String, Object>> dataList = new ArrayList<>();
+        List<ExaminationImportDto> examinationImportDtoList = new ArrayList<>();
 
         for (int r = 1; r < totalRows; r++) {
             Row row = sheet.getRow(r);
 
-            String studentCode = null;
-            String studentName = null;
-            String courseCode = null;
-            String courseName = null;
-            String examPlace = null;
-            String examRoom = null;
-            String examDate = null;
-            String examTime = null;
-            String paperNumber = null;
             List<FieldsDto> secondaryFieldList = new ArrayList<>(); // 备选字段
+
+            ExaminationImportDto examinationImportDto = new ExaminationImportDto();
+            Field[] examinationImportDtoFields = examinationImportDto.getClass().getDeclaredFields();
             for (FieldsDto fieldsDto : fieldsDtoList) {
+                boolean match = false;
                 String name = fieldsDto.getName();
                 String code = fieldsDto.getCode();
                 int index = fieldsDto.getIndex();
                 String level = fieldsDto.getLevel();
 
                 Cell cell = row.getCell(index);
+                if (cell == null) {
+                    throw ExceptionResultEnum.ERROR.exception("excel中第[" + (r + 1) + "]行,第[" + (index + 1) + "]列,字段[" + name + "]必填");
+                }
                 String cellValue = String.valueOf(ExcelUtil.convert(cell));
-                // TODO: 2021/4/20 可以优化 
-                if (ExaminationDBFieldsEnum.STUDENT_CODE.getDesc().equals(name)) {
-                    studentCode = cellValue;
-                    ConvertUtil.verifyLength(studentCode, 10, ExaminationDBFieldsEnum.STUDENT_CODE.getDesc());
-                } else if (ExaminationDBFieldsEnum.STUDENT_NAME.getDesc().equals(name)) {
-                    studentName = cellValue;
-                    ConvertUtil.verifyLength(studentName, 15, ExaminationDBFieldsEnum.STUDENT_NAME.getDesc());
-                } else if (ExaminationDBFieldsEnum.COURSE_CODE.getDesc().equals(name)) {
-                    courseCode = cellValue;
-                    ConvertUtil.verifyLength(courseCode, 10, ExaminationDBFieldsEnum.COURSE_CODE.getDesc());
-                } else if (ExaminationDBFieldsEnum.COURSE_NAME.getDesc().equals(name)) {
-                    courseName = cellValue;
-                    ConvertUtil.verifyLength(courseName, 20, ExaminationDBFieldsEnum.COURSE_NAME.getDesc());
-                } else if (ExaminationDBFieldsEnum.EXAM_PLACE.getDesc().equals(name)) {
-                    examPlace = cellValue;
-                    ConvertUtil.verifyLength(examPlace, 10, ExaminationDBFieldsEnum.EXAM_PLACE.getDesc());
-                } else if (ExaminationDBFieldsEnum.EXAM_ROOM.getDesc().equals(name)) {
-                    examRoom = cellValue;
-                    ConvertUtil.verifyLength(examRoom, 10, ExaminationDBFieldsEnum.EXAM_ROOM.getDesc());
-                } else if (ExaminationDBFieldsEnum.EXAM_DATE.getDesc().equals(name)) {
-                    examDate = cellValue;
-                } else if (ExaminationDBFieldsEnum.EXAM_TIME.getDesc().equals(name)) {
-                    examTime = cellValue;
-                } 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);
+                if (cellValue == null || cellValue.length() < 1 || cellValue.equals("null")) {
+                    throw ExceptionResultEnum.ERROR.exception("excel中第[" + (r + 1) + "]行,第[" + (index + 1) + "]列,字段[" + name + "]必填");
+                }
+
+                for (Field examinationImportDtoField : examinationImportDtoFields) {
+                    ExcelDBFieldDesc excelDBFieldDesc = examinationImportDtoField.getAnnotation(ExcelDBFieldDesc.class);
+                    if (excelDBFieldDesc == null) {
+                        // 如果没有注解,说明该数据库必须字段不是从excel中获得的,直接跳过
+                        continue;
                     }
-                    if ("secondary".equals(level)) {
-                        // 备选字段处理
-                        FieldsDto secondaryField = new FieldsDto();
-                        secondaryField.setLevel(level);
-                        secondaryField.setCode(code);
-                        secondaryField.setName(name);
-                        secondaryField.setEnable(true);
-                        secondaryField.setValue(cellValue);
-                        secondaryFieldList.add(secondaryField);
+
+                    // 如果数据库字段中文名和必填字段中文名称对应,则通过反射为数据库必选字段赋值
+                    String dbName = excelDBFieldDesc.name();
+                    int dbLength = excelDBFieldDesc.length();
+                    if (dbName.equals(name)) {
+                        if (dbLength > 0) {
+                            ConvertUtil.verifyLength(cellValue, dbLength, dbName);
+                        }
+                        examinationImportDtoField.setAccessible(true);
+                        examinationImportDtoField.set(examinationImportDto, cellValue);
+                        match = true;
+                        break;
                     }
                 }
+                if (!match || "secondary".equals(level)) {
+                    // 必选+扩展字段不能匹配到数据库中的字段存放 或者 该字段为扩展字段,则添加到扩展字段中
+                    FieldsDto secondaryField = new FieldsDto();
+                    secondaryField.setCode(code);
+                    secondaryField.setName(name);
+                    secondaryField.setEnable(true);
+                    secondaryField.setValue(cellValue);
+                    secondaryFieldList.add(secondaryField);
+                }
             }
             // 校验试卷编号
-            examTaskService.verifyCourseCodeByPaperNumber(schoolId, paperNumber, courseCode);
+            examTaskService.verifyCourseCodeByPaperNumber(schoolId, examinationImportDto.getPaperNumber(), examinationImportDto.getCourseCode());
 
             // 校验课程信息
-            basicCourseService.verifyCourseInfo(schoolId, courseCode, courseName, userId);
+            basicCourseService.verifyCourseInfo(schoolId, examinationImportDto.getCourseCode(), examinationImportDto.getCourseName(), userId);
 
             // 解析时间
-            Map<String, Object> timeMap = ConvertUtil.analyzeStartAndEndTime(examDate, examTime);
+            Map<String, Object> timeMap = ConvertUtil.analyzeStartAndEndTime(examinationImportDto.getExamDate(), examinationImportDto.getExamTime());
             String examStartTime = String.valueOf(timeMap.get("startTime"));
             String examEndTime = String.valueOf(timeMap.get("endTime"));
 
-            Map<String, Object> dataMap = new HashMap<>();
-            dataMap.put("studentCode", studentCode);
-            dataMap.put("studentName", studentName);
-            dataMap.put("courseCode", courseCode);
-            dataMap.put("courseName", courseName);
-            dataMap.put("examPlace", examPlace);
-            dataMap.put("examRoom", examRoom);
-            dataMap.put("examStartTime", examStartTime);
-            dataMap.put("examEndTime", examEndTime);
-            dataMap.put("paperNumber", paperNumber);
-            dataMap.put("secondaryFieldList", secondaryFieldList);
-            dataMap.put("schoolId", schoolId);
-            dataMap.put("printPlanId", printPlanId);
-            dataMap.put("printPlanName", printPlanName);
-            dataList.add(dataMap);
+            examinationImportDto.setSecondaryFieldList(secondaryFieldList);
+            examinationImportDto.setExamStartTime(examStartTime);
+            examinationImportDto.setExamEndTime(examEndTime);
+            examinationImportDto.setSchoolId(schoolId);
+            examinationImportDto.setPrintPlanId(printPlanId);
+            examinationImportDto.setPrintPlanName(printPlanName);
+            examinationImportDtoList.add(examinationImportDto);
         }
-        System.out.println(JSON.toJSONString(dataList));
+
+        System.out.println(JSON.toJSONString(examinationImportDtoList));
+
         // 校验课程代码和试卷编号在印刷计划下是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());
+        List<String> courseCodeList = examinationImportDtoList.stream().map(ExaminationImportDto::getCourseCode).distinct().collect(Collectors.toList());
+        List<String> paperNumberList = examinationImportDtoList.stream().map(ExaminationImportDto::getPaperNumber).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());
+            List<String> tmp = examinationImportDtoList.stream().filter(e -> courseCode.equals(e.getCourseCode()))
+                    .map(ExaminationImportDto::getPaperNumber).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());
+            List<String> tmp = examinationImportDtoList.stream().filter(e -> paperNumber.equals(e.getPaperNumber()))
+                    .map(ExaminationImportDto::getCourseCode).distinct().collect(Collectors.toList());
             if (tmp.size() != 1) {
                 throw ExceptionResultEnum.ERROR.exception("试卷编号为 " + paperNumber + ",对应多个课程代码 : " + tmp);
             }
@@ -528,21 +529,25 @@ public class TaskLogicServiceImpl implements TaskLogicService {
         // 删除印刷计划下的考务数据
         examDetailService.deleteExaminationData(printPlanId);
 
-
+        // 卷袋号生成规则
         SerialNumberParams serialNumberParams = new SerialNumberParams("packageCode-", "p", 6);
         String key = serialNumberParams.getModel() + serialNumberParams.getPrefix();
         RedisAtomicLong counter = new RedisAtomicLong(key, Objects.requireNonNull(redisTemplate.getConnectionFactory()));
         Long value = counter.get();
         try {
             // 组装exam_detail数据
-            List<Long> examDetailIdList = examDetailService.disposeExamDetailByExaminationExcel(dataList, userId, serialNumberParams);
+            List<Long> examDetailIdList = examDetailService.disposeExamDetailByExaminationExcel(examinationImportDtoList, userId, serialNumberParams);
             // 组装exam_detail_course数据
-            examDetailService.disposeExamDetailCourseByExaminationExcel(dataList, userId);
+            examDetailService.disposeExamDetailCourseByExaminationExcel(examinationImportDtoList, userId);
             // 组装exam_student数据
-            examDetailService.disposeExamStudentByExaminationExcel(dataList, userId);
+            examDetailService.disposeExamStudentByExaminationExcel(examinationImportDtoList, userId);
+
+            // 更改印刷计划状态
+            examPrintPlan.setStatus(PrintPlanStatusEnum.READY);
+            examPrintPlanService.updateById(examPrintPlan);
 
             map.put("examDetailIdList", examDetailIdList);
-            map.put("dataCount", dataList.size());
+            map.put("dataCount", examinationImportDtoList.size());
         } catch (Exception e) {
             redisTemplate.opsForValue().set(key, value);
             throw new RuntimeException(e);
@@ -595,8 +600,8 @@ public class TaskLogicServiceImpl implements TaskLogicService {
                         JSONObject jsonObject = JSONObject.parseObject(basicAttachment.getPath());
                         StringJoiner stringJoinerPdf = new StringJoiner("")
                                 .add(SystemConstant.TEMP_FILES_DIR).add(File.separator)
-                                .add((String) jsonObject.get("path"));
-                        sourceFiles.add(ossUtil.ossDownload((String) jsonObject.get("path"), stringJoinerPdf.toString()));
+                                .add((String) jsonObject.get(SystemConstant.PATH));
+                        sourceFiles.add(ossUtil.ossDownload((String) jsonObject.get(SystemConstant.PATH), stringJoinerPdf.toString()));
                     }
                     FileUtil.doZip(zipFile, sourceFiles);
                     ossUtil.ossUpload(dirName.toString(), zipFile, BinaryUtil.toBase64String(HexUtils.decodeHex(DigestUtils.md5Hex(new FileInputStream(zipFile)))));
@@ -654,36 +659,39 @@ public class TaskLogicServiceImpl implements TaskLogicService {
             }
             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<ExamTaskDetail> examTaskDetailList = examTaskDetailService.list(new QueryWrapper<ExamTaskDetail>().lambda().eq(ExamTaskDetail::getExamTaskId, id));
+//            if (examTaskDetailList.size() != 1) {
+//                throw ExceptionResultEnum.ERROR.exception("获取命题任务详情失败");
+//            }
+//            ExamTaskDetail examTaskDetail = examTaskDetailList.get(0);
+            ReviewSampleDto reviewSampleDto = examTaskService.findReviewSampleInfoByExamTaskId(id);
 
 
             // 处理试卷样品
-            List<Map> paperInfo = JSONObject.parseArray(examTaskDetail.getPaperAttachmentIds(), Map.class);
+            List<Map> paperInfo = JSONObject.parseArray(reviewSampleDto.getPaperAttachmentIds(), Map.class);
+            if (Objects.isNull(paperInfo)) {
+                throw ExceptionResultEnum.ERROR.exception("试卷信息不存在");
+            }
             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");
+                if (Objects.nonNull(paperMap.get("attachmentId")) && String.valueOf(paperMap.get("attachmentId")).length() > 0 && !String.valueOf(paperMap.get("attachmentId")).equals("null")) {
+                    Long attachmentId = Long.valueOf(String.valueOf(paperMap.get("attachmentId")));
+                    attPaperIds.add(attachmentId);
                 }
-                Long attachmentId = Long.valueOf(String.valueOf(paperMap.get("attachmentId")));
-                attPaperIds.add(attachmentId);
             }
-            List<BasicAttachment> paperAttachmentList = basicAttachmentService.listByIds(attPaperIds);
-            if (Objects.nonNull(paperAttachmentList)) {
+            if (attPaperIds.size() > 0) {
+                List<BasicAttachment> paperAttachmentList = basicAttachmentService.listByIds(attPaperIds);
                 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);
+                    ossUtil.ossDownload((String) jsonObject.get(SystemConstant.PATH), paperPath);
                     count++;
                 }
             }
 
             // 处理审核样品
-            List<Map> confirmInfo = JSONObject.parseArray(examTaskDetail.getPaperConfirmAttachmentIds(), Map.class);
+            List<Map> confirmInfo = JSONObject.parseArray(reviewSampleDto.getPaperConfirmAttachmentIds(), Map.class);
             System.out.println("confirmInfo = " + JSON.toJSONString(confirmInfo));
             Set<Long> attConfirmIds = new HashSet<>();
             for (Map confirmMap : confirmInfo) {
@@ -693,48 +701,47 @@ public class TaskLogicServiceImpl implements TaskLogicService {
                 Long attachmentId = Long.valueOf(String.valueOf(confirmMap.get("attachmentId")));
                 attConfirmIds.add(attachmentId);
             }
-            List<BasicAttachment> confirmAttachmentList = basicAttachmentService.listByIds(attConfirmIds);
-            if (Objects.nonNull(confirmAttachmentList)) {
+            if (attConfirmIds.size() > 0) {
+                List<BasicAttachment> confirmAttachmentList = basicAttachmentService.listByIds(attConfirmIds);
                 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);
+                    ossUtil.ossDownload((String) jsonObject.get(SystemConstant.PATH), confirmPath);
                     count++;
                 }
             }
 
             // 处理题卡
-            Long cardId = examTaskDetail.getCardId();
+            Long cardId = reviewSampleDto.getCardId();
             ExamCard examCard = examCardService.getById(cardId);
             if (Objects.isNull(examCard)) {
-                throw ExceptionResultEnum.ERROR.exception("找不到答题卡 cardId = " + cardId);
+                throw ExceptionResultEnum.ERROR.exception("找不到答题卡");
             }
             MakeMethodEnum makeMethodEnum = examCard.getMakeMethod();
             if (MakeMethodEnum.SELECT.equals(makeMethodEnum)) {
                 Long templateId = examCard.getTemplateId();
                 if (templateId == null || templateId == 0) {
-                    throw ExceptionResultEnum.ERROR.exception("找不到题卡对应的模板 templateId = " + templateId);
+                    throw ExceptionResultEnum.ERROR.exception("找不到题卡对应的模板");
                 }
                 BasicTemplate basicTemplate = basicTemplateService.getById(templateId);
                 if (Objects.isNull(basicTemplate)) {
-                    throw ExceptionResultEnum.ERROR.exception("找不到模板信息 templateId = " + templateId);
+                    throw ExceptionResultEnum.ERROR.exception("找不到模板信息");
                 }
                 Long attachmentId = basicTemplate.getAttachmentId();
                 if (attachmentId == null || attachmentId == 0) {
-                    throw ExceptionResultEnum.ERROR.exception("找不到模板对应的附件 templateId = " + templateId);
+                    throw ExceptionResultEnum.ERROR.exception("找不到模板对应的附件");
                 }
                 BasicAttachment cardAttachment = basicAttachmentService.getById(attachmentId);
                 if (Objects.isNull(cardAttachment)) {
-                    throw ExceptionResultEnum.ERROR.exception("找不到附件 attachmentId = " + attachmentId);
+                    throw ExceptionResultEnum.ERROR.exception("找不到附件");
                 }
                 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++;
+                ossUtil.ossDownload((String) jsonObject.get(SystemConstant.PATH), cardPath);
             } 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);
+                    throw ExceptionResultEnum.ERROR.exception("题卡明细信息异常");
                 }
                 ExamCardDetail examCardDetail = examCardDetailService.getByCardId(cardId);
                 String htmlContent = examCardDetail.getHtmlContent();
@@ -745,8 +752,8 @@ public class TaskLogicServiceImpl implements TaskLogicService {
                     localFile.getParentFile().mkdirs();
                 }
                 FileCopyUtils.copy(bytes, localFile);
-                count++;
             }
+            count++;
         }
         ZipUtil.zip(zipLocalRootPath, zipFile.getPath(), true);
         ossUtil.ossUpload(dirNameTmp, zipFile, BinaryUtil.toBase64String(HexUtils.decodeHex(DigestUtils.md5Hex(new FileInputStream(zipFile)))));

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

@@ -257,7 +257,7 @@ public class ConvertUtil {
             throw ExceptionResultEnum.ERROR.exception(name + "不能为空");
         }
         if (str.length() > length){
-            throw ExceptionResultEnum.ERROR.exception("内容'" + str + "' 超过长度限制 : " + length);
+            throw ExceptionResultEnum.ERROR.exception("[" + name + ":" + str + "]' 超过长度限制 : " + length);
         }
     }
 }

+ 174 - 60
distributed-print-business/src/main/java/com/qmth/distributed/print/business/util/CreatePdfUtil.java

@@ -7,14 +7,12 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.google.gson.Gson;
 import com.itextpdf.text.DocumentException;
 import com.qmth.distributed.print.business.bean.dto.ExamStudentDto;
+import com.qmth.distributed.print.business.bean.dto.PaperPdfDto;
 import com.qmth.distributed.print.business.bean.dto.PdfDto;
+import com.qmth.distributed.print.business.cache.CreatePdfCacheUtil;
 import com.qmth.distributed.print.business.entity.*;
-import com.qmth.distributed.print.business.enums.DrawRuleEnum;
-import com.qmth.distributed.print.business.enums.ExamDetailStatusEnum;
-import com.qmth.distributed.print.business.enums.PageSizeEnum;
-import com.qmth.distributed.print.business.enums.PrintMethodEnum;
+import com.qmth.distributed.print.business.enums.*;
 import com.qmth.distributed.print.business.service.BasicAttachmentService;
-import com.qmth.distributed.print.business.service.BasicExamRuleService;
 import com.qmth.distributed.print.business.service.CommonService;
 import com.qmth.distributed.print.business.service.ExamDetailService;
 import com.qmth.distributed.print.common.contant.SystemConstant;
@@ -58,16 +56,17 @@ public class CreatePdfUtil {
     ExamDetailService detailService;
 
     @Resource
-    BasicExamRuleService basicExamRuleService;
+    RedisUtil redisUtil;
 
     /**
      * 创建登记表
      *
+     * @param examDetail
      * @param basicAttachment
      * @param ordinaryPdfList
      * @param printCount
      */
-    public void createCheckIn(BasicAttachment basicAttachment, List<PdfDto> ordinaryPdfList, Integer printCount) throws IOException, DocumentException {
+    public void createCheckIn(ExamDetail examDetail, BasicAttachment basicAttachment, List<PdfDto> ordinaryPdfList, Integer printCount) throws IOException, DocumentException {
         if (Objects.isNull(basicAttachment)) {
             throw ExceptionResultEnum.ERROR.exception("找不到附件");
         }
@@ -77,12 +76,12 @@ public class CreatePdfUtil {
             String filePath = (String) jsonObject.get(SystemConstant.PATH);
             String url = SystemConstant.TEMP_FILES_DIR + File.separator + filePath;
             File localFile = ossUtil.ossDownload(filePath, url);
-            int pageCount = PdfUtil.addPdfPage(localFile);
+            PdfDto pdfDto = PdfUtil.addPdfPage(localFile);
             for (int i = 0; i < printCount; i++) {
-                ordinaryPdfList.add(new PdfDto(localFile.getPath(), PageSizeEnum.A4, pageCount));
+                ordinaryPdfList.add(new PdfDto(localFile.getPath(), PageSizeEnum.A4, pdfDto.getPageCount()));
             }
         } else {
-            basicAttachmentService.saveAttachmentPdf(basicAttachment, ordinaryPdfList, printCount, 0);
+            basicAttachmentService.saveAttachmentPdf(ClassifyEnum.CHECK_IN, examDetail, basicAttachment, ordinaryPdfList, printCount, 0);
         }
     }
 
@@ -112,7 +111,9 @@ public class CreatePdfUtil {
         htmlMap.put("startTime", DateUtil.format(new Date(examDetail.getExamStartTime()), SystemConstant.DEFAULT_DATE_PATTERN));
         htmlMap.put("endTime", DateUtil.format(new Date(examDetail.getExamEndTime()), SystemConstant.DEFAULT_DATE_PATTERN));
         htmlMap.put("paperCode", examDetailCourse.getPaperNumber());
-        htmlMap.put("paperCodeImg", GoogleBarCodeUtil.createBarCode(examDetailCourse.getPaperNumber(), false));
+        if (Objects.nonNull(examDetailCourse.getPaperNumber())) {
+            htmlMap.put("paperCodeImg", GoogleBarCodeUtil.createBarCode(examDetailCourse.getPaperNumber(), false));
+        }
 
         List<String> extendColumnList = examStudentList.stream().map(m -> m.getExtendFields()).distinct().collect(Collectors.toList());
         Set<String> startCollege = new HashSet();
@@ -145,8 +146,12 @@ public class CreatePdfUtil {
         htmlMap.put("proctorCollege", String.join(",", proctorCollege));
         htmlMap.put("examManager", String.join(",", examManager));
 
-        String minSite = examStudentList.stream().min((a, b) -> a.getSiteNumber().compareTo(b.getSiteNumber())).get().getSiteNumber();
-        String maxSite = examStudentList.stream().max((a, b) -> a.getSiteNumber().compareTo(b.getSiteNumber())).get().getSiteNumber();
+        List<ExamStudent> tempList = examStudentList.stream().filter(s -> (Objects.nonNull(s.getSiteNumber()) && !Objects.equals("", s.getSiteNumber().trim()))).collect(Collectors.toList());
+        String minSite = "", maxSite = "";
+        if (Objects.nonNull(tempList) && tempList.size() > 0) {
+            minSite = tempList.stream().min((a, b) -> a.getSiteNumber().compareTo(b.getSiteNumber())).get().getSiteNumber();
+            maxSite = tempList.stream().max((a, b) -> a.getSiteNumber().compareTo(b.getSiteNumber())).get().getSiteNumber();
+        }
 
         htmlMap.put("minSite", minSite);
         htmlMap.put("maxSite", maxSite);
@@ -158,6 +163,8 @@ public class CreatePdfUtil {
         htmlMap.computeIfAbsent("variablePdfList", v -> variablePdfList);
         htmlMap.computeIfAbsent("printCount", v -> printCount);
         htmlMap.computeIfAbsent("sequence", v -> 1);
+        htmlMap.computeIfAbsent("examDetail", v -> examDetail);
+        htmlMap.computeIfAbsent("printType", v -> ClassifyEnum.PACKAGE);
         freemarkerUtil.createPaperPackage(htmlMap);
     }
 
@@ -199,7 +206,9 @@ public class CreatePdfUtil {
         htmlMap.put("startTime", DateUtil.format(new Date(examDetail.getExamStartTime()), SystemConstant.DEFAULT_DATE_PATTERN));
         htmlMap.put("endTime", DateUtil.format(new Date(examDetail.getExamEndTime()), SystemConstant.DEFAULT_DATE_PATTERN));
         htmlMap.put("paperCode", examDetailCourse.getPaperNumber());
-        htmlMap.put("paperCodeImg", GoogleBarCodeUtil.createBarCode(examDetailCourse.getPaperNumber(), false));
+        if (Objects.nonNull(examDetailCourse.getPaperNumber())) {
+            htmlMap.put("paperCodeImg", GoogleBarCodeUtil.createBarCode(examDetailCourse.getPaperNumber(), false));
+        }
 
         int totalCount = examStudentList.size();
         if (totalCount > 0) {
@@ -254,6 +263,8 @@ public class CreatePdfUtil {
         htmlMap.computeIfAbsent("variablePdfList", v -> variablePdfList);
         htmlMap.computeIfAbsent("printCount", v -> printCount);
         htmlMap.computeIfAbsent("sequence", v -> 2);
+        htmlMap.computeIfAbsent("examDetail", v -> examDetail);
+        htmlMap.computeIfAbsent("printType", v -> ClassifyEnum.SIGN);
         freemarkerUtil.createSignBook(htmlMap);
     }
 
@@ -278,12 +289,12 @@ public class CreatePdfUtil {
      * @param attachmentIds
      */
     public void getCardAttachmentId(ExamCardDetail examCardDetail, Set<Long> attachmentIds) {
-        if (Objects.nonNull(examCardDetail.getAttachmentId())) {
+        if (Objects.nonNull(examCardDetail.getAttachmentId()) && !Objects.equals("", examCardDetail.getAttachmentId())) {
             JSONObject jsonObjectCard = JSONObject.parseObject(examCardDetail.getAttachmentId());
             JSONArray jsonArrayCard = (JSONArray) jsonObjectCard.get("card");
             for (int i = 0; i < jsonArrayCard.size(); i++) {
                 JSONObject object = (JSONObject) jsonArrayCard.get(i);
-                if (Objects.nonNull(object.get("attachmentId"))) {
+                if (Objects.nonNull(object.get("attachmentId")) && !Objects.equals("", object.get("attachmentId"))) {
                     attachmentIds.add((Long) (object.get("attachmentId")));
                 }
             }
@@ -293,19 +304,59 @@ public class CreatePdfUtil {
     /**
      * 获取试卷pdf
      *
-     * @param paperType
-     * @param examTaskDetail
+     * @param paperPdfDto
+     * @param pdfList
+     * @return
+     * @throws IOException
+     */
+    public PdfDto getExamStudentPaperPdf(PaperPdfDto paperPdfDto, List<PdfDto> pdfList) throws IOException {
+        if (Objects.nonNull(paperPdfDto)) {
+            int pages = paperPdfDto.getPages();
+            PdfDto pdfDto = PdfUtil.addPdfPage(paperPdfDto.getFile());
+            pdfList.add(new PdfDto(paperPdfDto.getFile().getPath(), PageSizeEnum.A3, pdfDto.getPageCount()));
+            return new PdfDto(PageSizeEnum.A3, pages);
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * 获取试卷pdf
+     *
+     * @param paperPdfDto
      * @param backupCount
      * @param pdfList
      * @return
      * @throws IOException
      */
-    public boolean getPaperPdf(String paperType, ExamTaskDetail examTaskDetail, Integer backupCount, List<PdfDto>... pdfList) throws IOException {
-        boolean tag = true;
+    public PdfDto getPaperPdf(PaperPdfDto paperPdfDto, Integer backupCount, List<PdfDto> pdfList) throws IOException {
+        if (Objects.nonNull(paperPdfDto)) {
+            int pages = paperPdfDto.getPages();
+            boolean tag = pages > 2 ? true : false;
+            PdfDto pdfDto = PdfUtil.addPdfPage(paperPdfDto.getFile());
+            for (int j = 1; j <= backupCount; j++) {
+                pdfList.add(new PdfDto(paperPdfDto.getFile().getPath(), PageSizeEnum.A3, pdfDto.getPageCount()));
+            }
+            return new PdfDto(PageSizeEnum.A3, pages, tag);
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * 获取考试试卷
+     *
+     * @param paperType
+     * @param examTaskDetail
+     * @return
+     * @throws IOException
+     */
+    public PaperPdfDto getPaperPdfFile(String paperType, ExamTaskDetail examTaskDetail) throws IOException {
+        PaperPdfDto paperPdfDto = null;
         JSONArray jsonArrayPaper = JSONArray.parseArray(examTaskDetail.getPaperAttachmentIds());
         for (int i = 0; i < jsonArrayPaper.size(); i++) {
             JSONObject object = (JSONObject) jsonArrayPaper.get(i);
-            if (Objects.nonNull(object.get("attachmentId"))) {
+            if (Objects.nonNull(object.get("attachmentId")) && !Objects.equals("", object.get("attachmentId"))) {
                 Long attachmentId = Long.parseLong((String) (object.get("attachmentId")));
                 BasicAttachment basicAttachment = basicAttachmentService.getById(attachmentId);
                 if (Objects.isNull(basicAttachment)) {
@@ -315,16 +366,12 @@ public class CreatePdfUtil {
                 if (Objects.equals(name.toUpperCase(), paperType.toUpperCase())) {
                     File file = commonService.getFile(basicAttachment.getPath(), false);
                     int pages = (int) object.get("pages");
-                    tag = pages > 2 ? true : false;
-                    int pageCount = PdfUtil.addPdfPage(file);
-                    pdfList[0].add(new PdfDto(file.getPath(), PageSizeEnum.A3, pageCount));
-                    for (int j = 1; j <= backupCount; j++) {
-                        pdfList[1].add(new PdfDto(file.getPath(), PageSizeEnum.A3, pageCount));
-                    }
+                    paperPdfDto = new PaperPdfDto(file, pages);
+                    break;
                 }
             }
         }
-        return tag;
+        return paperPdfDto;
     }
 
     /**
@@ -332,34 +379,77 @@ public class CreatePdfUtil {
      *
      * @param examPrintPlan
      * @param examTaskDetail
+     * @param examDetail
+     * @param examDetailCourse
      * @return
      */
-    public String getPaperType(ExamPrintPlan examPrintPlan, ExamTaskDetail examTaskDetail) {
+    public String getPaperType(ExamPrintPlan examPrintPlan, ExamTaskDetail examTaskDetail, ExamDetail examDetail, ExamDetailCourse examDetailCourse) {
+        String key = examDetail.getSchoolId()
+                + "_" + examDetail.getExamStartTime()
+                + "_" + examDetail.getExamEndTime()
+                + "_" + examDetail.getExamPlace()
+                + "_" + examDetailCourse.getCourseCode()
+                + "_" + examDetailCourse.getPaperNumber();
+
         //抽取卷型
         DrawRuleEnum drawRule = Objects.nonNull(examPrintPlan.getDrawRule()) ? examPrintPlan.getDrawRule() : DrawRuleEnum.ONE;
         //未曝光卷型
         String unexposedPaperType = examTaskDetail.getUnexposedPaperType();
         //已曝光卷型
         String exposedPaperType = examTaskDetail.getExposedPaperType();
-        String[] paperTypes = null;
         if (drawRule == DrawRuleEnum.ONE) {
             if (Objects.isNull(unexposedPaperType)) {
+                CreatePdfCacheUtil.deletePaperType(key);
                 throw ExceptionResultEnum.ERROR.exception("当前没有未曝光的卷型");
-            } else {
-                paperTypes = unexposedPaperType.split(",");
             }
         } else {
             if (Objects.isNull(exposedPaperType) && Objects.isNull(unexposedPaperType)) {
+                CreatePdfCacheUtil.deletePaperType(key);
                 throw ExceptionResultEnum.ERROR.exception("当前没有未曝光的卷型");
             }
-            if (Objects.nonNull(unexposedPaperType)) {
-                paperTypes = unexposedPaperType.split(",");
-            } else {
-                paperTypes = exposedPaperType.split(",");
+        }
+        String paperType = null;
+        String[] paperTypes = null;
+        boolean lock = true;
+        for (int i = 0; i < SystemConstant.MAX_RETRY_COUNT; i++) {
+            lock = redisUtil.lock(key, SystemConstant.REDIS_CACHE_TIME_OUT);
+            if (lock) {
+                try {
+                    paperType = CreatePdfCacheUtil.getPaperType(key);
+                    if (Objects.isNull(paperType)) {
+                        if (drawRule == DrawRuleEnum.ONE) {
+                            paperTypes = unexposedPaperType.split(",");
+                        } else {
+                            if (Objects.nonNull(unexposedPaperType)) {
+                                paperTypes = unexposedPaperType.split(",");
+                            } else {
+                                paperTypes = exposedPaperType.split(",");
+                            }
+                        }
+                        int paperRandom = new Random().nextInt(paperTypes.length);
+                        paperType = paperTypes[paperRandom];
+                        CreatePdfCacheUtil.setPaperType(key, paperType);
+                    }
+                    break;
+                } catch (Exception e) {
+                    log.error("请求出错", e);
+                } finally {
+                    redisUtil.releaseLock(key);
+                }
+            } else {//未获取到锁,等待500毫秒继续获取
+                try {
+                    Thread.sleep(500);
+                } catch (InterruptedException e) {
+                    e.printStackTrace();
+                }
             }
         }
-        int paperRandom = new Random().nextInt(paperTypes.length);
-        return paperTypes[paperRandom];
+        log.info("getPaperType key:{},paperType:{},lock:{},examDetailId:{},examDetailCourseId:{}", key, paperType, lock, examDetail.getId(), examDetailCourse.getId());
+        if (!lock) {
+            log.info("getPaperType 未获取到锁,key:{}", key);
+            throw ExceptionResultEnum.ERROR.exception("未获取到试卷类型");
+        }
+        return paperType;
     }
 
     /**
@@ -373,14 +463,16 @@ public class CreatePdfUtil {
      * @return
      * @throws IOException
      */
-    public BasicAttachment mergePdf(TBTask tbTask, ExamDetail examDetail, Long userId, Long schoolId, List<PdfDto>... list) throws IOException {
+    public BasicAttachment mergePdf(BasicExamRule basicExamRule, TBTask tbTask, ExamDetail examDetail, Long userId, Long schoolId, List<PdfDto>... list) throws IOException {
         StringJoiner stringJoiner = new StringJoiner("").add(SystemConstant.PDF_TEMP_FILES_DIR).add(File.separator);
         List<PdfDto> mergePdfList = new ArrayList<>();
+        List<PdfDto> mergePdfA4List = new ArrayList<>();
         int pageA3Count = 0;
         int pageA4Count = 0;
         for (int i = 0; i < list.length; i++) {
             if (list[i].size() > 0 && list[i].get(0).getPageSize() == PageSizeEnum.A4) {
                 pageA4Count = pageA4Count + list[i].stream().mapToInt(PdfDto::getPageCount).sum();
+                mergePdfA4List.addAll(list[i]);
             } else if (list[i].size() > 0 && list[i].get(0).getPageSize() == PageSizeEnum.A3) {
                 pageA3Count = pageA3Count + list[i].stream().mapToInt(PdfDto::getPageCount).sum();
                 mergePdfList.addAll(list[i]);
@@ -388,6 +480,8 @@ public class CreatePdfUtil {
         }
         List<String> pathList = mergePdfList.stream().map(PdfDto::getPath).collect(Collectors.toList());
         String dirName = PdfUtil.mergePdf(pathList.toArray(new String[mergePdfList.size()]), null);
+        // oss上只认"/",windows生成的路径分隔符全部替换为"/"
+        dirName = dirName.replaceAll("\\\\", "/");
         File localPdfFile = new File(stringJoiner.toString() + File.separator + dirName);
         BasicAttachment basicAttachment = basicAttachmentService.saveAttachmentPdf(dirName, userId);
         tbTask.setImportFileName(basicAttachment.getName());
@@ -395,14 +489,16 @@ public class CreatePdfUtil {
         examDetail.setAttachmentId(basicAttachment.getId());
         examDetail.setPagesA3(pageA3Count);
         examDetail.setPagesA4(pageA4Count);
-        BasicExamRule basicExamRule = basicExamRuleService.getBySchoolId(schoolId);
         examDetail.setStatus(PrintMethodEnum.AUTO == basicExamRule.getPrintMethod() ? ExamDetailStatusEnum.WAITING : ExamDetailStatusEnum.READY);
         detailService.saveOrUpdate(examDetail);
         ossUtil.ossUpload(dirName, localPdfFile, DigestUtils.md5Hex(new FileInputStream(localPdfFile)));
-        localPdfFile.delete();
-        for (PdfDto pdfDto : mergePdfList) {
-            new File(pdfDto.getPath()).delete();
-        }
+//        localPdfFile.delete();
+//        for (PdfDto pdfDto : mergePdfList) {
+//            new File(pdfDto.getPath()).delete();
+//        }
+//        for (PdfDto pdfDto : mergePdfA4List) {
+//            new File(pdfDto.getPath()).delete();
+//        }
         return basicAttachment;
     }
 
@@ -432,14 +528,14 @@ public class CreatePdfUtil {
      * @param attachmentIds
      * @param studentContent
      * @param t
-     * @param paperType
-     * @param examCard
+     * @param examDetail
+     * @param examDetailCourse
      * @param userId
      * @param examStudentPdfList
      * @return
      * @throws IOException
      */
-    public BasicAttachment examStudentHtml(Set<Long> attachmentIds, String studentContent, ExamStudent t, String paperType, ExamCard examCard, Long userId, List<PdfDto> examStudentPdfList) throws IOException {
+    public BasicAttachment examStudentHtml(Set<Long> attachmentIds, String studentContent, ExamStudent t, ExamDetail examDetail, ExamDetailCourse examDetailCourse, Long userId, List<PdfDto> examStudentPdfList) throws IOException {
         if (Objects.nonNull(t.getAttachmentId())) {
             attachmentIds.add(t.getAttachmentId());
         }
@@ -454,19 +550,32 @@ public class CreatePdfUtil {
             }
         }
         //生成学生考号条码并将图片转成base64
-        studentHtml = studentHtml.replaceAll("\\$\\{examNumber\\}", GoogleBarCodeUtil.createBarCode(t.getTicketNumber(), false));
+        if (Objects.nonNull(t.getTicketNumber())) {
+            studentHtml = studentHtml.replaceAll("\\$\\{examNumber\\}", GoogleBarCodeUtil.createBarCode(t.getTicketNumber(), false));
+        }
         studentHtml = studentHtml.replaceAll("\\$\\{examNumberStr\\}", t.getTicketNumber());
         //随机生成学生试卷条码并将图片转成base64
-        studentHtml = studentHtml.replaceAll("\\$\\{paperType\\}", GoogleBarCodeUtil.createBarCode(SystemConstant.convertPaperType(paperType), false));
-        studentHtml = studentHtml.replaceAll("\\$\\{paperTypeName\\}", paperType);
+        if (Objects.nonNull(examDetailCourse.getPaperType())) {
+            studentHtml = studentHtml.replaceAll("\\$\\{paperType\\}", GoogleBarCodeUtil.createBarCode(SystemConstant.convertPaperType(examDetailCourse.getPaperType()), false));
+        }
+        Map<String, Object> map = ConvertUtil.analyzeDateAndTime(examDetail.getExamStartTime(), examDetail.getExamEndTime());
+        studentHtml = studentHtml.replaceAll("\\$\\{examDate\\}", Objects.nonNull(map.get("date")) ? (String) map.get("date") : "");
+        studentHtml = studentHtml.replaceAll("\\$\\{examTime\\}", Objects.nonNull(map.get("time")) ? (String) map.get("time") : "");
+        studentHtml = studentHtml.replaceAll("\\$\\{ticketNumber\\}", t.getTicketNumber());
+        studentHtml = studentHtml.replaceAll("\\$\\{siteNumber\\}", t.getSiteNumber());
+        studentHtml = studentHtml.replaceAll("\\$\\{paperTypeName\\}", examDetailCourse.getPaperType());
         studentHtml = studentHtml.replaceAll("\\$\\{studentCode\\}", t.getStudentCode());
         studentHtml = studentHtml.replaceAll("\\$\\{studentName\\}", t.getStudentName());
-        studentHtml = studentHtml.replaceAll("\\$\\{courseName\\}", examCard.getCourseName());
+        studentHtml = studentHtml.replaceAll("\\$\\{courseName\\}", examDetailCourse.getCourseName());
+        studentHtml = studentHtml.replaceAll("\\$\\{courseCode\\}", examDetailCourse.getCourseCode());
+        studentHtml = studentHtml.replaceAll("\\$\\{examPlace\\}", examDetail.getExamPlace());
+        studentHtml = studentHtml.replaceAll("\\$\\{examRoom\\}", examDetail.getExamRoom());
+        studentHtml = studentHtml.replaceAll("\\$\\{paperNumber\\}", examDetailCourse.getPaperNumber());
 
         //学生题卡
-        BasicAttachment examStudentAttachment = basicAttachmentService.saveAttachmentHtml(examCard.getSchoolId() + "|" + examCard.getCourseCode() + "|" + t.getTicketNumber(), studentHtml, userId, examStudentPdfList);
+        BasicAttachment examStudentAttachment = basicAttachmentService.saveAttachmentHtml(examDetail.getSchoolId() + "|" + examDetailCourse.getCourseCode() + "|" + t.getTicketNumber(), studentHtml, userId, examStudentPdfList);
         t.setAttachmentId(examStudentAttachment.getId());
-        t.setPaperType(paperType);
+        t.setPaperType(examDetailCourse.getPaperType());
         return examStudentAttachment;
     }
 
@@ -474,7 +583,6 @@ public class CreatePdfUtil {
      * 通用题卡html
      *
      * @param cardContent
-     * @param paperType
      * @param examDetailCourse
      * @param examCard
      * @param jsonArray
@@ -483,22 +591,28 @@ public class CreatePdfUtil {
      * @return
      * @throws IOException
      */
-    public BasicAttachment cardHtml(String cardContent, String paperType, ExamDetail examDetail, ExamDetailCourse examDetailCourse, ExamCard examCard, JSONArray jsonArray, Long userId, List<PdfDto> cardPdfList) throws IOException {
+    public BasicAttachment cardHtml(String sequence, String cardContent, ExamDetail examDetail, ExamDetailCourse examDetailCourse, ExamCard examCard, JSONArray jsonArray, Long userId, List<PdfDto> cardPdfList) throws IOException {
         //通用题卡
         String cardTemp = cardContent;
-        cardTemp = cardTemp.replaceAll("\\$\\{paperTypeName\\}", paperType);
+        cardTemp = cardTemp.replaceAll("\\$\\{paperTypeName\\}", examDetailCourse.getPaperType());
         //随机生成试卷条码并将图片转成base64
-        cardTemp = cardTemp.replaceAll("\\$\\{paperType\\}", GoogleBarCodeUtil.createBarCode(SystemConstant.convertPaperType(paperType), false));
+        if (Objects.nonNull(examDetailCourse.getPaperType())) {
+            cardTemp = cardTemp.replaceAll("\\$\\{paperType\\}", GoogleBarCodeUtil.createBarCode(SystemConstant.convertPaperType(examDetailCourse.getPaperType()), false));
+        }
         //通用题卡生成卷袋贴条码
-        String packageCode = examDetail.getPackageCode();
-        String packageCodeImg = GoogleBarCodeUtil.createBarCode(packageCode, false);
+        String packageCode = examDetail.getPackageCode() + sequence;
+        String packageCodeImg = null;
+        if (Objects.nonNull(packageCode)) {
+            packageCodeImg = GoogleBarCodeUtil.createBarCode(packageCode, false);
+        }
         String packageCodeDiv = "<div class=\"page-box page-box-0\"><div class=\"package-number\" style=\"position: absolute;width: 200px;height: 40px;top: 80px;right: 35px;transform: rotate(-90deg);transform-origin: center right;text-align: center;z-index: 99;\"><img src=\"data:image/png;base64," + packageCodeImg + "\" style=\"display: block; height: 28px; width: 100%\" /><p style=\"line-height: 1; font-size: 12px; margin: 0;\">" + packageCode + "</p></div>";
         cardTemp = cardTemp.replaceAll("<div class=\"page-box page-box-0\">", packageCodeDiv);
         BasicAttachment cardAttachment = basicAttachmentService.saveAttachmentHtml(examCard.getSchoolId() + "|" + examCard.getCourseCode(), cardTemp, userId, cardPdfList);
         JSONObject object = new JSONObject();
-        object.put("name", paperType);
+        object.put("name", examDetailCourse.getPaperType());
         object.put("examDetailCourseId", examDetailCourse.getId());
         object.put("attachmentId", cardAttachment.getId());
+        object.put("packageCode", packageCode);
         jsonArray.add(object);
         return cardAttachment;
     }

+ 3 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/util/ExcelUtil.java

@@ -119,6 +119,9 @@ public class ExcelUtil {
                         int lastcell = row.getLastCellNum();
                         o = clazz.get(y).newInstance();
                         Field[] fields = o.getClass().getDeclaredFields();
+                        if (lastcell > fields.length) {
+                            throw ExceptionResultEnum.ERROR.exception("导入文件和模版不一致");
+                        }
                         boolean extend = fields[fields.length - 1].getName().contains(SystemConstant.EXTEND_COLUMN);
                         for (int j = firstcell; j < lastcell; j++) {
                             //获取第j列

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

@@ -4,6 +4,8 @@ import com.alibaba.fastjson.JSONObject;
 import com.qmth.distributed.print.business.bean.dto.PdfDto;
 import com.qmth.distributed.print.business.config.DictionaryConfig;
 import com.qmth.distributed.print.business.entity.BasicAttachment;
+import com.qmth.distributed.print.business.entity.ExamDetail;
+import com.qmth.distributed.print.business.enums.ClassifyEnum;
 import com.qmth.distributed.print.business.enums.UploadFileEnum;
 import com.qmth.distributed.print.business.service.BasicAttachmentService;
 import com.qmth.distributed.print.common.contant.SystemConstant;
@@ -18,6 +20,7 @@ import org.springframework.util.ResourceUtils;
 
 import javax.annotation.Resource;
 import java.io.*;
+import java.time.LocalDateTime;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -79,6 +82,8 @@ public class FreemarkerUtil {
         Writer out = null;
         try {
             BasicAttachment basicAttachment = (BasicAttachment) dataMap.get("basicAttachment");
+            ExamDetail examDetail = (ExamDetail) dataMap.get("examDetail");
+            ClassifyEnum classifyEnum = (ClassifyEnum) dataMap.get("printType");
             JSONObject jsonObject = JSONObject.parseObject(basicAttachment.getPath());
             String path = (String) jsonObject.get(SystemConstant.PATH);
             String ftlPath = path.substring(0, path.lastIndexOf("/"));
@@ -90,12 +95,17 @@ public class FreemarkerUtil {
             // step1 加载模版文件
             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()).replaceAll(UploadFileEnum.UPLOAD.getTitle(), UploadFileEnum.HTML.getTitle()))
-                    .add(File.separator)
-                    .add(ftlName)
-                    .add(SystemConstant.HTML_PREFIX);
-            File htmlFile = new File(localStringJoiner.toString());
+            boolean oss = dictionaryConfig.sysDomain().isOss();
+            LocalDateTime nowTime = LocalDateTime.now();
+            StringJoiner stringJoiner = new StringJoiner("");
+            stringJoiner.add(SystemConstant.TEMP_FILES_DIR).add(File.separator);
+            StringJoiner htmlStringJoiner = new StringJoiner("");
+            htmlStringJoiner.add(UploadFileEnum.HTML.getTitle()).add(File.separator);
+            htmlStringJoiner.add(String.valueOf(nowTime.getYear())).add(File.separator)
+                    .add(String.format("%02d", nowTime.getMonthValue())).add(File.separator)
+                    .add(String.format("%02d", nowTime.getDayOfMonth()));
+            htmlStringJoiner.add(File.separator).add(SystemConstant.getUuid()).add(SystemConstant.HTML_PREFIX);
+            File htmlFile = new File(stringJoiner.toString() + htmlStringJoiner.toString());
             if (!htmlFile.getParentFile().exists()) {
                 htmlFile.getParentFile().mkdirs();
                 htmlFile.createNewFile();
@@ -104,21 +114,17 @@ public class FreemarkerUtil {
             // step3 输出文件
             template.process(dataMap, out);
             out.flush();
-            boolean oss = dictionaryConfig.sysDomain().isOss();
             if (oss) {
-                StringJoiner stringJoiner = new StringJoiner("");
-                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());
+                ossUtil.ossUpload(htmlStringJoiner.toString(), htmlFile, DigestUtils.md5Hex(new FileInputStream(htmlFile)));
+                jsonObject.put(SystemConstant.HTML_PATH, htmlStringJoiner.toString());
                 jsonObject.put(SystemConstant.UPLOAD_TYPE, new UploadFileEnum[]{
                         UploadFileEnum.FILE,
                         UploadFileEnum.HTML
                 });
                 basicAttachment.setPath(jsonObject.toJSONString());
-                basicAttachmentService.saveAttachmentPdf(basicAttachment, (List<PdfDto>) dataMap.get("variablePdfList"), (Integer) dataMap.get("printCount"), (Integer) dataMap.get("sequence"));
+                basicAttachmentService.saveAttachmentPdf(classifyEnum, examDetail, basicAttachment, (List<PdfDto>) dataMap.get("variablePdfList"), (Integer) dataMap.get("printCount"), (Integer) dataMap.get("sequence"));
             }
-            htmlFile.delete();
+//            htmlFile.delete();
         } catch (Exception e) {
             log.error("请求出错", e);
         } finally {

+ 7 - 3
distributed-print-business/src/main/java/com/qmth/distributed/print/business/util/PdfUtil.java

@@ -5,6 +5,9 @@ import com.itextpdf.text.pdf.PdfCopy;
 import com.itextpdf.text.pdf.PdfImportedPage;
 import com.itextpdf.text.pdf.PdfReader;
 import com.itextpdf.text.pdf.PdfStamper;
+import com.qmth.distributed.print.business.bean.dto.PdfDto;
+import com.qmth.distributed.print.business.entity.BasicAttachment;
+import com.qmth.distributed.print.business.enums.PageSizeEnum;
 import com.qmth.distributed.print.business.enums.UploadFileEnum;
 import com.qmth.distributed.print.common.contant.SystemConstant;
 import org.apache.commons.io.IOUtils;
@@ -88,12 +91,13 @@ public class PdfUtil {
      * @return
      * @throws IOException
      */
-    public static int addPdfPage(File pdfFile) throws IOException {
+    public static PdfDto addPdfPage(File pdfFile) throws IOException {
         PdfReader reader = null;
         FileOutputStream fileOutputStream = null;
+        int pageCount = 0;
         try {
             reader = new PdfReader(pdfFile.getPath());
-            int pageCount = reader.getNumberOfPages();
+            pageCount = reader.getNumberOfPages();
             if (Math.abs(pageCount % 2) == 1) {//取偶
                 ByteArrayOutputStream baos = new ByteArrayOutputStream();
                 PdfStamper stamper = new PdfStamper(reader, baos);
@@ -113,7 +117,7 @@ public class PdfUtil {
                 fileOutputStream.close();
             }
         }
-        return Objects.nonNull(reader) ? reader.getNumberOfPages() : 0;
+        return new PdfDto(PageSizeEnum.A3, Objects.nonNull(reader) ? reader.getNumberOfPages() : 0, pageCount);
     }
 
     /**

+ 10 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/util/RedisUtil.java

@@ -214,6 +214,16 @@ public class RedisUtil {
         redisTemplate.opsForHash().putAll(key, map);
     }
 
+    /**
+     * 保存list
+     *
+     * @param key
+     * @param Object
+     */
+    public void setForList(String key, Object Object) {
+        redisTemplate.opsForList().leftPush(key, Object);
+    }
+
     /**
      * 设置过期时间(秒)
      *

+ 8 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/util/ServletUtil.java

@@ -158,6 +158,14 @@ public class ServletUtil {
         return object;
     }
 
+    /**
+     * 获取header中schoolId
+     * @return
+     */
+    public static Object getRequestHeaderSchoolIdByNotVaild() {
+        return getRequest().getHeader(SystemConstant.SCHOOL_ID);
+    }
+
     /**
      * 获取请求的学校
      *

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

@@ -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_task_id` bigint(20) NOT NULL COMMENT '命题任务ID',
+  `exam_task_id` bigint(20) NULL COMMENT '命题任务ID',
   `course_code` varchar(100) NOT NULL COMMENT '课程代码',
   `course_name` varchar(200) NOT NULL COMMENT '课程名称',
   `paper_number` varchar(50) NOT NULL COMMENT '试卷编号',
@@ -220,7 +220,7 @@ CREATE TABLE `exam_card`  (
   `school_id` bigint(20) NOT NULL,
   `course_code` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '课程编码',
   `course_name` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '课程名称',
-  `title` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '标题',
+  `title` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '标题',
   `make_method` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '题卡制作方式:SELECT-选择已有题卡,SELF-自助创建,CUST-客户制卡',
   `status` varchar(45) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'STAGE-暂存,SUBMIT-提交',
   `create_id` bigint(20) NULL DEFAULT NULL,
@@ -239,9 +239,10 @@ DROP TABLE IF EXISTS `exam_card_detail`;
 CREATE TABLE `exam_card_detail`  (
   `id` bigint(20) NOT NULL,
   `card_id` bigint(20) NOT NULL COMMENT '题卡ID',
-  `content` MEDIUMTEXT CHARACTER SET utf8 COLLATE utf8_general_ci NULL,
-  `html_content` MEDIUMTEXT CHARACTER SET utf8 COLLATE utf8_general_ci NULL,
-  `attachment_id` MEDIUMTEXT CHARACTER SET utf8 COLLATE utf8_general_ci NULL,
+  `content` MEDIUMTEXT  NULL COMMENT '题卡工具制作题卡内容',
+  `html_content` MEDIUMTEXT  NULL COMMENT 'html格式内容',
+  `attachment_id` MEDIUMTEXT  NULL COMMENT '备用题卡json',
+  `cust_attachment_id` bigint(20)  NULL COMMENT '客服制卡上传附件ID',
   `create_id` bigint(20) NULL DEFAULT NULL,
   `create_time` bigint(20) NULL DEFAULT NULL,
   `update_id` bigint(20) NULL DEFAULT NULL,
@@ -277,6 +278,7 @@ CREATE TABLE `exam_detail`  (
   `create_time` bigint(20) NULL DEFAULT NULL,
   `update_id` bigint(20) NULL DEFAULT NULL,
   `update_time` bigint(20) NULL DEFAULT NULL,
+  `attachment_path` mediumtext COMMENT '印品附件路径',
   PRIMARY KEY (`id`) USING BTREE
 ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '考务数据' ROW_FORMAT = Dynamic;
 
@@ -298,6 +300,7 @@ CREATE TABLE `exam_detail_course`  (
   `create_time` bigint(20) NULL DEFAULT NULL,
   `update_id` bigint(20) NULL DEFAULT NULL,
   `update_time` bigint(20) NULL DEFAULT NULL,
+  `paper_type` varchar(30) DEFAULT NULL COMMENT '当前试卷类型',
   PRIMARY KEY (`id`) USING BTREE
 ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '考务数据(考场关联科目)' ROW_FORMAT = Dynamic;
 
@@ -399,6 +402,25 @@ CREATE TABLE `exam_task_detail`  (
   PRIMARY KEY (`id`) USING BTREE
 ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '命题任务明细表(入库申请)' ROW_FORMAT = Dynamic;
 
+-- ----------------------------
+-- Table structure for exam_task_paper_log
+-- ----------------------------
+DROP TABLE IF EXISTS `exam_task_paper_log`;
+CREATE TABLE `exam_task_paper_log`  (
+  `id` bigint(20) NOT NULL,
+  `exam_task_id` bigint(20) NOT NULL COMMENT '命题任务ID',
+  `paper_type` varchar(45) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
+  `paper_attachment_ids` mediumtext CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '修改后试卷',
+  `card_id` bigint(20) NULL DEFAULT NULL COMMENT '修改后题卡ID',
+  `review` tinyint(1) NULL DEFAULT NULL COMMENT '是否审核:true-审核,false-未审核',
+  `review_status` varchar(45) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '审核状态:PASS-通过,NOT_PASS-不通过',
+  `create_id` bigint(20) NULL DEFAULT NULL,
+  `create_time` bigint(20) NULL DEFAULT NULL,
+  `update_id` bigint(20) NULL DEFAULT NULL,
+  `update_time` bigint(20) NULL DEFAULT NULL,
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '卷库修改审核临时表' ROW_FORMAT = Dynamic;
+
 -- ----------------------------
 -- Table structure for exam_task_review_log
 -- ----------------------------
@@ -407,7 +429,7 @@ CREATE TABLE `exam_task_review_log`  (
   `id` bigint(20) NOT NULL,
   `exam_task_id` bigint(20) NOT NULL COMMENT '命题任务ID',
   `review_status` varchar(8) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 'PASS-通过,NOT_PASS-不通过',
-  `reason` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '审核意见',
+  `reason` MEDIUMTEXT CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '审核意见',
   `operate_id` bigint(20) NULL DEFAULT NULL,
   `operate_time` bigint(20) NULL DEFAULT NULL,
   `create_id` bigint(20) NULL DEFAULT NULL,
@@ -701,7 +723,7 @@ INSERT INTO `sys_privilege` VALUES (3, '配置管理', 'rule', 'MENU', 1, 2, NUL
 INSERT INTO `sys_privilege` VALUES (4, '组织架构', 'OrganizationManage', 'MENU', 2, 1, NULL, NULL, NULL, 1);
 INSERT INTO `sys_privilege` VALUES (5, '用户管理', 'UserManage', 'MENU', 2, 2, NULL, NULL, NULL, 1);
 INSERT INTO `sys_privilege` VALUES (6, '角色管理', 'RoleManage', 'MENU', 2, 3, NULL, NULL, NULL, 1);
-INSERT INTO `sys_privilege` VALUES (7, '权限管理', 'MenuManage', 'MENU', 2, 4, NULL, NULL, NULL, 1);
+INSERT INTO `sys_privilege` VALUES (7, '权限管理', 'MenuManage', 'MENU', 129, 6, NULL, NULL, NULL, 1);
 INSERT INTO `sys_privilege` VALUES (8, '通用规则', 'CommonRule', 'MENU', 3, 1, NULL, NULL, NULL, 1);
 INSERT INTO `sys_privilege` VALUES (9, '题卡规则管理', 'CardRuleManage', 'MENU', 3, 2, NULL, NULL, NULL, 1);
 INSERT INTO `sys_privilege` VALUES (10, '通卡模板', 'CommonCardTemplate', 'MENU', 3, 3, NULL, NULL, NULL, 1);
@@ -743,7 +765,7 @@ INSERT INTO `sys_privilege` VALUES (65, '命题任务管理-启用/禁用', '/ap
 INSERT INTO `sys_privilege` VALUES (66, '命题任务管理-新建', '/api/admin/exam/task/save', 'URL', 39, 4, 'AUTH', NULL, NULL, 1);
 INSERT INTO `sys_privilege` VALUES (67, '命题任务管理-批量新建-文件导入', '/api/admin/exam/task/import', 'URL', 39, 5, 'AUTH', NULL, NULL, 1);
 INSERT INTO `sys_privilege` VALUES (68, '命题任务管理-批量新建', '/api/admin/exam/task/save_batch', 'URL', 39, 6, 'AUTH', NULL, NULL, 1);
-INSERT INTO `sys_privilege` VALUES (69, '命题任务管理-审核历史', '/api/admin/exam/task/review_list', 'URL', 39, 7, 'AUTH', NULL, NULL, 1);
+INSERT INTO `sys_privilege` VALUES (69, '命题任务管理-审核历史', '/api/admin/exam/task/review_list', 'URL', 39, 7, 'SYS', NULL, NULL, 1);
 INSERT INTO `sys_privilege` VALUES (70, '入库申请-查询', '/api/admin/exam/task/apply_list', 'URL', 40, 1, 'AUTH', NULL, NULL, 1);
 INSERT INTO `sys_privilege` VALUES (71, '入库申请-提交/暂存', '/api/admin/exam/task/apply_save', 'URL', 40, 2, 'AUTH', NULL, NULL, 1);
 INSERT INTO `sys_privilege` VALUES (72, '入库申请-撤回/重新申请', '/api/admin/exam/task/apply_status', 'URL', 40, 3, 'AUTH', NULL, NULL, 1);
@@ -761,12 +783,12 @@ INSERT INTO `sys_privilege` VALUES (83, '角色管理-查询', '/api/admin/sys/r
 INSERT INTO `sys_privilege` VALUES (84, '角色管理-删除', '/api/admin/sys/role/remove', 'URL', 6, 2, 'AUTH', NULL, NULL, 1);
 INSERT INTO `sys_privilege` VALUES (85, '角色管理-新增/修改', '/api/admin/sys/role/save', 'URL', 6, 3, 'AUTH', NULL, NULL, 1);
 INSERT INTO `sys_privilege` VALUES (86, '角色管理-启用/禁用', '/api/admin/sys/role/enable', 'URL', 6, 4, 'AUTH', NULL, NULL, 1);
-INSERT INTO `sys_privilege` VALUES (87, '角色管理-用户已绑定角色列表', '/api/admin/sys/role/get_user_roles', 'URL', 6, 5, 'AUTH', NULL, NULL, 1);
+INSERT INTO `sys_privilege` VALUES (87, '用户管理-用户已绑定角色列表', '/api/admin/sys/role/get_user_roles', 'URL', 5, 5, 'AUTH', NULL, NULL, 1);
 INSERT INTO `sys_privilege` VALUES (88, '权限管理-查询', '/api/admin/sys/privilege/list', 'URL', 7, 1, 'AUTH', NULL, NULL, 1);
 INSERT INTO `sys_privilege` VALUES (89, '权限管理-新增/修改', '/api/admin/sys/privilege/save', 'URL', 7, 2, 'AUTH', NULL, NULL, 1);
 INSERT INTO `sys_privilege` VALUES (90, '权限管理-删除', '/api/admin/sys/privilege/remove', 'URL', 7, 3, 'AUTH', NULL, NULL, 1);
-INSERT INTO `sys_privilege` VALUES (91, '权限管理-角色已绑定权限列表', '/api/admin/sys/privilege/get_role_privileges', 'URL', 7, 4, 'AUTH', NULL, NULL, 1);
-INSERT INTO `sys_privilege` VALUES (92, '组织机构-查询', '/api/admin/sys/org/list', 'URL', 4, 1, 'AUTH', NULL, NULL, 1);
+INSERT INTO `sys_privilege` VALUES (91, '角色管理-角色已绑定权限列表', '/api/admin/sys/privilege/get_role_privileges', 'URL', 6, 4, 'AUTH', NULL, NULL, 1);
+INSERT INTO `sys_privilege` VALUES (92, '组织机构-查询', '/api/admin/sys/org/list', 'URL', 4, 1, 'SYS', NULL, NULL, 1);
 INSERT INTO `sys_privilege` VALUES (93, '组织机构-新增/修改', '/api/admin/sys/org/save', 'URL', 4, 2, 'AUTH', NULL, NULL, 1);
 INSERT INTO `sys_privilege` VALUES (94, '组织机构-删除', '/api/admin/sys/org/remove', 'URL', 4, 3, 'AUTH', NULL, NULL, 1);
 INSERT INTO `sys_privilege` VALUES (95, '组织机构-启用/禁用', '/api/admin/sys/org/enable', 'URL', 4, 4, 'AUTH', NULL, NULL, 1);
@@ -800,31 +822,31 @@ INSERT INTO `sys_privilege` VALUES (128, '普通印品模板-启用/禁用', '/a
 INSERT INTO `sys_privilege` VALUES (129, '公共接口', 'common', 'MENU', NULL, 31, NULL, NULL, 1618276314557, 1);
 INSERT INTO `sys_privilege` VALUES (130, '用户登录相关', 'login', 'MENU', 129, 1, NULL, NULL, 1618276356747, 1);
 INSERT INTO `sys_privilege` VALUES (131, '用户登录', '/api/admin/common/login', 'URL', 130, 1, 'NO_AUTH', NULL, 1618276400583, 1);
-INSERT INTO `sys_privilege` VALUES (132, '查询用户权限', '/api/admin/common/get_menu', 'URL', 130, 2, 'AUTH', NULL, 1618276452859, 1);
-INSERT INTO `sys_privilege` VALUES (133, '发送验证码', '/api/admin/common/get_verify_code', 'URL', 130, 3, 'AUTH', NULL, 1618276515195, 1);
-INSERT INTO `sys_privilege` VALUES (134, '修改密码', '/api/admin/sys/user/update_password', 'URL', 130, 4, 'AUTH', NULL, 1618276598837, 1);
-INSERT INTO `sys_privilege` VALUES (135, '用户登出', '/api/admin/common/logout', 'URL', 130, 5, 'AUTH', NULL, 1618276619911, 1);
+INSERT INTO `sys_privilege` VALUES (132, '查询用户权限', '/api/admin/common/get_menu', 'URL', 130, 2, 'SYS', NULL, 1618276452859, 1);
+INSERT INTO `sys_privilege` VALUES (133, '发送验证码', '/api/admin/common/get_verify_code', 'URL', 130, 3, 'SYS', NULL, 1618276515195, 1);
+INSERT INTO `sys_privilege` VALUES (134, '修改密码', '/api/admin/sys/user/update_password', 'URL', 130, 4, 'SYS', NULL, 1618276598837, 1);
+INSERT INTO `sys_privilege` VALUES (135, '用户登出', '/api/admin/common/logout', 'URL', 130, 5, 'SYS', NULL, 1618276619911, 1);
 INSERT INTO `sys_privilege` VALUES (136, '模糊查询', 'query', 'MENU', 129, 2, NULL, NULL, 1618276655623, 1);
-INSERT INTO `sys_privilege` VALUES (137, '模糊查询-印刷计划', '/api/admin/exam/print/query', 'URL', 136, 1, 'AUTH', NULL, 1618276890195, 1);
-INSERT INTO `sys_privilege` VALUES (138, '模糊查询-题卡规则', '/api/admin/basic/card_rule/query', 'URL', 136, 2, 'AUTH', NULL, 1618276948061, 1);
-INSERT INTO `sys_privilege` VALUES (139, '模糊查询-课程', '/api/admin/basic/course/query', 'URL', 136, 3, 'AUTH', NULL, 1618276979583, 1);
-INSERT INTO `sys_privilege` VALUES (140, '模糊查询-试卷编号', '/api/admin/exam/task/paper_number_query', 'URL', 136, 4, 'AUTH', NULL, 1618277023075, 1);
-INSERT INTO `sys_privilege` VALUES (141, '模糊查询-命题老师', '/api/admin/exam/task/user_query', 'URL', 136, 5, 'AUTH', NULL, 1618277050673, 1);
-INSERT INTO `sys_privilege` VALUES (142, '模糊查询-考点', '/api/admin/exam/print/data_place_query', 'URL', 136, 6, 'AUTH', NULL, 1618277080906, 1);
-INSERT INTO `sys_privilege` VALUES (143, '模糊查询-考场', '/api/admin/exam/print/data_room_query', 'URL', 136, 7, 'AUTH', NULL, 1618277102519, 1);
+INSERT INTO `sys_privilege` VALUES (137, '模糊查询-印刷计划', '/api/admin/exam/print/query', 'URL', 136, 1, 'SYS', NULL, 1618276890195, 1);
+INSERT INTO `sys_privilege` VALUES (138, '模糊查询-题卡规则', '/api/admin/basic/card_rule/query', 'URL', 136, 2, 'SYS', NULL, 1618276948061, 1);
+INSERT INTO `sys_privilege` VALUES (139, '模糊查询-课程', '/api/admin/basic/course/query', 'URL', 136, 3, 'SYS', NULL, 1618276979583, 1);
+INSERT INTO `sys_privilege` VALUES (140, '模糊查询-试卷编号', '/api/admin/exam/task/paper_number_query', 'URL', 136, 4, 'SYS', NULL, 1618277023075, 1);
+INSERT INTO `sys_privilege` VALUES (141, '模糊查询-命题老师', '/api/admin/exam/task/user_query', 'URL', 136, 5, 'SYS', NULL, 1618277050673, 1);
+INSERT INTO `sys_privilege` VALUES (142, '模糊查询-考点', '/api/admin/exam/print/data_place_query', 'URL', 136, 6, 'SYS', NULL, 1618277080906, 1);
+INSERT INTO `sys_privilege` VALUES (143, '模糊查询-考场', '/api/admin/exam/print/data_room_query', 'URL', 136, 7, 'SYS', NULL, 1618277102519, 1);
 INSERT INTO `sys_privilege` VALUES (144, '文件相关', 'file', 'MENU', 129, 3, NULL, NULL, 1618278402138, 1);
-INSERT INTO `sys_privilege` VALUES (145, '文件上传', '/api/admin/common/file/upload', 'URL', 144, 1, 'AUTH', NULL, 1618278573080, 1);
-INSERT INTO `sys_privilege` VALUES (146, '文件查询', '/api/admin/common/file/get_one', 'URL', 144, 2, 'AUTH', NULL, 1618278641214, 1);
-INSERT INTO `sys_privilege` VALUES (147, '文件下载', '/api/admin/common/file/download', 'URL', 144, 3, 'AUTH', NULL, 1618278672207, 1);
-INSERT INTO `sys_privilege` VALUES (148, '文件预览', '/api/admin/common/file/preview', 'URL', 144, 4, 'AUTH', NULL, 1618278691498, 1);
+INSERT INTO `sys_privilege` VALUES (145, '文件上传', '/api/admin/common/file/upload', 'URL', 144, 1, 'SYS', NULL, 1618278573080, 1);
+INSERT INTO `sys_privilege` VALUES (146, '文件查询', '/api/admin/common/file/get_one', 'URL', 144, 2, 'SYS', NULL, 1618278641214, 1);
+INSERT INTO `sys_privilege` VALUES (147, '文件下载', '/api/admin/common/file/download', 'URL', 144, 3, 'SYS', NULL, 1618278672207, 1);
+INSERT INTO `sys_privilege` VALUES (148, '文件预览', '/api/admin/common/file/preview', 'URL', 144, 4, 'SYS', NULL, 1618278691498, 1);
 INSERT INTO `sys_privilege` VALUES (149, '系统相关', 'sys', 'MENU', 129, 4, NULL, NULL, 1618278754471, 1);
-INSERT INTO `sys_privilege` VALUES (150, '查询枚举类型', '/api/admin/common/get_enums', 'URL', 149, 1, 'AUTH', NULL, 1618278867874, 1);
-INSERT INTO `sys_privilege` VALUES (151, '查询学校列表', '/api/admin/common/school/list', 'URL', 149, 2, 'AUTH', NULL, 1618279075676, 1);
+INSERT INTO `sys_privilege` VALUES (150, '查询枚举类型', '/api/admin/common/get_enums', 'URL', 149, 1, 'SYS', NULL, 1618278867874, 1);
+INSERT INTO `sys_privilege` VALUES (151, '查询学校列表', '/api/admin/common/school/list', 'URL', 149, 2, 'SYS', NULL, 1618279075676, 1);
 INSERT INTO `sys_privilege` VALUES (152, '查询系统参数', '/api/admin/common/sys_config/get_one', 'URL', 149, 3, 'NO_AUTH', NULL, 1618279142302, 1);
 INSERT INTO `sys_privilege` VALUES (153, '根据学校代码查询学校信息', '/api/admin/common/school/query_by_school_code', 'URL', 149, 4, 'NO_AUTH', NULL, 1618279184033, 1);
 INSERT INTO `sys_privilege` VALUES (154, '其他', 'other', 'MENU', 129, 5, NULL, NULL, 1618279415391, 1);
-INSERT INTO `sys_privilege` VALUES (155, '用户导入(异步)', '/api/admin/sys/user/async/import', 'URL', 154, 1, 'AUTH', NULL, 1618279437670, 1);
-INSERT INTO `sys_privilege` VALUES (156, '用户导出', '/api/admin/sys/user/export', 'URL', 154, 2, 'AUTH', NULL, 1618279460909, 1);
+INSERT INTO `sys_privilege` VALUES (155, '用户导入(异步)', '/api/admin/sys/user/async/import', 'URL', 154, 1, 'SYS', NULL, 1618279437670, 1);
+INSERT INTO `sys_privilege` VALUES (156, '用户导出', '/api/admin/sys/user/export', 'URL', 154, 2, 'SYS', NULL, 1618279460909, 1);
 INSERT INTO `sys_privilege` VALUES (157, '考务数据导入-模板下载', '/api/admin/exam/print/template_download', 'URL', 44, 5, 'AUTH', NULL, 1618279526607, 1);
 INSERT INTO `sys_privilege` VALUES (158, '考务数据导入-结果导出', '/api/admin/exam/print/data_export', 'URL', 44, 6, 'AUTH', NULL, 1618279673622, 1);
 INSERT INTO `sys_privilege` VALUES (159, '考务明细查询-查询', '/api/admin/exam/print/data_detail', 'URL', 45, 1, 'AUTH', NULL, 1618279759583, 1);
@@ -836,8 +858,8 @@ INSERT INTO `sys_privilege` VALUES (164, '卷库查询-下载试卷', '/api/admi
 INSERT INTO `sys_privilege` VALUES (165, '卷库查询-试卷启用/禁用', '/api/admin/exam/task/paper_enable', 'URL', 42, 3, 'AUTH', NULL, 1618280085672, 1);
 INSERT INTO `sys_privilege` VALUES (166, '入库审核-查询已审核', '/api/admin/exam/task/review_list_audited', 'URL', 41, 5, 'AUTH', NULL, 1618280139790, 1);
 INSERT INTO `sys_privilege` VALUES (167, '入库申请-查询可选择题卡', '/api/admin/exam/card/select_card_list', 'URL', 40, 4, 'AUTH', NULL, 1618280304150, 1);
-INSERT INTO `sys_privilege` VALUES (168, '入库申请-查询申请详情', '/api/admin/exam/task/apply_get_one', 'URL', 40, 5, 'AUTH', NULL, 1618280348974, 1);
-INSERT INTO `sys_privilege` VALUES (169, '用户管理-根据课程查询命题老师', '/api/admin/sys/user/user_list', 'URL', 5, 7, 'AUTH', NULL, 1618280688210, 1);
+INSERT INTO `sys_privilege` VALUES (168, '入库申请-查询申请详情', '/api/admin/exam/task/apply_get_one', 'URL', 40, 5, 'SYS', NULL, 1618280348974, 1);
+INSERT INTO `sys_privilege` VALUES (169, '命题任务管理-根据课程查询命题老师', '/api/admin/sys/user/user_list', 'URL', 39, 7, 'AUTH', NULL, 1618280688210, 1);
 INSERT INTO `sys_privilege` VALUES (170, '客服制卡', 'customer', 'MENU', NULL, 4, NULL, NULL, 1618282871937, 1);
 INSERT INTO `sys_privilege` VALUES (171, '客服制卡', 'customer', 'MENU', 170, 1, NULL, NULL, 1618282892511, 1);
 INSERT INTO `sys_privilege` VALUES (172, '题卡审核', 'CustomerCard', 'MENU', 171, 1, NULL, NULL, 1618282907795, 1);
@@ -847,8 +869,33 @@ INSERT INTO `sys_privilege` VALUES (175, '题卡管理', 'card', 'MENU', NULL, 5
 INSERT INTO `sys_privilege` VALUES (176, '题卡管理-查询题卡规则', '/api/admin/basic/card_rule/get_one', 'URL', 175, 1, 'AUTH', NULL, 1618283074324, 1);
 INSERT INTO `sys_privilege` VALUES (177, '题卡管理-查询题卡详情', '/api/admin/exam/card/get_one', 'URL', 175, 2, 'AUTH', NULL, 1618283096674, 1);
 INSERT INTO `sys_privilege` VALUES (178, '题卡管理-保存/提交', '/api/admin/exam/card/save', 'URL', 175, 3, 'AUTH', NULL, 1618283124980, 1);
-INSERT INTO `sys_privilege` VALUES (179, '查询考务规则', '/api/admin/basic/exam_rule/list', 'URL', 149, 5, 'AUTH', NULL, 1618295452892, 1);
-
+INSERT INTO `sys_privilege` VALUES (179, '查询考务规则', '/api/admin/basic/exam_rule/list', 'URL', 149, 5, 'SYS', NULL, 1618295452892, 1);
+INSERT INTO `sys_privilege` VALUES (180, '角色管理-查询可设置权限列表', '/api/admin/sys/privilege/list_auth', 'URL', 6, 6, 'AUTH', NULL, 1618379766163, 1);
+INSERT INTO `sys_privilege` VALUES (181, '超管中心', 'admin', 'MENU', 129, 7, NULL, NULL, 1618387216180, 1);
+INSERT INTO `sys_privilege` VALUES (182, '查询客服', '/api/admin/sys/user/list_customer', 'URL', 181, 1, 'SYS', NULL, 1618387265194, 1);
+INSERT INTO `sys_privilege` VALUES (183, '新增客服', '/api/admin/sys/user/save_customer', 'URL', 181, 2, 'SYS', NULL, 1618387304029, 1);
+INSERT INTO `sys_privilege` VALUES (184, '用户管理-查询用户可绑定角色', '/api/admin/sys/role/list_to_user', 'URL', 5, 7, 'AUTH', NULL, 1618387370044, 1);
+INSERT INTO `sys_privilege` VALUES (185,'客服制卡-批量下载文件','/api/admin/exam/card/download_files','URL',172,2,'AUTH',NULL,1618282968373,1);
+INSERT INTO `sys_privilege` VALUES (186,'印刷任务管理-查看印品','/api/admin/exam/print/template_view','URL',47,8,'AUTH',NULL,1618986009123,1);
+INSERT INTO `sys_privilege` VALUES (187,'客户端登录','/api/admin/client/user/login','URL',NULL,1,'NO_AUTH',NULL,NULL,1);
+INSERT INTO `sys_privilege` VALUES (188,'考务明细查询-学生明细','/api/admin/exam/print/get_student_detail','URL',45,2,'SYS',NULL,1619502584844,1);
+INSERT INTO `sys_privilege` VALUES (189,'卷库查询-修改','/api/admin/exam/task/paper_update','URL',42,4,'AUTH',NULL,1619502584844,1);
+INSERT INTO `sys_privilege` VALUES (199,'客户端','client','MENU',NULL,22,NULL,NULL,1619502252306,1);
+INSERT INTO `sys_privilege` VALUES (200,'试卷打样-查询列表','/api/admin/client/paper_try/list','URL',199,2,'AUTH',NULL,NULL,1);
+INSERT INTO `sys_privilege` VALUES (201,'试卷打样-查看/试印/重印','/api/admin/client/paper_try/print','URL',199,3,'AUTH',NULL,NULL,1);
+INSERT INTO `sys_privilege` VALUES (202,'试卷打样-批量试印','/api/admin/client/paper_try/print_batch','URL',199,4,'AUTH',NULL,NULL,1);
+INSERT INTO `sys_privilege` VALUES (203,'试卷打样-标记合格状态','/api/admin/client/paper_try/tag_pass','URL',199,5,'AUTH',NULL,NULL,1);
+INSERT INTO `sys_privilege` VALUES (204,'印刷管理-查询列表','/api/admin/client/print/task_list','URL',199,6,'AUTH',NULL,NULL,1);
+INSERT INTO `sys_privilege` VALUES (205,'印刷管理-导出','/api/admin/client/print/task_list_export','URL',199,7,'AUTH',NULL,NULL,1);
+INSERT INTO `sys_privilege` VALUES (206,'印刷管理-汇总数据查询','/api/admin/client/print/task_total_data','URL',199,8,'AUTH',NULL,NULL,1);
+INSERT INTO `sys_privilege` VALUES (207,'印刷管理-查看','/api/admin/client/print/preview','URL',199,9,'AUTH',NULL,NULL,1);
+INSERT INTO `sys_privilege` VALUES (208,'印刷管理-印刷/缓存数据','/api/admin/client/print/get_print_data','URL',199,10,'AUTH',NULL,NULL,1);
+INSERT INTO `sys_privilege` VALUES (209,'印刷管理-批量缓存','/api/admin/client/print/get_print_data_batch','URL',199,11,'AUTH',NULL,NULL,1);
+INSERT INTO `sys_privilege` VALUES (210,'印刷管理-缓存后更新状态','/api/admin/client/print/update_download','URL',199,12,'AUTH',NULL,NULL,1);
+INSERT INTO `sys_privilege` VALUES (211,'印刷管理-校验','/api/admin/client/print/validate_data','URL',199,13,'AUTH',NULL,NULL,1);
+INSERT INTO `sys_privilege` VALUES (212,'印刷管理-更新打印进度','/api/admin/client/print/update_progress','URL',199,14,'AUTH',NULL,NULL,1);
+INSERT INTO `sys_privilege` VALUES (213,'重打-查询考生列表','/api/admin/client/print/list_student','URL',199,15,'AUTH',NULL,NULL,1);
+INSERT INTO `sys_privilege` VALUES (214,'重打-内容查询','/api/admin/client/print/get_reprint_data','URL',199,16,'AUTH',NULL,NULL,1);
 -- ----------------------------
 -- Table structure for sys_role
 -- ----------------------------
@@ -910,307 +957,261 @@ CREATE TABLE `sys_role_privilege`  (
 -- ----------------------------
 -- Records of sys_role_privilege
 -- ----------------------------
-INSERT INTO `sys_role_privilege` VALUES (1381809551369105410, 114685879674470400, 170, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381809551377494018, 114685879674470400, 171, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381809551385882625, 114685879674470400, 172, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381809551385882626, 114685879674470400, 173, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381809551385882627, 114685879674470400, 175, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381809551385882628, 114685879674470400, 176, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381809551385882629, 114685879674470400, 177, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381809551394271234, 114685879674470400, 178, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381809551394271235, 114685879674470400, 130, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381809551394271236, 114685879674470400, 131, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381809551398465537, 114685879674470400, 132, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381809551398465538, 114685879674470400, 133, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381809551398465539, 114685879674470400, 134, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381809551398465540, 114685879674470400, 135, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381809551406854146, 114685879674470400, 136, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381809551406854147, 114685879674470400, 137, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381809551406854148, 114685879674470400, 138, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381809551411048450, 114685879674470400, 139, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381809551411048451, 114685879674470400, 140, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381809551411048452, 114685879674470400, 141, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381809551411048453, 114685879674470400, 142, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381809551419437058, 114685879674470400, 143, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381809551419437059, 114685879674470400, 144, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381809551419437060, 114685879674470400, 145, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381809551419437061, 114685879674470400, 146, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381809551419437062, 114685879674470400, 147, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381809551419437063, 114685879674470400, 148, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381809551427825666, 114685879674470400, 149, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381809551427825667, 114685879674470400, 150, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381809551432019969, 114685879674470400, 151, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381809551432019970, 114685879674470400, 152, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381809551432019971, 114685879674470400, 153, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381809551432019972, 114685879674470400, 129, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857482600210434, 114679324187033600, 117, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857482608599041, 114679324187033600, 118, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857482608599042, 114679324187033600, 40, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857482616987649, 114679324187033600, 70, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857482616987650, 114679324187033600, 71, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857482625376258, 114679324187033600, 72, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857482633764865, 114679324187033600, 167, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857482633764866, 114679324187033600, 168, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857482642153474, 114679324187033600, 174, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857482642153475, 114679324187033600, 175, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857482650542082, 114679324187033600, 176, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857482650542083, 114679324187033600, 177, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857482658930689, 114679324187033600, 178, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857482658930690, 114679324187033600, 130, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857482667319298, 114679324187033600, 131, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857482675707906, 114679324187033600, 132, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857482684096513, 114679324187033600, 133, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857482692485121, 114679324187033600, 134, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857482692485122, 114679324187033600, 135, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857482700873730, 114679324187033600, 138, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857482700873731, 114679324187033600, 139, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857482709262337, 114679324187033600, 140, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857482709262338, 114679324187033600, 142, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857482717650946, 114679324187033600, 143, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857482717650947, 114679324187033600, 144, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857482717650948, 114679324187033600, 145, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857482726039554, 114679324187033600, 146, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857482726039555, 114679324187033600, 147, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857482726039556, 114679324187033600, 148, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857482734428162, 114679324187033600, 150, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857482734428163, 114679324187033600, 152, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857482742816769, 114679324187033600, 153, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857482742816770, 114679324187033600, 114733730018361344, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857482747011073, 114679324187033600, 14, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857482747011074, 114679324187033600, 15, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857482747011075, 114679324187033600, 16, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857482755399681, 114679324187033600, 37, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857482759593986, 114679324187033600, 129, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857482767982594, 114679324187033600, 136, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857482767982595, 114679324187033600, 149, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857555769843714, 114680250561986560, 119, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857555778232321, 114680250561986560, 120, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857555778232322, 114680250561986560, 121, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857555786620929, 114680250561986560, 122, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857555786620930, 114680250561986560, 39, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857555795009538, 114680250561986560, 63, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857555795009539, 114680250561986560, 64, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857555795009540, 114680250561986560, 65, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857555803398145, 114680250561986560, 66, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857555803398146, 114680250561986560, 67, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857555803398147, 114680250561986560, 68, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857555811786753, 114680250561986560, 69, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857555811786754, 114680250561986560, 41, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857555811786755, 114680250561986560, 73, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857555824369666, 114680250561986560, 74, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857555824369667, 114680250561986560, 75, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857555832758274, 114680250561986560, 163, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857555832758275, 114680250561986560, 166, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857555832758276, 114680250561986560, 42, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857555841146881, 114680250561986560, 76, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857555841146882, 114680250561986560, 164, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857555841146883, 114680250561986560, 165, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857555849535489, 114680250561986560, 38, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857555849535490, 114680250561986560, 43, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857555849535491, 114680250561986560, 48, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857555857924097, 114680250561986560, 49, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857555857924098, 114680250561986560, 50, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857555866312705, 114680250561986560, 51, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857555866312706, 114680250561986560, 44, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857555866312707, 114680250561986560, 52, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857555874701313, 114680250561986560, 53, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857555874701314, 114680250561986560, 54, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857555883089921, 114680250561986560, 55, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857555883089922, 114680250561986560, 157, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857555883089923, 114680250561986560, 158, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857555891478529, 114680250561986560, 45, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857555891478530, 114680250561986560, 159, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857555899867137, 114680250561986560, 46, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857555899867138, 114680250561986560, 56, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857555899867139, 114680250561986560, 57, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857555899867140, 114680250561986560, 58, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857555912450049, 114680250561986560, 47, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857555912450050, 114680250561986560, 59, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857555920838657, 114680250561986560, 60, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857555920838658, 114680250561986560, 61, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857555929227265, 114680250561986560, 62, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857555929227266, 114680250561986560, 160, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857555937615874, 114680250561986560, 161, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857555937615875, 114680250561986560, 162, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857555937615876, 114680250561986560, 112, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857555937615877, 114680250561986560, 113, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857556113776641, 114680250561986560, 114, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857556113776642, 114680250561986560, 130, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857556122165250, 114680250561986560, 131, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857556122165251, 114680250561986560, 132, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857556122165252, 114680250561986560, 133, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857556130553857, 114680250561986560, 134, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857556130553858, 114680250561986560, 135, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857556138942465, 114680250561986560, 136, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857556138942466, 114680250561986560, 137, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857556138942467, 114680250561986560, 138, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857556147331074, 114680250561986560, 139, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857556147331075, 114680250561986560, 140, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857556155719682, 114680250561986560, 141, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857556155719683, 114680250561986560, 142, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857556155719684, 114680250561986560, 143, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857556164108289, 114680250561986560, 144, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857556164108290, 114680250561986560, 145, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857556172496897, 114680250561986560, 146, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857556172496898, 114680250561986560, 147, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857556172496899, 114680250561986560, 148, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857556180885506, 114680250561986560, 150, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857556180885507, 114680250561986560, 152, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857556189274113, 114680250561986560, 153, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857556189274114, 114680250561986560, 114733730018361344, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857556189274115, 114680250561986560, 14, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857556197662722, 114680250561986560, 15, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857556197662723, 114680250561986560, 16, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857556197662724, 114680250561986560, 37, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857556206051329, 114680250561986560, 129, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857556206051330, 114680250561986560, 149, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604348272641, 114680556444188672, 4, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604356661249, 114680556444188672, 92, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604356661250, 114680556444188672, 93, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604356661251, 114680556444188672, 94, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604356661252, 114680556444188672, 95, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604365049858, 114680556444188672, 5, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604365049859, 114680556444188672, 77, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604365049860, 114680556444188672, 78, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604373438466, 114680556444188672, 79, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604373438467, 114680556444188672, 80, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604373438468, 114680556444188672, 81, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604381827074, 114680556444188672, 82, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604381827075, 114680556444188672, 169, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604381827076, 114680556444188672, 6, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604381827077, 114680556444188672, 83, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604381827078, 114680556444188672, 84, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604390215681, 114680556444188672, 85, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604390215682, 114680556444188672, 86, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604390215683, 114680556444188672, 87, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604398604289, 114680556444188672, 3, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604398604290, 114680556444188672, 8, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604398604291, 114680556444188672, 99, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604402798593, 114680556444188672, 100, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604402798594, 114680556444188672, 9, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604402798595, 114680556444188672, 101, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604411187202, 114680556444188672, 102, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604411187203, 114680556444188672, 103, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604411187204, 114680556444188672, 104, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604411187205, 114680556444188672, 10, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604411187206, 114680556444188672, 105, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604411187207, 114680556444188672, 106, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604419575809, 114680556444188672, 107, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604419575810, 114680556444188672, 11, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604419575811, 114680556444188672, 123, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604419575812, 114680556444188672, 124, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604427964417, 114680556444188672, 125, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604427964418, 114680556444188672, 12, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604436353025, 114680556444188672, 126, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604436353026, 114680556444188672, 127, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604436353027, 114680556444188672, 128, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604436353028, 114680556444188672, 13, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604436353029, 114680556444188672, 96, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604436353030, 114680556444188672, 97, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604444741634, 114680556444188672, 98, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604444741635, 114680556444188672, 14, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604444741636, 114680556444188672, 15, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604448935938, 114680556444188672, 16, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604448935939, 114680556444188672, 117, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604448935940, 114680556444188672, 118, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604448935941, 114680556444188672, 119, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604457324545, 114680556444188672, 120, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604457324546, 114680556444188672, 121, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604457324547, 114680556444188672, 122, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604457324548, 114680556444188672, 37, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604457324549, 114680556444188672, 39, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604457324550, 114680556444188672, 63, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604465713153, 114680556444188672, 64, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604465713154, 114680556444188672, 65, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604465713155, 114680556444188672, 66, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604465713156, 114680556444188672, 67, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604465713157, 114680556444188672, 68, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604465713158, 114680556444188672, 69, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604474101761, 114680556444188672, 40, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604474101762, 114680556444188672, 70, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604474101763, 114680556444188672, 71, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604474101764, 114680556444188672, 72, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604474101765, 114680556444188672, 167, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604482490370, 114680556444188672, 168, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604482490371, 114680556444188672, 174, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604482490372, 114680556444188672, 41, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604482490373, 114680556444188672, 73, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604482490374, 114680556444188672, 74, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604482490375, 114680556444188672, 75, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604482490376, 114680556444188672, 163, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604490878977, 114680556444188672, 166, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604490878978, 114680556444188672, 42, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604490878979, 114680556444188672, 76, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604490878980, 114680556444188672, 164, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604499267586, 114680556444188672, 165, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604499267587, 114680556444188672, 38, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604499267588, 114680556444188672, 43, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604499267589, 114680556444188672, 48, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604499267590, 114680556444188672, 49, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604499267591, 114680556444188672, 50, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604507656194, 114680556444188672, 51, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604507656195, 114680556444188672, 44, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604507656196, 114680556444188672, 52, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604507656197, 114680556444188672, 53, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604507656198, 114680556444188672, 54, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604516044802, 114680556444188672, 55, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604516044803, 114680556444188672, 157, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604516044804, 114680556444188672, 158, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604516044805, 114680556444188672, 45, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604516044806, 114680556444188672, 159, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604516044807, 114680556444188672, 46, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604524433410, 114680556444188672, 56, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604524433411, 114680556444188672, 57, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604524433412, 114680556444188672, 58, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604524433413, 114680556444188672, 47, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604524433414, 114680556444188672, 59, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604524433415, 114680556444188672, 60, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604524433416, 114680556444188672, 61, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604532822018, 114680556444188672, 62, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604532822019, 114680556444188672, 160, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604532822020, 114680556444188672, 161, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604532822021, 114680556444188672, 162, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604532822022, 114680556444188672, 112, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604532822023, 114680556444188672, 113, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604541210625, 114680556444188672, 114, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604541210626, 114680556444188672, 170, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604541210627, 114680556444188672, 171, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604541210628, 114680556444188672, 172, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604541210629, 114680556444188672, 173, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604549599233, 114680556444188672, 175, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604549599234, 114680556444188672, 176, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604549599235, 114680556444188672, 177, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604549599236, 114680556444188672, 178, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604549599237, 114680556444188672, 130, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604549599238, 114680556444188672, 131, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604557987841, 114680556444188672, 132, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604557987842, 114680556444188672, 133, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604557987843, 114680556444188672, 134, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604566376449, 114680556444188672, 135, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604566376450, 114680556444188672, 136, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604574765058, 114680556444188672, 137, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604574765059, 114680556444188672, 138, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604574765060, 114680556444188672, 139, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604583153666, 114680556444188672, 140, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604583153667, 114680556444188672, 141, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604591542273, 114680556444188672, 142, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604591542274, 114680556444188672, 143, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604591542275, 114680556444188672, 144, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604591542276, 114680556444188672, 145, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604591542277, 114680556444188672, 146, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604599930882, 114680556444188672, 147, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604599930883, 114680556444188672, 148, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604599930884, 114680556444188672, 150, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604608319489, 114680556444188672, 152, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604608319490, 114680556444188672, 153, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604608319491, 114680556444188672, 114733730018361344, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604608319492, 114680556444188672, 154, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604616708097, 114680556444188672, 155, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604616708098, 114680556444188672, 156, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604616708099, 114680556444188672, 1, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604625096706, 114680556444188672, 2, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604625096707, 114680556444188672, 129, 1);
-INSERT INTO `sys_role_privilege` VALUES (1381857604625096708, 114680556444188672, 149, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079113662465, 2, 1, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079126245378, 2, 2, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079134633986, 2, 4, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079134633987, 2, 92, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079134633988, 2, 93, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079143022593, 2, 94, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079143022594, 2, 95, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079143022595, 2, 5, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079151411201, 2, 77, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079151411202, 2, 78, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079151411203, 2, 79, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079151411204, 2, 80, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079151411205, 2, 81, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079163994113, 2, 87, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079163994114, 2, 82, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079172382722, 2, 184, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079172382723, 2, 6, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079172382724, 2, 83, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079189159938, 2, 84, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079189159939, 2, 85, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079189159940, 2, 86, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079189159941, 2, 91, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079201742849, 2, 180, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079201742850, 2, 3, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079210131457, 2, 8, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079210131458, 2, 99, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079210131459, 2, 100, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079218520065, 2, 9, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079218520066, 2, 101, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079226908674, 2, 102, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079226908675, 2, 103, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079226908676, 2, 104, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079235297282, 2, 10, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079235297283, 2, 105, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079235297284, 2, 106, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079235297285, 2, 107, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079235297286, 2, 11, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079235297287, 2, 123, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079243685890, 2, 124, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079243685891, 2, 125, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079243685892, 2, 12, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079252074498, 2, 126, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079252074499, 2, 127, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079252074500, 2, 128, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079252074501, 2, 13, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079260463106, 2, 96, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079260463107, 2, 97, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079260463108, 2, 98, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079260463109, 2, 14, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079268851714, 2, 15, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079268851715, 2, 16, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079268851716, 2, 117, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079273046018, 2, 118, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079273046019, 2, 119, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079273046020, 2, 120, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079273046021, 2, 121, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079273046022, 2, 122, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079281434625, 2, 37, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079281434626, 2, 39, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079281434627, 2, 63, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079281434628, 2, 64, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079281434629, 2, 65, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079289823233, 2, 66, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079289823234, 2, 67, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079289823235, 2, 68, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079289823236, 2, 69, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079298211841, 2, 169, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079298211842, 2, 40, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079298211843, 2, 70, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079298211844, 2, 71, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079298211845, 2, 72, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079298211846, 2, 167, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079298211847, 2, 168, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079306600450, 2, 174, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079306600451, 2, 41, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079306600452, 2, 73, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079306600453, 2, 74, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079306600454, 2, 75, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079314989057, 2, 163, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079314989058, 2, 166, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079314989059, 2, 42, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079314989060, 2, 76, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079323377666, 2, 164, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079323377667, 2, 165, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079323377668, 2, 38, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079331766274, 2, 43, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079331766275, 2, 48, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079331766276, 2, 49, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079331766277, 2, 50, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079331766278, 2, 51, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079340154882, 2, 44, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079340154883, 2, 52, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079340154884, 2, 53, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079340154885, 2, 54, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079340154886, 2, 55, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079348543489, 2, 157, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079348543490, 2, 158, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079348543491, 2, 45, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079356932097, 2, 159, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079356932098, 2, 46, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079356932099, 2, 56, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079356932100, 2, 57, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079365320706, 2, 58, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079365320707, 2, 47, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079365320708, 2, 59, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079365320709, 2, 60, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079365320710, 2, 61, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079365320711, 2, 62, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079373709314, 2, 160, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079373709315, 2, 161, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079373709316, 2, 162, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079373709317, 2, 112, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079373709318, 2, 113, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079373709319, 2, 114, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079382097921, 2, 175, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079382097922, 2, 176, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079382097923, 2, 177, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382504079382097924, 2, 178, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505138762625026, 4, 117, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505138762625027, 4, 118, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505138771013633, 4, 40, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505138771013634, 4, 70, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505138771013635, 4, 71, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505138771013636, 4, 72, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505138771013637, 4, 167, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505138771013638, 4, 168, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505138779402242, 4, 174, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505138779402243, 4, 175, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505138779402244, 4, 176, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505138779402245, 4, 177, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505138779402246, 4, 178, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505138787790850, 4, 14, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505138787790851, 4, 15, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505138787790852, 4, 16, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505138787790853, 4, 37, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505172719710209, 5, 170, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505172719710210, 5, 171, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505172719710211, 5, 172, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505172728098817, 5, 173, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505172728098818, 5, 175, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505172728098819, 5, 176, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505172728098820, 5, 177, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505172728098821, 5, 178, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505274322530306, 6, 38, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505274330918913, 6, 43, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505274339307521, 6, 48, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505274339307522, 6, 49, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505274339307523, 6, 50, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505274339307524, 6, 51, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505274339307525, 6, 44, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505274347696129, 6, 52, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505274347696130, 6, 53, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505274347696131, 6, 54, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505274347696132, 6, 55, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505274356084738, 6, 157, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505274356084739, 6, 158, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505274356084740, 6, 45, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505274364473345, 6, 159, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505274364473346, 6, 46, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505274368667649, 6, 56, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505274368667650, 6, 57, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505274368667651, 6, 58, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505274368667652, 6, 47, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505274368667653, 6, 59, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505274377056257, 6, 60, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505274377056258, 6, 61, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505274381250562, 6, 62, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505274381250563, 6, 160, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505274381250564, 6, 161, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505274381250565, 6, 162, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505274389639170, 6, 112, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505274389639171, 6, 113, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505274398027778, 6, 114, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382505274398027779, 6, 14, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665569263222785, 3, 119, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665569263222786, 3, 120, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665569263222787, 3, 121, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665569263222788, 3, 122, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665569263222789, 3, 39, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665569263222790, 3, 63, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665569263222791, 3, 64, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665569263222792, 3, 65, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665569263222793, 3, 66, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665569263222794, 3, 67, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665569263222795, 3, 68, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665569263222796, 3, 169, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665569263222797, 3, 41, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665569263222798, 3, 73, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665569263222799, 3, 74, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665569263222800, 3, 75, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665569263222801, 3, 163, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665569263222802, 3, 166, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665569263222803, 3, 42, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665569263222804, 3, 76, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665569263222805, 3, 164, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665569263222806, 3, 165, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665569263222807, 3, 38, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665569263222808, 3, 43, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665569263222809, 3, 48, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665569263222810, 3, 49, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665570106277889, 3, 50, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665570114666497, 3, 51, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665570123055106, 3, 44, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665570123055107, 3, 52, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665570131443713, 3, 53, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665570139832321, 3, 54, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665570148220929, 3, 55, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665570156609538, 3, 157, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665570164998146, 3, 158, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665570173386753, 3, 45, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665570177581058, 3, 159, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665570185969665, 3, 46, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665570202746882, 3, 56, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665570211135489, 3, 57, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665570211135490, 3, 58, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665570211135491, 3, 47, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665570223718402, 3, 59, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665570232107009, 3, 60, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665570240495618, 3, 61, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665570240495619, 3, 62, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665570248884226, 3, 160, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665570257272833, 3, 161, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665570265661442, 3, 162, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665570265661443, 3, 112, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665570320187394, 3, 113, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665570328576002, 3, 114, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665570328576003, 3, 176, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665570336964610, 3, 177, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665570336964611, 3, 14, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665570345353218, 3, 15, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665570357936130, 3, 16, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665570374713345, 3, 37, 1);
+INSERT INTO `sys_role_privilege` VALUES (1382665570383101953, 3, 175, 1);
+INSERT INTO `sys_role_privilege` VALUES (1384755205368246277,5,185,1);
+INSERT INTO `sys_role_privilege` VALUES (1384755205368246278,4,42,1);
+INSERT INTO `sys_role_privilege` VALUES (1384755205368246279,4,76,1);
+INSERT INTO `sys_role_privilege` VALUES (1384755205368246280,4,164,1);
+INSERT INTO `sys_role_privilege` VALUES (1384755205368246281,3,188,1);
+INSERT INTO `sys_role_privilege` VALUES (1384755205368246282,4,189,1);
+INSERT INTO `sys_role_privilege` VALUES (1384755205368247199, 6, 199, 1);
+INSERT INTO `sys_role_privilege` VALUES (1384755205368247200, 6, 200, 1);
+INSERT INTO `sys_role_privilege` VALUES (1384755205368247201, 6, 201, 1);
+INSERT INTO `sys_role_privilege` VALUES (1384755205368247202, 6, 202, 1);
+INSERT INTO `sys_role_privilege` VALUES (1384755205368247203, 6, 203, 1);
+INSERT INTO `sys_role_privilege` VALUES (1384755205368247204, 6, 204, 1);
+INSERT INTO `sys_role_privilege` VALUES (1384755205368247205, 6, 205, 1);
+INSERT INTO `sys_role_privilege` VALUES (1384755205368247206, 6, 206, 1);
+INSERT INTO `sys_role_privilege` VALUES (1384755205368247207, 6, 207, 1);
+INSERT INTO `sys_role_privilege` VALUES (1384755205368247208, 6, 208, 1);
+INSERT INTO `sys_role_privilege` VALUES (1384755205368247209, 6, 209, 1);
+INSERT INTO `sys_role_privilege` VALUES (1384755205368247210, 6, 210, 1);
+INSERT INTO `sys_role_privilege` VALUES (1384755205368247211, 6, 211, 1);
+INSERT INTO `sys_role_privilege` VALUES (1384755205368247212, 6, 212, 1);
+INSERT INTO `sys_role_privilege` VALUES (1384755205368247213, 6, 213, 1);
+INSERT INTO `sys_role_privilege` VALUES (1384755205368247214, 6, 214, 1);
 
 -- ----------------------------
 -- Table structure for sys_user
@@ -1219,7 +1220,7 @@ DROP TABLE IF EXISTS `sys_user`;
 CREATE TABLE `sys_user`  (
   `id` bigint(20) NOT NULL,
   `school_id` bigint(20) NULL DEFAULT NULL COMMENT '学校ID',
-  `login_name` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用户名',
+  `login_name` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用户名',
   `real_name` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '姓名',
   `password` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '密码',
   `mobile_number` varchar(11) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '手机号',

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

@@ -43,5 +43,19 @@
         </where>
         order by create_time desc
     </select>
+    <select id="findByUserLoginNameAndRealName"
+            resultType="com.qmth.distributed.print.business.bean.dto.CourseInfoDto">
+        SELECT
+            bc.code AS courseCode, bc.name AS courseName
+        FROM
+            basic_course bc
+                INNER JOIN
+            basic_user_course buc ON buc.course_id = bc.id
+                INNER JOIN
+            sys_user su ON su.id = buc.user_id
+        WHERE
+            su.login_name = #{loginName}
+          AND real_name = #{realName};
+    </select>
 
 </mapper>

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

@@ -54,6 +54,9 @@
             sys_user g ON a.create_id = g.id
         <where>
             a.make_method = 'CUST'
+            <if test="schoolId != null and schoolId != ''">
+                and a.school_id = #{schoolId}
+            </if>
             <if test="status != null and status != ''">
                 and a.status = #{status}
             </if>
@@ -133,4 +136,18 @@
                 a.id = b.card_id)
         order by a.create_time desc
     </select>
+    <select id="getCardDetailBySelect" resultType="com.qmth.distributed.print.business.bean.dto.CardDetailDto">
+        SELECT
+            a.id cardId,
+            a.title,
+            a.make_method makeMethod,
+            a.type,
+            b.content,
+            b.html_content htmlContent
+        FROM
+            exam_card a
+                LEFT JOIN
+            exam_card_detail b ON a.id = b.card_id
+        where a.id = #{cardId}
+    </select>
 </mapper>

+ 52 - 2
distributed-print-business/src/main/resources/mapper/ExamDetailCourseMapper.xml

@@ -19,11 +19,15 @@
     </sql>
     <select id="listByExamDetailId" resultType="java.util.Map">
         SELECT
+            a.id examDetailCourseId,
             a.course_code courseCode,
             a.course_name courseName,
             a.paper_number paperNumber,
-            b.paper_attachment_ids paperAttachmentIds,
-            d.attachment_id attachmentIds
+            c.paper_attachment_ids paperAttachmentIds,
+            d.attachment_id attachmentIds,
+            b.id examTaskId,
+            c.exposed_paper_type exposedPaperType,
+            c.unexposed_paper_type unexposedPaperType
         FROM
             exam_detail_course a
                 LEFT JOIN
@@ -37,5 +41,51 @@
         WHERE
             a.exam_detail_id = #{examDetailId} AND b.status = #{status}
     </select>
+    <select id="listByExamDetailIdAndStatus" resultMap="BaseResultMap">
+        SELECT
+            a.*
+        FROM
+            exam_detail_course a
+                LEFT JOIN
+            exam_task b ON a.school_id = b.school_id
+                AND a.course_code = b.course_code
+                AND a.paper_number = b.paper_number
+                LEFT JOIN
+            exam_task_detail c ON b.id = c.exam_task_id
+                LEFT JOIN
+            exam_card_detail d ON c.card_id = d.card_id
+        WHERE
+            a.exam_detail_id = #{examDetailId} AND b.status != #{status}
+    </select>
+    <select id="listCoursesByPrintPlanId" resultType="com.qmth.distributed.print.business.entity.BasicCourse">
+        SELECT
+            distinct a.course_code code, a.course_name name
+        FROM
+            exam_detail_course a
+                LEFT JOIN
+            exam_detail b ON a.exam_detail_id = b.id
+        <where>
+            b.print_plan_id = #{printPlanId}
+            <if test="param != null and param != ''">
+                and (a.course_code like concat('%', #{param},'%')
+                or a.course_name like concat('%', #{param},'%'))
+            </if>
+        </where>
+
+    </select>
+    <select id="listPaperNumberByPrintPlanId" resultType="java.lang.String">
+        SELECT
+            a.paper_number paperNumber
+        FROM
+            exam_detail_course a
+                LEFT JOIN
+            exam_detail b ON a.exam_detail_id = b.id
+        <where>
+            b.print_plan_id = #{printPlanId}
+            <if test="param != null and param != ''">
+                and a.paper_number like concat('%', #{param},'%')
+            </if>
+        </where>
+    </select>
 
 </mapper>

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

@@ -42,7 +42,10 @@
             ifnull(b.pages_a3, 0) pagesA3,
             ifnull(b.pages_a4, 0) pagesA4,
             c.singlePagesA3,
-            b.status
+            b.status,
+            b.validate,
+            b.print_start_time printStartTime,
+            b.print_end_time printEndTime
         FROM
             exam_print_plan a
                  JOIN
@@ -57,33 +60,33 @@
                 exam_detail_course
                 <where>
                     <if test="courseCode != null and courseCode != ''">
-                        course_code = #{courseCode}
+                        and course_code = #{courseCode}
                     </if>
                     <if test="paperNumber != null and paperNumber != ''">
-                        paper_number = #{paperNumber}
+                        and paper_number = #{paperNumber}
                     </if>
                 </where>
             GROUP BY exam_detail_id) c ON b.id = c.exam_detail_id
-                 JOIN
+                LEFT JOIN
             sys_user d on a.create_id = d.id
             <where>
                 <if test="printPlanId != null and printPlanId != ''">
-                    a.id = #{printPlanId}
+                    and a.id = #{printPlanId}
                 </if>
                 <if test="status != null and status != ''">
-                    b.status = #{status}
+                    and b.status = #{status}
                 </if>
                 <if test="examPlace != null and examPlace != ''">
-                    b.exam_place = #{examPlace}
+                    and b.exam_place = #{examPlace}
                 </if>
                 <if test="examRoom != null and examRoom != ''">
-                    b.exam_room = #{examRoom}
+                    and b.exam_room = #{examRoom}
                 </if>
                 <if test="examStartTime != null and examStartTime != ''">
-                    b.exam_start_time &gt; #{examStartTime}
+                    and b.exam_start_time &gt; #{examStartTime}
                 </if>
                 <if test="examEndTime != null and examEndTime != ''">
-                    b.exam_end_time &lt; #{examEndTime}
+                    and b.exam_end_time &lt; #{examEndTime}
                 </if>
                 <if test="orgIds != null">
                     AND d.org_id IN
@@ -117,6 +120,8 @@
         INNER JOIN
         exam_detail_course cou ON det.id = cou.exam_detail_id
         AND det.school_id = cou.school_id
+        LEFT JOIN
+        sys_user b on det.create_id = b.id
         <where>
             <if test="schoolId != null and schoolId > 0">
                 AND det.school_id = #{schoolId}
@@ -133,6 +138,12 @@
             <if test="packageCode != null and packageCode.length > 0">
                 AND det.package_code = #{packageCode}
             </if>
+            <if test="orgIds != null">
+                AND b.org_id IN
+                <foreach collection="orgIds" item="item" index="index" open="(" separator="," close=")">
+                    #{item}
+                </foreach>
+            </if>
         </where>
         GROUP BY det.id
         <trim prefix="having" suffixOverrides="and">
@@ -162,6 +173,8 @@
             cou.paper_number AS paperNumber,
             det.print_plan_id AS printPlanId,
             det.print_plan_name AS printPlanName,
+            det.exam_start_time AS examStartTime,
+            det.exam_end_time AS examEndTime,
             det.exam_place AS examPlace,
             det.exam_room AS examRoom
         FROM
@@ -172,7 +185,12 @@
                 INNER JOIN
             exam_detail det ON cou.exam_detail_id = det.id
                 AND stu.school_id = det.school_id
+                LEFT JOIN
+            sys_user b on det.create_id = b.id
         <where>
+            <if test="schoolId != null and schoolId > 0">
+                AND det.school_id = #{schoolId}
+            </if>
             <if test="printPlanId != null and printPlanId > 0">
                 AND det.print_plan_id = #{printPlanId}
             </if>
@@ -188,8 +206,14 @@
             <if test="examRoom != null and examRoom.length > 0">
                 AND det.exam_room = #{examRoom}
             </if>
-            <if test="studentParam != null and studentParam.length > 0">
-                AND (stu.ticket_number LIKE CONCAT('%',#{studentParam},'%') OR stu.student_code LIKE CONCAT('%',#{studentParam},'%') OR stu.student_name LIKE CONCAT('%',#{studentParam},'%'))
+            <if test="studentParams != null and studentParams.length > 0">
+                AND (stu.ticket_number LIKE CONCAT('%',#{studentParams},'%') OR stu.student_code LIKE CONCAT('%',#{studentParams},'%') OR stu.student_name LIKE CONCAT('%',#{studentParams},'%'))
+            </if>
+            <if test="orgIds != null">
+                AND b.org_id IN
+                <foreach collection="orgIds" item="item" index="index" open="(" separator="," close=")">
+                    #{item}
+                </foreach>
             </if>
         </where>
     </select>
@@ -232,60 +256,19 @@
             count(b.package_code) packageCount,
             sum(b.total_subjects) totalSubjects,
             sum(ifnull(b.pages_a3, 0))/2 pagesA3,
-            sum(ifnull(b.pages_a4, 0))/2 pagesA4
-        FROM
-            exam_print_plan a
-         JOIN
-            exam_detail b ON a.id = b.print_plan_id
-        <where>
-            <if test="printPlanId != null and printPlanId != ''">
-                a.id = #{printPlanId}
-            </if>
-            <if test="status != null and status != ''">
-                b.status = #{status}
-            </if>
-            <if test="examPlace != null and examPlace != ''">
-                b.exam_place = #{examPlace}
-            </if>
-            <if test="examRoom != null and examRoom != ''">
-                b.exam_room = #{examRoom}
-            </if>
-            <if test="examStartTime != null and examStartTime != ''">
-                b.exam_start_time &gt; #{examStartTime}
-            </if>
-            <if test="examEndTime != null and examEndTime != ''">
-                b.exam_end_time &lt; #{examEndTime}
-            </if>
-        </where>
-    </select>
-    <select id="calcLeftA3" resultType="com.qmth.distributed.print.business.bean.dto.TaskTotalLeftDto">
-        SELECT
-            IFNULL(c.paper_pages_a3, 0) paperPagesA3,
-            IFNULL(c.card_pages_a3, 0) cardPagesA3,
-            IFNULL(d.print_paper_count, 0) printPaperCount,
-            IFNULL(d.print_card_count, 0) printCardCount
+            sum(ifnull(b.pages_a4, 0))/2 pagesA4,
+            sum(case b.status when 'FINISH' then 0 else ifnull(b.pages_a3, 0) end)/2 pagesA3Left,
+            sum(case b.status when 'FINISH' then 0 else ifnull(b.pages_a4, 0) end)/2 pagesA4Left
         FROM
             exam_print_plan a
          JOIN
             exam_detail b ON a.id = b.print_plan_id
         JOIN
-        exam_detail_course c
-                JOIN
-            (SELECT
-                exam_detail_course_id,
-                    SUM(CASE print_paper
-                        WHEN 0 THEN 1
-                        ELSE 0
-                    END) print_paper_count,
-                    SUM(CASE print_card
-                        WHEN 0 THEN 1
-                        ELSE 0
-                    END) print_card_count
-            FROM
-                exam_student ab
-            GROUP BY exam_detail_course_id) d ON c.id = d.exam_detail_course_id
+            sys_user d on a.create_id = d.id
         <where>
-                and c.school_id = #{schoolId}
+            <if test="schoolId != null and schoolId != ''">
+                and a.school_id = #{schoolId}
+            </if>
             <if test="printPlanId != null and printPlanId != ''">
                 and a.id = #{printPlanId}
             </if>
@@ -304,6 +287,12 @@
             <if test="examEndTime != null and examEndTime != ''">
                 and b.exam_end_time &lt; #{examEndTime}
             </if>
+            <if test="orgIds != null">
+                AND d.org_id IN
+                <foreach collection="orgIds" item="item" index="index" open="(" separator="," close=")">
+                    #{item}
+                </foreach>
+            </if>
         </where>
     </select>
     <select id="listClientExamStudentPage"
@@ -358,8 +347,49 @@
             and c.ticket_number = #{ticketNumber}
         </if>
         <if test="type == 'MORE'">
-            and c.ticket_number > 0+cast(#{ticketNumber} as char)
+            and c.ticket_number >= #{ticketNumber}
         </if>
     </select>
+    <select id="selectPaperCount" resultType="java.lang.Integer">
+        SELECT
+            COUNT(distinct c.paper_number)
+        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
+        sys_user d ON a.create_id = d.id
+        <where>
+            <if test="schoolId != null and schoolId != ''">
+                and a.school_id = #{schoolId}
+            </if>
+            <if test="printPlanId != null and printPlanId != ''">
+                and a.id = #{printPlanId}
+            </if>
+            <if test="status != null and status != ''">
+                and b.status = #{status}
+            </if>
+            <if test="examPlace != null and examPlace != ''">
+                and b.exam_place = #{examPlace}
+            </if>
+            <if test="examRoom != null and examRoom != ''">
+                and b.exam_room = #{examRoom}
+            </if>
+            <if test="examStartTime != null and examStartTime != ''">
+                and b.exam_start_time &gt; #{examStartTime}
+            </if>
+            <if test="examEndTime != null and examEndTime != ''">
+                and b.exam_end_time &lt; #{examEndTime}
+            </if>
+            <if test="orgIds != null">
+                AND d.org_id IN
+                <foreach collection="orgIds" item="item" index="index" open="(" separator="," close=")">
+                    #{item}
+                </foreach>
+            </if>
+        </where>
+    </select>
 
 </mapper>

+ 21 - 9
distributed-print-business/src/main/resources/mapper/ExamPrintPlanMapper.xml

@@ -114,12 +114,14 @@
             IFNULL(b.pages_a4, 0) pagesA4,
             c.singlePagesA3,
             b.status,
-            b.validate,
-            c.isDownload,
+            ifnull(b.validate, false) validate,
+            case c.isDownload when 0 then true else false end isDownload,
             b.print_user printUser,
             e.real_name printUserName,
             b.print_start_time printStartTime,
-            b.print_end_time printEndTime
+            b.print_end_time printEndTime,
+            case c.isTry when 0 then true else false end isTry,
+            case c.isPass when 0 then true else false end isPass
         FROM
             exam_print_plan a
                 JOIN
@@ -131,18 +133,24 @@
                     GROUP_CONCAT(a.paper_number) paperNumber,
                     GROUP_CONCAT(IFNULL(a.paper_pages_a3, 0) + IFNULL(a.card_pages_a3, 0)) singlePagesA3,
                     SUM(CASE b.is_download
-                        WHEN FALSE THEN 1
-                        ELSE 0
-                    END) isDownload
+                        WHEN true THEN 0
+                        ELSE 1
+                    END) isDownload,
+                    SUM(CASE b.is_try
+                        WHEN true THEN 0
+                        ELSE 1
+                    END) isTry,
+                    SUM(CASE b.is_pass
+                        WHEN true THEN 0
+                        ELSE 1
+                    END) isPass
             FROM
                 exam_detail_course a
             LEFT JOIN client_status b ON a.school_id = b.school_id
                 AND a.course_code = b.course_code
                 AND a.paper_number = b.paper_number
+                AND b.machine_code = #{machineCode}
             <where>
-                <if test="machineCode != null and machineCode != ''">
-                    and b.machine_code = #{machineCode}
-                </if>
                 <if test="courseCode != null and courseCode != ''">
                     and a.course_code = #{courseCode}
                 </if>
@@ -157,6 +165,10 @@
             sys_user d ON a.create_id = d.id
         <where>
             and a.school_id = #{schoolId}
+            AND b.status not IN
+            <foreach collection="examDetailStatus" item="item" index="index" open="(" separator="," close=")">
+                #{item}
+            </foreach>
             <if test="printPlanId != null and printPlanId != ''">
                 and a.id = #{printPlanId}
             </if>

+ 23 - 0
distributed-print-business/src/main/resources/mapper/ExamStudentMapper.xml

@@ -22,5 +22,28 @@
         id,
         school_id, exam_detail_course_id, student_name, student_code, ticket_number, site_number, print_paper, print_card, extend_fields, paper_type
     </sql>
+    <select id="getStudentDetail" resultType="java.util.Map">
+        SELECT
+            a.student_name studentName,
+            a.student_code studentCode,
+            a.ticket_number ticketNumber,
+            a.site_number siteNumber,
+            a.extend_fields extendFields,
+            b.course_code courseCode,
+            b.course_name courseName,
+            b.paper_number paperNumber,
+            c.exam_start_time examStartTime,
+            c.exam_end_time examEndTime,
+            c.exam_place examPlace,
+            c.exam_room examRoom
+        FROM
+            exam_student a
+                LEFT JOIN
+            exam_detail_course b ON a.exam_detail_course_id = b.id
+                LEFT JOIN
+            exam_detail c ON b.exam_detail_id = c.id
+        WHERE
+            a.id = #{id}
+    </select>
 
 </mapper>

+ 4 - 23
distributed-print-business/src/main/resources/mapper/ExamTaskDetailMapper.xml

@@ -30,6 +30,7 @@
             c.course_name courseName,
             c.paper_number paperNumber,
             c.card_rule_id cardRuleId,
+            c.specialty,
             CASE c.card_rule_id
                 WHEN - 1 THEN '全部通卡'
                 ELSE e.name
@@ -38,7 +39,7 @@
             f.real_name userName,
             d.exposed_paper_type exposedPaperType,
             d.unexposed_paper_type unexposedPaperType,
-            d.relate_paper_type relatePaperType,
+            a.paper_type relatePaperType,
             a.total_subjects totalSubjects
         FROM
         (SELECT
@@ -48,11 +49,12 @@
             b.paper_number,
             b.course_code,
             b.course_name,
+            b.paper_type,
             SUM(b.total_subjects) total_subjects
         FROM
             exam_detail a
             LEFT JOIN exam_detail_course b ON a.id = b.exam_detail_id
-        GROUP BY a.school_id , a.print_plan_id , a.print_plan_name , b.paper_number , b.course_code , b.course_name) a
+        GROUP BY a.school_id , a.print_plan_id , a.print_plan_name , b.paper_number , b.course_code , b.course_name , b.paper_type) a
             LEFT JOIN
         exam_task c ON a.school_id = c.school_id
             AND a.course_code = c.course_code
@@ -108,25 +110,4 @@
                     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>

+ 85 - 19
distributed-print-business/src/main/resources/mapper/ExamTaskMapper.xml

@@ -116,7 +116,7 @@
             a.specialty,
             a.paper_number paperNumber,
             a.card_rule_id cardRuleId,
-            b.name cardRuleName,
+            case a.card_rule_id when -1 then '全部通卡' else b.name end cardRuleName,
             a.user_id userId,
             c.real_name userName,
             a.start_time startTime,
@@ -186,7 +186,7 @@
             a.specialty,
             a.paper_number paperNumber,
             a.card_rule_id cardRuleId,
-            b.name cardRuleName,
+            case a.card_rule_id when -1 then '全部通卡' else b.name end cardRuleName,
             a.user_id userId,
             c.real_name userName,
             d.real_name createName,
@@ -213,8 +213,12 @@
             sys_user c ON a.user_id = c.id
         LEFT JOIN
             sys_user d ON a.create_id = d.id
+        LEFT JOIN
+            exam_task_paper_log e ON a.id = e.exam_task_id AND e.review = false
         <where>
-            a.enable = true and a.review = true and a.status = 'SUBMIT' and a.review_status is null
+            a.enable = true
+            and a.review = true
+            and ((a.status = 'SUBMIT' and a.review_status is null) or (a.status = 'FINISH' and e.id is not null ))
             <if test="schoolId != null and schoolId != ''">
                 and a.school_id = #{schoolId}
             </if>
@@ -254,7 +258,7 @@
             a.specialty,
             a.paper_number paperNumber,
             a.card_rule_id cardRuleId,
-            b.name cardRuleName,
+            case a.card_rule_id when -1 then '全部通卡' else b.name end cardRuleName,
             a.user_id userId,
             c.real_name userName,
             d.real_name createName,
@@ -326,12 +330,13 @@
             a.specialty,
             a.paper_number paperNumber,
             a.user_id userId,
+            a.card_rule_id cardRuleId,
             c.real_name userName,
             d.real_name createName,
             a.start_time startTime,
             a.end_time endTime,
             a.create_id createId,
-            a.create_time createTime,
+            ifnull(e.operate_time, a.update_time)  createTime,
             b.enable,
             b.paper_type paperType,
             b.exposed_paper_type exposedPaperType,
@@ -341,6 +346,12 @@
                 LEFT JOIN
             exam_task_detail b ON a.id = b.exam_task_id
                 LEFT JOIN
+            (SELECT
+                a.exam_task_id, MAX(operate_time) operate_time
+            FROM
+                exam_task_review_log a
+            GROUP BY a.exam_task_id) e ON e.exam_task_id = a.id
+                LEFT JOIN
             sys_user c ON a.user_id = c.id
                 LEFT JOIN
             sys_user d ON a.create_id = d.id
@@ -361,7 +372,10 @@
             <if test="endTime != null and endTime != ''">
                 and a.create_time &lt;= #{endTime}
             </if>
-            <if test="orgIds != null">
+            <if test="containsQuestionTeacher">
+                and a.user_id = #{userId}
+            </if>
+            <if test="!containsQuestionTeacher and orgIds != null">
                 AND d.org_id IN
                 <foreach collection="orgIds" item="item" index="index" open="(" separator="," close=")">
                     #{item}
@@ -380,23 +394,27 @@
         FROM
             exam_task
         <where>
-            school_id = #{schoolId} and course_code = #{courseCode} and enable = true
+            school_id = #{schoolId} and course_code = #{courseCode} and status = #{status} and enable = true
         </where>
     </select>
     <select id="applyGetOne" resultType="com.qmth.distributed.print.business.bean.dto.ExamTaskDetailCardDto">
         SELECT
             a.exam_task_id examTaskId,
-            a.paper_type paperType,
-            a.paper_attachment_ids paperAttachmentIds,
-            a.card_id cardId,
+            ifnull(c.paper_type, a.paper_type) paperType,
+            ifnull(c.paper_attachment_ids, a.paper_attachment_ids) paperAttachmentIds,
+            ifnull(c.card_id, a.card_id) cardId,
             a.paper_confirm_attachment_ids paperConfirmAttachmentIds,
             a.remark,
-            b.make_method makeMethod,
-            b.status
+            ifnull(d.make_method, b.make_method) makeMethod,
+            ifnull(d.status, b.status) status
         FROM
             exam_task_detail a
                 LEFT JOIN
+            exam_task_paper_log c ON a.exam_task_id = c.exam_task_id and c.review = false
+                LEFT JOIN
             exam_card b ON a.card_id = b.id
+                left join
+            exam_card d on c.card_id = d.id
         where a.exam_task_id = #{examTaskId}
     </select>
 
@@ -420,13 +438,13 @@
         <include refid="myworkCommonHead" />
         <include refid="myworkCommonMiddle" />
         <where>
-            <include refid="myworkSubmitCommonFoot" />
+            <include refid="myworkSubmitCommonFootNew" />
         </where>
     </select>
     <select id="listClientExamTaskPage"
             resultType="com.qmth.distributed.print.business.bean.dto.ClientExamTaskDto">
         SELECT
-            a.school_id schoolId,
+        distinct a.school_id schoolId,
             a.id printPlanId,
             a.name printPlanName,
             c.course_code courseCode,
@@ -436,8 +454,8 @@
             d.specialty,
             d.user_id userId,
             f.real_name userName,
-            e.is_try isTry,
-            e.is_pass isPass,
+            ifnull(e.is_try, false) isTry,
+            ifnull(e.is_pass, false) isPass,
             e.try_time tryTime
         FROM
             exam_print_plan a
@@ -451,14 +469,15 @@
                 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
+                AND e.course_code = d.course_code
+                AND e.paper_number = d.paper_number
+                and e.machine_code = #{machineCode}
                 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}
+            and a.status = #{printPlanStatus}
             <if test="printPlanId != null and printPlanId != ''">
                 and a.id = #{printPlanId}
             </if>
@@ -482,6 +501,32 @@
             </if>
         </where>
     </select>
+    <select id="listExamTaskByCardId" resultMap="BaseResultMap">
+        SELECT
+            a.*
+        FROM
+            exam_task a
+                LEFT JOIN
+            exam_task_detail b ON a.id = b.exam_task_id
+        WHERE
+            b.card_id = #{cardId}
+    </select>
+    <select id="listReviewSampleInfoByExamTaskId"
+            resultType="com.qmth.distributed.print.business.bean.dto.ReviewSampleDto">
+        SELECT
+            IFNULL(log.paper_attachment_ids,
+                   det.paper_attachment_ids) AS paperAttachmentIds,
+            IFNULL(log.card_id, det.card_id) AS cardId,
+            det.paper_confirm_attachment_ids AS paperConfirmAttachmentIds
+        FROM
+            exam_task_detail det
+                LEFT JOIN
+            exam_task_paper_log log ON det.exam_task_id = log.exam_task_id
+                AND log.review = 0
+        WHERE
+            det.exam_task_id = #{examTaskId}
+        ORDER BY det.update_time DESC
+    </select>
 
     <sql id="myworkCommonHead">
         SELECT
@@ -509,6 +554,8 @@
                 LEFT JOIN
             basic_card_rule b ON et.card_rule_id = b.id
                 LEFT JOIN
+            exam_task_paper_log d ON et.id = d.exam_task_id and d.review = false
+                LEFT JOIN
             sys_user c ON et.user_id = c.id
     </sql>
 
@@ -550,4 +597,23 @@
         </if>
         and et.enable = 1
     </sql>
+
+    <sql id="myworkSubmitCommonFootNew">
+        <choose>
+            <when test="userId != null and userId != ''">
+                and et.create_id = #{userId}
+            </when>
+        </choose>
+        <if test="schoolId != null and schoolId != ''">
+            and et.school_id = #{schoolId}
+        </if>
+        <if test="status != null and status != ''">
+            and (et.status in
+            <foreach item="item" collection="status" separator="," open="(" close=")" index="">
+                #{item}
+            </foreach>
+            or (et.status = 'FINISH' and d.id is not null))
+        </if>
+        and et.enable = 1
+    </sql>
 </mapper>

+ 4 - 0
distributed-print-business/src/main/resources/mapper/ExamTaskPaperLogMapper.xml

@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="com.qmth.distributed.print.business.mapper.ExamTaskPaperLogMapper">
+</mapper>

+ 3 - 2
distributed-print-business/src/main/resources/mapper/SysUserMapper.xml

@@ -41,8 +41,8 @@
             <if test="schoolId != null and schoolId != ''">
                 and a.school_id = #{schoolId}
             </if>
-            <if test="realName != null and realName != ''">
-                and a.real_name like concat('%', #{realName} , '%')
+            <if test="loginName != null and loginName != ''">
+                and a.login_name like concat('%', #{loginName} , '%')
             </if>
             <if test="roleId != null and roleId != ''">
                 and a.id in (select user_id from sys_user_role b where b.role_id = #{roleId})
@@ -68,6 +68,7 @@
                 LEFT JOIN
             basic_course e ON d.course_id = e.id
         <where>
+            and a.enable = true
             <if test="schoolId != null and schoolId != ''">
                 and a.school_id = #{schoolId}
             </if>

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

@@ -6,7 +6,7 @@
         select
             tbt.id,
             tbt.print_plan_id as printPlanId,
-            epp.name as printPlanName,
+            concat_ws('-', epp.name, tbt.obj_name) as printPlanName,
             tbt.`type`,
             tbt.status,
             tbt.`result`,
@@ -26,6 +26,9 @@
             left join exam_print_plan epp on
             epp.id = tbt.print_plan_id
             <where>
+                <if test="schoolId != null and schoolId != ''">
+                    and tbt.school_id = #{schoolId}
+                </if>
                 <if test="printPlanId != null and printPlanId != ''">
                     and tbt.print_plan_id = #{printPlanId}
                 </if>

+ 7 - 0
distributed-print-common/src/main/java/com/qmth/distributed/print/common/contant/SystemConstant.java

@@ -92,6 +92,13 @@ public class SystemConstant {
      */
     public static final int DEFAULT_SESSION_EXPIRE = 1;//过期时间1天
     public static final long REDIS_DEFAULT_EXPIRE_TIME = 24 * 60L * 60L;//过期时间24小时
+    public static final long REDIS_CREATE_PDF_EXPIRE_TIME = 1 * 60L * 60L;//过期时间1小时
+
+    /**
+     * redis lock
+     */
+    public static final int MAX_RETRY_COUNT = 30;
+    public static final long REDIS_CACHE_TIME_OUT = 60L;
 
     /**
      * aes相关

+ 1 - 1
distributed-print-task/src/main/java/com/qmth/distributed/print/task/job/TimedSyncSchoolJob.java

@@ -21,8 +21,8 @@ public class TimedSyncSchoolJob extends QuartzJobBean {
     @Override
     protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
         try {
-            jobService.updatePrintPlan();
             jobService.updateSchoolInfo();
+            jobService.updatePrintPlan();
         } catch (IOException e) {
             e.printStackTrace();
         }

+ 14 - 2
distributed-print-task/src/main/java/com/qmth/distributed/print/task/job/service/impl/JobServiceImpl.java

@@ -1,8 +1,10 @@
 package com.qmth.distributed.print.task.job.service.impl;
 
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.qmth.distributed.print.business.entity.ExamDetail;
 import com.qmth.distributed.print.business.entity.ExamPrintPlan;
 import com.qmth.distributed.print.business.enums.PrintPlanStatusEnum;
+import com.qmth.distributed.print.business.service.ExamDetailService;
 import com.qmth.distributed.print.business.service.ExamPrintPlanService;
 import com.qmth.distributed.print.business.service.OrgCenterDataDisposeService;
 import com.qmth.distributed.print.task.job.service.JobService;
@@ -13,6 +15,7 @@ import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
 import java.io.IOException;
+import java.util.Arrays;
 import java.util.List;
 import java.util.Objects;
 
@@ -33,6 +36,9 @@ public class JobServiceImpl implements JobService {
     @Resource
     ExamPrintPlanService examPrintPlanService;
 
+    @Resource
+    ExamDetailService examDetailService;
+
     @Override
     public void updateSchoolInfo() throws IOException {
         orgCenterDataDisposeService.updateSchoolInfo();
@@ -49,8 +55,14 @@ public class JobServiceImpl implements JobService {
         List<ExamPrintPlan> examPrintPlanList = examPrintPlanService.list(examPrintPlanQueryWrapper);
         if (Objects.nonNull(examPrintPlanList) && examPrintPlanList.size() > 0) {
             for (ExamPrintPlan examPrintPlan : examPrintPlanList) {
-                if (Objects.nonNull(examPrintPlan.getExamEndTime()) && System.currentTimeMillis() >= examPrintPlan.getExamEndTime()) {
-                    examPrintPlan.setStatus(PrintPlanStatusEnum.END);
+                QueryWrapper<ExamDetail> examDetailQueryWrapper = new QueryWrapper<>();
+                examDetailQueryWrapper.lambda().eq(ExamDetail::getPrintPlanId, examPrintPlan.getId());
+                List<ExamDetail> examDetailList = examDetailService.list(examDetailQueryWrapper);
+                if (Objects.nonNull(examDetailList) && examDetailList.size() > 0) {
+                    Long maxEndTime = examDetailList.stream().mapToLong(i -> i.getExamEndTime()).max().getAsLong();
+                    if (System.currentTimeMillis() >= maxEndTime.longValue()) {
+                        examPrintPlan.setStatus(PrintPlanStatusEnum.END);
+                    }
                 }
             }
         }

+ 3 - 2
distributed-print/src/main/java/com/qmth/distributed/print/api/BasicCourseController.java

@@ -60,8 +60,9 @@ public class BasicCourseController {
      */
     @ApiOperation(value = "模糊查询")
     @RequestMapping(value = "/query", method = RequestMethod.POST)
-    public Result query(@RequestParam(value = "param", required = false) String param){
-        List<BasicCourse> userDtos = basicCourseService.list(param);
+    public Result query(@RequestParam(value = "param", required = false) String param,
+                        @RequestParam(value = "printPlanId", required = false) Long printPlanId){
+        List<BasicCourse> userDtos = basicCourseService.list(param, printPlanId);
         return ResultUtil.ok(userDtos);
     }
 

+ 0 - 21
distributed-print/src/main/java/com/qmth/distributed/print/api/BasicTemplateOrgController.java

@@ -1,21 +0,0 @@
-package com.qmth.distributed.print.api;
-
-
-import org.springframework.web.bind.annotation.RequestMapping;
-
-import org.springframework.web.bind.annotation.RestController;
-
-/**
- * <p>
- * 适用学院(题卡规则、模板适用学院) 前端控制器
- * </p>
- *
- * @author xf
- * @since 2021-03-23
- */
-@RestController
-@RequestMapping("/basicTemplateOrg")
-public class BasicTemplateOrgController {
-
-}
-

+ 0 - 21
distributed-print/src/main/java/com/qmth/distributed/print/api/BasicUserCourseController.java

@@ -1,21 +0,0 @@
-package com.qmth.distributed.print.api;
-
-
-import org.springframework.web.bind.annotation.RequestMapping;
-
-import org.springframework.web.bind.annotation.RestController;
-
-/**
- * <p>
- * 用户和课程关联表 前端控制器
- * </p>
- *
- * @author xf
- * @since 2021-03-23
- */
-@RestController
-@RequestMapping("/basicUserCourse")
-public class BasicUserCourseController {
-
-}
-

+ 0 - 21
distributed-print/src/main/java/com/qmth/distributed/print/api/BasicVerifyCodeController.java

@@ -1,21 +0,0 @@
-package com.qmth.distributed.print.api;
-
-
-import org.springframework.web.bind.annotation.RequestMapping;
-
-import org.springframework.web.bind.annotation.RestController;
-
-/**
- * <p>
- * 短信验证码记录表 前端控制器
- * </p>
- *
- * @author xf
- * @since 2021-03-23
- */
-@RestController
-@RequestMapping("/basicVerifyCode")
-public class BasicVerifyCodeController {
-
-}
-

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است