From f423a12228518ca34b8e380b0515dd01ae91b02e Mon Sep 17 00:00:00 2001
From: 杜洪波 <1074825718@qq.com>
Date: 星期一, 03 十一月 2025 15:52:56 +0800
Subject: [PATCH] 文档借阅调整

---
 src/main/java/com/product/file/service/FileManagerService.java |  404 ++++++++++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 311 insertions(+), 93 deletions(-)

diff --git a/src/main/java/com/product/file/service/FileManagerService.java b/src/main/java/com/product/file/service/FileManagerService.java
index b20eae9..db4ae7e 100644
--- a/src/main/java/com/product/file/service/FileManagerService.java
+++ b/src/main/java/com/product/file/service/FileManagerService.java
@@ -1,10 +1,12 @@
 package com.product.file.service;
 
 import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.RandomUtil;
 import com.alibaba.fastjson.JSONObject;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import com.product.common.lang.StringUtils;
+import com.product.core.cache.util.RedisUtil;
 import com.product.core.config.CoreConst;
 import com.product.core.config.Global;
 import com.product.core.connection.ConnectionManager;
@@ -18,11 +20,17 @@
 import com.product.core.spring.context.SpringMVCContextHolder;
 import com.product.file.config.CmnConst;
 import com.product.file.config.FileCode;
+import com.product.file.util.AsposeUtil;
 import com.product.file.util.CreateDocumentIndexThread;
 import com.product.file.util.FileUtil;
 import com.product.file.util.FileUtils;
 import com.product.module.sys.entity.SystemUser;
+import com.product.tool.table.enums.FieldType;
 import com.product.util.BaseUtil;
+import com.product.util.http.HttpRequestUtil;
+import okhttp3.MediaType;
+import okhttp3.MultipartBody;
+import okhttp3.RequestBody;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -30,6 +38,8 @@
 import javax.servlet.http.HttpServletResponse;
 import java.io.*;
 import java.net.URLEncoder;
+import java.nio.file.Files;
+import java.nio.file.StandardCopyOption;
 import java.text.SimpleDateFormat;
 import java.util.*;
 
@@ -50,6 +60,15 @@
 	public BaseDao baseDao;
 	@Autowired
 	FileUtils fileUtils;
+
+	/**
+	 *  鏍囪鏂囦欢宸茶淇敼
+	 * @param uuid
+	 * @param userId
+	 */
+	public void signUpdateAttachment(String uuid, int userId) {
+		baseDao.executeUpdate("UPDATE product_sys_attachments SET updated_by = ?, updated_utc_datetime = NOW() WHERE uuid = ?", new Object[] {userId, uuid});
+	}
 
 	/**
 	 * 鑾峰彇闈欐�佽祫婧�
@@ -266,6 +285,134 @@
 		}
 	}
 
+    /**
+     * 闆嗙兢鏂囦欢鍚屾鏂规硶-鎺ユ敹
+     * @param rpe
+     * @return
+     */
+    public void clusterFileSyncAccept(RequestParameterEntity rpe) throws IOException {
+        List<String> ipList = RedisUtil.getSet(CoreConst.SYSTEM_IP_PORT_KEY, String.class);
+        String curRequestIp = rpe.getIp();
+        boolean checkFlag = false;
+        for (String ipInfo : ipList) {
+            if (!StringUtils.isEmpty(ipInfo) && ipInfo.contains(":") && curRequestIp.equals(ipInfo.split(":")[0])) {
+                checkFlag = true;
+                break;
+            }
+        }
+        if (!checkFlag) {
+            throw new BaseException(FileCode.CLUSTER_FILE_SYNC_CHECK_FAIL);
+        }
+        Map<Object, Object> otherMap = rpe.getOther();
+        Map<String, File> fileMap = rpe.getFiles();
+        File aimFile = new File(Global.getSystemConfig("local.dir", "") + File.separator + otherMap.get("relativePath"));
+        for (Map.Entry<String, File> entry : fileMap.entrySet()) {
+            File file = entry.getValue();
+            Files.copy(file.toPath(), aimFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
+        }
+    }
+
+    /**
+     * 闆嗙兢鏂囦欢鍚屾鏂规硶-璇锋眰璋冪敤
+     * @param file              鍚屾鐨勬枃浠�
+     * @param fileName          鏂囦欢鍚嶇О锛屼繚瀛樼殑鏂囦欢鍚嶇О锛屽氨鏄椂闂存埑+2浣嶉殢鏈哄瓧绗︿覆
+     * @param relativePath      鐩稿璺緞
+     * @param attachmentUUID    闄勮繎琛╱uid
+     * @param preLogFse         涔嬪墠鐨勬棩蹇梖se
+     */
+    public void clusterFileSyncRequest(File file, String fileName, String relativePath, String attachmentUUID, FieldSetEntity preLogFse) {
+        try {
+            if (file == null || StringUtils.isEmpty(fileName)) {
+                return;
+            }
+            List<String> ipList = RedisUtil.getSet(CoreConst.SYSTEM_IP_PORT_KEY, String.class);
+            String curIpInfo = Global.getSystemConfig(CoreConst.SYSTEM_NAME, "");
+            for (String ipInfo : ipList) {
+                // 鎺掗櫎褰撳墠
+                if (curIpInfo.equals(ipInfo)) {
+                   continue;
+                }
+                if (!StringUtils.isEmpty(ipInfo) && ipInfo.contains(":")) {
+                    String url = String.format("http://%s/lx/api/fileManager/cluster-file-sync/v1", ipInfo);
+                    RequestBody requestBody = new MultipartBody.Builder()
+                            .setType(MultipartBody.FORM)
+                            // 娣诲姞鏂囦欢瀛楁
+                            .addFormDataPart("file", fileName, RequestBody.create(MediaType.parse("application/octet-stream"), file))
+                            .addFormDataPart("title", fileName)
+                            .addFormDataPart("relativePath", relativePath)
+                            .build();
+                    JSONObject result = HttpRequestUtil.request(url, "POST", "multipart/form-data", requestBody);
+                    SpringMVCContextHolder.getSystemLogger().error("[6ctest]锛�" + result.toString());
+                    // 璁板綍鏃ュ織
+                    recordClusterSyncFileLog(result, attachmentUUID, curIpInfo, ipInfo, preLogFse);
+                }
+            }
+        } catch (Exception e) {
+            throw new BaseException(FileCode.CLUSTER_FILE_SYNC_FAIL);
+        }
+    }
+    public void clusterFileSyncRequest(File file, String fileName, String relativePath, String attachmentUUID) {
+        clusterFileSyncRequest(file, fileName, relativePath, attachmentUUID, null);
+    }
+
+    /**
+     * 璁板綍闆嗙兢鍚屾鏂囦欢鏃ュ織
+     * @param result            缁撴灉锛�-1-澶辫触锛�1-鎴愬姛锛�2-宸查噸鏂板鐞�
+     * @param attachmentUUID    闄勪欢uuid
+     * @param sourceIpInfo      璇锋眰鍦板潃淇℃伅
+     * @param targetIpInfo      鐩爣鍦板潃淇℃伅
+     * @param preLogFse         涔嬪墠鏃ュ織fse
+     */
+    private void recordClusterSyncFileLog(JSONObject result, String attachmentUUID, String sourceIpInfo, String targetIpInfo, FieldSetEntity preLogFse) {
+        FieldSetEntity logFse = new FieldSetEntity();
+        logFse.setTableName(CmnConst.PRODUCT_SYS_CLUSTER_SYNC_FILE_LOG);
+        if (!"200".equals(result.getString("code"))) {
+            logFse.setValue(CmnConst.ERROR_INFO, result.getString("msg"));
+            logFse.setValue(CmnConst.RESULT, -1);
+            logFse.setValue(CmnConst.NEED_RETRY, 1);
+        } else {
+            logFse.setValue(CmnConst.RESULT, 1);
+            logFse.setValue(CmnConst.NEED_RETRY, -1);
+        }
+        if (!FieldSetEntity.isEmpty(preLogFse)) {
+            logFse.setValue(CmnConst.RETRY_COUNT, preLogFse.getInteger(CmnConst.RETRY_COUNT) == null ? 1 : (preLogFse.getInteger(CmnConst.RETRY_COUNT) + 1));
+            logFse.setValue(CmnConst.PRE_UUID, preLogFse.getUUID());
+        } else {
+            logFse.setValue(CmnConst.RETRY_COUNT, 0);
+        }
+        logFse.setValue(CmnConst.ATTACHMENT_UUID, attachmentUUID);
+        logFse.setValue(CmnConst.SOURCE_INFO, sourceIpInfo);
+        logFse.setValue(CmnConst.TARGET_INFO, targetIpInfo);
+        logFse.setValue(CmnConst.CREATED_UTC_DATETIME, new Date());
+        SystemUser curUser = SpringMVCContextHolder.getCurrentUser();
+        logFse.setValue(CmnConst.CREATED_BY, curUser == null ? -1 : curUser.getUser_id());
+        baseDao.saveFieldSetEntity(logFse);
+    }
+
+    /**
+     * 瀹氭椂浠诲姟瑙﹀彂-鎵弿闆嗙兢鍚屾鏂囦欢鏃ュ織璁板綍琛紝閲嶈瘯鏈揪鏈�澶ф鏁扮殑閿欒鏃ュ織
+     */
+    public void retryClusterSyncFileFailLog() {
+        // 鏈�澶ч噸璇曟鏁�
+        int maxRetryCount = 3;
+        // 褰撳墠鍦板潃淇℃伅
+        String curIpInfo = Global.getSystemConfig(CoreConst.SYSTEM_NAME, "");
+        DataTableEntity waitRetryDte = baseDao.listTable(CmnConst.PRODUCT_SYS_CLUSTER_SYNC_FILE_LOG, "result=-1 AND retry_count<? AND need_retry=1 AND source_info=?", new Object[]{maxRetryCount, curIpInfo});
+        for (int i = 0; i < waitRetryDte.getRows(); i++) {
+            FieldSetEntity waitRetryFse = waitRetryDte.getFieldSetEntity(i);
+
+            FieldSetEntity attachmentFse = baseDao.getFieldSetEntity(CmnConst.PRODUCT_SYS_ATTACHMENTS, waitRetryFse.getString(CmnConst.ATTACHMENT_UUID), false);
+            String fileName = attachmentFse.getString("attachment_title");
+            String relativePath = attachmentFse.getString("attachment_url") + File.separator + fileName;
+            File aimFile = new File(Global.getSystemConfig("local.dir", "") + File.separator + relativePath);
+            clusterFileSyncRequest(aimFile, fileName, relativePath, attachmentFse.getUUID(), waitRetryFse);
+
+            waitRetryFse.setValue(CmnConst.RESULT, 2);
+            waitRetryFse.setValue(CmnConst.NEED_RETRY, -1);
+            baseDao.saveFieldSetEntity(waitRetryFse);
+        }
+    }
+
 	/**
 	 * 涓婁紶鏂囦欢鍒版湰鍦版湇鍔″櫒
 	 * 绂佹淇敼浠讳綍閫昏緫锛侊紒锛侊紒锛侊紒
@@ -301,7 +448,7 @@
 		Object value;
 		String fileNames;
 		FieldSetEntity fieldFse;
-		File tempFile;
+		File tempFile = null;
 		File localTempFile = null;
 		long fileLength = 0;
 
@@ -317,10 +464,11 @@
 		}
 
 		String uuids = "";
+        String fileFinalName = "";
 		for (Map.Entry<Object, Object> entry : map.entrySet()) {
 			fieldFse = fieldMetaEntity.getFieldMeta(fieldName);
-			if (fieldFse == null || (!CmnConst.ATTACHMENT_TYPE.equals(fieldFse.getString(CmnConst.FIELD_TYPE)) && !"file-image".equals(fieldFse.getString(CmnConst.FIELD_TYPE)))) {
-				fse.setValue(entry.getKey().toString(), null);
+            if (fieldFse == null || !Arrays.asList(CmnConst.ATTACHMENT_TYPE, "file-image", FieldType.FILE_ATTACHMENT.getDictValue()).contains(fieldFse.getString(CmnConst.FIELD_TYPE))) {
+                fse.setValue(entry.getKey().toString(), null);
 				continue;
 			}
 			// 宸茬粡鍒ゅ畾涓洪檮浠讹紝杩涜鎿嶄綔
@@ -351,65 +499,83 @@
 					}
 				}
 
-
-				final String fileFinalName = FileUtils.uploadFile(tempFile, templateType, clientUuid);
+                boolean saveInDbFlag = FieldType.FILE_ATTACHMENT.getDictValue().equals(fieldFse.getString("field_type"));
+                if (!saveInDbFlag) {
+                    fileFinalName = FileUtils.uploadFile(tempFile, templateType, clientUuid);
+                } else {
+                    fileFinalName = System.currentTimeMillis() + RandomUtil.randomString(2);
+                }
 
 				// 璁板綍闄勪欢淇℃伅鍒版暟鎹簱
-				logger.info("姝e湪璁板綍闄勪欢淇℃伅鍒版暟鎹簱...");
-				FieldSetEntity dictFse = baseDao.getFieldSetEntityByFilter(CmnConst.PRODUCT_SYS_DICT,
-						new String[]{CmnConst.UUID, CmnConst.DICT_VALUE}, "lower( " + CmnConst.DICT_VALUE + ")=lower(?) and dict_name='upload_file_format' and is_used=1", new Object[]{tail}, false, "");
-				FieldSetEntity attachmentFse = new FieldSetEntity();
-				attachmentFse.setTableName(CmnConst.PRODUCT_SYS_ATTACHMENTS);
-				String fileType;
-				if (dictFse != null && !StringUtils.isEmpty(dictFse.getString(CmnConst.UUID))) {
-					attachmentFse.setValue(CmnConst.ATTACHMENT_TYPE_UUID, dictFse.getUUID());
-					fileType = dictFse.getString(CmnConst.DICT_VALUE);
-				} else {
-					fileType = tail;
-					attachmentFse.setValue(CmnConst.ATTACHMENT_TYPE_UUID, tail);
-				}
-				//鍏佽缂栬緫
-				int allowEdit = ("," + Global.getSystemConfig("can.web.online.edit", "doc,docx,xls,xlsx.ppt,pptx,wps,cvs,wps,wpt,et,eet") + ",").indexOf("," + fileType + ",") != -1 ? 1 : 0;
-				attachmentFse.setValue(CmnConst.OPT_FLAT, 2);
-				attachmentFse.setValue(CmnConst.FILE_NAME, fileName);
-				attachmentFse.setValue(CmnConst.ATTACHMENT_TITLE, fileFinalName);
-				attachmentFse.setValue(CmnConst.CLIENT_UUID, clientUuid);
-				attachmentFse.setValue(CmnConst.VIEW_ONLINE_SIGN, viewOnlineSign);
-				attachmentFse.setValue(CmnConst.ATTACHMENT_DATA_TABLE, fse.getTableName());
-				attachmentFse.setValue(CmnConst.ATTACHMENT_DATA_FIELD, fieldName);
-				attachmentFse.setValue(CmnConst.ATTACHMENT_URL, dir.replaceAll("\\\\", "/"));
-				attachmentFse.setValue(CmnConst.ENCRPT_SIGN, Global.getPropertyToBoolean("file.encrypt", "true") ? 1 : 0);
-				attachmentFse.setValue(CmnConst.ATTACHMENT_SIZE, fileLength);
-				attachmentFse.setValue(CmnConst.UPLOAD_SIGN, needUpload2FileServerFlag ? 1 : 0);
-				attachmentFse.setValue(CmnConst.FUNCTION_UUID, fse.getString(CmnConst.FUNCTION_UUID));
-				attachmentFse.setValue(CmnConst.ATTACHMENT_CONTAINER, fse.getString(CmnConst.ATTACHMENT_CONTAINER));
-				attachmentFse.setValue(CmnConst.ATTACHMENT_DOMAIN, fse.getString(CmnConst.ATTACHMENT_DOMAIN));
-				attachmentFse.setValue(CmnConst.MODULE_UUID, fse.getString(CmnConst.MODULE_UUID));
-				//luoxin 鏈幏鍙栧綋鍓嶄汉id  灏辩洿鎺ヨ1
-				try {
-					attachmentFse.setValue(CmnConst.CREATED_BY, SpringMVCContextHolder.getCurrentUser().getUser_id());
-				} catch (Exception e) {
-					e.getStackTrace();
-					attachmentFse.setValue(CmnConst.CREATED_BY, 1);
-				}
+                logger.info("姝e湪璁板綍闄勪欢淇℃伅鍒版暟鎹簱...");
+                FieldSetEntity dictFse = baseDao.getFieldSetEntityByFilter(CmnConst.PRODUCT_SYS_DICT,
+                        new String[]{CmnConst.UUID, CmnConst.DICT_VALUE}, "lower( " + CmnConst.DICT_VALUE + ")=lower(?) and dict_name='upload_file_format' and is_used=1", new Object[]{tail}, false, "");
+                FieldSetEntity attachmentFse = new FieldSetEntity();
+                attachmentFse.setTableName(CmnConst.PRODUCT_SYS_ATTACHMENTS);
+                String fileType;
+                if (dictFse != null && !StringUtils.isEmpty(dictFse.getString(CmnConst.UUID))) {
+                    attachmentFse.setValue(CmnConst.ATTACHMENT_TYPE_UUID, dictFse.getUUID());
+                    fileType = dictFse.getString(CmnConst.DICT_VALUE);
+                } else {
+                    fileType = tail;
+                    attachmentFse.setValue(CmnConst.ATTACHMENT_TYPE_UUID, tail);
+                }
+                if (saveInDbFlag) {
+                    // 鍒ゆ柇闄勪欢瀛楁鐨勭被鍨嬩负FileAttachment鏃讹紝瑕佹妸鏂囨。鍐呭鏀惧埌闄勪欢琛ㄤ腑鐨刦ile_content瀛楁涓�
+                    try {
+                        attachmentFse.setValue(CmnConst.FILE_CONTENT, com.product.common.io.FileUtils.readFileToByteArray(tempFile));
+                    } catch (Exception e) {
+                        throw new BaseException(FileCode.FILE_TRANSFER_BYTE_ARRAY_FAIL);
+                    }
+                }
+                //鍏佽缂栬緫
+                int allowEdit = ("," + Global.getSystemConfig("can.web.online.edit", "doc,docx,xls,xlsx.ppt,pptx,wps,cvs,wps,wpt,et,eet") + ",").indexOf("," + fileType + ",") != -1 ? 1 : 0;
+                attachmentFse.setValue(CmnConst.OPT_FLAT, 2);
+                attachmentFse.setValue(CmnConst.FILE_NAME, fileName);
+                attachmentFse.setValue(CmnConst.ATTACHMENT_TITLE, fileFinalName);
+                attachmentFse.setValue(CmnConst.CLIENT_UUID, clientUuid);
+                attachmentFse.setValue(CmnConst.VIEW_ONLINE_SIGN, viewOnlineSign);
+                attachmentFse.setValue(CmnConst.ATTACHMENT_DATA_TABLE, fse.getTableName());
+                attachmentFse.setValue(CmnConst.ATTACHMENT_DATA_FIELD, fieldName);
+                attachmentFse.setValue(CmnConst.ATTACHMENT_URL, dir.replaceAll("\\\\", "/"));
+                attachmentFse.setValue(CmnConst.ENCRPT_SIGN, Global.getPropertyToBoolean("file.encrypt", "true") ? 1 : 0);
+                attachmentFse.setValue(CmnConst.ATTACHMENT_SIZE, fileLength);
+                attachmentFse.setValue(CmnConst.UPLOAD_SIGN, needUpload2FileServerFlag ? 1 : 0);
+                attachmentFse.setValue(CmnConst.FUNCTION_UUID, fse.getString(CmnConst.FUNCTION_UUID));
+                attachmentFse.setValue(CmnConst.ATTACHMENT_CONTAINER, fse.getString(CmnConst.ATTACHMENT_CONTAINER));
+                attachmentFse.setValue(CmnConst.ATTACHMENT_DOMAIN, fse.getString(CmnConst.ATTACHMENT_DOMAIN));
+                attachmentFse.setValue(CmnConst.MODULE_UUID, fse.getString(CmnConst.MODULE_UUID));
+                //luoxin 鏈幏鍙栧綋鍓嶄汉id  灏辩洿鎺ヨ1
+                try {
+                    attachmentFse.setValue(CmnConst.CREATED_BY, SpringMVCContextHolder.getCurrentUser().getUser_id());
+                } catch (Exception e) {
+                    e.getStackTrace();
+                    attachmentFse.setValue(CmnConst.CREATED_BY, 1);
+                }
 
-				attachmentFse.setValue(CmnConst.CREATED_UTC_DATETIME, new Date());
-				baseDao.saveFieldSetEntity(attachmentFse);
-				logger.info("璁板綍鎴愬姛");
-				String uuid = attachmentFse.getUUID();
-				FieldSetEntity fseIndex = new FieldSetEntity();
-				fseIndex.setTableName("fseIndex");
-				fseIndex.setValue("function_uuid", fse.getString("function_uuid"));
-				fseIndex.setValue("attachment_uuid", uuid);
-				CreateDocumentIndexThread.getInstance().appendAttaInfo(fseIndex);
-				fse.setValue(uuid, fileName);
-				fse.setValue(entry.getKey().toString(), uuid);
-				fse.setValue(entry.getKey().toString() + "_edit", allowEdit);
-				fse.setValue(entry.getKey().toString() + "_type", fileType);
-				if (!StringUtils.isEmpty(uuids)) {
-					uuids += ",";
-				}
-				uuids += uuid;
+                attachmentFse.setValue(CmnConst.CREATED_UTC_DATETIME, new Date());
+                baseDao.saveFieldSetEntity(attachmentFse);
+                logger.info("璁板綍鎴愬姛");
+                String uuid = attachmentFse.getUUID();
+                FieldSetEntity fseIndex = new FieldSetEntity();
+                fseIndex.setTableName("fseIndex");
+                fseIndex.setValue("function_uuid", fse.getString("function_uuid"));
+                fseIndex.setValue("attachment_uuid", uuid);
+                CreateDocumentIndexThread.getInstance().appendAttaInfo(fseIndex);
+                fse.setValue(uuid, fileName);
+                fse.setValue(entry.getKey().toString(), uuid);
+                fse.setValue(entry.getKey().toString() + "_edit", allowEdit);
+                fse.setValue(entry.getKey().toString() + "_type", fileType);
+                if (!StringUtils.isEmpty(uuids)) {
+                    uuids += ",";
+                }
+                uuids += uuid;
+
+                // 闆嗙兢甯冪讲鏈湴瀛樺偍鏃讹紝闄勪欢淇℃伅瑕佸悓姝ュ埌鍏跺畠鏈嶅姟鍣ㄤ笂
+                if (!saveInDbFlag && !needUpload2FileServerFlag) {
+                    File curFile = new File(Global.getSystemConfig("local.dir", "") + File.separator + dir + File.separator + fileFinalName);
+                    clusterFileSyncRequest(curFile, fileFinalName, dir + File.separator + fileFinalName, attachmentFse.getUUID());
+                }
 			}
 			logger.info("姝e湪鍥炲啓uuid...");
 			System.out.println(uuids);
@@ -445,16 +611,17 @@
 			}
 		}
 	}
+
 	/**
 	 * 绉诲姩绔崌绾э紝瀹夎鍖呬笅杞�
 	 *
 	 * @param fse
 	 * @param response
 	 */
-	public void getFileContent(FieldSetEntity fse, HttpServletResponse response,boolean isUpgrade) throws IOException {
-		if(isUpgrade) {
+	public void getFileContent(FieldSetEntity fse, HttpServletResponse response, boolean isUpgrade) throws IOException {
+		if (isUpgrade) {
 			FieldSetEntity attachmentFse = baseDao.getFieldSetEntity(CmnConst.PRODUCT_SYS_ATTACHMENTS, fse.getUUID(), false);
-			if (attachmentFse == null || !"product_sys_app_version".equals(attachmentFse.getString("attachment_data_table")) ) {
+			if (attachmentFse == null || !"product_sys_app_version".equals(attachmentFse.getString("attachment_data_table"))) {
 				return;
 			}
 			logger.info("姝e湪鑾峰彇鏂囦欢娴�...");
@@ -466,8 +633,8 @@
 			String viewOnlineSign = attachmentFse.getString(CmnConst.VIEW_ONLINE_SIGN);
 			boolean encrptSignFlag = "1".equals(attachmentFse.getString(CmnConst.ENCRPT_SIGN));
 			boolean needOnlineViewFlag = "1".equals(fse.getString(CmnConst.NEED_ONLINE_VIEW)) && "1".equals(viewOnlineSign);
-			
-			String clientType =CoreConst.CLIENT_TYPE_APP;
+
+			String clientType = CoreConst.CLIENT_TYPE_APP;
 
 			String contentType = "multipart/form-data";
 			boolean isExcel = realFileName.endsWith(".xlsx") || realFileName.endsWith(".xls");
@@ -582,8 +749,9 @@
 			}
 			logger.info("鏂囦欢娴佽幏鍙栨垚鍔�");
 		}
-	
+
 	}
+
 	/**
 	 * 鎻愬彇鏂囦欢淇℃伅-涓嬭浇鏂囦欢鎴栬�呭湪绾块瑙堟枃浠�
 	 *
@@ -656,6 +824,19 @@
 					tempOs.flush();
 					tempOs.close();
 				}
+				boolean delete = false;
+				if (realFileName.endsWith(".xls") && needOnlineViewFlag && localTempFile.exists() && !CoreConst.CLIENT_TYPE_APP.equals(clientType)) {
+					//杞崲涓簒lsx
+					AsposeUtil.xls2xlsx(localTempFile.getPath(), getSystemConfig("temp.dir", "/attachment/temp") + "/" + localTempFile.getName(), "xls");
+					File oldFile = localTempFile;
+					localTempFile = new File(getSystemConfig("temp.dir", "/attachment/temp") + "/" + localTempFile.getName());
+					if (!localTempFile.isFile()) {
+						localTempFile = oldFile;
+					} else {
+						delete = true;
+						oldFile.delete();
+					}
+				}
 				response.setContentLengthLong(localTempFile.length());
 				InputStream is = new FileInputStream(localTempFile);
 				int len;
@@ -671,40 +852,74 @@
 				localTempFile.delete();
 			}
 		} else {
-			// 鐩存帴鍦ㄦ湰鍦扮殑鐩綍涓壘鏂囦欢
-			logger.info("鐩存帴鍦ㄦ湰鍦扮殑鐩綍涓壘鏂囦欢...");
-			String localBasePath = Global.getSystemConfig("local.dir", "");
-			path = localBasePath + File.separator + path;
-			File file = new File(path);
-			if (needOnlineViewFlag && file.exists() && CoreConst.CLIENT_TYPE_APP.equals(clientType)) {
-				//鐗规畩澶勭悊锛� 鏄疉pp 浣嗛瑙堢殑鏂囦欢鏄疎xcel 闇�瑕佸皢涔嬪墠宸茶浆鎹负鐨勬枃浠跺垹闄ゆ帀閲嶆柊杞崲锛堝洜杞崲鍚庣殑鏍煎紡涓嶆槸pdf)
-				String changeTime = "2025-02-11 23:59:59";
-				Date changeDate = DateUtil.parse(changeTime, "yyyy-MM-dd HH:mm:ss");
-				long fileTime = file.lastModified();
-				//濡傛灉鏃堕棿鏄� 2025骞�2鏈�10鏃�23:59:59锛岄偅涔堝氨閲嶆柊杞崲
-				//鍒犻櫎鏂囦欢
-				if (fileTime <= changeDate.getTime()) {
-					file.delete();
-				}
-			}
-			if (needOnlineViewFlag && !file.exists()) {
-				// 鑻ユ槸棰勮锛屼絾鏄浆鎹㈠悗鐨勬枃浠朵笉瀛樺湪锛岄偅涔堥噸鏂版墽琛岃浆鎹㈡搷浣�
-				File sourceFile = fileUtils.getFile(false, attachmentFse.getString(CmnConst.ATTACHMENT_URL), fileName, encrptSignFlag);
-				File tempSourceFile = new File(sourceFile.getParentFile().getAbsolutePath() + File.separator + attachmentFse.getString(CmnConst.FILE_NAME));
-				sourceFile.renameTo(tempSourceFile);
-				FileUtils.convertPdf(false, false, encrptSignFlag, true, tempSourceFile, dir, fileName, attachmentFse.getString(CmnConst.FILE_NAME));
-				tempSourceFile.delete();
-			}
+            InputStream is = null;
+            boolean delete = false;
+            File file = null;
+            long fileLength = 0L;
+            Object fileContent = attachmentFse.getValue("file_content");
+            // 鏄惁瀛樺偍鍒版暟鎹簱
+            boolean saveInDb = fileContent != null;
+            if (saveInDb) {
+                is = (InputStream) fileContent;
+                fileLength = attachmentFse.getLong("attachment_size");
+            }
+            if (fileContent == null || needOnlineViewFlag) {
+                // 鐩存帴鍦ㄦ湰鍦扮殑鐩綍涓壘鏂囦欢
+                logger.info("鐩存帴鍦ㄦ湰鍦扮殑鐩綍涓壘鏂囦欢...");
+                String localBasePath = Global.getSystemConfig("local.dir", "");
+                path = localBasePath + File.separator + path;
+                file = new File(path);
+                if (needOnlineViewFlag && file.exists() && CoreConst.CLIENT_TYPE_APP.equals(clientType)) {
+                    //鐗规畩澶勭悊锛� 鏄疉pp 浣嗛瑙堢殑鏂囦欢鏄疎xcel 闇�瑕佸皢涔嬪墠宸茶浆鎹负鐨勬枃浠跺垹闄ゆ帀閲嶆柊杞崲锛堝洜杞崲鍚庣殑鏍煎紡涓嶆槸pdf)
+                    String changeTime = "2025-02-11 23:59:59";
+                    Date changeDate = DateUtil.parse(changeTime, "yyyy-MM-dd HH:mm:ss");
+                    long fileTime = file.lastModified();
+                    //濡傛灉鏃堕棿鏄� 2025骞�2鏈�10鏃�23:59:59锛岄偅涔堝氨閲嶆柊杞崲
+                    //鍒犻櫎鏂囦欢
+                    if (fileTime <= changeDate.getTime()) {
+                        file.delete();
+                    }
+                }
+                if (needOnlineViewFlag && !file.exists()) {
+                    // 鑻ユ槸棰勮锛屼絾鏄浆鎹㈠悗鐨勬枃浠朵笉瀛樺湪锛岄偅涔堥噸鏂版墽琛岃浆鎹㈡搷浣�
+                    // 鑻ユ槸瀛樺偍鍒版暟鎹簱鐨勶紝閭d箞鍏堟煡鐪嬫湰鍦版槸鍚﹀瓨鍦紝鑻ユ槸涓嶅瓨鍦紝閭d箞瀛樹竴浠藉埌鏈湴
+                    if (saveInDb) {
+                        File localFile = new File(Global.getSystemConfig("local.dir", "") + File.separator + attachmentFse.getString(CmnConst.ATTACHMENT_URL) + File.separator + fileName);
+                        if (!localFile.exists()) {
+                            Files.copy(is, localFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
+                        }
+                    }
+                    File sourceFile = fileUtils.getFile(false, attachmentFse.getString(CmnConst.ATTACHMENT_URL), fileName, encrptSignFlag);
+                    File tempSourceFile = new File(sourceFile.getParentFile().getAbsolutePath() + File.separator + attachmentFse.getString(CmnConst.FILE_NAME));
+                    sourceFile.renameTo(tempSourceFile);
+                    FileUtils.convertPdf(false, false, encrptSignFlag, true, tempSourceFile, dir, fileName, attachmentFse.getString(CmnConst.FILE_NAME));
+                    tempSourceFile.delete();
+                }
+                if (realFileName.endsWith(".xls") && needOnlineViewFlag && file.exists() && !CoreConst.CLIENT_TYPE_APP.equals(clientType)) {
+                    //杞崲涓簒lsx
+                    AsposeUtil.xls2xlsx(file.getPath(), getSystemConfig("temp.dir", "/attachment/temp") + "/" + file.getName(), "xls");
+                    File oldFile = file;
+                    file = new File(getSystemConfig("temp.dir", "/attachment/temp") + "/" + file.getName());
+                    if (!file.isFile()) {
+                        file = oldFile;
+                    } else {
+                        delete = true;
+                    }
+                }
+                is = Files.newInputStream(file.toPath());
+                fileLength = file.length();
+            }
+
 			int len;
 			byte[] b = new byte[1024];
-			InputStream is = new FileInputStream(file);
 			response.setHeader("Access-Control-Expose-Headers", "*");
 
+            response.setContentType("application/octet-stream");
 			response.setContentType(contentType);
 			response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(realFileName, "UTF-8"));
-			response.setContentLengthLong(file.length());
-			try (ServletOutputStream os = response.getOutputStream()) {
-				while ((len = is.read(b)) > 0) {
+			response.setContentLengthLong(fileLength);
+            try (ServletOutputStream os = response.getOutputStream()) {
+				while ((len = is.read(b)) != -1) {
 					if (encrptSignFlag) {
 						// 闇�瑕佽В瀵�
 						logger.info("闇�瑕佽В瀵�...");
@@ -717,6 +932,9 @@
 				os.flush();
 			}
 			is.close();
+			if (delete && file != null) {
+				file.delete();
+			}
 		}
 		logger.info("鏂囦欢娴佽幏鍙栨垚鍔�");
 	}

--
Gitblit v1.9.2