diff --git a/bonus-admin/src/main/java/com/bonus/web/controller/archive/FileManagementController.java b/bonus-admin/src/main/java/com/bonus/web/controller/archive/FileManagementController.java index 8f9c12e..845b5ba 100644 --- a/bonus-admin/src/main/java/com/bonus/web/controller/archive/FileManagementController.java +++ b/bonus-admin/src/main/java/com/bonus/web/controller/archive/FileManagementController.java @@ -7,10 +7,7 @@ import com.bonus.common.core.domain.AjaxResult; import com.bonus.common.core.domain.R; import com.bonus.common.core.page.TableDataInfo; import com.bonus.common.enums.OperaType; -import com.bonus.common.utils.SecurityUtils; import com.bonus.common.utils.bean.FileDto; -import com.bonus.common.utils.file.FileUploadUtils; -import com.bonus.common.utils.file.FileUtils; import com.bonus.web.domain.DaKyProFilesContentsDto; import com.bonus.web.domain.FilesClassifyNameStandardDto; import com.bonus.web.domain.ProjectDto; @@ -18,23 +15,20 @@ import com.bonus.web.domain.vo.DaKyProFilesContentsVo; import com.bonus.web.mapper.FileManageMapper; import com.bonus.web.service.FileManageService; import com.bonus.web.service.ProjectService; +import com.bonus.web.util.FileUtils; import com.fasterxml.jackson.databind.ObjectMapper; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; -import org.hibernate.validator.constraints.Length; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; -import javax.servlet.http.HttpServletRequest; import javax.validation.ConstraintViolation; import javax.validation.Validation; import javax.validation.Validator; import javax.validation.ValidatorFactory; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; @@ -42,8 +36,6 @@ import java.nio.file.Paths; import java.util.*; import java.util.stream.Collectors; -import static com.bonus.common.utils.SecurityUtils.getLoginUser; - /** * @Author:liang.chao * @Date:2025/9/11 - 13:29 @@ -131,7 +123,7 @@ public class FileManagementController extends BaseController { @SysLog(title = "获取当前节点数据", module = "档案管理->档案右侧列表", businessType = OperaType.QUERY, details = "获取当前节点数据", logType = 1) @RequiresPermissions("file:manage:query") public AjaxResult getFileManageById(DaKyProFilesContentsDto dto) { - return AjaxResult.success(fileManageService.getFileManageById(dto)); + return AjaxResult.success(fileManageService.getFileManageById(dto)); } @ApiOperation(value = "新增右侧档案树") @@ -204,7 +196,7 @@ public class FileManagementController extends BaseController { @PostMapping("updateFileManageRight") @SysLog(title = "修改档案", module = "档案管理->档案目录管理", businessType = OperaType.UPDATE, details = "修改档案", logType = 1) @RequiresPermissions("file:manage:update") - public R updateFileManage(@RequestPart("file") MultipartFile file, + public R updateFileManage(@RequestPart(value = "file", required = false) MultipartFile file, @RequestParam("params") String params) { try { ObjectMapper objectMapper = new ObjectMapper(); @@ -357,10 +349,10 @@ public class FileManagementController extends BaseController { @GetMapping("/getFileAsBase64") public R getFileAsBase64(DaKyProFilesContentsDto dto) throws IOException { Map response = new HashMap<>(); - DaKyProFilesContentsVo record = fileManageService.getFileById(Long.parseLong(dto.getId())); + DaKyProFilesContentsVo record = fileManageService.getFileById(Long.parseLong(dto.getId())); if (record == null || StringUtils.isBlank(record.getFilePath())) { - return R.fail("文件未找到"); + return R.fail("文件未找到"); } String filePath = record.getFilePath(); diff --git a/bonus-admin/src/main/java/com/bonus/web/util/FileUtils.java b/bonus-admin/src/main/java/com/bonus/web/util/FileUtils.java new file mode 100644 index 0000000..bec17fb --- /dev/null +++ b/bonus-admin/src/main/java/com/bonus/web/util/FileUtils.java @@ -0,0 +1,139 @@ +package com.bonus.web.util; + +import com.bonus.common.config.BonusConfig; +import com.bonus.common.constant.Constants; +import com.bonus.common.core.domain.entity.SysDictData; +import com.bonus.common.utils.DateUtils; +import com.bonus.common.utils.StringUtils; +import com.bonus.common.utils.bean.FileDto; +import com.bonus.common.utils.file.FileTypeUtils; +import com.bonus.common.utils.file.FileUploadUtils; +import com.bonus.common.utils.file.MimeTypeUtils; +import com.bonus.common.utils.uuid.IdUtils; +import com.bonus.system.mapper.SysDictDataMapper; +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.ArrayUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.PostConstruct; +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.*; +import java.math.BigDecimal; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.*; + +/** + * 文件处理工具类 + * + * @author bonus + */ +public class FileUtils { + // 常见的图片扩展名(小写) + private static final Set IMAGE_EXTENSIONS; + private static String UPLOAD_DIR; + + @Resource + private static SysDictDataMapper dictDataMapper; + + private static final List BLOCKED_PATTERNS = Arrays.asList( + "<", ">", "[", "]", "(", ")", "/", "'", "\"", "@", "!", "+", + "%3c", "%3e", "%2b", + "script", "alert", "svg", "confirm", "prompt", "onload", "img", "src" + ); + + + static { + HashSet set = new HashSet<>(); + set.add("jpg"); + set.add("jpeg"); + set.add("png"); + set.add("gif"); + set.add("bmp"); + set.add("webp"); + set.add("tiff"); + set.add("svg"); + set.add("ico"); + IMAGE_EXTENSIONS = Collections.unmodifiableSet(set); + } + + + @Value("${bonus.profile}") + private String uploadDir; + + @PostConstruct + public void init() { + UPLOAD_DIR = uploadDir; + } + + + public static final FileDto upload(MultipartFile file) throws IOException { + FileDto bean = new FileDto(); + if (file != null && !file.isEmpty()) { + // 验证文件类型 + String originalFileName = file.getOriginalFilename(); + // 校验是否含有特殊字符(转小写便于忽略大小写比较) + String lowerInput = originalFileName.toLowerCase(); + + for (String pattern : BLOCKED_PATTERNS) { + if (lowerInput.contains(pattern)) { + throw new RuntimeException("文件名包含非法字符:" + pattern); + } + } + // 校验文件大小 + SysDictData fileSizeLimit = selectDictDataByType("file_size_limit"); + // 转换为 MB(保留 2 位小数) + double sizeInMB = file.getSize() / (1024.0 * 1024.0); + if (sizeInMB > Double.parseDouble(fileSizeLimit.getDictValue())){ + throw new RuntimeException("文件大小超出限制"); + } + String fileExtension = originalFileName != null ? originalFileName.split("\\.")[1] : ""; + if (isImage(fileExtension)) { + bean.setFileType("1"); + } else { + bean.setFileType("2"); + } + File targetDir = new File(UPLOAD_DIR); + if (!targetDir.exists()) { + targetDir.mkdirs(); + } + String fileName = file.getOriginalFilename(); + String sourceFileName = System.currentTimeMillis() + "_" + file.getOriginalFilename(); + File targetFile = new File(UPLOAD_DIR, fileName); + file.transferTo(targetFile); + String pathName = targetFile.getAbsolutePath(); + bean.setFilePath(pathName); + bean.setFileName(fileName); + bean.setSourceFileName(sourceFileName); + bean.setFileSize(new BigDecimal(file.getSize())); + bean.setSuffixName(fileExtension); + return bean; + } else { + return bean; + } + + } + + /** + * 根据文件扩展名判断是否为图片 + * + * @param fileExtension 文件扩展名(例如 "jpg", "png", "pdf") + * @return true 表示是图片,false 表示是普通文件 + */ + public static boolean isImage(String fileExtension) { + if (fileExtension == null || fileExtension.trim().isEmpty()) { + return false; + } + String ext = fileExtension.toLowerCase().trim(); + return IMAGE_EXTENSIONS.contains(ext); + } + public static SysDictData selectDictDataByType(String dataType) { + List sysDictData = dictDataMapper.selectDictDataByType(dataType); + return sysDictData.get(0); + } +} diff --git a/bonus-common/src/main/java/com/bonus/common/utils/file/FileUtils.java b/bonus-common/src/main/java/com/bonus/common/utils/file/FileUtils.java index 2039d44..af887eb 100644 --- a/bonus-common/src/main/java/com/bonus/common/utils/file/FileUtils.java +++ b/bonus-common/src/main/java/com/bonus/common/utils/file/FileUtils.java @@ -7,19 +7,11 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.UnsupportedEncodingException; -import java.math.BigDecimal; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import javax.annotation.PostConstruct; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import com.bonus.common.core.domain.R; -import com.bonus.common.utils.bean.FileDto; import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.ArrayUtils; @@ -28,9 +20,7 @@ import com.bonus.common.constant.Constants; import com.bonus.common.utils.DateUtils; import com.bonus.common.utils.StringUtils; import com.bonus.common.utils.uuid.IdUtils; -import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; -import org.springframework.web.multipart.MultipartFile; /** * 文件处理工具类 @@ -40,32 +30,6 @@ import org.springframework.web.multipart.MultipartFile; @Component public class FileUtils { public static String FILENAME_PATTERN = "[a-zA-Z0-9_\\-\\|\\.\\u4e00-\\u9fa5]+"; - // 常见的图片扩展名(小写) - // 常见的图片扩展名(小写) - private static final Set IMAGE_EXTENSIONS; - private static String UPLOAD_DIR; - static { - HashSet set = new HashSet<>(); - set.add("jpg"); - set.add("jpeg"); - set.add("png"); - set.add("gif"); - set.add("bmp"); - set.add("webp"); - set.add("tiff"); - set.add("svg"); - set.add("ico"); - IMAGE_EXTENSIONS = Collections.unmodifiableSet(set); - } - - - @Value("${bonus.profile}") - private String uploadDir; - @PostConstruct - public void init() { - UPLOAD_DIR = uploadDir; // 在对象初始化时赋值给 static 变量 - } - /** * 输出指定文件的byte数组 @@ -296,50 +260,4 @@ public class FileUtils { String baseName = FilenameUtils.getBaseName(fileName); return baseName; } - - public static final FileDto upload(MultipartFile file) throws IOException { - FileDto bean = new FileDto(); - if (file != null && !file.isEmpty()) { - // 验证文件类型 - String originalFileName = file.getOriginalFilename(); - String fileExtension = originalFileName != null ? originalFileName.split("\\.")[1] : ""; - if (isImage(fileExtension)) { - bean.setFileType("1"); - } else { - bean.setFileType("2"); - } - File targetDir = new File(UPLOAD_DIR); - if (!targetDir.exists()) { - targetDir.mkdirs(); - } - String fileName = file.getOriginalFilename(); - String sourceFileName = System.currentTimeMillis() + "_" + file.getOriginalFilename(); - File targetFile = new File(UPLOAD_DIR, fileName); - file.transferTo(targetFile); - String pathName = targetFile.getAbsolutePath(); - bean.setFilePath(pathName); - bean.setFileName(fileName); - bean.setSourceFileName(sourceFileName); - bean.setFileSize(new BigDecimal(file.getSize())); - bean.setSuffixName(fileExtension); - return bean; - } else { - return bean; - } - - } - - /** - * 根据文件扩展名判断是否为图片 - * - * @param fileExtension 文件扩展名(例如 "jpg", "png", "pdf") - * @return true 表示是图片,false 表示是普通文件 - */ - public static boolean isImage(String fileExtension) { - if (fileExtension == null || fileExtension.trim().isEmpty()) { - return false; - } - String ext = fileExtension.toLowerCase().trim(); - return IMAGE_EXTENSIONS.contains(ext); - } }