diff --git a/ruoyi-admin/src/main/resources/application-dev.yml b/ruoyi-admin/src/main/resources/application-dev.yml index 6238ebc..204d775 100644 --- a/ruoyi-admin/src/main/resources/application-dev.yml +++ b/ruoyi-admin/src/main/resources/application-dev.yml @@ -52,8 +52,8 @@ spring: # url: jdbc:mysql://localhost:3306/zaojia?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # username: root # password: root -# url: jdbc:mysql://10.1.21.250:3306/aitable?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true - url: jdbc:mysql://218.0.1.42:53306/aitable?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true + url: jdbc:mysql://10.1.21.250:3306/aitable?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true +# url: jdbc:mysql://218.0.1.42:53306/aitable?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true username: root password: 'HXj-6nR|D8xy*h#!I&:(' # 从库数据源 diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml index 3ede292..91539dc 100644 --- a/ruoyi-admin/src/main/resources/application.yml +++ b/ruoyi-admin/src/main/resources/application.yml @@ -71,7 +71,7 @@ spring: basename: i18n/messages profiles: #@profiles.active@ - active: dev + active: test # 文件上传 servlet: multipart: diff --git a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/controller/DocumentTaskResultsController.java b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/controller/DocumentTaskResultsController.java index 7ddeaac..c5ea292 100644 --- a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/controller/DocumentTaskResultsController.java +++ b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/controller/DocumentTaskResultsController.java @@ -156,4 +156,16 @@ public class DocumentTaskResultsController extends BaseController { @PathVariable Long[] ids,HttpServletResponse response) { documentTaskResultsService.downloadResult(ids,response); } + + /** + * 获取PDF文件流 + * + * @param taskId 任务ID + */ + @GetMapping("/getPdfStream/{taskId}") + public void getPdfStream(@NotNull(message = "任务ID不能为空") + @PathVariable String taskId, + HttpServletResponse response) { + documentTaskResultsService.getPdfStream(taskId, response); + } } diff --git a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/DocumentTasks.java b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/DocumentTasks.java index 46e88d7..dcf42b1 100644 --- a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/DocumentTasks.java +++ b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/DocumentTasks.java @@ -80,4 +80,6 @@ public class DocumentTasks extends TenantEntity { */ private String taskIndustry; + private String pdfPath; + } diff --git a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/bo/DocumentTasksBo.java b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/bo/DocumentTasksBo.java index d3fa3a0..e21504a 100644 --- a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/bo/DocumentTasksBo.java +++ b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/bo/DocumentTasksBo.java @@ -30,7 +30,7 @@ public class DocumentTasksBo extends BaseTaskBo { */ private String id; - + private String pdfPath; diff --git a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/vo/BaseTaskVo.java b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/vo/BaseTaskVo.java index 57db8d4..cc54a68 100644 --- a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/vo/BaseTaskVo.java +++ b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/vo/BaseTaskVo.java @@ -61,7 +61,7 @@ public class BaseTaskVo { @ExcelProperty(value = "上传时间") private Date createTime; - + private Long ossId; /** * 创建者 */ @@ -70,4 +70,5 @@ public class BaseTaskVo { @ExcelProperty(value = "更新时间") private Date updateTime; + } diff --git a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/vo/DocumentTasksVo.java b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/vo/DocumentTasksVo.java index 8f03265..b989c94 100644 --- a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/vo/DocumentTasksVo.java +++ b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/domain/vo/DocumentTasksVo.java @@ -31,6 +31,6 @@ public class DocumentTasksVo extends BaseTaskVo implements Serializable { private static final long serialVersionUID = 1L; @ExcelProperty(value = "主键") private String id; - + private String pdfPath; } diff --git a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/IDocumentTaskResultsService.java b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/IDocumentTaskResultsService.java index 0c51933..38b3c86 100644 --- a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/IDocumentTaskResultsService.java +++ b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/IDocumentTaskResultsService.java @@ -95,4 +95,12 @@ public interface IDocumentTaskResultsService { Boolean updateResultItemStatus(String id, String field, String value); void downloadResult(Long[] ids, HttpServletResponse response); + + /** + * 获取PDF文件流 + * + * @param taskId 任务ID + * @param response HTTP响应对象 + */ + void getPdfStream(String taskId, HttpServletResponse response); } diff --git a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/impl/DocumentTaskResultsServiceImpl.java b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/impl/DocumentTaskResultsServiceImpl.java index a9595c7..6f5be07 100644 --- a/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/impl/DocumentTaskResultsServiceImpl.java +++ b/zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/impl/DocumentTaskResultsServiceImpl.java @@ -10,6 +10,7 @@ import com.vladsch.flexmark.parser.Parser; import com.vladsch.flexmark.util.ast.Node; import com.vladsch.flexmark.util.data.MutableDataSet; import jakarta.servlet.http.HttpServletResponse; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.FileUtils; import org.dromara.common.core.service.DictService; import org.dromara.common.core.utils.MapstructUtils; @@ -22,14 +23,20 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import lombok.RequiredArgsConstructor; import org.dromara.productManagement.domain.DocumentTaskResultDetail; +import org.dromara.productManagement.domain.DocumentTasks; +import org.dromara.productManagement.domain.bo.DocumentTasksBo; import org.dromara.productManagement.domain.vo.DocumentTaskResultVO; import org.dromara.productManagement.domain.vo.DocumentTasksVo; import org.dromara.productManagement.enums.TaskEnum; import org.dromara.productManagement.mapper.DocumentTaskResultDetailMapper; +import org.dromara.productManagement.mapper.DocumentTasksMapper; import org.dromara.productManagement.service.IDocumentTasksService; +import org.dromara.system.domain.vo.SysOssVo; +import org.dromara.system.service.ISysOssService; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.safety.Safelist; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.dromara.productManagement.domain.bo.DocumentTaskResultsBo; import org.dromara.productManagement.domain.vo.DocumentTaskResultsVo; @@ -37,17 +44,23 @@ import org.dromara.productManagement.domain.DocumentTaskResults; import org.dromara.productManagement.mapper.DocumentTaskResultsMapper; import org.dromara.productManagement.service.IDocumentTaskResultsService; import org.xhtmlrenderer.pdf.ITextRenderer; +import org.springframework.beans.factory.annotation.Value; +import javax.sql.DataSource; import javax.xml.parsers.SAXParser; import java.io.*; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Collection; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; +import java.nio.file.Files; /** * 文档任务结果Service业务层处理 @@ -57,12 +70,21 @@ import java.util.zip.ZipOutputStream; */ @RequiredArgsConstructor @Service +@Slf4j public class DocumentTaskResultsServiceImpl implements IDocumentTaskResultsService { private final DocumentTaskResultsMapper baseMapper; private final DocumentTaskResultDetailMapper documentTaskResultDetailMapper; private final IDocumentTasksService documentTasksService; + private final DocumentTasksMapper documentTasksMapper; private final DictService dictTypeService; + protected final ISysOssService ossService; + @Value("${chat.tempfilePath}") + protected String tempfilePath; + @Value("${chat.filePath}") + protected String fileRootPath; + @Autowired + private DataSource dataSource; /** * 查询文档任务结果 @@ -243,22 +265,22 @@ public class DocumentTaskResultsServiceImpl implements IDocumentTaskResultsServi if (!"isRead".equals(field) && !"isAdopted".equals(field)) { throw new RuntimeException("不支持更新的字段: " + field); } - + // 验证值是否合法 if (!"0".equals(value) && !"1".equals(value)) { throw new RuntimeException("无效的值: " + value); } - + try { LambdaUpdateWrapper updateWrapper = Wrappers.lambdaUpdate(DocumentTaskResultDetail.class); updateWrapper.eq(DocumentTaskResultDetail::getId, id); - + if ("isRead".equals(field)) { updateWrapper.set(DocumentTaskResultDetail::getIsRead, value); } else { updateWrapper.set(DocumentTaskResultDetail::getIsAdopted, value); } - + return documentTaskResultDetailMapper.update(null, updateWrapper) > 0; } catch (Exception e) { throw new RuntimeException("更新状态失败: " + e.getMessage(), e); @@ -282,7 +304,6 @@ public class DocumentTaskResultsServiceImpl implements IDocumentTaskResultsServi DocumentTasksVo documentTasksVo = documentTasksService.queryById(list.get(0).getDocumentTaskId()); String documentName = documentTasksVo.getDocumentName(); - String tempDir = System.getProperty("java.io.tmpdir"); String zipFileName = "results_" +documentName + ".zip"; String zipFilePath = tempDir + File.separator + zipFileName; @@ -520,4 +541,104 @@ public class DocumentTaskResultsServiceImpl implements IDocumentTaskResultsServi content = content.replaceAll("style=\"\"", ""); return content.trim(); } + + @Override + public void getPdfStream(String taskId, HttpServletResponse response) { + try { + // 查询任务信息 + DocumentTasksVo task = documentTasksService.queryById(Long.valueOf(taskId)); + String outputPath = tempfilePath + File.separator + "pdf_preview" + File.separator; + String filerotPath =""; + if (task == null) { + throw new RuntimeException("任务不存在"); + } + + String pdfPath = task.getPdfPath(); + String filePath=""; + + if (StringUtils.isNotEmpty(pdfPath)) { + // 如果pdfPath存在,直接使用该路径 + filePath = pdfPath; + } else { + // 如果pdfPath不存在,从oss获取文件 + Long ossId = task.getOssId(); + if (ossId == null) { + throw new RuntimeException("文件不存在"); + } + + SysOssVo fileInfo = ossService.getById(ossId); + if (fileInfo == null) { + throw new RuntimeException("文件信息不存在"); + } + + String fileName = fileInfo.getOriginalName(); + + // 创建pdf预览目录 + File previewDir = new File(outputPath); + if (!previewDir.exists()) { + previewDir.mkdirs(); + } + + filerotPath = fileRootPath + fileInfo.getFileName(); + + // 如果不是pdf文件,需要转换 + if (!fileName.toLowerCase().endsWith(".pdf")) { + // 更新文件路径为转换后的pdf路径 + String originalFileName = fileInfo.getFileName(); + // 获取不带路径的文件名 + String fileNameOnly = originalFileName.substring(originalFileName.lastIndexOf("/") + 1); + // 获取不带扩展名的文件名 + String fileNameWithoutExt = fileNameOnly.substring(0, fileNameOnly.lastIndexOf(".")); + filePath = outputPath + fileNameWithoutExt + ".pdf"; + log.info("开始转换文件: " + fileName + " -> " + filePath); + } + } + log.info("开始输出文件: " + filePath); + // 读取文件并输出到response + File file = new File(filePath); + if (!file.exists()) { + log.info("开始转换文件: 文件不存在" + filePath); + // 使用libreoffice转换为pdf + ProcessBuilder builder = new ProcessBuilder("libreoffice", "--headless", "--convert-to", "pdf", filerotPath, "--outdir", outputPath); + Process process = builder.start(); + int completed = process.waitFor(); + if (completed != 0) { + InputStream errorStream = process.getErrorStream(); + String errorMessage = new String(errorStream.readAllBytes()); + process.destroyForcibly(); + throw new RuntimeException("文件转换失败: " + errorMessage); + } + process.destroyForcibly(); + } + log.info("开始输出文件: 文件存在" + filePath); + // 使用JDBC更新数据库 + try (Connection conn = dataSource.getConnection()) { + String sql = "UPDATE document_tasks SET pdf_path = ? WHERE id = ?"; + try (PreparedStatement pstmt = conn.prepareStatement(sql)) { + pstmt.setString(1, filePath); + pstmt.setLong(2, Long.parseLong(taskId)); + pstmt.executeUpdate(); + } + } catch (SQLException e) { + log.error("更新PDF路径失败", e); + throw new RuntimeException("更新PDF路径失败: " + e.getMessage()); + } + + response.setContentType("application/pdf"); + response.setHeader("Content-Disposition", "inline; filename=" + URLEncoder.encode(file.getName(), StandardCharsets.UTF_8.name())); + + try (FileInputStream fis = new FileInputStream(file); + BufferedInputStream bis = new BufferedInputStream(fis, 8192); + OutputStream os = response.getOutputStream()) { + byte[] buffer = new byte[8192]; + int bytesRead; + while ((bytesRead = bis.read(buffer)) != -1) { + os.write(buffer, 0, bytesRead); + } + os.flush(); + } + } catch (Exception e) { + throw new RuntimeException("获取PDF文件流失败: " + e.getMessage()); + } + } }