Browse Source

优化还原内容

sjj_dev
zhouhaibin 4 days ago
parent
commit
c06430f904
  1. 4
      ruoyi-admin/src/main/resources/application-dev.yml
  2. 395
      zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/impl/SjjDocumentTasksServiceImpl.java

4
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 # 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 # username: root
# password: root # password: root
url: jdbc:mysql://10.1.21.250:3306/sjjtable?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/sjjtable?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/sjjtable?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/sjjtable?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
username: root username: root
password: 'HXj-6nR|D8xy*h#!I&:(' password: 'HXj-6nR|D8xy*h#!I&:('
# 从库数据源 # 从库数据源

395
zaojiaManagement/zaojia-productManagement/src/main/java/org/dromara/productManagement/service/impl/SjjDocumentTasksServiceImpl.java

@ -1,10 +1,6 @@
package org.dromara.productManagement.service.impl; package org.dromara.productManagement.service.impl;
import cn.dev33.satoken.stp.StpUtil;
import net.lingala.zip4j.ZipFile;
import net.lingala.zip4j.model.FileHeader;
import okhttp3.*; import okhttp3.*;
import org.dromara.common.core.domain.model.LoginUser;
import org.dromara.common.core.utils.MapstructUtils; import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils; import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.mybatis.core.page.TableDataInfo;
@ -25,18 +21,12 @@ import org.dromara.productManagement.domain.vo.SjjDocumentTasksVo;
import org.dromara.productManagement.domain.SjjDocumentTasks; import org.dromara.productManagement.domain.SjjDocumentTasks;
import org.dromara.productManagement.mapper.SjjDocumentTasksMapper; import org.dromara.productManagement.mapper.SjjDocumentTasksMapper;
import org.dromara.productManagement.service.ISjjDocumentTasksService; import org.dromara.productManagement.service.ISjjDocumentTasksService;
import org.dromara.productManagement.utils.PdfParserUtils;
import java.io.*; import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Collection; import java.util.Collection;
import java.util.zip.ZipException;
/** /**
* 审计局标书任务Service业务层处理 * 审计局标书任务Service业务层处理
@ -98,10 +88,6 @@ public class SjjDocumentTasksServiceImpl implements ISjjDocumentTasksService {
private LambdaQueryWrapper<SjjDocumentTasks> buildQueryWrapper(SjjDocumentTasksBo bo) { private LambdaQueryWrapper<SjjDocumentTasks> buildQueryWrapper(SjjDocumentTasksBo bo) {
Map<String, Object> params = bo.getParams(); Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<SjjDocumentTasks> lqw = Wrappers.lambdaQuery(); LambdaQueryWrapper<SjjDocumentTasks> lqw = Wrappers.lambdaQuery();
if(!StpUtil.hasRole("superadmin")){
LoginUser user = LoginHelper.getLoginUser();
lqw.eq(SjjDocumentTasks::getCreateBy, user.getUserId());
}
lqw.like(StringUtils.isNotBlank(bo.getTaskName()), SjjDocumentTasks::getTaskName, bo.getTaskName()); lqw.like(StringUtils.isNotBlank(bo.getTaskName()), SjjDocumentTasks::getTaskName, bo.getTaskName());
lqw.like(StringUtils.isNotBlank(bo.getTenderDocumentName()), SjjDocumentTasks::getTenderDocumentName, bo.getTenderDocumentName()); lqw.like(StringUtils.isNotBlank(bo.getTenderDocumentName()), SjjDocumentTasks::getTenderDocumentName, bo.getTenderDocumentName());
lqw.like(StringUtils.isNotBlank(bo.getBidDocumentName()), SjjDocumentTasks::getBidDocumentName, bo.getBidDocumentName()); lqw.like(StringUtils.isNotBlank(bo.getBidDocumentName()), SjjDocumentTasks::getBidDocumentName, bo.getBidDocumentName());
@ -118,71 +104,23 @@ public class SjjDocumentTasksServiceImpl implements ISjjDocumentTasksService {
* @return 是否新增成功 * @return 是否新增成功
*/ */
@Override @Override
public Boolean insertByBo(SjjDocumentTasksBo bo) throws IOException { public Boolean insertByBo(SjjDocumentTasksBo bo) {
SjjDocumentTasks add = MapstructUtils.convert(bo, SjjDocumentTasks.class); SjjDocumentTasks add = MapstructUtils.convert(bo, SjjDocumentTasks.class);
String bidDocZipOssId = add.getBidDocZipOssId(); String bidDocOssId = add.getBidDocZipOssId();
String tenderDocPath="";
String tenderDocName="";
SysOssVo bidZipFileInfo = ossService.getById(Long.valueOf(bidDocZipOssId));
String bidZipName = bidZipFileInfo.getOriginalName();
String bidZipNameWithoutExt = bidZipName;
if (bidZipName.lastIndexOf(".") > 0) {
bidZipNameWithoutExt = bidZipName.substring(0, bidZipName.lastIndexOf("."));
}
String bidZipPath = fileRootPath + bidZipFileInfo.getFileName();
String tenderDocOssId = add.getTenderDocOssId(); String tenderDocOssId = add.getTenderDocOssId();
if(StringUtils.isNotBlank(tenderDocOssId)){ SysOssVo bidFileInfo = ossService.getById(Long.valueOf(bidDocOssId));
String bidDocName = bidFileInfo.getOriginalName();
String bidDocPath = fileRootPath + bidFileInfo.getFileName();
String tenderDocName="";
String tenderDocPath="";
if(tenderDocOssId != null){
SysOssVo tenderFileInfo = ossService.getById(Long.valueOf(tenderDocOssId)); SysOssVo tenderFileInfo = ossService.getById(Long.valueOf(tenderDocOssId));
tenderDocName = tenderFileInfo.getOriginalName(); tenderDocName = tenderFileInfo.getOriginalName();
tenderDocPath = fileRootPath + tenderFileInfo.getFileName(); tenderDocPath = fileRootPath + tenderFileInfo.getFileName();
add.setTenderDocumentName(tenderDocName);
}
add.setBidDocumentName(bidZipName);
// 创建唯一文件夹
String uniqueFolderName = "task_" + System.currentTimeMillis() + "_" + Math.abs(bidZipName.hashCode());
String taskFolder = tempfilePath + File.separator + uniqueFolderName;
File taskFolderDir = new File(taskFolder);
if (!taskFolderDir.exists()) {
taskFolderDir.mkdirs();
}
// 创建四个子文件夹
String bidOriginalDir = taskFolder + File.separator + "bid_original"; // 投标文件解压后的原始文件
String bidTxtDir = taskFolder + File.separator + "bid_txt"; // 投标文件解析后的TXT文件
String tenderOriginalDir = taskFolder + File.separator + "tender_original"; // 招标文件原始文件
String tenderTxtDir = taskFolder + File.separator + "tender_txt"; // 招标文件解析后的TXT文件
bidOriginalDir =bidOriginalDir+ File.separator + bidZipNameWithoutExt;
// 创建子文件夹
new File(bidOriginalDir).mkdirs();
new File(bidTxtDir).mkdirs();
new File(tenderOriginalDir).mkdirs();
new File(tenderTxtDir).mkdirs();
// 处理投标文件压缩包
processZipFile(add.getTaskName(),bidZipPath, bidOriginalDir, bidTxtDir);
// 复制招标文件到任务文件夹
File tenderDoc = new File(tenderDocPath);
if (tenderDoc.exists()) {
// 复制招标文件到招标文件原始目录
File tenderDocCopy = new File(tenderOriginalDir, tenderDocName);
try (FileInputStream fis = new FileInputStream(tenderDoc);
FileOutputStream fos = new FileOutputStream(tenderDocCopy)) {
byte[] buffer = new byte[1024];
int length;
while ((length = fis.read(buffer)) > 0) {
fos.write(buffer, 0, length);
}
}
// 如果是PDF文件,解析其内容到招标文件TXT目录
if (tenderDocName.toLowerCase().endsWith(".pdf") && PdfParserUtils.isValidPdf(tenderDocCopy.getAbsolutePath())) {
if (add.getTaskName().equals("ssjjbidAnalysis")){
processAndSavePdfContent(tenderDocCopy, tenderTxtDir, getSystemCharset());
}
}
} }
add.setBidDocumentName(bidDocName);
add.setTenderDocumentName(tenderDocName);
add.setProgressStatus("PENDING"); add.setProgressStatus("PENDING");
validEntityBeforeSave(add); validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0; boolean flag = baseMapper.insert(add) > 0;
@ -198,10 +136,13 @@ public class SjjDocumentTasksServiceImpl implements ISjjDocumentTasksService {
throw new IllegalArgumentException("无效的任务名称: " + add.getTaskName()); throw new IllegalArgumentException("无效的任务名称: " + add.getTaskName());
} }
// Request request = new Request.Builder()
// .url(url+"?userId="+ LoginHelper.getUserId()+"&taskId="+taskId+"&filename="+filename+"&taskName="+taskName+"&priority="+priority)
// .build();
HttpUrl.Builder urlBuilder = HttpUrl.parse(chatUrl +"/back/taskStart").newBuilder(); HttpUrl.Builder urlBuilder = HttpUrl.parse(chatUrl +"/back/taskStart").newBuilder();
urlBuilder.addQueryParameter("userId", String.valueOf(LoginHelper.getUserId())); urlBuilder.addQueryParameter("userId", String.valueOf(LoginHelper.getUserId()));
urlBuilder.addQueryParameter("taskId", String.valueOf(add.getId())); urlBuilder.addQueryParameter("taskId", String.valueOf(add.getId()));
urlBuilder.addQueryParameter("filename", bidOriginalDir+"\n"+tenderOriginalDir); urlBuilder.addQueryParameter("filename", bidDocPath+"\n"+tenderDocPath);
urlBuilder.addQueryParameter("taskName", add.getTaskName()); urlBuilder.addQueryParameter("taskName", add.getTaskName());
urlBuilder.addQueryParameter("priority", "1"); urlBuilder.addQueryParameter("priority", "1");
Request request = new Request.Builder() Request request = new Request.Builder()
@ -224,305 +165,6 @@ public class SjjDocumentTasksServiceImpl implements ISjjDocumentTasksService {
return flag; return flag;
} }
/**
* 处理ZIP文件解压并解析PDF
*
* @param zipFilePath ZIP文件路径
* @param originalDir 存放解压原始文件的目录
* @param txtDir 存放PDF解析后TXT文件的目录
* @throws IOException 解压或解析过程中发生IO错误
* @throws ZipException ZIP文件处理错误
*/
private void processZipFile(String taskName,String zipFilePath, String originalDir, String txtDir) throws IOException, ZipException {
// 创建解压目标目录(如果不存在)
File extractDirFile = new File(originalDir);
if (!extractDirFile.exists()) {
extractDirFile.mkdirs();
}
// 检测最佳编码
Charset bestCharset = detectBestCharset(zipFilePath);
try {
// 使用zip4j解压文件
ZipFile zipFile = new ZipFile(zipFilePath);
zipFile.setCharset(bestCharset);
// 获取所有文件头
List<FileHeader> fileHeaders = zipFile.getFileHeaders();
for (FileHeader fileHeader : fileHeaders) {
// 跳过目录项
if (fileHeader.isDirectory()) {
continue;
}
try {
// 获取文件名(不包括路径)
String fileName = new File(fileHeader.getFileName()).getName();
// 提取到指定目录,使用新的文件名
zipFile.extractFile(fileHeader, originalDir, fileName);
} catch (Exception e) {
// 如果使用检测到的编码解压失败,使用系统默认编码重试
try {
ZipFile fallbackZipFile = new ZipFile(zipFilePath);
fallbackZipFile.setCharset(getSystemCharset());
fallbackZipFile.extractFile(fileHeader.getFileName(), originalDir);
} catch (Exception fallbackEx) {
System.err.println("解压文件失败: " + fileHeader.getFileName() + ", 错误: " + fallbackEx.getMessage());
}
}
}
// 递归处理所有PDF文件
processAllPdfFiles(taskName,extractDirFile, txtDir, bestCharset);
} catch (Exception e) {
// 如果使用检测的编码失败,尝试直接整体解压
try {
ZipFile zipFile = new ZipFile(zipFilePath);
zipFile.setCharset(getSystemCharset());
zipFile.extractAll(originalDir);
processAllPdfFiles(taskName,extractDirFile, txtDir, getSystemCharset());
} catch (Exception e2) {
System.err.println("解压失败: " + e2.getMessage());
throw new IOException("解压失败", e2);
}
}
}
/**
* 检测ZIP文件的最佳字符编码
* 通过对比不同编码下的文件名可读性来确定最佳编码
*/
private Charset detectBestCharset(String zipFilePath) {
// 常用的中文编码
Charset[] charsets = {
Charset.forName("GB18030"), // 首选,覆盖面最广的中文编码
Charset.forName("GBK"), // 次选,常用中文编码
StandardCharsets.UTF_8, // 通用编码
getSystemCharset() // 系统默认编码
};
int bestScore = -1;
Charset bestCharset = getSystemCharset(); // 默认使用系统字符集
try {
// 尝试每种编码并评分
for (Charset charset : charsets) {
int score = evaluateCharsetForZip(zipFilePath, charset);
if (score > bestScore) {
bestScore = score;
bestCharset = charset;
}
}
} catch (Exception e) {
System.err.println("检测字符集时出错: " + e.getMessage());
}
System.out.println("为ZIP文件选择的最佳字符集: " + bestCharset.name());
return bestCharset;
}
/**
* 评估特定字符集对ZIP文件的适用性
* 返回评分值分数越高表示编码越适合
*/
private int evaluateCharsetForZip(String zipFilePath, Charset charset) {
int score = 0;
try {
ZipFile zipFile = new ZipFile(zipFilePath);
zipFile.setCharset(charset);
List<FileHeader> fileHeaders = zipFile.getFileHeaders();
for (FileHeader fileHeader : fileHeaders) {
if (fileHeader.isDirectory()) continue;
String fileName = fileHeader.getFileName();
score += evaluateString(fileName, charset);
}
} catch (Exception e) {
// 如果使用此编码打开ZIP失败,得分为-1
return -1;
}
return score;
}
/**
* 评估字符串在特定编码下的可读性
* 检查是否包含乱码字符返回可读性得分
*/
private int evaluateString(String str, Charset charset) {
int score = 0;
try {
// 将字符串转换为字节,然后再转回来,检查是否有信息丢失
byte[] bytes = str.getBytes(charset);
String decoded = new String(bytes, charset);
if (str.equals(decoded)) {
score += 10; // 完全匹配加10分
}
// 检查是否包含常见乱码字符
score -= countCharactersInRange(str, 0xFFFD, 0xFFFD); // Unicode替换字符
score -= countCharactersInRange(str, 0xD800, 0xDFFF) * 2; // Unicode代理区域
// 检查特殊字符比例
int specialChars = countSpecialCharacters(str);
if (specialChars > str.length() / 3) {
score -= 5; // 特殊字符过多,扣分
}
// 检查中文字符的存在
int chineseChars = countChineseCharacters(str);
if (chineseChars > 0) {
score += 5; // 包含中文字符加分
}
} catch (Exception e) {
score -= 10; // 转换异常,大幅扣分
}
return score;
}
/**
* 计算字符串中特定Unicode范围内的字符数量
*/
private int countCharactersInRange(String str, int start, int end) {
int count = 0;
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if (c >= start && c <= end) {
count++;
}
}
return count;
}
/**
* 计算字符串中特殊字符非字母数字常用标点的数量
*/
private int countSpecialCharacters(String str) {
int count = 0;
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if (!Character.isLetterOrDigit(c) && !isCommonPunctuation(c)) {
count++;
}
}
return count;
}
/**
* 判断字符是否为常用标点符号
*/
private boolean isCommonPunctuation(char c) {
return c == '.' || c == ',' || c == ';' || c == ':' || c == '!' ||
c == '?' || c == '(' || c == ')' || c == '[' || c == ']' ||
c == '{' || c == '}' || c == '_' || c == '-' || c == ' ' ||
c == '/' || c == '\\';
}
/**
* 计算字符串中中文字符的数量
*/
private int countChineseCharacters(String str) {
int count = 0;
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if (isChinese(c)) {
count++;
}
}
return count;
}
/**
* 判断字符是否为中文字符
*/
private boolean isChinese(char c) {
Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
return ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS
|| ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
|| ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A;
}
/**
* 递归处理目录中的所有PDF文件
*
* @param directory 需要处理的目录
* @param txtOutputDir PDF解析后的TXT文件输出目录
* @param charset 字符集
*/
private void processAllPdfFiles(String taskName,File directory, String txtOutputDir, Charset charset) {
if (!directory.isDirectory()) {
return;
}
File[] files = directory.listFiles();
if (files == null) {
return;
}
for (File file : files) {
if (file.isDirectory()) {
// 递归处理子目录
processAllPdfFiles(taskName,file, txtOutputDir, charset);
} else if (file.getName().toLowerCase().endsWith(".pdf") && PdfParserUtils.isValidPdf(file.getAbsolutePath())) {
// 处理PDF文件
if (taskName.equals("sjjbidAnalysis")){
processAndSavePdfContent(file, txtOutputDir, charset);
}
}
}
}
/**
* 获取系统默认字符集
*
* @return 适合当前操作系统的字符集
*/
private Charset getSystemCharset() {
String osName = System.getProperty("os.name").toLowerCase();
return osName.contains("win") ? Charset.forName("GBK") : StandardCharsets.UTF_8;
}
/**
* 处理PDF文件并保存为TXT
*
* @param pdfFile PDF文件
* @param outputDir 输出目录
* @param charset 字符集
*/
private void processAndSavePdfContent(File pdfFile, String outputDir, Charset charset) {
try {
// 提取PDF段落
List<String> paragraphs = PdfParserUtils.extractParagraphs(pdfFile.getAbsolutePath());
if (paragraphs.isEmpty()) {
return;
}
// 创建TXT文件名(替换扩展名)
String txtFileName = pdfFile.getName().replaceAll("\\.pdf$", ".txt");
File txtFile = new File(outputDir, txtFileName);
// 写入TXT文件
try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(txtFile), charset))) {
for (String paragraph : paragraphs) {
writer.write(paragraph);
writer.newLine();
writer.newLine(); // 段落间添加空行
}
}
} catch (Exception e) {
}
}
/** /**
* 修改审计局标书任务 * 修改审计局标书任务
* *
@ -562,13 +204,11 @@ public class SjjDocumentTasksServiceImpl implements ISjjDocumentTasksService {
public Boolean ossRemoveById(List<String> ids, Boolean b) { public Boolean ossRemoveById(List<String> ids, Boolean b) {
List<SjjDocumentTasksVo> sjjDocumentTasksVos = baseMapper.selectVoByIds(ids); List<SjjDocumentTasksVo> sjjDocumentTasksVos = baseMapper.selectVoByIds(ids);
for (SjjDocumentTasksVo sjjDocumentTasksVo : sjjDocumentTasksVos) { for (SjjDocumentTasksVo sjjDocumentTasksVo : sjjDocumentTasksVos) {
if (sjjDocumentTasksVo.getTenderDocOssId() != null ) { if (sjjDocumentTasksVo.getTenderDocOssId() != null) {
ossService.deleteWithValidByIds(Collections.singletonList(Long.valueOf(sjjDocumentTasksVo.getTenderDocOssId())), true); ossService.deleteWithValidByIds(Collections.singletonList(Long.valueOf(sjjDocumentTasksVo.getTenderDocOssId())), true);
} }
if (sjjDocumentTasksVo.getBidDocZipOssId() != null ) { if (sjjDocumentTasksVo.getBidDocZipOssId() != null) {
ossService.deleteWithValidByIds(Collections.singletonList(Long.valueOf(sjjDocumentTasksVo.getBidDocZipOssId())), true); ossService.deleteWithValidByIds(Collections.singletonList(Long.valueOf(sjjDocumentTasksVo.getBidDocZipOssId())), true);
} }
SjjDocumentTasks convert = MapstructUtils.convert(sjjDocumentTasksVo, SjjDocumentTasks.class); SjjDocumentTasks convert = MapstructUtils.convert(sjjDocumentTasksVo, SjjDocumentTasks.class);
convert.setDeleteFlag("Y"); convert.setDeleteFlag("Y");
@ -577,4 +217,3 @@ public class SjjDocumentTasksServiceImpl implements ISjjDocumentTasksService {
return true; return true;
} }
} }

Loading…
Cancel
Save