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()); + } + } +}