瀏覽代碼

Merge remote-tracking branch 'origin/dev_v3.3.1' into dev_v3.3.1

wangliang 1 年之前
父節點
當前提交
eb70cda62f
共有 32 個文件被更改,包括 2617 次插入349 次删除
  1. 1 1
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/activiti/custom/listener/ProcessEventListener.java
  2. 64 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/dto/CreatePdfDto.java
  3. 1 1
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/dto/PdfDto.java
  4. 126 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/entity/ExamTaskAssignPaperType.java
  5. 242 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/entity/TBTaskPdf.java
  6. 41 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/enums/AssignModeEnum.java
  7. 17 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/mapper/ExamTaskAssignPaperTypeMapper.java
  8. 16 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/mapper/TBTaskPdfMapper.java
  9. 2 2
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ExamPrintPlanService.java
  10. 21 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ExamTaskAssignPaperTypeService.java
  11. 6 1
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/PrintCommonService.java
  12. 26 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/TBTaskPdfService.java
  13. 1 3
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamDetailCourseServiceImpl.java
  14. 20 3
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamPrintPlanServiceImpl.java
  15. 43 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamTaskAssignPaperTypeServiceImpl.java
  16. 256 7
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/PrintCommonServiceImpl.java
  17. 66 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/TBTaskPdfServiceImpl.java
  18. 6 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/create/AsyncCreateTaskTemplete.java
  19. 51 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/execute/AsyncCreatePdfTempleteService.java
  20. 26 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/service/PdfTaskLogicService.java
  21. 409 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/service/impl/PdfTaskLogicServiceImpl.java
  22. 1 327
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/util/CreatePdfUtil.java
  23. 50 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/util/PdfUtil.java
  24. 1039 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/util/pdf/CreatePdfNewUtil.java
  25. 1 0
      distributed-print-business/src/main/resources/mapper/ExamDetailCourseMapper.xml
  26. 15 0
      distributed-print-business/src/main/resources/mapper/ExamTaskAssignPaperTypeMapper.xml
  27. 25 0
      distributed-print-business/src/main/resources/mapper/TBTaskPdfMapper.xml
  28. 3 0
      distributed-print/install/mysql/upgrade/3.3.1.sql
  29. 2 2
      distributed-print/src/main/java/com/qmth/distributed/print/api/ExamTaskApplyController.java
  30. 1 1
      distributed-print/src/main/java/com/qmth/distributed/print/api/ExamTaskQueryController.java
  31. 28 1
      distributed-print/src/main/java/com/qmth/distributed/print/api/TBTaskController.java
  32. 11 0
      teachcloud-common/src/main/java/com/qmth/teachcloud/common/bean/result/TbTaskDetailResult.java

+ 1 - 1
distributed-print-business/src/main/java/com/qmth/distributed/print/business/activiti/custom/listener/ProcessEventListener.java

@@ -106,7 +106,7 @@ public class ProcessEventListener implements ActivitiEventListener, Serializable
                             //取命题老师ID
                             SysUser sysUser = sysUserService.getById(((ExamTask) object).getUserId());
                             try {
-                                printCommonService.checkData(((ExamTask) object).getSchoolId(), ((ExamTask) object).getExamId(), ((ExamTask) object).getCourseCode(), ((ExamTask) object).getPaperNumber(), sysUser);
+                                printCommonService.checkDataNew(((ExamTask) object).getSchoolId(), ((ExamTask) object).getExamId(), ((ExamTask) object).getCourseCode(), ((ExamTask) object).getPaperNumber(), sysUser);
                             } catch (IOException e) {
                                 throw ExceptionResultEnum.ERROR.exception("生成pdf失败");
                             }

+ 64 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/dto/CreatePdfDto.java

@@ -0,0 +1,64 @@
+package com.qmth.distributed.print.business.bean.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 生成pdf文件对象
+ */
+public class CreatePdfDto {
+
+    @ApiModelProperty(name = "所有试卷")
+    private List<PdfDto> paperPdfList = new ArrayList<>();
+    @ApiModelProperty(name = "所有题卡")
+    private List<PdfDto> cardPdfList = new ArrayList<>();
+    @ApiModelProperty(name = "备份试卷")
+    private List<PdfDto> backupPaperPdfList = new ArrayList<>();
+    @ApiModelProperty(name = "备份题卡")
+    private List<PdfDto> backupCardPdfList = new ArrayList<>();
+    @ApiModelProperty(name = "临时文件")
+    private List<File> fileTempList = new ArrayList<>();
+
+    public List<PdfDto> getPaperPdfList() {
+        return paperPdfList;
+    }
+
+    public void setPaperPdfList(List<PdfDto> paperPdfList) {
+        this.paperPdfList = paperPdfList;
+    }
+
+    public List<PdfDto> getCardPdfList() {
+        return cardPdfList;
+    }
+
+    public void setCardPdfList(List<PdfDto> cardPdfList) {
+        this.cardPdfList = cardPdfList;
+    }
+
+    public List<PdfDto> getBackupPaperPdfList() {
+        return backupPaperPdfList;
+    }
+
+    public void setBackupPaperPdfList(List<PdfDto> backupPaperPdfList) {
+        this.backupPaperPdfList = backupPaperPdfList;
+    }
+
+    public List<PdfDto> getBackupCardPdfList() {
+        return backupCardPdfList;
+    }
+
+    public void setBackupCardPdfList(List<PdfDto> backupCardPdfList) {
+        this.backupCardPdfList = backupCardPdfList;
+    }
+
+    public List<File> getFileTempList() {
+        return fileTempList;
+    }
+
+    public void setFileTempList(List<File> fileTempList) {
+        this.fileTempList = fileTempList;
+    }
+}

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

@@ -27,7 +27,7 @@ public class PdfDto {
     @ApiModelProperty(name = "序号")
     int sequence = 0;
 
-    @ApiModelProperty(name = "tag")
+    @ApiModelProperty(name = "是否大于2页")
     boolean tag = true;
 
     public PdfDto() {

+ 126 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/entity/ExamTaskAssignPaperType.java

@@ -0,0 +1,126 @@
+package com.qmth.distributed.print.business.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import java.io.Serializable;
+
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.SerializableSerializer;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.github.jeffreyning.mybatisplus.anno.MppMultiId;
+import com.qmth.distributed.print.business.enums.AssignModeEnum;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author xf
+ * @since 2024-02-07
+ */
+@TableName("exam_task_assign_paper_type")
+@ApiModel(value="ExamTaskAssignPaperType对象", description="")
+public class ExamTaskAssignPaperType implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @JsonSerialize(using = ToStringSerializer.class)
+    @ApiModelProperty(value = "考试ID")
+    @MppMultiId(value = "exam_id")
+    private Long examId;
+
+    @ApiModelProperty(value = "试卷编号")
+    @MppMultiId(value = "paper_number")
+    private String paperNumber;
+
+    @ApiModelProperty(value = "考试时间(开始)")
+    @MppMultiId(value = "exam_start_time")
+    private Long examStartTime;
+
+    @ApiModelProperty(value = "考试时间(结束)")
+    @MppMultiId(value = "exam_end_time")
+    private Long examEndTime;
+
+    @ApiModelProperty(value = "卷型")
+    private String paperType;
+
+    @ApiModelProperty(value = "分配方式:MANUAL-手动关联,AUTO-自动分配")
+    private AssignModeEnum assignMode;
+
+    public ExamTaskAssignPaperType() {
+    }
+
+    public ExamTaskAssignPaperType(Long examId, String paperNumber, Long examStartTime, Long examEndTime) {
+        this.examId = examId;
+        this.paperNumber = paperNumber;
+        this.examStartTime = examStartTime;
+        this.examEndTime = examEndTime;
+    }
+
+    public ExamTaskAssignPaperType(Long examId, String paperNumber, Long examStartTime, Long examEndTime, String paperType, AssignModeEnum assignMode) {
+        this.examId = examId;
+        this.paperNumber = paperNumber;
+        this.examStartTime = examStartTime;
+        this.examEndTime = examEndTime;
+        this.paperType = paperType;
+        this.assignMode = assignMode;
+    }
+
+    public Long getExamId() {
+        return examId;
+    }
+
+    public void setExamId(Long examId) {
+        this.examId = examId;
+    }
+    public String getPaperNumber() {
+        return paperNumber;
+    }
+
+    public void setPaperNumber(String paperNumber) {
+        this.paperNumber = paperNumber;
+    }
+    public Long getExamStartTime() {
+        return examStartTime;
+    }
+
+    public void setExamStartTime(Long examStartTime) {
+        this.examStartTime = examStartTime;
+    }
+    public Long getExamEndTime() {
+        return examEndTime;
+    }
+
+    public void setExamEndTime(Long examEndTime) {
+        this.examEndTime = examEndTime;
+    }
+    public String getPaperType() {
+        return paperType;
+    }
+
+    public void setPaperType(String paperType) {
+        this.paperType = paperType;
+    }
+    public AssignModeEnum getAssignMode() {
+        return assignMode;
+    }
+
+    public void setAssignMode(AssignModeEnum assignMode) {
+        this.assignMode = assignMode;
+    }
+
+    @Override
+    public String toString() {
+        return "ExamTaskAssignPaperType{" +
+            "examId=" + examId +
+            ", paperNumber=" + paperNumber +
+            ", examStartTime=" + examStartTime +
+            ", examEndTime=" + examEndTime +
+            ", paperType=" + paperType +
+            ", assignMode=" + assignMode +
+        "}";
+    }
+}

+ 242 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/entity/TBTaskPdf.java

@@ -0,0 +1,242 @@
+package com.qmth.distributed.print.business.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+
+import java.io.Serializable;
+
+import com.qmth.teachcloud.common.enums.CreatePdfTypeEnum;
+import com.qmth.teachcloud.common.enums.TaskResultEnum;
+import com.qmth.teachcloud.common.enums.TaskStatusEnum;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * <p>
+ * pdf生成日志表
+ * </p>
+ *
+ * @author xf
+ * @since 2024-02-06
+ */
+@TableName("t_b_task_pdf")
+@ApiModel(value = "TBTaskPdf对象", description = "pdf生成日志表")
+public class TBTaskPdf implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "主键(与exam_detail表id一致)")
+    @TableId(value = "id", type = IdType.INPUT)
+    private Long id;
+
+    @ApiModelProperty(value = "学校ID")
+    private Long schoolId;
+
+    @ApiModelProperty(value = "学期ID")
+    private Long semesterId;
+
+    @ApiModelProperty(value = "考试ID")
+    private Long examId;
+
+    @ApiModelProperty(value = "印刷计划ID")
+    private Long printPlanId;
+
+    @ApiModelProperty(value = "课程名称")
+    private String courseNameCode;
+
+    @ApiModelProperty(value = "试卷编号")
+    private String paperNumber;
+    @ApiModelProperty(value = "生成pdf类型")
+    private CreatePdfTypeEnum createType;
+
+    @ApiModelProperty(value = "任务状态,INIT:未开始,RUNNING:进行中,FINISH:已完成")
+    private TaskStatusEnum status;
+
+    @ApiModelProperty(value = "实时摘要信息")
+    private String summary;
+
+    @ApiModelProperty(value = "数据结果,SUCCESS:成功,ERROR:失败")
+    private TaskResultEnum result;
+
+    @ApiModelProperty(value = "创建人")
+    private Long createId;
+
+    @ApiModelProperty(value = "创建时间")
+    private Long createTime;
+
+    @ApiModelProperty(value = "更新人")
+    private Long updateId;
+
+    @ApiModelProperty(value = "更新时间")
+    private Long updateTime;
+
+    @ApiModelProperty(value = "备注")
+    private String remark;
+
+    public TBTaskPdf() {
+    }
+
+    public TBTaskPdf(Long id, Long schoolId, Long semesterId, Long examId, Long printPlanId, String courseNameCode, String paperNumber, Long createId) {
+        this.id = id;
+        this.schoolId = schoolId;
+        this.semesterId = semesterId;
+        this.examId = examId;
+        this.printPlanId = printPlanId;
+        this.courseNameCode = courseNameCode;
+        this.paperNumber = paperNumber;
+        this.createId = createId;
+        this.createTime = System.currentTimeMillis();
+        this.status = TaskStatusEnum.INIT;
+        this.createType = CreatePdfTypeEnum.ALL;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Long getSchoolId() {
+        return schoolId;
+    }
+
+    public void setSchoolId(Long schoolId) {
+        this.schoolId = schoolId;
+    }
+
+    public Long getSemesterId() {
+        return semesterId;
+    }
+
+    public void setSemesterId(Long semesterId) {
+        this.semesterId = semesterId;
+    }
+
+    public Long getExamId() {
+        return examId;
+    }
+
+    public void setExamId(Long examId) {
+        this.examId = examId;
+    }
+
+    public Long getPrintPlanId() {
+        return printPlanId;
+    }
+
+    public void setPrintPlanId(Long printPlanId) {
+        this.printPlanId = printPlanId;
+    }
+
+    public String getCourseNameCode() {
+        return courseNameCode;
+    }
+
+    public void setCourseNameCode(String courseNameCode) {
+        this.courseNameCode = courseNameCode;
+    }
+
+    public String getPaperNumber() {
+        return paperNumber;
+    }
+
+    public void setPaperNumber(String paperNumber) {
+        this.paperNumber = paperNumber;
+    }
+
+    public CreatePdfTypeEnum getCreateType() {
+        return createType;
+    }
+
+    public void setCreateType(CreatePdfTypeEnum createType) {
+        this.createType = createType;
+    }
+
+    public TaskStatusEnum getStatus() {
+        return status;
+    }
+
+    public void setStatus(TaskStatusEnum status) {
+        this.status = status;
+    }
+
+    public String getSummary() {
+        return summary;
+    }
+
+    public void setSummary(String summary) {
+        this.summary = summary;
+    }
+
+    public TaskResultEnum getResult() {
+        return result;
+    }
+
+    public void setResult(TaskResultEnum result) {
+        this.result = result;
+    }
+
+    public Long getCreateId() {
+        return createId;
+    }
+
+    public void setCreateId(Long createId) {
+        this.createId = createId;
+    }
+
+    public Long getCreateTime() {
+        return createTime;
+    }
+
+    public void setCreateTime(Long createTime) {
+        this.createTime = createTime;
+    }
+
+    public Long getUpdateId() {
+        return updateId;
+    }
+
+    public void setUpdateId(Long updateId) {
+        this.updateId = updateId;
+    }
+
+    public Long getUpdateTime() {
+        return updateTime;
+    }
+
+    public void setUpdateTime(Long updateTime) {
+        this.updateTime = updateTime;
+    }
+
+    public String getRemark() {
+        return remark;
+    }
+
+    public void setRemark(String remark) {
+        this.remark = remark;
+    }
+
+    @Override
+    public String toString() {
+        return "TBTaskPdf{" +
+                "id=" + id +
+                ", schoolId=" + schoolId +
+                ", semesterId=" + semesterId +
+                ", examId=" + examId +
+                ", printPlanId=" + printPlanId +
+                ", courseNameCode=" + courseNameCode +
+                ", paperNumber=" + paperNumber +
+                ", status=" + status +
+                ", summary=" + summary +
+                ", result=" + result +
+                ", createId=" + createId +
+                ", createTime=" + createTime +
+                ", updateId=" + updateId +
+                ", updateTime=" + updateTime +
+                ", remark=" + remark +
+                "}";
+    }
+}

+ 41 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/enums/AssignModeEnum.java

@@ -0,0 +1,41 @@
+package com.qmth.distributed.print.business.enums;
+
+import com.qmth.teachcloud.common.enums.EnumResult;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 分配方式
+ */
+public enum AssignModeEnum {
+
+    AUTO("自动"),
+    MANUAL("手动");
+
+    AssignModeEnum(String name) {
+        this.name = name;
+    }
+
+    private String name;
+
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * @return
+     */
+    public static List<EnumResult> listTypes() {
+        List<EnumResult> list = new ArrayList<EnumResult>();
+        for (AssignModeEnum value : AssignModeEnum.values()) {
+            EnumResult result = new EnumResult();
+            result.setCode(value.name());
+            result.setName(value.getName());
+            result.setOrdinal(value.ordinal());
+            list.add(result);
+        }
+        return list;
+    }
+
+}

+ 17 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/mapper/ExamTaskAssignPaperTypeMapper.java

@@ -0,0 +1,17 @@
+package com.qmth.distributed.print.business.mapper;
+
+import com.github.jeffreyning.mybatisplus.base.MppBaseMapper;
+import com.qmth.distributed.print.business.entity.ExamTaskAssignPaperType;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author xf
+ * @since 2024-02-07
+ */
+public interface ExamTaskAssignPaperTypeMapper extends MppBaseMapper<ExamTaskAssignPaperType> {
+
+}

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

@@ -0,0 +1,16 @@
+package com.qmth.distributed.print.business.mapper;
+
+import com.qmth.distributed.print.business.entity.TBTaskPdf;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ * 导入导出任务表 Mapper 接口
+ * </p>
+ *
+ * @author xf
+ * @since 2024-02-06
+ */
+public interface TBTaskPdfMapper extends BaseMapper<TBTaskPdf> {
+
+}

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

@@ -5,8 +5,6 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.qmth.distributed.print.business.bean.dto.ClientPrintStatisticsDto;
 import com.qmth.distributed.print.business.bean.dto.ClientPrintStatisticsTotalDto;
-import com.qmth.distributed.print.business.bean.dto.ClientPrintTaskDto;
-import com.qmth.distributed.print.business.bean.dto.ClientPrintTaskTotalDto;
 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;
@@ -104,4 +102,6 @@ public interface ExamPrintPlanService extends IService<ExamPrintPlan> {
     List<ExamPrintPlan> findByPaperNumber(Long schoolId, String paperNumber);
 
     void updateAttachmentIdByTemplateId(Long templateId, Long attachmentId);
+
+    void updateStatusById(Long printPlanId, PrintPlanStatusEnum status);
 }

+ 21 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ExamTaskAssignPaperTypeService.java

@@ -0,0 +1,21 @@
+package com.qmth.distributed.print.business.service;
+
+import com.github.jeffreyning.mybatisplus.service.IMppService;
+import com.github.jeffreyning.mybatisplus.service.MppServiceImpl;
+import com.qmth.distributed.print.business.entity.ExamDetailCourse;
+import com.qmth.distributed.print.business.entity.ExamTaskAssignPaperType;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.qmth.distributed.print.business.entity.TBTaskPdf;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author xf
+ * @since 2024-02-07
+ */
+public interface ExamTaskAssignPaperTypeService extends IMppService<ExamTaskAssignPaperType> {
+
+    ExamTaskAssignPaperType extractPaperType(TBTaskPdf tbTaskPdf, ExamDetailCourse examDetailCourse);
+}

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

@@ -49,9 +49,10 @@ public interface PrintCommonService {
      * @return
      * @throws IOException
      */
-    BasicAttachment saveAttachmentPdf(ClassifyEnum classifyEnum, ExamDetail examDetail, BasicAttachment basicAttachment, List<PdfDto> pdfList, Integer printCount, Integer sequence, List<File> fileTempList) throws IOException, DocumentException;
+    BasicAttachment saveAttachmentPdf(ClassifyEnum classifyEnum, ExamDetail examDetail, BasicAttachment basicAttachment, List<PdfDto> pdfList, Integer printCount, Integer sequence) throws IOException, DocumentException;
 
     void saveAttachmentSignPdf(PdfSignDto pdfFillDto, ExamDetail examDetail, List<PdfDto> pdfList, Integer printCount, List<File> fileTempList, BasicTemplate basicTemplate);
+    void saveAttachmentSignPdf(PdfSignDto pdfFillDto, ExamDetail examDetail,  Integer printCount, BasicTemplate basicTemplate);
 
     /**
      * 保存html附件
@@ -65,6 +66,8 @@ public interface PrintCommonService {
      * @throws IOException
      */
     BasicAttachment saveAttachmentHtml(String fileName, String htmlContent, Long userId, List<PdfDto> localFileList, List<File> fileTempList) throws IOException;
+    BasicAttachment saveAttachmentPdfFromHtml(String fileName, String htmlContent, Long userId, List<PdfDto> localFileList) throws IOException;
+    BasicAttachment saveAttachmentPdfFromHtml(String fileName, File file, Long userId, List<PdfDto> localFileList) throws IOException;
 
     /**
      * 保存html附件和该html转成pdf的附件
@@ -223,6 +226,7 @@ public interface PrintCommonService {
      * @throws IOException
      */
     void checkData(Long schoolId, Long examId, String courseCode, String paperNumber, SysUser user) throws IOException;
+    void checkDataNew(Long schoolId, Long examId, String courseCode, String paperNumber, SysUser user) throws IOException;
 
     void checkDataMakeup(Long schoolId, ExamDetail examDetail, String courseCode, String paperNumber, SysUser user);
 
@@ -268,6 +272,7 @@ public interface PrintCommonService {
     public void updateGradeBatchStatus(Long schoolId, Long examId, String paperNumber, String paperType);
 
     void saveAttachmentPackagePdf(PdfPackageDto pdfPackageDto, ExamDetail examDetail, List<PdfDto> variablePdfList, Integer printCount, List<File> fileTempList);
+    void saveAttachmentPackagePdf(PdfPackageDto pdfPackageDto, ExamDetail examDetail,Integer printCount);
 
     String parseAttachmentPath(String attachmentPath, PrintPathVo printPathVo);
 

+ 26 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/TBTaskPdfService.java

@@ -0,0 +1,26 @@
+package com.qmth.distributed.print.business.service;
+
+import com.qmth.distributed.print.business.entity.TBTaskPdf;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.qmth.teachcloud.common.bean.result.TbTaskDetailResult;
+import com.qmth.teachcloud.common.entity.SysUser;
+import com.qmth.teachcloud.common.enums.TaskResultEnum;
+import com.qmth.teachcloud.common.enums.TaskStatusEnum;
+import com.qmth.teachcloud.common.enums.TaskTypeEnum;
+
+import java.util.Map;
+
+/**
+ * <p>
+ * 导入导出任务表 服务类
+ * </p>
+ *
+ * @author xf
+ * @since 2024-02-06
+ */
+public interface TBTaskPdfService extends IService<TBTaskPdf> {
+
+    boolean updateStatusById(TaskStatusEnum status, TaskResultEnum result, String summary, Long id);
+
+    TBTaskPdf saveTask(TbTaskDetailResult tbTaskDetailResult, TaskTypeEnum createPdf, Long printPlanId, SysUser user, Long id);
+}

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

@@ -108,10 +108,8 @@ public class ExamDetailCourseServiceImpl extends ServiceImpl<ExamDetailCourseMap
 
     @Override
     public List<ExamDetailCourse> listByExamDetailId(Long examDetailId) {
-        Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
         QueryWrapper<ExamDetailCourse> queryWrapper = new QueryWrapper<>();
-        queryWrapper.lambda().eq(ExamDetailCourse::getSchoolId, schoolId)
-                .eq(ExamDetailCourse::getExamDetailId, examDetailId);
+        queryWrapper.lambda().eq(ExamDetailCourse::getExamDetailId, examDetailId);
         return this.list(queryWrapper);
     }
 

+ 20 - 3
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamPrintPlanServiceImpl.java

@@ -2,14 +2,14 @@ package com.qmth.distributed.print.business.service.impl;
 
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.qmth.distributed.print.business.bean.dto.ClientPrintStatisticsDto;
 import com.qmth.distributed.print.business.bean.dto.ClientPrintStatisticsTotalDto;
-import com.qmth.distributed.print.business.bean.dto.ClientPrintTaskDto;
-import com.qmth.distributed.print.business.bean.dto.ClientPrintTaskTotalDto;
 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;
@@ -30,11 +30,11 @@ import com.qmth.teachcloud.common.enums.ClassifyEnum;
 import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
 import com.qmth.teachcloud.common.service.*;
 import com.qmth.teachcloud.common.util.ServletUtil;
+import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.BeanUtils;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
-import org.springframework.util.CollectionUtils;
 
 import javax.annotation.Resource;
 import java.util.*;
@@ -401,6 +401,23 @@ public class ExamPrintPlanServiceImpl extends ServiceImpl<ExamPrintPlanMapper, E
         this.updateBatchById(examPrintPlanList);
     }
 
+    @Override
+    public void updateStatusById(Long printPlanId, PrintPlanStatusEnum status) {
+        QueryWrapper<ExamDetail> queryWrapper = new QueryWrapper<>();
+        LambdaQueryWrapper<ExamDetail> lambda = queryWrapper.lambda();
+        lambda.eq(ExamDetail::getPrintPlanId, printPlanId);
+        if (PrintPlanStatusEnum.READY.equals(status)) {
+            lambda.notIn(ExamDetail::getStatus, ExamDetailStatusEnum.NEW, ExamDetailStatusEnum.READY);
+        }
+        List<ExamDetail> examDetails = examDetailService.list(queryWrapper);
+        if (CollectionUtils.isEmpty(examDetails)) {
+            UpdateWrapper<ExamPrintPlan> printPlanUpdateWrapper = new UpdateWrapper<>();
+            printPlanUpdateWrapper.lambda().set(ExamPrintPlan::getStatus, status)
+                    .eq(ExamPrintPlan::getId, printPlanId);
+            this.update(printPlanUpdateWrapper);
+        }
+    }
+
     /**
      * 查找子机构
      *

+ 43 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamTaskAssignPaperTypeServiceImpl.java

@@ -0,0 +1,43 @@
+package com.qmth.distributed.print.business.service.impl;
+
+import com.github.jeffreyning.mybatisplus.service.MppServiceImpl;
+import com.qmth.boot.core.concurrent.annotation.Lockable;
+import com.qmth.distributed.print.business.entity.*;
+import com.qmth.distributed.print.business.enums.AssignModeEnum;
+import com.qmth.distributed.print.business.mapper.ExamTaskAssignPaperTypeMapper;
+import com.qmth.distributed.print.business.service.ExamDetailService;
+import com.qmth.distributed.print.business.service.ExamTaskAssignPaperTypeService;
+import com.qmth.distributed.print.business.util.pdf.CreatePdfNewUtil;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author xf
+ * @since 2024-02-07
+ */
+@Service
+public class ExamTaskAssignPaperTypeServiceImpl extends MppServiceImpl<ExamTaskAssignPaperTypeMapper, ExamTaskAssignPaperType> implements ExamTaskAssignPaperTypeService {
+
+    @Resource
+    ExamDetailService examDetailService;
+    @Resource
+    CreatePdfNewUtil createPdfNewUtil;
+
+    @Lockable(name = "#p0.examId + '-' + #p1.paperNumber")
+    @Override
+    public ExamTaskAssignPaperType extractPaperType(TBTaskPdf tbTaskPdf, ExamDetailCourse examDetailCourse) {
+        ExamDetail examDetail = examDetailService.getById(tbTaskPdf.getId());
+        ExamTaskAssignPaperType examTaskAssignPaperType = this.selectByMultiId(new ExamTaskAssignPaperType(tbTaskPdf.getExamId(), examDetailCourse.getPaperNumber(), examDetail.getExamStartTime(), examDetail.getExamEndTime()));
+        if(examTaskAssignPaperType == null){
+            String paperType = createPdfNewUtil.getPaperType(examDetail.getPrintPlanId(), examDetail.getExamId(), examDetailCourse.getPaperNumber());
+            examTaskAssignPaperType = new ExamTaskAssignPaperType(tbTaskPdf.getExamId(), examDetailCourse.getPaperNumber(), examDetail.getExamStartTime(), examDetail.getExamEndTime(), paperType, AssignModeEnum.AUTO);
+            this.saveOrUpdateByMultiId(examTaskAssignPaperType);
+        }
+        return examTaskAssignPaperType;
+    }
+}

+ 256 - 7
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/PrintCommonServiceImpl.java

@@ -31,6 +31,7 @@ import com.qmth.teachcloud.common.bean.dto.MqDto;
 import com.qmth.teachcloud.common.bean.params.ArraysParams;
 import com.qmth.teachcloud.common.bean.result.BasicStudentResult;
 import com.qmth.teachcloud.common.bean.result.TbTaskDetailResult;
+import com.qmth.teachcloud.common.bean.vo.FilePathVo;
 import com.qmth.teachcloud.common.config.DictionaryConfig;
 import com.qmth.teachcloud.common.contant.SpringContextHolder;
 import com.qmth.teachcloud.common.contant.SystemConstant;
@@ -108,6 +109,8 @@ public class PrintCommonServiceImpl implements PrintCommonService {
 
     @Resource
     TBTaskService tbTaskService;
+    @Resource
+    TBTaskPdfService tbTaskPdfService;
 
     @Resource
     @Lazy
@@ -126,6 +129,9 @@ public class PrintCommonServiceImpl implements PrintCommonService {
     @Resource
     private FileStoreUtil fileStoreUtil;
 
+    @Resource
+    private FileUploadService fileUploadService;
+
     @Resource
     TeachcloudCommonService teachcloudCommonService;
 
@@ -177,13 +183,12 @@ public class PrintCommonServiceImpl implements PrintCommonService {
      * @param pdfList
      * @param printCount
      * @param sequence
-     * @param fileTempList
      * @return
-     * @throws IOException
      */
     @Override
     @Transactional
-    public BasicAttachment saveAttachmentPdf(ClassifyEnum classifyEnum, ExamDetail examDetail, BasicAttachment basicAttachment, List<PdfDto> pdfList, Integer printCount, Integer sequence, List<File> fileTempList) throws IOException, DocumentException {
+    public BasicAttachment saveAttachmentPdf(ClassifyEnum classifyEnum, ExamDetail examDetail, BasicAttachment basicAttachment, List<PdfDto> pdfList, Integer printCount, Integer sequence) {
+        File htmlFileTemp = null;
         try {
             boolean oss = dictionaryConfig.sysDomain().isOss();
             JSONObject jsonObject = JSONObject.parseObject(basicAttachment.getPath());
@@ -196,15 +201,15 @@ public class PrintCommonServiceImpl implements PrintCommonService {
                 UploadFileEnum uploadType = Enum.valueOf(UploadFileEnum.class, (String) jsonObject.get(SystemConstant.UPLOAD_TYPE));
                 if (oss || (!oss && dictionaryConfig.fssPrivateDomain().getConfig().startsWith(SystemConstant.START_PARENT))) {
                     ossStr = oss ? SystemConstant.OSS : SystemConstant.LOCAL;
-                    File htmlFileTemp = SystemConstant.getFileTempVar(SystemConstant.HTML_PREFIX);
-                    fileTempList.add(htmlFileTemp);
+                    htmlFileTemp = SystemConstant.getFileTempVar(SystemConstant.HTML_PREFIX);
+
                     htmlFile = fileStoreUtil.ossDownload(filePath, htmlFileTemp, uploadType.getFssType());
                 } else {
                     ossStr = SystemConstant.LOCAL;
                     if (Objects.nonNull(dictionaryConfig.fssPublicDomain()) && !StringUtils.isBlank(dictionaryConfig.fssPublicDomain().getConfig()) && filePath.contains(dictionaryConfig.fssPublicDomain().getConfig())) {
                         htmlFile = new File(filePath);
                     } else {
-                        File htmlFileTemp = SystemConstant.getFileTempVar(SystemConstant.HTML_PREFIX);
+                        htmlFileTemp = SystemConstant.getFileTempVar(SystemConstant.HTML_PREFIX);
                         htmlFile = fileStoreUtil.ossDownload(filePath, htmlFileTemp, uploadType.getFssType());
                     }
                     if (Objects.nonNull(dictionaryConfig.fssPrivateDomain()) && !StringUtils.isBlank(dictionaryConfig.fssPrivateDomain().getConfig()) && !dictionaryConfig.fssPrivateDomain().getConfig().startsWith(SystemConstant.START_PARENT)) {
@@ -217,7 +222,6 @@ public class PrintCommonServiceImpl implements PrintCommonService {
             pdfStringJoiner.add(SystemConstant.getNanoId()).add(SystemConstant.PDF_PREFIX);
             String pdfDirName = pdfStringJoiner.toString();
             File pdfFileTemp = SystemConstant.getFileTempVar(SystemConstant.PDF_PREFIX);
-            fileTempList.add(pdfFileTemp);
             HtmlToPdfUtil.convert(htmlFile.getPath(), pdfFileTemp.getPath(), PageSizeEnum.A4);
 
             String htmlFileMd5 = DigestUtils.md5Hex(new FileInputStream(htmlFile));
@@ -242,6 +246,10 @@ public class PrintCommonServiceImpl implements PrintCommonService {
             } else {
                 ResultUtil.error(e.getMessage());
             }
+        } finally {
+            if (htmlFileTemp != null) {
+                FileUtil.deleteFile(htmlFileTemp);
+            }
         }
         return basicAttachment;
     }
@@ -303,6 +311,59 @@ public class PrintCommonServiceImpl implements PrintCommonService {
         }
     }
 
+    @Override
+    @Transactional
+    public void saveAttachmentSignPdf(PdfSignDto pdfFillDto, ExamDetail examDetail, Integer printCount, BasicTemplate basicTemplate) {
+        File pdfFileTemp = null;
+        try {
+            boolean oss = dictionaryConfig.sysDomain().isOss();
+            StringJoiner pdfStringJoiner = new StringJoiner("");
+            String ossStr = null;
+            if (!oss && Objects.nonNull(dictionaryConfig.fssPrivateDomain()) && !StringUtils.isBlank(dictionaryConfig.fssPrivateDomain().getConfig()) && !dictionaryConfig.fssPrivateDomain().getConfig().startsWith(SystemConstant.START_PARENT)) {
+                pdfStringJoiner.add(dictionaryConfig.fssPrivateDomain().getConfig()).add(File.separator);
+            }
+            pdfStringJoiner = SystemConstant.getDirName(pdfStringJoiner, UploadFileEnum.PDF, true);
+            pdfStringJoiner.add(SystemConstant.getNanoId()).add(SystemConstant.PDF_PREFIX);
+
+            pdfFileTemp = SystemConstant.getFileTempVar(SystemConstant.PDF_PREFIX);
+            pdfFileTemp = createPrintPdfUtil.createSignPdf(pdfFillDto, pdfFileTemp.getPath(), basicTemplate);
+            // 校验签到表是否自动分页。2页及以上的pdf,每页后面都需要补一个空白页
+            // 补空白页
+            if (basicTemplate != null && basicTemplate.getAddBlankPage()) {
+                // 补空白页
+                PdfUtil.addPdfEmptyPage(pdfFileTemp);
+            }
+
+            String pdfDirName = FileUtil.replaceSplit(pdfStringJoiner.toString());
+            //pdf生成和上传
+            String pdfFileMd5 = DigestUtils.md5Hex(new FileInputStream(pdfFileTemp));
+            if (oss || (!oss && dictionaryConfig.fssPrivateDomain().getConfig().startsWith(SystemConstant.START_PARENT))) {
+                ossStr = oss ? SystemConstant.OSS : SystemConstant.LOCAL;
+                fileStoreUtil.ossUpload(pdfDirName, pdfFileTemp, pdfFileMd5, fileStoreUtil.getUploadEnumByPath(pdfDirName).getFssType());
+            } else {
+                ossStr = SystemConstant.LOCAL;
+                fileStoreUtil.localUpload(pdfDirName, new FileInputStream(pdfFileTemp), pdfFileMd5, LocalCatalogEnum.LOCAL_PDF);
+            }
+            PdfDto pdfDto = PdfUtil.addPdfPage(pdfFileTemp);
+            PrintPathVo printPathVo = new PrintPathVo(ClassifyEnum.SIGN, UploadFileEnum.PDF, ossStr, pdfDirName, pdfFileMd5, null, null);
+            examDetail.setAttachmentPath(parseAttachmentPath(examDetail.getAttachmentPath(), printPathVo));
+//            for (int i = 0; i < printCount; i++) {
+//                pdfList.add(new PdfDto(pdfFileTemp.getPath(), PageSizeEnum.A4, pdfDto.getPageCount(), 2));
+//            }
+        } catch (Exception e) {
+            log.error(SystemConstant.LOG_ERROR, e);
+            if (e instanceof ApiException) {
+                ResultUtil.error((ApiException) e, e.getMessage());
+            } else {
+                ResultUtil.error(e.getMessage());
+            }
+        } finally {
+            if (pdfFileTemp != null) {
+                FileUtil.deleteFile(pdfFileTemp);
+            }
+        }
+    }
+
     @Override
     public String parseAttachmentPath(String attachmentPath, PrintPathVo printPathVo) {
         List<PrintPathVo> printPathVos = new ArrayList<>();
@@ -550,6 +611,85 @@ public class PrintCommonServiceImpl implements PrintCommonService {
         return basicAttachment;
     }
 
+    /**
+     * 保存html附件
+     *
+     * @param fileName
+     * @param htmlContent
+     * @param userId
+     * @param localFileList
+     * @return
+     */
+    @Override
+    @Transactional
+    public BasicAttachment saveAttachmentPdfFromHtml(String fileName, String htmlContent, Long userId, List<PdfDto> localFileList) {
+        BasicAttachment basicAttachment = null;
+        File htmlFileTemp = null, pdfFileTemp = null;
+        try {
+            htmlFileTemp = SystemConstant.getFileTempVar(SystemConstant.HTML_PREFIX);
+            FileCopyUtils.copy(htmlContent.getBytes(StandardCharsets.UTF_8), htmlFileTemp);
+
+            return saveAttachmentPdfFromHtml(fileName, htmlFileTemp, userId, localFileList);
+        } catch (Exception e) {
+            log.error(SystemConstant.LOG_ERROR, e);
+            basicAttachmentService.deleteAttachment(basicAttachment);
+            if (e instanceof ApiException) {
+                ResultUtil.error((ApiException) e, e.getMessage());
+            } else {
+                ResultUtil.error(e.getMessage());
+            }
+        } finally {
+            if (htmlFileTemp != null) {
+                FileUtil.deleteFile(htmlFileTemp);
+            }
+//            if (pdfFileTemp != null) {
+//                FileUtil.deleteFile(pdfFileTemp);
+//            }
+        }
+        return basicAttachment;
+    }
+
+    @Override
+    @Transactional
+    public BasicAttachment saveAttachmentPdfFromHtml(String fileName, File file, Long userId, List<PdfDto> localFileList) {
+        BasicAttachment basicAttachment = null;
+        File  pdfFileTemp = null;
+        try {
+
+            pdfFileTemp = SystemConstant.getFileTempVar(SystemConstant.PDF_PREFIX);
+            // html转pdf
+            HtmlToPdfUtil.convert(file.getPath(), pdfFileTemp.getPath(), PageSizeEnum.A3);
+
+            //pdf上传
+            String pdfDirName = SystemConstant.getNanoId() + SystemConstant.PDF_PREFIX;
+            FilePathVo filePathVo = fileUploadService.uploadFile(pdfFileTemp, UploadFileEnum.PDF, pdfDirName);
+
+            PdfDto pdfDto = PdfUtil.addPdfPage(pdfFileTemp);
+            if(localFileList != null) {
+                localFileList.add(new PdfDto(pdfFileTemp.getPath(), PageSizeEnum.A3, pdfDto.getPageCount()));
+            }
+            basicAttachment = new BasicAttachment(JSON.toJSONString(filePathVo), fileName, SystemConstant.PDF_PREFIX, new BigDecimal(file.length()), filePathVo.getMd5(), userId);
+            basicAttachment.setPages(pdfDto.getActualPageCount());
+            basicAttachmentService.save(basicAttachment);
+        } catch (Exception e) {
+            log.error(SystemConstant.LOG_ERROR, e);
+            basicAttachmentService.deleteAttachment(basicAttachment);
+            if (e instanceof ApiException) {
+                ResultUtil.error((ApiException) e, e.getMessage());
+            } else {
+                ResultUtil.error(e.getMessage());
+            }
+        } finally {
+            if (file != null) {
+                FileUtil.deleteFile(file);
+            }
+//            if (pdfFileTemp != null) {
+//                FileUtil.deleteFile(pdfFileTemp);
+//            }
+        }
+        return basicAttachment;
+    }
+
     /**
      * 保存html附件和该html转成pdf的附件
      *
@@ -1196,6 +1336,68 @@ public class PrintCommonServiceImpl implements PrintCommonService {
         }
     }
 
+    @Override
+    public void checkDataNew(Long schoolId, Long examId, String courseCode, String paperNumber, SysUser user) throws IOException {
+        // 校验命题任务是否提交
+        ExamTask examTask = examTaskService.getByCourseCodeAndPaperNumber(schoolId, examId, courseCode, paperNumber);
+        BasicExam basicExam = basicExamService.getById(examTask.getExamId());
+        if (basicExam != null && ExamModelEnum.MODEL3.equals(basicExam.getExamModel())) {
+            log.info("考试模式为模式3,不生成pdf");
+            return;
+        }
+
+        if (examTask != null && !examTask.getEnable()) {
+            log.info("命题任务已禁用");
+            return;
+        }
+        ExamTaskDetail examTaskDetail = examTaskDetailService.getByExamTaskId(examTask.getId());
+        if (!examTaskDetail.getEnable()) {
+            log.info("卷库已禁用");
+            return;
+        }
+
+        boolean canCreatePdf = true;
+        if (examTask.getReview()) {
+            TFFlowApprove tfFlowApprove = tfFlowApproveService.findByFlowId(examTask.getFlowId());
+            // 1.命题任务已完成
+            if (tfFlowApprove == null || tfFlowApprove.getStatus() != FlowStatusEnum.FINISH) {
+                canCreatePdf = false;
+            }
+        }
+
+        if (canCreatePdf) {
+            // 2.校验考务数据是否导入
+            List<ExamDetail> examDetails = examDetailService.listByCourseCodeAndPaperNumber(schoolId, examId, courseCode, paperNumber);
+            if (examDetails != null && examDetails.size() > 0) {
+                // 3.检查examDetailId下有无其它课程
+                for (ExamDetail examDetail : examDetails) {
+                    List<ExamDetailCourse> examDetailCourses = examDetailCourseService.listByExamDetailIdAndStatus(examDetail.getId());
+                    // 4.没有未完成的命题任务
+                    if (examDetailCourses.isEmpty()) {
+                        // 更新考场状态为初始新建状态
+                        UpdateWrapper<ExamDetail> examDetailUpdateWrapper = new UpdateWrapper<>();
+                        examDetailUpdateWrapper.lambda().set(ExamDetail::getStatus, ExamDetailStatusEnum.NEW).eq(ExamDetail::getId, examDetail.getId());
+                        examDetailService.update(examDetailUpdateWrapper);
+
+                        //所有考场都撤回,印刷任务状态改为就绪
+                        QueryWrapper<ExamDetail> queryWrapper = new QueryWrapper<>();
+                        queryWrapper.lambda().eq(ExamDetail::getPrintPlanId, examDetail.getPrintPlanId()).notIn(ExamDetail::getStatus, ExamDetailStatusEnum.NEW, ExamDetailStatusEnum.READY);
+                        List<ExamDetail> examDetailss = examDetailService.list(queryWrapper);
+                        if (examDetailss.isEmpty()) {
+                            UpdateWrapper<ExamPrintPlan> printPlanUpdateWrapper = new UpdateWrapper<>();
+                            printPlanUpdateWrapper.lambda().set(ExamPrintPlan::getStatus, PrintPlanStatusEnum.READY).eq(ExamPrintPlan::getId, examDetail.getPrintPlanId());
+                            examPrintPlanService.update(printPlanUpdateWrapper);
+                        }
+                        TbTaskDetailResult tbTaskDetailResult = examDetailCourseService.getByExamDetailId(examDetail.getId());
+                        TBTaskPdf tbTaskPdf = tbTaskPdfService.saveTask(tbTaskDetailResult, TaskTypeEnum.CREATE_PDF, examDetail.getPrintPlanId(), user, examDetail.getId());
+//                        MqDto mqDto = new MqDto(MqTagEnum.PDF.getCode(), map, String.valueOf(map.get(SystemConstant.TB_TASK_ID)));
+//                        redisUtil.sendMessage(mqDto.getTopic(), mqDto);
+                    }
+                }
+            }
+        }
+    }
+
     /**
      * 校验是否可以提交
      *
@@ -1461,4 +1663,51 @@ public class PrintCommonServiceImpl implements PrintCommonService {
             }
         }
     }
+
+    @Override
+    public void saveAttachmentPackagePdf(PdfPackageDto pdfPackageDto, ExamDetail examDetail, Integer printCount) {
+        File pdfFileTemp = null;
+        try {
+            boolean oss = dictionaryConfig.sysDomain().isOss();
+            StringJoiner pdfStringJoiner = new StringJoiner("");
+            String ossStr = null;
+            if (!oss && Objects.nonNull(dictionaryConfig.fssPrivateDomain()) && !StringUtils.isBlank(dictionaryConfig.fssPrivateDomain().getConfig()) && !dictionaryConfig.fssPrivateDomain().getConfig().startsWith(SystemConstant.START_PARENT)) {
+                pdfStringJoiner.add(dictionaryConfig.fssPrivateDomain().getConfig()).add(File.separator);
+            }
+            pdfStringJoiner = SystemConstant.getDirName(pdfStringJoiner, UploadFileEnum.PDF, true);
+            pdfStringJoiner.add(SystemConstant.getNanoId()).add(SystemConstant.PDF_PREFIX);
+
+            String pdfDirName = FileUtil.replaceSplit(pdfStringJoiner.toString());
+            pdfFileTemp = SystemConstant.getFileTempVar(SystemConstant.PDF_PREFIX);
+            createPrintPdfUtil.createPackagePdf(pdfPackageDto, pdfFileTemp.getPath());
+            //pdf生成和上传
+            String pdfFileMd5 = DigestUtils.md5Hex(new FileInputStream(pdfFileTemp));
+            if (oss || (!oss && dictionaryConfig.fssPrivateDomain().getConfig().startsWith(SystemConstant.START_PARENT))) {
+                ossStr = oss ? SystemConstant.OSS : SystemConstant.LOCAL;
+                fileStoreUtil.ossUpload(pdfDirName, pdfFileTemp, pdfFileMd5, fileStoreUtil.getUploadEnumByPath(pdfDirName).getFssType());
+            } else {
+                ossStr = SystemConstant.LOCAL;
+                fileStoreUtil.localUpload(pdfDirName, new FileInputStream(pdfFileTemp), pdfFileMd5, LocalCatalogEnum.LOCAL_PDF);
+            }
+
+            PdfDto pdfDto = PdfUtil.addPdfPage(pdfFileTemp);
+            PrintPathVo printPathVo = new PrintPathVo(ClassifyEnum.PACKAGE, UploadFileEnum.PDF, ossStr, pdfDirName, pdfFileMd5, null, null);
+            examDetail.setAttachmentPath(parseAttachmentPath(examDetail.getAttachmentPath(), printPathVo));
+
+//            for (int i = 0; i < printCount; i++) {
+//                pdfList.add(new PdfDto(pdfFileTemp.getPath(), PageSizeEnum.A4, pdfDto.getPageCount(), 2));
+//            }
+        } catch (Exception e) {
+            log.error(SystemConstant.LOG_ERROR, e);
+            if (e instanceof ApiException) {
+                ResultUtil.error((ApiException) e, e.getMessage());
+            } else {
+                ResultUtil.error(e.getMessage());
+            }
+        } finally {
+            if (pdfFileTemp != null) {
+                FileUtil.deleteFile(pdfFileTemp);
+            }
+        }
+    }
 }

+ 66 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/TBTaskPdfServiceImpl.java

@@ -0,0 +1,66 @@
+package com.qmth.distributed.print.business.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.qmth.boot.api.exception.ApiException;
+import com.qmth.distributed.print.business.entity.TBTaskPdf;
+import com.qmth.distributed.print.business.mapper.TBTaskPdfMapper;
+import com.qmth.distributed.print.business.service.TBTaskPdfService;
+import com.qmth.teachcloud.common.bean.result.TbTaskDetailResult;
+import com.qmth.teachcloud.common.contant.SystemConstant;
+import com.qmth.teachcloud.common.entity.SysUser;
+import com.qmth.teachcloud.common.enums.TaskResultEnum;
+import com.qmth.teachcloud.common.enums.TaskStatusEnum;
+import com.qmth.teachcloud.common.enums.TaskTypeEnum;
+import com.qmth.teachcloud.common.util.ResultUtil;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Service;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * <p>
+ * 导入导出任务表 服务实现类
+ * </p>
+ *
+ * @author xf
+ * @since 2024-02-06
+ */
+@Service
+public class TBTaskPdfServiceImpl extends ServiceImpl<TBTaskPdfMapper, TBTaskPdf> implements TBTaskPdfService {
+
+    @Override
+    public boolean updateStatusById(TaskStatusEnum status, TaskResultEnum result, String summary, Long id) {
+        UpdateWrapper<TBTaskPdf> updateWrapper = new UpdateWrapper<>();
+        LambdaUpdateWrapper<TBTaskPdf> lambda = updateWrapper.lambda();
+        lambda.set(TBTaskPdf::getStatus, status)
+                .set(TBTaskPdf::getResult, result);
+        if (StringUtils.isNotBlank(summary)) {
+            lambda.set(TBTaskPdf::getSummary, status);
+        }
+        lambda.eq(TBTaskPdf::getId, id);
+        return this.update(updateWrapper);
+    }
+
+    @Override
+    public TBTaskPdf saveTask(TbTaskDetailResult tbTaskDetailResult, TaskTypeEnum createPdf, Long printPlanId, SysUser user, Long examDetailId) {
+        try {
+            TBTaskPdf tbTaskPdf = this.getById(examDetailId);
+            if (tbTaskPdf == null) {
+                tbTaskPdf = new TBTaskPdf(examDetailId, user.getSchoolId(), tbTaskDetailResult.getSemesterId(), tbTaskDetailResult.getExamId(), printPlanId, tbTaskDetailResult.getCourseNameCode(), tbTaskDetailResult.getPaperNumber(), user.getId());
+                this.save(tbTaskPdf);
+            }
+            return tbTaskPdf;
+        } catch (Exception e) {
+            log.error(SystemConstant.LOG_ERROR, e);
+            if (e instanceof ApiException) {
+                ResultUtil.error((ApiException) e, ((ApiException) e).getCode(), e.getMessage());
+            } else {
+                ResultUtil.error(e.getMessage());
+            }
+        }
+        return null;
+    }
+}

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

@@ -1,5 +1,6 @@
 package com.qmth.distributed.print.business.templete.create;
 
+import com.qmth.distributed.print.business.entity.TBTaskPdf;
 import com.qmth.distributed.print.business.templete.callback.CallbackCreatePdf;
 import com.qmth.distributed.print.business.templete.importData.AsyncImportTaskTemplete;
 import com.qmth.teachcloud.common.util.Result;
@@ -34,4 +35,9 @@ public abstract class AsyncCreateTaskTemplete extends AsyncImportTaskTemplete {
     public Result createPdf(Map<String, Object> map, CallbackCreatePdf callbackCreatePdf) throws IOException {
         return null;
     }
+
+    @Async("taskThreadPool")
+    public Result createPdf(TBTaskPdf tbTaskPdf, CallbackCreatePdf callbackCreatePdf) throws IOException {
+        return null;
+    }
 }

+ 51 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/execute/AsyncCreatePdfTempleteService.java

@@ -2,8 +2,11 @@ package com.qmth.distributed.print.business.templete.execute;
 
 import cn.hutool.core.date.DateUtil;
 import com.qmth.boot.api.exception.ApiException;
+import com.qmth.distributed.print.business.entity.TBTaskPdf;
+import com.qmth.distributed.print.business.service.TBTaskPdfService;
 import com.qmth.distributed.print.business.templete.callback.CallbackCreatePdf;
 import com.qmth.distributed.print.business.templete.create.AsyncCreateTaskTemplete;
+import com.qmth.distributed.print.business.templete.service.PdfTaskLogicService;
 import com.qmth.distributed.print.business.templete.service.TaskLogicService;
 import com.qmth.teachcloud.common.contant.SpringContextHolder;
 import com.qmth.teachcloud.common.contant.SystemConstant;
@@ -14,6 +17,7 @@ import com.qmth.teachcloud.common.enums.TaskStatusEnum;
 import com.qmth.teachcloud.common.service.TBTaskService;
 import com.qmth.teachcloud.common.util.Result;
 import com.qmth.teachcloud.common.util.ResultUtil;
+import org.bouncycastle.crypto.paddings.TBCPadding;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Service;
@@ -94,6 +98,53 @@ public class AsyncCreatePdfTempleteService extends AsyncCreateTaskTemplete {
         return ResultUtil.ok(map);
     }
 
+    /**
+     * 创建pdf
+     *
+     * @param tbTaskPdf
+     * @param callbackCreatePdf
+     * @return
+     * @throws IOException
+     */
+    @Override
+    public Result createPdf(TBTaskPdf tbTaskPdf, CallbackCreatePdf callbackCreatePdf) throws IOException {
+        StringJoiner stringJoinerSummary = new StringJoiner("\n").add(MessageFormat.format("{0}{1}{2}", DateUtil.format(new Date(), SystemConstant.DEFAULT_DATE_PATTERN), BEGIN_TITLE, OBJ_TITLE));
+        TBTaskPdfService tbTaskService = SpringContextHolder.getBean(TBTaskPdfService.class);
+//        if (Objects.isNull(manual) && (Objects.nonNull(dbTask) && dbTask.getStatus() == TaskStatusEnum.FINISH && Objects.nonNull(dbTask.getResult()))) {//无需重新生成pdf
+//            return ResultUtil.ok();
+//        }
+        tbTaskPdf.setStatus(TaskStatusEnum.RUNNING);
+        tbTaskService.updateById(tbTaskPdf);
+        try {
+            PdfTaskLogicService pdfTaskLogicService = SpringContextHolder.getBean(PdfTaskLogicService.class);
+            pdfTaskLogicService.executeCreatePdfLogic(tbTaskPdf);
+            stringJoinerSummary.add(MessageFormat.format("{0}{1}{2}{3}", DateUtil.format(new Date(), SystemConstant.DEFAULT_DATE_PATTERN), FINISH_TITLE, 0, FINISH_ERROR_SIZE));
+            tbTaskPdf.setResult(TaskResultEnum.SUCCESS);
+        } catch (Exception e) {
+            log.error(SystemConstant.LOG_ERROR, e);
+            stringJoinerSummary.add(MessageFormat.format("{0}{1}{2}{3}", DateUtil.format(new Date(), SystemConstant.DEFAULT_DATE_PATTERN), EXCEPTION_TITLE, EXCEPTION_DATA, e.getMessage()));
+            tbTaskPdf.setResult(TaskResultEnum.ERROR);
+            if (e instanceof ApiException) {
+                if (((ApiException) e).getCode() == ExceptionResultEnum.PAPER_ERROR.getCode()
+                        || ((ApiException) e).getCode() == ExceptionResultEnum.PAPER_TYPE_ERROR.getCode()
+                        || ((ApiException) e).getCode() == ExceptionResultEnum.ATTACHMENT_IS_NULL.getCode()
+                        || ((ApiException) e).getCode() == ExceptionResultEnum.EXAM_PRINT_IS_NULL.getCode()
+                        || ((ApiException) e).getCode() == ExceptionResultEnum.EXAM_RULE_IS_NULL.getCode()
+                        || ((ApiException) e).getCode() == ExceptionResultEnum.EXAM_DETAIL_IS_NULL.getCode()
+                        || ((ApiException) e).getCode() == ExceptionResultEnum.EXAM_CARD_IS_NULL.getCode()
+                        || ((ApiException) e).getCode() == ExceptionResultEnum.EXAM_TASK_IS_NULL.getCode()) {
+//                    tbTaskPdf.setErrorMessage(e.getMessage());
+                }
+                ResultUtil.error((ApiException) e, ((ApiException) e).getCode(), e.getMessage());
+            } else {
+                ResultUtil.error(e.getMessage());
+            }
+        } finally {
+            tbTaskPdf.setSummary(stringJoinerSummary.toString());
+        }
+        return ResultUtil.ok(tbTaskPdf);
+    }
+
     @Override
     public Result importTask(Map<String, Object> map) throws IOException {
         return null;

+ 26 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/service/PdfTaskLogicService.java

@@ -0,0 +1,26 @@
+package com.qmth.distributed.print.business.templete.service;
+
+import com.qmth.distributed.print.business.entity.TBTaskPdf;
+
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * @Description: 任务处理逻辑
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2021/3/29
+ */
+public interface PdfTaskLogicService {
+
+
+    /**
+     * 创建pdf逻辑
+     *
+     * @param tbTaskPdf
+     * @return
+     */
+
+    void executeCreatePdfLogic(TBTaskPdf tbTaskPdf);
+}

+ 409 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/service/impl/PdfTaskLogicServiceImpl.java

@@ -0,0 +1,409 @@
+package com.qmth.distributed.print.business.templete.service.impl;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.qmth.distributed.print.business.bean.dto.CreatePdfDto;
+import com.qmth.distributed.print.business.bean.dto.ExamStudentCourseDto;
+import com.qmth.distributed.print.business.bean.dto.PaperPdfDto;
+import com.qmth.distributed.print.business.bean.dto.PdfDto;
+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.templete.service.PdfTaskLogicService;
+import com.qmth.distributed.print.business.util.pdf.CreatePdfNewUtil;
+import com.qmth.teachcloud.common.base.BaseEntity;
+import com.qmth.teachcloud.common.bean.vo.PaperInfoVo;
+import com.qmth.teachcloud.common.contant.SystemConstant;
+import com.qmth.teachcloud.common.entity.BasicAttachment;
+import com.qmth.teachcloud.common.entity.BasicExam;
+import com.qmth.teachcloud.common.entity.BasicPrintConfig;
+import com.qmth.teachcloud.common.entity.BasicSchool;
+import com.qmth.teachcloud.common.enums.CreatePdfTypeEnum;
+import com.qmth.teachcloud.common.enums.ExamCategoryEnum;
+import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
+import com.qmth.teachcloud.common.enums.FlowStatusEnum;
+import com.qmth.teachcloud.common.service.BasicAttachmentService;
+import com.qmth.teachcloud.common.service.BasicStudentService;
+import com.qmth.teachcloud.common.service.CommonCacheService;
+import com.qmth.teachcloud.common.util.ExamTaskUtil;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+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;
+
+import javax.annotation.Resource;
+import java.util.*;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
+
+/**
+ * @Description: 任务处理逻辑impl
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2021/3/29
+ */
+@Service
+public class PdfTaskLogicServiceImpl implements PdfTaskLogicService {
+    private final static Logger log = LoggerFactory.getLogger(PdfTaskLogicServiceImpl.class);
+
+    @Resource
+    ExamPrintPlanService examPrintPlanService;
+    @Resource
+    ExamTaskService examTaskService;
+    @Resource
+    ExamTaskDetailService examTaskDetailService;
+    @Resource
+    ExamCardService examCardService;
+    @Resource
+    ExamStudentService examStudentService;
+    @Resource
+    BasicAttachmentService basicAttachmentService;
+    @Resource
+    ExamDetailService examDetailService;
+    @Resource
+    CommonCacheService commonCacheService;
+    @Resource
+    CreatePdfNewUtil createPdfNewUtil;
+    @Resource
+    BasicCardRuleService basicCardRuleService;
+    @Autowired
+    ExamDetailCourseService examDetailCourseService;
+    @Autowired
+    BasicStudentService basicStudentService;
+    @Autowired
+    ExamTaskPrintService examTaskPrintService;
+    @Resource
+    BasicExamService basicExamService;
+    @Resource
+    ExamTaskAssignPaperTypeService examTaskAssignPaperTypeService;
+
+    /**
+     * 创建A4文件
+     *
+     * @param tbTaskPdf
+     * @param examDetailCourseList
+     * @throws Exception
+     */
+    @Transactional
+    public void createA4File(TBTaskPdf tbTaskPdf, List<ExamDetailCourse> examDetailCourseList) throws Exception {
+        CreatePdfTypeEnum createPdfType = tbTaskPdf.getCreateType();
+        ExamPrintPlan examPrintPlan = examPrintPlanService.getById(tbTaskPdf.getPrintPlanId());
+        ExamDetail examDetail = examDetailService.getById(tbTaskPdf.getId());
+        BasicSchool basicSchool = commonCacheService.schoolCache(tbTaskPdf.getSchoolId());
+        // 印品
+        String ordinaryContent = examPrintPlan.getOrdinaryContent();
+        if ((CreatePdfTypeEnum.ALL.equals(createPdfType) || CreatePdfTypeEnum.CHECK_IN.equals(createPdfType)) && StringUtils.isNotBlank(ordinaryContent)) {
+            //获取普通印品
+            JSONArray jsonArrayOrdinary = JSONArray.parseArray(ordinaryContent);
+            for (int i = 0; i < jsonArrayOrdinary.size(); i++) {
+                JSONObject jsonObjectOrdinary = jsonArrayOrdinary.getJSONObject(i);
+                if (Objects.nonNull(jsonObjectOrdinary.get("attachmentId")) && !Objects.equals("", jsonObjectOrdinary.get("attachmentId"))) {
+                    Long attachmentId = Long.parseLong((String) jsonObjectOrdinary.get("attachmentId"));
+                    BasicAttachment basicAttachment = basicAttachmentService.getById(attachmentId);
+                    createPdfNewUtil.createCheckIn(examDetail, basicAttachment, (Integer) jsonObjectOrdinary.get("backupCount"));
+                }
+            }
+        }
+        BasicExam basicExam = basicExamService.getById(examPrintPlan.getExamId());
+        if (basicExam.getCategory().equals(ExamCategoryEnum.FORMAL)) {
+            String variableContent = examPrintPlan.getVariableContent();
+            if (StringUtils.isNotBlank(variableContent)) {
+                List<Long> examDetailCourseListIds = examDetailCourseList.stream().map(BaseEntity::getId).collect(Collectors.toList());
+                List<ExamStudentCourseDto> examStudentCourseDtoList = examStudentService.queryBySchoolIdAndExamDetailCourseIds(basicSchool.getId(), examDetailCourseListIds);
+                //获取变量印品
+                JSONArray jsonArrayVariable = JSONArray.parseArray(variableContent);
+                for (int i = 0; i < jsonArrayVariable.size(); i++) {
+                    JSONObject jsonObjectVariable = jsonArrayVariable.getJSONObject(i);
+                    String type = (String) jsonObjectVariable.get("type");
+                    if (Objects.nonNull(jsonObjectVariable.get("templateId")) && !Objects.equals("", jsonObjectVariable.get("templateId"))) {
+                        Long templateId = Long.parseLong((String) jsonObjectVariable.get("templateId"));
+                        if ((CreatePdfTypeEnum.ALL.equals(createPdfType) || CreatePdfTypeEnum.SIGN.equals(createPdfType)) && Objects.nonNull(type) && Objects.equals(type.toUpperCase(), "SIGN")) {//签到表
+                            createPdfNewUtil.createSignBook(templateId, basicSchool.getName(), examDetail, examStudentCourseDtoList, (Integer) jsonObjectVariable.get("backupCount"), examDetailCourseList);
+                        } else if ((CreatePdfTypeEnum.ALL.equals(createPdfType) || CreatePdfTypeEnum.PACKAGE.equals(createPdfType)) && Objects.nonNull(type) && Objects.equals(type.toUpperCase(), "PACKAGE")) {//卷袋贴
+                            Integer backupCount = SystemConstant.calcBackupCount(examDetail.getBackupCount(), examDetail.getTotalSubjects(), 1);
+                            createPdfNewUtil.createPaperPackage(templateId, basicSchool.getName(), examDetail, examStudentCourseDtoList, backupCount, (Integer) jsonObjectVariable.get("backupCount"), examDetailCourseList, examPrintPlan.getExamId());
+                        }
+                    }
+                }
+            }
+        }
+        examDetailService.updateById(examDetail);
+    }
+
+    @Override
+    public void executeCreatePdfLogic(TBTaskPdf tbTaskPdf) {
+        try {
+            // 更新状态(考场状态、印刷计划状态)
+            updatePdfDataStatus(tbTaskPdf);
+            List<ExamDetailCourse> examDetailCourseList = examDetailCourseService.listByExamDetailId(tbTaskPdf.getId());
+            // 抽取卷型,更新考场、考生对应卷型值
+            updateAssignPaperType(tbTaskPdf, examDetailCourseList);
+            // 查询生成pdf需要文件
+            CreatePdfDto createPdfDto = new CreatePdfDto();
+            assemblePdfFile(tbTaskPdf, createPdfDto);
+            // 生成pdf文件并合并
+            //合并(试卷+备用试卷)
+            String dirNamePaper = createPdfNewUtil.mergeA3Pdf(createPdfDto.getPaperPdfList(), createPdfDto.getBackupPaperPdfList());
+            //合并A3(题卡+备用题卡)
+            String dirNameCardA3 = createPdfNewUtil.mergeA3Pdf(createPdfDto.getCardPdfList(), createPdfDto.getBackupCardPdfList());
+            // 生成A4文件
+            createA4File(tbTaskPdf, examDetailCourseList);
+            // 更新文件路径、更新考场状态、印刷计划状态
+            createPdfNewUtil.mergePdfSaveDb(dirNamePaper, dirNameCardA3, tbTaskPdf);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private void assemblePdfFile(TBTaskPdf tbTaskPdf, CreatePdfDto createPdfDto) throws Exception {
+        List<ExamDetailCourse> examDetailCourseList = examDetailCourseService.listByExamDetailId(tbTaskPdf.getId());
+        for (ExamDetailCourse examDetailCourse : examDetailCourseList) {
+            String[] paperTypes = examDetailCourse.getPaperType().split(",");
+
+            List<PdfDto> studentPaperPdfList = new ArrayList<>();//所有试卷
+            List<PdfDto> studentCardPdfList = new ArrayList<>();//所有题卡
+            List<PdfDto> backupPaperPdfList = new ArrayList<>();//备份试卷
+            List<PdfDto> backupCardPdfList = new ArrayList<>();//备份题卡
+
+            //查询命题任务绑定的试卷和题卡
+            ExamTask examTask = examTaskService.getByCourseCodeAndPaperNumber(tbTaskPdf.getSchoolId(), tbTaskPdf.getExamId(), examDetailCourse.getCourseCode(), examDetailCourse.getPaperNumber());
+            if (examTask == null) {
+                throw ExceptionResultEnum.EXAM_TASK_IS_NULL.exception();
+            } else if (examTask.getReview()) {
+                examTask = examTaskService.findExamTaskByFlowStatus(tbTaskPdf.getSchoolId(), tbTaskPdf.getExamId(), examDetailCourse.getCourseCode(), examDetailCourse.getPaperNumber(), FlowStatusEnum.FINISH);
+            } else {
+                if (!ExamStatusEnum.SUBMIT.equals(examTask.getStatus())) {
+                    throw ExceptionResultEnum.EXAM_TASK_NOT_SUBMIT.exception();
+                } else if (!examTask.getEnable()) {
+                    throw ExceptionResultEnum.EXAM_TASK_ENABLE.exception();
+                }
+            }
+            ExamTaskDetail examTaskDetail = examTaskDetailService.getByExamTaskId(examTask.getId());
+
+            Map<String, ExamCard> examCardMap = new HashMap<>();
+            List<PaperInfoVo> paperInfoVoList = ExamTaskUtil.parsePaperAttachmentPath(examTaskDetail.getPaperAttachmentIds());
+            ExamCard examCard;
+            for (PaperInfoVo paperInfoVo : paperInfoVoList) {
+                Long cardId = Long.valueOf(paperInfoVo.getCardId());
+                if (Objects.nonNull(cardId)) {
+                    examCard = examCardService.getById(cardId);
+                    if (Objects.isNull(examCard)) {
+                        throw ExceptionResultEnum.EXAM_CARD_IS_NULL.exception();
+                    }
+                    examCardMap.put(paperInfoVo.getName(), examCard);
+                }
+            }
+
+            //查询题卡规则
+            BasicCardRule basicCardRule = basicCardRuleService.getById(examTask.getCardRuleId());
+
+            List<ExamStudent> examStudentList = examStudentService.listByExamDetailCourseId(examDetailCourse.getId());
+
+            CreatePdfTypeEnum createPdfType = tbTaskPdf.getCreateType();
+
+            ExamPrintPlan examPrintPlan = examPrintPlanService.getById(tbTaskPdf.getPrintPlanId());
+            String printContent = examPrintPlan.getPrintContent();
+            if (StringUtils.isBlank(printContent)) {
+                continue;
+            }
+
+            // 计算备份数量,默认最小为1份。
+            ExamDetail examDetail = examDetailService.getById(tbTaskPdf.getId());
+            int backupCount = SystemConstant.calcBackupCount(examDetail.getBackupCount(), examDetail.getTotalSubjects(), 1);
+
+            // 试卷数据组装
+            if ((CreatePdfTypeEnum.ALL.equals(createPdfType) || CreatePdfTypeEnum.PAPER.equals(createPdfType)) && printContent.contains("PAPER")) {
+                List<PaperPdfDto> paperPdfDto = createPdfNewUtil.getPaperPdfFile(examDetailCourse.getPaperType(), examTaskDetail, createPdfDto.getFileTempList());
+
+                //获取试卷pdf
+                PdfDto pdfDto = createPdfNewUtil.getPaperPdf(paperPdfDto, backupCount, backupPaperPdfList);
+                if (Objects.nonNull(pdfDto)) {
+                    examDetailCourse.setPaperPagesA3(pdfDto.getPageCount());
+                } else {
+                    examDetailCourse.setPaperPagesA3(examDetailCourse.getPaperPagesA3());
+                }
+                // 备用试卷
+                createPdfDto.getBackupPaperPdfList().addAll(backupPaperPdfList);
+
+                if (examStudentList != null && examStudentList.size() > 0) {
+                    for (ExamStudent t : examStudentList) {
+                        if (Objects.nonNull(pdfDto)) {
+                            String[] waterMarkNames = {t.getStudentName(), t.getTicketNumber()};
+                            createPdfNewUtil.getExamStudentPaperPdf(t.getPaperType(), paperPdfDto, studentPaperPdfList, waterMarkNames);
+                        }
+                    }
+                } else if (examDetail.getTotalSubjects() != null) {
+                    AtomicInteger atomicInteger = new AtomicInteger(0);
+                    int i = 0;
+                    while (i < examDetail.getTotalSubjects()) {
+                        int seq = atomicInteger.getAndIncrement();
+                        int mod = seq % paperTypes.length;
+                        if (Objects.nonNull(pdfDto)) {
+                            createPdfNewUtil.getExamStudentPaperPdf(paperTypes[mod], paperPdfDto, studentPaperPdfList, null);
+                        }
+                        i++;
+                    }
+                } else {
+                    throw ExceptionResultEnum.ERROR.exception("数据错误:未找到考生或者印刷数量");
+                }
+                // 考生试卷
+                createPdfDto.getPaperPdfList().addAll(studentPaperPdfList);
+            }
+
+            // 题卡数据组装
+            if ((CreatePdfTypeEnum.ALL.equals(createPdfType) || CreatePdfTypeEnum.CARD_A3.equals(createPdfType)) && printContent.contains("CARD")) {
+                Map<String, ExamCard> examCardDetailMap = new HashMap<>();
+                Map<String, String> cardContentMap = new HashMap<>();
+                JSONObject jsonObject = new JSONObject();
+                JSONArray jsonArray = new JSONArray();
+                JSONArray stuJsonArray = new JSONArray();
+                for (String s : paperTypes) {
+                    examCard = examCardMap.get(s);
+                    Optional.ofNullable(examCard).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("卷型" + s + "题卡不存在"));
+
+                    //把模板页面上的 ${} 替换成空
+                    String cardContent = createPdfNewUtil.resetHtmlTemplateBar(examCard.getHtmlContent());
+
+                    for (int i = 1; i <= backupCount; i++) {
+                        String packageCode = examDetail.getPackageCode() + String.format(SystemConstant.DATE_TIME_FORMAT, i);
+                        BasicAttachment basicAttachment = createPdfNewUtil.cardHtml(packageCode, cardContent, s, tbTaskPdf.getCreateId(), backupCardPdfList, basicCardRule);
+                        examDetailCourse.setCardPagesA3(basicAttachment.getPages());
+
+                        JSONObject object = new JSONObject();
+                        object.put("name", s);
+                        object.put("attachmentId", basicAttachment.getId());
+                        object.put("packageCode", packageCode);
+                        jsonArray.add(object);
+                    }
+                    examCardDetailMap.put(s, examCard);
+                    cardContentMap.put(s, cardContent);
+                }
+                jsonObject.put("card", jsonArray);
+                examDetailCourse.setAttachmentId(jsonObject.toJSONString());
+
+                // 备用题卡
+                createPdfDto.getBackupCardPdfList().addAll(backupCardPdfList);
+
+                if (examStudentList != null && examStudentList.size() > 0) {
+                    for (ExamStudent t : examStudentList) {
+                        // 用带条码的模板
+                        createPdfNewUtil.examStudentHtml(examCardDetailMap.get(t.getPaperType()).getHtmlContent(), t, t.getPaperType(), examDetail, tbTaskPdf.getCreateId(), studentCardPdfList, basicCardRule);
+                    }
+                    examStudentService.updateBatchById(examStudentList);
+                } else if (examDetailCourse.getTotalSubjects() != null) {
+                    AtomicInteger atomicInteger = new AtomicInteger(0);
+                    Map<String, BasicAttachment> stringBasicAttachmentMap = new HashMap<>();
+                    int i = 0;
+                    while (i < examDetailCourse.getTotalSubjects()) {
+                        int seq = atomicInteger.getAndIncrement();
+                        int mod = seq % examTaskDetail.getDrawCount();
+                        String tempPaperType = paperTypes[mod];
+                        BasicAttachment basicAttachment = createPdfNewUtil.examStudentHtml(cardContentMap.get(tempPaperType), null, tempPaperType, examDetail, tbTaskPdf.getCreateId(), studentCardPdfList, basicCardRule);
+
+                        if (!stringBasicAttachmentMap.containsKey(tempPaperType)) {
+                            stringBasicAttachmentMap.put(tempPaperType, basicAttachment);
+                            JSONObject object = new JSONObject();
+                            object.put("name", tempPaperType);
+                            object.put("attachmentId", basicAttachment.getId());
+                            stuJsonArray.add(object);
+
+                            // 用不带条码的模板
+//                            basicAttachmentList.add(basicAttachment);
+                        }
+                        i++;
+                    }
+                    examDetailCourse.setCommonAttachmentId(stuJsonArray.toJSONString());
+                } else {
+                    throw ExceptionResultEnum.ERROR.exception("数据错误:未找到考生或者印刷数量");
+                }
+                // 题卡
+                createPdfDto.getCardPdfList().addAll(studentCardPdfList);
+            }
+        }
+    }
+
+    @Transactional
+    public void updateAssignPaperType(TBTaskPdf tbTaskPdf, List<ExamDetailCourse> examDetailCourseList) {
+
+        for (ExamDetailCourse examDetailCourse : examDetailCourseList) {
+            ExamTaskAssignPaperType examTaskAssignPaperType = examTaskAssignPaperTypeService.extractPaperType(tbTaskPdf, examDetailCourse);
+            List<ExamStudent> examStudentList = examStudentService.listByExamDetailCourseId(examDetailCourse.getId());
+            // 考生实际关联试卷类型
+            List<String> relatePaperTypes = new ArrayList<>();
+            List<String> paperTypes = Arrays.stream(examTaskAssignPaperType.getPaperType().split(",")).sorted(Comparator.comparing(String::valueOf)).collect(Collectors.toList());
+            if (CollectionUtils.isNotEmpty(examStudentList)) {
+                AtomicInteger atomicInteger = new AtomicInteger(0);
+                for (ExamStudent examStudent : examStudentList) {
+                    int i1 = atomicInteger.getAndIncrement();
+                    int mod = i1 % paperTypes.size();
+                    examStudent.setPaperType(paperTypes.get(mod));
+                    if (!relatePaperTypes.contains(examStudent.getPaperType())) {
+                        relatePaperTypes.add(examStudent.getPaperType());
+                    }
+                }
+            } else if (examDetailCourse.getTotalSubjects() != null) {
+                if (examDetailCourse.getTotalSubjects().intValue() - paperTypes.size() >= 0) {
+                    relatePaperTypes.addAll(paperTypes);
+                } else {
+                    for (int i = 0; i < examDetailCourse.getTotalSubjects().intValue(); i++) {
+                        relatePaperTypes.add(paperTypes.get(i));
+                    }
+                }
+            } else {
+                relatePaperTypes.addAll(paperTypes);
+            }
+
+            // 更新卷型数据
+            if (!CollectionUtils.isEqualCollection(paperTypes, relatePaperTypes)) {
+                examTaskAssignPaperType.setPaperType(String.join(",", relatePaperTypes));
+                examTaskAssignPaperTypeService.updateByMultiId(examTaskAssignPaperType);
+            }
+
+            examDetailCourse.setPaperType(String.join(",", relatePaperTypes));
+            examDetailCourseService.updateById(examDetailCourse);
+
+            examStudentService.updateBatchById(examStudentList);
+        }
+    }
+
+    private void updatePdfDataStatus(TBTaskPdf tbTaskPdf) {
+        //查询printPlan
+        ExamPrintPlan examPrintPlan = examPrintPlanService.getById(tbTaskPdf.getPrintPlanId());
+        if (Objects.isNull(examPrintPlan)) {
+            throw ExceptionResultEnum.EXAM_PRINT_IS_NULL.exception();
+        }
+        UpdateWrapper<ExamDetail> examDetailQueryWrapper = new UpdateWrapper<>();
+        examDetailQueryWrapper.lambda().set(ExamDetail::getStatus, ExamDetailStatusEnum.CREATING)
+                .eq(ExamDetail::getId, tbTaskPdf.getId());
+        examDetailService.update(examDetailQueryWrapper);
+
+        //所有考场都撤回,印刷任务状态改为就绪
+        QueryWrapper<ExamDetail> queryWrapper = new QueryWrapper<>();
+        queryWrapper.lambda().eq(ExamDetail::getPrintPlanId, tbTaskPdf.getPrintPlanId())
+                .notIn(ExamDetail::getStatus, ExamDetailStatusEnum.NEW, ExamDetailStatusEnum.READY);
+        List<ExamDetail> examDetails = examDetailService.list(queryWrapper);
+        if (CollectionUtils.isEmpty(examDetails)) {
+            examPrintPlanService.updateStatusById(tbTaskPdf.getPrintPlanId(), PrintPlanStatusEnum.READY);
+        }
+    }
+
+    /**
+     * 更新考试计划
+     *
+     * @param basicPrintConfig
+     * @param examPrintPlan
+     */
+    @Transactional
+    public void updateExamPrintPlan(BasicPrintConfig basicPrintConfig, ExamPrintPlan examPrintPlan) {
+
+    }
+
+}

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

@@ -121,143 +121,10 @@ public class CreatePdfUtil {
                 ordinaryPdfList.add(new PdfDto(filePath, PageSizeEnum.A4, 0));
             }
         } else {
-            printCommonService.saveAttachmentPdf(ClassifyEnum.CHECK_IN, examDetail, basicAttachment, ordinaryPdfList, printCount, 0, fileTempList);
+            printCommonService.saveAttachmentPdf(ClassifyEnum.CHECK_IN, examDetail, basicAttachment, ordinaryPdfList, printCount, 0);
         }
     }
 
-//    /**
-//     * 生成卷袋贴
-//     *
-//     * @param tag
-//     * @param basicAttachment
-//     * @param schoolName
-//     * @param examStudentList
-//     * @param variablePdfList
-//     * @param printCount
-//     * @param examDetailCourseList
-//     * @throws IOException
-//     */
-//    public void createPaperPackage(boolean tag, BasicAttachment basicAttachment, String schoolName, ExamDetail examDetail, List<ExamStudentCourseDto> examStudentList, List<PdfDto> variablePdfList, Integer printCount, List<ExamDetailCourse> examDetailCourseList) throws IOException {
-//        if (Objects.isNull(basicAttachment)) {
-//            throw ExceptionResultEnum.ATTACHMENT_IS_NULL.exception();
-//        }
-//        Map<String, Object> htmlMap = new HashMap<>();
-//        if (Objects.nonNull(examDetailCourseList) && examDetailCourseList.size() > 0) {
-//            List<String> paperNumbers = examDetailCourseList.stream().map(s -> s.getPaperNumber()).collect(Collectors.toList());
-//            List<String> courseCodes = examDetailCourseList.stream().map(s -> s.getCourseCode()).collect(Collectors.toList());
-//            List<String> courseNames = examDetailCourseList.stream().map(s -> s.getCourseName()).collect(Collectors.toList());
-//            htmlMap.put("courseName", String.join(", ", courseNames));
-//            htmlMap.put("courseCode", String.join(", ", paperNumbers));
-//            // 学院
-////            Set<String> stringSet = new HashSet<>();
-////            List<BasicCourse> basicCourses = basicCourseService.findBySchoolIdAndCourseCode(examDetail.getSchoolId(), courseCodes);
-////            for (BasicCourse basicCours : basicCourses) {
-////                List<SysOrg> sysOrgs = sysOrgService.findParentsByOrgId(basicCours.getTeachingRoomId());
-////                Set<String> collegeName = sysOrgs.stream().filter(m -> OrgTypeEnum.COLLEGE.equals(m.getType())).map(m -> m.getName()).collect(Collectors.toSet());
-////                if (CollectionUtils.isEmpty(collegeName)) {
-////                    collegeName = sysOrgs.stream().filter(m -> OrgTypeEnum.FACULTY.equals(m.getType())).map(m -> m.getName()).collect(Collectors.toSet());
-////                }
-////                if (!CollectionUtils.isEmpty(collegeName)) {
-////                    stringSet.addAll(collegeName);
-////                }
-////            }
-////            htmlMap.put("collegeName", CollectionUtils.isEmpty(stringSet) ? "" : String.join(",", stringSet));
-//        } else {
-//            htmlMap.put("courseName", "");
-//            htmlMap.put("courseCode", "");
-//            htmlMap.put("collegeName", "");
-//        }
-//        Set<Long> clazzIdSet = new HashSet<>();
-//        for (ExamDetailCourse examDetailCourse : examDetailCourseList) {
-//            String clazzInfo = examDetailCourse.getClazzId();
-//            if (SystemConstant.strNotNull(clazzInfo)) {
-//                Set<Long> clazzIdSetCell = Arrays.stream(clazzInfo.split(",")).map(SystemConstant::convertIdToLong).collect(Collectors.toSet());
-//                clazzIdSet.addAll(clazzIdSetCell);
-//            }
-//        }
-//        List<Long> classIds = new ArrayList<>(clazzIdSet);
-//
-////        String campusName = CollectionUtils.isEmpty(classIds) ? "" : basicCampusService.findCampusNamesByClazzIdList(classIds, ",");
-//        htmlMap.put("schoolName", schoolName);
-////        htmlMap.put("campusName", campusName);
-//        htmlMap.put("examSite", examDetail.getExamPlace());
-//        htmlMap.put("examRoom", examDetail.getExamRoom());
-//        htmlMap.put("startTime", DateUtil.format(new Date(examDetail.getExamStartTime()), SystemConstant.DEFAULT_DATE_PATTERN));
-//        htmlMap.put("endTime", DateUtil.format(new Date(examDetail.getExamEndTime()), SystemConstant.DEFAULT_DATE_PATTERN));
-//        htmlMap.put("paperCode", examDetail.getPackageCode());
-//        htmlMap.put("paperCodeImg", GoogleBarCodeUtil.createBarCode(examDetail.getPackageCode(), false));
-//
-//        List<String> extendColumnList = examStudentList.stream().map(m -> m.getExtendFields()).distinct().collect(Collectors.toList());
-//        Set<String> startCollege = new HashSet();
-//        Set<String> className = new HashSet();
-//        Set<String> proctorCollege = new HashSet();
-//        Set<String> examManager = new HashSet();
-//
-//        String className1 = examDetailService.findClazzNamesByClazzIds(classIds, ",");
-//
-//        if (Objects.nonNull(extendColumnList) && extendColumnList.size() > 0) {
-//            for (String s : extendColumnList) {
-//                List<Map> mapList = JSONObject.parseArray(s, Map.class);
-//                for (Map map : mapList) {
-//                    if (Objects.equals("startCollege", map.get("code").toString())) {
-//                        startCollege.add(map.get("value").toString());
-//                    }
-//                    if (Objects.equals("className", map.get("code").toString())) {
-//                        className.add(map.get("value").toString());
-//                    }
-//                    if (Objects.equals("proctorCollege", map.get("code").toString())) {
-//                        proctorCollege.add(map.get("value").toString());
-//                    }
-//                    if (Objects.equals("examManager", map.get("code").toString())) {
-//                        examManager.add(map.get("value").toString());
-//                    }
-//                }
-//            }
-//        }
-//
-//        htmlMap.put("startCollege", String.join(",", startCollege));
-//        htmlMap.put("className", StringUtils.isNotBlank(className1) ? className1 : String.join(",", className));
-//        htmlMap.put("proctorCollege", String.join(",", proctorCollege));
-//        htmlMap.put("examManager", String.join(",", examManager));
-//
-////        List<ExamStudent> tempList = examStudentList.stream().filter(s -> (Objects.nonNull(s.getSiteNumber()) && !Objects.equals("", s.getSiteNumber().trim()))).collect(Collectors.toList());
-////        String minSite = "", maxSite = "";
-////        if (Objects.nonNull(tempList) && tempList.size() > 0) {
-////            minSite = tempList.stream().min((a, b) -> a.getSiteNumber().compareTo(b.getSiteNumber())).get().getSiteNumber();
-////            maxSite = tempList.stream().max((a, b) -> a.getSiteNumber().compareTo(b.getSiteNumber())).get().getSiteNumber();
-////        }
-//
-//        Optional<ExamStudentCourseDto> minSite = null;
-//        Optional<ExamStudentCourseDto> maxSite = null;
-//        List<ExamStudentCourseDto> tempList = examStudentList.stream().filter(s -> (Objects.nonNull(s.getSiteNumber()) && !Objects.equals("", s.getSiteNumber().trim()))).collect(Collectors.toList());
-//        if (Objects.nonNull(tempList) && tempList.size() > 0) {
-////            for (ExamStudentCourseDto e : tempList) {
-////                char[] chars = e.getSiteNumber().toLowerCase().toCharArray();
-////                String ascii = "";
-////                for (int i = 0; i < chars.length; i++) {
-////                    ascii = ascii + chars[i];
-////                }
-////                e.setAscii(ascii.hashCode());
-////            }
-//            minSite = tempList.stream().min(Comparator.comparing(s -> s.getSiteNumber().hashCode()));
-//            maxSite = tempList.stream().max(Comparator.comparing(s -> s.getSiteNumber().hashCode()));
-//        }
-//
-//        htmlMap.put("minSite", Optional.ofNullable(minSite).map(s -> s.get().getSiteNumber()).orElse(""));
-//        htmlMap.put("maxSite", Optional.ofNullable(maxSite).map(s -> s.get().getSiteNumber()).orElse(""));
-//        htmlMap.put("studentCount", examStudentList != null && examStudentList.size() > 0 ? examStudentList.size() : examDetail.getPrintCount());
-//
-//        String tagValue = tag ? "订" : null;
-//        htmlMap.put("tag", tagValue);
-//
-//        htmlMap.computeIfAbsent("basicAttachment", v -> basicAttachment);
-//        htmlMap.computeIfAbsent("variablePdfList", v -> variablePdfList);
-//        htmlMap.computeIfAbsent("printCount", v -> printCount);
-//        htmlMap.computeIfAbsent("sequence", v -> 1);
-//        htmlMap.computeIfAbsent("examDetail", v -> examDetail);
-//        htmlMap.computeIfAbsent("printType", v -> ClassifyEnum.PACKAGE);
-//        freemarkerUtil.createPaperPackage(htmlMap);
-//    }
 
     /**
      * 生成卷袋贴
@@ -472,199 +339,6 @@ public class CreatePdfUtil {
         printCommonService.saveAttachmentPackagePdf(pdfPackageDto, examDetail, variablePdfList, printCount, fileTempList);
     }
 
-//    /**
-//     * 创建签到表
-//     *
-//     * @param basicAttachment
-//     * @param schoolName
-//     * @param examDetail
-//     * @param examStudentList
-//     * @param variablePdfList
-//     * @param printCount
-//     * @param examDetailCourseList
-//     */
-//    public void createSignBook(BasicAttachment basicAttachment, String schoolName, ExamDetail
-//            examDetail, List<ExamStudentCourseDto> examStudentList, List<PdfDto> variablePdfList, Integer
-//                                       printCount, List<ExamDetailCourse> examDetailCourseList) throws IOException {
-//        if (Objects.isNull(basicAttachment)) {
-//            throw ExceptionResultEnum.ATTACHMENT_IS_NULL.exception();
-//        }
-//        Map<String, Object> htmlMap = new HashMap<>();
-//        if (Objects.nonNull(examDetailCourseList) && examDetailCourseList.size() > 0) {
-//            List<String> paperNumbers = examDetailCourseList.stream().map(ExamDetailCourse::getPaperNumber).collect(Collectors.toList());
-//            List<String> courseNames = examDetailCourseList.stream().map(ExamDetailCourse::getCourseName).collect(Collectors.toList());
-//            htmlMap.put("courseName", String.join(", ", courseNames));
-//            htmlMap.put("courseCode", String.join(", ", paperNumbers));
-//        } else {
-//            htmlMap.put("courseName", "");
-//            htmlMap.put("courseCode", "");
-//        }
-//        htmlMap.put("schoolName", schoolName);
-//        htmlMap.put("examRoom", examDetail.getExamRoom());
-//
-//        List<String> extendColumnList = examStudentList.stream().map(ExamStudent::getExtendFields).distinct().collect(Collectors.toList());
-//        Set<String> classTeacher = new HashSet();
-//        if (extendColumnList.size() > 0) {
-//            for (String s : extendColumnList) {
-//                List<Map> mapList = JSONObject.parseArray(s, Map.class);
-//                for (Map map : mapList) {
-//                    if (Objects.equals("classTeacher", map.get("code").toString())) {
-//                        classTeacher.add(map.get("value").toString());
-//                    }
-//                }
-//            }
-//        }
-//        htmlMap.put("classTeacher", String.join(",", classTeacher));
-//        htmlMap.put("startTime", DateUtil.format(new Date(examDetail.getExamStartTime()), SystemConstant.DEFAULT_DATE_PATTERN));
-//        htmlMap.put("endTime", DateUtil.format(new Date(examDetail.getExamEndTime()), SystemConstant.DEFAULT_DATE_PATTERN));
-//        htmlMap.put("paperCode", examDetail.getPackageCode());
-//        htmlMap.put("paperCodeImg", GoogleBarCodeUtil.createBarCode(examDetail.getPackageCode(), false));
-//
-//        int pageSize = 60;
-//        int halfPageSize = pageSize / 2;
-//
-//        if (examStudentList.size() > 0) {
-//            int totalCount = examStudentList.size();
-//            List<Map> subList = new ArrayList<>();
-//            int pageCount = totalCount % pageSize == 0 ? totalCount / pageSize : totalCount / pageSize + 1;
-//            for (int i = 0; i < pageCount; i++) {
-//                Map subMap = new HashMap();
-//                subMap.put("index", i + 1);
-//                int studentCount;
-//                List<ExamStudentCourseDto> subStudents;
-//                if (pageCount == 1) {
-//                    studentCount = totalCount;
-//                    subStudents = examStudentList;
-//                } else if (i == pageCount - 1) {
-//                    studentCount = totalCount - (pageCount - 1) * pageSize;
-//                    subStudents = examStudentList.subList(pageSize * i, examStudentList.size());
-//                } else {
-//                    studentCount = pageSize;
-//                    subStudents = examStudentList.subList(pageSize * i, pageSize * (i + 1));
-//                }
-//                subMap.put("studentCount", totalCount);
-//                List<ExamStudentDto> examStudentList1 = new ArrayList<>();
-//                List<ExamStudentDto> examStudentList2 = new ArrayList<>();
-//
-//                Gson gson = new Gson();
-//                int mod = subStudents.size() % 2;
-//                int htmlTableCount = mod == 0 ? subStudents.size() / 2 : subStudents.size() / 2 + 1;
-//                for (int j = 0; j < htmlTableCount; j++) {
-//                    ExamStudentDto examStudentDto = gson.fromJson(gson.toJson(subStudents.get(j)), ExamStudentDto.class);
-//                    examStudentDto.setIndex(j + 1);
-//                    String clazzName = getClassName(examStudentDto);
-//                    examStudentDto.setClazzName(clazzName);
-//                    examStudentList1.add(examStudentDto);
-//                }
-//                for (int j = htmlTableCount; j < subStudents.size(); j++) {
-//                    ExamStudentDto examStudentDto = gson.fromJson(gson.toJson(subStudents.get(j)), ExamStudentDto.class);
-//                    examStudentDto.setIndex(j + 1);
-//                    String clazzName = getClassName(examStudentDto);
-//                    examStudentDto.setClazzName(clazzName);
-//                    examStudentList2.add(examStudentDto);
-//                }
-////                if (examStudentList1.size() > examStudentList2.size()) {
-////                    for (int j = subStudents.size() - htmlTableCount; j < examStudentList1.size(); j++) {
-////                        examStudentList2.add(new ExamStudentDto());
-////                    }
-////                }
-//                if (examStudentList1.size() < halfPageSize) {
-//                    int examStudentList1Size = examStudentList1.size();
-//                    for (int j = 0; j < halfPageSize - examStudentList1Size; j++) {
-//                        ExamStudentDto examStudentDto = new ExamStudentDto();
-//                        examStudentDto.setIndex(null);
-//                        examStudentDto.setSiteNumber("");
-//                        examStudentDto.setStudentName("");
-//                        examStudentDto.setClazzName("");
-//                        examStudentList1.add(examStudentDto);
-//                    }
-//                }
-//                if (examStudentList2.size() < halfPageSize) {
-//                    int examStudentList2Size = examStudentList2.size();
-//                    for (int j = 0; j < halfPageSize - examStudentList2Size; j++) {
-//                        ExamStudentDto examStudentDto = new ExamStudentDto();
-//                        examStudentDto.setIndex(null);
-//                        examStudentDto.setSiteNumber("");
-//                        examStudentDto.setStudentName("");
-//                        examStudentDto.setClazzName("");
-//                        examStudentList2.add(examStudentDto);
-//                    }
-//                }
-//                subMap.put("studentList1", examStudentList1);
-//                subMap.put("studentList2", examStudentList2);
-//                subList.add(subMap);
-//            }
-//            htmlMap.put("subList", subList);
-//        } else {
-//            int totalCount = examDetail.getPrintCount();
-//            List<Map> subList = new ArrayList<>();
-//            int pageCount = totalCount % pageSize == 0 ? totalCount / pageSize : totalCount / pageSize + 1;
-//            for (int i = 0; i < pageCount; i++) {
-//                Map subMap = new HashMap();
-//                subMap.put("index", i + 1);
-//                int studentCount;
-//                if (pageCount == 1) {
-//                    studentCount = pageSize;
-//                } else if (i == pageCount - 1) {
-//                    studentCount = totalCount - (pageCount - 1) * pageSize;
-//                } else {
-//                    studentCount = pageSize;
-//                }
-//                subMap.put("studentCount", totalCount);
-//                List<ExamStudentDto> examStudentList1 = new ArrayList<>();
-//                List<ExamStudentDto> examStudentList2 = new ArrayList<>();
-//
-//                int mod = studentCount % 2;
-//                int htmlTableCount = mod == 0 ? studentCount / 2 : studentCount / 2 + 1;
-//                for (int j = 0; j < htmlTableCount; j++) {
-//                    ExamStudentDto examStudentDto = new ExamStudentDto();
-//                    examStudentDto.setIndex(null);
-//                    examStudentDto.setStudentName("");
-//                    examStudentDto.setClazzName("");
-//                    examStudentList1.add(examStudentDto);
-//                }
-//                for (int j = htmlTableCount; j < studentCount; j++) {
-//                    ExamStudentDto examStudentDto = new ExamStudentDto();
-//                    examStudentDto.setIndex(null);
-//                    examStudentDto.setStudentName("");
-//                    examStudentDto.setClazzName("");
-//                    examStudentList2.add(examStudentDto);
-//                }
-//                if (examStudentList1.size() < halfPageSize) {
-//                    for (int j = 0; j < halfPageSize - examStudentList1.size(); j++) {
-//                        ExamStudentDto examStudentDto = new ExamStudentDto();
-//                        examStudentDto.setIndex(null);
-//                        examStudentDto.setSiteNumber("");
-//                        examStudentDto.setStudentName("");
-//                        examStudentDto.setClazzName("");
-//                        examStudentList1.add(examStudentDto);
-//                    }
-//                }
-//                if (examStudentList2.size() < halfPageSize) {
-//                    for (int j = 0; j < halfPageSize - examStudentList2.size(); j++) {
-//                        ExamStudentDto examStudentDto = new ExamStudentDto();
-//                        examStudentDto.setIndex(null);
-//                        examStudentDto.setSiteNumber("");
-//                        examStudentDto.setStudentName("");
-//                        examStudentDto.setClazzName("");
-//                        examStudentList2.add(examStudentDto);
-//                    }
-//                }
-//                subMap.put("studentList1", examStudentList1);
-//                subMap.put("studentList2", examStudentList2);
-//                subList.add(subMap);
-//            }
-//            htmlMap.put("subList", subList);
-//        }
-//        htmlMap.computeIfAbsent("basicAttachment", v -> basicAttachment);
-//        htmlMap.computeIfAbsent("variablePdfList", v -> variablePdfList);
-//        htmlMap.computeIfAbsent("printCount", v -> printCount);
-//        htmlMap.computeIfAbsent("sequence", v -> 2);
-//        htmlMap.computeIfAbsent("examDetail", v -> examDetail);
-//        htmlMap.computeIfAbsent("printType", v -> ClassifyEnum.SIGN);
-//        freemarkerUtil.createSignBook(htmlMap);
-//    }
-
     /**
      * 创建签到表
      *

+ 50 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/util/PdfUtil.java

@@ -16,6 +16,7 @@ import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
 import com.qmth.teachcloud.common.enums.PageSizeEnum;
 import com.qmth.teachcloud.common.enums.UploadFileEnum;
 import com.qmth.teachcloud.common.service.CommonCacheService;
+import com.qmth.teachcloud.common.util.FileUtil;
 import org.apache.commons.io.IOUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -84,6 +85,55 @@ public class PdfUtil {
         return Objects.nonNull(dirName) ? dirName.toString() : null;
     }
 
+    /**
+     * 将多个PDF合并成一个PDF
+     *
+     * @param files
+     * @param outputPath
+     */
+    public static String mergePdf(String[] files, String outputPath) {
+        Document document = null;
+        PdfCopy copy = null;
+        StringJoiner dirName = new StringJoiner("");
+        File pdfFileTemp = null;
+        try {
+            if (Objects.nonNull(files) && files.length > 0) {
+                document = new Document(new PdfReader(ByteArray.fromFile(new File(files[0])).value()).getPageSize(1));
+                if (Objects.isNull(outputPath)) {
+                    pdfFileTemp = SystemConstant.getFileTempVar(SystemConstant.PDF_PREFIX);
+                    dirName.add(pdfFileTemp.getPath());
+                    outputPath = dirName.toString();
+                }
+                copy = new PdfSmartCopy(document, new FileOutputStream(outputPath));
+                document.open();
+                for (int i = 0; i < files.length; i++) {
+                    PdfReader reader = new PdfReader(ByteArray.fromFile(new File(files[i])).value());
+                    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) {
+            log.error(SystemConstant.LOG_ERROR, e);
+        } finally {
+            if (Objects.nonNull(document)) {
+                document.close();
+            }
+            if (Objects.nonNull(copy)) {
+                copy.flush();
+                copy.close();
+            }
+//            if(Objects.nonNull(pdfFileTemp)){
+//                FileUtil.deleteFile(pdfFileTemp);
+//            }
+        }
+        return Objects.nonNull(dirName) ? dirName.toString() : null;
+    }
+
     /**
      * 新增pdf page
      *

+ 1039 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/util/pdf/CreatePdfNewUtil.java

@@ -0,0 +1,1039 @@
+package com.qmth.distributed.print.business.util.pdf;
+
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.ReflectUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.qmth.distributed.print.business.bean.createPdf.PrintPathVo;
+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.ExamNumberStyleEnum;
+import com.qmth.distributed.print.business.enums.PrintPlanStatusEnum;
+import com.qmth.distributed.print.business.enums.StudentClazzEnum;
+import com.qmth.distributed.print.business.service.*;
+import com.qmth.distributed.print.business.util.GoogleBarCodeUtil;
+import com.qmth.distributed.print.business.util.PdfUtil;
+import com.qmth.teachcloud.common.bean.vo.FilePathVo;
+import com.qmth.teachcloud.common.bean.vo.OriginalVo;
+import com.qmth.teachcloud.common.bean.vo.PaperInfoVo;
+import com.qmth.teachcloud.common.contant.SystemConstant;
+import com.qmth.teachcloud.common.entity.BasicAttachment;
+import com.qmth.teachcloud.common.entity.BasicPrintConfig;
+import com.qmth.teachcloud.common.entity.BasicSemester;
+import com.qmth.teachcloud.common.enums.*;
+import com.qmth.teachcloud.common.service.BasicAttachmentService;
+import com.qmth.teachcloud.common.service.BasicSemesterService;
+import com.qmth.teachcloud.common.service.FileUploadService;
+import com.qmth.teachcloud.common.service.TeachcloudCommonService;
+import com.qmth.teachcloud.common.util.*;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+import java.io.File;
+import java.io.IOException;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * @Description: 创建pdf util
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2021/4/14
+ */
+@Component
+public class CreatePdfNewUtil {
+    private final static Logger log = LoggerFactory.getLogger(CreatePdfNewUtil.class);
+
+    @Resource
+    private BasicAttachmentService basicAttachmentService;
+    @Resource
+    @Lazy
+    private PrintCommonService printCommonService;
+    @Resource
+    private TeachcloudCommonService teachcloudCommonService;
+    @Resource
+    private ExamDetailService examDetailService;
+    @Resource
+    private ExamStudentService examStudentService;
+    @Resource
+    private BasicTemplateService basicTemplateService;
+    @Resource
+    private BasicSemesterService basicSemesterService;
+    @Resource
+    private ExamTaskService examTaskService;
+    @Resource
+    private ExamTaskDetailService examTaskDetailService;
+    @Resource
+    private ExamPrintPlanService examPrintPlanService;
+    @Resource
+    private BasicPrintConfigService basicPrintConfigService;
+    @Resource
+    private FileUploadService fileUploadService;
+
+    /**
+     * 创建登记表
+     * @param examDetail
+     * @param basicAttachment
+     * @param printCount
+     * @throws Exception
+     */
+    public void createCheckIn(ExamDetail examDetail, BasicAttachment basicAttachment,Integer printCount) throws Exception {
+        Optional.ofNullable(basicAttachment).orElseThrow(() -> ExceptionResultEnum.ATTACHMENT_IS_NULL.exception());
+
+        String type = basicAttachment.getType();
+        FilePathVo filePathVo = JSON.parseObject(basicAttachment.getPath(), FilePathVo.class);
+
+        if (Objects.nonNull(type) && Objects.equals(type, SystemConstant.PDF_PREFIX)) {
+            String filePath = filePathVo.getPath();
+            PrintPathVo printPathVo = new PrintPathVo(ClassifyEnum.CHECK_IN, filePathVo.getUploadType(), filePathVo.getType(), filePath, basicAttachment.getMd5(), null, null);
+            examDetail.setAttachmentPath(printCommonService.parseAttachmentPath(examDetail.getAttachmentPath(), printPathVo));
+
+//            for (int i = 0; i < printCount; i++) {
+//                ordinaryPdfList.add(new PdfDto(filePath, PageSizeEnum.A4, 0));
+//            }
+        } else {
+            File htmlFileTemp = SystemConstant.getFileTempVar(SystemConstant.HTML_PREFIX);
+            File file = fileUploadService.downloadFile(basicAttachment.getId(), htmlFileTemp.getPath());
+            BasicAttachment attachment = printCommonService.saveAttachmentPdfFromHtml(String.valueOf(basicAttachment.getId()), file, examDetail.getCreateId(), null);
+            FilePathVo filePathVo1 = JSON.parseObject(attachment.getPath(), FilePathVo.class);
+            PrintPathVo printPathVo = new PrintPathVo(ClassifyEnum.CHECK_IN, filePathVo1.getUploadType(), filePathVo1.getType(), filePathVo1.getPath(), attachment.getMd5(), null, null);
+            examDetail.setAttachmentPath(printCommonService.parseAttachmentPath(examDetail.getAttachmentPath(), printPathVo));
+        }
+    }
+
+
+    /**
+     * 生成卷袋贴
+     * @param templateId
+     * @param schoolName
+     * @param examDetail
+     * @param examStudentList
+     * @param backupCount
+     * @param printCount
+     * @param examDetailCourseList
+     * @param examId
+     */
+    public void createPaperPackage(Long templateId, String schoolName, ExamDetail examDetail, List<ExamStudentCourseDto> examStudentList, Integer backupCount, Integer printCount, List<ExamDetailCourse> examDetailCourseList, Long examId) {
+        BasicTemplate basicTemplate = basicTemplateService.getById(templateId);
+        if (Objects.isNull(basicTemplate)) {
+            throw ExceptionResultEnum.ERROR.exception("印品数据有误");
+        }
+
+        JSONObject object = JSON.parseObject(basicTemplate.getDisplayRange());
+
+        PdfPackageDto pdfPackageDto = new PdfPackageDto();
+        pdfPackageDto.setTitle(schoolName);
+        pdfPackageDto.setPackageNumber(examDetail.getPackageCode());
+
+        boolean isTag = false;
+        for (ExamDetailCourse detailCourse : examDetailCourseList) {
+            ExamTask examTask = examTaskService.getByCourseCodeAndPaperNumber(examDetail.getSchoolId(), examId, detailCourse.getCourseCode(), detailCourse.getPaperNumber());
+            ExamTaskDetail examTaskDetail = examTaskDetailService.getByExamTaskId(examTask.getId());
+            List<PaperInfoVo> paperInfoVoList = ExamTaskUtil.parsePaperAttachmentPath(examTaskDetail.getPaperAttachmentIds());
+            for (PaperInfoVo paperInfoVo : paperInfoVoList) {
+                int pages = paperInfoVo.getPages();
+                isTag = pages > 2;
+                pdfPackageDto.setTag(isTag);
+                if (isTag) {
+                    break;
+                }
+            }
+        }
+
+        // 标题信息
+        List<JSONObject> objectTitleList = JSON.parseArray(object.getString("title"), JSONObject.class).stream().filter(m -> m.getBoolean("enable")).collect(Collectors.toList());
+        List<Map<String, String>> titlePlate = new ArrayList<>();
+        for (JSONObject jsonObject : objectTitleList) {
+            Map<String, String> titleMap = new HashMap<>();
+            String code = jsonObject.getString("code");
+            String name = jsonObject.getString("name");
+            titleMap.put("code", code);
+            titleMap.put("name", name);
+            if ("semesterName".equals(code)) {
+                BasicSemester basicSemester = basicSemesterService.selectByExamId(examId);
+                titleMap.put("value", basicSemester == null ? null : basicSemester.getName() + "  课程考试");
+            }
+            titlePlate.add(titleMap);
+        }
+        pdfPackageDto.setTitlePlate(titlePlate);
+
+        List<JSONObject> objectList = JSON.parseArray(object.getString("basic"), JSONObject.class).stream().filter(m -> m.getBoolean("enable")).collect(Collectors.toList());
+
+        boolean isCourseHasTwo = objectList.stream().filter(m -> "courseCode".equals(m.getString("code")) || "courseName".equals(m.getString("code"))).count() == 2;
+        boolean isDateHasTwo = objectList.stream().filter(m -> "examDate".equals(m.getString("code")) || "examTime".equals(m.getString("code"))).count() == 2;
+        boolean isCourseFill = false;
+        boolean isDateFill = false;
+        // 基础信息
+        List<Map<String, String>> basicPlate = new ArrayList<>();
+        for (JSONObject jsonObject : objectList) {
+            String code = jsonObject.getString("code");
+            String name = jsonObject.getString("name");
+            if ("examDate".equals(code) || "examTime".equals(code)) {
+                String startDate = DateUtil.format(new Date(examDetail.getExamStartTime()), SystemConstant.DATE_PATTERN);
+                String endDate = DateUtil.format(new Date(examDetail.getExamEndTime()), SystemConstant.DATE_PATTERN);
+                String startTime = DateUtil.format(new Date(examDetail.getExamStartTime()), SystemConstant.TIME_PATTERN);
+                String endTime = DateUtil.format(new Date(examDetail.getExamEndTime()), SystemConstant.TIME_PATTERN);
+                Map<String, String> basicMap = new HashMap<>();
+                if (isDateHasTwo) {
+                    if (isDateFill) {
+                        continue;
+                    }
+                    String examTime;
+                    if (startDate.equals(endDate)) {
+                        examTime = startDate + " " + startTime + SystemConstant.HYPHEN + endTime;
+                    } else {
+                        examTime = startDate + " " + startTime + SystemConstant.HYPHEN + endDate + " " + endTime;
+                    }
+                    basicMap.put("code", "examTime");
+                    basicMap.put("name", "考试时间");
+                    basicMap.put("value", examTime);
+                    isDateFill = true;
+                } else {
+                    String examTime = "";
+                    if ("examDate".equals(code)) {
+                        if (startDate.equals(endDate)) {
+                            examTime = startDate;
+                        } else {
+                            examTime = startDate + SystemConstant.HYPHEN + endDate;
+                        }
+                    } else if ("examTime".equals(code)) {
+                        if (startDate.equals(endDate)) {
+                            examTime = startDate + " " + startTime + SystemConstant.HYPHEN + endTime;
+                        } else {
+                            examTime = startDate + " " + startTime + SystemConstant.HYPHEN + endDate + " " + endTime;
+                        }
+                    }
+                    basicMap.put("code", code);
+                    basicMap.put("name", name);
+                    basicMap.put("value", examTime);
+                }
+                basicPlate.add(basicMap);
+            } else if ("courseCode".equals(code) || "courseName".equals(code)) {
+                Map<String, String> basicMap = new HashMap<>();
+                if (isCourseHasTwo) {
+                    if (isCourseFill) {
+                        continue;
+                    }
+                    List<String> courseNames = examDetailCourseList.stream().map(m -> String.format("%s(%s)", m.getCourseName(), m.getCourseCode())).collect(Collectors.toList());
+                    basicMap.put("code", "courseName");
+                    basicMap.put("name", "课程名称");
+                    basicMap.put("value", String.join(SystemConstant.COMMA_OF_CHINESE, courseNames));
+                    isCourseFill = true;
+                } else {
+                    List<String> courseNames = examDetailCourseList.stream().map(m -> "courseCode".equals(code) ? m.getCourseCode() : "courseName".equals(code) ? m.getCourseName() : "").collect(Collectors.toList());
+                    basicMap.put("code", code);
+                    basicMap.put("name", name);
+                    basicMap.put("value", String.join(SystemConstant.COMMA_OF_CHINESE, courseNames));
+                }
+                basicPlate.add(basicMap);
+            } else if ("paperNumber".equals(code)) {
+                List<String> paperNumbers = examDetailCourseList.stream().map(ExamDetailCourse::getPaperNumber).collect(Collectors.toList());
+                Map<String, String> basicMap = new HashMap<>();
+                basicMap.put("code", code);
+                basicMap.put("name", name);
+                basicMap.put("value", String.join(SystemConstant.COMMA_OF_CHINESE, paperNumbers));
+                basicPlate.add(basicMap);
+            } else if ("examPlace".equals(code) || "campusName".equals(code)) {
+                Map<String, String> basicMap = new HashMap<>();
+                basicMap.put("code", code);
+                basicMap.put("name", name);
+                basicMap.put("value", examDetail.getExamPlace());
+                basicPlate.add(basicMap);
+            } else if ("examRoom".equals(code) || "examClassroomName".equals(code)) {
+                Map<String, String> basicMap = new HashMap<>();
+                basicMap.put("code", code);
+                basicMap.put("name", name);
+                basicMap.put("value", examDetail.getExamRoom());
+                basicPlate.add(basicMap);
+            } else if ("collegeName".equals(code)) {
+                Set<String> collegeNames = examStudentList.stream().map(ExamStudent::getCollegeName).collect(Collectors.toSet());
+                Map<String, String> basicMap = new HashMap<>();
+                basicMap.put("code", code);
+                basicMap.put("name", name);
+                basicMap.put("value", String.join(SystemConstant.COMMA_OF_CHINESE, collegeNames));
+                basicPlate.add(basicMap);
+            } else if ("majorName".equals(code)) {
+                Set<String> stringSet = new HashSet<>();
+                Set<String> majorNames = examStudentList.stream().filter(m -> StringUtils.isNotBlank(m.getMajorName())).map(ExamStudent::getMajorName).collect(Collectors.toSet());
+                if (!majorNames.isEmpty()) {
+                    stringSet.addAll(majorNames);
+                }
+                Map<String, String> basicMap = new HashMap<>();
+                basicMap.put("code", code);
+                basicMap.put("name", name);
+                basicMap.put("value", String.join(SystemConstant.COMMA_OF_CHINESE, stringSet));
+                basicPlate.add(basicMap);
+            } else if ("clazzName".equals(code)) {
+                Set<String> stringSet = new HashSet<>();
+                Set<String> clazzNames = examStudentList.stream().filter(m -> m.getStudentClazzType().equals(StudentClazzEnum.BASIC_CLAZZ) && StringUtils.isNotBlank(m.getClazzName())).map(ExamStudent::getClazzName).collect(Collectors.toSet());
+                if (!clazzNames.isEmpty()) {
+                    stringSet.addAll(clazzNames);
+                }
+                Set<String> teachClazzNames = examStudentList.stream().filter(m -> m.getStudentClazzType().equals(StudentClazzEnum.TEACH_CLAZZ) && StringUtils.isNotBlank(m.getTeachClazzName())).map(ExamStudent::getTeachClazzName).collect(Collectors.toSet());
+                if (!teachClazzNames.isEmpty()) {
+                    stringSet.addAll(teachClazzNames);
+                }
+                Map<String, String> basicMap = new HashMap<>();
+                basicMap.put("code", code);
+                basicMap.put("name", name);
+                basicMap.put("value", String.join(SystemConstant.COMMA_OF_CHINESE, stringSet));
+                basicPlate.add(basicMap);
+            } else {
+                // 扩展字段走本校验,进行数据组装
+                Set<String> extendFieldsSet = examStudentList.stream().map(ExamStudentCourseDto::getExtendFields).collect(Collectors.toSet());
+                Set<String> finalSet = new HashSet<>();
+                for (String extendField : extendFieldsSet) {
+                    List<JSONObject> jsonObjects = JSON.parseArray(extendField, JSONObject.class);
+                    Set<String> values = jsonObjects.stream().filter(m -> code.equals(m.getString("code"))).map(m -> m.getString("value")).collect(Collectors.toSet());
+                    finalSet.addAll(values);
+                }
+                Map<String, String> basicMap = new HashMap<>();
+                basicMap.put("code", code);
+                basicMap.put("name", name);
+                basicMap.put("value", String.join(SystemConstant.COMMA_OF_CHINESE, finalSet));
+                basicPlate.add(basicMap);
+            }
+        }
+        Map<String, String> basicMap1 = new HashMap<>();
+        basicMap1.put("code", "paperCount");
+        basicMap1.put("name", "试卷数量");
+        basicMap1.put("value", examStudentList.size() + " + " + backupCount);
+        basicPlate.add(basicMap1);
+
+        Map<String, String> basicMap2 = new HashMap<>();
+        basicMap2.put("code", "examCount");
+        basicMap2.put("name", "应考人数");
+        basicMap2.put("value", String.valueOf(examStudentList.size()));
+        basicPlate.add(basicMap2);
+
+        Map<String, String> basicMap3 = new HashMap<>();
+        basicMap3.put("code", "actualExamCount");
+        basicMap3.put("name", "实考人数");
+        basicMap3.put("value", "");
+        basicPlate.add(basicMap3);
+
+        pdfPackageDto.setBasicPlate(basicPlate);
+        printCommonService.saveAttachmentPackagePdf(pdfPackageDto, examDetail, printCount);
+    }
+
+    /**
+     * 创建签到表
+     *
+     * @param templateId
+     * @param schoolName
+     * @param examDetail
+     * @param examStudentList
+     * @param printCount
+     * @param examDetailCourseList
+     */
+    public void createSignBook(Long templateId, String schoolName, ExamDetail examDetail, List<ExamStudentCourseDto> examStudentList, Integer printCount, List<ExamDetailCourse> examDetailCourseList) {
+        BasicTemplate basicTemplate = basicTemplateService.getById(templateId);
+        if (Objects.isNull(basicTemplate)) {
+            throw ExceptionResultEnum.ERROR.exception("印品数据有误");
+        }
+        PdfSignDto pdfFillDto = new PdfSignDto();
+        pdfFillDto.setTitle(schoolName + "签到表");
+        pdfFillDto.setPackageNumber(examDetail.getPackageCode());
+        pdfFillDto.setTextDesc(basicTemplate.getTextDesc());
+
+        JSONObject jsonObject = JSON.parseObject(basicTemplate.getDisplayRange());
+        List<JSONObject> objectList = JSON.parseArray(jsonObject.getString("basic"), JSONObject.class).stream().filter(m -> m.getBoolean("enable")).collect(Collectors.toList());
+
+        boolean isCourseHasTwo = objectList.stream().filter(m -> "courseCode".equals(m.getString("code")) || "courseName".equals(m.getString("code"))).count() == 2;
+        boolean isDateHasTwo = objectList.stream().filter(m -> "examDate".equals(m.getString("code")) || "examTime".equals(m.getString("code"))).count() == 2;
+        boolean isPlaceHasTwo = objectList.stream().filter(m -> "examPlace".equals(m.getString("code")) || "examRoom".equals(m.getString("code"))).count() == 2;
+
+        // 基础信息
+        List<Map<String, String>> basicPlate = new ArrayList<>();
+        boolean isCourseFill = false;
+        boolean isDateFill = false;
+        boolean isPlaceFill = false;
+        for (JSONObject object : objectList) {
+            String code = object.getString("code");
+            String name = object.getString("name");
+            if ("courseCode".equals(code) || "courseName".equals(code)) {
+                Map<String, String> basicMap = new HashMap<>();
+                if (isCourseHasTwo) {
+                    if (isCourseFill) {
+                        continue;
+                    }
+                    List<String> courseNames = examDetailCourseList.stream().map(m -> String.format("%s(%s)", m.getCourseName(), m.getCourseCode())).collect(Collectors.toList());
+                    basicMap.put("code", "courseName");
+                    basicMap.put("name", "课程名称");
+                    basicMap.put("value", String.join(SystemConstant.COMMA_OF_CHINESE, courseNames));
+                    isCourseFill = true;
+                } else {
+                    List<String> courseNames = examDetailCourseList.stream().map(m -> "courseCode".equals(code) ? m.getCourseCode() : "courseName".equals(code) ? m.getCourseName() : "").collect(Collectors.toList());
+                    basicMap.put("code", code);
+                    basicMap.put("name", name);
+                    basicMap.put("value", String.join(SystemConstant.COMMA_OF_CHINESE, courseNames));
+                }
+                basicPlate.add(basicMap);
+            } else if ("paperNumber".equals(code)) {
+                List<String> paperNumbers = examDetailCourseList.stream().map(ExamDetailCourse::getPaperNumber).collect(Collectors.toList());
+                Map<String, String> basicMap = new HashMap<>();
+                basicMap.put("code", code);
+                basicMap.put("name", name);
+                basicMap.put("value", String.join(SystemConstant.COMMA_OF_CHINESE, paperNumbers));
+                basicPlate.add(basicMap);
+            } else if ("examDate".equals(code) || "examTime".equals(code)) {
+                String startDate = DateUtil.format(new Date(examDetail.getExamStartTime()), SystemConstant.DATE_PATTERN);
+                String endDate = DateUtil.format(new Date(examDetail.getExamEndTime()), SystemConstant.DATE_PATTERN);
+                String startTime = DateUtil.format(new Date(examDetail.getExamStartTime()), SystemConstant.TIME_PATTERN);
+                String endTime = DateUtil.format(new Date(examDetail.getExamEndTime()), SystemConstant.TIME_PATTERN);
+
+                Map<String, String> basicMap = new HashMap<>();
+                if (isDateHasTwo) {
+                    if (isDateFill) {
+                        continue;
+                    }
+                    String examTime;
+                    if (startDate.equals(endDate)) {
+                        examTime = startDate + " " + startTime + SystemConstant.HYPHEN + endTime;
+                    } else {
+                        examTime = startDate + " " + startTime + SystemConstant.HYPHEN + endDate + " " + endTime;
+                    }
+                    basicMap.put("code", "examTime");
+                    basicMap.put("name", "考试时间");
+                    basicMap.put("value", examTime);
+                    isDateFill = true;
+                } else {
+                    String examTime = "";
+                    if ("examDate".equals(code)) {
+                        if (startDate.equals(endDate)) {
+                            examTime = startDate;
+                        } else {
+                            examTime = startDate + SystemConstant.HYPHEN + endDate;
+                        }
+                    } else if ("examTime".equals(code)) {
+                        if (startDate.equals(endDate)) {
+                            examTime = startDate + " " + startTime + SystemConstant.HYPHEN + endTime;
+                        } else {
+                            examTime = startDate + " " + startTime + SystemConstant.HYPHEN + endDate + " " + endTime;
+                        }
+                    }
+                    basicMap.put("code", code);
+                    basicMap.put("name", name);
+                    basicMap.put("value", examTime);
+                }
+                basicPlate.add(basicMap);
+            } else if ("examPlace".equals(code) || "examRoom".equals(code)) {
+                Map<String, String> basicMap = new HashMap<>();
+                if (isPlaceHasTwo) {
+                    if (isPlaceFill) {
+                        continue;
+                    }
+                    StringJoiner stringJoiner = new StringJoiner("");
+                    if (StringUtils.isNotBlank(examDetail.getExamPlace())) {
+                        stringJoiner.add(examDetail.getExamPlace());
+                    }
+                    if (StringUtils.isNotBlank(examDetail.getExamRoom())) {
+                        stringJoiner.add(examDetail.getExamRoom());
+                    }
+                    basicMap.put("code", "examRoom");
+                    basicMap.put("name", "考试地点");
+                    basicMap.put("value", stringJoiner.toString());
+                    isPlaceFill = true;
+                } else {
+                    StringJoiner stringJoiner = new StringJoiner("");
+                    if ("examPlace".equals(code) && StringUtils.isNotBlank(examDetail.getExamPlace())) {
+                        stringJoiner.add(examDetail.getExamPlace());
+                    }
+                    if ("examRoom".equals(code) && StringUtils.isNotBlank(examDetail.getExamRoom())) {
+                        stringJoiner.add(examDetail.getExamRoom());
+                    }
+                    basicMap.put("code", code);
+                    basicMap.put("name", name);
+                    basicMap.put("value", stringJoiner.toString());
+                }
+                basicPlate.add(basicMap);
+            } else if ("collegeName".equals(code)) {
+                Set<String> collegeNames = examStudentList.stream().map(ExamStudentCourseDto::getCollegeName).collect(Collectors.toSet());
+                Map<String, String> basicMap = new HashMap<>();
+                basicMap.put("code", code);
+                basicMap.put("name", name);
+                basicMap.put("value", String.join(SystemConstant.COMMA_OF_CHINESE, collegeNames));
+                basicPlate.add(basicMap);
+            } else if ("majorName".equals(code)) {
+                Set<String> majorNames = examStudentList.stream().map(ExamStudentCourseDto::getMajorName).collect(Collectors.toSet());
+                Map<String, String> basicMap = new HashMap<>();
+                basicMap.put("code", code);
+                basicMap.put("name", name);
+                basicMap.put("value", String.join(SystemConstant.COMMA_OF_CHINESE, majorNames));
+                basicPlate.add(basicMap);
+            } else if ("examCount".equals(code)) {
+                Map<String, String> basicMap = new HashMap<>();
+                basicMap.put("code", code);
+                basicMap.put("name", name);
+                basicMap.put("value", String.valueOf(examStudentList.size()));
+                basicPlate.add(basicMap);
+            } else if ("actualExamCount".equals(code)) {
+                Map<String, String> basicMap = new HashMap<>();
+                basicMap.put("code", code);
+                basicMap.put("name", name);
+                basicMap.put("value", "");
+                basicPlate.add(basicMap);
+            } else {
+                // 扩展字段走本校验,进行数据组装
+                Set<String> extendFieldsSet = examStudentList.stream().map(ExamStudentCourseDto::getExtendFields).collect(Collectors.toSet());
+                Set<String> finalSet = new HashSet<>();
+                for (String extendField : extendFieldsSet) {
+                    List<JSONObject> jsonObjects = JSON.parseArray(extendField, JSONObject.class);
+                    Set<String> values = jsonObjects.stream().filter(m -> code.equals(m.getString("code"))).map(m -> m.getString("value")).collect(Collectors.toSet());
+                    finalSet.addAll(values);
+                }
+                Map<String, String> basicMap = new HashMap<>();
+                basicMap.put("code", code);
+                basicMap.put("name", name);
+                basicMap.put("value", String.join(SystemConstant.COMMA_OF_CHINESE, finalSet));
+                basicPlate.add(basicMap);
+            }
+        }
+        pdfFillDto.setBasicPlate(basicPlate);
+
+        // 表头信息
+        List<JSONObject> tableList = JSON.parseArray(jsonObject.getString("table"), JSONObject.class).stream().filter(m -> m.getBoolean("enable")).collect(Collectors.toList());
+        Map<String, String> studentHeadPlateMap = new LinkedHashMap<>();
+        for (JSONObject object : tableList) {
+            studentHeadPlateMap.put(object.getString("code"), object.getString("name"));
+        }
+        studentHeadPlateMap.put("studentSign", "签名");
+        pdfFillDto.setStudentHeadPlate(studentHeadPlateMap);
+
+        // 考生信息
+        List<Map<String, String>> studentPlate = new ArrayList<>();
+        for (ExamStudentCourseDto examStudentCourseDto : examStudentList) {
+            Map<String, String> studentMap = new LinkedHashMap<>();
+            if (studentHeadPlateMap.containsKey("siteNumber")) {
+                studentMap.put("siteNumber", examStudentCourseDto.getSiteNumber());
+            }
+            if (studentHeadPlateMap.containsKey("studentName")) {
+                studentMap.put("studentName", examStudentCourseDto.getStudentName());
+            }
+            if (studentHeadPlateMap.containsKey("studentCode")) {
+                studentMap.put("studentCode", examStudentCourseDto.getStudentCode());
+            }
+            if (studentHeadPlateMap.containsKey("courseName")) {
+                studentMap.put("courseName", examStudentCourseDto.getCourseName());
+            }
+            if (studentHeadPlateMap.containsKey("clazzName")) {
+                studentMap.put("clazzName", StringUtils.isBlank(examStudentCourseDto.getTeachClazzName()) ? examStudentCourseDto.getClazzName() : examStudentCourseDto.getTeachClazzName());
+            }
+            if (studentHeadPlateMap.containsKey("ticketNumber")) {
+                studentMap.put("ticketNumber", examStudentCourseDto.getTicketNumber());
+            }
+            if (studentHeadPlateMap.containsKey("studentSign")) {
+                studentMap.put("studentSign", "");
+            }
+            studentPlate.add(studentMap);
+        }
+        pdfFillDto.setStudentPlate(studentPlate);
+
+        printCommonService.saveAttachmentSignPdf(pdfFillDto, examDetail, printCount, basicTemplate);
+    }
+
+    /**
+     * 替换html通用模版中的条码信息
+     *
+     * @param content 题卡详细内容
+     */
+    public String resetHtmlTemplateBar(String content) {
+        content = content.replaceAll("<img src=\"data:image/png;base64,\\$\\{examNumber\\}\">", "");
+        content = content.replaceAll("\\$\\{examNumberStr\\}", "");
+        return content;
+    }
+
+    /**
+     * 替换自定义题卡参数
+     *
+     * @param examCard
+     * @return
+     * @throws IOException
+     */
+    public String replaceHtmlCard(ExamCard examCard, BasicCardRule basicCardRule) throws IOException {
+        //通用题卡
+        String cardTemp = examCard.getHtmlContent();
+        cardTemp = cardTemp.replaceAll("\\$\\{paperTypeName\\}", "");
+        //随机生成试卷条码并将图片转成base64
+        cardTemp = cardTemp.replaceAll("\\$\\{paperType\\}", "");
+        cardTemp = cardTemp.replaceAll("<img src=\"data:image/png;base64,\\$\\{examNumber\\}\">", "");
+        cardTemp = cardTemp.replaceAll("\\$\\{examNumberStr\\}", "");
+        if (Objects.nonNull(basicCardRule) && Objects.nonNull(basicCardRule.getExtendFields())) {
+            JSONArray jsonObjectExtend = (JSONArray) JSONArray.parse(basicCardRule.getExtendFields());//扩展字段
+            if (Objects.nonNull(jsonObjectExtend)) {
+                for (int i = 0; i < jsonObjectExtend.size(); i++) {
+                    JSONObject object = (JSONObject) jsonObjectExtend.get(i);
+                    cardTemp = cardTemp.replaceAll("\\$\\{" + object.get("code") + "\\}", "");
+                }
+            }
+        }
+        cardTemp = cardTemp.replaceAll("\\$\\{examDate\\}", "");
+        cardTemp = cardTemp.replaceAll("\\$\\{examTime\\}", "");
+        cardTemp = cardTemp.replaceAll("\\$\\{ticketNumber\\}", "");
+        cardTemp = cardTemp.replaceAll("\\$\\{siteNumber\\}", "");
+        cardTemp = cardTemp.replaceAll("\\$\\{paperTypeName\\}", "");
+        cardTemp = cardTemp.replaceAll("\\$\\{studentCode\\}", "");
+        cardTemp = cardTemp.replaceAll("\\$\\{studentName\\}", "");
+        cardTemp = cardTemp.replaceAll("\\$\\{courseName\\}", "");
+        cardTemp = cardTemp.replaceAll("\\$\\{courseCode\\}", "");
+        cardTemp = cardTemp.replaceAll("\\$\\{examPlace\\}", "");
+        cardTemp = cardTemp.replaceAll("\\$\\{examRoom\\}", "");
+        cardTemp = cardTemp.replaceAll("\\$\\{paperNumber\\}", "");
+
+        // 根据题卡规则必选字段,替换相应值,没有则“”
+        List<StudentExtendDto> studentExtendDtos = createExtendObjectNull(basicCardRule);
+        if (studentExtendDtos != null) {
+            for (StudentExtendDto extendDto : studentExtendDtos) {
+                cardTemp = cardTemp.replaceAll("\\$\\{" + extendDto.getFieldName() + "\\}", String.valueOf(extendDto.getValue()));
+            }
+        }
+
+        return cardTemp;
+    }
+
+    /**
+     * 获取题卡attachmentId
+     *
+     * @param examCard
+     * @param attachmentIds
+     */
+    public void getCardAttachmentId(ExamCard examCard, Set<Long> attachmentIds) {
+        if (Objects.nonNull(examCard.getBackupAttachment()) && !Objects.equals("", examCard.getBackupAttachment())) {
+            JSONObject jsonObjectCard = JSONObject.parseObject(examCard.getBackupAttachment());
+            JSONArray jsonArrayCard = (JSONArray) jsonObjectCard.get("card");
+            for (int i = 0; i < jsonArrayCard.size(); i++) {
+                JSONObject object = (JSONObject) jsonArrayCard.get(i);
+                if (Objects.nonNull(object.get("attachmentId")) && !Objects.equals("", object.get("attachmentId"))) {
+                    attachmentIds.add((Long) (object.get("attachmentId")));
+                }
+            }
+        }
+    }
+
+    /**
+     * 获取试卷pdf
+     *
+     * @param stuPaperType   考生卷型
+     * @param paperPdfDto    抽取的试卷文件信息
+     * @param pdfList        考生试卷集合
+     * @param waterMarkNames 水印内容
+     */
+    public PdfDto getExamStudentPaperPdf(String stuPaperType, List<PaperPdfDto> paperPdfDto, List<PdfDto> pdfList, String[] waterMarkNames) throws IOException {
+        Set<Integer> pagesList = new HashSet<>();
+        if (!CollectionUtils.isEmpty(paperPdfDto)) {
+            for (PaperPdfDto dto : paperPdfDto) {
+                if (stuPaperType.equals(dto.getType())) {
+                    int pages = dto.getPages();
+                    pagesList.add(pages);
+                    PdfDto pdfDto = PdfUtil.addPdfPage(dto.getFile());
+                    File file = paperPdfDto.size() > 1 ? PdfUtil.addWaterMark(dto.getFile(), waterMarkNames, 0.5f, 12, 0) : dto.getFile();
+                    pdfList.add(new PdfDto(file.getPath(), dto.getPageSize(), pdfDto.getPageCount()));
+                }
+            }
+            int pageCount = pagesList.stream().mapToInt(Integer::intValue).sum();
+            return new PdfDto(paperPdfDto.get(0).getPageSize(), pageCount);
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * 获取试卷pdf
+     *
+     * @param paperPdfDto 抽取的试卷文件信息
+     * @param backupCount 备份数量
+     * @param pdfList     备份试卷集合
+     */
+    public PdfDto getPaperPdf(List<PaperPdfDto> paperPdfDto, Integer backupCount, List<PdfDto> pdfList) throws
+            IOException {
+        Set<Integer> pagesList = new HashSet<>();
+        boolean tag = false;
+        if (CollectionUtils.isNotEmpty(paperPdfDto)) {
+            for (PaperPdfDto dto : paperPdfDto) {
+                int pages = dto.getPages();
+                pagesList.add(pages);
+                tag = pages > 2;
+                PdfDto pdfDto = PdfUtil.addPdfPage(dto.getFile());
+                for (int j = 1; j <= backupCount; j++) {
+                    pdfList.add(new PdfDto(dto.getFile().getPath(), dto.getPageSize(), pdfDto.getPageCount()));
+                }
+            }
+            int pageCount = pagesList.stream().mapToInt(Integer::intValue).sum();
+            return new PdfDto(paperPdfDto.get(0).getPageSize(), pageCount, tag);
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * 获取考试试卷
+     *
+     * @param paperType      抽取的试卷型(多个用,分隔)
+     * @param examTaskDetail 命题任务上传试卷信息
+     * @param fileTempList
+     */
+    public List<PaperPdfDto> getPaperPdfFile(String paperType, ExamTaskDetail examTaskDetail, List<File> fileTempList) throws Exception {
+        String[] paperTypes = paperType.split(",");
+        List<PaperPdfDto> paperPdfDtoList = new ArrayList<>();
+        PaperPdfDto paperPdfDto;
+        List<PaperInfoVo> paperInfoVoList = ExamTaskUtil.parsePaperAttachmentPath(examTaskDetail.getPaperAttachmentIds());
+        for (PaperInfoVo paperInfoVo : paperInfoVoList) {
+            String attachmentId = paperInfoVo.getAttachmentId();
+            if (StringUtils.isNotBlank(attachmentId)) {
+                BasicAttachment basicAttachment = basicAttachmentService.getById(attachmentId);
+                Optional.ofNullable(basicAttachment).orElseThrow(() -> ExceptionResultEnum.ATTACHMENT_IS_NULL.exception("文件路径不存在"));
+
+                // 卷型
+                String name = paperInfoVo.getName();
+                OriginalVo original = paperInfoVo.getOriginal();
+                // 返回抽中的试卷
+                for (String type : paperTypes) {
+                    if (Objects.equals(name.toUpperCase(), type.toUpperCase())) {
+                        File file = teachcloudCommonService.getFile(basicAttachment.getPath(), false, fileTempList);
+                        PageSizeEnum pageSizeEnum = PageSizeEnum.valueOf(original.getPageSize());
+                        Optional.ofNullable(pageSizeEnum).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("未设置pdf格式"));
+
+                        paperPdfDto = new PaperPdfDto(type, file, original.getPages(), pageSizeEnum);
+                        paperPdfDtoList.add(paperPdfDto);
+                        break;
+                    }
+                }
+            }
+        }
+        return paperPdfDtoList;
+    }
+
+    private String randomPaperType(String[] unexposedPaperTypes, int drawCount) {
+        List<String> finalTypes = new ArrayList<>();
+        List<String> unexposedPaperTypesList = new ArrayList<>(Arrays.asList(unexposedPaperTypes));
+        for (int i = 0; i < drawCount; i++) {
+            int index = new Random().nextInt(unexposedPaperTypesList.size());
+            finalTypes.add(unexposedPaperTypesList.get(index));
+            unexposedPaperTypesList.remove(index);
+        }
+
+        finalTypes = finalTypes.stream().sorted(Comparator.comparing(String::valueOf)).collect(Collectors.toList());
+        return String.join(",", finalTypes);
+    }
+
+    /**
+     * 合并A3 pdf
+     *
+     * @param list
+     * @return
+     * @throws IOException
+     */
+    public String mergeA3Pdf(List<PdfDto>... list) {
+        List<PdfDto> mergePdfA3List = new ArrayList<>();
+        for (int i = 0; i < list.length; i++) {
+            mergePdfA3List.addAll(list[i]);
+        }
+        List<String> pathA3List = mergePdfA3List.stream().map(PdfDto::getPath).collect(Collectors.toList());
+        return PdfUtil.mergePdf(pathA3List.toArray(new String[mergePdfA3List.size()]), null);
+    }
+
+    /**
+     * 合并A4 pdf
+     *
+     * @param list
+     * @return
+     * @throws IOException
+     */
+    public String mergeA4Pdf(List<File> fileTempList, List<PdfDto>... list) {
+        List<PdfDto> mergePdfA4List = new ArrayList<>();
+        for (int i = 0; i < list.length; i++) {
+            mergePdfA4List.addAll(list[i]);
+        }
+        List<String> pathA4List = mergePdfA4List.stream().map(PdfDto::getPath).collect(Collectors.toList());
+        return PdfUtil.mergePdf(pathA4List.toArray(new String[mergePdfA4List.size()]), null, fileTempList);
+    }
+
+    /**
+     * 合并pdf后保存数据库
+     *
+     * @param dirNamePaper
+     * @param dirNameCardA3
+     * @param tbTaskPdf
+     * @return
+     * @throws Exception
+     */
+    @Transactional
+    public BasicAttachment mergePdfSaveDb(String dirNamePaper,
+                                          String dirNameCardA3,
+                                          TBTaskPdf tbTaskPdf) throws Exception {
+        ExamDetail examDetail = examDetailService.getById(tbTaskPdf.getId());
+        BasicPrintConfig basicPrintConfig = basicPrintConfigService.getByExamId(tbTaskPdf.getExamId());
+        File localPaperPdfFile = null, localA3PdfCardFile = null;
+        BasicAttachment basicAttachment = null;
+        // 试卷+题卡
+        if (StringUtils.isNotBlank(dirNamePaper)) {
+            dirNamePaper = FileUtil.replaceSplit(dirNamePaper);
+            localPaperPdfFile = new File(dirNamePaper);
+            examDetail.setPaperPages(PdfUtil.getPdfPages(localPaperPdfFile));
+            basicAttachment = basicAttachmentService.saveAttachmentPdf(dirNamePaper, tbTaskPdf.getCreateId());
+            examDetail.setAttachmentId(basicAttachment.getId());
+        }
+        // 题卡
+        if (StringUtils.isNotBlank(dirNameCardA3)) {
+            localA3PdfCardFile = new File(FileUtil.replaceSplit(dirNameCardA3));
+            examDetail.setCardPages(PdfUtil.getPdfPages(localA3PdfCardFile));
+            basicAttachment = basicAttachmentService.saveAttachmentPdf(dirNameCardA3, tbTaskPdf.getCreateId());
+            examDetail.setCardAttachmentId(basicAttachment.getId());
+        }
+        if (PrintMethodEnum.AUTO == basicPrintConfig.getPrintMethod()) {
+            examDetail.setStatus(ExamDetailStatusEnum.WAITING);
+        } else {
+            examDetail.setStatus(ExamDetailStatusEnum.READY);
+        }
+        examDetail.setNormal(true);
+        examDetailService.saveOrUpdate(examDetail);
+
+        ExamPrintPlan examPrintPlan = examPrintPlanService.getById(tbTaskPdf.getPrintPlanId());
+        if (PrintMethodEnum.AUTO == basicPrintConfig.getPrintMethod()) {
+            examPrintPlan.setStatus(PrintPlanStatusEnum.PRINTING);
+            examPrintPlanService.updateById(examPrintPlan);
+        }
+        return basicAttachment;
+    }
+
+    /**
+     * 考生题卡html
+     *
+     * @param studentHtml        题卡html内容
+     * @param examStudent        考生对象
+     * @param examDetail         考场对象
+     * @param userId             当前用户ID
+     * @param examStudentPdfList 考生题卡集合
+     * @param basicCardRule      题卡规则
+     */
+    public BasicAttachment examStudentHtml(String studentHtml, ExamStudent examStudent, String paperType, ExamDetail examDetail,
+                                           Long userId, List<PdfDto> examStudentPdfList, BasicCardRule basicCardRule) throws IOException {
+        if (ExamNumberStyleEnum.PRINT.equals(basicCardRule.getExamNumberStyle())) {
+            // 生成学生考号条码并将图片转成base64
+            studentHtml = studentHtml.replaceAll("\\$\\{studentCodeBarcode\\}", examStudent != null && examStudent.getStudentCode() != null ? GoogleBarCodeUtil.createBarCode(examStudent.getStudentCode(), false) : "");
+            studentHtml = studentHtml.replaceAll("\\$\\{ticketNumberBarcode\\}", examStudent != null && examStudent.getTicketNumber() != null ? GoogleBarCodeUtil.createBarCode(examStudent.getTicketNumber(), false) : "");
+            studentHtml = studentHtml.replaceAll("\\$\\{examNumber\\}", examStudent != null && examStudent.getStudentCode() != null ? GoogleBarCodeUtil.createBarCode(examStudent.getStudentCode(), false) : "");
+            studentHtml = studentHtml.replaceAll("\\$\\{examNumberStr\\}", examStudent != null && examStudent.getStudentCode() != null ? examStudent.getStudentCode() : "");
+            // 随机生成学生试卷条码并将图片转成base64
+            studentHtml = studentHtml.replaceAll("\\$\\{paperType\\}", examStudent != null && examStudent.getPaperType() != null ? GoogleBarCodeUtil.createBarCode(SystemConstant.convertPaperType(examStudent.getPaperType()), false) : StringUtils.isNotBlank(paperType) ? GoogleBarCodeUtil.createBarCode(SystemConstant.convertPaperType(paperType), false) : "");
+            // 替换考生卷型
+            studentHtml = studentHtml.replaceAll("\\$\\{paperTypeName\\}", examStudent != null && examStudent.getPaperType() != null ? examStudent.getPaperType() : StringUtils.isNotBlank(paperType) ? paperType : "");
+
+            if (examStudent != null) {
+                // 根据题卡规则必选字段,替换相应值,没有则“”
+                List<StudentExtendDto> studentExtendDtos = createExtendObject(examDetail, examStudent, basicCardRule);
+                if (studentExtendDtos != null) {
+                    for (StudentExtendDto extendDto : studentExtendDtos) {
+                        studentHtml = studentHtml.replaceAll("\\$\\{" + extendDto.getFieldName() + "\\}", String.valueOf(extendDto.getValue()));
+                    }
+                }
+            }
+        }
+
+        studentHtml = studentHtml.replaceAll("\\$\\{packageCodeDom\\}", "");
+        // 将其它未匹配到值的参数,填入空值
+        studentHtml = studentHtml.replaceAll("\\$\\{[A-Za-z0-9]+\\}", "");
+        //学生题卡
+        BasicAttachment examStudentAttachment = printCommonService.saveAttachmentPdfFromHtml(examStudent != null ? examStudent.getId() + "|" + examStudent.getStudentCode() : String.valueOf(System.currentTimeMillis()), studentHtml, userId, examStudentPdfList);
+        if (examStudent != null) {
+            examStudent.setAttachmentId(examStudentAttachment.getId());
+        }
+        return examStudentAttachment;
+    }
+
+    /**
+     * 题卡规则字段
+     *
+     * @param examDetail
+     * @param examStudent   考生对象
+     * @param basicCardRule 题卡规则对象
+     */
+    private List<StudentExtendDto> createExtendObject(ExamDetail examDetail, ExamStudent examStudent, BasicCardRule
+            basicCardRule) {
+        ExamStudentPdfInfoDto examStudentPdfInfoDto = examStudent == null ? null : examStudentService.getByStudentId(examStudent.getId());
+        if (basicCardRule == null) {
+            return null;
+        }
+        List<JSONObject> requiredFieldsJson = JSONArray.parseArray(basicCardRule.getRequiredFields(), JSONObject.class);
+        List<StudentExtendDto> studentExtendDtos = new ArrayList<>();
+        if (requiredFieldsJson.size() > 0) {
+            for (JSONObject jsonObject : requiredFieldsJson) {
+                StudentExtendDto studentExtendDto = new StudentExtendDto();
+                String code = String.valueOf(jsonObject.get("code"));
+                studentExtendDto.setFieldName(code);
+                Object value = examStudentPdfInfoDto == null ? null : ReflectUtil.getFieldValue(examStudentPdfInfoDto, code);
+                studentExtendDto.setValue(value == null ? "" : value);
+                studentExtendDtos.add(studentExtendDto);
+            }
+        }
+        List<JSONObject> extendFieldsJson = JSONArray.parseArray(basicCardRule.getExtendFields(), JSONObject.class);
+        if (extendFieldsJson.size() > 0) {
+            Map<String, Object> studentExtendMap = null;
+            if (examStudentPdfInfoDto != null && StringUtils.isNotBlank(examStudentPdfInfoDto.getExtendFields())) {
+                studentExtendMap = JSONArray.parseArray(examStudentPdfInfoDto.getExtendFields(), JSONObject.class).stream().collect(Collectors.toMap(k -> String.valueOf(k.get("code")), v -> v.get("value")));
+            }
+
+            Map<String, Object> map = ConvertUtil.analyzeDateAndTime(examDetail.getExamStartTime(), examDetail.getExamEndTime());
+
+            for (JSONObject jsonObject : extendFieldsJson) {
+                boolean enable = Boolean.parseBoolean(jsonObject.get("enable").toString());
+                StudentExtendDto studentExtendDto = new StudentExtendDto();
+                String code = String.valueOf(jsonObject.get("code"));
+
+                studentExtendDto.setFieldName(code);
+                Object value = examStudentPdfInfoDto == null ? null : ReflectUtil.getFieldValue(examStudentPdfInfoDto, code);
+                // 时间需要特殊处理
+                if ("examDate".equals(code)) {
+                    value = Objects.nonNull(map.get("date")) ? (String) map.get("date") : "";
+                }
+                if ("examTime".equals(code)) {
+                    value = Objects.nonNull(map.get("time")) ? (String) map.get("time") : "";
+                }
+                if (value == null) {
+                    value = studentExtendMap == null ? null : studentExtendMap.get(code);
+                }
+                studentExtendDto.setValue(value == null ? "" : value);
+                studentExtendDtos.add(studentExtendDto);
+            }
+        }
+        return studentExtendDtos;
+    }
+
+    /**
+     * 题卡规则字段
+     *
+     * @param basicCardRule 题卡规则对象
+     */
+    private List<StudentExtendDto> createExtendObjectNull(BasicCardRule basicCardRule) {
+        if (basicCardRule == null) {
+            return null;
+        }
+        List<JSONObject> requiredFieldsJson = JSONArray.parseArray(basicCardRule.getRequiredFields(), JSONObject.class);
+        List<StudentExtendDto> studentExtendDtos = new ArrayList<>();
+        if (requiredFieldsJson.size() > 0) {
+            for (JSONObject jsonObject : requiredFieldsJson) {
+                StudentExtendDto studentExtendDto = new StudentExtendDto();
+                String code = String.valueOf(jsonObject.get("code"));
+                studentExtendDto.setFieldName(code);
+                studentExtendDto.setValue("");
+                studentExtendDtos.add(studentExtendDto);
+            }
+        }
+        List<JSONObject> extendFieldsJson = JSONArray.parseArray(basicCardRule.getExtendFields(), JSONObject.class);
+        if (extendFieldsJson.size() > 0) {
+            for (JSONObject jsonObject : extendFieldsJson) {
+                StudentExtendDto studentExtendDto = new StudentExtendDto();
+                String code = String.valueOf(jsonObject.get("code"));
+                studentExtendDto.setFieldName(code);
+                studentExtendDto.setValue("");
+                studentExtendDtos.add(studentExtendDto);
+            }
+        }
+        return studentExtendDtos;
+    }
+
+    /**
+     * 通用题卡html
+     * @param packageCode
+     * @param cardContent
+     * @param paperType
+     * @param userId
+     * @param cardPdfList
+     * @param basicCardRule
+     * @return
+     * @throws IOException
+     */
+    public BasicAttachment cardHtml(String packageCode, String cardContent, String paperType, Long userId, List<PdfDto> cardPdfList, BasicCardRule basicCardRule) throws
+            IOException {
+        //通用题卡
+        String cardTemp = cardContent;
+        cardTemp = cardTemp.replaceAll("\\$\\{paperTypeName\\}", paperType);
+        //随机生成试卷条码并将图片转成base64
+        if (Objects.nonNull(paperType)) {
+            cardTemp = cardTemp.replaceAll("\\$\\{paperType\\}", GoogleBarCodeUtil.createBarCode(SystemConstant.convertPaperType(paperType), false));
+        }
+        if (Objects.nonNull(basicCardRule) && Objects.nonNull(basicCardRule.getExtendFields())) {
+            JSONArray jsonObjectExtend = (JSONArray) JSONArray.parse(basicCardRule.getExtendFields());//扩展字段
+            if (Objects.nonNull(jsonObjectExtend)) {
+                int i = 0;
+                while (i < jsonObjectExtend.size()) {
+                    JSONObject object = (JSONObject) jsonObjectExtend.get(i);
+                    cardTemp = cardTemp.replaceAll("\\$\\{" + object.get("code") + "\\}", "");
+                    i++;
+                }
+            }
+        }
+        cardTemp = cardTemp.replaceAll("\\$\\{examDate\\}", "");
+        cardTemp = cardTemp.replaceAll("\\$\\{examTime\\}", "");
+        cardTemp = cardTemp.replaceAll("\\$\\{ticketNumber\\}", "");
+        cardTemp = cardTemp.replaceAll("\\$\\{siteNumber\\}", "");
+        cardTemp = cardTemp.replaceAll("\\$\\{paperTypeName\\}", "");
+        cardTemp = cardTemp.replaceAll("\\$\\{studentCode\\}", "");
+        cardTemp = cardTemp.replaceAll("\\$\\{studentName\\}", "");
+        cardTemp = cardTemp.replaceAll("\\$\\{courseName\\}", "");
+        cardTemp = cardTemp.replaceAll("\\$\\{courseCode\\}", "");
+        cardTemp = cardTemp.replaceAll("\\$\\{examPlace\\}", "");
+        cardTemp = cardTemp.replaceAll("\\$\\{examRoom\\}", "");
+        cardTemp = cardTemp.replaceAll("\\$\\{paperNumber\\}", "");
+
+        //通用题卡生成卷袋贴条码
+        String packageCodeImg = GoogleBarCodeUtil.createBarCode(packageCode, false);
+        cardTemp = cardTemp.replaceAll("\\$\\{packageCodeDom\\}", "<img src='" + "data:image/png;base64," + packageCodeImg + "'><p>" + packageCode + "</p>");
+
+        return printCommonService.saveAttachmentPdfFromHtml(packageCode + paperType, cardTemp, userId, cardPdfList);
+    }
+
+    public String getPaperType(Long printPlanId, Long examId, String paperNumber) {
+        ExamPrintPlan examPrintPlan = examPrintPlanService.getById(printPlanId);
+        //抽取卷型
+        DrawRuleEnum drawRule = Objects.nonNull(examPrintPlan.getDrawRule()) ? examPrintPlan.getDrawRule() : DrawRuleEnum.ONE;
+        ExamTaskDetail examTaskDetail = examTaskDetailService.getByExamIdAndCourseCodeAndPaperNumber(examId, null, paperNumber);
+        // 单次抽取套数
+        int drawCount = examTaskDetail.getDrawCount().intValue();
+
+        String paperType = null;
+        try {
+            //未曝光卷型
+            String unexposedPaperType = examTaskDetail.getUnexposedPaperType();
+            //已曝光卷型
+            String exposedPaperType = examTaskDetail.getExposedPaperType();
+            String totalPaperType = examTaskDetail.getPaperType();
+            String[] paperTypes;
+            if (drawRule == DrawRuleEnum.ONE) {
+                if (StringUtils.isBlank(unexposedPaperType)) {
+                    throw ExceptionResultEnum.PAPER_ERROR.exception();
+                }
+                paperTypes = unexposedPaperType.split(",");
+                if (paperTypes.length - drawCount < 0) {
+                    throw ExceptionResultEnum.ERROR.exception("可用卷型数量小于抽取数量");
+                }
+            } else {
+                if (StringUtils.isAllBlank(totalPaperType, unexposedPaperType)) {
+                    throw ExceptionResultEnum.PAPER_ERROR.exception();
+                }
+                if (StringUtils.isNotBlank(unexposedPaperType)) {
+                    paperTypes = unexposedPaperType.split(",");
+                    // 未曝光卷型小于抽取数量,则使用所有卷型
+                    if (paperTypes.length - drawCount < 0) {
+                        paperTypes = totalPaperType.split(",");
+                    }
+                } else {
+                    paperTypes = totalPaperType.split(",");
+                }
+            }
+            paperType = randomPaperType(paperTypes, drawCount);
+        } catch (Exception e) {
+            log.error(SystemConstant.LOG_ERROR, e);
+        }
+        return paperType;
+    }
+}

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

@@ -144,6 +144,7 @@
             ed.exam_id examId,
             GROUP_CONCAT(edc.course_code) courseCode,
             GROUP_CONCAT(edc.course_name) courseName,
+            GROUP_CONCAT(concat(edc.course_name, '(',edc.course_code, ')')) courseNameCode,
             GROUP_CONCAT(edc.paper_number) paperNumber
         FROM
             exam_detail ed

+ 15 - 0
distributed-print-business/src/main/resources/mapper/ExamTaskAssignPaperTypeMapper.xml

@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.qmth.distributed.print.business.mapper.ExamTaskAssignPaperTypeMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.qmth.distributed.print.business.entity.ExamTaskAssignPaperType">
+        <id column="exam_id" property="examId" />
+        <id column="paper_number" property="paperNumber" />
+        <id column="exam_start_time" property="examStartTime" />
+        <id column="exam_end_time" property="examEndTime" />
+        <result column="paper_type" property="paperType" />
+        <result column="assign_mode" property="assignMode" />
+    </resultMap>
+
+</mapper>

+ 25 - 0
distributed-print-business/src/main/resources/mapper/TBTaskPdfMapper.xml

@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.qmth.distributed.print.business.mapper.TBTaskPdfMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.qmth.distributed.print.business.entity.TBTaskPdf">
+        <id column="id" property="id" />
+        <result column="school_id" property="schoolId" />
+        <result column="semester_id" property="semesterId" />
+        <result column="exam_id" property="examId" />
+        <result column="print_plan_id" property="printPlanId" />
+        <result column="course_name_code" property="courseNameCode" />
+        <result column="paper_number" property="paperNumber" />
+        <result column="create_type" property="createType" />
+        <result column="status" property="status" />
+        <result column="summary" property="summary" />
+        <result column="result" property="result" />
+        <result column="create_id" property="createId" />
+        <result column="create_time" property="createTime" />
+        <result column="update_id" property="updateId" />
+        <result column="update_time" property="updateTime" />
+        <result column="remark" property="remark" />
+    </resultMap>
+
+</mapper>

+ 3 - 0
distributed-print/install/mysql/upgrade/3.3.1.sql

@@ -20,6 +20,9 @@ ALTER TABLE `basic_card_rule`
     ADD COLUMN `first_level_subheading` VARCHAR(200) NULL COMMENT '一级副标题' AFTER `fill_number`,
 ADD COLUMN `second_level_subheading` VARCHAR(200) NULL COMMENT '二级副标题' AFTER `first_level_subheading`;
 
+insert into t_b_task_pdf(id, school_id, semester_id, exam_id, print_plan_id, course_name_code, paper_number, status, summary, result) select a.entity_id, a.school_id, a.semester_id, a.exam_id, a.print_plan_id, a.course_name_code, a.paper_number,a.status, a.summary, a.result  from (select id, entity_id, school_id, semester_id, exam_id, print_plan_id, case when course_name is null then null else concat(course_name, '(', course_code, ')') end as course_name_code, paper_number,status, summary, result from t_b_task where type = 'CREATE_PDF' and entity_id is not null) a join (SELECT entity_id, min(id) min_id FROM t_b_task where type = 'CREATE_PDF' group by entity_id having entity_id is not null ) b on a.entity_id = b.entity_id and a.id = b.min_id;
+update t_b_task_pdf set create_type = 'ALL';
+
 ALTER TABLE `exam_task`
 DROP INDEX `idx_school_id_paper_number` ,
 ADD INDEX `idx_school_id_paper_number` USING BTREE (`exam_id`, `paper_number`) VISIBLE;

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

@@ -163,7 +163,7 @@ public class ExamTaskApplyController {
         ExamTask examTask = examTaskService.getById(examTaskDetail.getExamTaskId());
         if (examTaskDetail.getOperateType().equals(ExamStatusEnum.SUBMIT.name()) && (Objects.nonNull(examTask.getReview()) && !examTask.getReview())) {
             // 校验是否可以提交打印状态
-            printCommonService.checkData(examTask.getSchoolId(), examTask.getExamId(), examTask.getCourseCode(), examTask.getPaperNumber(), (SysUser) ServletUtil.getRequestUser());
+            printCommonService.checkDataNew(examTask.getSchoolId(), examTask.getExamId(), examTask.getCourseCode(), examTask.getPaperNumber(), (SysUser) ServletUtil.getRequestUser());
         }
         Boolean sendFlowMq = (Boolean) map.get(SystemConstant.SEND_FLOW_MQ);
         if (Objects.nonNull(sendFlowMq) && sendFlowMq) {
@@ -203,7 +203,7 @@ public class ExamTaskApplyController {
         ExamTask examTask = (ExamTask) map.get(SystemConstant.EXAM_TASK);
         if (Objects.nonNull(examTask.getReview()) && !examTask.getReview()) {
             // 校验是否可以提交打印状态
-            printCommonService.checkData(examTask.getSchoolId(), examTask.getExamId(), examTask.getCourseCode(), examTask.getPaperNumber(), (SysUser) ServletUtil.getRequestUser());
+            printCommonService.checkDataNew(examTask.getSchoolId(), examTask.getExamId(), examTask.getCourseCode(), examTask.getPaperNumber(), (SysUser) ServletUtil.getRequestUser());
         }
         Boolean sendFlowStartMq = (Boolean) map.get(SystemConstant.SEND_FLOW_START_MQ);
         Boolean sendFlowMq = (Boolean) map.get(SystemConstant.SEND_FLOW_MQ);

+ 1 - 1
distributed-print/src/main/java/com/qmth/distributed/print/api/ExamTaskQueryController.java

@@ -115,7 +115,7 @@ public class ExamTaskQueryController {
             Boolean isCreate = printCommonService.checkExamDetailStatus(examTask.getSchoolId(), null, examTask.getExamId(), examTask.getCourseCode(), examTask.getPaperNumber());
             // 校验是否可以提交打印状态
             if (isCreate) {
-                printCommonService.checkData(examTask.getSchoolId(), examTask.getExamId(), examTask.getCourseCode(), examTask.getPaperNumber(), sysUser);
+                printCommonService.checkDataNew(examTask.getSchoolId(), examTask.getExamId(), examTask.getCourseCode(), examTask.getPaperNumber(), sysUser);
             }
         }
         return ResultUtil.ok(isSuccess);

+ 28 - 1
distributed-print/src/main/java/com/qmth/distributed/print/api/TBTaskController.java

@@ -2,11 +2,15 @@ package com.qmth.distributed.print.api;
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.qmth.boot.api.annotation.Aac;
 import com.qmth.boot.api.constant.ApiConstant;
 import com.qmth.distributed.print.business.bean.result.EditResult;
+import com.qmth.distributed.print.business.entity.TBTaskPdf;
 import com.qmth.distributed.print.business.enums.ExamDetailStatusEnum;
 import com.qmth.distributed.print.business.service.ExamDetailService;
 import com.qmth.distributed.print.business.service.PrintCommonService;
+import com.qmth.distributed.print.business.service.TBTaskPdfService;
+import com.qmth.distributed.print.business.templete.execute.AsyncCreatePdfTempleteService;
 import com.qmth.teachcloud.common.bean.dto.MqDto;
 import com.qmth.teachcloud.common.bean.result.TaskListResult;
 import com.qmth.teachcloud.common.contant.SystemConstant;
@@ -23,10 +27,12 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
+import retrofit2.http.Path;
 
 import javax.annotation.Resource;
 import javax.validation.constraints.Max;
 import javax.validation.constraints.Min;
+import java.io.IOException;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -49,13 +55,34 @@ public class TBTaskController {
 
     @Resource
     TBTaskService tbTaskService;
+    @Resource
+    TBTaskPdfService tbTaskPdfService;
 
     @Resource
     ExamDetailService examDetailService;
 
+    @Resource
+    AsyncCreatePdfTempleteService asyncCreatePdfTempleteService;
+
     @Resource
     PrintCommonService printCommonService;
 
+    @Aac(auth = false)
+    @ApiOperation(value = "test")
+    @RequestMapping(value = "/{id}/{type}", method = RequestMethod.POST)
+    @ApiResponses({@ApiResponse(code = 200, message = "重新生成pdf", response = EditResult.class)})
+    public Result test(@PathVariable Long id,
+                       @PathVariable CreatePdfTypeEnum type) {
+        TBTaskPdf tbTaskPdf = tbTaskPdfService.getById(id);
+        try {
+            asyncCreatePdfTempleteService.createPdf(tbTaskPdf, null);
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+        return ResultUtil.ok(new EditResult());
+    }
+
+
     @ApiOperation(value = "任务管理查询接口")
     @RequestMapping(value = "/query", method = RequestMethod.POST)
     @ApiResponses({@ApiResponse(code = 200, message = "任务管理列表信息", response = TaskListResult.class)})
@@ -96,7 +123,7 @@ public class TBTaskController {
     public Result resetCreatePdf(@ApiParam(value = "任务id", required = true) @RequestParam Long id,
                                  @ApiParam(value = "pdf生成类型") @RequestParam(defaultValue = "ALL") CreatePdfTypeEnum type) {
         TBTask tbTask = tbTaskService.getById(id);
-        examDetailService.resetExamDetail(tbTask.getEntityId(), type, ExamDetailStatusEnum.NEW,false);
+        examDetailService.resetExamDetail(tbTask.getEntityId(), type, ExamDetailStatusEnum.NEW, false);
         tbTaskService.resetCreatePdf(tbTask, type);
         return ResultUtil.ok(new EditResult());
     }

+ 11 - 0
teachcloud-common/src/main/java/com/qmth/teachcloud/common/bean/result/TbTaskDetailResult.java

@@ -25,6 +25,9 @@ public class TbTaskDetailResult implements Serializable {
     @ApiModelProperty(value = "课程名称")
     private String courseName;
 
+    @ApiModelProperty(value = "课程名称(代码)")
+    private String courseNameCode;
+
     @ApiModelProperty(value = "试卷编号")
     private String paperNumber;
 
@@ -60,6 +63,14 @@ public class TbTaskDetailResult implements Serializable {
         this.courseName = courseName;
     }
 
+    public String getCourseNameCode() {
+        return courseNameCode;
+    }
+
+    public void setCourseNameCode(String courseNameCode) {
+        this.courseNameCode = courseNameCode;
+    }
+
     public String getPaperNumber() {
         return paperNumber;
     }