feat: 增强文件上传功能和菜单管理优化
- 新增文件上传预检查功能,支持文件格式和大小验证 - 完善全局异常处理器,增加文件上传异常处理 - 优化菜单管理,添加菜单类型枚举,提升代码可读性 - 完善常量类,新增数据计数阈值常量 - 统一文件上传逻辑,支持图片和文档分类管理
This commit is contained in:
parent
9d17718747
commit
77d2ad543b
@ -126,4 +126,19 @@ public class CoderConstants {
|
|||||||
*/
|
*/
|
||||||
public static final String CODER_COMMON = "CODER_COMMON";
|
public static final String CODER_COMMON = "CODER_COMMON";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据计数阈值 - 多条记录
|
||||||
|
*/
|
||||||
|
public static final Long COUNT_THRESHOLD_MULTIPLE = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据计数阈值 - 单条记录
|
||||||
|
*/
|
||||||
|
public static final Long COUNT_THRESHOLD_SINGLE = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据计数阈值 - 存在性判断
|
||||||
|
*/
|
||||||
|
public static final Long COUNT_THRESHOLD_EXISTS = 0L;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,68 @@
|
|||||||
|
package org.leocoder.thin.domain.enums.menu;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Leocoder
|
||||||
|
* @description [菜单状态枚举]
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum MenuStatusEnum {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 启用
|
||||||
|
*/
|
||||||
|
ENABLED("0", "启用"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 停用
|
||||||
|
*/
|
||||||
|
DISABLED("1", "停用");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 状态值
|
||||||
|
*/
|
||||||
|
private final String value;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 状态描述
|
||||||
|
*/
|
||||||
|
private final String description;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据值获取枚举
|
||||||
|
*
|
||||||
|
* @param value 状态值
|
||||||
|
* @return 对应的枚举
|
||||||
|
*/
|
||||||
|
public static MenuStatusEnum getByValue(String value) {
|
||||||
|
for (MenuStatusEnum status : values()) {
|
||||||
|
if (status.getValue().equals(value)) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否是启用状态
|
||||||
|
*
|
||||||
|
* @param value 状态值
|
||||||
|
* @return 是否是启用状态
|
||||||
|
*/
|
||||||
|
public static boolean isEnabled(String value) {
|
||||||
|
return ENABLED.getValue().equals(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否是停用状态
|
||||||
|
*
|
||||||
|
* @param value 状态值
|
||||||
|
* @return 是否是停用状态
|
||||||
|
*/
|
||||||
|
public static boolean isDisabled(String value) {
|
||||||
|
return DISABLED.getValue().equals(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,83 @@
|
|||||||
|
package org.leocoder.thin.domain.enums.menu;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Leocoder
|
||||||
|
* @description [菜单类型枚举]
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum MenuTypeEnum {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 目录
|
||||||
|
*/
|
||||||
|
DIRECTORY("1", "目录"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 菜单
|
||||||
|
*/
|
||||||
|
MENU("2", "菜单"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按钮
|
||||||
|
*/
|
||||||
|
BUTTON("3", "按钮");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 类型值
|
||||||
|
*/
|
||||||
|
private final String value;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 类型描述
|
||||||
|
*/
|
||||||
|
private final String description;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据值获取枚举
|
||||||
|
*
|
||||||
|
* @param value 类型值
|
||||||
|
* @return 对应的枚举
|
||||||
|
*/
|
||||||
|
public static MenuTypeEnum getByValue(String value) {
|
||||||
|
for (MenuTypeEnum type : values()) {
|
||||||
|
if (type.getValue().equals(value)) {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否是按钮类型
|
||||||
|
*
|
||||||
|
* @param value 类型值
|
||||||
|
* @return 是否是按钮类型
|
||||||
|
*/
|
||||||
|
public static boolean isButton(String value) {
|
||||||
|
return BUTTON.getValue().equals(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否是目录类型
|
||||||
|
*
|
||||||
|
* @param value 类型值
|
||||||
|
* @return 是否是目录类型
|
||||||
|
*/
|
||||||
|
public static boolean isDirectory(String value) {
|
||||||
|
return DIRECTORY.getValue().equals(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否是菜单类型
|
||||||
|
*
|
||||||
|
* @param value 类型值
|
||||||
|
* @return 是否是菜单类型
|
||||||
|
*/
|
||||||
|
public static boolean isMenu(String value) {
|
||||||
|
return MENU.getValue().equals(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -7,6 +7,7 @@ import com.alibaba.excel.util.StringUtils;
|
|||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.leocoder.thin.common.constants.CoderConstants;
|
import org.leocoder.thin.common.constants.CoderConstants;
|
||||||
|
import org.leocoder.thin.common.exception.BusinessException;
|
||||||
import org.leocoder.thin.common.satoken.CoderLoginUtil;
|
import org.leocoder.thin.common.satoken.CoderLoginUtil;
|
||||||
import org.leocoder.thin.common.utils.file.FileTypeUtil;
|
import org.leocoder.thin.common.utils.file.FileTypeUtil;
|
||||||
import org.leocoder.thin.common.utils.file.UploadUtil;
|
import org.leocoder.thin.common.utils.file.UploadUtil;
|
||||||
@ -21,6 +22,9 @@ import org.springframework.core.env.Environment;
|
|||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -37,6 +41,26 @@ public class FileController {
|
|||||||
@Value("${coder.filePath}")
|
@Value("${coder.filePath}")
|
||||||
private String basePath;
|
private String basePath;
|
||||||
|
|
||||||
|
// 允许的图片文件扩展名
|
||||||
|
private static final List<String> ALLOWED_IMAGE_EXTENSIONS = Arrays.asList(
|
||||||
|
"jpg", "jpeg", "png", "gif", "bmp", "webp", "svg"
|
||||||
|
);
|
||||||
|
|
||||||
|
// 允许的文档文件扩展名
|
||||||
|
private static final List<String> ALLOWED_DOCUMENT_EXTENSIONS = Arrays.asList(
|
||||||
|
"doc", "docx", "pdf", "txt", "xls", "xlsx", "ppt", "md", "zip", "rar", "7z"
|
||||||
|
);
|
||||||
|
|
||||||
|
// 文件大小限制(字节)
|
||||||
|
// 1MB
|
||||||
|
private static final long MAX_FILE_SIZE_1MB = 1048576L;
|
||||||
|
// 2MB
|
||||||
|
private static final long MAX_FILE_SIZE_2MB = 2097152L;
|
||||||
|
// 5MB
|
||||||
|
private static final long MAX_FILE_SIZE_5MB = 5242880L;
|
||||||
|
// 10MB
|
||||||
|
private static final long MAX_FILE_SIZE_10MB = 10485760L;
|
||||||
|
|
||||||
private final Environment env;
|
private final Environment env;
|
||||||
|
|
||||||
private final SysFileService sysFileService;
|
private final SysFileService sysFileService;
|
||||||
@ -52,13 +76,18 @@ public class FileController {
|
|||||||
@Operation(summary = "上传文件", description = "上传单个文件到服务器")
|
@Operation(summary = "上传文件", description = "上传单个文件到服务器")
|
||||||
@PostMapping("/file/uploadFile/{fileSize}/{folderName}/{fileParam}")
|
@PostMapping("/file/uploadFile/{fileSize}/{folderName}/{fileParam}")
|
||||||
public Map<String, Object> uploadSingleFile(@RequestParam("file") MultipartFile file, @PathVariable("fileSize") Integer fileSize, @PathVariable("folderName") String folderName, @PathVariable("fileParam") String fileParam) {
|
public Map<String, Object> uploadSingleFile(@RequestParam("file") MultipartFile file, @PathVariable("fileSize") Integer fileSize, @PathVariable("folderName") String folderName, @PathVariable("fileParam") String fileParam) {
|
||||||
|
|
||||||
|
// 文件预检查
|
||||||
|
validateUploadFile(file, fileSize, folderName);
|
||||||
|
|
||||||
Map<String, Object> fileMap = UploadUtil.coderSingleFile(file, basePath + "/" + folderName + "/"+ CoderLoginUtil.getLoginName() + "/", fileSize);
|
Map<String, Object> fileMap = UploadUtil.coderSingleFile(file, basePath + "/" + folderName + "/"+ CoderLoginUtil.getLoginName() + "/", fileSize);
|
||||||
|
|
||||||
|
// 统一保存到文件表,便于文件管理页面统一显示
|
||||||
|
saveUploadFilesInformation(fileMap, CoderConstants.TRUE);
|
||||||
|
|
||||||
|
// 如果是图片,同时保存到图库表(保持图库管理功能)
|
||||||
if (CoderConstants.PICTURES.equals(folderName)) {
|
if (CoderConstants.PICTURES.equals(folderName)) {
|
||||||
// 保存图库信息
|
|
||||||
saveUploadPicturesInformation(fileMap, fileParam, CoderConstants.TRUE);
|
saveUploadPicturesInformation(fileMap, fileParam, CoderConstants.TRUE);
|
||||||
} else {
|
|
||||||
// 保存文件信息
|
|
||||||
saveUploadFilesInformation(fileMap, CoderConstants.TRUE);
|
|
||||||
}
|
}
|
||||||
return fileMap;
|
return fileMap;
|
||||||
}
|
}
|
||||||
@ -82,7 +111,7 @@ public class FileController {
|
|||||||
protocol = "http";
|
protocol = "http";
|
||||||
}
|
}
|
||||||
String hostIp = IpUtil.getHostIp(ServletUtil.getRequest());
|
String hostIp = IpUtil.getHostIp(ServletUtil.getRequest());
|
||||||
String hostPort = StringUtils.isNotBlank(env.getProperty("server.port")) ? env.getProperty("server.port") : "18088";
|
String hostPort = StringUtils.isNotBlank(env.getProperty("server.port")) ? env.getProperty("server.port") : "18099";
|
||||||
log.info("IP地址:{},端口号:{}", hostIp, env.getProperty("server.port"));
|
log.info("IP地址:{},端口号:{}", hostIp, env.getProperty("server.port"));
|
||||||
sysPicture.setPicturePath(protocol + "://" + hostIp + ":" + hostPort + fileMap.get("fileUploadPath").toString());
|
sysPicture.setPicturePath(protocol + "://" + hostIp + ":" + hostPort + fileMap.get("fileUploadPath").toString());
|
||||||
log.info("图片回显地址:{}", sysPicture.getPicturePath());
|
log.info("图片回显地址:{}", sysPicture.getPicturePath());
|
||||||
@ -138,9 +167,96 @@ public class FileController {
|
|||||||
@SaIgnore
|
@SaIgnore
|
||||||
@PostMapping("/file/uploadAnyFile/{fileSize}/{folderName}/{fileParam}")
|
@PostMapping("/file/uploadAnyFile/{fileSize}/{folderName}/{fileParam}")
|
||||||
public Map<String, Object> uploadAnyFile(@RequestParam("file") MultipartFile file, @PathVariable("fileSize") Integer fileSize, @PathVariable("folderName") String folderName, @PathVariable("fileParam") String fileParam) {
|
public Map<String, Object> uploadAnyFile(@RequestParam("file") MultipartFile file, @PathVariable("fileSize") Integer fileSize, @PathVariable("folderName") String folderName, @PathVariable("fileParam") String fileParam) {
|
||||||
|
|
||||||
|
// 文件预检查
|
||||||
|
validateUploadFile(file, fileSize, folderName);
|
||||||
|
|
||||||
Map<String, Object> fileMap = UploadUtil.coderSingleFile(file, basePath + "/" + folderName + "/", fileSize);
|
Map<String, Object> fileMap = UploadUtil.coderSingleFile(file, basePath + "/" + folderName + "/", fileSize);
|
||||||
|
|
||||||
|
// 统一保存到文件表
|
||||||
saveUploadFilesInformation(fileMap, false);
|
saveUploadFilesInformation(fileMap, false);
|
||||||
|
|
||||||
|
// 如果是图片,同时保存到图库表
|
||||||
|
if (CoderConstants.PICTURES.equals(folderName)) {
|
||||||
|
saveUploadPicturesInformation(fileMap, fileParam, false);
|
||||||
|
}
|
||||||
return fileMap;
|
return fileMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description [文件上传预检查]
|
||||||
|
* @author Leocoder
|
||||||
|
*/
|
||||||
|
private void validateUploadFile(MultipartFile file, Integer fileSizeLimit, String folderName) {
|
||||||
|
// 检查文件是否为空
|
||||||
|
if (file == null || file.isEmpty()) {
|
||||||
|
throw new BusinessException(400, "请选择要上传的文件");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查文件大小是否超限
|
||||||
|
long fileSize = file.getSize();
|
||||||
|
long maxSizeBytes = convertMBToBytes(fileSizeLimit);
|
||||||
|
|
||||||
|
if (fileSize > maxSizeBytes) {
|
||||||
|
String sizeMsg = fileSizeLimit + "MB";
|
||||||
|
throw new BusinessException(413, "文件大小超出限制,最大允许上传" + sizeMsg + "的文件");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取文件扩展名
|
||||||
|
String originalFilename = file.getOriginalFilename();
|
||||||
|
if (StringUtils.isBlank(originalFilename)) {
|
||||||
|
throw new BusinessException(400, "文件名不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
String fileExtension = getFileExtension(originalFilename).toLowerCase();
|
||||||
|
if (StringUtils.isBlank(fileExtension)) {
|
||||||
|
throw new BusinessException(400, "文件必须有扩展名");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据文件夹类型检查文件格式
|
||||||
|
if (CoderConstants.PICTURES.equals(folderName)) {
|
||||||
|
// 图片文件检查
|
||||||
|
if (!ALLOWED_IMAGE_EXTENSIONS.contains(fileExtension)) {
|
||||||
|
throw new BusinessException(400, "不支持的图片格式,仅支持:" + String.join(", ", ALLOWED_IMAGE_EXTENSIONS));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 文档文件检查 - 允许图片和文档类型
|
||||||
|
if (!ALLOWED_IMAGE_EXTENSIONS.contains(fileExtension) && !ALLOWED_DOCUMENT_EXTENSIONS.contains(fileExtension)) {
|
||||||
|
List<String> allAllowedExtensions = new ArrayList<>();
|
||||||
|
allAllowedExtensions.addAll(ALLOWED_IMAGE_EXTENSIONS);
|
||||||
|
allAllowedExtensions.addAll(ALLOWED_DOCUMENT_EXTENSIONS);
|
||||||
|
throw new BusinessException(400, "不支持的文件格式,仅支持:" + String.join(", ", allAllowedExtensions));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("文件验证通过:文件名={}, 大小={}bytes, 类型={}", originalFilename, fileSize, fileExtension);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description [将MB转换为字节]
|
||||||
|
* @author Leocoder
|
||||||
|
*/
|
||||||
|
private long convertMBToBytes(Integer fileSizeMB) {
|
||||||
|
if (fileSizeMB == null || fileSizeMB <= 0) {
|
||||||
|
// 默认2MB
|
||||||
|
return MAX_FILE_SIZE_2MB;
|
||||||
|
}
|
||||||
|
return fileSizeMB * 1024L * 1024L;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description [获取文件扩展名]
|
||||||
|
* @author Leocoder
|
||||||
|
*/
|
||||||
|
private String getFileExtension(String filename) {
|
||||||
|
if (StringUtils.isBlank(filename)) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
int lastDotIndex = filename.lastIndexOf('.');
|
||||||
|
if (lastDotIndex == -1 || lastDotIndex == filename.length() - 1) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return filename.substring(lastDotIndex + 1);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,6 +14,7 @@ import org.apache.commons.lang3.ObjectUtils;
|
|||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.leocoder.thin.common.constants.CoderConstants;
|
import org.leocoder.thin.common.constants.CoderConstants;
|
||||||
import org.leocoder.thin.common.exception.coder.YUtil;
|
import org.leocoder.thin.common.exception.coder.YUtil;
|
||||||
|
import org.leocoder.thin.domain.enums.menu.MenuTypeEnum;
|
||||||
import org.leocoder.thin.common.satoken.CoderLoginUtil;
|
import org.leocoder.thin.common.satoken.CoderLoginUtil;
|
||||||
import org.leocoder.thin.domain.enums.oper.OperType;
|
import org.leocoder.thin.domain.enums.oper.OperType;
|
||||||
import org.leocoder.thin.domain.model.bo.element.CascaderLongBo;
|
import org.leocoder.thin.domain.model.bo.element.CascaderLongBo;
|
||||||
@ -103,14 +104,14 @@ public class SysMenuController {
|
|||||||
LambdaQueryWrapper<SysMenu> wrapper = new LambdaQueryWrapper<>();
|
LambdaQueryWrapper<SysMenu> wrapper = new LambdaQueryWrapper<>();
|
||||||
wrapper.eq(SysMenu::getPath, sysMenu.getPath());
|
wrapper.eq(SysMenu::getPath, sysMenu.getPath());
|
||||||
long count = sysMenuService.count(wrapper);
|
long count = sysMenuService.count(wrapper);
|
||||||
YUtil.isTrue(count > 1L, "请联系管理员,检查路由path重复多次");
|
YUtil.isTrue(count > CoderConstants.ONE_LONG, "请联系管理员,检查路由path重复多次");
|
||||||
if (count == 1L) {
|
if (count == CoderConstants.ONE_LONG) {
|
||||||
SysMenu menu = sysMenuService.getOne(wrapper);
|
SysMenu menu = sysMenuService.getOne(wrapper);
|
||||||
YUtil.isTrue(!Objects.equals(menu.getMenuId(), sysMenu.getMenuId()), "该路由path已存在");
|
YUtil.isTrue(!Objects.equals(menu.getMenuId(), sysMenu.getMenuId()), "该路由path已存在");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 如果是按钮类型并且非外链,必须得隐藏。
|
// 如果是按钮类型并且非外链,必须得隐藏。
|
||||||
if (sysMenu.getMenuType().equals("3") && StringUtils.isBlank(sysMenu.getIsLink())) {
|
if (MenuTypeEnum.isButton(sysMenu.getMenuType()) && StringUtils.isBlank(sysMenu.getIsLink())) {
|
||||||
sysMenu.setIsHide(CoderConstants.ZERO_STRING);
|
sysMenu.setIsHide(CoderConstants.ZERO_STRING);
|
||||||
}
|
}
|
||||||
if (StringUtils.isNotBlank(CoderLoginUtil.getUserName())) {
|
if (StringUtils.isNotBlank(CoderLoginUtil.getUserName())) {
|
||||||
@ -134,8 +135,8 @@ public class SysMenuController {
|
|||||||
LambdaQueryWrapper<SysMenu> wrapper = new LambdaQueryWrapper<>();
|
LambdaQueryWrapper<SysMenu> wrapper = new LambdaQueryWrapper<>();
|
||||||
wrapper.eq(SysMenu::getPath, sysMenu.getPath());
|
wrapper.eq(SysMenu::getPath, sysMenu.getPath());
|
||||||
long count = sysMenuService.count(wrapper);
|
long count = sysMenuService.count(wrapper);
|
||||||
YUtil.isTrue(count > 1L, "请联系管理员,检查路由path重复多次");
|
YUtil.isTrue(count > CoderConstants.ONE_LONG, "请联系管理员,检查路由path重复多次");
|
||||||
if (count == 1L) {
|
if (count == CoderConstants.ONE_LONG) {
|
||||||
SysMenu menu = sysMenuService.getOne(wrapper);
|
SysMenu menu = sysMenuService.getOne(wrapper);
|
||||||
YUtil.isTrue(!Objects.equals(menu.getMenuId(), sysMenu.getMenuId()), "该路由path已存在");
|
YUtil.isTrue(!Objects.equals(menu.getMenuId(), sysMenu.getMenuId()), "该路由path已存在");
|
||||||
}
|
}
|
||||||
@ -161,7 +162,7 @@ public class SysMenuController {
|
|||||||
LambdaQueryWrapper<SysMenu> wrapper = new LambdaQueryWrapper<>();
|
LambdaQueryWrapper<SysMenu> wrapper = new LambdaQueryWrapper<>();
|
||||||
wrapper.eq(SysMenu::getParentId, menu.getMenuId());
|
wrapper.eq(SysMenu::getParentId, menu.getMenuId());
|
||||||
long count = sysMenuService.count(wrapper);
|
long count = sysMenuService.count(wrapper);
|
||||||
YUtil.isTrue(count > 0L, "请先删除该节点下的子节点");
|
YUtil.isTrue(count > CoderConstants.ZERO_LONG, "请先删除该节点下的子节点");
|
||||||
YUtil.isTrue(!sysMenuService.removeById(id), "删除失败,请稍后重试");
|
YUtil.isTrue(!sysMenuService.removeById(id), "删除失败,请稍后重试");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -20,6 +20,8 @@ import org.springframework.web.bind.MethodArgumentNotValidException;
|
|||||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||||
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
|
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
|
||||||
|
import org.springframework.web.multipart.MaxUploadSizeExceededException;
|
||||||
|
import org.springframework.web.multipart.MultipartException;
|
||||||
import org.yaml.snakeyaml.constructor.DuplicateKeyException;
|
import org.yaml.snakeyaml.constructor.DuplicateKeyException;
|
||||||
|
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
@ -305,4 +307,56 @@ public class GlobalExceptionHandler {
|
|||||||
return ErrorHandler.error(500, ex.getMessage(), request.getRequestURL().toString());
|
return ErrorHandler.error(500, ex.getMessage(), request.getRequestURL().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description [文件上传大小超限异常]
|
||||||
|
* @author Leocoder
|
||||||
|
*/
|
||||||
|
@ExceptionHandler(MaxUploadSizeExceededException.class)
|
||||||
|
public ErrorHandler handleMaxUploadSizeExceededException(HttpServletRequest request, MaxUploadSizeExceededException ex) {
|
||||||
|
log.error("文件上传大小超限异常:{},请求地址:{}", ex.getMessage(), request.getRequestURL().toString());
|
||||||
|
|
||||||
|
// 提取文件大小限制信息,提供更友好的错误提示
|
||||||
|
String message = "文件大小超出限制,请上传小于2MB的文件";
|
||||||
|
|
||||||
|
// 尝试从异常信息中提取具体的大小限制
|
||||||
|
String exceptionMsg = ex.getMessage();
|
||||||
|
if (exceptionMsg != null && exceptionMsg.contains("maximum permitted size")) {
|
||||||
|
if (exceptionMsg.contains("1048576")) {
|
||||||
|
message = "文件大小超出限制,最大允许上传1MB的文件";
|
||||||
|
} else if (exceptionMsg.contains("2097152")) {
|
||||||
|
message = "文件大小超出限制,最大允许上传2MB的文件";
|
||||||
|
} else if (exceptionMsg.contains("5242880")) {
|
||||||
|
message = "文件大小超出限制,最大允许上传5MB的文件";
|
||||||
|
} else if (exceptionMsg.contains("10485760")) {
|
||||||
|
message = "文件大小超出限制,最大允许上传10MB的文件";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ErrorHandler.error(413, message, request.getRequestURL().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description [文件上传异常]
|
||||||
|
* @author Leocoder
|
||||||
|
*/
|
||||||
|
@ExceptionHandler(MultipartException.class)
|
||||||
|
public ErrorHandler handleMultipartException(HttpServletRequest request, MultipartException ex) {
|
||||||
|
log.error("文件上传异常:{},请求地址:{}", ex.getMessage(), request.getRequestURL().toString());
|
||||||
|
|
||||||
|
String message = "文件上传失败";
|
||||||
|
String exceptionMsg = ex.getMessage();
|
||||||
|
|
||||||
|
if (exceptionMsg != null) {
|
||||||
|
if (exceptionMsg.contains("size")) {
|
||||||
|
message = "文件大小超出限制,请选择较小的文件";
|
||||||
|
} else if (exceptionMsg.contains("format") || exceptionMsg.contains("type")) {
|
||||||
|
message = "文件格式不支持,请选择正确的文件格式";
|
||||||
|
} else if (exceptionMsg.contains("empty")) {
|
||||||
|
message = "请选择要上传的文件";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ErrorHandler.error(400, message, request.getRequestURL().toString());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user