feat: 增强文件上传控制器功能

完善文件上传相关的控制器模块:
- FileController: 通用文件上传控制器
- SysFileController: 系统文件管理控制器
- SysPictureController: 系统图片管理控制器

集成OSS存储服务,支持多种存储方式,
提供统一的文件上传、下载和管理接口。
This commit is contained in:
Leo 2025-07-09 14:44:07 +08:00
parent a810edb0bc
commit b2ea8a3906
3 changed files with 69 additions and 46 deletions

View File

@ -79,16 +79,24 @@ public class FileController {
*/
@Operation(summary = "上传文件", description = "上传单个文件到服务器")
@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,
@RequestParam(value = "storageType", required = false) String requestStorageType) {
// 文件预检查
validateUploadFile(file, fileSize, folderName);
// 确定要使用的存储类型
String requestedStorageType = determineStorageType(requestStorageType);
Map<String, Object> fileMap;
try {
// 根据配置选择存储服务
StorageService storageService = storageServiceFactory.getStorageService(storageType);
// 根据确定的存储类型选择存储服务
StorageService storageService = storageServiceFactory.getStorageService(requestedStorageType);
// 生成唯一文件名
String fileName = OssUtil.generateUniqueFileName(file.getOriginalFilename());
@ -99,11 +107,10 @@ public class FileController {
// 上传文件
fileMap = storageService.uploadFile(file, fileName, folderPath);
log.info("文件上传成功: storageType={}, fileName={}, filePath={}",
storageType, fileName, fileMap.get("filePath"));
log.info("文件上传成功: requestedStorageType={}, fileName={}, filePath={}",
requestedStorageType, fileName, fileMap.get("filePath"));
} catch (Exception e) {
log.error("文件上传失败,尝试使用本地存储降级", e);
// 降级到本地存储
try {
@ -172,6 +179,7 @@ public class FileController {
} else {
sysPicture.setPictureType(fileParam);
}
if (isCreateBy) {
sysPicture.setCreateBy(CoderLoginUtil.getUserName());
}
@ -179,21 +187,18 @@ public class FileController {
}
/**
* @description [保存上传文件信息]
* @author Leocoder
* 保存文件信息到数据库
*/
private void saveUploadFilesInformation(Map<String, Object> fileMap, String storageServiceType, boolean isCreateBy) {
log.info("文件上传 ->");
// 新增文件信息
private void saveUploadFilesInformation(Map<String, Object> fileMap, String storageType, Boolean isCreateBy) {
SysFile sysFile = new SysFile();
sysFile.setFileName(fileMap.get("fileName").toString());
sysFile.setNewName(fileMap.get("newName").toString());
sysFile.setFileSize(fileMap.get("fileSize").toString());
sysFile.setFileSuffix(fileMap.get("suffixName").toString());
sysFile.setFileUpload(fileMap.get("filePath").toString());
sysFile.setFileService(storageServiceType);
sysFile.setFileService(storageType);
// 设置文件访问路径
// 判断是否为完整URL如OSS存储
String fileUploadPath = (String) fileMap.get("fileUploadPath");
if (isFullUrl(fileUploadPath)) {
// 如果已经是完整URL如OSS直接使用
@ -226,6 +231,30 @@ public class FileController {
return StringUtils.isNotBlank(url) && (url.startsWith("http://") || url.startsWith("https://"));
}
/**
* 确定要使用的存储类型
*/
private String determineStorageType(String requestStorageType) {
// 如果前端传递了存储类型优先使用前端选择的类型
if (StringUtils.isNotBlank(requestStorageType)) {
String normalizedType = requestStorageType.trim().toUpperCase();
// 将前端选择的类型转换为实际的存储服务类型
switch (normalizedType) {
case "LOCAL":
return "local";
case "OSS":
return "oss";
default:
log.warn("未知的存储类型: {}, 使用默认配置", requestStorageType);
break;
}
}
// 如果前端没有传递存储类型或类型无效使用配置文件中的默认值
return storageType;
}
/**
* 确定实际使用的存储服务类型
*/
@ -236,14 +265,14 @@ public class FileController {
if (isFullUrl(fileUploadPath)) {
// 如果是完整URL检查是否包含OSS域名
if (fileUploadPath.contains(".aliyuncs.com") || fileUploadPath.contains("oss-")) {
return "3"; // OSS
} else if (fileUploadPath.contains("minio") || fileUploadPath.contains(":9000")) {
return "2"; // MinIO
// OSS
return "3";
}
}
// 默认为本地存储
return "1"; // Local
// Local
return "1";
}
/**
@ -255,16 +284,24 @@ public class FileController {
@Operation(summary = "匿名上传文件", description = "匿名上传单个文件到服务器,无需登录认证")
@SaIgnore
@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,
@RequestParam(value = "storageType", required = false) String requestStorageType) {
// 文件预检查
validateUploadFile(file, fileSize, folderName);
// 确定要使用的存储类型
String requestedStorageType = determineStorageType(requestStorageType);
Map<String, Object> fileMap;
try {
// 根据配置选择存储服务
StorageService storageService = storageServiceFactory.getStorageService(storageType);
// 根据确定的存储类型选择存储服务
StorageService storageService = storageServiceFactory.getStorageService(requestedStorageType);
// 生成唯一文件名
String fileName = OssUtil.generateUniqueFileName(file.getOriginalFilename());
@ -275,8 +312,8 @@ public class FileController {
// 上传文件
fileMap = storageService.uploadFile(file, fileName, folderPath);
log.info("匿名文件上传成功: storageType={}, fileName={}, filePath={}",
storageType, fileName, fileMap.get("filePath"));
log.info("匿名文件上传成功: requestedStorageType={}, fileName={}, filePath={}",
requestedStorageType, fileName, fileMap.get("filePath"));
} catch (Exception e) {
log.error("匿名文件上传失败,尝试使用本地存储降级", e);

View File

@ -169,19 +169,12 @@ public class SysFileController {
boolean deleteResult = false;
switch (fileService) {
case "1": // 本地存储
// 本地存储
case "1":
deleteResult = FileUtil.deleteFile(filePath);
break;
case "2": // MinIO存储
try {
StorageService minioService = storageServiceFactory.getStorageService("minio");
deleteResult = minioService.deleteFile(filePath);
} catch (Exception e) {
log.error("MinIO存储服务不可用尝试本地删除", e);
deleteResult = FileUtil.deleteFile(filePath);
}
break;
case "3": // OSS存储
// OSS存储
case "3":
try {
StorageService ossService = storageServiceFactory.getStorageService("oss");
deleteResult = ossService.deleteFile(filePath);

View File

@ -162,20 +162,13 @@ public class SysPictureController {
boolean deleteResult = false;
switch (fileService) {
case "1": // 本地存储
// 本地存储
case "1":
// 对于本地存储需要使用完整路径
deleteResult = new java.io.File(filePath).delete();
break;
case "2": // MinIO存储
try {
StorageService minioService = storageServiceFactory.getStorageService("minio");
deleteResult = minioService.deleteFile(filePath);
} catch (Exception e) {
log.error("MinIO存储服务不可用跳过删除", e);
deleteResult = false;
}
break;
case "3": // OSS存储
// OSS存储
case "3":
try {
StorageService ossService = storageServiceFactory.getStorageService("oss");
deleteResult = ossService.deleteFile(filePath);