新增 页码定位 美化前端 其他功能调整等

This commit is contained in:
高雄
2026-01-19 17:46:32 +08:00
parent 904af89190
commit 7dc0469b30
48 changed files with 10922 additions and 1241 deletions

View File

@@ -7,12 +7,18 @@ import cn.keking.service.FileHandlerService;
import cn.keking.service.FilePreview;
import cn.keking.service.TifToPdfService;
import cn.keking.utils.DownloadUtils;
import cn.keking.utils.FileConvertStatusManager;
import cn.keking.utils.KkFileUtils;
import cn.keking.utils.WebUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.ui.Model;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* tiff 图片文件处理
@@ -22,21 +28,37 @@ import java.util.List;
@Service
public class TiffFilePreviewImpl implements FilePreview {
private static final Logger logger = LoggerFactory.getLogger(TiffFilePreviewImpl.class);
// 用于处理回调的线程池
private static final ExecutorService callbackExecutor = Executors.newFixedThreadPool(3);
private final FileHandlerService fileHandlerService;
private final OtherFilePreviewImpl otherFilePreview;
private final TifToPdfService tiftoservice;
public TiffFilePreviewImpl(FileHandlerService fileHandlerService,OtherFilePreviewImpl otherFilePreview,TifToPdfService tiftoservice) {
private final OfficeFilePreviewImpl officefilepreviewimpl;
public TiffFilePreviewImpl(FileHandlerService fileHandlerService, OtherFilePreviewImpl otherFilePreview, TifToPdfService tiftoservice, OfficeFilePreviewImpl officefilepreviewimpl) {
this.fileHandlerService = fileHandlerService;
this.otherFilePreview = otherFilePreview;
this.tiftoservice = tiftoservice;
this.officefilepreviewimpl = officefilepreviewimpl;
}
@Override
public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) {
String fileName = fileAttribute.getName();
String tifPreviewType = ConfigConstants.getTifPreviewType();
String cacheName = fileAttribute.getCacheName();
String cacheName = fileAttribute.getCacheName();
String outFilePath = fileAttribute.getOutFilePath();
boolean forceUpdatedCache=fileAttribute.forceUpdatedCache();
boolean forceUpdatedCache = fileAttribute.forceUpdatedCache();
// 查询转换状态
String statusResult = officefilepreviewimpl.checkAndHandleConvertStatus(model, fileName, cacheName, fileAttribute);
if (statusResult != null) {
return statusResult;
}
if ("jpg".equalsIgnoreCase(tifPreviewType) || "pdf".equalsIgnoreCase(tifPreviewType)) {
if (forceUpdatedCache || !fileHandlerService.listConvertedFiles().containsKey(cacheName) || !ConfigConstants.isCacheEnabled()) {
ReturnResponse<String> response = DownloadUtils.downLoad(fileAttribute, fileName);
@@ -44,66 +66,111 @@ public class TiffFilePreviewImpl implements FilePreview {
return otherFilePreview.notSupportedFile(model, fileAttribute, response.getMsg());
}
String filePath = response.getContent();
try {
// 启动异步转换
startAsyncTiffConversion(filePath, outFilePath, cacheName, fileName, fileAttribute, tifPreviewType, forceUpdatedCache);
// 返回等待页面
model.addAttribute("fileName", fileName);
model.addAttribute("message", "文件正在转换中,请稍候...");
return WAITING_FILE_PREVIEW_PAGE;
} catch (Exception e) {
logger.error("Failed to start TIF conversion: {}", filePath, e);
return otherFilePreview.notSupportedFile(model, fileAttribute, "TIF转换异常请联系系统管理员!");
}
} else {
// 如果已有缓存,直接渲染预览
if ("pdf".equalsIgnoreCase(tifPreviewType)) {
try {
tiftoservice.convertTif2Pdf(filePath, outFilePath,forceUpdatedCache);
} catch (Exception e) {
if (e.getMessage().contains("Bad endianness tag (not 0x4949 or 0x4d4d)") ) {
model.addAttribute("imgUrls", url);
model.addAttribute("currentUrl", url);
return PICTURE_FILE_PREVIEW_PAGE;
}else {
return otherFilePreview.notSupportedFile(model, fileAttribute, "TIF转pdf异常请联系系统管理员!" );
}
}
//是否保留TIFF源文件
if (!fileAttribute.isCompressFile() && ConfigConstants.getDeleteSourceFile()) {
KkFileUtils.deleteFileByPath(filePath);
}
if (ConfigConstants.isCacheEnabled()) {
// 加入缓存
fileHandlerService.addConvertedFile(cacheName, fileHandlerService.getRelativePath(outFilePath));
}
model.addAttribute("pdfUrl", WebUtils.encodeFileName(cacheName));
return PDF_FILE_PREVIEW_PAGE;
}else {
// 将tif转换为jpg返回转换后的文件路径、文件名的list
List<String> listPic2Jpg;
try {
listPic2Jpg = tiftoservice.convertTif2Jpg(filePath, outFilePath,forceUpdatedCache);
} catch (Exception e) {
if (e.getMessage().contains("Bad endianness tag (not 0x4949 or 0x4d4d)") ) {
model.addAttribute("imgUrls", url);
model.addAttribute("currentUrl", url);
return PICTURE_FILE_PREVIEW_PAGE;
}else {
return otherFilePreview.notSupportedFile(model, fileAttribute, "TIF转JPG异常请联系系统管理员!" );
}
} else if ("jpg".equalsIgnoreCase(tifPreviewType)) {
List<String> imgCache = fileHandlerService.getImgCache(cacheName);
if (imgCache == null || imgCache.isEmpty()) {
return otherFilePreview.notSupportedFile(model, fileAttribute, "TIF转换缓存异常请联系系统管理员!");
}
//是否保留源文件,转换失败保留源文件,转换成功删除源文件
if(!fileAttribute.isCompressFile() && ConfigConstants.getDeleteSourceFile()) {
KkFileUtils.deleteFileByPath(filePath);
}
if (ConfigConstants.isCacheEnabled()) {
// 加入缓存
fileHandlerService.putImgCache(cacheName, listPic2Jpg);
fileHandlerService.addConvertedFile(cacheName, fileHandlerService.getRelativePath(outFilePath));
}
model.addAttribute("imgUrls", listPic2Jpg);
model.addAttribute("currentUrl", listPic2Jpg.get(0));
model.addAttribute("imgUrls", imgCache);
model.addAttribute("currentUrl", imgCache.getFirst());
return PICTURE_FILE_PREVIEW_PAGE;
}
}
if ("pdf".equalsIgnoreCase(tifPreviewType)) {
model.addAttribute("pdfUrl", WebUtils.encodeFileName(cacheName));
return PDF_FILE_PREVIEW_PAGE;
}
else if ("jpg".equalsIgnoreCase(tifPreviewType)) {
model.addAttribute("imgUrls", fileHandlerService.getImgCache(cacheName));
model.addAttribute("currentUrl", fileHandlerService.getImgCache(cacheName).get(0));
return PICTURE_FILE_PREVIEW_PAGE;
}
}
// 处理普通TIF预览不进行转换
return handleRegularTiffPreview(url, model, fileAttribute, fileName, forceUpdatedCache, outFilePath);
}
/**
* 启动异步TIF转换
*/
private void startAsyncTiffConversion(String filePath, String outFilePath, String cacheName,
String fileName, FileAttribute fileAttribute,
String tifPreviewType, boolean forceUpdatedCache) {
// 启动异步转换
CompletableFuture<Void> conversionFuture = CompletableFuture.supplyAsync(() -> {
try {
// 更新状态
FileConvertStatusManager.startConvert(cacheName);
FileConvertStatusManager.updateProgress(cacheName, "正在启动TIF转换", 10);
if ("pdf".equalsIgnoreCase(tifPreviewType)) {
tiftoservice.convertTif2Pdf(filePath, outFilePath,fileName,cacheName, forceUpdatedCache);
// 转换成功,更新缓存
if (ConfigConstants.isCacheEnabled()) {
fileHandlerService.addConvertedFile(cacheName, fileHandlerService.getRelativePath(outFilePath));
}
} else {
List<String> listPic2Jpg = tiftoservice.convertTif2Jpg(filePath, outFilePath,fileName,cacheName, forceUpdatedCache);
// 转换成功,更新缓存
if (ConfigConstants.isCacheEnabled()) {
fileHandlerService.putImgCache(cacheName, listPic2Jpg);
fileHandlerService.addConvertedFile(cacheName, fileHandlerService.getRelativePath(outFilePath));
}
}
FileConvertStatusManager.convertSuccess(cacheName);
return null;
} catch (Exception e) {
// 检查是否为Bad endianness tag异常
if (e.getMessage() != null && e.getMessage().contains("Bad endianness tag (not 0x4949 or 0x4d4d)")) {
// 特殊处理:对于这种异常,我们不标记为转换失败,而是记录日志
logger.warn("TIF文件格式异常Bad endianness tag将尝试直接预览: {}", filePath);
FileConvertStatusManager.convertSuccess(cacheName);
return null;
} else {
logger.error("TIF转换执行失败: {}", cacheName, e);
// 检查是否已经标记为超时
FileConvertStatusManager.ConvertStatus status = FileConvertStatusManager.getConvertStatus(cacheName);
if (status == null || status.getStatus() != FileConvertStatusManager.Status.TIMEOUT) {
FileConvertStatusManager.markError(cacheName, "转换失败: " + e.getMessage());
}
throw new RuntimeException(e);
}
}
});
// 添加转换完成后的回调
conversionFuture.thenRunAsync(() -> {
try {
// 是否保留源文件(只在转换成功后才删除)
if (!fileAttribute.isCompressFile() && ConfigConstants.getDeleteSourceFile()) {
KkFileUtils.deleteFileByPath(filePath);
}
} catch (Exception e) {
logger.error("TIF转换后续处理失败: {}", filePath, e);
}
}, callbackExecutor).exceptionally(throwable -> {
// 转换失败,记录日志但不删除源文件
logger.error("TIF转换失败保留源文件供排查: {}", filePath, throwable);
return null;
});
}
/**
* 处理普通TIF预览不进行转换
*/
private String handleRegularTiffPreview(String url, Model model, FileAttribute fileAttribute,
String fileName, boolean forceUpdatedCache, String outFilePath) {
// 不是http开头浏览器不能直接访问需下载到本地
if (url != null && !url.toLowerCase().startsWith("http")) {
if (forceUpdatedCache || !fileHandlerService.listConvertedFiles().containsKey(fileName) || !ConfigConstants.isCacheEnabled()) {
@@ -117,12 +184,11 @@ public class TiffFilePreviewImpl implements FilePreview {
fileHandlerService.addConvertedFile(fileName, fileHandlerService.getRelativePath(outFilePath));
}
} else {
model.addAttribute("currentUrl", WebUtils.encodeFileName(fileName));
model.addAttribute("currentUrl", WebUtils.encodeFileName(fileName));
}
return TIFF_FILE_PREVIEW_PAGE;
}
model.addAttribute("currentUrl", url);
return TIFF_FILE_PREVIEW_PAGE;
}
}
}