| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262 |
- package com.hotent.util;
- import com.hotent.baseInfo.vo.FileUploadResult;
- import com.hotent.config.EipConfig;
- import com.hotent.constant.BaseConstant;
- import lombok.extern.slf4j.Slf4j;
- import org.apache.commons.lang.StringUtils;
- import org.springframework.web.multipart.MultipartFile;
- import java.io.File;
- import java.io.IOException;
- import java.nio.file.Files;
- import java.nio.file.Path;
- import java.nio.file.Paths;
- import java.time.LocalDateTime;
- import java.time.format.DateTimeFormatter;
- import java.util.*;
- @Slf4j
- public class FileUploadUtil {
- // 允许上传的文件类型
- private static final Set<String> ALLOWED_EXTENSIONS = new HashSet<>(Arrays.asList(
- // 文档格式
- "doc", "docx", "xls", "xlsx", "ppt", "pptx", "pdf", "txt",
- // 图片格式
- "jpg", "jpeg", "png", "gif", "bmp", "webp",
- // 压缩包格式
- "zip", "rar", "7z",
- // 其他常用格式
- "csv", "xml", "json"
- ));
- // 文件大小限制 (单位: 字节,默认100MB)
- private static long MAX_FILE_SIZE = 100 * 1024 * 1024;
- /**
- * 单文件上传
- * @param file 上传的文件
- * @param businessFolder 业务文件夹名称
- * @param baseUploadPath 基础上传路径
- * @return 文件上传结果
- */
- public static FileUploadResult uploadFile(MultipartFile file, String baseUploadPath) {
- return uploadFiles(Collections.singletonList(file), baseUploadPath).get(0);
- }
- /**
- * 多文件上传
- * @param files 上传的文件列表
- * @param 业务文件夹名称
- * @param baseUploadPath 基础上传路径
- * @return 文件上传结果列表
- */
- public static List<FileUploadResult> uploadFiles(List<MultipartFile> files, String baseUploadPath) {
- List<FileUploadResult> results = new ArrayList<>();
- for (MultipartFile file : files) {
- FileUploadResult result = new FileUploadResult();
- result.setOriginalFilename(file.getOriginalFilename());
- try {
- // 验证文件
- validateFile(file);
- // 生成文件保存路径
- String fileExtension = getFileExtension(file.getOriginalFilename());
- String fileName = generateFileName(file.getOriginalFilename());
- String savePath = generateSavePath(baseUploadPath, fileName, fileExtension);
- // 创建目录
- createDirectories(savePath);
- log.info(savePath);
- // 保存文件
- File destFile = new File(savePath);
- file.transferTo(destFile);
- // 设置成功结果
- result.setFileName(fileName);
- result.setFileExtension(fileExtension);
- result.setSavePath(getPathFileName(savePath,fileName));
- result.setFileSize(file.getSize());
- result.setMessage("上传成功");
- } catch (Exception e) {
- result.setMessage("上传失败: " + e.getMessage());
- }
- results.add(result);
- }
- return results;
- }
- public static final String getPathFileName(String uploadDir, String fileName)
- {
- int dirLastIndex = EipConfig.getProfile().length() + 1;
- String currentDir = StringUtils.substring(uploadDir, dirLastIndex);
- return BaseConstant.RESOURCE_PREFIX + "/" + currentDir;
- }
- /**
- * 验证文件合法性
- * @param file 文件
- * @throws Exception 验证异常
- */
- private static void validateFile(MultipartFile file) throws Exception {
- // 检查文件是否为空
- if (file.isEmpty()) {
- throw new Exception("文件为空");
- }
- // 检查文件大小
- if (file.getSize() > MAX_FILE_SIZE) {
- throw new Exception("文件大小超过限制(" + MAX_FILE_SIZE / (1024 * 1024) + "MB)");
- }
- // 检查文件类型
- String extension = getFileExtension(file.getOriginalFilename());
- if (!ALLOWED_EXTENSIONS.contains(extension.toLowerCase())) {
- throw new Exception("不支持的文件类型: " + extension);
- }
- }
- public static String getFileType(String fileName)
- {
- int separatorIndex = fileName.lastIndexOf(".");
- if (separatorIndex < 0)
- {
- return "";
- }
- return fileName.substring(separatorIndex + 1).toLowerCase();
- }
- public static boolean checkAllowDownload(String resource)
- {
- // 禁止目录上跳级别
- if (StringUtils.contains(resource, ".."))
- {
- return false;
- }
- if (ALLOWED_EXTENSIONS.contains(resource)) {
- return true;
- }
- // 不在允许下载的文件规则
- return false;
- }
- /**
- * 获取文件扩展名
- * @param fileName 文件名
- * @return 文件扩展名
- */
- public static String getFileExtension(String fileName) {
- if (fileName == null || fileName.lastIndexOf(".") == -1) {
- return "";
- }
- return fileName.substring(fileName.lastIndexOf(".") + 1);
- }
- /**
- * 生成文件名(避免重名)
- * @param originalFilename 原始文件名
- * @return 新文件名
- */
- public static String generateFileName(String originalFilename) {
- String extension = "";
- String name = originalFilename;
- if (originalFilename != null && originalFilename.lastIndexOf(".") != -1) {
- extension = originalFilename.substring(originalFilename.lastIndexOf("."));
- name = originalFilename.substring(0, originalFilename.lastIndexOf("."));
- }
- // 使用时间戳+随机数避免重名
- String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
- String random = String.valueOf(new Random().nextInt(1000));
- return name + timestamp + random + extension;
- }
- /**
- * 生成文件保存路径
- * @param baseUploadPath 基础上传路径
- * @param 业务文件夹
- * @param fileName 文件名
- * @param fileExtension 文件扩展名
- * @return 完整保存路径
- */
- public static String generateSavePath(String baseUploadPath, String fileName, String fileExtension) {
- // 标准化路径分隔符
- String separator ="/";
- // 构建路径
- StringBuilder pathBuilder = new StringBuilder();
- pathBuilder.append(normalizePath(baseUploadPath)).append(separator);
- // 添加业务文件夹
- // if (businessFolder != null && !businessFolder.trim().isEmpty()) {
- // pathBuilder.append(normalizePath(businessFolder)).append(separator);
- // }
- // 添加日期文件夹(按年月日分类)
- String datePath = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
- pathBuilder.append(datePath).append(separator);
- // 添加文件名
- pathBuilder.append(fileName);
- return pathBuilder.toString();
- }
- /**
- * 标准化路径(处理跨平台路径分隔符)
- * @param path 路径
- * @return 标准化后的路径
- */
- private static String normalizePath(String path) {
- if (path == null) {
- return null;
- }
- // 将所有反斜杠替换为正斜杠,然后根据系统转换
- return path.replace("\\", "/").replace("/", File.separator);
- }
- /**
- * 创建目录(支持跨平台)
- * @param filePath 文件路径
- * @throws IOException IO异常
- */
- private static void createDirectories(String filePath) throws IOException {
- Path path = Paths.get(filePath);
- Path parentDir = path.getParent();
- if (parentDir != null && !Files.exists(parentDir)) {
- Files.createDirectories(parentDir);
- }
- }
- /**
- * 设置允许的文件扩展名
- * @param extensions 扩展名列表
- */
- public static void setAllowedExtensions(Set<String> extensions) {
- ALLOWED_EXTENSIONS.clear();
- ALLOWED_EXTENSIONS.addAll(extensions);
- }
- /**
- * 设置最大文件大小
- * @param maxSize 最大大小(字节)
- */
- public static void setMaxFileSize(long maxSize) {
- MAX_FILE_SIZE = maxSize;
- }
- }
|