浏览代码

feature 增加文件预览已经签名文件预览的功能

xiahan 1 天之前
父节点
当前提交
1d970d3941
共有 22 个文件被更改,包括 693 次插入171 次删除
  1. 17 0
      qhse-common/pom.xml
  2. 15 0
      qhse-common/src/main/java/com/rongwei/bscommon/sys/dao/FileItemMapper.java
  3. 19 0
      qhse-common/src/main/java/com/rongwei/bscommon/sys/dao/QhseTargetResponsibilityDocumentDao.java
  4. 18 0
      qhse-common/src/main/java/com/rongwei/bscommon/sys/dao/QhseTargetResponsibilityDocumentSignatureDao.java
  5. 17 0
      qhse-common/src/main/java/com/rongwei/bscommon/sys/service/FileFormatConversionService.java
  6. 16 0
      qhse-common/src/main/java/com/rongwei/bscommon/sys/service/FileItemService.java
  7. 18 0
      qhse-common/src/main/java/com/rongwei/bscommon/sys/service/QhseTargetResponsibilityDocumentService.java
  8. 13 0
      qhse-common/src/main/java/com/rongwei/bscommon/sys/service/QhseTargetResponsibilityDocumentSignatureService.java
  9. 125 0
      qhse-common/src/main/java/com/rongwei/bscommon/sys/service/impl/FileFormatConversionServiceImpl.java
  10. 145 0
      qhse-common/src/main/java/com/rongwei/bscommon/sys/service/impl/QhseTargetResponsibilityDocumentServiceImpl.java
  11. 22 0
      qhse-common/src/main/java/com/rongwei/bscommon/sys/service/impl/QhseTargetResponsibilityDocumentSignatureServiceImpl.java
  12. 2 3
      qhse-common/src/main/java/com/rongwei/bscommon/sys/service/impl/RedisServiceImpl.java
  13. 12 0
      qhse-common/src/main/java/com/rongwei/bscommon/sys/service/impl/SysFileItemServiceImpl.java
  14. 36 0
      qhse-common/src/main/java/com/rongwei/bscommon/sys/utils/AsposeLicenseConfig.java
  15. 11 159
      qhse-common/src/main/java/com/rongwei/bscommon/sys/utils/QHSEConstant.java
  16. 60 0
      qhse-common/src/main/java/com/rongwei/bscommon/sys/utils/WordMergeHandler.java
  17. 51 0
      qhse-common/src/main/java/com/rongwei/bscommon/sys/utils/WordUtils.java
  18. 0 2
      qhse-server/src/main/java/com/rongwei/BusinessServerApplication.java
  19. 40 0
      qhse-server/src/main/java/com/rongwei/controller/FileFormatConversionController.java
  20. 37 0
      qhse-server/src/main/java/com/rongwei/controller/LettersOfResponsibilityController.java
  21. 4 7
      qhse-server/src/main/java/com/rongwei/jxkh/controller/SysPagePartController.java
  22. 15 0
      qhse-server/src/main/resources/license.xml

+ 17 - 0
qhse-common/pom.xml

@@ -62,10 +62,27 @@
             <version>7.1.8</version>
             <type>pom</type>
         </dependency>
+        <dependency>
+            <groupId>com.aspose</groupId>
+            <artifactId>aspose-cells</artifactId>
+            <version>23.4</version>
+        </dependency>
         <dependency>
             <groupId>org.springframework.cloud</groupId>
             <artifactId>spring-cloud-starter-openfeign</artifactId>
             <version>2.1.0.RELEASE</version>
         </dependency>
+        <dependency>
+            <groupId>com.aspose</groupId>
+            <artifactId>aspose-cells</artifactId>
+            <version>18.9</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+            <version>32.1.3-android</version>
+            <scope>compile</scope>
+        </dependency>
     </dependencies>
 </project>

+ 15 - 0
qhse-common/src/main/java/com/rongwei/bscommon/sys/dao/FileItemMapper.java

@@ -0,0 +1,15 @@
+package com.rongwei.bscommon.sys.dao;
+
+import com.rongwei.rwcommon.base.BaseDao;
+import com.rongwei.rwcommonentity.commonservers.domain.SysFileItemDo;
+
+/**
+ * 文件表
+ * 
+ * @author chenshun
+ * @email sunlightcs@gmail.com
+ * @date 2019-10-08 14:53:10
+ */
+public interface FileItemMapper extends BaseDao<SysFileItemDo> {
+	
+}

+ 19 - 0
qhse-common/src/main/java/com/rongwei/bscommon/sys/dao/QhseTargetResponsibilityDocumentDao.java

@@ -0,0 +1,19 @@
+package com.rongwei.bscommon.sys.dao;
+
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.rongwei.bsentity.domain.QhseTargetResponsibilityDocumentDo;
+
+/**
+* @author libai
+* @description 针对表【qhse_target_responsibility_document(目标责任书)】的数据库操作Mapper
+* @createDate 2025-08-04 15:50:27
+* @Entity generator.domain.QhseTargetResponsibilityDocument
+*/
+public interface QhseTargetResponsibilityDocumentDao extends BaseMapper<QhseTargetResponsibilityDocumentDo> {
+
+}
+
+
+
+

+ 18 - 0
qhse-common/src/main/java/com/rongwei/bscommon/sys/dao/QhseTargetResponsibilityDocumentSignatureDao.java

@@ -0,0 +1,18 @@
+package com.rongwei.bscommon.sys.dao;
+
+import com.rongwei.bsentity.domain.QhseTargetResponsibilityDocumentSignatureDo;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+* @author libai
+* @description 针对表【qhse_target_responsibility_document_signature(目标责任书签名子表)】的数据库操作Mapper
+* @createDate 2025-08-04 15:50:27
+* @Entity generator.domain.QhseTargetResponsibilityDocumentSignature
+*/
+public interface QhseTargetResponsibilityDocumentSignatureDao extends BaseMapper<QhseTargetResponsibilityDocumentSignatureDo> {
+
+}
+
+
+
+

+ 17 - 0
qhse-common/src/main/java/com/rongwei/bscommon/sys/service/FileFormatConversionService.java

@@ -0,0 +1,17 @@
+package com.rongwei.bscommon.sys.service;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.UnsupportedEncodingException;
+import java.util.Map;
+
+/**
+ * FileFormatConversionService class
+ *
+ * @author XH
+ * @date 2025/08/01
+ */
+public interface FileFormatConversionService {
+    void fileFormatConversion(String id, HttpServletResponse response);
+
+
+}

+ 16 - 0
qhse-common/src/main/java/com/rongwei/bscommon/sys/service/FileItemService.java

@@ -0,0 +1,16 @@
+package com.rongwei.bscommon.sys.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.rongwei.rwcommonentity.commonservers.domain.SysFileItemDo;
+
+
+/**
+ * 文件表
+ *
+ * @author chenshun
+ * @email sunlightcs@gmail.com
+ * @date 2019-10-08 14:53:10
+ */
+public interface FileItemService extends IService<SysFileItemDo> {
+}
+

+ 18 - 0
qhse-common/src/main/java/com/rongwei/bscommon/sys/service/QhseTargetResponsibilityDocumentService.java

@@ -0,0 +1,18 @@
+package com.rongwei.bscommon.sys.service;
+
+import com.rongwei.bsentity.domain.QhseTargetResponsibilityDocumentDo;
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.springframework.web.bind.annotation.RequestBody;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.Map;
+
+/**
+* @author libai
+* @description 针对表【qhse_target_responsibility_document(目标责任书)】的数据库操作Service
+* @createDate 2025-08-04 15:50:27
+*/
+public interface QhseTargetResponsibilityDocumentService extends IService<QhseTargetResponsibilityDocumentDo> {
+
+    void lettersOfResponsibilitySignaturePreview(@RequestBody Map<String, String> mapData, HttpServletResponse response);
+}

+ 13 - 0
qhse-common/src/main/java/com/rongwei/bscommon/sys/service/QhseTargetResponsibilityDocumentSignatureService.java

@@ -0,0 +1,13 @@
+package com.rongwei.bscommon.sys.service;
+
+import com.rongwei.bsentity.domain.QhseTargetResponsibilityDocumentSignatureDo;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+* @author libai
+* @description 针对表【qhse_target_responsibility_document_signature(目标责任书签名子表)】的数据库操作Service
+* @createDate 2025-08-04 15:50:27
+*/
+public interface QhseTargetResponsibilityDocumentSignatureService extends IService<QhseTargetResponsibilityDocumentSignatureDo> {
+
+}

+ 125 - 0
qhse-common/src/main/java/com/rongwei/bscommon/sys/service/impl/FileFormatConversionServiceImpl.java

@@ -0,0 +1,125 @@
+package com.rongwei.bscommon.sys.service.impl;
+
+import com.aspose.cells.*;
+import com.aspose.words.Document;
+import com.aspose.words.SaveOutputParameters;
+import com.rongwei.bscommon.sys.service.FileFormatConversionService;
+import com.rongwei.bscommon.sys.utils.AsposeLicenseConfig;
+import com.rongwei.rwcommon.base.exception.CustomException;
+import com.rongwei.rwcommon.utils.StringUtils;
+import com.rongwei.rwcommonentity.commonservers.domain.SysFileItemDo;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URLEncoder;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+
+import static com.rongwei.bscommon.sys.utils.QHSEConstant.FileType.*;
+
+/**
+ * FileFormatConversionServiceImpl class
+ *
+ * @author XH
+ * @date 2025/08/01
+ */
+@Service
+public class FileFormatConversionServiceImpl implements FileFormatConversionService {
+    private static final Logger log = LoggerFactory.getLogger(FileFormatConversionServiceImpl.class);
+    @Autowired
+    private SysFileItemServiceImpl sysFileItemServiceImpl;
+
+    public SysFileItemDo fileCheck(String id) {
+        SysFileItemDo sysFileItemDo = sysFileItemServiceImpl.getById(id);
+        if (sysFileItemDo == null) {
+            throw new CustomException("无法根据ID获取到文件信息");
+        }
+        log.debug("获取到的文件id:{}", sysFileItemDo.getId());
+        return sysFileItemDo;
+    }
+
+    @Override
+    public void fileFormatConversion(String id, HttpServletResponse response) {
+        log.info("开始进行文件格式转换Id为:{}", id);
+        if (StringUtils.isBlank(id)) {
+            log.error("参数异常");
+            throw new CustomException("文件ID为空,请联系系统管理员");
+        }
+        SysFileItemDo sysFileItemDo = fileCheck(id);
+        String lowerCaseFileTYpe = sysFileItemDo.getFiletype().toLowerCase();
+        String fullpath = sysFileItemDo.getFullpath();
+        String fileName = null;
+        try {
+            fileName = URLEncoder.encode(sysFileItemDo.getFilename(), "utf-8");
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+        response.setContentType("application/pdf");
+        response.setHeader("Content-Disposition", "inline; filename=" + fileName);
+        response.setHeader("X-Content-Length", String.valueOf(sysFileItemDo.getFilesize()));
+
+        if (XLSX.equals(lowerCaseFileTYpe) || XLS.equals(lowerCaseFileTYpe)) {
+            AsposeLicenseConfig.getExcelLicense();
+            convertExcelToPdf(null, fullpath, response);
+        } else if (DOCX.equals(lowerCaseFileTYpe) || DOC.equals(lowerCaseFileTYpe)) {
+            convertWordToPdf(null, fullpath, response);
+        } else {
+            try {
+                response.setContentType("application/octet-stream");
+                Files.copy(Paths.get(fullpath), response.getOutputStream());
+            } catch (Exception e) {
+                log.error("文件名:{}格式化失败- 原因: {} | 异常类型: {}", sysFileItemDo.getFilename(), e.getMessage(), e.getClass().getSimpleName(), e);
+                throw new RuntimeException("获取预览文件失败!请联系系统管理员");
+            }
+
+        }
+    }
+
+
+    public void convertExcelToPdf(InputStream inputStream, String fullPath, HttpServletResponse response) {
+
+        try (OutputStream out = response.getOutputStream();
+             InputStream templateStream = Files.newInputStream(Paths.get(fullPath))) {
+            LoadOptions loadOptions = new LoadOptions(LoadFormat.XLSX);
+            loadOptions.setMemorySetting(MemorySetting.MEMORY_PREFERENCE);
+            Workbook workbook = new Workbook(templateStream, loadOptions);
+            Worksheet worksheet = workbook.getWorksheets().get(0);
+            // 自动调整所有列的宽度
+            worksheet.autoFitColumns();
+            // 设置 PDF 转换选项
+            PdfSaveOptions pdfSaveOptions = new PdfSaveOptions();
+            pdfSaveOptions.setOnePagePerSheet(true); // 每个工作表单独一页
+            pdfSaveOptions.setAllColumnsInOnePagePerSheet(true); // 所有列在一页
+            workbook.calculateFormula();
+            // 转换为 PDF 并输出到流
+            workbook.save(out, pdfSaveOptions);
+            out.flush();
+        } catch (Exception e) {
+            log.error("excel转pdf失败- 原因: {} | 异常类型: {}", e.getMessage(), e.getClass().getSimpleName(), e);
+            throw new RuntimeException("获取预览文件失败!请联系系统管理员");
+        }
+    }
+
+    public void convertWordToPdf(InputStream inputStream, String fullPath, HttpServletResponse response) {
+        try (OutputStream out = response.getOutputStream();
+             InputStream templateStream = Files.newInputStream(Paths.get(fullPath))) {
+            Document doc = new Document(templateStream);
+            // 设置 PDF 转换选项
+            PdfSaveOptions options = new PdfSaveOptions();
+            options.setCompliance(PdfCompliance.PDF_A_1_A); // 设置PDF/A-1a标准
+            // 3. 直接输出到响应流(避免中间文件)
+            SaveOutputParameters save = doc.save(out, com.aspose.words.SaveFormat.PDF);
+            // 4. 强制刷新缓冲区(确保数据完整传输)
+            out.flush();
+        } catch (Exception e) {
+            log.error("word转pdf失败- 原因: {} | 异常类型: {}", e.getMessage(), e.getClass().getSimpleName(), e);
+            throw new RuntimeException("获取预览文件失败!请联系系统管理员");
+        }
+    }
+
+}

+ 145 - 0
qhse-common/src/main/java/com/rongwei/bscommon/sys/service/impl/QhseTargetResponsibilityDocumentServiceImpl.java

@@ -0,0 +1,145 @@
+package com.rongwei.bscommon.sys.service.impl;
+
+import com.aspose.cells.PdfCompliance;
+import com.aspose.cells.PdfSaveOptions;
+import com.aspose.words.Document;
+import com.aspose.words.SaveOutputParameters;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.rongwei.bscommon.sys.dao.QhseTargetResponsibilityDocumentDao;
+import com.rongwei.bscommon.sys.service.QhseTargetResponsibilityDocumentService;
+import com.rongwei.bscommon.sys.utils.WordMergeHandler;
+import com.rongwei.bscommon.sys.utils.WordUtils;
+import com.rongwei.bsentity.domain.QhseTargetResponsibilityDocumentDo;
+import com.rongwei.bsentity.domain.QhseTargetResponsibilityDocumentSignatureDo;
+import com.rongwei.rwcommon.base.exception.CustomException;
+import com.rongwei.rwcommon.utils.StringUtils;
+import com.rongwei.rwcommonentity.commonservers.domain.SysFileItemDo;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URLEncoder;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.HashMap;
+import java.util.Map;
+
+import static com.rongwei.bscommon.sys.utils.QHSEConstant.FILE_SEPARATOR;
+import static com.rongwei.bscommon.sys.utils.QHSEConstant.FileType.DOC;
+import static com.rongwei.bscommon.sys.utils.QHSEConstant.FileType.DOCX;
+
+/**
+ * @author libai
+ * @description 针对表【qhse_target_responsibility_document(目标责任书)】的数据库操作Service实现
+ * @createDate 2025-08-04 15:50:27
+ */
+@Service
+public class QhseTargetResponsibilityDocumentServiceImpl extends ServiceImpl<QhseTargetResponsibilityDocumentDao, QhseTargetResponsibilityDocumentDo>
+        implements QhseTargetResponsibilityDocumentService {
+    @Autowired
+    private QhseTargetResponsibilityDocumentSignatureServiceImpl qhseTargetResponsibilityDocumentSignatureService;
+    @Autowired
+    private FileFormatConversionServiceImpl fileFormatConversionService;
+
+
+    private static final Logger log = LoggerFactory.getLogger(QhseTargetResponsibilityDocumentServiceImpl.class);
+
+    @Override
+    public void lettersOfResponsibilitySignaturePreview(Map<String, String> mapData, HttpServletResponse response) {
+        log.debug("开始生成责任书签名后文件");
+        String mainId = mapData.getOrDefault("mainId", "");
+        String subTableId = mapData.getOrDefault("subTableId", "");
+        QhseTargetResponsibilityDocumentDo qhseTargetResponsibilityDocumentDo = this.getById(mainId);
+        if (qhseTargetResponsibilityDocumentDo == null) {
+            log.error("无法获取到责任书信息");
+            throw new CustomException("无法获取到责任书信息");
+        }
+        String responsibilityfiles = qhseTargetResponsibilityDocumentDo.getResponsibilityfiles();
+        if (StringUtils.isBlank(responsibilityfiles)) {
+            throw new CustomException("未上传责任书附件");
+        }
+        String fileId = responsibilityfiles.split(FILE_SEPARATOR)[1];
+
+        QhseTargetResponsibilityDocumentSignatureDo documentSignatureDo = qhseTargetResponsibilityDocumentSignatureService.getById(subTableId);
+        // 没有签名直接预览
+        if (documentSignatureDo == null || StringUtils.isBlank(documentSignatureDo.getSignature())) {
+            log.error("无法获取到签名信息");
+            fileFormatConversionService.fileFormatConversion(fileId, response);
+            return;
+        }
+        // 甲方或者乙方
+        String signaturesource = documentSignatureDo.getSignaturesource();
+        // 签名
+        String signatureInfo = documentSignatureDo.getSignature();
+        // Id
+        String signatureId = signatureInfo.split(FILE_SEPARATOR)[1];
+        SysFileItemDo tempDo = fileFormatConversionService.fileCheck(fileId);
+        if (tempDo == null) {
+            log.error("无法根据id:{}获取到责任书文件信息", fileId);
+            throw new RuntimeException("无法获取到责任书");
+        }
+        // 模板路径
+        String tempFullpath = tempDo.getFullpath();
+        if (StringUtils.isBlank(tempFullpath)) {
+            log.error("无法根据id:{}获取到责任书文件信息", fileId);
+            throw new RuntimeException("无法获取到责任书");
+        }
+        SysFileItemDo signatureDo = fileFormatConversionService.fileCheck(signatureId);
+        if (signatureDo == null) {
+            log.error("无法根据id:{}获取到签名信息", signatureId);
+            throw new RuntimeException("无法获取到签名");
+        }
+        // 乙方签名路径
+        String signaturePath = signatureDo.getFullpath();
+        if (StringUtils.isBlank(signaturePath)) {
+            log.error("无法根据id:{}获取到签名信息", signatureId);
+            throw new RuntimeException("无法获取到签名");
+        }
+
+        String filetype = tempDo.getFiletype();
+        if (!DOCX.equals(filetype) && !DOC.equals(filetype)) {
+            log.error("责任书格式:{}不正确", filetype);
+            throw new CustomException("责任书格式不正确");
+        }
+
+        try (InputStream templateStream = Files.newInputStream(Paths.get(tempFullpath));
+             OutputStream out = response.getOutputStream();) {
+            Document doc = new Document(templateStream);
+            // 设置邮件合并回调
+            doc.getMailMerge().setFieldMergingCallback(new WordMergeHandler());
+            HashMap<String, String> objectObjectHashMap = new HashMap<>();
+            objectObjectHashMap.put("YFQM", signaturePath);
+            objectObjectHashMap.put("ZRR", "责任人");
+            WordUtils.MailMergeFill(objectObjectHashMap, doc);
+
+            String fileName = null;
+            try {
+                fileName = URLEncoder.encode(tempDo.getFilename(), "utf-8");
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+            response.setContentType("application/pdf");
+            response.setHeader("Content-Disposition", "inline; filename=" + fileName);
+            response.setHeader("X-Content-Length", String.valueOf(tempDo.getFilesize()));
+
+            // 设置 PDF 转换选项
+            PdfSaveOptions options = new PdfSaveOptions();
+            options.setCompliance(PdfCompliance.PDF_A_1_A); // 设置PDF/A-1a标准
+            // 3. 直接输出到响应流(避免中间文件)
+            SaveOutputParameters save = doc.save(out, com.aspose.words.SaveFormat.PDF);
+            // 4. 强制刷新缓冲区(确保数据完整传输)
+            out.flush();
+        } catch (Exception e) {
+            log.error("excel转pdf失败- 原因: {} | 异常类型: {}", e.getMessage(), e.getClass().getSimpleName(), e);
+            throw new RuntimeException("获取签名责任书失败!请联系系统管理员");
+        }
+    }
+}
+
+
+
+

+ 22 - 0
qhse-common/src/main/java/com/rongwei/bscommon/sys/service/impl/QhseTargetResponsibilityDocumentSignatureServiceImpl.java

@@ -0,0 +1,22 @@
+package com.rongwei.bscommon.sys.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.rongwei.bscommon.sys.dao.QhseTargetResponsibilityDocumentSignatureDao;
+import com.rongwei.bscommon.sys.service.QhseTargetResponsibilityDocumentSignatureService;
+import com.rongwei.bsentity.domain.QhseTargetResponsibilityDocumentSignatureDo;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author libai
+ * @description 针对表【qhse_target_responsibility_document_signature(目标责任书签名子表)】的数据库操作Service实现
+ * @createDate 2025-08-04 15:50:27
+ */
+@Service
+public class QhseTargetResponsibilityDocumentSignatureServiceImpl extends ServiceImpl<QhseTargetResponsibilityDocumentSignatureDao, QhseTargetResponsibilityDocumentSignatureDo>
+        implements QhseTargetResponsibilityDocumentSignatureService {
+
+}
+
+
+
+

+ 2 - 3
qhse-common/src/main/java/com/rongwei/bscommon/sys/service/impl/RedisServiceImpl.java

@@ -23,13 +23,12 @@ import java.util.concurrent.TimeUnit;
 @Service("MyRedisService")
 public class RedisServiceImpl implements RedisService {
 
-    @Value("${jwt.expire}")
+    @Value("${jwt.expire:360000}")
     private int expire;
 
     @Autowired
     private RedisTemplate redisTemplate;
-    @Autowired
-    private StringRedisTemplate stringRedisTemplate;
+
 
 
     @Override

+ 12 - 0
qhse-common/src/main/java/com/rongwei/bscommon/sys/service/impl/SysFileItemServiceImpl.java

@@ -0,0 +1,12 @@
+package com.rongwei.bscommon.sys.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.rongwei.bscommon.sys.dao.FileItemMapper;
+import com.rongwei.bscommon.sys.service.FileItemService;
+import com.rongwei.rwcommonentity.commonservers.domain.SysFileItemDo;
+import org.springframework.stereotype.Service;
+
+@Service("sysFileServiceImpl")
+public class SysFileItemServiceImpl extends ServiceImpl<FileItemMapper, SysFileItemDo> implements FileItemService {
+
+}

+ 36 - 0
qhse-common/src/main/java/com/rongwei/bscommon/sys/utils/AsposeLicenseConfig.java

@@ -0,0 +1,36 @@
+package com.rongwei.bscommon.sys.utils;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+import java.io.InputStream;
+
+/**
+ * AsposeWordsUtils class
+ *
+ * @author XH
+ * @date 2022/08/01
+ */
+@Component
+public class AsposeLicenseConfig {
+    private static final Logger log = LoggerFactory.getLogger(AsposeLicenseConfig.class);
+    private static final String LICENSE_PATH = "license.xml";
+
+    private static volatile boolean excelLicenseInit = false;
+
+    public static void getExcelLicense() {
+        if (excelLicenseInit) {
+            log.debug("已初始化");
+            return;
+        }
+        try (InputStream is = AsposeLicenseConfig.class.getClassLoader().getResourceAsStream(LICENSE_PATH);) {
+            com.aspose.cells.License license = new com.aspose.cells.License();
+            license.setLicense(is);
+            excelLicenseInit = true;
+        } catch (Exception e) {
+            log.error("aspose License 失败- 原因: {} | 异常类型: {}", e.getMessage(), e.getClass().getSimpleName(), e);
+        }
+    }
+
+}

+ 11 - 159
qhse-common/src/main/java/com/rongwei/bscommon/sys/utils/QHSEConstant.java

@@ -1,7 +1,5 @@
 package com.rongwei.bscommon.sys.utils;
 
-import java.math.BigDecimal;
-
 /**
  * JXKHConstant class
  *
@@ -20,168 +18,22 @@ public class QHSEConstant {
         public static final String DATE_PATTERN_YMD_POINT = "yyyy.MM.dd";
     }
 
-    public static class BusinessReturnCode {
-        /**
-         * 接口执行成功
-         */
-        public static final int CODE_100 = 100;
-        /**
-         * 必填项xxx为空
-         */
-        public static final int CODE_101 = 101;
-        /**
-         * 数据主键或数据编码有误,数据操作失败
-         */
-        public static final int CODE_103 = 103;
-    }
+    public static final String FILE_SEPARATOR = "-;-";
 
-    public static class StandardReturn {
-        /**
-         * 请求成功
-         */
-        public static final String CODE_000 = "000";
-        /**
-         * token校验失败
-         */
-        public static final String CODE_001 = "001";
-        /**
-         * 单位编码为空
-         */
-        public static final String CODE_002 = "002";
-        /**
-         * 接口无权限
-         */
-        public static final String CODE_003 = "003";
-        /**
-         * token过期
-         */
-        public static final String CODE_004 = "004";
-        /**
-         * 数据超过最大处理数量
-         */
-        public static final String CODE_006 = "006";
-    }
 
-    public static class DefaultSource {
-        public static final BigDecimal THREE_SOURCE = BigDecimal.valueOf(3);
-        public static final BigDecimal TWO_SOURCE = BigDecimal.valueOf(2);
-        public static final BigDecimal FOUR_SOURCE = BigDecimal.valueOf(4);
-        public static final BigDecimal FIVE_SOURCE = BigDecimal.valueOf(5);
-        public static final BigDecimal ZERO_POINT_FIVE_SOURCE = BigDecimal.valueOf(0.5);
+    public static class PartType {
+        public static final String PARTY_A = "A";
+        public static final String PARTY_B = "B";
     }
 
-    public static class JXJB {
-        /**
-         * 设计咨询省部级(一等)
-         */
-        public static final String JXJB_27 = "27";
-        /**
-         * 设计咨询集团级(一等)
-         */
-        public static final String JXJB_26 = "26";
-        /**
-         * 设计咨询国家级(三等)
-         */
-        public static final String JXJB_25 = "25";
-        /**
-         * 设计咨询国家级(二等)
-         */
-        public static final String JXJB_24 = "24";
-        /**
-         * 设计咨询国家级(一等)
-         */
-        public static final String JXJB_23 = "23";
-        /**
-         * 技术发明其他
-         */
-        public static final String JXJB_22 = "22";
-        /**
-         * 技术发明省部级(一等)
-         */
-        public static final String JXJB_21 = "21";
-        /**
-         * 技术发明集团级(一等)
-         */
-        public static final String JXJB_20 = "20";
-        /**
-         * 技术发明国家级(一等)
-         */
-        public static final String JXJB_19 = "19";
-        /**
-         * 低碳技术其他
-         */
-        public static final String JXJB_18 = "18";
-        /**
-         * 低碳技术省部级(一等)
-         */
-        public static final String JXJB_17 = "17";
-        /**
-         * 低碳技术集团级(一等)
-         */
-        public static final String JXJB_16 = "16";
-        /**
-         * 低碳技术国家级(三级)
-         */
-        public static final String JXJB_15 = "15";
-        /**
-         * 低碳技术国家级(二等)
-         */
-        public static final String JXJB_14 = "14";
-        /**
-         * 低碳技术国家级(一等)
-         */
-        public static final String JXJB_13 = "13";
-        /**
-         * 天佑奖
-         */
-        public static final String JXJB_12 = "12";
-        /**
-         * 班奖
-         */
-        public static final String JXJB_11 = "11";
-        /**
-         * 国家优质工程金奖
-         */
-        public static final String JXJB_10 = "10";
-        /**
-         * 国家优质工程奖
-         */
-        public static final String JXJB_9 = "9";
-        /**
-         * 科技奖集团(一等)
-         */
-        public static final String JXJB_7 = "7";
-        /**
-         * 科技奖省部级(一等)
-         */
-        public static final String JXJB_5 = "5";
-        /**
-         * 科技奖国家级(三级)
-         */
-        public static final String JXJB_4 = "4";
-        /**
-         * 科技奖国家级(二等)
-         */
-        public static final String JXJB_3 = "3";
-        /**
-         * 科技奖国家级(一等)
-         */
-        public static final String JXJB_2 = "2";
-        /**
-         * 设计咨询国际级
-         */
-        public static final String JXJB_1 = "1";
-    }
 
-    public static class YZLX{
-        /**
-         * 基础资料验证
-         */
-        public static final String JCZL="0";
-        /**
-         * 外业验收验证
-         */
-        public static final String WYYS="1";
+    public static class FileType {
+        public static final String DOC = "doc";
+        public static final String DOCX = "docx";
+        public static final String XLS = "xls";
+        public static final String XLSX = "xlsx";
+        public static final String PDF = "pdf";
     }
+
 }
 

+ 60 - 0
qhse-common/src/main/java/com/rongwei/bscommon/sys/utils/WordMergeHandler.java

@@ -0,0 +1,60 @@
+package com.rongwei.bscommon.sys.utils;
+
+import com.aspose.words.*;
+import com.rongwei.rwcommon.utils.StringUtils;
+
+import javax.imageio.ImageIO;
+import java.awt.image.BufferedImage;
+import java.io.FileInputStream;
+
+/**
+ * ImageMergeHandler class
+ *
+ * @author XH
+ * @date 2025/08/04
+ */
+public class WordMergeHandler implements IFieldMergingCallback {
+    @Override
+    public void fieldMerging(FieldMergingArgs args) throws Exception {
+        // 其他字段自动按文本处理
+    }
+
+    @Override
+    public void imageFieldMerging(ImageFieldMergingArgs imageFieldMergingArgs) throws Exception {
+        String documentFieldName = imageFieldMergingArgs.getDocumentFieldName();
+        // 处理图片类型字段
+        if (documentFieldName.contains("QM")) {
+            // 从数据源获取图片路径
+            String imagePath = (String) imageFieldMergingArgs.getFieldValue();
+            if (StringUtils.isBlank(imagePath)) {
+                return;
+            }
+            // 创建图片形状对象
+            Shape imageShape = new Shape(imageFieldMergingArgs.getDocument(), ShapeType.IMAGE);
+            imageShape.setWrapType(WrapType.SQUARE); // 四周型环绕
+            imageShape.setWrapSide(WrapSide.BOTH);   // 两侧环绕
+            imageShape.setBehindText(false);         // 图片在文字上方
+            // 设置图片数据(支持文件路径/字节数组)
+            try (FileInputStream stream = new FileInputStream(imagePath)) {
+                imageShape.getImageData().setImage(stream);
+            }
+            FileInputStream imageStream = new FileInputStream(imagePath);
+            BufferedImage img = ImageIO.read(imageStream);
+            double aspectRatio = (double) img.getHeight() / img.getWidth();
+            imageShape.setWidth(100);
+            imageShape.setHeight(50 * aspectRatio);
+            if (documentFieldName.contains("JF")) {
+                imageShape.setRelativeHorizontalPosition(RelativeHorizontalPosition.MARGIN);
+                imageShape.setLeft(0); // 左边距为0
+                imageShape.setHorizontalAlignment(HorizontalAlignment.LEFT);
+            }
+            if (documentFieldName.contains("YF")) {
+                imageShape.setRelativeHorizontalPosition(RelativeHorizontalPosition.MARGIN);
+                imageShape.setHorizontalAlignment(HorizontalAlignment.RIGHT);
+            }
+
+            // 将图片插入文档
+            imageFieldMergingArgs.setShape(imageShape);
+        }
+    }
+}

+ 51 - 0
qhse-common/src/main/java/com/rongwei/bscommon/sys/utils/WordUtils.java

@@ -0,0 +1,51 @@
+package com.rongwei.bscommon.sys.utils;
+
+import com.aspose.words.*;
+import com.rongwei.rwcommon.base.exception.CustomException;
+import lombok.Data;
+import org.springframework.core.io.ClassPathResource;
+
+import java.util.Map;
+
+/**
+ * WordMailMergeFill class
+ *
+ * @author XH
+ * @date 2025/08/04
+ */
+@Data
+public class WordUtils {
+
+    public static void MailMergeFill(Map<String, String> wordMap, String tempPatch) {
+        try {
+            ClassPathResource classPathResource = new ClassPathResource(tempPatch);
+            Document doc = new Document(classPathResource.getInputStream());
+            if (wordMap != null) {
+                doc.getMailMerge().execute(wordMap.keySet().toArray(new String[0]), wordMap.values().toArray(new String[0]));
+            }
+            doc.getMailMerge().setCleanupOptions(MailMergeCleanupOptions.REMOVE_UNUSED_FIELDS);
+            doc.getMailMerge().setCleanupOptions(MailMergeCleanupOptions.REMOVE_EMPTY_TABLE_ROWS);
+            doc.getMailMerge().deleteFields();
+            // response.setContentType("application/octet-stream;charset=ISO8859-1");
+            // response.setHeader("Content-Disposition", "attachment;filename=AccidentHandlingSheet.docx");
+            // doc.save(response.getOutputStream(), SaveFormat.DOCX);
+        } catch (Exception e) {
+            throw new CustomException("文件导出异常");
+        }
+    }
+    public static void MailMergeFill(Map<String, String> wordMap, Document doc) {
+        try {
+            if (wordMap != null) {
+                doc.getMailMerge().execute(wordMap.keySet().toArray(new String[0]), wordMap.values().toArray(new String[0]));
+            }
+            doc.getMailMerge().setCleanupOptions(MailMergeCleanupOptions.REMOVE_UNUSED_FIELDS);
+            doc.getMailMerge().setCleanupOptions(MailMergeCleanupOptions.REMOVE_EMPTY_TABLE_ROWS);
+            doc.getMailMerge().deleteFields();
+            // response.setContentType("application/octet-stream;charset=ISO8859-1");
+            // response.setHeader("Content-Disposition", "attachment;filename=AccidentHandlingSheet.docx");
+            // doc.save(response.getOutputStream(), SaveFormat.DOCX);
+        } catch (Exception e) {
+            throw new CustomException("文件导出异常");
+        }
+    }
+}

+ 0 - 2
qhse-server/src/main/java/com/rongwei/BusinessServerApplication.java

@@ -15,9 +15,7 @@ import org.springframework.scheduling.annotation.EnableScheduling;
 @MapperScan("com.rongwei.bscommon.sys.dao")
 @EnableScheduling
 public class BusinessServerApplication {
-
     public static void main(String[] args) {
         SpringApplication.run(BusinessServerApplication.class, args);
     }
-
 }

+ 40 - 0
qhse-server/src/main/java/com/rongwei/controller/FileFormatConversionController.java

@@ -0,0 +1,40 @@
+package com.rongwei.controller;
+
+import com.rongwei.bscommon.sys.service.impl.FileFormatConversionServiceImpl;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.Map;
+
+/**
+ * FileFormatConversionController class
+ *
+ * @author XH
+ * @date 2025/08/01
+ */
+@RestController
+@RequestMapping("/file")
+public class FileFormatConversionController {
+    private static final Logger log = LoggerFactory.getLogger(FileFormatConversionController.class);
+
+    @Autowired
+    private FileFormatConversionServiceImpl fileFormatConversionService;
+
+    /**
+     * 文件转为pdf 预览
+     *
+     * @param id
+     * @param response
+     */
+    @GetMapping("/format/conversion/{id}")
+    public void fileFormatConversion(@PathVariable String id, HttpServletResponse response) {
+        log.info("文件预览接口入参为:{}", id);
+        fileFormatConversionService.fileFormatConversion(id, response);
+    }
+
+
+
+}

+ 37 - 0
qhse-server/src/main/java/com/rongwei/controller/LettersOfResponsibilityController.java

@@ -0,0 +1,37 @@
+package com.rongwei.controller;
+
+import com.rongwei.bscommon.sys.service.impl.QhseTargetResponsibilityDocumentServiceImpl;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.Map;
+
+/**
+ * LettersOfResponsibilityController class
+ *
+ * @author XH
+ * @date 2025/08/04
+ */
+@RestController
+@RequestMapping("/lor")
+public class LettersOfResponsibilityController {
+    private static final Logger log = LoggerFactory.getLogger(LettersOfResponsibilityController.class);
+    @Autowired
+    private QhseTargetResponsibilityDocumentServiceImpl qhseTargetResponsibilityDocumentService;
+
+    /**
+     * @param id
+     * @param response
+     */
+    @GetMapping("/signature/preview")
+    public void lettersOfResponsibilitySignaturePreview(@RequestBody Map<String, String> mapData, HttpServletResponse response) {
+        log.info("增加签名接口入参为:{}", mapData);
+        qhseTargetResponsibilityDocumentService.lettersOfResponsibilitySignaturePreview(mapData, response);
+    }
+}

+ 4 - 7
qhse-server/src/main/java/com/rongwei/jxkh/controller/SysPagePartController.java

@@ -1,7 +1,6 @@
-package com.rongwei.jxkh.controller;
+package com.rongwei.controller;
 
 
-import com.rongwei.bscommon.sys.dao.SysPagePartDao;
 import com.rongwei.bscommon.sys.service.SysPagePartService;
 import com.rongwei.bsentity.domain.SysPagePartDo;
 import com.rongwei.rwcommon.base.R;
@@ -13,12 +12,10 @@ import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
-import java.util.HashMap;
-
 @RestController
 @RequestMapping("page-part")
 @Slf4j
-public class SysPagePartController {
+public class PagePartController {
 
     private final Logger logger = LoggerFactory.getLogger(getClass());
 
@@ -26,10 +23,9 @@ public class SysPagePartController {
     SysPagePartService sysPagePartService;
 
 
-
     @GetMapping("/getPageInfo/{id}")
     public R getUserById(@PathVariable String id) {
-        logger.info("/getPageInfo 入参 id: {}",id);
+        logger.info("/getPageInfo 入参 id: {}", id);
         SysPagePartDo sysPagePartDo = sysPagePartService.getById(id);
         return R.ok(sysPagePartDo);
 
@@ -37,6 +33,7 @@ public class SysPagePartController {
 
     /**
      * 通用主从表insert执行
+     *
      * @param masterSlaveInsert
      * @throws Exception
      */

+ 15 - 0
qhse-server/src/main/resources/license.xml

@@ -0,0 +1,15 @@
+<License>
+    <Data>
+        <Products>
+            <Product>Aspose.Total for Java</Product>
+            <Product>Aspose.Words for Java</Product>
+        </Products>
+        <EditionType>Enterprise</EditionType>
+        <SubscriptionExpiry>20991231</SubscriptionExpiry>
+        <LicenseExpiry>20991231</LicenseExpiry>
+        <SerialNumber>8bfe198c-7f0c-4ef8-8ff0-acc3237bf0d7</SerialNumber>
+    </Data>
+    <Signature>
+        sNLLKGMUdF0r8O1kKilWAGdgfs2BvJb/2Xp8p5iuDVfZXmhppo+d0Ran1P9TKdjV4ABwAgKXxJ3jcQTqE/2IRfqwnPf8itN8aFZlV3TJPYeD3yWE7IT55Gz6EijUpC7aKeoohTb4w2fpox58wWoF3SNp6sK6jDfiAUGEHYJ9pjU=
+    </Signature>
+</License>