|
|
@ -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<DocumentTaskResultDetail> 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()); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|