From 17bc9512899eb2670f99df893ad095be40c78d9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E9=B9=8F=E9=A3=9E?= Date: Mon, 22 Dec 2025 17:36:59 +0800 Subject: [PATCH] =?UTF-8?q?refactor(file-upload):=20=E7=A7=BB=E9=99=A4MinI?= =?UTF-8?q?O=EF=BC=8C=E6=96=B0=E5=A2=9ERustFS=E5=AD=98=E5=82=A8=E6=94=AF?= =?UTF-8?q?=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 删除MinIO相关实现及配置 - 新增RustFS配置类,支持RustFS客户端初始化 - 新增RustFS存储服务实现,实现文件上传接口 - FileController添加日志打印上传异常信息 - pom.xml替换MinIO依赖为AWS SDK S3依赖 - 代码结构优化,提升文件上传模块的扩展性和稳定性 --- .../wms/admin/controller/FileController.java | 3 + nflg-wms-starter/pom.xml | 35 ++++------- .../nflg/wms/starter/config/MinIOConfig.java | 59 ------------------ .../nflg/wms/starter/config/RustFSConfig.java | 39 ++++++++++++ .../service/impl/MinIOServiceImpl.java | 51 ---------------- .../service/impl/RustFSServiceImpl.java | 60 +++++++++++++++++++ 6 files changed, 113 insertions(+), 134 deletions(-) delete mode 100644 nflg-wms-starter/src/main/java/com/nflg/wms/starter/config/MinIOConfig.java create mode 100644 nflg-wms-starter/src/main/java/com/nflg/wms/starter/config/RustFSConfig.java delete mode 100644 nflg-wms-starter/src/main/java/com/nflg/wms/starter/service/impl/MinIOServiceImpl.java create mode 100644 nflg-wms-starter/src/main/java/com/nflg/wms/starter/service/impl/RustFSServiceImpl.java diff --git a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/FileController.java b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/FileController.java index e2480db4..a4b80be6 100644 --- a/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/FileController.java +++ b/nflg-wms-admin/src/main/java/com/nflg/wms/admin/controller/FileController.java @@ -20,6 +20,7 @@ import jakarta.annotation.Resource; import jakarta.validation.Valid; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.FilenameUtils; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; @@ -33,6 +34,7 @@ import java.util.List; /** * 文件管理相关接口 **/ +@Slf4j @RestController @RequestMapping("/file") public class FileController extends BaseController { @@ -58,6 +60,7 @@ public class FileController extends BaseController { String url = fileUploadService.upload(buildFilePath(fileType), file); return ApiResult.success(new FileUploadVO(0L, fileName, url)); } catch (Exception ex) { + log.error("上传文件失败", ex); throw new NflgException(STATE.BusinessError, "上传文件失败:" + ex.getMessage()); } } diff --git a/nflg-wms-starter/pom.xml b/nflg-wms-starter/pom.xml index a4abd924..675ea26a 100644 --- a/nflg-wms-starter/pom.xml +++ b/nflg-wms-starter/pom.xml @@ -43,19 +43,18 @@ com.alibaba.cloud spring-cloud-starter-alibaba-nacos-discovery - - - - - - - - + + + + + + + + org.springframework.boot spring-boot-starter-data-redis - org.projectlombok lombok @@ -94,18 +93,6 @@ org.apache.commons commons-pool2 - - - - - - - - - - - - jakarta.servlet jakarta.servlet-api @@ -126,9 +113,9 @@ - io.minio - minio - 8.5.17 + software.amazon.awssdk + s3 + 2.39.5 diff --git a/nflg-wms-starter/src/main/java/com/nflg/wms/starter/config/MinIOConfig.java b/nflg-wms-starter/src/main/java/com/nflg/wms/starter/config/MinIOConfig.java deleted file mode 100644 index abaafc0c..00000000 --- a/nflg-wms-starter/src/main/java/com/nflg/wms/starter/config/MinIOConfig.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.nflg.wms.starter.config; - -import io.minio.BucketExistsArgs; -import io.minio.MakeBucketArgs; -import io.minio.MinioClient; -import io.minio.SetBucketPolicyArgs; -import jakarta.annotation.PreDestroy; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Lazy; - -@Slf4j -@Configuration -@ConditionalOnProperty(name = "file.upload.type", havingValue = "minio") -public class MinIOConfig { - - @Value("${minio.endpoint}") - private String endpoint; - - @Value("${minio.access-key}") - private String accessKey; - - @Value("${minio.secret-key}") - private String secretKey; - - @Value("${minio.bucket-name}") - private String bucketName; - - private MinioClient client; - - @Bean - @Lazy - public MinioClient initMinioClient() throws Exception{ - client= MinioClient.builder() - .endpoint(endpoint) - .credentials(accessKey, secretKey) - .build(); - // 自动创建 bucket(如果不存在) - if (!client.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) { - client.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build()); - } - String policyJsonString = """ - {"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":"*","Action":"s3:GetObject","Resource":"arn:aws:s3:::%s/*"}]}""".formatted(bucketName); - client.setBucketPolicy(SetBucketPolicyArgs.builder().bucket(bucketName).config(policyJsonString).build()); - return client; - } - - @PreDestroy - public void destroy() { - try { - client.close(); - } catch (Exception e) { - log.error("MinIO 销毁出错", e); - } - } -} diff --git a/nflg-wms-starter/src/main/java/com/nflg/wms/starter/config/RustFSConfig.java b/nflg-wms-starter/src/main/java/com/nflg/wms/starter/config/RustFSConfig.java new file mode 100644 index 00000000..7405fbc2 --- /dev/null +++ b/nflg-wms-starter/src/main/java/com/nflg/wms/starter/config/RustFSConfig.java @@ -0,0 +1,39 @@ +package com.nflg.wms.starter.config; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import software.amazon.awssdk.auth.credentials.AwsBasicCredentials; +import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider; +import software.amazon.awssdk.regions.Region; +import software.amazon.awssdk.services.s3.S3Client; + +import java.net.URI; + +@Slf4j +@Configuration +@ConditionalOnProperty(name = "file.upload.type", havingValue = "rustfs") +public class RustFSConfig { + + @Value("${rustfs.endpoint}") + private String endpoint; + + @Value("${rustfs.access-key}") + private String accessKey; + + @Value("${rustfs.secret-key}") + private String secretKey; + + @Bean + public S3Client s3Client() { + return S3Client.builder() + .endpointOverride(URI.create(endpoint)) + .region(Region.US_EAST_1) // 自建服务通常可设为任意值 + .credentialsProvider(StaticCredentialsProvider.create( + AwsBasicCredentials.create(accessKey, secretKey))) + .forcePathStyle(true) // RustFS 必须启用 Path-Style + .build(); + } +} diff --git a/nflg-wms-starter/src/main/java/com/nflg/wms/starter/service/impl/MinIOServiceImpl.java b/nflg-wms-starter/src/main/java/com/nflg/wms/starter/service/impl/MinIOServiceImpl.java deleted file mode 100644 index 01fe8942..00000000 --- a/nflg-wms-starter/src/main/java/com/nflg/wms/starter/service/impl/MinIOServiceImpl.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.nflg.wms.starter.service.impl; - -import cn.hutool.core.util.StrUtil; -import com.nflg.wms.starter.service.FileUploadService; -import io.minio.MinioClient; -import io.minio.PutObjectArgs; -import jakarta.annotation.Resource; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.stereotype.Service; -import org.springframework.web.multipart.MultipartFile; - -import java.io.InputStream; - -@Slf4j -@Service -@ConditionalOnProperty(name = "file.upload.type", havingValue = "minio") -public class MinIOServiceImpl implements FileUploadService { - - @Value("${minio.bucket-name}") - private String bucketName; - - @Value("${minio.endpoint}") - private String domain; - - @Resource - private MinioClient minioClient; - - @Override - public String upload(String filePath, MultipartFile file) throws Exception { - return upload(filePath, file.getInputStream(), file.getContentType()); - } - - @Override - public String upload(String filePath, InputStream stream, String contentType) throws Exception { - minioClient.putObject(PutObjectArgs.builder() - .bucket(bucketName) - .object(filePath) - .stream(stream, stream.available(), -1) - .contentType(contentType) - .build()); -// return minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder() -// .method(Method.GET) -// .bucket(bucketName) -// .object(filePath) -// .expiry(7, TimeUnit.DAYS) -// .build()); - return StrUtil.format("{}/{}/{}", domain,bucketName, filePath); - } -} diff --git a/nflg-wms-starter/src/main/java/com/nflg/wms/starter/service/impl/RustFSServiceImpl.java b/nflg-wms-starter/src/main/java/com/nflg/wms/starter/service/impl/RustFSServiceImpl.java new file mode 100644 index 00000000..b4eea343 --- /dev/null +++ b/nflg-wms-starter/src/main/java/com/nflg/wms/starter/service/impl/RustFSServiceImpl.java @@ -0,0 +1,60 @@ +package com.nflg.wms.starter.service.impl; + +import cn.hutool.core.util.StrUtil; +import com.nflg.wms.starter.service.FileUploadService; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; +import software.amazon.awssdk.core.sync.RequestBody; +import software.amazon.awssdk.services.s3.S3Client; +import software.amazon.awssdk.services.s3.model.CreateBucketRequest; +import software.amazon.awssdk.services.s3.model.HeadBucketRequest; +import software.amazon.awssdk.services.s3.model.NoSuchBucketException; +import software.amazon.awssdk.services.s3.model.PutObjectRequest; + +import java.io.InputStream; + +@Slf4j +@Service +@ConditionalOnProperty(name = "file.upload.type", havingValue = "rustfs") +public class RustFSServiceImpl implements FileUploadService { + + @Value("${rustfs.bucket-name}") + private String bucketName; + + @Value("${rustfs.domain}") + private String domain; + + @Resource + private S3Client s3Client; + + @Override + public String upload(String filePath, MultipartFile file) throws Exception { + return upload(filePath, file.getInputStream(), file.getContentType()); + } + + @Override + public String upload(String filePath, InputStream stream, String contentType) throws Exception { + ensureBucketExists(); + s3Client.putObject( + PutObjectRequest.builder() + .bucket(bucketName) + .key(filePath) + .contentType(contentType) + .build(), + RequestBody.fromInputStream(stream, stream.available()) + ); + return StrUtil.format("{}/{}/{}", domain, bucketName, filePath); + } + + private void ensureBucketExists() { + try { + s3Client.headBucket(HeadBucketRequest.builder().bucket(bucketName).build()); + } catch (NoSuchBucketException e) { + s3Client.createBucket(CreateBucketRequest.builder().bucket(bucketName).build()); + } + } +}