Ver Fonte

[task-3907]新增打包下载接口

szjbdgzl há 1 ano atrás
pai
commit
9a0efb4ef3

+ 9 - 5
ibps-comp-base-root/modules/comp-file-server-api/src/main/java/com/lc/ibps/file/server/api/IDownloadService.java

@@ -31,19 +31,23 @@ import java.util.HashMap;
 public interface IDownloadService {
 
 	/**
-	 * 
 	 * 文件下载
-	 *
-	 * @param request
-	 * @param response
 	 * @param attachmentId
 	 */
-
 	@RequestMapping(value = "/download", method = {RequestMethod.GET})
 	public void download(
 			@NotBlank(message = "{com.lc.ibps.cloud.file.attachmentId}") 
 			@RequestParam(name = "attachmentId", required = true) String attachmentId);
 
+	/**
+	 * 多个文件下载处理成zip
+	 * @param attachmentIds
+	 */
+	@RequestMapping(value = "/downloadZip", method = { RequestMethod.GET })
+	public void downloadZip(
+			@NotEmpty(message = ("com.lc.ibps.cloud.file.attachmentIds"))
+			@RequestParam(name = "attachmentIds", required = true) String[] attachmentIds);
+
 	@RequestMapping(value = "/downloadUse", method = {RequestMethod.GET})
 	public void downloadUse();
 

+ 82 - 0
ibps-comp-root/modules/comp-file-server/src/main/java/com/lc/ibps/cloud/file/provider/DownloadProvider.java

@@ -2,6 +2,9 @@ package com.lc.ibps.cloud.file.provider;
 
 import java.io.*;
 import java.net.URL;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 import java.util.Scanner;
 import java.util.concurrent.TimeUnit;
 
@@ -14,8 +17,10 @@ import cn.hutool.json.JSONObject;
 import cn.hutool.json.JSONUtil;
 import com.google.gson.JsonObject;
 import com.lc.ibps.base.core.util.*;
+import com.lc.ibps.base.framework.id.UniqueIdUtil;
 import com.lc.ibps.cloud.redis.utils.RedisUtil;
 import com.lc.ibps.common.file.persistence.entity.AttachmentPo;
+import org.apache.commons.io.FileUtils;
 import org.jodconverter.OfficeDocumentConverter;
 import org.jodconverter.office.DefaultOfficeManagerBuilder;
 import org.jodconverter.office.OfficeException;
@@ -79,6 +84,83 @@ public class DownloadProvider extends GenericUploadProvider implements IDownload
 		}
 	}
 
+	@ApiOperation(value = "批量下载文件为ZIP", notes = "根据多个附件ID下载文件并打包为ZIP压缩包")
+	public void downloadZip(
+			@ApiParam(name = "attachmentIds", value = "附件ID数组", required = true)
+			@RequestParam(name = "attachmentIds", required = true) String[] attachmentIds) {
+		String realFilePath = null;
+		String zipFilePath = null;
+		Map<String, Integer> fileNameCounter = new HashMap<>();  // 用于处理重复文件名
+		try {
+			// 创建临时目录
+			String rootRealPath = AppFileUtil.getRealPath("/"+AppFileUtil.TEMP_PATH);
+			String uuid = UniqueIdUtil.getId();
+			String folderName = "downloads_" + uuid;
+			realFilePath = rootRealPath + File.separator + folderName;
+			File targetDir = new File(realFilePath);
+			if (!targetDir.exists()) {
+				targetDir.mkdirs();
+			}
+			// 循环处理每个文件
+			this.getUploadService();
+			for (String attachmentId : attachmentIds) {
+				try {
+					FileInfo fileInfo = uploadService.downloadFile(attachmentId.trim());
+					if (fileInfo == null || fileInfo.getFileBytes() == null) {
+						logger.warn("文件不存在: {}", attachmentId);
+						continue;
+					}
+					// 生成唯一文件名
+					String originalName = UploadUtil.getFileName(fileInfo.getFileName(),fileInfo.getExt());
+					String safeName = generateUniqueName(originalName, fileNameCounter);
+					// 写入临时文件
+					File outputFile = new File(targetDir, safeName);
+					FileUtils.writeByteArrayToFile(outputFile, fileInfo.getFileBytes());
+				} catch (Exception e) {
+					logger.error("文件处理失败: {}", attachmentId, e);
+				}
+			}
+			// 压缩目录
+			ZipUtil.zip(realFilePath, true);  // 自动删除原目录
+			String zipFileName = folderName + ".zip";
+			zipFilePath = rootRealPath + File.separator + zipFileName;
+			// 发送压缩包
+			RequestUtil.downLoadFile(this.getRequest(),this.getResponse(),zipFilePath,zipFileName);
+		} catch (Exception e) {
+			logger.error("/upload/downloadUse", e);
+		} finally {
+			// 清理残留文件(双重保障)
+			if (realFilePath != null) {
+				FileUtil.deleteDir(new File(realFilePath));
+			}
+			if (zipFilePath != null) {
+				FileUtil.deleteFile(zipFilePath);
+			}
+		}
+	}
+
+	/**
+	 * 生成唯一文件名(带序号)
+	 */
+	private String generateUniqueName(String originalName, Map<String, Integer> counter) {
+		// 处理特殊字符
+		String safeName = originalName.replaceAll("[\\\\/:*?\"<>|]", "_");
+		// 处理重复文件名
+		int count = counter.getOrDefault(safeName, 0);
+		counter.put(safeName, count + 1);
+		if (count == 0) {
+			return safeName;
+		} else {
+			int dotIndex = safeName.lastIndexOf('.');
+			if (dotIndex > 0) {
+				String base = safeName.substring(0, dotIndex);
+				String ext = safeName.substring(dotIndex);
+				return base + "(" + count + ")" + ext;
+			}
+			return safeName + "(" + count + ")";
+		}
+	}
+
 	@Override
 	public void downloadUse() {
 		try {