瀏覽代碼

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

wangliang 2 年之前
父節點
當前提交
f42a433884
共有 33 個文件被更改,包括 1498 次插入67 次删除
  1. 4 0
      distributed-print-business/pom.xml
  2. 50 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/dto/PdfPackageDto.java
  3. 78 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/dto/PdfSignDto.java
  4. 24 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/entity/BasicTemplate.java
  5. 3 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/BasicTemplateService.java
  6. 3 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ExamPaperGroupService.java
  7. 2 1
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/ExamPaperStructureService.java
  8. 5 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/PrintCommonService.java
  9. 26 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/BasicTemplateServiceImpl.java
  10. 0 1
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamPaperGroupServiceImpl.java
  11. 5 1
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/ExamPaperStructureServiceImpl.java
  12. 14 6
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/GradeBatchPaperServiceImpl.java
  13. 153 8
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/PrintCommonServiceImpl.java
  14. 12 19
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/templete/service/impl/TaskLogicServiceImpl.java
  15. 218 6
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/util/CreatePdfUtil.java
  16. 462 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/util/CreatePrintPdfUtil.java
  17. 307 0
      distributed-print-business/src/main/java/com/qmth/distributed/print/business/util/PdfFillUtils.java
  18. 1 0
      distributed-print-business/src/main/resources/mapper/ExamPaperStructureMapper.xml
  19. 4 1
      distributed-print-business/src/main/resources/mapper/ExamStudentMapper.xml
  20. 10 0
      distributed-print/src/main/java/com/qmth/distributed/print/api/BasicTemplateController.java
  21. 7 2
      distributed-print/src/main/java/com/qmth/distributed/print/api/ExamPaperStructureController.java
  22. 1 1
      distributed-print/src/main/java/com/qmth/distributed/print/api/SysUserController.java
  23. 12 11
      distributed-print/src/test/java/com/qmth/distributed/print/ServiceTest.java
  24. 6 0
      pom.xml
  25. 2 0
      teachcloud-common/src/main/java/com/qmth/teachcloud/common/contant/SystemConstant.java
  26. 1 1
      teachcloud-common/src/main/java/com/qmth/teachcloud/common/enums/OrgTypeEnum.java
  27. 3 1
      teachcloud-common/src/main/java/com/qmth/teachcloud/common/mapper/SysUserMapper.java
  28. 13 2
      teachcloud-common/src/main/java/com/qmth/teachcloud/common/service/SysUserService.java
  29. 22 2
      teachcloud-common/src/main/java/com/qmth/teachcloud/common/service/impl/SysUserServiceImpl.java
  30. 0 2
      teachcloud-common/src/main/java/com/qmth/teachcloud/common/sync/TeachCloudReportTaskUtils.java
  31. 17 0
      teachcloud-common/src/main/java/com/qmth/teachcloud/common/util/ConvertUtil.java
  32. 32 1
      teachcloud-common/src/main/resources/mapper/SysUserMapper.xml
  33. 1 1
      teachcloud-report/src/main/java/com/qmth/teachcloud/report/api/SysUserController.java

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

@@ -43,6 +43,10 @@
             <groupId>com.itextpdf</groupId>
             <artifactId>itextpdf</artifactId>
         </dependency>
+        <dependency>
+            <groupId>com.itextpdf</groupId>
+            <artifactId>itext-asian</artifactId>
+        </dependency>
         <dependency>
             <groupId>com.google.zxing</groupId>
             <artifactId>core</artifactId>

+ 50 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/dto/PdfPackageDto.java

@@ -0,0 +1,50 @@
+package com.qmth.distributed.print.business.bean.dto;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ *
+ */
+public class PdfPackageDto {
+
+    /**
+     * 标题
+     */
+    private String title;
+
+    /**
+     * 卷袋号
+     */
+    private String packageNumber;
+
+    /**
+     * 基础板块信息
+     */
+    private List<Map<String, String>> basicPlate;
+
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public String getPackageNumber() {
+        return packageNumber;
+    }
+
+    public void setPackageNumber(String packageNumber) {
+        this.packageNumber = packageNumber;
+    }
+
+    public List<Map<String, String>> getBasicPlate() {
+        return basicPlate;
+    }
+
+    public void setBasicPlate(List<Map<String, String>> basicPlate) {
+        this.basicPlate = basicPlate;
+    }
+}

+ 78 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/bean/dto/PdfSignDto.java

@@ -0,0 +1,78 @@
+package com.qmth.distributed.print.business.bean.dto;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ *
+ */
+public class PdfSignDto {
+
+    /**
+     * 标题
+     */
+    private String title;
+
+    /**
+     * 卷袋号
+     */
+    private String packageNumber;
+
+    /**
+     * 基础板块信息
+     */
+    private List<Map<String, String>> basicPlate;
+
+    /**
+     * 考生表头信息
+     */
+    private Map<String, String> studentHeadPlate;
+
+    /**
+     * 考生信息
+     */
+    private List<Map<String, String>> studentPlate;
+
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public String getPackageNumber() {
+        return packageNumber;
+    }
+
+    public void setPackageNumber(String packageNumber) {
+        this.packageNumber = packageNumber;
+    }
+
+    public List<Map<String, String>> getBasicPlate() {
+        return basicPlate;
+    }
+
+    public void setBasicPlate(List<Map<String, String>> basicPlate) {
+        this.basicPlate = basicPlate;
+    }
+
+    public Map<String, String> getStudentHeadPlate() {
+        return studentHeadPlate;
+    }
+
+    public void setStudentHeadPlate(Map<String, String> studentHeadPlate) {
+        this.studentHeadPlate = studentHeadPlate;
+    }
+
+    public List<Map<String, String>> getStudentPlate() {
+        return studentPlate;
+    }
+
+    public void setStudentPlate(List<Map<String, String>> studentPlate) {
+        this.studentPlate = studentPlate;
+    }
+
+
+}

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

@@ -48,6 +48,14 @@ public class BasicTemplate extends BaseEntity implements Serializable {
      * SIGN-签到表,PACKAGE-卷袋贴,CHECK_IN-登记表
      */
     private ClassifyEnum classify;
+    /**
+     * 卷袋贴、签到表数据范围
+     */
+    private String displayRange;
+    /**
+     * 预览地址
+     */
+    private String previewPath;
     /**
      * 模板附件ID(保存到附件表ID)
      */
@@ -114,6 +122,22 @@ public class BasicTemplate extends BaseEntity implements Serializable {
         this.classify = classify;
     }
 
+    public String getDisplayRange() {
+        return displayRange;
+    }
+
+    public void setDisplayRange(String displayRange) {
+        this.displayRange = displayRange;
+    }
+
+    public String getPreviewPath() {
+        return previewPath;
+    }
+
+    public void setPreviewPath(String previewPath) {
+        this.previewPath = previewPath;
+    }
+
     public Long getAttachmentId() {
         return attachmentId;
     }

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

@@ -6,6 +6,7 @@ import com.qmth.distributed.print.business.bean.dto.TemplateDto;
 import com.qmth.distributed.print.business.bean.result.TemplatePrintInfoResult;
 import com.qmth.distributed.print.business.entity.BasicTemplate;
 
+import javax.servlet.http.HttpServletResponse;
 import java.util.List;
 
 /**
@@ -35,4 +36,6 @@ public interface BasicTemplateService extends IService<BasicTemplate> {
      * @return
      */
     List<TemplatePrintInfoResult> findTemplateInfoByOrgIds(List<Long> ids);
+
+    void preview(HttpServletResponse response, String data);
 }

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

@@ -1,6 +1,7 @@
 package com.qmth.distributed.print.business.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.qmth.distributed.print.business.bean.marking.CardJpgResult;
 import com.qmth.distributed.print.business.bean.marking.GroupInfo;
 import com.qmth.distributed.print.business.entity.ExamPaperGroup;
 
@@ -23,12 +24,14 @@ public interface ExamPaperGroupService extends IService<ExamPaperGroup> {
 
     /**
      * 删除考试试卷分组信息
+     *
      * @param examPaperStructureId 试卷结构id
      */
     void deleteExamPaperGroupInfo(Long examPaperStructureId);
 
     /**
      * 查询分组
+     *
      * @param id 试卷结构表id
      */
     List<ExamPaperGroup> listByExamPaperStructureId(Long id);

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

@@ -63,9 +63,10 @@ public interface ExamPaperStructureService extends IService<ExamPaperStructure>
      * @param examId      考试id
      * @param courseCode  课程编号
      * @param paperNumber 试卷编号
+     * @param paperType   试卷类型
      * @return 题卡jpg文件结果
      */
-    List<CardJpgResult> findCardJpgFileByPaperNumber(Long examId, String courseCode, String paperNumber);
+    List<CardJpgResult> findCardJpgFileByPaperNumber(Long examId, String courseCode, String paperNumber, String paperType);
 
     /**
      * 绑定科组长

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

@@ -3,6 +3,8 @@ package com.qmth.distributed.print.business.service;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.itextpdf.text.DocumentException;
 import com.qmth.distributed.print.business.bean.dto.PdfDto;
+import com.qmth.distributed.print.business.bean.dto.PdfPackageDto;
+import com.qmth.distributed.print.business.bean.dto.PdfSignDto;
 import com.qmth.distributed.print.business.bean.params.ExamTaskStudentObjectParam;
 import com.qmth.distributed.print.business.bean.params.SerialNumberParams;
 import com.qmth.distributed.print.business.entity.ExamDetail;
@@ -46,6 +48,7 @@ public interface PrintCommonService {
      */
     public BasicAttachment saveAttachmentPdf(ClassifyEnum classifyEnum, ExamDetail examDetail, BasicAttachment basicAttachment, List<PdfDto> pdfList, Integer printCount, Integer sequence) throws IOException, DocumentException;
 
+    public void saveAttachmentSignPdf(PdfSignDto pdfFillDto, ExamDetail examDetail, List<PdfDto> pdfList, Integer printCount);
     /**
      * 保存html附件
      *
@@ -289,4 +292,6 @@ public interface PrintCommonService {
      * @param paperType   试卷类型
      */
     public void updateGradeBatchStatus(Long schoolId, String paperNumber, String paperType);
+
+    void saveAttachmentPackagePdf(PdfPackageDto pdfPackageDto, ExamDetail examDetail, List<PdfDto> variablePdfList, Integer printCount);
 }

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

@@ -1,5 +1,7 @@
 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.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -19,9 +21,12 @@ import com.qmth.distributed.print.business.mapper.BasicTemplateMapper;
 import com.qmth.distributed.print.business.service.BasicTemplateService;
 import com.qmth.distributed.print.business.service.ExamCardDetailService;
 import com.qmth.distributed.print.business.service.ExamCardService;
+import com.qmth.distributed.print.business.util.PdfFillUtils;
 import com.qmth.teachcloud.common.contant.SystemConstant;
 import com.qmth.teachcloud.common.entity.BasicAttachment;
 import com.qmth.teachcloud.common.entity.SysUser;
+import com.qmth.teachcloud.common.enums.ClassifyEnum;
+import com.qmth.teachcloud.common.enums.EnumResult;
 import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
 import com.qmth.teachcloud.common.service.BasicAttachmentService;
 import com.qmth.teachcloud.common.service.TeachcloudCommonService;
@@ -31,8 +36,10 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
 import java.util.List;
 import java.util.Objects;
+import java.util.stream.Collectors;
 
 /**
  * <p>
@@ -174,4 +181,23 @@ public class BasicTemplateServiceImpl extends ServiceImpl<BasicTemplateMapper, B
     public List<TemplatePrintInfoResult> findTemplateInfoByOrgIds(List<Long> ids) {
         return basicTemplateMapper.findTemplateInfoByOrgIds(ids);
     }
+
+    @Override
+    public void preview(HttpServletResponse response, String data) {
+        JSONObject jsonObject = JSON.parseObject(data);
+        String classifyStr = jsonObject.getString("classify");
+        List<String> stringList = ClassifyEnum.listTypes().stream().map(EnumResult::getName).collect(Collectors.toList());
+        if (!stringList.contains(classifyStr)) {
+            throw ExceptionResultEnum.ERROR.exception("模板类型有误");
+        }
+        ClassifyEnum classifyEnum = ClassifyEnum.valueOf(classifyStr);
+        // 签到表
+        if (ClassifyEnum.SIGN.equals(classifyEnum)) {
+            PdfFillUtils.parseSignTempData(response, jsonObject.getString("data"), "签到表预览.pdf");
+        } else if (ClassifyEnum.PACKAGE.equals(classifyEnum)) {
+            PdfFillUtils.packageTempData(response, jsonObject.getString("data"), "卷袋贴预览.pdf");
+        } else {
+            throw ExceptionResultEnum.ERROR.exception("不支持当前模板预览");
+        }
+    }
 }

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

@@ -8,7 +8,6 @@ import com.qmth.distributed.print.business.bean.marking.Marker;
 import com.qmth.distributed.print.business.bean.marking.PictureConfig;
 import com.qmth.distributed.print.business.bean.marking.Question;
 import com.qmth.distributed.print.business.entity.ExamPaperGroup;
-import com.qmth.distributed.print.business.entity.ExamPaperGroupMarker;
 import com.qmth.distributed.print.business.mapper.ExamPaperGroupMapper;
 import com.qmth.distributed.print.business.service.ExamPaperGroupMarkerService;
 import com.qmth.distributed.print.business.service.ExamPaperGroupService;

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

@@ -354,7 +354,7 @@ public class ExamPaperStructureServiceImpl extends ServiceImpl<ExamPaperStructur
     }
 
     @Override
-    public List<CardJpgResult> findCardJpgFileByPaperNumber(Long examId, String courseCode, String paperNumber) {
+    public List<CardJpgResult> findCardJpgFileByPaperNumber(Long examId, String courseCode, String paperNumber, String paperType) {
         Long examTaskId = examTaskService.getOne(new QueryWrapper<ExamTask>().lambda()
                 .eq(ExamTask::getExamId, examId)
                 .eq(ExamTask::getCourseCode, courseCode)
@@ -368,6 +368,10 @@ public class ExamPaperStructureServiceImpl extends ServiceImpl<ExamPaperStructur
             JSONArray jsonArrayPaper = JSONArray.parseArray(examTaskDetail.getPaperAttachmentIds());
             for (int i = 0; i < jsonArrayPaper.size(); i++) {
                 JSONObject object = jsonArrayPaper.getJSONObject(i);
+                if (!paperType.equals(String.valueOf(object.get("name")))){
+                    // 试卷类型不匹配跳过
+                    continue;
+                }
                 String jpgAttachmentInfo = examCardDetailService.getOne(new QueryWrapper<ExamCardDetail>().lambda()
                         .eq(ExamCardDetail::getCardId, Long.parseLong((String) object.get("cardId")))).getJpgAttachmentInfo();
                 if (StringUtils.isBlank(jpgAttachmentInfo)) {

+ 14 - 6
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/GradeBatchPaperServiceImpl.java

@@ -16,6 +16,7 @@ import com.qmth.teachcloud.common.entity.SysOrg;
 import com.qmth.teachcloud.common.entity.SysUser;
 import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
 import com.qmth.teachcloud.common.enums.GradeAnalyzePaperStatusEnum;
+import com.qmth.teachcloud.common.enums.OrgTypeEnum;
 import com.qmth.teachcloud.common.service.SysOrgService;
 import com.qmth.teachcloud.common.service.TeachcloudCommonService;
 import org.springframework.beans.BeanUtils;
@@ -243,12 +244,19 @@ public class GradeBatchPaperServiceImpl extends ServiceImpl<GradeBatchPaperMappe
             throw ExceptionResultEnum.ERROR.exception("机构id不存在");
         }
 
-        List<SysOrg> collegeList = null;
-//        List<SysOrg> collegeList = sysOrgService.findParentsByOrgId(orgId).stream().filter(e -> OrgTypeEnum.COLLEGE.equals(e.getType())).distinct().collect(Collectors.toList());
-//        if (collegeList.size() != 1) {
-//            throw ExceptionResultEnum.ERROR.exception("未找到开课学院");
-//        }
-        return collegeList.get(0);
+
+        List<SysOrg> orgList = sysOrgService.findParentsByOrgId(orgId).stream().distinct().collect(Collectors.toList());
+        List<SysOrg> schoolOrgList = orgList.stream().filter(e -> OrgTypeEnum.SCHOOL.equals(e.getType())).collect(Collectors.toList());
+        if (schoolOrgList.size() != 1){
+            throw ExceptionResultEnum.ERROR.exception("学校信息异常");
+        }
+        SysOrg schoolOrg = schoolOrgList.get(0);
+        Long schoolOrgId = schoolOrg.getId();
+        List<SysOrg> collegeOrgList = orgList.stream().filter(e -> schoolOrgId.equals(e.getParentId())).collect(Collectors.toList());;
+        if (collegeOrgList.size() != 1){
+            throw ExceptionResultEnum.ERROR.exception("开课学院异常");
+        }
+        return collegeOrgList.get(0);
     }
 
     @Transactional(rollbackFor = Exception.class)

+ 153 - 8
distributed-print-business/src/main/java/com/qmth/distributed/print/business/service/impl/PrintCommonServiceImpl.java

@@ -1,6 +1,7 @@
 package com.qmth.distributed.print.business.service.impl;
 
 import cn.hutool.core.date.DateUtil;
+import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.aliyun.oss.common.utils.BinaryUtil;
@@ -13,6 +14,8 @@ import com.itextpdf.text.pdf.PdfReader;
 import com.qmth.boot.api.exception.ApiException;
 import com.qmth.boot.tools.models.ByteArray;
 import com.qmth.distributed.print.business.bean.dto.PdfDto;
+import com.qmth.distributed.print.business.bean.dto.PdfPackageDto;
+import com.qmth.distributed.print.business.bean.dto.PdfSignDto;
 import com.qmth.distributed.print.business.bean.params.ExamTaskStudentObjectParam;
 import com.qmth.distributed.print.business.bean.params.SerialNumberParams;
 import com.qmth.distributed.print.business.entity.*;
@@ -20,6 +23,7 @@ import com.qmth.distributed.print.business.enums.ExamDetailStatusEnum;
 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.CreatePrintPdfUtil;
 import com.qmth.distributed.print.business.util.HtmlToPdfUtil;
 import com.qmth.distributed.print.business.util.PdfUtil;
 import com.qmth.teachcloud.common.bean.dto.MqDto;
@@ -144,6 +148,9 @@ public class PrintCommonServiceImpl implements PrintCommonService {
     @Resource
     BasicClazzService basicClazzService;
 
+    @Resource
+    CreatePrintPdfUtil createPrintPdfUtil;
+
     /**
      * 保存附件
      *
@@ -273,6 +280,79 @@ public class PrintCommonServiceImpl implements PrintCommonService {
         return basicAttachment;
     }
 
+    /**
+     * 保存附件
+     *
+     * @param examDetail
+     * @param pdfList
+     * @param printCount
+     */
+    @Override
+    @Transactional
+    public void saveAttachmentSignPdf(PdfSignDto pdfFillDto, ExamDetail examDetail, List<PdfDto> pdfList, Integer printCount) {
+        try {
+            boolean oss = dictionaryConfig.sysDomain().isOss();
+            LocalDateTime nowTime = LocalDateTime.now();
+            StringJoiner pdfStringJoiner = new StringJoiner("");
+            pdfStringJoiner.add(UploadFileEnum.PDF.getTitle()).add(File.separator);
+            pdfStringJoiner.add(String.valueOf(nowTime.getYear())).add(File.separator)
+                    .add(String.format("%02d", nowTime.getMonthValue())).add(File.separator)
+                    .add(String.format("%02d", nowTime.getDayOfMonth()));
+            pdfStringJoiner.add(File.separator).add(SystemConstant.getUuid()).add(SystemConstant.PDF_PREFIX);
+
+            String pdfDirName = pdfStringJoiner.toString();
+            String pdfDirNameStr = pdfStringJoiner.toString().replace("\\", "/");
+            String destUrl = dictionaryConfig.fssLocalPdfDomain().getConfig() + File.separator + pdfDirName;
+
+            createPrintPdfUtil.createSignPdf(null, pdfFillDto, destUrl, true);
+
+            File pdfFile = new File(destUrl);
+            if (!pdfFile.exists()) {
+                pdfFile.getParentFile().mkdirs();
+                pdfFile.createNewFile();
+            }
+            byte[] data = ByteArray.fromFile(pdfFile).value();
+            String md5 = ByteArray.md5(data).toHexString();
+            InputStream ins = new ByteArrayInputStream(data);
+            PdfDto pdfDto = PdfUtil.addPdfPage(pdfFile);
+            if (oss) {//上传至oss
+                fileStoreUtil.ossUpload(pdfDirNameStr, ins, md5, fileStoreUtil.getUploadEnumByPath(pdfDirNameStr).getFssType());
+                ins.close();
+            }
+            JSONObject attachmentPath = JSONObject.parseObject(examDetail.getAttachmentPath());
+            attachmentPath = Objects.isNull(attachmentPath) ? new JSONObject() : attachmentPath;
+            JSONArray jsonArray = (JSONArray) attachmentPath.get(SystemConstant.PATH);
+            jsonArray = Objects.isNull(jsonArray) ? new JSONArray() : jsonArray;
+            JSONObject object = new JSONObject();
+            object.put("printType", ClassifyEnum.SIGN.name());
+            object.put("pdfMd5", md5);
+            if (!oss) {
+                object.put(SystemConstant.PDF_PATH, pdfFile.getPath());
+                object.put(SystemConstant.TYPE, SystemConstant.LOCAL);
+            } else {
+                object.put(SystemConstant.PDF_PATH, pdfDirNameStr);
+                object.put(SystemConstant.TYPE, SystemConstant.OSS);
+            }
+            object.put(SystemConstant.UPLOAD_TYPE, new UploadFileEnum[]{
+                    UploadFileEnum.HTML,
+                    UploadFileEnum.PDF
+            });
+            jsonArray.add(object);
+            attachmentPath.put(SystemConstant.PATH, jsonArray);
+            examDetail.setAttachmentPath(attachmentPath.toJSONString());
+            for (int i = 0; i < printCount; i++) {
+                pdfList.add(new PdfDto(pdfFile.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());
+            }
+        }
+    }
+
     /**
      * 保存html附件
      *
@@ -563,7 +643,7 @@ public class PrintCommonServiceImpl implements PrintCommonService {
                 jsonObject.put(SystemConstant.TYPE, SystemConstant.OSS);
                 jsonObject.put(SystemConstant.PATH, dirName);
             } else {//上传至服务器
-                fileStoreUtil.localUpload(dirName,file.getInputStream(),md5,LocalCatalogEnum.LOCAL_FILE);
+                fileStoreUtil.localUpload(dirName, file.getInputStream(), md5, LocalCatalogEnum.LOCAL_FILE);
                 jsonObject.put(SystemConstant.TYPE, SystemConstant.LOCAL);
                 jsonObject.put(SystemConstant.PATH, dirName);
             }
@@ -1122,17 +1202,17 @@ public class PrintCommonServiceImpl implements PrintCommonService {
                 throw ExceptionResultEnum.ERROR.exception("行政班数据不一致");
             }
             BasicClazz basicClazz = null;
-            if (SystemConstant.longNotNull(basicClazzId)){
+            if (SystemConstant.longNotNull(basicClazzId)) {
                 basicClazz = basicClazzService.getById(basicClazzId);
-                if (Objects.isNull(basicClazz)){
+                if (Objects.isNull(basicClazz)) {
                     throw ExceptionResultEnum.ERROR.exception("未找到行政班");
                 }
             }
 
             TeachClazz teachClazz = null;
-            if (SystemConstant.longNotNull(teachClazzId)){
+            if (SystemConstant.longNotNull(teachClazzId)) {
                 teachClazz = teachClazzService.getById(teachClazzId);
-                if (Objects.isNull(teachClazz)){
+                if (Objects.isNull(teachClazz)) {
                     throw ExceptionResultEnum.ERROR.exception("未找到教学班");
                 }
             }
@@ -1151,12 +1231,12 @@ public class PrintCommonServiceImpl implements PrintCommonService {
             examStudent.setExtendFields(extendFields);
             examStudent.setCreateId(sysUser.getId());
             // 行政班数据
-            if (Objects.nonNull(basicClazz)){
+            if (Objects.nonNull(basicClazz)) {
                 examStudent.setClazzId(String.valueOf(basicClazz.getId()));
                 examStudent.setClazzName(basicClazz.getClazzName());
             }
             // 教学班模式 教学班数据
-            if (Objects.nonNull(teachClazz)){
+            if (Objects.nonNull(teachClazz)) {
                 examStudent.setTeachClazzId(teachClazz.getId());
                 examStudent.setTeachClazzName(teachClazz.getTeachClazzName());
             }
@@ -1200,7 +1280,7 @@ public class PrintCommonServiceImpl implements PrintCommonService {
                 fileStoreUtil.ossUpload(dirName, inputStream, DigestUtils.md5Hex(new ByteArrayInputStream(fos.toByteArray())), UploadFileEnum.FILE.getFssType());
                 jsonObject.put(SystemConstant.TYPE, SystemConstant.OSS);
             } else {
-                fileStoreUtil.copyInputStreamToFile(inputStream,new File(stringJoiner.toString()),DigestUtils.md5Hex(new ByteArrayInputStream(fos.toByteArray())),LocalCatalogEnum.LOCAL_FILE);
+                fileStoreUtil.copyInputStreamToFile(inputStream, new File(stringJoiner.toString()), DigestUtils.md5Hex(new ByteArrayInputStream(fos.toByteArray())), LocalCatalogEnum.LOCAL_FILE);
                 jsonObject.put(SystemConstant.TYPE, SystemConstant.LOCAL);
             }
             jsonObject.put(SystemConstant.PATH, dirName);
@@ -1256,4 +1336,69 @@ public class PrintCommonServiceImpl implements PrintCommonService {
             }
         }
     }
+
+    @Override
+    public void saveAttachmentPackagePdf(PdfPackageDto pdfPackageDto, ExamDetail examDetail, List<PdfDto> pdfList, Integer printCount) {
+        try {
+            boolean oss = dictionaryConfig.sysDomain().isOss();
+            LocalDateTime nowTime = LocalDateTime.now();
+            StringJoiner pdfStringJoiner = new StringJoiner("");
+            pdfStringJoiner.add(UploadFileEnum.PDF.getTitle()).add(File.separator);
+            pdfStringJoiner.add(String.valueOf(nowTime.getYear())).add(File.separator)
+                    .add(String.format("%02d", nowTime.getMonthValue())).add(File.separator)
+                    .add(String.format("%02d", nowTime.getDayOfMonth()));
+            pdfStringJoiner.add(File.separator).add(SystemConstant.getUuid()).add(SystemConstant.PDF_PREFIX);
+
+            String pdfDirName = pdfStringJoiner.toString();
+            String pdfDirNameStr = pdfStringJoiner.toString().replace("\\", "/");
+            String destUrl = dictionaryConfig.fssLocalPdfDomain().getConfig() + File.separator + pdfDirName;
+
+            createPrintPdfUtil.createPackagePdf(null, pdfPackageDto, destUrl, true);
+
+            File pdfFile = new File(destUrl);
+            if (!pdfFile.exists()) {
+                pdfFile.getParentFile().mkdirs();
+                pdfFile.createNewFile();
+            }
+            byte[] data = ByteArray.fromFile(pdfFile).value();
+            String md5 = ByteArray.md5(data).toHexString();
+            InputStream ins = new ByteArrayInputStream(data);
+            PdfDto pdfDto = PdfUtil.addPdfPage(pdfFile);
+            if (oss) {//上传至oss
+                fileStoreUtil.ossUpload(pdfDirNameStr, ins, md5, fileStoreUtil.getUploadEnumByPath(pdfDirNameStr).getFssType());
+                ins.close();
+            }
+            JSONObject attachmentPath = JSON.parseObject(examDetail.getAttachmentPath());
+            attachmentPath = Objects.isNull(attachmentPath) ? new JSONObject() : attachmentPath;
+            JSONArray jsonArray = (JSONArray) attachmentPath.get(SystemConstant.PATH);
+            jsonArray = Objects.isNull(jsonArray) ? new JSONArray() : jsonArray;
+            JSONObject object = new JSONObject();
+            object.put("printType", ClassifyEnum.PACKAGE.name());
+            object.put("pdfMd5", md5);
+            if (!oss) {
+                object.put(SystemConstant.PDF_PATH, pdfFile.getPath());
+                object.put(SystemConstant.TYPE, SystemConstant.LOCAL);
+            } else {
+                object.put(SystemConstant.PDF_PATH, pdfDirNameStr);
+                object.put(SystemConstant.TYPE, SystemConstant.OSS);
+            }
+            object.put(SystemConstant.UPLOAD_TYPE, new UploadFileEnum[]{
+                    UploadFileEnum.HTML,
+                    UploadFileEnum.PDF
+            });
+            jsonArray.add(object);
+            attachmentPath.put(SystemConstant.PATH, jsonArray);
+            examDetail.setAttachmentPath(attachmentPath.toJSONString());
+            for (int i = 0; i < printCount; i++) {
+                pdfList.add(new PdfDto(pdfFile.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());
+            }
+        }
+    }
 }

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

@@ -22,6 +22,7 @@ import com.qmth.distributed.print.business.enums.*;
 import com.qmth.distributed.print.business.service.*;
 import com.qmth.distributed.print.business.templete.service.TaskLogicService;
 import com.qmth.distributed.print.business.util.CreatePdfUtil;
+import com.qmth.distributed.print.business.util.CreatePrintPdfUtil;
 import com.qmth.distributed.print.business.util.HtmlToPdfUtil;
 import com.qmth.teachcloud.common.annotation.ExcelDBFieldDesc;
 import com.qmth.teachcloud.common.base.BaseEntity;
@@ -118,6 +119,9 @@ public class TaskLogicServiceImpl implements TaskLogicService {
     @Resource
     CreatePdfUtil createPdfUtil;
 
+    @Resource
+    CreatePrintPdfUtil createPrintPdfUtil;
+
     @Resource
     RedisTemplate<String, Object> redisTemplate;
 
@@ -452,19 +456,15 @@ public class TaskLogicServiceImpl implements TaskLogicService {
      * @param examPrintPlan
      * @param examDetail
      * @param basicSchool
-     * @param ftlList
      * @param examDetailCourseList
      * @param list
      * @throws IOException
      * @throws DocumentException
      */
     @Transactional
-    public void createA4File(ExamPrintPlan examPrintPlan, ExamDetail examDetail, BasicSchool basicSchool, Set<File> ftlList, List<ExamDetailCourse> examDetailCourseList, List<PdfDto>... list) throws Exception {
+    public void createA4File(ExamPrintPlan examPrintPlan, ExamDetail examDetail, BasicSchool basicSchool, List<ExamDetailCourse> examDetailCourseList, List<PdfDto>... list) throws Exception {
         // 印品
-        List<Long> examDetailCourseListIds = examDetailCourseList.stream().map(BaseEntity::getId).collect(Collectors.toList());
-
         String ordinaryContent = examPrintPlan.getOrdinaryContent();
-
         if (StringUtils.isNotBlank(ordinaryContent)) {
             //获取普通印品
             JSONArray jsonArrayOrdinary = JSONArray.parseArray(ordinaryContent);
@@ -479,8 +479,8 @@ public class TaskLogicServiceImpl implements TaskLogicService {
         }
 
         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);
             int count = (int) examStudentCourseDtoList.stream().filter(s -> s.getPaperPageA3() != null && s.getPaperPageA3() > 2).count();
             boolean tag = count > 0;
@@ -490,25 +490,18 @@ public class TaskLogicServiceImpl implements TaskLogicService {
             for (int i = 0; i < jsonArrayVariable.size(); i++) {
                 JSONObject jsonObjectVariable = jsonArrayVariable.getJSONObject(i);
                 String type = (String) jsonObjectVariable.get("type");
-                if (Objects.nonNull(jsonObjectVariable.get("attachmentId")) && !Objects.equals("", jsonObjectVariable.get("attachmentId"))) {
-                    Long attachmentId = Long.parseLong((String) jsonObjectVariable.get("attachmentId"));
-                    BasicAttachment basicAttachment = basicAttachmentService.getById(attachmentId);
-                    ftlList.add(teachcloudCommonService.getFile(basicAttachment.getPath(), false));
+                if (Objects.nonNull(jsonObjectVariable.get("templateId")) && !Objects.equals("", jsonObjectVariable.get("templateId"))) {
+                    Long templateId = Long.parseLong((String) jsonObjectVariable.get("templateId"));
                     if (Objects.nonNull(type) && Objects.equals(type.toUpperCase(), "SIGN")) {//签到表
-                        createPdfUtil.createSignBook(basicAttachment, basicSchool.getName(), examDetail, examStudentCourseDtoList, list[1], (Integer) jsonObjectVariable.get("backupCount"), examDetailCourseList);
+                        createPdfUtil.createSignBook(templateId, basicSchool.getName(), examDetail, examStudentCourseDtoList, list[1], (Integer) jsonObjectVariable.get("backupCount"), examDetailCourseList);
                     } else if (Objects.nonNull(type) && Objects.equals(type.toUpperCase(), "PACKAGE")) {//卷袋贴
-                        createPdfUtil.createPaperPackage(tag, basicAttachment, basicSchool.getName(), examDetail, examStudentCourseDtoList, list[1], (Integer) jsonObjectVariable.get("backupCount"), examDetailCourseList);
+                        createPdfUtil.createPaperPackage(templateId, basicSchool.getName(), examDetail, examStudentCourseDtoList, list[1], (Integer) jsonObjectVariable.get("backupCount"), examDetailCourseList);
                     }
                 }
             }
         }
 
-        Collections.sort(list[1], new Comparator<PdfDto>() {
-            @Override
-            public int compare(PdfDto o1, PdfDto o2) {
-                return o1.getSequence() > o2.getSequence() ? 1 : -1;
-            }
-        });
+        list[1].sort((o1, o2) -> o1.getSequence() > o2.getSequence() ? 1 : -1);
     }
 
     /**
@@ -587,7 +580,7 @@ public class TaskLogicServiceImpl implements TaskLogicService {
                         paperPdfList,
                         examStudentPdfList);
 
-                createA4File(examPrintPlan, examDetail, basicSchool, ftlList, examDetailCourseList, ordinaryPdfList, variablePdfList);
+                createA4File(examPrintPlan, examDetail, basicSchool, examDetailCourseList, ordinaryPdfList, variablePdfList);
 
                 //合并A3(试卷+题卡+备用试卷+备用题卡)
 //                String dirNameA3 = createPdfUtil.mergeA3Pdf(paperPdfList, examStudentPdfList, backupPaperPdfList, backupCardPdfList);

+ 218 - 6
distributed-print-business/src/main/java/com/qmth/distributed/print/business/util/CreatePdfUtil.java

@@ -2,6 +2,7 @@ package com.qmth.distributed.print.business.util;
 
 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.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
@@ -11,6 +12,7 @@ import com.qmth.distributed.print.business.cache.CreatePdfCacheUtil;
 import com.qmth.distributed.print.business.entity.*;
 import com.qmth.distributed.print.business.enums.ExamDetailStatusEnum;
 import com.qmth.distributed.print.business.enums.PrintMethodEnum;
+import com.qmth.distributed.print.business.service.BasicTemplateService;
 import com.qmth.distributed.print.business.service.ExamDetailService;
 import com.qmth.distributed.print.business.service.ExamStudentService;
 import com.qmth.distributed.print.business.service.PrintCommonService;
@@ -100,6 +102,9 @@ public class CreatePdfUtil {
     @Resource
     ExamStudentService examStudentService;
 
+    @Resource
+    BasicTemplateService basicTemplateService;
+
     @Resource
     DictionaryConfig dictionaryConfig;
 
@@ -276,6 +281,82 @@ public class CreatePdfUtil {
         freemarkerUtil.createPaperPackage(htmlMap);
     }
 
+    /**
+     * 生成卷袋贴
+     *
+     * @param schoolName
+     * @param examStudentList
+     * @param variablePdfList
+     * @param printCount
+     * @param examDetailCourseList
+     * @throws IOException
+     */
+    public void createPaperPackage(Long templateId, String schoolName, ExamDetail examDetail, List<ExamStudentCourseDto> examStudentList, List<PdfDto> variablePdfList, Integer printCount, List<ExamDetailCourse> examDetailCourseList) throws IOException {
+        BasicTemplate basicTemplate = basicTemplateService.getById(templateId);
+        if (Objects.isNull(basicTemplate)) {
+            throw ExceptionResultEnum.ERROR.exception("印品数据有误");
+        }
+
+        List<JSONObject> objectList = JSON.parseArray(basicTemplate.getDisplayRange(), JSONObject.class);
+
+        PdfPackageDto pdfPackageDto = new PdfPackageDto();
+        pdfPackageDto.setTitle(schoolName + "卷袋贴");
+        pdfPackageDto.setPackageNumber(examDetail.getPackageCode());
+
+        // 基础信息
+        List<Map<String, String>> basicPlate = new ArrayList<>();
+        for (JSONObject jsonObject : objectList) {
+            Map<String, String> basicMap = new HashMap<>();
+            if (jsonObject.getBoolean("enable")) {
+                String code = jsonObject.getString("code");
+                String name = jsonObject.getString("name");
+                basicMap.put("code", "courseCode");
+                basicMap.put("name", "课程代码");
+                if ("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);
+                    String examTime;
+                    if (startDate.equals(endDate)) {
+                        examTime = startDate + " " + startTime + "-" + endTime;
+                    } else {
+                        examTime = startDate + " " + startTime + "-" + endDate + " " + endTime;
+                    }
+                    basicMap.put("value", examTime);
+                } else if ("courseName".equals(code)) {
+                    List<String> courseNames = examDetailCourseList.stream().map(m -> String.format("s%(s%)", m.getCourseName(), m.getCourseCode())).collect(Collectors.toList());
+                    basicMap.put("value", String.join(",", courseNames));
+                } else if ("paperNumber".equals(code)) {
+                    List<String> paperNumbers = examDetailCourseList.stream().map(ExamDetailCourse::getPaperNumber).collect(Collectors.toList());
+                    basicMap.put("value", String.join(",", paperNumbers));
+                } else if ("examPlace".equals(code)) {
+                    basicMap.put("value", examDetail.getExamPlace());
+                } else if ("examRoom".equals(code)) {
+                    basicMap.put("value", examDetail.getExamRoom());
+                } else if ("collegeName".equals(code)) {
+                    Set<String> collegeNames = examStudentList.stream().map(ExamStudent::getCollegeName).collect(Collectors.toSet());
+                    basicMap.put("value", String.join(",", collegeNames));
+                } else if ("majorName".equals(code)) {
+                    Set<String> stringSet = new HashSet<>();
+                    Set<String> clazzNames = examStudentList.stream().filter(m -> StringUtils.isNotBlank(m.getClazzName())).map(ExamStudent::getClazzName).collect(Collectors.toSet());
+                    if (!clazzNames.isEmpty()) {
+                        stringSet.addAll(clazzNames);
+                    }
+                    Set<String> teachClazzNames = examStudentList.stream().filter(m -> StringUtils.isNotBlank(m.getTeachClazzName())).map(ExamStudent::getTeachClazzName).collect(Collectors.toSet());
+                    if (!teachClazzNames.isEmpty()) {
+                        stringSet.addAll(teachClazzNames);
+                    }
+                    basicMap.put("value", String.join(",", stringSet));
+                }
+                basicPlate.add(basicMap);
+
+            }
+        }
+        pdfPackageDto.setBasicPlate(basicPlate);
+        printCommonService.saveAttachmentPackagePdf(pdfPackageDto, examDetail, variablePdfList, printCount);
+    }
+
     /**
      * 创建签到表
      *
@@ -287,7 +368,9 @@ public class CreatePdfUtil {
      * @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 {
+    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();
         }
@@ -467,6 +550,128 @@ public class CreatePdfUtil {
         freemarkerUtil.createSignBook(htmlMap);
     }
 
+    /**
+     * 创建签到表
+     *
+     * @param templateId
+     * @param schoolName
+     * @param examDetail
+     * @param examStudentList
+     * @param variablePdfList
+     * @param printCount
+     * @param examDetailCourseList
+     */
+    public void createSignBook(Long templateId, String schoolName, ExamDetail
+            examDetail, List<ExamStudentCourseDto> examStudentList, List<PdfDto> variablePdfList, 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());
+
+        JSONObject jsonObject = JSON.parseObject(basicTemplate.getDisplayRange());
+        List<JSONObject> objectList = JSON.parseArray(jsonObject.getString("basic"), JSONObject.class);
+
+        // 基础信息
+        List<Map<String, String>> basicPlate = new ArrayList<>();
+        for (JSONObject object : objectList) {
+            if (!object.getBoolean("enable")) {
+                continue;
+            }
+            String code = object.getString("code");
+            String name = object.getString("name");
+            if ("courseName".equals(code)) {
+                List<String> courseNames = examDetailCourseList.stream().map(m -> String.format("s%(s%)", m.getCourseName(), m.getCourseCode())).collect(Collectors.toList());
+                Map<String, String> basicMap = new HashMap<>();
+                basicMap.put("code", code);
+                basicMap.put("name", name);
+                basicMap.put("value", String.join(",", 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(",", paperNumbers));
+                basicPlate.add(basicMap);
+            } else if ("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);
+                String examTime;
+                if (startDate.equals(endDate)) {
+                    examTime = startDate + " " + startTime + "-" + endTime;
+                } else {
+                    examTime = startDate + " " + startTime + "-" + endDate + " " + endTime;
+                }
+                Map<String, String> basicMap = new HashMap<>();
+                basicMap.put("code", code);
+                basicMap.put("name", name);
+                basicMap.put("value", examTime);
+                basicPlate.add(basicMap);
+            } else if ("examRoom".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 ("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);
+            }
+        }
+        pdfFillDto.setBasicPlate(basicPlate);
+
+        // 表头信息
+        List<JSONObject> tableList = JSON.parseArray(jsonObject.getString("table"), JSONObject.class);
+        Map<String, String> studentHeadPlateMap = new LinkedHashMap<>();
+        for (JSONObject object : tableList) {
+            if (object.getBoolean("enable")) {
+                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("studentName")) {
+                studentMap.put("studentName", examStudentCourseDto.getStudentName());
+            }
+            if (studentHeadPlateMap.containsKey("studentCode")) {
+                studentMap.put("studentCode", examStudentCourseDto.getStudentCode());
+            }
+            if (studentHeadPlateMap.containsKey("className")) {
+                studentMap.put("className", StringUtils.isBlank(examStudentCourseDto.getTeachClazzName()) ? examStudentCourseDto.getClazzName() : examStudentCourseDto.getClazzName());
+            }
+            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, variablePdfList, printCount);
+    }
+
     /**
      * 替换html通用模版中的条码信息
      *
@@ -552,7 +757,8 @@ public class CreatePdfUtil {
      * @param paperPdfDto  抽取的试卷文件信息
      * @param pdfList      考生试卷集合
      */
-    public PdfDto getExamStudentPaperPdf(String stuPaperType, List<PaperPdfDto> paperPdfDto, List<PdfDto> pdfList) throws IOException {
+    public PdfDto getExamStudentPaperPdf(String
+                                                 stuPaperType, List<PaperPdfDto> paperPdfDto, List<PdfDto> pdfList) throws IOException {
         Set<Integer> pagesList = new HashSet<>();
         if (!CollectionUtils.isEmpty(paperPdfDto)) {
             for (PaperPdfDto dto : paperPdfDto) {
@@ -577,7 +783,8 @@ public class CreatePdfUtil {
      * @param backupCount 备份数量
      * @param pdfList     备份试卷集合
      */
-    public PdfDto getPaperPdf(List<PaperPdfDto> paperPdfDto, Integer backupCount, List<PdfDto> pdfList) throws IOException {
+    public PdfDto getPaperPdf(List<PaperPdfDto> paperPdfDto, Integer backupCount, List<PdfDto> pdfList) throws
+            IOException {
         Set<Integer> pagesList = new HashSet<>();
         boolean tag = false;
         if (!CollectionUtils.isEmpty(paperPdfDto)) {
@@ -900,7 +1107,9 @@ public class CreatePdfUtil {
      * @param examStudentPdfList 考生题卡集合
      * @param basicCardRule      题卡规则
      */
-    public BasicAttachment examStudentHtml(String studentContent, ExamStudent examStudent, String paperType, ExamDetail examDetail, ExamDetailCourse examDetailCourse, Long userId, List<PdfDto> examStudentPdfList, BasicCardRule basicCardRule) throws IOException {
+    public BasicAttachment examStudentHtml(String studentContent, ExamStudent examStudent, String
+            paperType, ExamDetail examDetail, ExamDetailCourse examDetailCourse, Long
+                                                   userId, List<PdfDto> examStudentPdfList, BasicCardRule basicCardRule) throws IOException {
         String studentHtml = studentContent;
             /*if (Objects.nonNull(examStudent.getExtendFields())) {
                 JSONArray jsonObjectExtend = (JSONArray) JSONArray.parse(examStudent.getExtendFields());//扩展字段
@@ -955,7 +1164,8 @@ public class CreatePdfUtil {
      * @param examStudent   考生对象
      * @param basicCardRule 题卡规则对象
      */
-    private List<StudentExtendDto> createExtendObject(ExamDetail examDetail, ExamStudent examStudent, BasicCardRule 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;
@@ -1052,7 +1262,9 @@ public class CreatePdfUtil {
      * @param cardPdfList      备用题卡集合
      * @param basicCardRule    题卡规则对象
      */
-    public BasicAttachment cardHtml(String sequence, String cardContent, ExamDetail examDetail, ExamDetailCourse examDetailCourse, JSONArray jsonArray, Long userId, List<PdfDto> cardPdfList, BasicCardRule basicCardRule) throws IOException {
+    public BasicAttachment cardHtml(String sequence, String cardContent, ExamDetail examDetail, ExamDetailCourse
+            examDetailCourse, JSONArray jsonArray, Long userId, List<PdfDto> cardPdfList, BasicCardRule basicCardRule) throws
+            IOException {
         //通用题卡
         String cardTemp = cardContent;
         cardTemp = cardTemp.replaceAll("\\$\\{paperTypeName\\}", examDetailCourse.getPaperType());

+ 462 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/util/CreatePrintPdfUtil.java

@@ -0,0 +1,462 @@
+package com.qmth.distributed.print.business.util;
+
+import com.itextpdf.text.*;
+import com.itextpdf.text.pdf.*;
+import com.qmth.distributed.print.business.bean.dto.ExamStudentCourseDto;
+import com.qmth.distributed.print.business.bean.dto.PdfDto;
+import com.qmth.distributed.print.business.bean.dto.PdfPackageDto;
+import com.qmth.distributed.print.business.bean.dto.PdfSignDto;
+import com.qmth.distributed.print.business.entity.ExamDetail;
+import com.qmth.distributed.print.business.entity.ExamDetailCourse;
+import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
+import com.qmth.teachcloud.common.util.ConvertUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.ByteArrayOutputStream;
+import java.util.List;
+import java.util.*;
+
+/**
+ * pdf模板内容填充
+ */
+@Component
+public class CreatePrintPdfUtil {
+    private static final Logger log = LoggerFactory.getLogger(CreatePrintPdfUtil.class);
+
+    /**
+     * 签到表生成
+     *
+     * @param response     response
+     * @param pdfFillDto   签到表数据
+     * @param destFileName 文件名
+     * @param saveLocal    是事保存本地文件
+     */
+    public void createSignPdf(HttpServletResponse response, PdfSignDto pdfFillDto, String destFileName, boolean saveLocal) throws Exception {
+
+        // 1:建立Document对象实例
+        Document document = new Document(PageSize.A4, 36.0F, 36.0F, 40F, 36.0F);
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        try {
+            // 2:建立一个PDF 写入器与document对象关联通过书写器(Writer)可以将文档写入到磁盘中
+            PdfWriter pdfWriter = PdfWriter.getInstance(document, baos);
+
+            //3、设置pdf页眉和页脚和水印
+            MyHeaderFooter headerFooter = new MyHeaderFooter();
+            pdfWriter.setPageEvent(headerFooter);
+
+            // 3:打开文档
+            document.open();
+            //生成pdf
+            this.generateSignPDF(document, pdfWriter, pdfFillDto);
+            // 5:关闭文档
+            document.close();
+        } catch (DocumentException e) {
+            e.printStackTrace();
+        }
+        if (saveLocal) {
+            PdfFillUtils.saveFile(baos, destFileName);
+        } else {
+            ConvertUtil.outputFile(response, baos, destFileName);
+        }
+    }
+
+    /**
+     * 卷袋贴生成
+     *
+     * @param response      response
+     * @param pdfPackageDto 卷袋贴参数
+     * @param destFileName  保存文件名
+     * @param saveLocal     是否保存本地
+     */
+    public void createPackagePdf(HttpServletResponse response, PdfPackageDto pdfPackageDto, String destFileName, boolean saveLocal) throws Exception {
+
+        // 1:建立Document对象实例
+        Document document = new Document(PageSize.A4, 36.0F, 36.0F, 40F, 36.0F);
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        try {
+            // 2:建立一个PDF 写入器与document对象关联通过书写器(Writer)可以将文档写入到磁盘中
+            PdfWriter pdfWriter = PdfWriter.getInstance(document, baos);
+            // 3:打开文档
+            document.open();
+            //生成pdf
+            this.generatePackagePDF(document, pdfWriter, pdfPackageDto);
+            // 5:关闭文档
+            document.close();
+        } catch (DocumentException e) {
+            e.printStackTrace();
+        }
+        if (saveLocal) {
+            PdfFillUtils.saveFile(baos, destFileName);
+        } else {
+            ConvertUtil.outputFile(response, baos, destFileName);
+        }
+    }
+
+    /**
+     * 生成签到表pdf文件
+     *
+     * @param document   document
+     * @param pdfWriter  pdfWriter
+     * @param pdfFillDto 签到表数据
+     */
+    private void generateSignPDF(Document document, PdfWriter pdfWriter, PdfSignDto pdfFillDto) throws DocumentException {
+        // 空格
+        Paragraph blank = new Paragraph(" ");
+        // 标题table
+        PdfPTable titleTable = PdfFillUtils.createTable(new float[]{33, 34, 33});
+        titleTable.addCell(PdfFillUtils.createCell("", null, null, 50f, Element.ALIGN_CENTER, 15, 3, 1));
+        titleTable.addCell(PdfFillUtils.createCell(pdfFillDto.getTitle(), PdfFillUtils.textFont18, null, 50f, Element.ALIGN_CENTER, 15, 3, 1));
+        // 条码
+        Image code128Image = PdfFillUtils.createBarcode(pdfWriter, pdfFillDto.getPackageNumber(), false, null, null);
+        code128Image.scalePercent(100);
+        titleTable.addCell(PdfFillUtils.createCell(code128Image, 50f, 15, 3));
+        document.add(titleTable);
+
+
+        // 基础信息表格
+        PdfPTable basicTable = PdfFillUtils.createTable(6);
+        List<Map<String, String>> basicPlate = pdfFillDto.getBasicPlate();
+        for (Map<String, String> stringMap : basicPlate) {
+            basicTable.addCell(PdfFillUtils.createCell(stringMap.get("name") + ":" + stringMap.get("value"), PdfFillUtils.textFont12, null, 16f, Element.ALIGN_LEFT, 0, 1, 3));
+        }
+        document.add(basicTable);
+
+        document.add(blank);
+
+        //表头
+        Map<String, String> studentHeadPlate = pdfFillDto.getStudentHeadPlate();
+        //计算表格宽度
+        float[] columnWidth = chooseColumnWidth(studentHeadPlate.size());
+        int columnCount = studentHeadPlate.size();
+
+        PdfPTable studentTable = PdfFillUtils.createTable(columnWidth);
+        String[] headKeys = new String[columnCount * 2];
+
+        for (int i = 0; i < 2; i++) {
+            int j = 0;
+            for (Map.Entry<String, String> entry : studentHeadPlate.entrySet()) {
+                headKeys[columnCount * i + j] = entry.getKey();
+                studentTable.addCell(PdfFillUtils.createCell(entry.getValue(), PdfFillUtils.textFont12, BaseColor.GRAY, 16f, Element.ALIGN_CENTER, 0, 1, 1));
+                j++;
+            }
+        }
+
+        //数据
+        List<Map<String, String>> studentPlate = pdfFillDto.getStudentPlate();
+        int studentPlateCount = studentPlate.size();
+        int forCount = studentPlateCount % 2 == 0 ? studentPlateCount / 2 : studentPlateCount / 2 + 1;
+
+        for (int i = 0; i < forCount; i++) {
+            Map<String, String> stringMap1 = studentPlate.get(2 * i);
+            for (int j = 0; j < stringMap1.size(); j++) {
+                String value = stringMap1.get(headKeys[j]);
+                studentTable.addCell(PdfFillUtils.createCell(value, chooseFont(value, columnWidth[j]), null, 0, Element.ALIGN_CENTER, 0, 1, 1));
+            }
+
+            if (studentPlateCount % 2 > 0 && 2 * i + 1 == studentPlate.size()) {
+                for (int i1 = 0; i1 < columnCount; i1++) {
+                    studentTable.addCell(PdfFillUtils.createCell("", PdfFillUtils.textFont12, null, 0, Element.ALIGN_CENTER, 0, 1, 1));
+                }
+                continue;
+            }
+            Map<String, String> stringMap2 = studentPlate.get(2 * i + 1);
+            for (int j = 0; j < stringMap2.size(); j++) {
+                String value = stringMap2.get(headKeys[j + columnCount]);
+                studentTable.addCell(PdfFillUtils.createCell(value, chooseFont(value, columnWidth[j + columnCount]), null, 0, Element.ALIGN_CENTER, 0, 1, 1));
+            }
+        }
+        document.add(studentTable);
+
+        document.add(blank);
+
+        Paragraph pDate = new Paragraph(" 年        月        日", PdfFillUtils.textFont12);
+        pDate.setAlignment(Element.ALIGN_RIGHT);
+        pDate.setIndentationRight(20);
+
+        PdfPTable signTable = new PdfPTable(4);
+        signTable.setWidthPercentage(100);// 表格宽度为100%
+        // 备注
+        PdfPCell cell34 = new PdfPCell();
+        cell34.setBorderWidth(0.5F);
+        cell34.setMinimumHeight(20);
+        cell34.setPhrase(new Paragraph("监考老师签名处", PdfFillUtils.textFont12));
+        cell34.setVerticalAlignment(Element.ALIGN_MIDDLE);
+        cell34.setHorizontalAlignment(Element.ALIGN_CENTER);
+        signTable.addCell(cell34);
+        PdfPCell cell35 = new PdfPCell();
+        cell35.setBorderWidth(0.5F);
+        cell35.setColspan(3);
+        cell35.addElement(blank);
+        cell35.addElement(pDate);
+        cell35.addElement(blank);
+        signTable.addCell(cell35);
+
+        try {
+            document.add(signTable);
+        } catch (DocumentException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 卷袋贴生成方法
+     *
+     * @param document      document
+     * @param pdfWriter     pdfWriter
+     * @param pdfPackageDto 卷袋贴数据
+     */
+    private void generatePackagePDF(Document document, PdfWriter pdfWriter, PdfPackageDto pdfPackageDto) {
+        try {
+            // 空格
+            Paragraph blank = new Paragraph(" ");
+            // 标题table
+            PdfPTable titleTable = PdfFillUtils.createTable(new float[]{33, 34, 33});
+            titleTable.addCell(PdfFillUtils.createCell("", null, null, 50f, Element.ALIGN_CENTER, 15, 3, 1));
+            titleTable.addCell(PdfFillUtils.createCell(pdfPackageDto.getTitle(), PdfFillUtils.textFont28, null, 50f, Element.ALIGN_CENTER, 15, 3, 1));
+            // 条码
+            Image code128Image = PdfFillUtils.createBarcode(pdfWriter, pdfPackageDto.getPackageNumber(), false, null, null);
+            code128Image.scalePercent(100);
+            titleTable.addCell(PdfFillUtils.createCell(code128Image, 50f, 15, 3));
+            document.add(titleTable);
+
+            document.add(blank);
+
+            // 基础信息表格
+            PdfPTable basicTable = PdfFillUtils.createTable(1);
+            List<Map<String, String>> basicPlate = pdfPackageDto.getBasicPlate();
+            for (Map<String, String> stringMap : basicPlate) {
+                basicTable.addCell(PdfFillUtils.createCell(stringMap.get("name") + ":" + stringMap.get("value"), PdfFillUtils.textFont24, 50f, Element.ALIGN_LEFT, 20f));
+                document.add(blank);
+            }
+            document.add(basicTable);
+            document.add(blank);
+        } catch (DocumentException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 签到表考生签到table表头宽度选择
+     *
+     * @param size 表头字段数量
+     */
+    private float[] chooseColumnWidth(int size) {
+        float[] columnWidth;
+        if (size == 1) {
+            columnWidth = new float[]{50, 50};
+        } else if (size == 2) {
+            columnWidth = new float[]{20, 30, 20, 30};
+        } else if (size == 3) {
+            columnWidth = new float[]{10, 25, 25, 10, 25, 25};
+        } else if (size == 4) {
+            columnWidth = new float[]{6, 12, 16, 16, 6, 12, 16, 16};
+        } else if (size == 5) {
+            columnWidth = new float[]{6, 10, 11, 12, 11, 6, 10, 11, 12, 11};
+        } else if (size == 6) {
+            columnWidth = new float[]{6, 9, 9, 9, 9, 8, 6, 9, 9, 9, 9, 8};
+        } else {
+            throw ExceptionResultEnum.ERROR.exception("签到表最多只能显示6个信息");
+        }
+        return columnWidth;
+    }
+
+    /**
+     * 根据表格大小,选择字号
+     *
+     * @param value   值
+     * @param percent 宽度
+     */
+    private Font chooseFont(String value, float percent) {
+        if (value.length() < percent) {
+            return PdfFillUtils.textFont12;
+        } else if (value.length() >= percent && value.length() < 1.5 * percent) {
+            return PdfFillUtils.textFont10;
+        } else if (value.length() >= 1.5 * percent && value.length() < 2 * percent) {
+            return PdfFillUtils.textFont9;
+        }
+        return PdfFillUtils.textFont8;
+    }
+
+    /**
+     * 内部类
+     * 添加页眉、页脚
+     */
+    public static class MyHeaderFooter extends PdfPageEventHelper {
+        // 总页数
+        PdfTemplate totalPage;
+
+        // 打开文档时,创建一个总页数的模版
+        @Override
+        public void onOpenDocument(PdfWriter writer, Document document) {
+            PdfContentByte cb = writer.getDirectContent();
+            totalPage = cb.createTemplate(30, 16);
+        }
+
+        // 一页加载完成触发,写入页眉和页脚
+        @Override
+        public void onEndPage(PdfWriter writer, Document document) {
+            PdfPTable table = new PdfPTable(3);
+            try {
+                table.setTotalWidth(PageSize.A4.getWidth() - 80);
+                table.setWidths(new int[]{24, 24, 3});
+                table.setLockedWidth(true);
+                table.getDefaultCell().setFixedHeight(-10);
+                table.getDefaultCell().setBorder(Rectangle.BOTTOM);
+                table.getDefaultCell().setBorderWidth(0.5f);
+
+                table.addCell(new Paragraph("", PdfFillUtils.textFont8));// 可以直接使用addCell(str),不过不能指定字体,中文无法显示
+                table.getDefaultCell().setHorizontalAlignment(Element.ALIGN_RIGHT);
+                table.addCell(new Paragraph("第" + writer.getPageNumber() + "页   /", PdfFillUtils.textFont8));
+                // 总页数
+                PdfPCell cell = new PdfPCell(Image.getInstance(totalPage));
+                cell.setBorder(Rectangle.BOTTOM);
+                table.addCell(cell);
+                // 将页眉写到document中,位置可以指定,指定到下面就是页脚
+                // 页眉
+                table.writeSelectedRows(0, -1, 40, PageSize.A4.getHeight() - 20, writer.getDirectContent());
+                // 页脚
+//                table.writeSelectedRows(0, -1, 40, 40, writer.getDirectContent());
+            } catch (Exception de) {
+                throw new ExceptionConverter(de);
+            }
+        }
+
+        // 全部完成后,将总页数的pdf模版写到指定位置
+        @Override
+        public void onCloseDocument(PdfWriter writer, Document document) {
+            String text = "共" + (writer.getPageNumber()) + "页";
+            ColumnText.showTextAligned(totalPage, Element.ALIGN_LEFT, new Paragraph(text, PdfFillUtils.textFont8), 2, 6, 0);
+        }
+    }
+
+
+    /**
+     * 测试方法
+     *
+     * @param args
+     */
+    public static void main(String[] args) {
+        PdfSignDto pdfFillDto = new PdfSignDto();
+        pdfFillDto.setTitle("测试签到表");
+        pdfFillDto.setPackageNumber("200032324");
+
+        // 基础信息
+        List<Map<String, String>> basicPlate = new ArrayList<>();
+        Map<String, String> basicMap = new HashMap<>();
+        basicMap.put("code", "courseCode");
+        basicMap.put("name", "课程代码");
+        basicMap.put("value", "高等数学");
+        basicPlate.add(basicMap);
+
+        basicMap = new HashMap<>();
+        basicMap.put("code", "paperNumber");
+        basicMap.put("name", "试卷编号");
+        basicMap.put("value", "bh001");
+        basicPlate.add(basicMap);
+
+        basicMap = new HashMap<>();
+        basicMap.put("code", "examTime");
+        basicMap.put("name", "考试时间");
+        basicMap.put("value", "2022-09-10 9:00-12:00");
+        basicPlate.add(basicMap);
+
+        basicMap = new HashMap<>();
+        basicMap.put("code", "examRoom");
+        basicMap.put("name", "考试地点");
+        basicMap.put("value", "教学楼301");
+        basicPlate.add(basicMap);
+
+        basicMap = new HashMap<>();
+        basicMap.put("code", "examCount");
+        basicMap.put("name", "应考人数");
+        basicMap.put("value", "61");
+        basicPlate.add(basicMap);
+
+        basicMap = new HashMap<>();
+        basicMap.put("code", "actualExamCount");
+        basicMap.put("name", "实考人数");
+        basicMap.put("value", "");
+        basicPlate.add(basicMap);
+
+        pdfFillDto.setBasicPlate(basicPlate);
+
+        // 表头信息
+        Map<String, String> studentHeadPlateMap = new LinkedHashMap<>();
+        studentHeadPlateMap.put("seq", "序号");
+        studentHeadPlateMap.put("studentCode", "学号");
+        studentHeadPlateMap.put("studentName", "姓名");
+        studentHeadPlateMap.put("className", "班级");
+        studentHeadPlateMap.put("studentSign", "签名");
+        pdfFillDto.setStudentHeadPlate(studentHeadPlateMap);
+
+        // 考生信息
+        List<Map<String, String>> studentPlate = new ArrayList<>();
+        for (int i = 0; i < 61; i++) {
+            Map<String, String> studentMap = new HashMap<>();
+            String seq = String.valueOf(i + 1);
+            studentMap.put("seq", seq);
+            studentMap.put("studentCode", "20010" + String.format("%03d", i + 1));
+            if (i > 10 && i < 20) {
+                studentMap.put("studentName", "学生" + String.format("%06d", i + 1));
+            } else if (i > 34 && i < 50) {
+                studentMap.put("studentName", "学生" + String.format("%010d", i + 1));
+            } else {
+                studentMap.put("studentName", "学生" + seq);
+            }
+            studentMap.put("className", "班级1");
+            studentMap.put("studentSign", "");
+            studentPlate.add(studentMap);
+        }
+        pdfFillDto.setStudentPlate(studentPlate);
+
+        PdfPackageDto pdfPackageDto = new PdfPackageDto();
+        pdfPackageDto.setTitle("测试卷袋贴");
+        pdfPackageDto.setPackageNumber("20000213134");
+
+        // 基础信息
+        List<Map<String, String>> basicPlate1 = new ArrayList<>();
+        Map<String, String> basicMap1 = new HashMap<>();
+        basicMap1.put("code", "courseCode");
+        basicMap1.put("name", "课程代码");
+        basicMap1.put("value", "高等数学");
+        basicPlate1.add(basicMap1);
+
+        basicMap1 = new HashMap<>();
+        basicMap1.put("code", "paperNumber");
+        basicMap1.put("name", "试卷编号");
+        basicMap1.put("value", "bh001");
+        basicPlate1.add(basicMap1);
+
+        basicMap1 = new HashMap<>();
+        basicMap1.put("code", "examTime");
+        basicMap1.put("name", "考试时间");
+        basicMap1.put("value", "2022-09-10 9:00-12:00");
+        basicPlate1.add(basicMap1);
+
+        basicMap1 = new HashMap<>();
+        basicMap1.put("code", "examRoom");
+        basicMap1.put("name", "考试地点");
+        basicMap1.put("value", "教学楼301");
+        basicPlate1.add(basicMap1);
+
+        basicMap1 = new HashMap<>();
+        basicMap1.put("code", "examCount");
+        basicMap1.put("name", "应考人数");
+        basicMap1.put("value", "61");
+        basicPlate1.add(basicMap1);
+
+        pdfPackageDto.setBasicPlate(basicPlate1);
+
+        try {
+            CreatePrintPdfUtil createPrintPdfUtil = new CreatePrintPdfUtil();
+            createPrintPdfUtil.createSignPdf(null, pdfFillDto, "D:/sign.pdf", true);
+            createPrintPdfUtil.createPackagePdf(null, pdfPackageDto, "D:/package.pdf", true);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+}

+ 307 - 0
distributed-print-business/src/main/java/com/qmth/distributed/print/business/util/PdfFillUtils.java

@@ -0,0 +1,307 @@
+package com.qmth.distributed.print.business.util;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.itextpdf.awt.AsianFontMapper;
+import com.itextpdf.text.*;
+import com.itextpdf.text.pdf.*;
+import com.qmth.distributed.print.business.bean.dto.PdfPackageDto;
+import com.qmth.distributed.print.business.bean.dto.PdfSignDto;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.*;
+import java.net.URLEncoder;
+import java.util.List;
+import java.util.*;
+
+/**
+ * pdf模板内容填充
+ */
+public class PdfFillUtils {
+    private final static Logger log = LoggerFactory.getLogger(PdfFillUtils.class);
+
+    // 定义全局的字体静态变量
+    public static Font textFont28;
+    public static Font textFont24;
+    public static Font textFont18;
+    public static Font textFont12;
+    public static Font textFont11;
+    public static Font textFont10;
+    public static Font textFont9;
+    public static Font textFont8;
+
+    // 静态代码块
+    static {
+        try {
+            //解决中文不显示问题
+            BaseFont bfChinese = BaseFont.createFont(AsianFontMapper.ChineseSimplifiedFont, AsianFontMapper.ChineseSimplifiedEncoding_H, BaseFont.NOT_EMBEDDED);
+            textFont28 = new Font(bfChinese, 28);
+            textFont24 = new Font(bfChinese, 24);
+            textFont18 = new Font(bfChinese, 18);
+            textFont12 = new Font(bfChinese, 12);
+            textFont11 = new Font(bfChinese, 11);
+            textFont10 = new Font(bfChinese, 10);
+            textFont9 = new Font(bfChinese, 9);
+            textFont8 = new Font(bfChinese, 8);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public static void saveFile(ByteArrayOutputStream baos, String fileName) {
+        FileOutputStream fileOutputStream = null;
+        try {
+            fileOutputStream = new FileOutputStream(fileName);
+            fileOutputStream.write(baos.toByteArray());
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        } finally {
+            try {
+                fileOutputStream.close();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    /**
+     * 填充table
+     *
+     * @param value       cell内容
+     * @param font        字体
+     * @param cellColor   背景色
+     * @param fixedHeight 垂直对齐方式
+     */
+    public static PdfPCell createCell(String value, Font font, BaseColor cellColor, float fixedHeight, int horizontalAlignment, int disableBorderSide, int rowspan, int colspan) {
+        PdfPCell cell = new PdfPCell();
+        cell.setBorderWidth(0.1F);
+        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
+        cell.setHorizontalAlignment(horizontalAlignment);
+        cell.setUseAscender(true);
+        if (font != null) {
+            cell.setPhrase(new Phrase(value, font));
+        } else {
+            cell.setPhrase(new Phrase(value));
+        }
+        if (cellColor != null) {
+            cell.setBackgroundColor(cellColor);
+        }
+        if (fixedHeight > 0) {
+            cell.setFixedHeight(fixedHeight);
+        }
+        if (disableBorderSide > 0) {
+            cell.disableBorderSide(disableBorderSide);
+        }
+        if (rowspan > 0) {
+            cell.setRowspan(rowspan);
+        }
+        if (colspan > 0) {
+            cell.setColspan(colspan);
+        }
+        return cell;
+    }
+
+    /**
+     * 填充table
+     *
+     * @param value       cell内容
+     * @param font        字体
+     * @param fixedHeight 垂直对齐方式
+     */
+    public static PdfPCell createCell(String value, Font font, float fixedHeight, int horizontalAlignment, float paddingLeft) {
+        PdfPCell cell = new PdfPCell();
+        cell.setBorderWidth(0.1F);
+        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
+        cell.setHorizontalAlignment(horizontalAlignment);
+        cell.setUseAscender(true);
+        if (font != null) {
+            cell.setPhrase(new Phrase(value, font));
+        } else {
+            cell.setPhrase(new Phrase(value));
+        }
+        if (fixedHeight > 0) {
+            cell.setFixedHeight(fixedHeight);
+        }
+        cell.disableBorderSide(15);
+        if (paddingLeft > 0) {
+            cell.setPaddingLeft(paddingLeft);
+        }
+        return cell;
+    }
+
+    /**
+     * 填充table
+     *
+     * @param image       cell内容
+     * @param fixedHeight 垂直对齐方式
+     */
+    public static PdfPCell createCell(Image image, float fixedHeight, int disableBorderSide, int rowspan) {
+        PdfPCell cell = new PdfPCell(image);
+        cell.setBorderWidth(0.1F);
+        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
+        cell.setUseAscender(true);
+        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
+//        cell.setExtraParagraphSpace(10);
+        if (fixedHeight > 0) {
+            cell.setFixedHeight(fixedHeight);
+        }
+        if (disableBorderSide > 0) {
+            cell.disableBorderSide(disableBorderSide);
+        }
+        if (rowspan > 0) {
+            cell.setRowspan(rowspan);
+        }
+        return cell;
+    }
+
+    /**
+     * 创建指定列宽、列数的表格
+     *
+     * @param columns 单元格数量
+     */
+    public static PdfPTable createTable(int columns) {
+        PdfPTable table = new PdfPTable(columns);
+        try {
+            table.setWidthPercentage(100);// 表格宽度为100%
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return table;
+    }
+
+    /**
+     * 创建指定列宽、列数的表格
+     *
+     * @param widths 宽度
+     */
+    public static PdfPTable createTable(float[] widths) {
+        PdfPTable table = new PdfPTable(widths.length);
+        try {
+            table.setTotalWidth(widths);
+            table.setWidthPercentage(100);// 表格宽度为100%
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return table;
+    }
+
+    /**
+     * 创建条形码
+     *
+     * @param writer   writer
+     * @param barCode  条形码(数字)
+     * @param hideCode 是否隐藏条形码(数字)
+     */
+    public static Image createBarcode(PdfWriter writer, String barCode, Boolean hideCode, BaseColor barColor, BaseColor textColor) {
+        Barcode128 barcode128 = new Barcode128();
+        barcode128.setCode(barCode);//设置数字
+        barcode128.setCodeType(Barcode.CODE128);
+        //设置字体
+        if (hideCode) {
+            barcode128.setFont(null);
+        }
+        return barcode128.createImageWithBarcode(writer.getDirectContent(), barColor, textColor);
+    }
+
+
+    /**
+     * 卷袋贴临时数据
+     *
+     * @param data data
+     */
+    public static void packageTempData(HttpServletResponse response, String data, String fileName) {
+        PdfPackageDto pdfPackageDto = new PdfPackageDto();
+        pdfPackageDto.setTitle("测试卷袋贴");
+        pdfPackageDto.setPackageNumber("20000213134");
+
+        List<JSONObject> basicObjectList = JSON.parseArray(data, JSONObject.class);
+        // 基础信息
+        List<Map<String, String>> basicPlate = new ArrayList<>();
+        for (JSONObject object : basicObjectList) {
+            Map<String, String> basicMap = new HashMap<>();
+            basicMap.put("code", object.getString("code"));
+            basicMap.put("name", object.getString("name"));
+            basicMap.put("value", "XXXXXX");
+            basicPlate.add(basicMap);
+        }
+        pdfPackageDto.setBasicPlate(basicPlate);
+
+        try {
+            CreatePrintPdfUtil createPrintPdfUtil = new CreatePrintPdfUtil();
+            createPrintPdfUtil.createPackagePdf(response, pdfPackageDto, fileName, false);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 签到表预览数据
+     *
+     * @param response response
+     * @param data     数据内容
+     * @param fileName 文件名
+     */
+    public static void parseSignTempData(HttpServletResponse response, String data, String fileName) {
+        PdfSignDto pdfFillDto = new PdfSignDto();
+        pdfFillDto.setTitle("XXXXX签到表");
+        pdfFillDto.setPackageNumber("123456789");
+
+        JSONObject jsonObject = JSON.parseObject(data);
+        // 基础信息
+        List<Map<String, String>> basicPlate = new ArrayList<>();
+        String basicData = jsonObject.getString("basic");
+        List<JSONObject> basicObjectList = JSON.parseArray(basicData, JSONObject.class);
+        Map<String, String> basicMap;
+        for (JSONObject object : basicObjectList) {
+            basicMap = new HashMap<>();
+            basicMap.put("code", object.getString("code"));
+            basicMap.put("name", object.getString("name"));
+            basicMap.put("value", "XXXXXX");
+            basicPlate.add(basicMap);
+        }
+        basicMap = new HashMap<>();
+        basicMap.put("code", "actualExamCount");
+        basicMap.put("name", "实考人数");
+        basicMap.put("value", "");
+        basicPlate.add(basicMap);
+
+        pdfFillDto.setBasicPlate(basicPlate);
+
+        // 表头信息
+        String studentData = jsonObject.getString("table");
+        List<JSONObject> studentObjectList = JSON.parseArray(studentData, JSONObject.class);
+        Map<String, String> studentHeadPlateMap = new LinkedHashMap<>();
+        for (JSONObject object : studentObjectList) {
+            studentHeadPlateMap.put(object.getString("code"), object.getString("name"));
+            studentHeadPlateMap.put("studentCode", "学号");
+            studentHeadPlateMap.put("studentName", "姓名");
+            studentHeadPlateMap.put("className", "班级");
+        }
+        studentHeadPlateMap.put("studentSign", "签名");
+        pdfFillDto.setStudentHeadPlate(studentHeadPlateMap);
+
+
+        // 考生信息
+        List<Map<String, String>> studentPlate = new ArrayList<>();
+        for (int i = 0; i < 55; i++) {
+            Map<String, String> studentMap = new HashMap<>();
+            for (JSONObject object : studentObjectList) {
+                studentMap.put(object.getString("code"), "XXXXXX");
+            }
+            studentMap.put("studentSign", "");
+            studentPlate.add(studentMap);
+        }
+        pdfFillDto.setStudentPlate(studentPlate);
+        try {
+            CreatePrintPdfUtil createPrintPdfUtil = new CreatePrintPdfUtil();
+            createPrintPdfUtil.createSignPdf(response, pdfFillDto, fileName, false);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+}

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

@@ -55,6 +55,7 @@
             exam_paper_structure eps ON edc.school_id = eps.school_id
                 AND edc.paper_number = eps.paper_number
                 AND edc.course_code = eps.course_code
+                AND es.paper_type = eps.paper_type
         WHERE
             epp.school_id = #{schoolId}
             and et.user_id = #{propositionTeacherId}

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

@@ -87,7 +87,10 @@
         edc.paper_pages_a3 as paperPageA3,
         edc.paper_number as paperNumber,
         es.clazz_id clazzId,
-        es.clazz_name clazzName
+        es.clazz_name clazzName,
+        es.college_name collegeName,
+        es.major_name majorName,
+        es.student_clazz_type studentClazzType
         from
         exam_student es
         left join exam_detail_course edc on

+ 10 - 0
distributed-print/src/main/java/com/qmth/distributed/print/api/BasicTemplateController.java

@@ -7,6 +7,7 @@ import com.qmth.distributed.print.business.bean.dto.TemplateDto;
 import com.qmth.distributed.print.business.entity.BasicTemplate;
 import com.qmth.distributed.print.business.service.BasicTemplateService;
 import com.qmth.teachcloud.common.contant.SystemConstant;
+import com.qmth.teachcloud.common.enums.ClassifyEnum;
 import com.qmth.teachcloud.common.util.Result;
 import com.qmth.teachcloud.common.util.ResultUtil;
 import io.swagger.annotations.Api;
@@ -15,6 +16,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
+import javax.servlet.http.HttpServletResponse;
 import javax.validation.constraints.Max;
 import javax.validation.constraints.Min;
 
@@ -112,5 +114,13 @@ public class BasicTemplateController {
         Object content = basicTemplateService.readContent(attachmentId);
         return ResultUtil.ok(content);
     }
+
+    @ApiOperation(value = "预览")
+    @RequestMapping(value = "/preview", method = RequestMethod.POST)
+    public void preview(HttpServletResponse response,
+                        @RequestBody String data) {
+        basicTemplateService.preview(response, data);
+    }
+
 }
 

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

@@ -153,8 +153,13 @@ public class ExamPaperStructureController {
     @ApiResponses({@ApiResponse(code = 200, message = "查询成功", response = Result.class)})
     public Result findCardJpgFileByPaperNumber(@ApiParam(value = "考试id", required = true) @RequestParam String examId,
                                                @ApiParam(value = "课程代码", required = true) @RequestParam String courseCode,
-                                               @ApiParam(value = "试卷编号", required = true) @RequestParam String paperNumber) {
-        return ResultUtil.ok(examPaperStructureService.findCardJpgFileByPaperNumber(SystemConstant.convertIdToLong(examId), courseCode, paperNumber));
+                                               @ApiParam(value = "试卷编号", required = true) @RequestParam String paperNumber,
+                                               @ApiParam(value = "试卷类型") @RequestParam(required = false) String paperType) {
+        if (!SystemConstant.strNotNull(paperType)){
+            // TODO: 2022/8/30 测试用需要删除 
+            paperType = "B";
+        }
+        return ResultUtil.ok(examPaperStructureService.findCardJpgFileByPaperNumber(SystemConstant.convertIdToLong(examId), courseCode, paperNumber, paperType));
     }
 }
 

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

@@ -81,7 +81,7 @@ public class SysUserController {
                        @RequestParam(value = "enable", required = false) Boolean enable,
                        @RequestParam @Min(SystemConstant.PAGE_NUMBER_MIN) Integer pageNumber,
                        @RequestParam @Min(SystemConstant.PAGE_SIZE_MIN) @Max(SystemConstant.PAGE_SIZE_MAX) Integer pageSize) {
-        return ResultUtil.ok(sysUserService.list(userInfo, SystemConstant.convertIdToLong(orgId), roleId, enable, null, null, pageNumber, pageSize));
+        return ResultUtil.ok(sysUserService.listForPrintSystem(userInfo, SystemConstant.convertIdToLong(orgId), roleId, enable, pageNumber, pageSize));
     }
 
     /**

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

@@ -135,14 +135,14 @@ public class ServiceTest {
     }
 
     @Test
-    public void findByExamDetailId(){
+    public void findByExamDetailId() {
         Long examDetailId = 1L;
         ExamPrintPlan examPrintPlan = examPrintPlanService.findByExamDetailId(examDetailId);
         System.out.println(JSON.toJSONString(examPrintPlan));
     }
 
     @Test
-    public void approveForm(){
+    public void approveForm() {
         Long examTask = 167675409079468032L;
         System.out.println(JSON.toJSONString(examTaskService.findExamTaskApprovalForm(examTask)));
     }
@@ -152,19 +152,19 @@ public class ServiceTest {
         Long id = 165147096339447808L;
         ExamCardDetail examCardDetail = examCardDetailService.getById(id);
         String htmlContent = examCardDetail.getHtmlContent();
-        BasicAttachment basicAttachment = printCommonService.saveAttachmentHtmlAndPdf("那不勒斯",htmlContent,1L);
+        BasicAttachment basicAttachment = printCommonService.saveAttachmentHtmlAndPdf("那不勒斯", htmlContent, 1L);
         System.out.println(JSON.toJSONString(basicAttachment));
     }
 
     @Test
-    public void findExamObject(){
+    public void findExamObject() {
         String paperNumber = "cn004-0906-001";
         ExamObjectDto examObjectDto = examTaskService.findExamObjectDtoByPaperNumber(paperNumber);
         System.out.println(JSON.toJSONString(examObjectDto));
     }
 
     @Test
-    public void findBasicPrintConfig(){
+    public void findBasicPrintConfig() {
         Long examId = 228554176387354624L;
         String courseCode = "gd-gdsx";
 //        BasicPrintConfig basicPrintConfig = basicPrintConfigService.getByExamIdAndCourseCode(examId,courseCode);
@@ -178,16 +178,16 @@ public class ServiceTest {
     }
 
     @Test
-    public void findExamStudent(){
+    public void findExamStudent() {
         Long schoolId = 2L;
         String clazzId = "225944699725156352";
-        List<ExamStudent> examStudentList = examStudentMapper.listExamStudentBySchoolIdAndClazzId(schoolId,clazzId);
+        List<ExamStudent> examStudentList = examStudentMapper.listExamStudentBySchoolIdAndClazzId(schoolId, clazzId);
         System.out.println(JSON.toJSONString(examStudentList));
     }
 
     @Test
-    public void findCardJpgFileByPaperNumber(){
-        List<CardJpgResult> resultList = examPaperStructureService.findCardJpgFileByPaperNumber(237292182900310016L,"yznwl","yznwl-0415-001");
+    public void findCardJpgFileByPaperNumber() {
+        List<CardJpgResult> resultList = examPaperStructureService.findCardJpgFileByPaperNumber(237292182900310016L, "yznwl", "yznwl-0415-001", "A");
         System.out.println(JSON.toJSONString(resultList));
     }
 
@@ -198,13 +198,14 @@ public class ServiceTest {
 
         File file = new File("E:" + File.separator + "file" + File.separator + "学生导入模板.xlsx");
         FileInputStream input = new FileInputStream(file);
-        MultipartFile multipartFile =new MockMultipartFile("file", file.getName(), "text/plain", IOUtils.toByteArray(input));
+        MultipartFile multipartFile = new MockMultipartFile("file", file.getName(), "text/plain", IOUtils.toByteArray(input));
 
         SysUser requestUser = new SysUser();
         requestUser.setId(293030757817909248L);
         requestUser.setSchoolId(292366699577999360L);
 
-        System.out.println(JSON.toJSONString(examTaskService.findExamTaskStudentObject(examObjectType,basicCourseId,multipartFile,requestUser)));
+        System.out.println(JSON.toJSONString(examTaskService.findExamTaskStudentObject(examObjectType, basicCourseId, multipartFile, requestUser)));
+        String x = "";
     }
 
 }

+ 6 - 0
pom.xml

@@ -44,6 +44,7 @@
         <version-plugin.version>2.8.1</version-plugin.version>
         <netty-all.version>4.1.49.Final</netty-all.version>
         <itextpdf.version>5.5.13</itextpdf.version>
+        <itextasian.version>5.2.0</itextasian.version>
         <googleBar.version>3.4.0</googleBar.version>
         <freemarker.version>2.3.30</freemarker.version>
         <commons-text.version>1.9</commons-text.version>
@@ -278,6 +279,11 @@
                 <artifactId>itextpdf</artifactId>
                 <version>${itextpdf.version}</version>
             </dependency>
+            <dependency>
+                <groupId>com.itextpdf</groupId>
+                <artifactId>itext-asian</artifactId>
+                <version>${itextasian.version}</version>
+            </dependency>
             <dependency>
                 <groupId>com.google.zxing</groupId>
                 <artifactId>core</artifactId>

+ 2 - 0
teachcloud-common/src/main/java/com/qmth/teachcloud/common/contant/SystemConstant.java

@@ -90,6 +90,8 @@ public class SystemConstant {
     public static final String ZIP_PREFIX = ".zip";
     //    public static final String JPG_PREFIX = ".jpg";
     public static final String DEFAULT_DATE_PATTERN = "yyyy-MM-dd HH:mm:ss";
+    public static final String DATE_PATTERN = "yyyy-MM-dd";
+    public static final String TIME_PATTERN = "HH:mm";
     public static final int PAGE_NUMBER = 0;
     public static final int PAGE_SIZE = 10000000;
     public static final int PAGE_SIZE_MIN = 10;

+ 1 - 1
teachcloud-common/src/main/java/com/qmth/teachcloud/common/enums/OrgTypeEnum.java

@@ -13,7 +13,7 @@ public enum OrgTypeEnum {
 
     SCHOOL("学校"),
 
-//    COLLEGE("学院"),
+    COLLEGE("学院"),
 
 //    FACULTY("院系"),
 

+ 3 - 1
teachcloud-common/src/main/java/com/qmth/teachcloud/common/mapper/SysUserMapper.java

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

+ 13 - 2
teachcloud-common/src/main/java/com/qmth/teachcloud/common/service/SysUserService.java

@@ -34,19 +34,30 @@ public interface SysUserService extends IService<SysUser> {
 
 
     /**
-     * 查询用户列表
+     * 知学知考系统 - 查询用户列表
      *
      * @param userInfo   用户信息(账号/姓名/手机号)
      * @param orgId      机构id
      * @param roleId     角色id
      * @param enable     启用禁用状态
+     * @param pageNumber 分页页数
+     * @param pageSize   分页容量
+     * @return 用户集合
+     */
+    IPage<UserDto> listForPrintSystem(String userInfo, Long orgId, String roleId, Boolean enable, Integer pageNumber, Integer pageSize);
+
+    /**
+     * 教研分析系统 - 查询用户列表
+     *
+     * @param roleId     角色id
+     * @param enable     启用禁用状态
      * @param loginName  账号
      * @param realName   真实姓名
      * @param pageNumber 分页页数
      * @param pageSize   分页容量
      * @return 用户集合
      */
-    IPage<UserDto> list(String userInfo, Long orgId, String roleId, Boolean enable, String loginName, String realName, Integer pageNumber, Integer pageSize);
+    IPage<UserDto> listForReportSystem(String roleId, Boolean enable, String loginName, String realName, Integer pageNumber, Integer pageSize);
 
     Long saveUser(UserSaveParams userSaveParams) throws IllegalAccessException;
 

+ 22 - 2
teachcloud-common/src/main/java/com/qmth/teachcloud/common/service/impl/SysUserServiceImpl.java

@@ -98,11 +98,31 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
     SysRoleGroupMemberService sysRoleGroupMemberService;
 
     @Override
-    public IPage<UserDto> list(String userInfo, Long orgId, String roleId, Boolean enable, String loginName, String realName, Integer pageNumber, Integer pageSize) {
+    public IPage<UserDto> listForPrintSystem(String userInfo, Long orgId, String roleId, Boolean enable, Integer pageNumber, Integer pageSize) {
         Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
 
         Page<UserDto> page = new Page<>(pageNumber, pageSize);
-        IPage<UserDto> userDtoIPage = this.baseMapper.listPage(page, schoolId, SystemConstant.translateSpecificSign(userInfo), orgId, roleId, enable, SystemConstant.translateSpecificSign(loginName), SystemConstant.translateSpecificSign(realName));
+        IPage<UserDto> userDtoIPage = this.baseMapper.listForPrintSystem(page, schoolId, SystemConstant.translateSpecificSign(userInfo), orgId, roleId, enable);
+        if (userDtoIPage.getRecords().size() > 0) {
+            userDtoIPage.getRecords().forEach(m -> {
+                //角色
+                List<SysRole> roles = sysRoleService.listRolesByUserId(Long.valueOf(m.getId()));
+                m.setRoles(roles);
+
+                //课程
+                List<BasicCourse> courses = basicCourseService.listCoursesByUserId(Long.valueOf(m.getId()));
+                m.setCourses(courses);
+            });
+        }
+        return userDtoIPage;
+    }
+
+    @Override
+    public IPage<UserDto> listForReportSystem(String roleId, Boolean enable, String loginName, String realName, Integer pageNumber, Integer pageSize) {
+        Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
+
+        Page<UserDto> page = new Page<>(pageNumber, pageSize);
+        IPage<UserDto> userDtoIPage = this.baseMapper.listForReportSystem(page, schoolId, roleId, enable, SystemConstant.translateSpecificSign(loginName), SystemConstant.translateSpecificSign(realName));
         if (userDtoIPage.getRecords().size() > 0) {
             userDtoIPage.getRecords().forEach(m -> {
                 //角色

+ 0 - 2
teachcloud-common/src/main/java/com/qmth/teachcloud/common/sync/TeachCloudReportTaskUtils.java

@@ -65,8 +65,6 @@ public class TeachCloudReportTaskUtils {
             Map<String, Object> map = new HashMap<>();
             map.put("id", validParam(thirdSemesterId, null, false, "学期ID"));
             map.put("semesterName", validParam(semesterName, null, true, "学期名称"));
-            map.put("startTime", validParam(startTime, null, true, "学期开始时间"));
-            map.put("endTime", validParam(endTime, null, true, "学期结束时间"));
             map.put("enable", validParam(enable, true, true, "是否启用标记"));
 
             String accessToken = createSign(schoolId, timestamp, saveUrl);

+ 17 - 0
teachcloud-common/src/main/java/com/qmth/teachcloud/common/util/ConvertUtil.java

@@ -19,6 +19,7 @@ import javax.imageio.ImageIO;
 import javax.servlet.http.HttpServletResponse;
 import java.awt.image.BufferedImage;
 import java.io.*;
+import java.net.URLEncoder;
 import java.text.DecimalFormat;
 import java.text.SimpleDateFormat;
 import java.util.*;
@@ -361,6 +362,22 @@ public class ConvertUtil {
         }
     }
 
+    public static void outputFile(HttpServletResponse response, ByteArrayOutputStream baos, String fileName) throws Exception {
+        try {
+            String fName = URLEncoder.encode(fileName, "UTF-8");
+
+            response.reset();
+            response.setContentType("application/x-msdownload");
+            response.setHeader("Content-Disposition", "attachment; filename=" + fName);
+
+            OutputStream outStream = response.getOutputStream();
+            baos.writeTo(outStream);
+            outStream.close();
+        } catch (IOException e) {
+            throw new Exception("下载失败");
+        }
+    }
+
     public static List<File> pdfToImageFile(String sourcePath, String targetPath) throws Exception {
         PDDocument doc = null;
         ByteArrayOutputStream os = null;

+ 32 - 1
teachcloud-common/src/main/resources/mapper/SysUserMapper.xml

@@ -35,7 +35,7 @@
             </if>
         </where>
     </update>
-    <select id="listPage" resultType="com.qmth.teachcloud.common.bean.dto.UserDto">
+    <select id="listForPrintSystem" resultType="com.qmth.teachcloud.common.bean.dto.UserDto">
         SELECT
             a.id,
             a.school_id schoolId,
@@ -71,6 +71,36 @@
             <if test="enable != null">
                 and a.enable = #{enable}
             </if>
+        </where>
+        order by a.create_time desc
+    </select>
+
+    <select id="listForReportSystem" resultType="com.qmth.teachcloud.common.bean.dto.UserDto">
+        SELECT
+            a.id,
+            a.school_id schoolId,
+            a.login_name loginName,
+            a.real_name realName,
+            a.mobile_number mobileNumber,
+            a.enable,
+            a.remark,
+            a.org_id orgId,
+            a.code code,
+            b.name orgName
+        FROM
+            sys_user a
+                left join
+            sys_org b on a.org_id = b.id
+        <where>
+            <if test="schoolId != null and schoolId != ''">
+                and a.school_id = #{schoolId}
+            </if>
+            <if test="roleId != null and roleId != ''">
+                and a.id in (select user_id from sys_user_role b where b.role_id = #{roleId})
+            </if>
+            <if test="enable != null">
+                and a.enable = #{enable}
+            </if>
             <if test="loginName != null and loginName != ''">
                 and a.login_name like concat('%', #{loginName} , '%')
             </if>
@@ -339,4 +369,5 @@
             </if>
         </where>
     </select>
+
 </mapper>

+ 1 - 1
teachcloud-report/src/main/java/com/qmth/teachcloud/report/api/SysUserController.java

@@ -59,7 +59,7 @@ public class SysUserController {
                        @RequestParam(value = "realName", required = false) String realName,
                        @RequestParam @Min(SystemConstant.PAGE_NUMBER_MIN) Integer pageNumber,
                        @RequestParam @Min(SystemConstant.PAGE_SIZE_MIN) @Max(SystemConstant.PAGE_SIZE_MAX) Integer pageSize) {
-        return ResultUtil.ok(sysUserService.list(null, null, roleId, enable, loginName, realName, pageNumber, pageSize));
+        return ResultUtil.ok(sysUserService.listForReportSystem(roleId, enable, loginName, realName, pageNumber, pageSize));
     }
 
     /**