浏览代码

Merge branch 'dev' of http://git.qmth.com.cn/wangliang/distributed-print-service into dev

xiaof 4 年之前
父节点
当前提交
1814fdaef3
共有 57 个文件被更改,包括 1478 次插入275 次删除
  1. 4 4
      distributed-print-business/pom.xml
  2. 144 7
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/dto/ClientPrintTaskDto.java
  3. 11 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/params/ClientLoginParam.java
  4. 10 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/domain/SysDomain.java
  5. 28 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/entity/BasicMessage.java
  6. 35 3
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/enums/MessageEnum.java
  7. 4 4
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/mapper/ExamPrintPlanMapper.java
  8. 1 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/mapper/ExamTaskDetailMapper.java
  9. 5 1
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/mapper/ExamTaskMapper.java
  10. 38 8
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/BasicMessageService.java
  11. 1 1
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ClientPrintDataService.java
  12. 4 4
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ClientService.java
  13. 9 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/CommonService.java
  14. 5 6
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ExamPrintPlanService.java
  15. 13 2
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ExamTaskService.java
  16. 1 1
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/OrgCenterDataDisposeService.java
  17. 1 1
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/TBTaskService.java
  18. 148 59
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/BasicMessageServiceImpl.java
  19. 1 1
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ClientPrintDataServiceImpl.java
  20. 62 7
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ClientServiceImpl.java
  21. 4 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ClientStatusServiceImpl.java
  22. 12 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/CommonServiceImpl.java
  23. 13 1
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamDetailServiceImpl.java
  24. 52 6
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamPrintPlanServiceImpl.java
  25. 75 38
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamTaskDetailServiceImpl.java
  26. 127 8
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamTaskServiceImpl.java
  27. 11 2
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/SysUserServiceImpl.java
  28. 3 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/TBTaskServiceImpl.java
  29. 1 1
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/create/AsyncCreateTaskTemplete.java
  30. 1 1
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/export/AsyncExportTaskTemplete.java
  31. 1 1
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/importData/AsyncImportTaskTemplete.java
  32. 4 8
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/service/impl/TaskLogicServiceImpl.java
  33. 29 15
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/threadPool/MyThreadPool.java
  34. 24 5
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/util/CreatePdfUtil.java
  35. 2 5
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/util/PdfUtil.java
  36. 1 0
      distributed-print-business/src/main/resources/db/init-data.sql
  37. 5 5
      distributed-print-business/src/main/resources/db/init-table.sql
  38. 1 0
      distributed-print-business/src/main/resources/mapper/BasicTemplateOrgMapper.xml
  39. 0 1
      distributed-print-business/src/main/resources/mapper/ExamDetailMapper.xml
  40. 29 24
      distributed-print-business/src/main/resources/mapper/ExamPrintPlanMapper.xml
  41. 35 4
      distributed-print-business/src/main/resources/mapper/ExamTaskDetailMapper.xml
  42. 47 5
      distributed-print-business/src/main/resources/mapper/ExamTaskMapper.xml
  43. 2 2
      distributed-print-common/src/main/java/com/qmth/distributed/print/common/contant/SystemConstant.java
  44. 9 1
      distributed-print-task/src/main/java/com/qmth/distributed/print/task/enums/JobEnum.java
  45. 26 0
      distributed-print-task/src/main/java/com/qmth/distributed/print/task/job/ResendSmsJob.java
  46. 27 0
      distributed-print-task/src/main/java/com/qmth/distributed/print/task/job/SendSmsExpireJob.java
  47. 27 0
      distributed-print-task/src/main/java/com/qmth/distributed/print/task/job/SendSmsOverdueJob.java
  48. 15 0
      distributed-print-task/src/main/java/com/qmth/distributed/print/task/job/service/JobService.java
  49. 23 4
      distributed-print-task/src/main/java/com/qmth/distributed/print/task/job/service/impl/JobServiceImpl.java
  50. 16 5
      distributed-print/src/main/java/com/qmth/distributed/print/api/ClientController.java
  51. 2 2
      distributed-print/src/main/java/com/qmth/distributed/print/api/ExamPrintPlanController.java
  52. 39 15
      distributed-print/src/main/java/com/qmth/distributed/print/api/ExamTaskController.java
  53. 16 0
      distributed-print/src/main/java/com/qmth/distributed/print/start/StartRunning.java
  54. 4 1
      distributed-print/src/main/resources/application.properties
  55. 264 0
      distributed-print/src/test/java/com/qmth/distributed/print/BasicDataImportTest.java
  56. 1 1
      distributed-print/src/test/java/com/qmth/distributed/print/ServiceTest.java
  57. 5 5
      pom.xml

+ 4 - 4
distributed-print-business/pom.xml

@@ -63,10 +63,10 @@
             <groupId>io.springfox</groupId>
             <artifactId>springfox-swagger2</artifactId>
         </dependency>
-        <dependency>
-            <groupId>com.github.xiaoymin</groupId>
-            <artifactId>swagger-bootstrap-ui</artifactId>
-        </dependency>
+<!--        <dependency>-->
+<!--            <groupId>com.github.xiaoymin</groupId>-->
+<!--            <artifactId>swagger-bootstrap-ui</artifactId>-->
+<!--        </dependency>-->
         <dependency>
             <groupId>org.jetbrains</groupId>
             <artifactId>annotations</artifactId>

+ 144 - 7
distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/dto/ClientPrintTaskDto.java

@@ -11,10 +11,12 @@ public class ClientPrintTaskDto {
     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)
+    @ExcelProperty(name = "考试开始日期", width = 30, index = 3)
+    private String examStartTimeStr;
     private Long examEndTime;
+    @ExcelProperty(name = "考试结束日期", width = 30, index = 4)
+    private String examEndTimeStr;
     @ExcelProperty(name = "课程(代码)", width = 30, index = 5)
     private String courseNameCode;
     @ExcelProperty(name = "试卷编号", width = 30, index = 6)
@@ -29,25 +31,40 @@ public class ClientPrintTaskDto {
     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)
+    @ExcelProperty(name = "印刷状态", width = 30, index = 11)
+    private String statusStr;
     private Boolean validate;
-    @ExcelProperty(name = "是否缓存", width = 30, index = 12)
+    @ExcelProperty(name = "是否校验", width = 30, index = 13)
+    private String validateStr;
     private Boolean download;
+    @ExcelProperty(name = "是否缓存", width = 30, index = 12)
+    private String downloadStr;
     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)
+    @ExcelProperty(name = "印刷开始时间", width = 30, index = 15)
+    private String printStartTimeStr;
     private Long printEndTime;
+    @ExcelProperty(name = "印刷完成时间", width = 30, index = 16)
+    private String printEndTimeStr;
     @ExcelProperty(name = "卷袋编号", width = 30, index = 1)
     private String packageCode;
     private Long createId;
     private Long createTime;
 
+    private String printContent;
+    private String variableContent;
+    private String ordinaryContent;
+
+    private Boolean incluedPaper;
+    private Boolean incluedCard;
+    private Boolean incluedSign;
+    private Boolean incluedPackage;
+    private Boolean incluedCheckin;
+
     public String getExamDetailId() {
         return examDetailId;
     }
@@ -80,6 +97,14 @@ public class ClientPrintTaskDto {
         this.examStartTime = examStartTime;
     }
 
+    public String getExamStartTimeStr() {
+        return examStartTimeStr;
+    }
+
+    public void setExamStartTimeStr(String examStartTimeStr) {
+        this.examStartTimeStr = examStartTimeStr;
+    }
+
     public Long getExamEndTime() {
         return examEndTime;
     }
@@ -88,6 +113,14 @@ public class ClientPrintTaskDto {
         this.examEndTime = examEndTime;
     }
 
+    public String getExamEndTimeStr() {
+        return examEndTimeStr;
+    }
+
+    public void setExamEndTimeStr(String examEndTimeStr) {
+        this.examEndTimeStr = examEndTimeStr;
+    }
+
     public String getCourseNameCode() {
         return courseNameCode;
     }
@@ -160,6 +193,14 @@ public class ClientPrintTaskDto {
         this.status = status;
     }
 
+    public String getStatusStr() {
+        return statusStr;
+    }
+
+    public void setStatusStr(String statusStr) {
+        this.statusStr = statusStr;
+    }
+
     public Boolean getValidate() {
         return validate;
     }
@@ -168,6 +209,14 @@ public class ClientPrintTaskDto {
         this.validate = validate;
     }
 
+    public String getValidateStr() {
+        return validateStr;
+    }
+
+    public void setValidateStr(String validateStr) {
+        this.validateStr = validateStr;
+    }
+
     public Boolean getDownload() {
         return download;
     }
@@ -176,6 +225,14 @@ public class ClientPrintTaskDto {
         this.download = download;
     }
 
+    public String getDownloadStr() {
+        return downloadStr;
+    }
+
+    public void setDownloadStr(String downloadStr) {
+        this.downloadStr = downloadStr;
+    }
+
     public Boolean getTry() {
         return isTry;
     }
@@ -208,6 +265,14 @@ public class ClientPrintTaskDto {
         this.printStartTime = printStartTime;
     }
 
+    public String getPrintStartTimeStr() {
+        return printStartTimeStr;
+    }
+
+    public void setPrintStartTimeStr(String printStartTimeStr) {
+        this.printStartTimeStr = printStartTimeStr;
+    }
+
     public Long getPrintEndTime() {
         return printEndTime;
     }
@@ -216,6 +281,14 @@ public class ClientPrintTaskDto {
         this.printEndTime = printEndTime;
     }
 
+    public String getPrintEndTimeStr() {
+        return printEndTimeStr;
+    }
+
+    public void setPrintEndTimeStr(String printEndTimeStr) {
+        this.printEndTimeStr = printEndTimeStr;
+    }
+
     public String getPackageCode() {
         return packageCode;
     }
@@ -239,4 +312,68 @@ public class ClientPrintTaskDto {
     public void setCreateTime(Long createTime) {
         this.createTime = createTime;
     }
+
+    public String getPrintContent() {
+        return printContent;
+    }
+
+    public void setPrintContent(String printContent) {
+        this.printContent = printContent;
+    }
+
+    public String getVariableContent() {
+        return variableContent;
+    }
+
+    public void setVariableContent(String variableContent) {
+        this.variableContent = variableContent;
+    }
+
+    public String getOrdinaryContent() {
+        return ordinaryContent;
+    }
+
+    public void setOrdinaryContent(String ordinaryContent) {
+        this.ordinaryContent = ordinaryContent;
+    }
+
+    public Boolean getIncluedPaper() {
+        return incluedPaper;
+    }
+
+    public void setIncluedPaper(Boolean incluedPaper) {
+        this.incluedPaper = incluedPaper;
+    }
+
+    public Boolean getIncluedCard() {
+        return incluedCard;
+    }
+
+    public void setIncluedCard(Boolean incluedCard) {
+        this.incluedCard = incluedCard;
+    }
+
+    public Boolean getIncluedSign() {
+        return incluedSign;
+    }
+
+    public void setIncluedSign(Boolean incluedSign) {
+        this.incluedSign = incluedSign;
+    }
+
+    public Boolean getIncluedPackage() {
+        return incluedPackage;
+    }
+
+    public void setIncluedPackage(Boolean incluedPackage) {
+        this.incluedPackage = incluedPackage;
+    }
+
+    public Boolean getIncluedCheckin() {
+        return incluedCheckin;
+    }
+
+    public void setIncluedCheckin(Boolean incluedCheckin) {
+        this.incluedCheckin = incluedCheckin;
+    }
 }

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

@@ -25,6 +25,9 @@ public class ClientLoginParam {
     @Length(message = "密码不能超过{max}位", max = 30)
     private String password;
 
+    @ApiModelProperty(value = "学校code")
+    private String schoolCode;
+
     public String getLoginName() {
         return loginName;
     }
@@ -40,4 +43,12 @@ public class ClientLoginParam {
     public void setPassword(String password) {
         this.password = password;
     }
+
+    public String getSchoolCode() {
+        return schoolCode;
+    }
+
+    public void setSchoolCode(String schoolCode) {
+        this.schoolCode = schoolCode;
+    }
 }

+ 10 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/domain/SysDomain.java

@@ -38,6 +38,16 @@ public class SysDomain implements Serializable {
 
     Integer threadPoolCoreSize;
 
+    boolean customThreadPoolCoreSize;
+
+    public boolean isCustomThreadPoolCoreSize() {
+        return customThreadPoolCoreSize;
+    }
+
+    public void setCustomThreadPoolCoreSize(boolean customThreadPoolCoreSize) {
+        this.customThreadPoolCoreSize = customThreadPoolCoreSize;
+    }
+
     public Integer getAutoCreatePdfResetMaxCount() {
         return autoCreatePdfResetMaxCount;
     }

+ 28 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/entity/BasicMessage.java

@@ -81,6 +81,18 @@ public class BasicMessage extends BaseEntity implements Serializable {
     @TableField("send_result")
     private String sendResult;
 
+    /**
+     * 备注
+     */
+    @TableField("remark")
+    private String remark;
+
+    /**
+     * 失败重发次数
+     */
+    @TableField("resend_count")
+    private Integer resendCount;
+
     public Long getUserId() {
         return userId;
     }
@@ -160,4 +172,20 @@ public class BasicMessage extends BaseEntity implements Serializable {
     public void setSendResult(String sendResult) {
         this.sendResult = sendResult;
     }
+
+    public String getRemark() {
+        return remark;
+    }
+
+    public void setRemark(String remark) {
+        this.remark = remark;
+    }
+
+    public Integer getResendCount() {
+        return resendCount;
+    }
+
+    public void setResendCount(Integer resendCount) {
+        this.resendCount = resendCount;
+    }
 }

+ 35 - 3
distributed-print-business/src/main/java/com/qmth/distributed/print/business/enums/MessageEnum.java

@@ -7,18 +7,50 @@ package com.qmth.distributed.print.business.enums;
  */
 public enum MessageEnum {
 
-    NOTICE_OF_AUDIT_PASS("审核通过通知"),
-    NOTICE_OF_AUDIT_NOT_PASS("审核不通过通知"),
+    /**
+     * 审核结果通知(考务老师审核触发,业务id为命题任务id,短信发送给命题老师 examTask.getUserId())
+     */
+    NOTICE_OF_AUDIT_PASS("审核通过通知", "${userName}您好,${courseName}课程、${paperNumber}试卷入库申请已通过,您可在卷库里进行查看已审核通过的试卷!"),
+    NOTICE_OF_AUDIT_NOT_PASS("审核不通过通知", "${userName}您好,${courseName}课程、${paperNumber}试卷入库申请未通过,您可查看审核意见后重新提交入库申请!"),
+
+    /**
+     * 命题任务待办提醒
+     */
+    NOTICE_OF_EXAM_TASK_CREATED("命题任务待办生成通知","${userName}您好,您有${count}条新命题待办生成,请您处理!"),
+    // 定时任务查询触发,业务id为命题老师id,短信发送给命题老师
+    NOTICE_OF_EXAM_TASK_WILL_EXPIRE("命题任务待办到期预警通知","${userName}您好,您还有${count}条命题待办即将逾期,请您尽快处理!"),
+    NOTICE_OF_EXAM_TASK_OVERDUE("命题任务待办逾期通知","${userName}您好,您今日新增${count}条命题待办逾期,请您尽快处理!"),
+
+    /**
+     * 命题分配待办提醒(定时任务查询触发,业务id为考务老师id,短信发送给考务老师)
+     */
+    NOTICE_OF_ALLOCATION_WILL_EXPIRE("命题分配待办到期预警通知","${userName}您好,您还有${count}条命题任务尚未分配命题老师,任务即将逾期,请您尽快处理!"),
+    NOTICE_OF_ALLOCATION_OVERDUE("命题分配待办逾期通知","${userName}您好,您今日新增${count}条命题分配待办逾期,请您尽快处理!"),
+
+    /**
+     * 审核待办提醒
+     */
+    // 命题任务被命题老师提交后触发,业务id为命题任务id,短信发送给考务老师 examTask.getCreateId()
+    NOTICE_OF_AUDIT_CREATED("审核待办生成通知","${userName}您好,${courseName}课程、${paperNumber}试卷已提交入库,请您尽快审核!"),
+    NOTICE_OF_AUDIT_REVIEW("审核待办修改申请通知","${userName}您好,${courseName}课程、${paperNumber}试卷重新提交修改申请,请您尽快审核!"),
+    // 定时任务查询触发,业务id为考务老师id,短信发送给考务老师
+    NOTICE_OF_AUDIT_WILL_EXPIRE("审核待办到期预警通知","${userName}您好,您还有${count}条审核待办即将逾期,请您尽快处理!"),
+    NOTICE_OF_AUDIT_OVERDUE("审核待办逾期通知","${userName}您好,您有${count}条审核待办已逾期!"),
     ;
 
-    MessageEnum(String name) {
+    MessageEnum(String name, String template) {
         this.name = name;
+        this.template = template;
     }
 
     private final String name;
+    private final String template;
 
     public String getName() {
         return name;
     }
 
+    public String getTemplate() {
+        return template;
+    }
 }

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

@@ -33,13 +33,13 @@ public interface ExamPrintPlanMapper extends BaseMapper<ExamPrintPlan> {
                                              @Param("endTime") Long endTime,
                                              @Param("orgIds") Set<Long> orgIds);
 
-    List<PrintPlanBrief> list(@Param("schoolId") Long schoolId, @Param("orgIds") Set<Long> orgIds);
+    List<PrintPlanBrief> list(@Param("schoolId") Long schoolId, @Param("source") String source, @Param("status") String[] status, @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);
+    IPage<ClientPrintTaskDto> listClientPrintTask(Page<ClientPrintTaskDto> page, @Param("schoolId") Long schoolId, @Param("machineCode") String 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, @Param("examDetailStatus") String[] examDetailStatus);
+    List<ClientPrintTaskDto> listClientPrintTask(@Param("schoolId") Long schoolId, @Param("machineCode") String 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);
 
-    ClientPrintTaskTotalDto clientTaskTotalData(@Param("schoolId") Long schoolId, @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("machineCode") Long machineCode, @Param("orgIds") Set<Long> orgIds, @Param("examDetailStatus") String[] examDetailStatus);
+    ClientPrintTaskTotalDto clientTaskTotalData(@Param("schoolId") Long schoolId, @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("machineCode") String machineCode, @Param("orgIds") Set<Long> orgIds, @Param("examDetailStatus") String[] examDetailStatus);
 
     IPage<ClientPrintStatisticsDto> listClientPrintStatistics(Page<ClientPrintStatisticsDto> page, @Param("schoolId") Long schoolId, @Param("printPlanId") String printPlanId, @Param("examPlace") String examPlace, @Param("examStartTime") Long examStartTime, @Param("examEndTime") Long examEndTime, @Param("courseCode") String courseCode, @Param("paperNumber") String paperNumber, @Param("orgIds") Set<Long> orgIds, @Param("examDetailStatus") String[] examDetailStatus);
 

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

@@ -24,4 +24,5 @@ public interface ExamTaskDetailMapper extends BaseMapper<ExamTaskDetail> {
 
     List<ExamTaskDetail> listByTemplateId(Long templateId);
 
+    List<String> listExamDetailCourse(@Param("schoolId") Long schoolId, @Param("paperType") String paperType, @Param("printPlanId") Long printPlanId, @Param("courseCode") String courseCode, @Param("paperNumber") String paperNumber);
 }

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

@@ -71,7 +71,7 @@ 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, @Param("printPlanStatus") String printPlanStatus, @Param("examDetailStatus") String examDetailStatus);
+    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);
 
@@ -83,4 +83,8 @@ public interface ExamTaskMapper extends BaseMapper<ExamTask> {
      * @return 结果
      */
     List<ReviewSampleDto> listReviewSampleInfoByExamTaskId(@Param("examTaskId") Long examTaskId);
+
+    List<ExamTask> listExamTaskExpire(@Param("startTime") Long startTime, @Param("endTime") Long endTime, @Param("status") String[] status);
+
+    List<ExamTask> listExamTaskAuditExpire(@Param("startTime") Long startTime, @Param("endTime") Long endTime);
 }

+ 38 - 8
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/BasicMessageService.java

@@ -2,6 +2,7 @@ package com.qmth.distributed.print.business.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.qmth.distributed.print.business.entity.BasicMessage;
+import com.qmth.distributed.print.business.entity.ExamTask;
 import com.qmth.distributed.print.business.entity.SysUser;
 import com.qmth.distributed.print.business.enums.MessageEnum;
 
@@ -16,20 +17,49 @@ public interface BasicMessageService extends IService<BasicMessage> {
 
     /**
      * 保存消息发送日志(以下参数必传)
-     * @param userId 接收人id
-     * @param mobileNumber 接收人电话
-     * @param businessId 业务id
+     *
+     * @param userId         接收人id
+     * @param mobileNumber   接收人电话
+     * @param businessId     业务id
      * @param variableParams 变量参数
-     * @param createId 发送人id
-     * @param messageType 消息类型
+     * @param messageType    消息类型
      */
-    void saveMessageSendLog(Long userId, String mobileNumber, Long businessId, String variableParams, Long createId, MessageEnum messageType);
+    void saveMessageSendLog(Long userId, String mobileNumber, Long businessId, String variableParams, Long createId, MessageEnum messageType, String remark);
 
     /**
      * 命题任务审核消息处理
+     *
      * @param examTaskIdList 命题任务主键集合
-     * @param messageType 消息类型枚举
-     * @param sysUser 发送信息的用户
+     * @param messageType    消息类型枚举
+     * @param sysUser        发送信息的用户
      */
     void noticeOfExamTaskAudit(List<Long> examTaskIdList, MessageEnum messageType, SysUser sysUser);
+
+    /**
+     * 发送给命题老师-命题待办提醒
+     *
+     * @param examTasks
+     */
+    void sendNoticeTaskCreate(ExamTask... examTasks);
+
+    /**
+     * 发送给考务老师-审核待办提醒、修改审核待办提醒
+     *
+     * @param examTask
+     * @param messageType
+     */
+    void sendNoticeTaskAuditCreateOrReview(ExamTask examTask, MessageEnum messageType);
+
+    /**
+     * 发送到期预警、逾期提醒
+     * @param messageType
+     * @param userId
+     * @param ids
+     */
+    void sendNoticeExpireOrOverdue(MessageEnum messageType, Long userId, List<String> ids);
+
+    /**
+     * 重发失败短信
+     */
+    void resendSmsTask();
 }

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

@@ -14,5 +14,5 @@ import java.util.List;
  * @since 2021-04-19
  */
 public interface ClientPrintDataService extends IService<ClientPrintData> {
-    List<ClientPrintData> listBySchoolIdAndMachineCode(Long schoolId, Long machineCode);
+    List<ClientPrintData> listBySchoolIdAndMachineCode(Long schoolId, String machineCode);
 }

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

@@ -23,11 +23,11 @@ public interface ClientService {
 
     Map<String, Object> getReprintData(Long examDetailId, String ticketNumber, String type);
 
-    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);
+    IPage<ClientPrintTaskDto> listClientPrintTask(String 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 examDetailId, String machineCode, Boolean isPrint, String printUser);
 
-    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);
+    List<Map<String, Object>> getPrintDataBatch(String 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);
 
@@ -37,9 +37,9 @@ public interface ClientService {
 
     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;
+    void exportClientPrintTask(HttpServletResponse response, String 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;
 
-    ClientPrintTaskTotalDto taskTotalData(String printPlanId, String status, String courseCode, String paperNumber, String examPlace, String examRoom, Long examStartTime, Long examEndTime, Boolean isDownload, Boolean validate, Long machineCode);
+    ClientPrintTaskTotalDto taskTotalData(String printPlanId, String status, String courseCode, String paperNumber, String examPlace, String examRoom, Long examStartTime, Long examEndTime, Boolean isDownload, Boolean validate, String machineCode);
 
     IPage<ClientPrintStatisticsDto> listClientPrintStatistics(String orgId, String printPlanId, String examPlace, Long examStartTime, Long examEndTime, String courseCode, String paperNumber, Integer pageNumber, Integer pageSize);
 

+ 9 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/CommonService.java

@@ -206,4 +206,13 @@ public interface CommonService {
      * @return
      */
     public String createPaperNumber(Long schoolId);
+
+    /**
+     * 校验课程关联考场是否提交打印
+     * @param schoolId
+     * @param courseCode
+     * @param paperNumber
+     * @return
+     */
+    Boolean checkExamDetailStatus(Long schoolId, String courseCode, String paperNumber);
 }

+ 5 - 6
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ExamPrintPlanService.java

@@ -11,10 +11,8 @@ import com.qmth.distributed.print.business.bean.params.DeleteParams;
 import com.qmth.distributed.print.business.bean.params.PrintPlanParams;
 import com.qmth.distributed.print.business.bean.result.PrintPlanBrief;
 import com.qmth.distributed.print.business.bean.result.PrintPlanResult;
-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 org.apache.ibatis.annotations.Param;
 
 import java.util.List;
 import java.util.Map;
@@ -47,8 +45,9 @@ public interface ExamPrintPlanService extends IService<ExamPrintPlan> {
      * 印刷计划模糊名称
      *
      * @return 印刷计划id和名称
+     * @param source
      */
-    List<PrintPlanBrief> printPlanBriefQuery();
+    List<PrintPlanBrief> printPlanBriefQuery(String source);
 
 
     /**
@@ -78,11 +77,11 @@ public interface ExamPrintPlanService extends IService<ExamPrintPlan> {
 
     List<Map<String, String>> tempalteView(Long printPlanId);
 
-    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);
+    IPage<ClientPrintTaskDto> listClientPrintTask(Page<ClientPrintTaskDto> page, Long schoolId, String machineCode, String printPlanId, String status, String courseCode, String paperNumber, String examPlace, String examRoom, Long examStartTime, Long examEndTime, Boolean isDownload, Boolean validate, Set<Long> orgIds);
 
-    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);
+    List<ClientPrintTaskDto> listClientPrintTask(Long schoolId, String machineCode, String printPlanId, String status, String courseCode, String paperNumber, String examPlace, String examRoom, Long examStartTime, Long examEndTime, Boolean isDownload, Boolean validate, Set<Long> orgIds);
 
-    ClientPrintTaskTotalDto clientTaskTotalData(String printPlanId, String status, String courseCode, String paperNumber, String examPlace, String examRoom, Long examStartTime, Long examEndTime, Boolean isDownload, Boolean validate, Long machineCode);
+    ClientPrintTaskTotalDto clientTaskTotalData(String printPlanId, String status, String courseCode, String paperNumber, String examPlace, String examRoom, Long examStartTime, Long examEndTime, Boolean isDownload, Boolean validate, String machineCode);
 
     IPage<ClientPrintStatisticsDto> listClientPrintStatistics(Page<ClientPrintStatisticsDto> page, Long schoolId, String printPlanId, String examPlace, Long examStartTime, Long examEndTime, String courseCode, String paperNumber, Set<Long> orgIds);
 

+ 13 - 2
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ExamTaskService.java

@@ -13,6 +13,7 @@ import org.springframework.web.multipart.MultipartFile;
 
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
+import java.text.ParseException;
 import java.util.List;
 import java.util.Map;
 
@@ -38,11 +39,11 @@ public interface ExamTaskService extends IService<ExamTask> {
 
     boolean enable(ExamTask examTask);
 
-    boolean saveExamTask(ExamTask examTask);
+    ExamTask saveExamTask(ExamTask examTask);
 
     ExamTaskImportDto importFile(MultipartFile file) throws IOException, NoSuchFieldException;
 
-    boolean saveBatch(ExamTask task);
+    List<ExamTask> saveBatch(ExamTask task);
 
     IPage<ExamTaskDto> listTaskApply(String auditStatus, String reviewStatus, Long cardRuleId, String courseCode, String paperNumber, Long startTime, Long endTime, Integer pageNumber, Integer pageSize);
 
@@ -121,4 +122,14 @@ public interface ExamTaskService extends IService<ExamTask> {
      * @return 命题任务信息
      */
     ReviewSampleDto findReviewSampleInfoByExamTaskId(Long examTaskId);
+
+    /**
+     * 发送即将到期数据短信提醒
+     */
+    void sendSmsExpireTask();
+
+    /**
+     * 发送已逾期数据短信提醒
+     */
+    void sendSmsOverdueTask();
 }

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

@@ -11,6 +11,6 @@ import java.io.IOException;
  */
 public interface OrgCenterDataDisposeService {
 
-    @Async("arbitrateThreadPool")
+    @Async("taskThreadPool")
     void updateSchoolInfo() throws IOException;
 }

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

@@ -145,7 +145,7 @@ public interface TBTaskService extends IService<TBTask> {
     /**
      * 更新任务状态
      */
-    @Async("arbitrateThreadPool")
+    @Async("taskThreadPool")
     public void updateStatus();
 
     /**

+ 148 - 59
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/BasicMessageServiceImpl.java

@@ -5,10 +5,10 @@ import com.aliyuncs.DefaultAcsClient;
 import com.aliyuncs.IAcsClient;
 import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
 import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
-import com.aliyuncs.exceptions.ClientException;
 import com.aliyuncs.http.MethodType;
 import com.aliyuncs.profile.DefaultProfile;
 import com.aliyuncs.profile.IClientProfile;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.qmth.distributed.print.business.config.DictionaryConfig;
 import com.qmth.distributed.print.business.entity.BasicMessage;
@@ -21,17 +21,17 @@ import com.qmth.distributed.print.business.service.BasicMessageService;
 import com.qmth.distributed.print.business.service.CacheService;
 import com.qmth.distributed.print.business.service.ExamTaskService;
 import com.qmth.distributed.print.business.service.SysConfigService;
+import com.qmth.distributed.print.business.util.ServletUtil;
 import com.qmth.distributed.print.common.contant.SpringContextHolder;
 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.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
+import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  * @Description: 短信消息发送
@@ -49,26 +49,31 @@ public class BasicMessageServiceImpl extends ServiceImpl<BasicMessageMapper, Bas
 
     @Transactional(rollbackFor = Exception.class)
     @Override
-    public void saveMessageSendLog(Long userId,String mobileNumber,Long businessId,String variableParams,Long createId,MessageEnum messageType) {
-        // 其他方法调用所传入的参数,必须校验有值
-        this.checkData(userId,mobileNumber,businessId,variableParams,createId,messageType);
-
+    public void saveMessageSendLog(Long userId, String mobileNumber, Long businessId, String variableParams, Long createId, MessageEnum messageType, String remark) {
+        BasicMessage basicMessage = new BasicMessage();
         // code和content
-        Map<String,String> enumInfo = this.getCodeAndContentByEnum(messageType);
+        Map<String, String> enumInfo = this.getCodeAndContentByEnum(messageType);
         String templateCode = enumInfo.get("templateCode");
         String templateContent = enumInfo.get("templateContent");
 
-
-        // 短信提示系统是否启用配置验证
-        SysConfig sysConfig = sysConfigService.getByKey("sys.message.enable");
-        if (sysConfig.getConfigValue() == null) {
-            throw ExceptionResultEnum.ERROR.exception("短信消息提示启用开关未设置");
-        }
-        if (sysConfig.getConfigValue().equals("false")) {
-            throw ExceptionResultEnum.ERROR.exception("短信消息提示已关闭");
-        }
+        String errorMessage = null;
 
         try {
+            // 其他方法调用所传入的参数,必须校验有值
+            this.checkData(userId, mobileNumber, variableParams, messageType);
+
+            // 短信提示系统是否启用配置验证
+            SysConfig sysConfig = sysConfigService.getByKey("sys.message.enable");
+            if (sysConfig == null) {
+                throw ExceptionResultEnum.ERROR.exception("未找到短信配置");
+            }
+            if (sysConfig.getConfigValue() == null) {
+                throw ExceptionResultEnum.ERROR.exception("短信消息提示启用开关未设置");
+            }
+            if (sysConfig.getConfigValue().equals("false")) {
+                throw ExceptionResultEnum.ERROR.exception("短信消息提示已关闭");
+            }
+
             System.setProperty("sun.net.client.defaultConnectTimeout", "180000");
             System.setProperty("sun.net.client.defaultReadTimeout", "18000");
             // 初始化ascClient需要的几个参数
@@ -103,29 +108,36 @@ public class BasicMessageServiceImpl extends ServiceImpl<BasicMessageMapper, Bas
             SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
 
             if (sendSmsResponse.getCode() != null) {
-                BasicMessage basicMessage = new BasicMessage();
-                // 传入的必填字段
-                basicMessage.setUserId(userId);
-                basicMessage.setMobileNumber(mobileNumber);
-                basicMessage.setBusinessId(businessId);
-                basicMessage.setVariableParams(variableParams);
-                basicMessage.setCreateId(createId);
-                basicMessage.setMessageType(messageType);
-
-                // 经过处理的新字段
-                basicMessage.setId(SystemConstant.getDbUuid());
-                basicMessage.setBusinessOperate(messageType.getName());
-                basicMessage.setCreateTime(System.currentTimeMillis());
-                basicMessage.setTemplateCode(templateCode);
-//                basicMessage.setTemplateContent(templateContent);
+
                 basicMessage.setSendStatus(sendSmsResponse.getCode());
                 basicMessage.setSendResult(sendSmsResponse.getMessage());
-                this.save(basicMessage);
+
             } else {
                 throw ExceptionResultEnum.ERROR.exception(sendSmsResponse.getMessage());
             }
-        }catch (ClientException e){
-            throw ExceptionResultEnum.ERROR.exception(e.getMessage());
+        } catch (Exception e) {
+            errorMessage = e.getMessage();
+        } finally {
+            // 传入的必填字段
+            basicMessage.setUserId(userId);
+            basicMessage.setMobileNumber(mobileNumber);
+            basicMessage.setBusinessId(businessId);
+            basicMessage.setVariableParams(variableParams);
+            basicMessage.setCreateId(createId);
+            basicMessage.setMessageType(messageType);
+            basicMessage.setRemark(remark);
+            basicMessage.setResendCount(0);
+
+            // 经过处理的新字段
+            basicMessage.setId(SystemConstant.getDbUuid());
+            basicMessage.setBusinessOperate(messageType.getName());
+            basicMessage.setCreateTime(System.currentTimeMillis());
+            basicMessage.setTemplateCode(templateCode);
+            if (errorMessage != null && errorMessage.length() > 0) {
+                basicMessage.setSendStatus("SYSTEM_ERROR");
+                basicMessage.setSendResult(errorMessage);
+            }
+            this.save(basicMessage);
         }
     }
 
@@ -133,15 +145,15 @@ public class BasicMessageServiceImpl extends ServiceImpl<BasicMessageMapper, Bas
     @Override
     public void noticeOfExamTaskAudit(List<Long> examTaskIdList, MessageEnum messageType, SysUser sysUser) {
         ExamTaskService examTaskService = SpringContextHolder.getBean(ExamTaskService.class);
-        Long createId = sysUser.getId();
         for (Long examTaskId : examTaskIdList) {
             ExamTask examTask = examTaskService.getById(examTaskId);
-            if (Objects.nonNull(examTask)){
+            if (Objects.nonNull(examTask)) {
                 String courseName = examTask.getCourseName();
                 String paperNumber = examTask.getPaperNumber();
-                Long userId = examTask.getCreateId();
+                // 获取短信接收对象的信息
+                Long userId = examTask.getUserId();
                 SysUser user = cacheService.userCache(userId);
-                if (Objects.nonNull(user)){
+                if (Objects.nonNull(user)) {
                     String userName = user.getRealName();
                     String mobileNumber = user.getMobileNumber();
 
@@ -150,48 +162,125 @@ public class BasicMessageServiceImpl extends ServiceImpl<BasicMessageMapper, Bas
                     jsonMap.put("courseName", courseName);
                     jsonMap.put("paperNumber", paperNumber);
                     String variableParams = JSON.toJSONString(jsonMap);
-                    this.saveMessageSendLog(userId,mobileNumber, examTaskId,variableParams,createId,messageType);
+                    this.saveMessageSendLog(userId, mobileNumber, examTaskId, variableParams, sysUser.getId(), messageType, null);
                 }
             }
         }
 
     }
 
-    private void checkData(Object ... objects){
+    /**
+     * 发送给命题老师-待办提醒
+     *
+     * @param examTasks
+     */
+    @Override
+    public void sendNoticeTaskCreate(ExamTask... examTasks) {
+        SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
+        // 指派命题老师的命题任务
+        Map<Long, List<String>> collects = Arrays.stream(examTasks).filter(m -> m.getUserId() != null).collect(Collectors.groupingBy(ExamTask::getUserId, Collectors.mapping(m -> String.valueOf(m.getId()), Collectors.toList())));
+        for (Map.Entry<Long, List<String>> longListEntry : collects.entrySet()) {
+            Long userId = longListEntry.getKey();
+            List<String> ids = longListEntry.getValue();
+            SysUser user = cacheService.userCache(userId);
+            if (Objects.nonNull(user)) {
+                String userName = user.getRealName();
+                String mobileNumber = user.getMobileNumber();
+
+                Map<String, Object> jsonMap = new HashMap<>();
+                jsonMap.put("userName", userName);
+                jsonMap.put("count", ids.size());
+                String variableParams = JSON.toJSONString(jsonMap);
+                String remark = String.format("命题任务ID:%s", String.join(",", ids));
+                this.saveMessageSendLog(userId, mobileNumber, null, variableParams, sysUser.getId(), MessageEnum.NOTICE_OF_EXAM_TASK_CREATED, remark);
+            }
+        }
+    }
+
+    @Override
+    public void sendNoticeTaskAuditCreateOrReview(ExamTask examTask, MessageEnum messageType) {
+        SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
+        // 考务老师(命题任务创建人)
+        Long userId = examTask.getCreateId();
+        SysUser user = cacheService.userCache(userId);
+        if (Objects.nonNull(user)) {
+            String userName = user.getRealName();
+            String mobileNumber = user.getMobileNumber();
+
+            Map<String, Object> jsonMap = new HashMap<>();
+            jsonMap.put("userName", userName);
+            jsonMap.put("courseName", examTask.getCourseName());
+            jsonMap.put("paperNumber", examTask.getPaperNumber());
+            String variableParams = JSON.toJSONString(jsonMap);
+            String remark = String.format("命题任务ID:%s", examTask.getId().toString());
+            this.saveMessageSendLog(userId, mobileNumber, examTask.getId(), variableParams, sysUser.getId(), messageType, remark);
+        }
+    }
+
+    @Override
+    public void sendNoticeExpireOrOverdue(MessageEnum messageType, Long userId, List<String> ids) {
+        // 考务老师(命题任务创建人)
+        SysUser user = cacheService.userCache(userId);
+        if (Objects.nonNull(user)) {
+            String userName = user.getRealName();
+            String mobileNumber = user.getMobileNumber();
+            Map<String, Object> jsonMap = new HashMap<>();
+            jsonMap.put("userName", userName);
+            jsonMap.put("count", ids.size());
+            String variableParams = JSON.toJSONString(jsonMap);
+            String remark = String.format("命题任务ID:%s", String.join(",", ids));
+            this.saveMessageSendLog(userId, mobileNumber, null, variableParams, null, messageType, remark);
+        }
+    }
+
+    @Override
+    public void resendSmsTask() {
+        SysConfig sysConfig = sysConfigService.getByKey("sys.message.resendCount");
+        if(sysConfig != null){
+            Integer resendCount = StringUtils.isBlank(sysConfig.getConfigValue()) ? 0 : Integer.valueOf(sysConfig.getConfigValue());
+            QueryWrapper<BasicMessage> queryWrapper = new QueryWrapper<>();
+            queryWrapper.lambda().ne(BasicMessage::getSendStatus, "OK").lt(BasicMessage::getResendCount, resendCount);
+            List<BasicMessage> basicMessageList = this.list(queryWrapper);
+            if (basicMessageList != null && basicMessageList.size() > 0) {
+
+            }
+        }
+    }
+
+    private void checkData(Object... objects) {
         for (Object object : objects) {
-            if (object instanceof String){
+            if (Objects.isNull(object)) {
+                throw ExceptionResultEnum.ERROR.exception("调用发送短信方法时必传参数缺失");
+            } else if (object instanceof String) {
                 String param = String.valueOf(object);
-                if (param.length() == 0 || param.equals("null")){
+                if (param.length() == 0 || param.equals("null")) {
                     throw ExceptionResultEnum.ERROR.exception("调用发送短信方法时必传参数缺失");
                 }
-            }else if (object instanceof Long){
+            } else if (object instanceof Long) {
                 Long param = SystemConstant.convertIdToLong(String.valueOf(object));
-                if (param == null || param == 0){
+                if (param == null || param == 0) {
                     throw ExceptionResultEnum.ERROR.exception("调用发送短信方法时必传参数缺失");
                 }
             }
         }
     }
 
-    private Map<String,String> getCodeAndContentByEnum(MessageEnum messageEnum){
-        Map<String,String> result = new HashMap<>();
-        String templateContent;
-        String templateCode;
-        switch (messageEnum){
+    private Map<String, String> getCodeAndContentByEnum(MessageEnum messageEnum) {
+        Map<String, String> result = new HashMap<>();
+        String templateContent = null;
+        String templateCode = null;
+        switch (messageEnum) {
             case NOTICE_OF_AUDIT_PASS:
-                // ${userName}您好,${courseName}、${paperNumber}试卷入库申请已通过,您可在卷库里进行查看已审核通过的试卷!
                 templateCode = dictionaryConfig.smsDomain().getAliyunSMSAuditPassCode();
-                templateContent = "${userName}您好,${courseName}、${paperNumber}试卷入库申请已通过,您可在卷库里进行查看已审核通过的试卷!";
+                templateContent = messageEnum.getTemplate();
                 break;
             case NOTICE_OF_AUDIT_NOT_PASS:
                 templateCode = dictionaryConfig.smsDomain().getAliyunSMSAuditNotPassCode();
-                templateContent = "${userName}您好,${courseName}、${paperNumber}试卷入库申请未通过,您可查看审核意见后重新提交入库申请";
+                templateContent = messageEnum.getTemplate();
                 break;
-            default:
-                throw new IllegalStateException("Unexpected value: " + messageEnum);
         }
-        result.put("templateContent",templateContent);
-        result.put("templateCode",templateCode);
+        result.put("templateContent", templateContent);
+        result.put("templateCode", templateCode);
         return result;
     }
 }

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

@@ -16,7 +16,7 @@ import java.util.List;
 public class ClientPrintDataServiceImpl extends ServiceImpl<ClientPrintDataMapper, ClientPrintData> implements ClientPrintDataService {
 
     @Override
-    public List<ClientPrintData> listBySchoolIdAndMachineCode(Long schoolId, Long machineCode) {
+    public List<ClientPrintData> listBySchoolIdAndMachineCode(Long schoolId, String machineCode) {
         QueryWrapper<ClientPrintData> queryWrapper = new QueryWrapper<>();
         queryWrapper.lambda().eq(ClientPrintData::getSchoolId, schoolId).eq(ClientPrintData::getMachineCode, machineCode);
         return this.list(queryWrapper);

+ 62 - 7
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ClientServiceImpl.java

@@ -8,6 +8,8 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 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.enums.ExamStatusEnum;
+import com.qmth.distributed.print.business.enums.PrintPlanStatusEnum;
 import com.qmth.distributed.print.business.service.*;
 import com.qmth.distributed.print.business.util.ExcelUtil;
 import com.qmth.distributed.print.business.util.ServletUtil;
@@ -19,6 +21,7 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import javax.servlet.http.HttpServletResponse;
+import java.text.SimpleDateFormat;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -93,6 +96,12 @@ public class ClientServiceImpl implements ClientService {
     public Map<String, Object> getReprintData(Long examDetailId, String ticketNumber, String type) {
         Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
         Map<String, Object> finalMap = new HashMap<>();
+        ExamDetail examDetail = examDetailService.getById(examDetailId);
+        // 撤回提示
+        if(ExamDetailStatusEnum.NEW.name().equals(examDetail.getStatus())
+                || ExamDetailStatusEnum.READY.name().equals(examDetail.getStatus())){
+            throw ExceptionResultEnum.ERROR.exception("该任务已被撤回");
+        }
         // 取试卷
         List<Map<String, Object>> examDetailCourses = examDetailCourseService.listByExamDetailId(examDetailId);
         Map<String, Map<String, String>> map = mapCourseUrl(examDetailCourses);
@@ -103,7 +112,6 @@ public class ClientServiceImpl implements ClientService {
         // 生成题卡List
         finalMap.put("card", spliceCardContent(studentList));
         //
-        ExamDetail examDetail = examDetailService.getById(examDetailId);
         ExamPrintPlan examPrintPlan = examPrintPlanService.getById(examDetail.getPrintPlanId());
         String variableContent = examPrintPlan.getVariableContent();
         String ordinaryContent = examPrintPlan.getOrdinaryContent();
@@ -130,7 +138,7 @@ public class ClientServiceImpl implements ClientService {
     }
 
     @Override
-    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) {
+    public IPage<ClientPrintTaskDto> listClientPrintTask(String 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);
@@ -141,10 +149,15 @@ public class ClientServiceImpl implements ClientService {
     @Transactional
     @Override
     public Map<String, Object> getPrintData(Long examDetailId, String machineCode, Boolean isPrint, String printUser) {
+        ExamDetail examDetail = examDetailService.getById(examDetailId);
+        // 撤回提示
+        if(ExamDetailStatusEnum.NEW.name().equals(examDetail.getStatus())
+                || ExamDetailStatusEnum.READY.name().equals(examDetail.getStatus())){
+            throw ExceptionResultEnum.ERROR.exception("该任务已被撤回");
+        }
         if (isPrint && StringUtils.isBlank(printUser)) {
             throw ExceptionResultEnum.ERROR.exception("打印员不能为空");
         }
-        ExamDetail examDetail = examDetailService.getById(examDetailId);
         if (isPrint && StringUtils.isNotBlank(examDetail.getPrintUser()) && !examDetail.getPrintUser().equals(printUser)) {
             throw ExceptionResultEnum.ERROR.exception("该任务已被[" + printUser + "]占用");
         }
@@ -300,10 +313,22 @@ public class ClientServiceImpl implements ClientService {
     }
 
     @Override
-    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) {
+    public List<Map<String, Object>> getPrintDataBatch(String 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);
+        // 撤回
+        long count = pirntTaskDtoList.stream().map(m -> {
+            ExamDetail examDetail = examDetailService.getById(m.getExamDetailId());
+            if (ExamDetailStatusEnum.NEW.name().equals(examDetail.getStatus())
+                    || ExamDetailStatusEnum.READY.name().equals(examDetail.getStatus())) {
+                return m.getExamDetailId();
+            }
+            return null;
+        }).filter(m->StringUtils.isNotBlank(m)).count();
+        if(count > 0){
+            throw ExceptionResultEnum.ERROR.exception("有任务被撤回,请刷新列表后再试");
+        }
         List<Map<String, Object>> finalList = new ArrayList<>();
         for (ClientPrintTaskDto clientPrintTaskDto : pirntTaskDtoList) {
             Map<String, Object> map = getPrintData(Long.valueOf(clientPrintTaskDto.getExamDetailId()), null, false, null);
@@ -358,6 +383,13 @@ public class ClientServiceImpl implements ClientService {
         if (examDetail == null) {
             throw ExceptionResultEnum.ERROR.exception("考场数据有误");
         }
+
+        // 撤回提示
+        if(ExamDetailStatusEnum.NEW.name().equals(examDetail.getStatus())
+                || ExamDetailStatusEnum.READY.name().equals(examDetail.getStatus())){
+            throw ExceptionResultEnum.ERROR.exception("该任务已被撤回");
+        }
+
         if (StringUtils.isBlank(packageCode)) {
             throw ExceptionResultEnum.ERROR.exception("卷袋编号不能为空");
         }
@@ -435,15 +467,38 @@ public class ClientServiceImpl implements ClientService {
     }
 
     @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 {
+    public void exportClientPrintTask(HttpServletResponse response, String 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);
+        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        printTaskDtoIList = printTaskDtoIList.stream().map(m -> {
+            if (m.getExamStartTime() != null) {
+                String eStartTime = simpleDateFormat.format(new Date(m.getExamStartTime()));
+                m.setExamStartTimeStr(eStartTime);
+            }
+            if (m.getExamEndTime() != null) {
+                String eEndTime = simpleDateFormat.format(new Date(m.getExamEndTime()));
+                m.setExamEndTimeStr(eEndTime);
+            }
+            if (m.getPrintStartTime() != null) {
+                String pStartTime = simpleDateFormat.format(new Date(m.getPrintStartTime()));
+                m.setPrintStartTimeStr(pStartTime);
+            }
+            if (m.getPrintEndTime() != null) {
+                String pEndTime = simpleDateFormat.format(new Date(m.getPrintEndTime()));
+                m.setPrintEndTimeStr(pEndTime);
+            }
+            m.setStatusStr(ExamStatusEnum.valueOf(m.getStatus()).getDesc());
+            m.setValidateStr(m.getValidate() ? "是" : "否");
+            m.setDownloadStr(m.getDownload() ? "是" : "否");
+            return m;
+        }).collect(Collectors.toList());
         ExcelUtil.excelExport("印刷管理", ClientPrintTaskDto.class, printTaskDtoIList, response);
     }
 
     @Override
-    public ClientPrintTaskTotalDto taskTotalData(String printPlanId, String status, String courseCode, String paperNumber, String examPlace, String examRoom, Long examStartTime, Long examEndTime, Boolean isDownload, Boolean validate, Long machineCode) {
+    public ClientPrintTaskTotalDto taskTotalData(String printPlanId, String status, String courseCode, String paperNumber, String examPlace, String examRoom, Long examStartTime, Long examEndTime, Boolean isDownload, Boolean validate, String machineCode) {
         return examPrintPlanService.clientTaskTotalData(printPlanId, status, courseCode, paperNumber, examPlace, examRoom, examStartTime, examEndTime, isDownload, validate, machineCode);
     }
 
@@ -505,7 +560,7 @@ public class ClientServiceImpl implements ClientService {
                 vMap.put("pdfMd5", path.get("pdfMd5"));
             }
         }
-        if(vMap.size() > 1) {
+        if (vMap.size() > 1) {
             otherList.add(vMap);
         }
     }

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

@@ -28,6 +28,10 @@ public class ClientStatusServiceImpl extends ServiceImpl<ClientStatusMapper, Cli
             clientStatus.setPass(isPass);
             clientStatus.setUpdateId(userId);
             clientStatus.setUpdateTime(System.currentTimeMillis());
+            // 合格,更新打印时间
+            if(isPass){
+                clientStatus.setTryTime(System.currentTimeMillis());
+            }
             return this.updateById(clientStatus);
         } else {
             clientStatus = new ClientStatus();

+ 12 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/CommonServiceImpl.java

@@ -734,6 +734,18 @@ public class CommonServiceImpl implements CommonService {
         }
     }
 
+    @Override
+    public Boolean checkExamDetailStatus(Long schoolId, String courseCode, String paperNumber) {
+        List<ExamDetail> examDetails = examDetailService.listByCourseCodeAndPaperNumber(schoolId, courseCode, paperNumber);
+        if (examDetails != null && examDetails.size() > 0) {
+            long count = examDetails.stream().filter(m->!ExamDetailStatusEnum.NEW.name().equals(m.getStatus().name()) && !ExamDetailStatusEnum.READY.name().equals(m.getStatus().name())).count();
+            if(count > 0){
+                throw ExceptionResultEnum.ERROR.exception("已有印刷任务进入打印状态,不能修改");
+            }
+        }
+        return true;
+    }
+
     private Set<Long> getOrgIds(Set<Long> stringSet, List<OrgDto> orgDtos, Long parentId) {
         for (OrgDto orgDto : orgDtos) {
             Long tempParentId = orgDto.getParentId();

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

@@ -642,13 +642,19 @@ public class ExamDetailServiceImpl extends ServiceImpl<ExamDetailMapper, ExamDet
     @Transactional
     @Override
     public Boolean updatePrintProgress(Long schoolId, Long examDetailId, String machineCode, Integer printProgress) {
+
+        ExamDetail examDetail = this.getById(examDetailId);
+        // 撤回提示
+        if(ExamDetailStatusEnum.NEW.name().equals(examDetail.getStatus())
+                || ExamDetailStatusEnum.READY.name().equals(examDetail.getStatus())){
+            throw ExceptionResultEnum.ERROR.exception("该任务已被撤回");
+        }
         // 更新考场进度、状态、打印结束时间
         UpdateWrapper<ExamDetail> updateWrapper = new UpdateWrapper<>();
         updateWrapper.lambda().set(ExamDetail::getPrintProgress, printProgress).set(ExamDetail::getPrintEndTime, System.currentTimeMillis()).set(ExamDetail::getStatus, ExamDetailStatusEnum.FINISH).eq(ExamDetail::getId, examDetailId);
         this.update(updateWrapper);
 
         // 记录机器打印数量
-        ExamDetail examDetail = this.getById(examDetailId);
         SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
         ClientPrintData clientPrintData = new ClientPrintData();
         clientPrintData.setId(SystemConstant.getDbUuid());
@@ -665,6 +671,12 @@ public class ExamDetailServiceImpl extends ServiceImpl<ExamDetailMapper, ExamDet
 
     @Override
     public IPage<ClientExamStudentDto> listStudent(Long schoolId, Long examDetailId, String ticketNumber, String studentName, String courseCode, Integer pageNumber, Integer pageSize) {
+        // 撤回提示
+        ExamDetail examDetail = this.getById(examDetailId);
+        if(ExamDetailStatusEnum.NEW.name().equals(examDetail.getStatus())
+                || ExamDetailStatusEnum.READY.name().equals(examDetail.getStatus())){
+            throw ExceptionResultEnum.ERROR.exception("该任务已被撤回");
+        }
         Page<ClientExamStudentDto> page = new Page<>(pageNumber, pageSize);
         IPage<ClientExamStudentDto> examStudentDtoIPage = this.baseMapper.listClientExamStudentPage(page, schoolId, examDetailId, ConvertUtil.translateSpecificSign(ticketNumber), ConvertUtil.translateSpecificSign(studentName), courseCode);
         return examStudentDtoIPage;

+ 52 - 6
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamPrintPlanServiceImpl.java

@@ -94,7 +94,7 @@ public class ExamPrintPlanServiceImpl extends ServiceImpl<ExamPrintPlanMapper, E
 
     @Transactional(rollbackFor = Exception.class)
     @Override
-    public List<PrintPlanBrief> printPlanBriefQuery() {
+    public List<PrintPlanBrief> printPlanBriefQuery(String source) {
         /*List<PrintPlanBrief> printPlanBriefList = new ArrayList<>();
         List<ExamPrintPlan> examPrintPlanList = this.list();
         for (ExamPrintPlan examPrintPlan : examPrintPlanList) {
@@ -105,7 +105,8 @@ public class ExamPrintPlanServiceImpl extends ServiceImpl<ExamPrintPlanMapper, E
         }*/
         Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
         Set<Long> orgIds = commonService.listSubOrgIds(null);
-        List<PrintPlanBrief> list = this.baseMapper.list(schoolId, orgIds);
+        String[] status = {PrintPlanStatusEnum.READY.name(), PrintPlanStatusEnum.PRINTING.name(),PrintPlanStatusEnum.PRINT_FINISH.name()};
+        List<PrintPlanBrief> list = this.baseMapper.list(schoolId, source, status, orgIds);
         return list;
     }
 
@@ -221,8 +222,16 @@ public class ExamPrintPlanServiceImpl extends ServiceImpl<ExamPrintPlanMapper, E
         examPrintPlan.setPrintContent(printContent);
         examPrintPlan.setCreateId(sysUser.getId());
         examPrintPlan.setUpdateId(sysUser.getId());
+
+        //印刷计划名称唯一性
+        QueryWrapper<ExamPrintPlan> printPlanQueryWrapper = new QueryWrapper<>();
+        printPlanQueryWrapper.lambda().eq(ExamPrintPlan::getSchoolId, schoolId).eq(ExamPrintPlan::getName, examPrintPlan.getName());
+        ExamPrintPlan printPlan = this.getOne(printPlanQueryWrapper);
         if (id == null || id == 0) {
             // 没有印刷计划id -> 新增印刷计划
+            if(printPlan != null){
+                throw ExceptionResultEnum.ERROR.exception("印刷计划名称已存在");
+            }
             examPrintPlan.setId(SystemConstant.getDbUuid());
             examPrintPlan.setStatus(PrintPlanStatusEnum.NEW);
             result = this.save(examPrintPlan);
@@ -232,6 +241,10 @@ public class ExamPrintPlanServiceImpl extends ServiceImpl<ExamPrintPlanMapper, E
             if (tmp == null) {
                 throw ExceptionResultEnum.ERROR.exception("印刷计划id不存在");
             }
+            if(printPlan != null && id.longValue() != printPlan.getId().longValue()){
+                throw ExceptionResultEnum.ERROR.exception("印刷计划名称已存在");
+            }
+
             PrintPlanStatusEnum status = tmp.getStatus();
             if (!PrintPlanStatusEnum.NEW.equals(status) && !PrintPlanStatusEnum.READY.equals(status)) {
                 throw ExceptionResultEnum.ERROR.exception("已经开始打印的印刷计划不能编辑");
@@ -280,22 +293,55 @@ 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) {
+    public IPage<ClientPrintTaskDto> listClientPrintTask(Page<ClientPrintTaskDto> page, Long schoolId, String machineCode, String printPlanId, String status, String courseCode, String paperNumber, String examPlace, String examRoom, Long examStartTime, Long examEndTime, Boolean isDownload, Boolean validate, Set<Long> 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);
+        IPage<ClientPrintTaskDto> clientPrintTaskDtoIPage = this.baseMapper.listClientPrintTask(page, schoolId, machineCode, printPlanId, status, courseCode, paperNumber, examPlace, examRoom, examStartTime, examEndTime, isDownload, validate, orgIds, examDetailStatus);
+        for (ClientPrintTaskDto record : clientPrintTaskDtoIPage.getRecords()) {
+            // 试卷、题卡
+            String printContent = record.getPrintContent();
+            record.setIncluedPaper(StringUtils.isBlank(printContent) ? false : printContent.contains("PAPER"));
+            record.setIncluedCard(StringUtils.isBlank(printContent) ? false : printContent.contains("CARD"));
+            //
+            String variableContent = record.getVariableContent();
+            List<Map> variableList = JSONObject.parseArray(variableContent, Map.class);
+            record.setIncluedSign(false);
+            record.setIncluedPackage(false);
+            for (Map map : variableList) {
+                String type = map.get("type").toString();
+                String templateId = map.get("templateId").toString();
+                if(ClassifyEnum.SIGN.name().equals(type) && StringUtils.isNotBlank(templateId)){
+                    record.setIncluedSign(true);
+                }
+                if(ClassifyEnum.PACKAGE.name().equals(type) && StringUtils.isNotBlank(templateId)){
+                    record.setIncluedPackage(true);
+                }
+            }
+            String ordinaryContent = record.getOrdinaryContent();
+            List<Map> ordinaryList = JSONObject.parseArray(ordinaryContent, Map.class);
+            record.setIncluedCheckin(false);
+            for (Map map : ordinaryList) {
+                String type = map.get("type").toString();
+                String templateId = map.get("templateId").toString();
+                if(ClassifyEnum.CHECK_IN.name().equals(type) && StringUtils.isNotBlank(templateId)){
+                    record.setIncluedCheckin(true);
+                }
+            }
+
+        }
+        return clientPrintTaskDtoIPage;
     }
 
 
     @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) {
+    public List<ClientPrintTaskDto> listClientPrintTask(Long schoolId, String machineCode, String printPlanId, String status, String courseCode, String paperNumber, String examPlace, String examRoom, Long examStartTime, Long examEndTime, Boolean isDownload, Boolean validate, Set<Long> 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);
     }
 
     @Override
-    public ClientPrintTaskTotalDto clientTaskTotalData(String printPlanId, String status, String courseCode, String paperNumber, String examPlace, String examRoom, Long examStartTime, Long examEndTime, Boolean isDownload, Boolean validate, Long machineCode) {
+    public ClientPrintTaskTotalDto clientTaskTotalData(String printPlanId, String status, String courseCode, String paperNumber, String examPlace, String examRoom, Long examStartTime, Long examEndTime, Boolean isDownload, Boolean validate, String machineCode) {
         Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
         Set<Long> orgIds = commonService.listSubOrgIds(null);
         // 以下状态考场状态不可查询

+ 75 - 38
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamTaskDetailServiceImpl.java

@@ -72,19 +72,23 @@ public class ExamTaskDetailServiceImpl extends ServiceImpl<ExamTaskDetailMapper,
     @Transactional
     @Override
     public boolean enable(ExamTaskDetail examTaskDetail) {
+        ExamTask examTask = examTaskService.getById(examTaskDetail.getId());
+        List<ExamDetail> examDetails = examDetailService.listByCourseCodeAndPaperNumber(examTask.getSchoolId(), examTask.getCourseCode(), examTask.getPaperNumber());
+        if (examDetails != null && examDetails.size() > 0) {
+            Map<Long, List<Long>> map = examDetails.stream().collect(Collectors.groupingBy(ExamDetail::getPrintPlanId, Collectors.mapping(ExamDetail::getId, Collectors.toList())));
+            for (Map.Entry<Long, List<Long>> listEntry : map.entrySet()) {
+                boolean b = tbTaskService.countByPrintPlanIdAndEntityId(examTask.getSchoolId(), listEntry.getKey(), listEntry.getValue());
+                if (!b) {
+                    throw ExceptionResultEnum.ERROR.exception("有关联该任务的考场正在生成打印pdf,不能启用/禁用卷库");
+                }
+            }
+        }
         // 禁用,解决试卷关联关系,并且解除生成pdf绑定
         if (!examTaskDetail.getEnable()) {
             // 正在生成pdf不能禁用
-            ExamTask examTask = examTaskService.getById(examTaskDetail.getId());
-            List<ExamDetail> examDetails = examDetailService.listByCourseCodeAndPaperNumber(examTask.getSchoolId(), examTask.getCourseCode(), examTask.getPaperNumber());
             if (examDetails != null && examDetails.size() > 0) {
                 Map<Long, List<Long>> map = examDetails.stream().collect(Collectors.groupingBy(ExamDetail::getPrintPlanId, Collectors.mapping(ExamDetail::getId, Collectors.toList())));
                 for (Map.Entry<Long, List<Long>> listEntry : map.entrySet()) {
-                    boolean b = tbTaskService.countByPrintPlanIdAndEntityId(examTask.getSchoolId(), listEntry.getKey(), listEntry.getValue());
-                    if (!b) {
-                        throw ExceptionResultEnum.ERROR.exception("有关联该任务的考场正在生成打印pdf,不能禁用卷库");
-                    }
-
                     // 解除所有考场该任务绑定关系
                     // 更新exam_detail
                     List<Long> examDetailIds = listEntry.getValue();
@@ -136,38 +140,47 @@ public class ExamTaskDetailServiceImpl extends ServiceImpl<ExamTaskDetailMapper,
             throw ExceptionResultEnum.ERROR.exception("印刷计划已结束,不能修改");
         }
         ExamTask examTask = examTaskService.getById(paperParam.getExamTaskId());
+        // 校验课程关联考场,是否已经提交打印
+        Boolean isCreate = commonService.checkExamDetailStatus(examTask.getSchoolId(), examTask.getCourseCode(), examTask.getPaperNumber());
+        if(isCreate) {
+            // 提交印刷的考场,不允许修改关联试卷
+            List<ExamDetail> examDetails = examDetailService.listByPrintPlanIdAndCourseCodeAndPaperNumber(examTask.getSchoolId(), paperParam.getPrintPlanId(), examTask.getCourseCode(), examTask.getPaperNumber());
+            List<ExamDetail> examDetails1 = examDetails.stream().filter(m -> !ExamDetailStatusEnum.NEW.equals(m.getStatus()) && !ExamDetailStatusEnum.READY.equals(m.getStatus())).collect(Collectors.toList());
+            if (!examDetails1.isEmpty()) {
+                throw ExceptionResultEnum.ERROR.exception("有考场已开始打印,不能修改");
+            }
 
-        // 提交印刷的考场,不允许修改关联试卷
-        List<ExamDetail> examDetails = examDetailService.listByPrintPlanIdAndCourseCodeAndPaperNumber(examTask.getSchoolId(), paperParam.getPrintPlanId(), examTask.getCourseCode(), examTask.getPaperNumber());
-        examDetails = examDetails.stream().filter(m -> !ExamDetailStatusEnum.NEW.equals(m.getStatus()) && !ExamDetailStatusEnum.READY.equals(m.getStatus())).collect(Collectors.toList());
-        if (!examDetails.isEmpty()) {
-            throw ExceptionResultEnum.ERROR.exception("有考场已开始打印,不能修改");
-        }
+            List<Long> entityIds = examDetails.stream().map(m -> m.getId()).collect(Collectors.toList());
+            boolean b = tbTaskService.countByPrintPlanIdAndEntityId(examTask.getSchoolId(), paperParam.getPrintPlanId(), entityIds);
+            if (!b) {
+                throw ExceptionResultEnum.ERROR.exception("有关联该任务的考场正在生成打印pdf,不能修改关联类型");
+            }
 
-        // 更新关联卷型
-        ExamTask newExamTask = examTaskService.getByCourseCodeAndPaperNumber(examTask.getSchoolId(), examTask.getCourseCode(), paperParam.getPaperNumber());
-        UpdateWrapper<ExamTaskDetail> updateWrapper = new UpdateWrapper<>();
-        updateWrapper.lambda().set(ExamTaskDetail::getRelatePaperType, paperParam.getRelatePaperType()).eq(ExamTaskDetail::getExamTaskId, newExamTask.getId());
-        this.update(updateWrapper);
+            // 更新关联卷型
+            ExamTask newExamTask = examTaskService.getByCourseCodeAndPaperNumber(examTask.getSchoolId(), examTask.getCourseCode(), paperParam.getPaperNumber());
+            UpdateWrapper<ExamTaskDetail> updateWrapper = new UpdateWrapper<>();
+            updateWrapper.lambda().set(ExamTaskDetail::getRelatePaperType, paperParam.getRelatePaperType()).eq(ExamTaskDetail::getExamTaskId, newExamTask.getId());
+            this.update(updateWrapper);
 
-        // 更新试卷编号
-        String examDetailCourseIdStr = paperParam.getExamDetailCourseIds();
-        List<Long> examDetailCourseIds = Arrays.asList(examDetailCourseIdStr.split(",")).stream().map(m -> Long.valueOf(m)).collect(Collectors.toList());
+            // 更新试卷编号
+            String examDetailCourseIdStr = paperParam.getExamDetailCourseIds();
+            List<Long> examDetailCourseIds = Arrays.asList(examDetailCourseIdStr.split(",")).stream().map(m -> Long.valueOf(m)).collect(Collectors.toList());
 //        List<ExamDetailCourse> examDetailCourses = examDetailCourseService.listByPrintPlanIdAndCourseCodeAndPaperNumber(examTask.getSchoolId(), paperParam.getPrintPlanId(), examTask.getCourseCode(), examTask.getPaperNumber());
-        examDetailCourseService.updatePaperNumber(examDetailCourseIds, paperParam.getPaperNumber(), paperParam.getRelatePaperType());
-
-        // 更新考生关联类型
-        examStudentService.updatePaperType(examDetailCourseIds, paperParam.getRelatePaperType());
-
-        // 重新生成pdf
-        List<ExamDetailCourse> examDetailCourses = examDetailCourseService.listByIds(examDetailCourseIds);
-        Map<Long, List<Long>> examDetailIdMap = examDetailCourses.stream().collect(Collectors.groupingBy(ExamDetailCourse::getExamDetailId, Collectors.mapping(ExamDetailCourse::getId, Collectors.toList())));
-        for (Map.Entry<Long, List<Long>> listEntry : examDetailIdMap.entrySet()) {
-            SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
-            Map<String, Object> map = tbTaskService.saveTask(TaskTypeEnum.CREATE_PDF, paperParam.getPrintPlanId(), sysUser, listEntry.getKey());
-            map.computeIfAbsent("examDetailCourseIds", v -> listEntry.getValue());
-            map.computeIfAbsent("paperType", v -> paperParam.getRelatePaperType());
-            asyncCreatePdfTempleteService.createPdf(map, null);
+            examDetailCourseService.updatePaperNumber(examDetailCourseIds, paperParam.getPaperNumber(), paperParam.getRelatePaperType());
+
+            // 更新考生关联类型
+            examStudentService.updatePaperType(examDetailCourseIds, paperParam.getRelatePaperType());
+
+            // 重新生成pdf
+            List<ExamDetailCourse> examDetailCourses = examDetailCourseService.listByIds(examDetailCourseIds);
+            Map<Long, List<Long>> examDetailIdMap = examDetailCourses.stream().collect(Collectors.groupingBy(ExamDetailCourse::getExamDetailId, Collectors.mapping(ExamDetailCourse::getId, Collectors.toList())));
+            for (Map.Entry<Long, List<Long>> listEntry : examDetailIdMap.entrySet()) {
+                SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
+                Map<String, Object> map = tbTaskService.saveTask(TaskTypeEnum.CREATE_PDF, paperParam.getPrintPlanId(), sysUser, listEntry.getKey());
+                map.computeIfAbsent("examDetailCourseIds", v -> listEntry.getValue());
+                map.computeIfAbsent("paperType", v -> paperParam.getRelatePaperType());
+                asyncCreatePdfTempleteService.createPdf(map, null);
+            }
         }
         return true;
     }
@@ -178,6 +191,15 @@ public class ExamTaskDetailServiceImpl extends ServiceImpl<ExamTaskDetailMapper,
         Set<Long> orgIds = commonService.listSubOrgIds(null);
         Page<ExamTaskDetailDto> page = new Page<>(pageNumber, pageSize);
         IPage<ExamTaskDetailDto> examDetailDtoIPage = this.baseMapper.listPage(page, schoolId, relateType, printPlanId, courseCode, paperNumber, orgIds);
+        examDetailDtoIPage.getRecords().stream().map(m -> {
+            String paperType = StringUtils.isBlank(m.getRelatePaperType()) ? null : m.getRelatePaperType();
+            Long printPlanIdT = Long.valueOf(m.getPrintPlanId());
+            String courseCodeT = m.getCourseCode();
+            String paperNumberT = m.getPaperNumber();
+            List<String> examDetailCourseIds = this.baseMapper.listExamDetailCourse(schoolId, paperType, printPlanIdT, courseCodeT, paperNumberT);
+            m.setExamDetailCourseIds(String.join(",", examDetailCourseIds));
+            return m;
+        }).collect(Collectors.toList());
         return examDetailDtoIPage;
     }
 
@@ -235,7 +257,23 @@ public class ExamTaskDetailServiceImpl extends ServiceImpl<ExamTaskDetailMapper,
     @Override
     public boolean paperUpdate(ExamTaskDetail examTaskDetail) {
         SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
-        // todo 前置校验条件,如打印中不能修改
+        // 提交印刷的考场,不允许修改关联试卷
+        ExamTask examTask = examTaskService.getById(examTaskDetail.getExamTaskId());
+        List<ExamDetail> examDetails = examDetailService.listByCourseCodeAndPaperNumber(examTask.getSchoolId(), examTask.getCourseCode(), examTask.getPaperNumber());
+        if (examDetails != null && examDetails.size() > 0) {
+            List<ExamDetail> examDetails1 = examDetails.stream().filter(m -> !ExamDetailStatusEnum.NEW.equals(m.getStatus()) && !ExamDetailStatusEnum.READY.equals(m.getStatus())).collect(Collectors.toList());
+            if (!examDetails1.isEmpty()) {
+                throw ExceptionResultEnum.ERROR.exception("有考场已开始打印,不能修改卷库");
+            }
+            Map<Long, List<Long>> map = examDetails.stream().collect(Collectors.groupingBy(ExamDetail::getPrintPlanId, Collectors.mapping(ExamDetail::getId, Collectors.toList())));
+            for (Map.Entry<Long, List<Long>> listEntry : map.entrySet()) {
+                boolean b = tbTaskService.countByPrintPlanIdAndEntityId(examTask.getSchoolId(), listEntry.getKey(), listEntry.getValue());
+                if (!b) {
+                    throw ExceptionResultEnum.ERROR.exception("有关联该任务的考场正在生成打印pdf,不能修改卷库");
+                }
+            }
+        }
+
         QueryWrapper<ExamTaskDetail> queryWrapper = new QueryWrapper<>();
         queryWrapper.lambda().eq(ExamTaskDetail::getExamTaskId, examTaskDetail.getExamTaskId());
         ExamTaskDetail examTaskDetailTemp = this.getOne(queryWrapper);
@@ -273,8 +311,7 @@ public class ExamTaskDetailServiceImpl extends ServiceImpl<ExamTaskDetailMapper,
 
         }
 
-        // 不需要审核,直接更新
-        ExamTask examTask = examTaskService.getById(examTaskDetail.getExamTaskId());
+        // 不需要审核,直接更新,否则加入待审核列表
         if (examTask.getReview()) {
             // 加入临时审核表
             ExamTaskPaperLog examTaskPaperLog = examTaskPaperLogService.getByExamTaskIdAndReview(examTaskDetail.getExamTaskId(), false);

+ 127 - 8
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamTaskServiceImpl.java

@@ -1,5 +1,6 @@
 package com.qmth.distributed.print.business.service.impl;
 
+import cn.hutool.core.date.DateUtil;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
@@ -22,6 +23,7 @@ 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.commons.lang3.time.DateUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -32,6 +34,8 @@ import javax.annotation.Resource;
 import javax.servlet.http.HttpServletResponse;
 import java.io.File;
 import java.io.IOException;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -100,6 +104,12 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
     @Autowired
     private ExamTaskPaperLogService examTaskPaperLogService;
 
+    @Autowired
+    private SysConfigService sysConfigService;
+
+    @Autowired
+    private BasicMessageService basicMessageService;
+
 
     @Override
     public List<ExamTask> listByCourseCode(Long schoolId, String code) {
@@ -221,7 +231,7 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
     }
 
     @Override
-    public boolean saveExamTask(ExamTask examTask) {
+    public ExamTask saveExamTask(ExamTask examTask) {
         Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
         examTask.setSchoolId(schoolId);
         SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
@@ -254,7 +264,8 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
         examTask.setCreateId(sysUser.getId());
         examTask.setCreateTime(System.currentTimeMillis());
         examTask.setReview(basicExamRule.getReview());
-        return this.save(examTask);
+        this.save(examTask);
+        return examTask;
     }
 
     @Override
@@ -311,7 +322,8 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
                 }
             }
             if (excelErrorTemp.size() > 0) {
-                throw ExceptionResultEnum.ERROR.exception(JSONObject.toJSONString(excelErrorTemp));
+                List<String> errors = excelErrorTemp.stream().map(m-> m.getExcelErrorType()).collect(Collectors.toList());
+                throw ExceptionResultEnum.ERROR.exception(JSONObject.toJSONString(errors));
             }
             return finalExcelList;
         });
@@ -416,7 +428,7 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
     }
 
     @Override
-    public boolean saveBatch(ExamTask task) {
+    public List<ExamTask> saveBatch(ExamTask task) {
         Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
         task.setSchoolId(schoolId);
         SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
@@ -485,7 +497,8 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
             examTask.setReview(basicExamRule.getReview());
             list.add(examTask);
         }
-        return this.saveBatch(list);
+        this.saveBatch(list);
+        return list;
     }
 
 //    @Override
@@ -636,7 +649,7 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
             this.update(updateWrapper);
         } else {
             // 更新记录表状态
-            taskAfterPass(taskReviewLog.getReviewStatus(), taskReviewLog.getExamTaskId() , examTaskPaperLog, sysUser);
+            taskAfterPass(taskReviewLog.getReviewStatus(), taskReviewLog.getExamTaskId(), examTaskPaperLog, sysUser);
         }
         return true;
     }
@@ -675,11 +688,21 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
                 // 更新记录表状态
                 taskAfterPass(taskReviewLog.getReviewStatus(), examTaskId, examTaskPaperLog, sysUser);
             }
+
+            if (taskReviewLog.getReviewStatus().name().equals(ReviewStatusEnum.PASS.name())) {
+                // 校验是否可以提交打印状态
+                ExamTask examTask = this.getById(examTaskId);
+                try {
+                    commonService.checkData(examTask.getSchoolId(), examTask.getCourseCode(), examTask.getPaperNumber(), sysUser);
+                } catch (IOException e) {
+                    log.error("调用生成pdf异常");
+                }
+            }
         }
         return true;
     }
 
-    private void taskAfterPass(ReviewStatusEnum statusEnum , Long examTaskId, ExamTaskPaperLog examTaskPaperLog, SysUser sysUser) {
+    private void taskAfterPass(ReviewStatusEnum statusEnum, Long examTaskId, ExamTaskPaperLog examTaskPaperLog, SysUser sysUser) {
         // 更新记录表状态
         examTaskPaperLog.setReview(true);
         examTaskPaperLog.setReviewStatus(statusEnum);
@@ -994,7 +1017,8 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
         Set<Long> orgIds = commonService.listSubOrgIds(orgId);
         Page<ClientExamTaskDto> page = new Page<>(pageNumber, pageSize);
         // 印刷任务状态为印刷中(PRINTING),考场状态为待打印(WAITING)
-        IPage<ClientExamTaskDto> examTaskDtoIPage = this.baseMapper.listClientExamTaskPage(page, schoolId, machineCode, printPlanId, courseCode, paperNumber, isTry, isPass, orgIds, PrintPlanStatusEnum.PRINTING.name(), ExamDetailStatusEnum.WAITING.name());
+        String[] examDetailstatus = {ExamDetailStatusEnum.NEW.name(), ExamDetailStatusEnum.READY.name()};
+        IPage<ClientExamTaskDto> examTaskDtoIPage = this.baseMapper.listClientExamTaskPage(page, schoolId, machineCode, printPlanId, courseCode, paperNumber, isTry, isPass, orgIds, PrintPlanStatusEnum.PRINTING.name(), examDetailstatus);
         return examTaskDtoIPage;
     }
 
@@ -1067,4 +1091,99 @@ public class ExamTaskServiceImpl extends ServiceImpl<ExamTaskMapper, ExamTask> i
         }
         return reviewSampleDtoList.get(0);
     }
+
+    /**
+     * 统计截止到当天为止的即将逾期的审核待办任务总数
+     */
+    @Override
+    public void sendSmsExpireTask() {
+        SysConfig sysConfig = sysConfigService.getByKey("sys.warning.days");
+        if (sysConfig != null && StringUtils.isNotBlank(sysConfig.getConfigValue())) {
+            Integer configValue = Integer.valueOf(sysConfig.getConfigValue());
+            // 当天15点
+            Calendar c1 = Calendar.getInstance();
+            c1.set(Calendar.HOUR_OF_DAY, 15);
+            c1.set(Calendar.MINUTE, 0);
+            c1.set(Calendar.SECOND, 0);
+            long startTime = c1.getTimeInMillis();
+            // 3天后
+            Calendar c2 = Calendar.getInstance();
+            c2.setTime(c1.getTime());
+            c2.add(Calendar.DATE, configValue);
+            long endTime = c2.getTimeInMillis();
+            // 命题任务到期预警
+            String[] examTaskStatus1 = {ExamStatusEnum.READY.name(), ExamStatusEnum.STAGE.name()};
+            List<ExamTask> examTasks1 = this.baseMapper.listExamTaskExpire(startTime, endTime, examTaskStatus1);
+            if (examTasks1 != null && examTasks1.size() > 0) {
+                Map<Long, List<String>> listMap = examTasks1.stream().collect(Collectors.groupingBy(ExamTask::getUserId, Collectors.mapping(m -> m.getId().toString(), Collectors.toList())));
+                for (Map.Entry<Long, List<String>> entry : listMap.entrySet()) {
+                    basicMessageService.sendNoticeExpireOrOverdue(MessageEnum.NOTICE_OF_EXAM_TASK_WILL_EXPIRE, entry.getKey(), entry.getValue());
+                }
+            }
+            // 命题分配到期预警
+            String[] examTaskStatus2 = {ExamStatusEnum.NEW.name()};
+            List<ExamTask> examTasks2 = this.baseMapper.listExamTaskExpire(startTime, endTime, examTaskStatus2);
+            if (examTasks2 != null && examTasks2.size() > 0) {
+                Map<Long, List<String>> listMap = examTasks2.stream().collect(Collectors.groupingBy(ExamTask::getCreateId, Collectors.mapping(m -> m.getId().toString(), Collectors.toList())));
+                for (Map.Entry<Long, List<String>> entry : listMap.entrySet()) {
+                    basicMessageService.sendNoticeExpireOrOverdue(MessageEnum.NOTICE_OF_ALLOCATION_WILL_EXPIRE, entry.getKey(), entry.getValue());
+                }
+            }
+
+            // 审核待办到期预警
+            List<ExamTask> examTasks3 = this.baseMapper.listExamTaskAuditExpire(startTime, endTime);
+            if (examTasks3 != null && examTasks3.size() > 0) {
+                Map<Long, List<String>> listMap = examTasks3.stream().collect(Collectors.groupingBy(ExamTask::getCreateId, Collectors.mapping(m -> m.getId().toString(), Collectors.toList())));
+                for (Map.Entry<Long, List<String>> entry : listMap.entrySet()) {
+                    basicMessageService.sendNoticeExpireOrOverdue(MessageEnum.NOTICE_OF_AUDIT_WILL_EXPIRE, entry.getKey(), entry.getValue());
+                }
+            }
+        }
+    }
+
+    /**
+     * 统计当天逾期的审核任务增量
+     */
+    @Override
+    public void sendSmsOverdueTask() {
+        // 当天9点
+        Calendar c1 = Calendar.getInstance();
+        c1.set(Calendar.HOUR_OF_DAY, 9);
+        c1.set(Calendar.MINUTE, 0);
+        c1.set(Calendar.SECOND, 0);
+        long endTime = c1.getTimeInMillis();
+
+        // 1天前
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(c1.getTime());
+        cal.add(Calendar.DATE, -1);
+        long startTime = cal.getTimeInMillis();
+        // 命题任务已逾期
+        String[] examTaskStatus1 = {ExamStatusEnum.READY.name(), ExamStatusEnum.STAGE.name()};
+        List<ExamTask> examTasks1 = this.baseMapper.listExamTaskExpire(startTime, endTime, examTaskStatus1);
+        if (examTasks1 != null && examTasks1.size() > 0) {
+            Map<Long, List<String>> listMap = examTasks1.stream().collect(Collectors.groupingBy(ExamTask::getUserId, Collectors.mapping(m -> m.getId().toString(), Collectors.toList())));
+            for (Map.Entry<Long, List<String>> entry : listMap.entrySet()) {
+                basicMessageService.sendNoticeExpireOrOverdue(MessageEnum.NOTICE_OF_EXAM_TASK_OVERDUE, entry.getKey(), entry.getValue());
+            }
+        }
+        // 命题分配已逾期
+        String[] examTaskStatus2 = {ExamStatusEnum.NEW.name()};
+        List<ExamTask> examTasks2 = this.baseMapper.listExamTaskExpire(startTime, endTime, examTaskStatus2);
+        if (examTasks2 != null && examTasks2.size() > 0) {
+            Map<Long, List<String>> listMap = examTasks2.stream().collect(Collectors.groupingBy(ExamTask::getCreateId, Collectors.mapping(m -> m.getId().toString(), Collectors.toList())));
+            for (Map.Entry<Long, List<String>> entry : listMap.entrySet()) {
+                basicMessageService.sendNoticeExpireOrOverdue(MessageEnum.NOTICE_OF_ALLOCATION_OVERDUE, entry.getKey(), entry.getValue());
+            }
+        }
+
+        // 审核待办已逾期
+        List<ExamTask> examTasks3 = this.baseMapper.listExamTaskAuditExpire(startTime, endTime);
+        if (examTasks3 != null && examTasks3.size() > 0) {
+            Map<Long, List<String>> listMap = examTasks3.stream().collect(Collectors.groupingBy(ExamTask::getCreateId, Collectors.mapping(m -> m.getId().toString(), Collectors.toList())));
+            for (Map.Entry<Long, List<String>> entry : listMap.entrySet()) {
+                basicMessageService.sendNoticeExpireOrOverdue(MessageEnum.NOTICE_OF_AUDIT_OVERDUE, entry.getKey(), entry.getValue());
+            }
+        }
+    }
 }

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

@@ -256,6 +256,14 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
             userSaveParams.setSchoolId(schoolId);
             SysUser sysUser = gson.fromJson(gson.toJson(userSaveParams), SysUser.class);
             if (Objects.isNull(sysUser.getId())) {//新增用户
+                // 登录名是否唯一
+                QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
+                queryWrapper.lambda().eq(SysUser::getSchoolId, schoolId).eq(SysUser::getLoginName, sysUser.getLoginName());
+                SysUser user = sysUserService.getOne(queryWrapper);
+                if(user != null){
+                    throw ExceptionResultEnum.ERROR.exception("用户名已存在");
+                }
+
                 sysUser.setInsertInfo(requestUser.getId());
                 sysUserService.save(sysUser);
                 for (Long roleId : userSaveParams.getRoleIds()) {
@@ -283,8 +291,9 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
                 if (count == 0 || dbUserRolesList.size() != userRolesList.size()) {
                     commonService.removeUserInfo(sysUser.getId());
                 }
-                //如果修改了机构,需更新用户缓存
-                if (dbUser.getOrgId().longValue() != sysUser.getOrgId().longValue()) {
+                //如果修改了机构或手机号,需更新用户缓存
+                if (dbUser.getOrgId().longValue() != sysUser.getOrgId().longValue()
+                        || !Objects.equals(dbUser.getMobileNumber(), sysUser.getMobileNumber())) {
                     cacheService.updateUserCache(sysUser.getId());
                     cacheService.updateUserAuthCache(sysUser.getId());
                 }

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

@@ -26,6 +26,8 @@ import com.qmth.distributed.print.common.contant.SystemConstant;
 import com.qmth.distributed.print.common.enums.ExceptionResultEnum;
 import com.qmth.distributed.print.common.util.JacksonUtil;
 import com.qmth.distributed.print.common.util.ResultUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.multipart.MultipartFile;
@@ -45,6 +47,7 @@ import java.util.concurrent.atomic.AtomicInteger;
  */
 @Service
 public class TBTaskServiceImpl extends ServiceImpl<TBTaskMapper, TBTask> implements TBTaskService {
+    private final static Logger log = LoggerFactory.getLogger(TBTaskServiceImpl.class);
 
     @Resource
     BasicAttachmentService basicAttachmentService;

+ 1 - 1
distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/create/AsyncCreateTaskTemplete.java

@@ -30,7 +30,7 @@ public abstract class AsyncCreateTaskTemplete extends AsyncImportTaskTemplete {
      * @return
      * @throws IOException
      */
-    @Async("arbitrateThreadPool")
+    @Async("taskThreadPool")
     public Result createPdf(Map<String, Object> map, CallbackCreatePdf callbackCreatePdf) throws IOException {
         return null;
     }

+ 1 - 1
distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/export/AsyncExportTaskTemplete.java

@@ -51,7 +51,7 @@ public abstract class AsyncExportTaskTemplete {
      * @param map
      * @return
      */
-    @Async("arbitrateThreadPool")
+    @Async("taskThreadPool")
     public abstract Result exportTask(Map<String, Object> map) throws Exception;
 
     /**

+ 1 - 1
distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/importData/AsyncImportTaskTemplete.java

@@ -54,7 +54,7 @@ public abstract class AsyncImportTaskTemplete {
      * @return
      * @throws IOException
      */
-    @Async("arbitrateThreadPool")
+    @Async("taskThreadPool")
     public abstract Result importTask(Map<String, Object> map) throws IOException, Exception;
 
     /**

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

@@ -39,6 +39,7 @@ import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.data.redis.support.atomic.RedisAtomicLong;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
 import org.springframework.util.FileCopyUtils;
 
 import javax.annotation.Resource;
@@ -148,15 +149,10 @@ public class TaskLogicServiceImpl implements TaskLogicService {
 
         //所有考场都撤回,印刷任务状态改为就绪
         QueryWrapper<ExamDetail> queryWrapper = new QueryWrapper<>();
-        queryWrapper.lambda().eq(ExamDetail::getPrintPlanId, tbTask.getPrintPlanId());
-        if (Objects.nonNull(examDetailId)) {
-            queryWrapper.lambda().eq(ExamDetail::getId, examDetailId);
-        } else if (Objects.nonNull(examDetailIds)) {
-            queryWrapper.lambda().in(ExamDetail::getId, examDetailIds);
-        }
-        queryWrapper.lambda().notIn(ExamDetail::getStatus, ExamDetailStatusEnum.NEW, ExamDetailStatusEnum.READY);
+        queryWrapper.lambda().eq(ExamDetail::getPrintPlanId, tbTask.getPrintPlanId())
+                .notIn(ExamDetail::getStatus, ExamDetailStatusEnum.NEW, ExamDetailStatusEnum.READY);
         List<ExamDetail> examDetails = detailService.list(queryWrapper);
-        if (examDetails.isEmpty()) {
+        if (CollectionUtils.isEmpty(examDetails)) {
             UpdateWrapper<ExamPrintPlan> printPlanUpdateWrapper = new UpdateWrapper<>();
             printPlanUpdateWrapper.lambda().set(ExamPrintPlan::getStatus, PrintPlanStatusEnum.READY).eq(ExamPrintPlan::getId, tbTask.getPrintPlanId());
             examPrintPlanService.update(printPlanUpdateWrapper);

+ 29 - 15
distributed-print-business/src/main/java/com/qmth/distributed/print/business/threadPool/MyThreadPool.java

@@ -1,6 +1,8 @@
 package com.qmth.distributed.print.business.threadPool;//package com.qmth.themis.business.threadPool;
 
 import com.qmth.distributed.print.common.contant.SystemConstant;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
@@ -20,15 +22,19 @@ import java.util.concurrent.ThreadPoolExecutor;
  */
 @Configuration
 public class MyThreadPool extends ThreadPoolTaskExecutor {
-
-    public MyThreadPool arbitratePoolTaskExecutor = null;
+    private final static Logger log = LoggerFactory.getLogger(MyThreadPool.class);
+    private MyThreadPool threadPoolTaskExecutor = null;
+    static final int cpuNum = Runtime.getRuntime().availableProcessors();
 
     @Value("${sys.config.threadPoolCoreSize}")
     Integer threadPoolCoreSize;
 
+    @Value("${sys.config.customThreadPoolCoreSize}")
+    boolean customThreadPoolCoreSize;
+
     @PostConstruct
     public void init() {
-        arbitrateThreadPool();
+        taskThreadPool();
     }
 
     /**
@@ -37,20 +43,28 @@ public class MyThreadPool extends ThreadPoolTaskExecutor {
      * @return
      */
     @Bean
-    public Executor arbitrateThreadPool() {
-        if (Objects.isNull(arbitratePoolTaskExecutor)) {
-            arbitratePoolTaskExecutor = new MyThreadPool();
-            arbitratePoolTaskExecutor.setCorePoolSize(threadPoolCoreSize);//核心线程数
-            arbitratePoolTaskExecutor.setMaxPoolSize(SystemConstant.THREAD_POOL_MAX_POOL_SIZE);//最大线程数
-            arbitratePoolTaskExecutor.setKeepAliveSeconds(SystemConstant.THREAD_POOL_KEEP_ALIVE_SECONDS);//线程空闲时间
-            arbitratePoolTaskExecutor.setQueueCapacity(SystemConstant.THREAD_POOL_QUEUE_CAPACITY);//队列容量
-            arbitratePoolTaskExecutor.setThreadNamePrefix(SystemConstant.THREAD_POOL_NAME);
-
+    public Executor taskThreadPool() {
+        if (Objects.isNull(threadPoolTaskExecutor)) {
+            log.info("cpuNum:{}", cpuNum);
+            threadPoolTaskExecutor = new MyThreadPool();
+            if (!customThreadPoolCoreSize && cpuNum > 0) {
+                threadPoolTaskExecutor.setCorePoolSize(cpuNum);//核心线程数
+                threadPoolTaskExecutor.setMaxPoolSize(cpuNum * 2);//最大线程数
+            } else {
+                threadPoolTaskExecutor.setCorePoolSize(threadPoolCoreSize);//核心线程数
+                threadPoolTaskExecutor.setMaxPoolSize(threadPoolCoreSize * 2);//最大线程数
+            }
+            threadPoolTaskExecutor.setKeepAliveSeconds(SystemConstant.THREAD_POOL_KEEP_ALIVE_SECONDS);//线程空闲时间
+            threadPoolTaskExecutor.setQueueCapacity(SystemConstant.THREAD_POOL_QUEUE_CAPACITY);//队列容量
+            threadPoolTaskExecutor.setThreadNamePrefix(SystemConstant.THREAD_POOL_NAME);
+            threadPoolTaskExecutor.setAllowCoreThreadTimeOut(true);//设置是否允许核心线程超时。若允许,核心线程超时后,会被销毁。默认为不允许(fasle)
+            threadPoolTaskExecutor.setWaitForTasksToCompleteOnShutdown(true);//设置shutdown时是否等到所有任务完成再真正关闭
+            threadPoolTaskExecutor.setAwaitTerminationSeconds(60);//当setWaitForTasksToCompleteOnShutdown(true)时,setAwaitTerminationSeconds 设置在 shutdown 之后最多等待多长时间后再真正关闭线程池
             // rejection-policy:当pool已经达到max size的时候,如何处理新任务
             // CALLER_RUNS:不在新线程中执行任务,而是由调用者所在的线程来执行
-            arbitratePoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
-            arbitratePoolTaskExecutor.initialize();
+            threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
+            threadPoolTaskExecutor.initialize();
         }
-        return arbitratePoolTaskExecutor;
+        return threadPoolTaskExecutor;
     }
 }

+ 24 - 5
distributed-print-business/src/main/java/com/qmth/distributed/print/business/util/CreatePdfUtil.java

@@ -459,6 +459,7 @@ public class CreatePdfUtil {
         StringJoiner stringJoiner = new StringJoiner("").add(SystemConstant.PDF_TEMP_FILES_DIR).add(File.separator);
         List<PdfDto> mergePdfA3List = new ArrayList<>();
         List<PdfDto> mergePdfA4List = new ArrayList<>();
+        List<PdfDto> mergePdfDeleteList = new ArrayList<>();
 //        AtomicInteger pageA4Count = new AtomicInteger(0);
 //        AtomicInteger pageA3Count = new AtomicInteger(0);
         for (int i = 0; i < list.length; i++) {
@@ -470,6 +471,9 @@ public class CreatePdfUtil {
                 mergePdfA3List.addAll(list[i]);
             }
         }
+//        mergePdfDeleteA3List.addAll(list[2]);
+        mergePdfDeleteList.addAll(list[3]);
+        mergePdfDeleteList.addAll(list[5]);
         List<String> pathA4List = mergePdfA4List.stream().map(PdfDto::getPath).collect(Collectors.toList());
         List<String> pathA3List = mergePdfA3List.stream().map(PdfDto::getPath).collect(Collectors.toList());
         String dirNameA4 = PdfUtil.mergePdf(pathA4List.toArray(new String[mergePdfA4List.size()]), null);
@@ -494,13 +498,28 @@ public class CreatePdfUtil {
 //        log.info("pageA3Count:{},examDetail:{}", pageA3Count.get(), JacksonUtil.parseJson(examDetail));
         examDetail.setStatus(PrintMethodEnum.AUTO == basicExamRule.getPrintMethod() ? ExamDetailStatusEnum.WAITING : ExamDetailStatusEnum.READY);
         detailService.saveOrUpdate(examDetail);
-        ossUtil.ossUpload(dirNameA3, localA3PdfFile, DigestUtils.md5Hex(new FileInputStream(localA3PdfFile)));
-//        localPdfFile.delete();
-//        for (PdfDto pdfDto : mergePdfList) {
-//            new File(pdfDto.getPath()).delete();
+        if (Objects.nonNull(localA3PdfFile)) {
+            ossUtil.ossUpload(dirNameA3, localA3PdfFile, DigestUtils.md5Hex(new FileInputStream(localA3PdfFile)));
+            localA3PdfFile.delete();
+        }
+        if (Objects.nonNull(localA4PdfFile)) {
+            localA4PdfFile.delete();
+        }
+        //删除题卡临时文件
+        for (PdfDto pdfDto : mergePdfDeleteList) {
+            if (Objects.nonNull(pdfDto)) {
+                new File(pdfDto.getPath()).delete();
+            }
+        }
+//        for (PdfDto pdfDto : mergePdfA3List) {
+//            if (Objects.nonNull(pdfDto)) {
+//                new File(pdfDto.getPath()).delete();
+//            }
 //        }
 //        for (PdfDto pdfDto : mergePdfA4List) {
-//            new File(pdfDto.getPath()).delete();
+//            if (Objects.nonNull(pdfDto)) {
+//                new File(pdfDto.getPath()).delete();
+//            }
 //        }
         return basicAttachment;
     }

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

@@ -43,7 +43,6 @@ public class PdfUtil {
         }
         Document document = null;
         PdfCopy copy = null;
-        PdfReader reader = null;
         StringJoiner dirName = null;
         try {
             if (Objects.nonNull(files) && files.length > 0) {
@@ -62,13 +61,14 @@ public class PdfUtil {
                 copy = new PdfSmartCopy(document, new FileOutputStream(outputPath));
                 document.open();
                 for (int i = 0; i < files.length; i++) {
-                    reader = new PdfReader(files[i]);
+                    PdfReader reader = new PdfReader(files[i]);
                     int numberOfPages = reader.getNumberOfPages();
                     for (int j = 1; j <= numberOfPages; j++) {
                         document.newPage();
                         PdfImportedPage page = copy.getImportedPage(reader, j);
                         copy.addPage(page);
                     }
+                    reader.close();
                 }
             }
         } catch (Exception e) {
@@ -77,9 +77,6 @@ public class PdfUtil {
             if (Objects.nonNull(document)) {
                 document.close();
             }
-            if (Objects.nonNull(reader)) {
-                reader.close();
-            }
             if (Objects.nonNull(copy)) {
                 copy.flush();
                 copy.close();

+ 1 - 0
distributed-print-business/src/main/resources/db/init-data.sql

@@ -4,4 +4,5 @@ INSERT INTO `sys_config` VALUES (1, 'sys.user.initPassword', '初始密码', '12
 INSERT INTO `sys_config` VALUES (2, 'sys.warning.days', '预警天数', '3',NULL, 1, NULL, NULL, NULL);
 INSERT INTO `sys_config` VALUES (3, 'sys.code.enable', '是否启用短信验证码', 'true', 'true-启用,false-禁用', 1, NULL, NULL, NULL);
 INSERT INTO `sys_config` VALUES (4, 'sys.message.enable', '是否启用短信消息提示', 'true', 'true-启用,false-禁用', 1, NULL, NULL, NULL);
+INSERT INTO `sys_config` VALUES (5, 'sys.message.resendCount', '失败短信重试次数', '3', NULL, 1, NULL, NULL, NULL);
 

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

@@ -107,13 +107,15 @@ CREATE TABLE `basic_message`  (
     `user_id` bigint(20) NOT NULL COMMENT '消息接收人用户',
     `mobile_number` varchar(11) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '电话号码',
     `business_id` bigint(20) NOT NULL COMMENT '业务id',
-    `business_operate` varchar(45) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '业务操作',
+    `business_operate` varchar(45) CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '业务操作',
     `template_code` varchar(45) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '消息模板代码',
     `variable_params` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '变量参数内容',
     `template_content` mediumtext CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '模板内容',
     `message_type` varchar(45) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '消息类型',
     `send_status` varchar(45) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '消息发送状态',
     `send_result` varchar(45) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '消息发送结果',
+    `remark` TEXT CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '备注',
+    `resend_count` INT CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '失败重发次数',
     `create_id` bigint(20) NULL DEFAULT NULL COMMENT '创建人',
     `create_time` bigint(20) NULL DEFAULT NULL COMMENT '创建时间',
     `update_id` bigint(20) NULL DEFAULT NULL COMMENT '更新人',
@@ -922,6 +924,7 @@ INSERT INTO `sys_privilege` VALUES (186,'印刷任务管理-查看印品','/api/
 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 (190,'任务管理-重新生成pdf','/api/admin/data/task/reset_create_pdf','URL',113,2,'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);
@@ -966,10 +969,6 @@ INSERT INTO `sys_role` VALUES (3, NULL, '考务老师', 1, 'EXAM_TEACHER', NULL,
 INSERT INTO `sys_role` VALUES (4, NULL, '命题老师', 1, 'QUESTION_TEACHER', NULL, NULL, NULL, NULL);
 INSERT INTO `sys_role` VALUES (5, NULL, '客服人员', 1, 'CUSTOMER', NULL, NULL, NULL, NULL);
 INSERT INTO `sys_role` VALUES (6, NULL, '印刷人员', 1, 'PRINTER', NULL, NULL, NULL, NULL);
-INSERT INTO `sys_role` VALUES (114679324187033600, 1, '命题老师', 1, 'QUESTION_TEACHER', 1, 1618282481532, 1, 1618295472171);
-INSERT INTO `sys_role` VALUES (114680250561986560, 1, '考务老师', 1, 'EXAM_TEACHER', 1, 1618282702391, 1, 1618295489620);
-INSERT INTO `sys_role` VALUES (114680556444188672, 1, '学校管理员', 1, 'SCHOOL_ADMIN', 1, 1618282775319, 1, 1618295501203);
-INSERT INTO `sys_role` VALUES (114685879674470400, 1, '客服员', 1, 'CUSTOMER', 1, 1618284044479, NULL, 1618284044479);
 
 -- ----------------------------
 -- Table structure for sys_role_course
@@ -1240,6 +1239,7 @@ 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 (1384755205368246283,3,190,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);

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

@@ -41,6 +41,7 @@
                 INNER JOIN
             basic_template tmp ON org.rule_id = tmp.id
         <where>
+            and tmp.enable = true
             AND (tmp.type = 'VARIABLE' OR tmp.type = 'ORDINARY')
         <if test="orgIds.size() == 0">
             AND org.org_id IN (null)

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

@@ -8,7 +8,6 @@
         <result column="school_id" property="schoolId" />
         <result column="print_plan_id" property="printPlanId" />
         <result column="print_plan_name" property="printPlanName" />
-        <result column="exam_name" property="examName" />
         <result column="exam_start_time" property="examStartTime" />
         <result column="exam_end_time" property="examEndTime" />
         <result column="exam_place" property="examPlace" />

+ 29 - 24
distributed-print-business/src/main/resources/mapper/ExamPrintPlanMapper.xml

@@ -88,6 +88,12 @@
             <if test="schoolId != null and schoolId != ''">
                 and a.school_id = #{schoolId}
             </if>
+            <if test="source == 'client'">
+                AND a.status IN
+                <foreach collection="status" item="item" index="index" open="(" separator="," close=")">
+                    #{item}
+                </foreach>
+            </if>
             <if test="orgIds != null">
                 AND b.org_id IN
                 <foreach collection="orgIds" item="item" index="index" open="(" separator="," close=")">
@@ -103,6 +109,9 @@
             b.package_code packageCode,
             a.id printPlanId,
             a.name printPlanName,
+            a.print_content printContent,
+            a.variable_content variableContent,
+            a.ordinary_content ordinaryContent,
             b.exam_start_time examStartTime,
             b.exam_end_time examEndTime,
             c.courseNameCode,
@@ -150,14 +159,6 @@
                 AND a.course_code = b.course_code
                 AND a.paper_number = b.paper_number
                 AND b.machine_code = #{machineCode}
-            <where>
-                <if test="courseCode != null and courseCode != ''">
-                    and a.course_code = #{courseCode}
-                </if>
-                <if test="paperNumber != null and paperNumber != ''">
-                    and a.paper_number = #{paperNumber}
-                </if>
-            </where>
             GROUP BY exam_detail_id) c ON b.id = c.exam_detail_id
                 LEFT JOIN
             sys_user e ON b.print_user = e.login_name
@@ -173,7 +174,13 @@
                 and a.id = #{printPlanId}
             </if>
             <if test="status != null and status != ''">
-                and a.status = #{status}
+                and b.status = #{status}
+            </if>
+            <if test="courseCode != null and courseCode != ''">
+                and c.courseNameCode like concat('%',#{courseCode},'%')
+            </if>
+            <if test="paperNumber != null and paperNumber != ''">
+                and c.paperNumber like concat('%',#{paperNumber},'%')
             </if>
             <if test="examPlace != null and examPlace != ''">
                 and b.exam_place = #{examPlace}
@@ -187,10 +194,10 @@
             <if test="examEndTime != null and examEndTime != ''">
                 and b.exam_end_time &lt; #{examEndTime}
             </if>
-            <if test="validate != null and validate != ''">
-                and b.validate = #{validate}
+            <if test="validate != null">
+                and ifnull(b.validate, false) = #{validate}
             </if>
-            <if test="isDownload != null and isDownload != ''">
+            <if test="isDownload != null">
                 <if test="isDownload == true">
                     and c.isDownload = 0
                 </if>
@@ -242,14 +249,6 @@
                 AND a.course_code = b.course_code
                 AND a.paper_number = b.paper_number
                 AND b.machine_code = #{machineCode}
-        <where>
-            <if test="courseCode != null and courseCode != ''">
-                and a.course_code = #{courseCode}
-            </if>
-            <if test="paperNumber != null and paperNumber != ''">
-                and a.paper_number = #{paperNumber}
-            </if>
-        </where>
         GROUP BY exam_detail_id) c ON b.id = c.exam_detail_id
             LEFT JOIN
         sys_user e ON b.print_user = e.login_name
@@ -265,7 +264,13 @@
                 and a.id = #{printPlanId}
             </if>
             <if test="status != null and status != ''">
-                and a.status = #{status}
+                and b.status = #{status}
+            </if>
+            <if test="courseCode != null and courseCode != ''">
+                and c.courseNameCode like concat('%',#{courseCode},'%')
+            </if>
+            <if test="paperNumber != null and paperNumber != ''">
+                and c.paperNumber like concat('%',#{paperNumber},'%')
             </if>
             <if test="examPlace != null and examPlace != ''">
                 and b.exam_place = #{examPlace}
@@ -279,10 +284,10 @@
             <if test="examEndTime != null and examEndTime != ''">
                 and b.exam_end_time &lt; #{examEndTime}
             </if>
-            <if test="validate != null and validate != ''">
-                and b.validate = #{validate}
+            <if test="validate != null">
+                and ifnull(b.validate, false) = #{validate}
             </if>
-            <if test="isDownload != null and isDownload != ''">
+            <if test="isDownload != null">
                 <if test="isDownload == true">
                     and c.isDownload = 0
                 </if>

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

@@ -40,8 +40,7 @@
             d.exposed_paper_type exposedPaperType,
             d.unexposed_paper_type unexposedPaperType,
             a.paper_type relatePaperType,
-            a.total_subjects totalSubjects,
-            a.exam_detail_course_ids examDetailCourseIds
+            a.total_subjects totalSubjects
         FROM
         (SELECT
             a.school_id,
@@ -51,8 +50,7 @@
             b.course_code,
             b.course_name,
             b.paper_type,
-            SUM(b.total_subjects) total_subjects,
-            group_concat(b.id) exam_detail_course_ids
+            SUM(b.total_subjects) total_subjects
         FROM
             exam_detail a
             LEFT JOIN exam_detail_course b ON a.id = b.exam_detail_id
@@ -112,4 +110,37 @@
                     a.card_id = b.id
                         AND b.template_id = #{templateId})
     </select>
+    <select id="listExamDetailCourse" resultType="java.lang.String">
+        SELECT
+            b.id
+        FROM
+            exam_detail a
+            LEFT JOIN exam_detail_course b ON a.id = b.exam_detail_id
+            LEFT JOIN
+            exam_task c ON a.school_id = c.school_id
+                AND b.course_code = c.course_code
+                AND b.paper_number = c.paper_number
+            LEFT JOIN
+            sys_user g ON c.create_id = g.id
+        <where>
+            <if test="schoolId != null and schoolId != ''">
+                and a.school_id = #{schoolId}
+            </if>
+            <if test="paperType != null">
+                and b.paper_type = #{paperType}
+            </if>
+            <if test="paperType == null">
+                and b.paper_type is null
+            </if>
+            <if test="printPlanId != null and printPlanId != ''">
+                and a.print_plan_id = #{printPlanId}
+            </if>
+            <if test="courseCode != null and courseCode != ''">
+                and c.course_code = #{courseCode}
+            </if>
+            <if test="paperNumber != null and paperNumber != ''">
+                and c.paper_number = #{paperNumber}
+            </if>
+        </where>
+    </select>
 </mapper>

+ 47 - 5
distributed-print-business/src/main/resources/mapper/ExamTaskMapper.xml

@@ -478,7 +478,11 @@
             sys_user g ON a.create_id = g.id
         <where>
             and a.status = #{printPlanStatus}
-            and b.status = #{examDetailStatus}
+            and d.status = 'FINISH'
+            and b.status not in
+            <foreach item="item" collection="examDetailStatus" separator="," open="(" close=")" index="">
+                #{item}
+            </foreach>
             <if test="printPlanId != null and printPlanId != ''">
                 and a.id = #{printPlanId}
             </if>
@@ -488,11 +492,11 @@
             <if test="paperNumber != null and paperNumber != ''">
                 and c.paper_number = #{paperNumber}
             </if>
-            <if test="isTry != null and isTry != ''">
-                and e.is_try = #{isTry}
+            <if test="isTry != null">
+                and IFNULL(e.is_try, FALSE) = #{isTry}
             </if>
-            <if test="isPass != null and isPass != ''">
-                and e.is_pass = #{isPass}
+            <if test="isPass != null">
+                and IFNULL(e.is_pass, FALSE) = #{isPass}
             </if>
             <if test="orgIds != null">
                 AND g.org_id IN
@@ -528,6 +532,44 @@
             det.exam_task_id = #{examTaskId}
         ORDER BY det.update_time DESC
     </select>
+    <select id="listExamTaskExpire" resultMap="BaseResultMap">
+        select * from exam_task a
+        <where>
+            and a.enable = true
+            <if test="status != null and status != ''">
+                and a.status in
+                <foreach item="item" collection="status" separator="," open="(" close=")" index="">
+                    #{item}
+                </foreach>
+            </if>
+            <if test="startTime != null and startTime != ''">
+                and a.end_time &gt;= #{startTime}
+            </if>
+            <if test="endTime != null and endTime != ''">
+                and a.end_time &lt; #{endTime}
+            </if>
+        </where>
+    </select>
+    <select id="listExamTaskAuditExpire" resultMap="BaseResultMap">
+        SELECT
+            *
+        FROM
+            exam_task a
+                LEFT JOIN
+            exam_task_paper_log b ON a.id = b.exam_task_id
+                AND b.review = FALSE
+        <where>
+            and a.enable = true
+            and a.review = true
+            and ((a.status = 'SUBMIT' and a.review_status is null) or (a.status = 'FINISH' and b.id is not null ))
+            <if test="startTime != null and startTime != ''">
+                and a.end_time &gt;= #{startTime}
+            </if>
+            <if test="endTime != null and endTime != ''">
+                and a.end_time &lt; #{endTime}
+            </if>
+        </where>
+    </select>
 
     <sql id="myworkCommonHead">
         SELECT

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

@@ -125,9 +125,9 @@ public class SystemConstant {
     /**
      * 线程池配置
      */
-    public static final String THREAD_POOL_NAME = "arbitrateThreadPool";
+    public static final String THREAD_POOL_NAME = "taskThreadPool";
 //    public static final int THREAD_POOL_CORE_POOL_SIZE = 5;
-    public static final int THREAD_POOL_MAX_POOL_SIZE = 100;
+//    public static final int THREAD_POOL_MAX_POOL_SIZE = 100;
     public static final int THREAD_POOL_KEEP_ALIVE_SECONDS = 10;
     public static final int THREAD_POOL_QUEUE_CAPACITY = 500;
 

+ 9 - 1
distributed-print-task/src/main/java/com/qmth/distributed/print/task/enums/JobEnum.java

@@ -17,7 +17,15 @@ public enum JobEnum {
 
     RESET_CREATE_PDF_JOB("重新生成pdf定时任务"),
 
-    RESET_CREATE_PDF_JOB_GROUP("重新生成pdfjob组");
+    RESET_CREATE_PDF_JOB_GROUP("重新生成pdfjob组"),
+
+    SMS_NOTICE_TASK_EXPIRE_JOB("任务到期提醒定时任务"),
+
+    SMS_NOTICE_TASK_EXPIRE_JOB_GROUP("任务到期提醒定时任务job组"),
+
+    SMS_NOTICE_TASK_OVERDUE_JOB("任务逾期提醒定时任务"),
+
+    SMS_NOTICE_TASK_OVERDUE_JOB_GROUP("任务逾期提醒定时任务job组");
 
     private String title;
 

+ 26 - 0
distributed-print-task/src/main/java/com/qmth/distributed/print/task/job/ResendSmsJob.java

@@ -0,0 +1,26 @@
+package com.qmth.distributed.print.task.job;
+
+import com.qmth.distributed.print.task.job.service.JobService;
+import org.quartz.JobExecutionContext;
+import org.quartz.JobExecutionException;
+import org.springframework.scheduling.quartz.QuartzJobBean;
+
+import javax.annotation.Resource;
+
+/**
+ * @Description: 定时重发失败短信
+ */
+public class ResendSmsJob extends QuartzJobBean {
+
+    @Resource
+    JobService jobService;
+
+    @Override
+    protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
+        try {
+            jobService.resendSmsTask();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}

+ 27 - 0
distributed-print-task/src/main/java/com/qmth/distributed/print/task/job/SendSmsExpireJob.java

@@ -0,0 +1,27 @@
+package com.qmth.distributed.print.task.job;
+
+import com.qmth.distributed.print.task.job.service.JobService;
+import org.quartz.JobExecutionContext;
+import org.quartz.JobExecutionException;
+import org.springframework.scheduling.quartz.QuartzJobBean;
+
+import javax.annotation.Resource;
+import java.io.IOException;
+
+/**
+ * @Description: 发送即将到期数据短信提醒(每天15点)
+ */
+public class SendSmsExpireJob extends QuartzJobBean {
+
+    @Resource
+    JobService jobService;
+
+    @Override
+    protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
+        try {
+            jobService.sendSmsExpireTask();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}

+ 27 - 0
distributed-print-task/src/main/java/com/qmth/distributed/print/task/job/SendSmsOverdueJob.java

@@ -0,0 +1,27 @@
+package com.qmth.distributed.print.task.job;
+
+import com.qmth.distributed.print.task.job.service.JobService;
+import org.quartz.JobExecutionContext;
+import org.quartz.JobExecutionException;
+import org.springframework.scheduling.quartz.QuartzJobBean;
+
+import javax.annotation.Resource;
+import java.io.IOException;
+
+/**
+ * @Description: 发送已逾期数据(每天9点)
+ */
+public class SendSmsOverdueJob extends QuartzJobBean {
+
+    @Resource
+    JobService jobService;
+
+    @Override
+    protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
+        try {
+            jobService.sendSmsOverdueTask();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}

+ 15 - 0
distributed-print-task/src/main/java/com/qmth/distributed/print/task/job/service/JobService.java

@@ -27,4 +27,19 @@ public interface JobService {
      * @throws IOException
      */
     void resetCreatePdfTask() throws IOException;
+
+    /**
+     * 发送即将到期数据
+     */
+    void sendSmsExpireTask();
+
+    /**
+     * 发送逾期数据
+     */
+    void sendSmsOverdueTask();
+
+    /**
+     * 重发失败短信
+     */
+    void resendSmsTask();
 }

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

@@ -4,13 +4,11 @@ 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.business.service.TBTaskService;
+import com.qmth.distributed.print.business.service.*;
 import com.qmth.distributed.print.task.job.service.JobService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -42,6 +40,12 @@ public class JobServiceImpl implements JobService {
     @Resource
     TBTaskService tbTaskService;
 
+    @Autowired
+    ExamTaskService examTaskService;
+
+    @Autowired
+    BasicMessageService basicMessageService;
+
     @Override
     public void updateSchoolInfo() throws IOException {
         orgCenterDataDisposeService.updateSchoolInfo();
@@ -81,4 +85,19 @@ public class JobServiceImpl implements JobService {
     public void resetCreatePdfTask() throws IOException {
         tbTaskService.resetCreatePdfTask();
     }
+
+    @Override
+    public void sendSmsExpireTask() {
+        examTaskService.sendSmsExpireTask();
+    }
+
+    @Override
+    public void sendSmsOverdueTask() {
+        examTaskService.sendSmsOverdueTask();
+    }
+
+    @Override
+    public void resendSmsTask() {
+        basicMessageService.resendSmsTask();
+    }
 }

+ 16 - 5
distributed-print/src/main/java/com/qmth/distributed/print/api/ClientController.java

@@ -9,8 +9,10 @@ import com.qmth.distributed.print.business.bean.auth.AuthBean;
 import com.qmth.distributed.print.business.bean.dto.*;
 import com.qmth.distributed.print.business.bean.params.ClientLoginParam;
 import com.qmth.distributed.print.business.bean.result.LoginResult;
+import com.qmth.distributed.print.business.entity.BasicSchool;
 import com.qmth.distributed.print.business.entity.SysUser;
 import com.qmth.distributed.print.business.enums.RoleTypeEnum;
+import com.qmth.distributed.print.business.service.CacheService;
 import com.qmth.distributed.print.business.service.ClientService;
 import com.qmth.distributed.print.business.service.CommonService;
 import com.qmth.distributed.print.business.service.SysUserService;
@@ -49,6 +51,9 @@ public class ClientController {
     @Resource
     CommonService commonService;
 
+    @Resource
+    CacheService cacheService;
+
     /**
      * 登录
      *
@@ -63,8 +68,14 @@ public class ClientController {
         if (bindingResult.hasErrors()) {
             return ResultUtil.error(bindingResult.getAllErrors().get(0).getDefaultMessage());
         }
+
+        BasicSchool basicSchool = cacheService.schoolCache(login.getSchoolCode());
+        if (Objects.isNull(basicSchool)) {
+            throw ExceptionResultEnum.SCHOOL_NO_DATA.exception();
+        }
+
         QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
-        wrapper.lambda().eq(SysUser::getLoginName, login.getLoginName());
+        wrapper.lambda().eq(SysUser::getSchoolId, basicSchool.getId()).eq(SysUser::getLoginName, login.getLoginName());
         SysUser sysUser = sysUserService.getOne(wrapper);
         //用户不存在
         if (Objects.isNull(sysUser)) {
@@ -188,7 +199,7 @@ public class ClientController {
      */
     @ApiOperation(value = "印刷管理-查询列表")
     @RequestMapping(value = "/print/task_list", method = RequestMethod.POST)
-    public Result printTaskList(@RequestParam("machineCode") Long machineCode,
+    public Result printTaskList(@RequestParam("machineCode") String machineCode,
                                 @RequestParam("orgId") String orgId,
                                 @RequestParam(value = "printPlanId", required = false) String printPlanId,
                                 @RequestParam(value = "status", required = false) String status,
@@ -228,7 +239,7 @@ public class ClientController {
     @ApiOperation(value = "印刷管理-导出")
     @RequestMapping(value = "/print/task_list_export", method = RequestMethod.POST)
     public void printTaskListExport(HttpServletResponse response,
-                                    @RequestParam("machineCode") Long machineCode,
+                                    @RequestParam("machineCode") String machineCode,
                                     @RequestParam("orgId") String orgId,
                                     @RequestParam(value = "printPlanId", required = false) String printPlanId,
                                     @RequestParam(value = "status", required = false) String status,
@@ -262,7 +273,7 @@ public class ClientController {
      */
     @ApiOperation(value = "印刷管理-汇总数据查询")
     @RequestMapping(value = "/print/task_total_data", method = RequestMethod.POST)
-    public Result printTaskTotalData(@RequestParam("machineCode") Long machineCode,
+    public Result printTaskTotalData(@RequestParam("machineCode") String machineCode,
                                      @RequestParam("orgId") String orgId,
                                      @RequestParam(value = "printPlanId", required = false) String printPlanId,
                                      @RequestParam(value = "status", required = false) String status,
@@ -319,7 +330,7 @@ public class ClientController {
      */
     @ApiOperation(value = "印刷管理-批量缓存数据")
     @RequestMapping(value = "/print/get_print_data_batch", method = RequestMethod.POST)
-    public Result printGetPrintDataBatch(@RequestParam("machineCode") Long machineCode,
+    public Result printGetPrintDataBatch(@RequestParam("machineCode") String machineCode,
                                          @RequestParam("orgId") String orgId,
                                          @RequestParam(value = "printPlanId", required = false) String printPlanId,
                                          @RequestParam(value = "status", required = false) String status,

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

@@ -86,8 +86,8 @@ public class ExamPrintPlanController {
     @ApiOperation(value = "印刷计划模糊查询")
     @RequestMapping(value = "/query", method = RequestMethod.POST)
     @ApiResponses({@ApiResponse(code = 200, message = "查询成功", response = Result.class)})
-    public Result findPrintPlanQuery() {
-        return ResultUtil.ok(examPrintPlanService.printPlanBriefQuery());
+    public Result findPrintPlanQuery(@RequestParam(value = "source", required = false) String source) {
+        return ResultUtil.ok(examPrintPlanService.printPlanBriefQuery(source));
     }
 
     @ApiOperation(value = "按类型查询模板")

+ 39 - 15
distributed-print/src/main/java/com/qmth/distributed/print/api/ExamTaskController.java

@@ -2,14 +2,10 @@ package com.qmth.distributed.print.api;
 
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
-import com.qmth.boot.api.annotation.Aac;
-import com.qmth.boot.api.annotation.BOOL;
 import com.qmth.boot.api.constant.ApiConstant;
 import com.qmth.boot.api.exception.ApiException;
 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.PrintPlanParams;
-import com.qmth.distributed.print.business.bean.result.EditResult;
 import com.qmth.distributed.print.business.entity.*;
 import com.qmth.distributed.print.business.enums.*;
 import com.qmth.distributed.print.business.service.*;
@@ -161,8 +157,12 @@ public class ExamTaskController {
     @ApiOperation(value = "新建")
     @RequestMapping(value = "/save", method = RequestMethod.POST)
     public Result save(@RequestBody ExamTask examTask) {
-        boolean isSuccess = examTaskService.saveExamTask(examTask);
-        return ResultUtil.ok(isSuccess);
+        ExamTask task = examTaskService.saveExamTask(examTask);
+        // todo 发送短信
+        /*if(task.getId() != null){
+            basicMessageService.sendNoticeTaskCreate(task);
+        }*/
+        return ResultUtil.ok(true);
     }
 
     /**
@@ -205,8 +205,13 @@ public class ExamTaskController {
     @ApiOperation(value = "批量保存")
     @RequestMapping(value = "/save_batch", method = RequestMethod.POST)
     public Result saveBatch(@RequestBody ExamTask task) {
-        boolean isSuccess = examTaskService.saveBatch(task);
-        return ResultUtil.ok(isSuccess);
+        List<ExamTask> examTasks = examTaskService.saveBatch(task);
+        /*if(examTasks != null && examTasks.size() > 0){
+            // todo 发送短信
+            ExamTask[] tasks = examTasks.toArray(new ExamTask[examTasks.size()]);
+            basicMessageService.sendNoticeTaskCreate(tasks);
+        }*/
+        return ResultUtil.ok(true);
     }
 
 
@@ -285,6 +290,11 @@ public class ExamTaskController {
             // 校验是否可以提交打印状态
             commonService.checkData(examTask.getSchoolId(), examTask.getCourseCode(), examTask.getPaperNumber(), (SysUser) ServletUtil.getRequestUser());
         }
+        // todo 待审核状态,发送短信
+        /*if(ExamStatusEnum.SUBMIT.name().equals(examTask.getStatus())){
+            basicMessageService.sendNoticeTaskAuditCreateOrReview(examTask, MessageEnum.NOTICE_OF_AUDIT_CREATED);
+        }*/
+
         return ResultUtil.ok(isSuccess);
     }
 
@@ -397,11 +407,6 @@ public class ExamTaskController {
         if (isSuccess && taskReviewLog.getReviewStatus().name().equals(ReviewStatusEnum.PASS.name())) {
             // 发送审核通过短信通知
             basicMessageService.noticeOfExamTaskAudit(examTaskIdList, MessageEnum.NOTICE_OF_AUDIT_PASS,sysUser);
-            // 校验是否可以提交打印状态
-            for (Long examTaskId : taskReviewLog.getExamTaskIds()) {
-                ExamTask examTask = examTaskService.getById(examTaskId);
-                commonService.checkData(examTask.getSchoolId(), examTask.getCourseCode(), examTask.getPaperNumber(), sysUser);
-            }
         }else if (isSuccess && taskReviewLog.getReviewStatus().name().equals(ReviewStatusEnum.NOT_PASS.name())){
             // 发送审核不通过短信通知
             basicMessageService.noticeOfExamTaskAudit(examTaskIdList, MessageEnum.NOTICE_OF_AUDIT_NOT_PASS,sysUser);
@@ -472,8 +477,12 @@ public class ExamTaskController {
         if(examTaskDetail.getEnable()){
             SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
             ExamTask examTask = examTaskService.getById(examTaskDetail.getId());
+            // 校验课程关联考场,是否已经提交打印
+            Boolean isCreate = commonService.checkExamDetailStatus(examTask.getSchoolId(), examTask.getCourseCode(), examTask.getPaperNumber());
             // 校验是否可以提交打印状态
-            commonService.checkData(examTask.getSchoolId(), examTask.getCourseCode(), examTask.getPaperNumber(), sysUser);
+            if(isCreate) {
+                commonService.checkData(examTask.getSchoolId(), examTask.getCourseCode(), examTask.getPaperNumber(), sysUser);
+            }
         }
         return ResultUtil.ok(isSuccess);
     }
@@ -485,8 +494,23 @@ public class ExamTaskController {
      */
     @ApiOperation(value = "卷库查询-卷库修改")
     @RequestMapping(value = "/paper_update", method = RequestMethod.POST)
-    public Result taskPaperUpdate(@RequestBody ExamTaskDetail examTaskDetail) {
+    public Result taskPaperUpdate(@RequestBody ExamTaskDetail examTaskDetail) throws IOException {
         boolean isSuccess = examTaskDetailService.paperUpdate(examTaskDetail);
+        if(isSuccess){
+            ExamTask examTask = examTaskService.getById(examTaskDetail.getExamTaskId());
+            if(examTask.getReview()){
+                // todo 发送短信
+//                basicMessageService.sendNoticeTaskAuditCreateOrReview(examTask, MessageEnum.NOTICE_OF_AUDIT_REVIEW);
+            } else {
+                SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
+                // 校验课程关联考场,是否已经提交打印
+                Boolean isCreate = commonService.checkExamDetailStatus(examTask.getSchoolId(), examTask.getCourseCode(), examTask.getPaperNumber());
+                // 校验是否可以提交打印状态
+                if(isCreate) {
+                    commonService.checkData(examTask.getSchoolId(), examTask.getCourseCode(), examTask.getPaperNumber(), sysUser);
+                }
+            }
+        }
         return ResultUtil.ok(isSuccess);
     }
 }

+ 16 - 0
distributed-print/src/main/java/com/qmth/distributed/print/start/StartRunning.java

@@ -60,6 +60,22 @@ public class StartRunning implements CommandLineRunner {
         quartzService.addJob(ResetCreatePdfJob.class, JobEnum.RESET_CREATE_PDF_JOB.name(), JobEnum.RESET_CREATE_PDF_JOB_GROUP.name(), "0 0/1 * * * ?", taskJobMap);
         log.info("增加重新生成pdf定时任务 end");
 
+//        log.info("增加任务到期提醒定时任务 start");
+//        Map expireJobMap = new HashMap();
+//        expireJobMap.computeIfAbsent("name", v -> SendSmsExpireJob.class.getName());
+//        quartzService.deleteJob(JobEnum.SMS_NOTICE_TASK_EXPIRE_JOB.name(), JobEnum.SMS_NOTICE_TASK_EXPIRE_JOB_GROUP.name());
+//        // 每天15点定时任务
+//        quartzService.addJob(SendSmsExpireJob.class, JobEnum.SMS_NOTICE_TASK_EXPIRE_JOB.name(), JobEnum.SMS_NOTICE_TASK_EXPIRE_JOB_GROUP.name(), "0 0 15 * * ?", expireJobMap);
+//        log.info("增加任务到期提醒定时任务 end");
+//
+//        log.info("增加任务逾期提醒定时任务 start");
+//        Map orverdueJobMap = new HashMap();
+//        orverdueJobMap.computeIfAbsent("name", v -> SendSmsOverdueJob.class.getName());
+//        quartzService.deleteJob(JobEnum.SMS_NOTICE_TASK_OVERDUE_JOB.name(), JobEnum.SMS_NOTICE_TASK_OVERDUE_JOB_GROUP.name());
+//        // 每天9点定时任务
+//        quartzService.addJob(SendSmsOverdueJob.class, JobEnum.SMS_NOTICE_TASK_OVERDUE_JOB.name(), JobEnum.SMS_NOTICE_TASK_OVERDUE_JOB_GROUP.name(), "0 */5 * * * ?", orverdueJobMap);
+//        log.info("增加任务逾期提醒定时任务 end");
+
         log.info("服务器启动时执行 end");
     }
 }

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

@@ -59,6 +59,7 @@ sys.config.adminLogoUrl=http://qmth-test.oss-cn-shenzhen.aliyuncs.com/frontend/w
 sys.config.htmlToPdfUrl=/usr/local/bin/wkhtmltopdf
 sys.config.autoCreatePdfResetMaxCount=5
 sys.config.threadPoolCoreSize=5
+sys.config.customThreadPoolCoreSize=false
 spring.resources.static-locations=file:${sys.config.serverUpload},classpath:/META-INF/resources/,classpath:/resources/
 
 org.center.url=https://solar.qmth.com.cn
@@ -102,4 +103,6 @@ sms.config.aliyunSMSKey=LTAI4Fi8jVRYT49QBXU9x5QX
 #aliyun SMS secret
 sms.config.aliyunSMSSecret=97aBLBfkQR5mzCiQa82yWLAH57eUd8
 sms.config.aliyunSMSSignName=\u9038\u6559\u4E91
-sms.config.aliyunSMSTplCode=SMS_147416565
+sms.config.aliyunSMSTplCode=SMS_147416565
+sms.config.aliyunSMSAuditPassCode=SMS_216425141
+sms.config.aliyunSMSAuditNotPassCode=SMS_216275156

+ 264 - 0
distributed-print/src/test/java/com/qmth/distributed/print/BasicDataImportTest.java

@@ -0,0 +1,264 @@
+package com.qmth.distributed.print;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.itextpdf.text.log.SysoCounter;
+import com.qmth.distributed.print.business.entity.*;
+import com.qmth.distributed.print.business.enums.RoleTypeEnum;
+import com.qmth.distributed.print.business.service.*;
+import com.qmth.distributed.print.common.contant.SystemConstant;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.xssf.usermodel.XSSFSheet;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.apache.xmlbeans.impl.schema.SchemaTypeSystemCompiler;
+import org.junit.Test;
+import org.junit.platform.commons.util.StringUtils;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description: 用户数据导入、课程导入、组织机构导入
+ */
+@SpringBootTest
+@RunWith(SpringRunner.class)
+public class BasicDataImportTest {
+    @Autowired
+    private BasicCourseService basicCourseService;
+    @Autowired
+    private SysUserService sysUserService;
+    @Autowired
+    private SysOrgService sysOrgService;
+    @Autowired
+    private BasicUserCourseService basicUserCourseService;
+    @Autowired
+    private SysRoleService sysRoleService;
+    @Autowired
+    private SysUserRoleService sysUserRoleService;
+    @Autowired
+    private SysRolePrivilegeService sysRolePrivilegeService;
+
+    // 学校Id
+    private Long schoolId = 1l;
+
+    // 用户数据文件
+    String userFile = "D:\\20210508140918-1.xlsx";
+    // 课程数据文件
+    String courseFile = "D:\\20210508140918-2.xlsx";
+
+
+    @Test
+    public void importBasicCourse() throws Exception {
+        List<BasicCourse> courses = readCourseFile();
+        for (BasicCourse cours : courses) {
+            QueryWrapper<BasicCourse> queryWrapper = new QueryWrapper<>();
+            queryWrapper.lambda().eq(BasicCourse::getCode, cours.getCode());
+            BasicCourse basicCourse = basicCourseService.getOne(queryWrapper);
+            if (basicCourse != null) {
+                if (basicCourse.getName().equals(cours.getName())) {
+                    continue;
+                } else {
+                    throw new Exception(String.format("s%代码已存在,名称不一致,数据库:s%,文件中:s%", cours.getCode(), basicCourse.getName(), cours.getName()));
+                }
+            }
+
+            cours.setId(SystemConstant.getDbUuid());
+            cours.setSchoolId(schoolId);
+            basicCourseService.save(cours);
+        }
+    }
+
+    @Test
+//    @Transactional
+    public void importBasicUser() throws Exception {
+        List<Map<String, String>> users = readUserFile();
+        for (Map<String, String> userMap : users) {
+            // sys_org
+            String orgCode = userMap.get("orgCode");
+            String orgName = userMap.get("orgName");
+            QueryWrapper<SysOrg> orgQueryWrapper = new QueryWrapper<>();
+            orgQueryWrapper.lambda().eq(SysOrg::getSchoolId, schoolId).eq(SysOrg::getCode, orgCode);
+            SysOrg sysOrg = sysOrgService.getOne(orgQueryWrapper);
+            if (sysOrg != null) {
+                if (!sysOrg.getName().equals(orgName)) {
+                    throw new Exception(String.format("s%代码已存在,名称不一致,数据库:s%,文件中:s%", orgCode, sysOrg.getName(), orgName));
+                }
+            } else {
+                sysOrg = new SysOrg();
+                sysOrg.setId(SystemConstant.getDbUuid());
+                sysOrg.setSchoolId(schoolId);
+                sysOrg.setCode(orgCode);
+                sysOrg.setName(orgName);
+                sysOrg.setParentId(100l);
+                sysOrgService.save(sysOrg);
+            }
+
+            // sys_user
+            String loginName = userMap.get("loginName");
+            String realName = userMap.get("realName");
+            String mobileNumber = userMap.get("mobileNumber");
+            String password = userMap.get("password");
+            QueryWrapper<SysUser> userQueryWrapper = new QueryWrapper<>();
+            userQueryWrapper.lambda().eq(SysUser::getSchoolId, schoolId).eq(SysUser::getLoginName, loginName);
+            SysUser sysUser = sysUserService.getOne(userQueryWrapper);
+            if(sysUser == null){
+                sysUser = new SysUser();
+                sysUser.setId(SystemConstant.getDbUuid());
+                sysUser.setSchoolId(schoolId);
+                sysUser.setLoginName(loginName);
+                sysUser.setRealName(realName);
+                sysUser.setPassword(password);
+                sysUser.setMobileNumber(mobileNumber);
+                sysUser.setOrgId(sysOrg.getId());
+                sysUserService.save(sysUser);
+            }
+
+            // sys_user_role
+            String roleType = userMap.get("roleType");
+            QueryWrapper<SysRole> roleQueryWrapper = new QueryWrapper<>();
+            roleQueryWrapper.lambda().eq(SysRole::getType, roleType);
+            SysRole sysRole = sysRoleService.getOne(roleQueryWrapper);
+            if (sysRole == null) {
+                throw new Exception("角色不存在");
+            }
+            QueryWrapper<SysRolePrivilege> rolePrivilegeQueryWrapper = new QueryWrapper<>();
+            rolePrivilegeQueryWrapper.lambda().eq(SysRolePrivilege::getRoleId, sysRole.getId()).eq(SysRolePrivilege::getEnable, true);
+            List<SysRolePrivilege> rolePrivileges = sysRolePrivilegeService.list(rolePrivilegeQueryWrapper);
+            List<SysUserRole> userRoles = new ArrayList<>();
+            for (SysRolePrivilege rolePrivilege : rolePrivileges) {
+                SysUserRole sysUserRole = new SysUserRole();
+                sysUserRole.setId(SystemConstant.getDbUuid());
+                sysUserRole.setUserId(sysUser.getId());
+                sysUserRole.setRoleId(rolePrivilege.getRoleId());
+                sysUserRole.setPrivilegeId(rolePrivilege.getPrivilegeId());
+                sysUserRole.setEnable(true);
+                userRoles.add(sysUserRole);
+            }
+            sysUserRoleService.saveBatch(userRoles);
+
+            // sys_user_course
+            String courseCodeses = userMap.get("courseCode");
+            if(roleType.equals(RoleTypeEnum.QUESTION_TEACHER.name())){
+                if(StringUtils.isBlank(courseCodeses)){
+                    throw new Exception("命题老师课程不能为空");
+                }
+
+                List<BasicUserCourse> userCourses = new ArrayList<>();
+                String[] courseCodes = courseCodeses.split(",");
+                for (String courseCode : courseCodes) {
+                    String[] coursees = courseCode.split("/");
+                    QueryWrapper<BasicCourse> basicCourseQueryWrapper = new QueryWrapper<>();
+                    basicCourseQueryWrapper.lambda().eq(BasicCourse::getSchoolId, schoolId).eq(BasicCourse::getCode, coursees[0]);
+                    BasicCourse basicCourse = basicCourseService.getOne(basicCourseQueryWrapper);
+                    if(basicCourse == null){
+                        throw new Exception("命题老师对应课程不存在");
+                    }
+                    BasicUserCourse basicUserCourse = new BasicUserCourse();
+                    basicUserCourse.setId(SystemConstant.getDbUuid());
+                    basicUserCourse.setUserId(sysUser.getId());
+                    basicUserCourse.setCourseId(basicCourse.getId());
+                    userCourses.add(basicUserCourse);
+                }
+                basicUserCourseService.saveBatch(userCourses);
+            }
+        }
+    }
+
+    /**
+     * 读取课程数据文件
+     *
+     * @return
+     * @throws Exception
+     */
+    private List<BasicCourse> readCourseFile() throws Exception {
+        File file = new File(courseFile);
+        if (!file.exists()) {
+            throw new Exception("课程数据文件不存在");
+        }
+        FileInputStream fileInputStream = new FileInputStream(file);
+        XSSFWorkbook workbook = new XSSFWorkbook(fileInputStream);
+        XSSFSheet sheet = workbook.getSheetAt(0);
+
+        List<BasicCourse> courseList = new ArrayList<>();
+        for (int i = 1; i < sheet.getPhysicalNumberOfRows(); i++) {
+            BasicCourse basicCourse = new BasicCourse();
+            Row row = sheet.getRow(i);
+            // 用户名
+            Cell cell0 = row.getCell(0);
+            basicCourse.setCode(cell0 == null ? null : cell0.getStringCellValue());
+            // 姓名
+            Cell cell1 = row.getCell(1);
+            basicCourse.setName(cell1 == null ? null : cell1.getStringCellValue());
+            courseList.add(basicCourse);
+        }
+        return courseList;
+    }
+
+    /**
+     * 读取用户数据文件
+     *
+     * @return
+     * @throws Exception
+     */
+    private List<Map<String, String>> readUserFile() throws Exception {
+        File file = new File(userFile);
+        if (!file.exists()) {
+            throw new Exception("用户数据文件不存在");
+        }
+        FileInputStream fileInputStream = new FileInputStream(file);
+        XSSFWorkbook workbook = new XSSFWorkbook(fileInputStream);
+        XSSFSheet sheet = workbook.getSheetAt(0);
+
+        List<Map<String, String>> userList = new ArrayList<>();
+        for (int i = 1; i < sheet.getPhysicalNumberOfRows(); i++) {
+            Map<String, String> map = new HashMap<>();
+            Row row = sheet.getRow(i);
+            // 用户名
+            Cell cell0 = row.getCell(0);
+            map.put("loginName", cell0 == null ? null : cell0.getStringCellValue());
+            // 姓名
+            Cell cell1 = row.getCell(1);
+            map.put("realName", cell1 == null ? null : cell1.getStringCellValue());
+            // 手机号
+            Cell cell2 = row.getCell(2);
+            map.put("mobileNumber", cell2 == null ? null : cell2.getStringCellValue());
+            // 密码
+            Cell cell4 = row.getCell(4);
+            map.put("password", cell4 == null ? null : cell4.getStringCellValue());
+            // 角色Code
+            Cell cell5 = row.getCell(5);
+            map.put("roleType", cell5 == null ? null : cell5.getStringCellValue());
+            // 机构code
+            Cell cell8 = row.getCell(8);
+            map.put("orgCode", cell8 == null ? null : cell8.getStringCellValue());
+            // 机构名称
+            Cell cell9 = row.getCell(9);
+            map.put("orgName", cell9 == null ? null : cell9.getStringCellValue());
+            // 命题老师可操作课程代码
+            Cell cell10 = row.getCell(10);
+            map.put("courseCode", cell10 == null ? null : cell10.getStringCellValue());
+            userList.add(map);
+        }
+
+        return userList;
+    }
+
+    @Test
+    public void createCourse() {
+        List<BasicCourse> courses = basicCourseService.list();
+        for (BasicCourse cours : courses) {
+            String a = "INSERT INTO `basic_course` VALUES (%s,1,'%s','%s',124882698949885952,1620464769921,NULL,1620464769921);";
+            System.out.println(String.format(a, SystemConstant.getDbUuid(), cours.getCode(), cours.getName()));
+        }
+    }
+
+}

+ 1 - 1
distributed-print/src/test/java/com/qmth/distributed/print/ServiceTest.java

@@ -88,7 +88,7 @@ public class ServiceTest {
         Long createId = 1L;
         MessageEnum messageType = MessageEnum.NOTICE_OF_AUDIT_PASS;
 
-        basicMessageService.saveMessageSendLog(userId, mobileNumber, businessId, variableParams, createId, messageType);
+        basicMessageService.saveMessageSendLog(userId, mobileNumber, businessId, variableParams, createId, messageType, null);
     }
 
     @Test

+ 5 - 5
pom.xml

@@ -102,11 +102,11 @@
                 <artifactId>springfox-swagger2</artifactId>
                 <version>${swagger2.version}</version>
             </dependency>
-            <dependency>
-                <groupId>com.github.xiaoymin</groupId>
-                <artifactId>swagger-bootstrap-ui</artifactId>
-                <version>${swagger2-bootstrap.version}</version>
-            </dependency>
+<!--            <dependency>-->
+<!--                <groupId>com.github.xiaoymin</groupId>-->
+<!--                <artifactId>swagger-bootstrap-ui</artifactId>-->
+<!--                <version>${swagger2-bootstrap.version}</version>-->
+<!--            </dependency>-->
             <dependency>
                 <groupId>org.apache.commons</groupId>
                 <artifactId>commons-lang3</artifactId>