From 1323c1f717c617b465a55b1e9a181c11de053db7 Mon Sep 17 00:00:00 2001 From: 86156 <823267011@qq.com> Date: Tue, 30 Sep 2025 19:23:42 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=B7=A5=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/MinioServiceImpl.java | 153 ++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/service/impl/MinioServiceImpl.java diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/service/impl/MinioServiceImpl.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/service/impl/MinioServiceImpl.java new file mode 100644 index 0000000..12efa0b --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/service/impl/MinioServiceImpl.java @@ -0,0 +1,153 @@ +package com.ruoyi.framework.service.impl; + +import com.ruoyi.framework.config.MinioProperties; +import com.ruoyi.framework.service.MinioService; +import io.minio.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import java.io.InputStream; +import java.util.UUID; + +/** + * MinIO服务实现类 + */ +@Service +@ConditionalOnProperty(name = "minio.enabled", havingValue = "true") +public class MinioServiceImpl implements MinioService { + + private static final Logger log = LoggerFactory.getLogger(MinioServiceImpl.class); + + @Autowired + private MinioProperties minioProperties; + + private MinioClient minioClient; + + private MinioClient getMinioClient() { + if (minioClient == null) { + minioClient = MinioClient.builder() + .endpoint(minioProperties.getEndpoint()) + .credentials(minioProperties.getAccessKey(), minioProperties.getSecretKey()) + .build(); + } + return minioClient; + } + + @Override + public String putObject(String bucketName, String objectName, InputStream inputStream) { + try { + // 确保bucket存在 + ensureBucketExists(bucketName); + + // 上传对象 + getMinioClient().putObject( + PutObjectArgs.builder() + .bucket(bucketName) + .object(objectName) + .stream(inputStream, -1, 10485760) + .build() + ); + + // 返回访问URL + return minioProperties.getEndpoint() + "/" + bucketName + "/" + objectName; + } catch (Exception e) { + log.error("上传对象到MinIO失败: bucket={}, object={}", bucketName, objectName, e); + throw new RuntimeException("上传对象失败: " + e.getMessage(), e); + } + } + + @Override + public InputStream getObject(String bucketName, String objectName) { + try { + return getMinioClient().getObject( + GetObjectArgs.builder() + .bucket(bucketName) + .object(objectName) + .build() + ); + } catch (Exception e) { + log.error("从MinIO获取对象失败: bucket={}, object={}", bucketName, objectName, e); + throw new RuntimeException("获取对象失败: " + e.getMessage(), e); + } + } + + @Override + public void removeObject(String bucketName, String objectName) { + try { + getMinioClient().removeObject( + RemoveObjectArgs.builder() + .bucket(bucketName) + .object(objectName) + .build() + ); + } catch (Exception e) { + log.error("从MinIO删除对象失败: bucket={}, object={}", bucketName, objectName, e); + throw new RuntimeException("删除对象失败: " + e.getMessage(), e); + } + } + + @Override + public boolean objectExists(String bucketName, String objectName) { + try { + getMinioClient().statObject( + StatObjectArgs.builder() + .bucket(bucketName) + .object(objectName) + .build() + ); + return true; + } catch (Exception e) { + return false; + } + } + + @Override + public String getObjectUrl(String bucketName, String objectName) { + return minioProperties.getEndpoint() + "/" + bucketName + "/" + objectName; + } + + @Override + public UploadResult upload(MultipartFile file) throws Exception { + String originalFilename = file.getOriginalFilename(); + String objectName = generateObjectName(originalFilename); + String url = putObject(minioProperties.getBucket(), objectName, file.getInputStream()); + return new UploadResult(objectName, url); + } + + @Override + public UploadResult uploadWithName(MultipartFile file, String objectName) throws Exception { + String url = putObject(minioProperties.getBucket(), objectName, file.getInputStream()); + return new UploadResult(objectName, url); + } + + /** + * 确保bucket存在 + */ + private void ensureBucketExists(String bucketName) throws Exception { + boolean exists = getMinioClient().bucketExists( + BucketExistsArgs.builder().bucket(bucketName).build() + ); + + if (!exists) { + getMinioClient().makeBucket( + MakeBucketArgs.builder().bucket(bucketName).build() + ); + log.info("创建MinIO bucket: {}", bucketName); + } + } + + /** + * 生成对象名称 + */ + private String generateObjectName(String originalFilename) { + String ext = ""; + if (originalFilename != null && originalFilename.contains(".")) { + ext = originalFilename.substring(originalFilename.lastIndexOf(".")); + } + return UUID.randomUUID().toString().replace("-", "") + ext; + } +} \ No newline at end of file