diff --git a/laws-module-system/pom.xml b/laws-module-system/pom.xml
index ca924543..99ef1c0b 100644
--- a/laws-module-system/pom.xml
+++ b/laws-module-system/pom.xml
@@ -83,6 +83,12 @@
pdfbox
2.0.27
+
+ org.dom4j
+ dom4j
+ 2.1.3
+ compile
+
diff --git a/laws-module-system/src/main/java/com/jero/modules/util/SysOnlyOfficePdfUtil.java b/laws-module-system/src/main/java/com/jero/modules/util/SysOnlyOfficePdfUtil.java
new file mode 100644
index 00000000..84e0bce7
--- /dev/null
+++ b/laws-module-system/src/main/java/com/jero/modules/util/SysOnlyOfficePdfUtil.java
@@ -0,0 +1,238 @@
+package com.jero.modules.util;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.jero.common.exception.JeroBootException;
+import com.jero.common.util.CommonUtils;
+import com.jero.common.util.IntekeyUtils;
+import com.jero.common.util.MinioUtil;
+import com.jero.common.util.oConvertUtils;
+import com.jero.modules.oss.entity.OSSFile;
+import com.jero.modules.oss.service.IOSSFileService;
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpStatus;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.ContentType;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.util.EntityUtils;
+import org.dom4j.Document;
+import org.dom4j.DocumentHelper;
+import org.dom4j.Element;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.mock.web.MockMultipartFile;
+import org.springframework.stereotype.Component;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.file.Files;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * @author: Mzaxd
+ * @Date: 2024/4/25 9:08
+ */
+@Slf4j
+@Component
+public class SysOnlyOfficePdfUtil {
+
+ @Resource
+ private IOSSFileService ossFileService;
+
+ @Value("${file.downloadUrl}")
+ private String downloadFileUrl;
+
+ @Value("${onlyoffice.toUrl}")
+ private String onlyOfficeUrl;
+
+ @Value("${onlyoffice.transferPDfUrl}")
+ private String transferPDfUrl;
+
+ @Value(value = "${jero.uploadType}")
+ private String uploadType;
+
+ @Value("#{'${download.enable}'}")
+ private boolean enable;
+
+ @Value("${file.path}")
+ private String filePath;//文件存储路径
+
+ private static final int TIMEOUT = 60000; // 通用超时设置
+
+ @SneakyThrows
+ public void convertAndSavePdfFile(String fileName, String originFileId, String onlineFilePath) {
+ String key = UUID.randomUUID().toString();
+ log.info("转换的请求参数:onlyOfficeUrl:{}, filePdfName:{}, key:{}, originFileId:{}, onlineFilePath:{}", onlyOfficeUrl, fileName, key, originFileId, onlineFilePath);
+ // 获取onlyOffice转换后文件的url
+ String fileUrl = convertFile(fileName, key, onlineFilePath);
+ log.info("文件转换后PDF的URL: {}", fileUrl);
+
+ try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {
+ // 根据url获取转换后的文件
+ fetchAndSaveFile(httpClient, fileName, fileUrl, originFileId);
+ } // 自动关闭httpClient
+ }
+
+ private CloseableHttpClient createHttpClient() {
+ RequestConfig requestConfig = RequestConfig.custom()
+ .setSocketTimeout(TIMEOUT)
+ .setConnectionRequestTimeout(TIMEOUT)
+ .setConnectTimeout(TIMEOUT)
+ .build();
+
+ HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
+ return httpClientBuilder.setDefaultRequestConfig(requestConfig).build();
+ }
+
+ @SneakyThrows
+ private String convertFile(String fileName, String key, String onlineFilePath) {
+ Map parameters = new HashMap<>();
+ parameters.put("async", false);
+ parameters.put("filetype", "docx");
+ parameters.put("key", key);
+ parameters.put("outputtype", "pdf");
+ parameters.put("title", fileName + ".pdf");
+ parameters.put("url", downloadFileUrl + onlineFilePath);
+ log.info("转换文件参数: {}", parameters);
+ JSONObject requestJson = new JSONObject(parameters);
+ String data = requestJson.toString();
+
+ try (CloseableHttpClient httpClient = createHttpClient()) {
+ String url = "http://" + onlyOfficeUrl + transferPDfUrl;
+ log.info("访问onlyOfficeUrl:{}", url);
+ HttpPost httpPost = new HttpPost(url);
+ httpPost.setEntity(new StringEntity(data, "UTF-8"));
+ httpPost.setHeader("Content-type", "application/json; charset=UTF-8");
+
+ try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
+ return handleResponse(response);
+ }
+ }
+ }
+
+ @SneakyThrows
+ private void fetchAndSaveFile(CloseableHttpClient httpClient, String fileName, String fileUrl, String originFileId) {
+ String pdfFileName = fileName + ".pdf";
+ HttpGet get = new HttpGet(fileUrl);
+ try (CloseableHttpResponse response = httpClient.execute(get)) {
+ if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
+ throw new JeroBootException("Failed to fetch the file: " + response);
+ }
+ HttpEntity entity = response.getEntity();
+ if (entity != null) {
+ try (InputStream content = entity.getContent()) {
+ MultipartFile file = new MockMultipartFile(pdfFileName, pdfFileName, ContentType.APPLICATION_OCTET_STREAM.toString(), content);
+ // 保存文件逻辑
+ String savePath = CommonUtils.upload(file, "convert", uploadType);
+ if (oConvertUtils.isNotEmpty(savePath)) {
+ // 如果有的话,删除原来的pdf版本
+ LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>();
+ lambdaQueryWrapper.eq(OSSFile::getBindId, originFileId);
+ ossFileService.remove(lambdaQueryWrapper);
+
+ // 上传成功 进行数据库存储
+ OSSFile ossFile = new OSSFile();
+ // 文件名
+ ossFile.setFileName(pdfFileName);
+ ossFile.setUrl(savePath);
+ ossFile.setBindId(originFileId);
+ ossFileService.save(ossFile);
+ }
+ }
+ }
+ }
+ }
+
+ @SneakyThrows
+ private String handleResponse(CloseableHttpResponse response) {
+ HttpEntity entity = response.getEntity();
+ if (entity != null) {
+ String responseData = EntityUtils.toString(entity, "UTF-8");
+ return analysisXML(responseData);
+ }
+ return null;
+ }
+
+ @SneakyThrows
+ public static String analysisXML(String xmlString) {
+ log.info("OnlyOffice返回xmlString:{}", xmlString);
+ Document document = DocumentHelper.parseText(xmlString);
+ Element root = document.getRootElement();
+ return root.elementText("FileUrl").replaceAll("&", "&");
+ }
+
+ public List docFileTransferPdf(String fileIds) {
+ List resultList = new ArrayList<>();
+ // 获取所有需要生成pdf版本的文件
+ // 先获取所有有url的文件记录
+ LambdaQueryWrapper ossWrapper = new LambdaQueryWrapper<>();
+ ossWrapper.in(StrUtil.isNotBlank(fileIds), OSSFile::getId, Arrays.asList(fileIds.split(",")));
+ ossWrapper.isNotNull(OSSFile::getUrl);
+ List ossFileList = ossFileService.list(ossWrapper);
+ if (CollUtil.isEmpty(ossFileList)) {
+ return null;
+ }
+ // 筛选出后缀为doc或docx的文件
+ List docFileList = ossFileList.stream()
+ .filter(o -> o.getUrl().endsWith("doc") || o.getUrl().endsWith("docx"))
+ .collect(Collectors.toList());
+ // 筛选出已经转换过的pdf文件
+ Map> alreadyTransferFileMap = ossFileList.stream()
+ .filter(o -> StrUtil.isNotBlank(o.getBindId()))
+ .collect(Collectors.groupingBy(OSSFile::getBindId));
+ for (OSSFile ossFile : docFileList){
+ List existPdfFileList = alreadyTransferFileMap.get(ossFile.getId());
+ // 已经转换过的不再重复转换
+ if (CollUtil.isNotEmpty(existPdfFileList)) {
+ continue;
+ }
+ String docFileName = ossFile.getFileName();
+ log.info("开始处理文件名为 {} 的文件转换工作", docFileName);
+ // 根据文件url获取文件
+ InputStream isDecrypt;
+ try (InputStream is = MinioUtil.download(ossFile.getUrl())) {
+ isDecrypt = is;
+ // 文件解密
+ if (enable) {
+ isDecrypt = IntekeyUtils.autoDecryptInputStreamFile(isDecrypt, ossFile.getFileName());
+ }
+ // 转换为pdf
+ String pdfFileName = docFileName.substring(0, docFileName.lastIndexOf("."));
+ String targetPath = "convert/" + ossFile.getFileName();
+ File targetFile = new File(filePath + targetPath);
+ try (OutputStream outputStream = Files.newOutputStream(targetFile.toPath())) {
+ byte[] buffer = new byte[1024];
+ int bytesRead;
+ while ((bytesRead = isDecrypt.read(buffer)) != -1) {
+ outputStream.write(buffer, 0, bytesRead);
+ }
+ } catch (IOException e) {
+ log.error("文件写入失败:" + e.getMessage());
+ }
+ this.convertAndSavePdfFile(pdfFileName, ossFile.getId(), targetPath);
+ // 将下载到本地的文件删除
+ FileUtil.del(targetFile);
+ log.info("文件名为 {} 的文件转换成功", docFileName);
+ resultList.add(ossFile);
+ } catch (Exception e) {
+ log.error("文件名为 {} 的文件转换失败,失败原因{}", docFileName, e.getMessage());
+ }
+ }
+ return resultList;
+ }
+
+}
diff --git a/laws-modules/src/main/java/com/jero/modules/activiti/process/esRevisionAdvice/listener/ProcessESRevisionEndListener.java b/laws-modules/src/main/java/com/jero/modules/activiti/process/esRevisionAdvice/listener/ProcessESRevisionEndListener.java
index 703ed6a2..34f28333 100644
--- a/laws-modules/src/main/java/com/jero/modules/activiti/process/esRevisionAdvice/listener/ProcessESRevisionEndListener.java
+++ b/laws-modules/src/main/java/com/jero/modules/activiti/process/esRevisionAdvice/listener/ProcessESRevisionEndListener.java
@@ -12,10 +12,10 @@ import com.jero.modules.activiti.process.esRevisionAdvice.service.EsRevisionAdvi
import com.jero.modules.activiti.process.esRevisionAdvice.service.EsRevisionService;
import com.jero.modules.laws.common.constant.FieldCommon;
import com.jero.modules.laws.common.service.ILawsCommonService;
-import com.jero.modules.laws.enterprise.service.EnterpriseStandardPlanService;
import com.jero.modules.oss.entity.OSSFile;
import com.jero.modules.oss.service.IOSSFileService;
import com.jero.modules.tag.enums.TableNameEnum;
+import com.jero.modules.util.SysOnlyOfficePdfUtil;
import lombok.SneakyThrows;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.ExecutionListener;
@@ -60,12 +60,12 @@ public class ProcessESRevisionEndListener implements ExecutionListener {
@Resource
private EsRevisionAdviceService revisionAdviceService;
+ @Resource
+ private SysOnlyOfficePdfUtil sysOnlyOfficePdfUtil;
+
@Value(value = "${jero.uploadType}")
private String uploadType;
- @Resource
- private EnterpriseStandardPlanService planService;
-
@SneakyThrows
@Override
public void notify(DelegateExecution delegateExecution) {
@@ -105,7 +105,12 @@ public class ProcessESRevisionEndListener implements ExecutionListener {
variables.put(FieldCommon.ID, standardId);
String onEditFile = data.getOnEditFile();
// 发布稿
- variables.put(FieldCommon.FILE_PUBLISH_OF_ORIGINAL, onEditFile);
+ List ossFileList = sysOnlyOfficePdfUtil.docFileTransferPdf(onEditFile);
+ if (ossFileList != null && !ossFileList.isEmpty()) {
+ variables.put(FieldCommon.FILE_PUBLISH_OF_ORIGINAL, onEditFile + "," + ossFileList.get(0).getId());
+ } else {
+ variables.put(FieldCommon.FILE_PUBLISH_OF_ORIGINAL, onEditFile);
+ }
return variables;
}