diff --git a/modules/core/src/main/java/com/bytedesk/core/upload/UploadMinioService.java b/modules/core/src/main/java/com/bytedesk/core/upload/UploadMinioService.java index 8e030adeb5..5c4988f95b 100644 --- a/modules/core/src/main/java/com/bytedesk/core/upload/UploadMinioService.java +++ b/modules/core/src/main/java/com/bytedesk/core/upload/UploadMinioService.java @@ -19,10 +19,17 @@ import java.net.URL; import java.nio.file.Files; import java.util.concurrent.TimeUnit; +import jakarta.annotation.PostConstruct; + import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile; +import io.minio.BucketExistsArgs; +import io.minio.MakeBucketArgs; +import io.minio.SetBucketPolicyArgs; + import com.bytedesk.core.config.properties.BytedeskProperties; import com.bytedesk.core.utils.BdDateUtils; @@ -43,13 +50,66 @@ import lombok.extern.slf4j.Slf4j; */ @Slf4j @Component +@ConditionalOnProperty(name = "bytedesk.minio.enabled", havingValue = "true", matchIfMissing = false) public class UploadMinioService { @Autowired private BytedeskProperties bytedeskProperties; + @Autowired private MinioClient minioClient; + /** + * 初始化 MinIO 存储桶和策略 + */ + @PostConstruct + public void initMinio() { + try { + String bucketName = bytedeskProperties.getMinioBucketName(); + + // 检查存储桶是否存在,如果不存在则创建 + boolean bucketExists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build()); + if (!bucketExists) { + log.info("创建 MinIO 存储桶: {}", bucketName); + minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build()); + } + + // 设置存储桶策略为公开读取 + String bucketPolicy = String.format(""" + { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": { + "AWS": "*" + }, + "Action": [ + "s3:GetObject" + ], + "Resource": [ + "arn:aws:s3:::%s/*" + ] + } + ] + } + """, bucketName); + + log.info("设置 MinIO 存储桶 {} 为公开读取", bucketName); + minioClient.setBucketPolicy( + SetBucketPolicyArgs.builder() + .bucket(bucketName) + .config(bucketPolicy) + .build() + ); + + log.info("MinIO 初始化完成,存储桶: {}, 策略: 公开读取", bucketName); + + } catch (Exception e) { + log.error("MinIO 初始化失败: {}", e.getMessage(), e); + } + } + /** * 上传文件到 MinIO * diff --git a/modules/core/src/main/java/com/bytedesk/core/upload/UploadRestService.java b/modules/core/src/main/java/com/bytedesk/core/upload/UploadRestService.java index 93e3436404..a85d2eb481 100755 --- a/modules/core/src/main/java/com/bytedesk/core/upload/UploadRestService.java +++ b/modules/core/src/main/java/com/bytedesk/core/upload/UploadRestService.java @@ -2,7 +2,7 @@ * @Author: jackning 270580156@qq.com * @Date: 2024-03-15 11:35:53 * @LastEditors: jackning 270580156@qq.com - * @LastEditTime: 2025-07-27 22:08:46 + * @LastEditTime: 2025-07-27 22:35:52 * @Description: bytedesk.com https://github.com/Bytedesk/bytedesk * Please be aware of the BSL license restrictions before installing Bytedesk IM – * selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license. @@ -28,6 +28,7 @@ import java.time.LocalDate; import java.time.format.DateTimeFormatter; import org.modelmapper.ModelMapper; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.Resource; import org.springframework.core.io.UrlResource; import org.springframework.data.domain.Page; @@ -35,6 +36,7 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.domain.Specification; import org.springframework.orm.ObjectOptimisticLockingFailureException; import org.springframework.stereotype.Service; +import org.springframework.util.FileSystemUtils; import org.springframework.web.multipart.MultipartFile; import com.bytedesk.core.base.BaseRestService; @@ -48,13 +50,13 @@ import com.bytedesk.core.upload.storage.UploadStorageFileNotFoundException; import com.bytedesk.core.utils.BdDateUtils; import com.bytedesk.core.utils.ConvertUtils; -import lombok.AllArgsConstructor; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; // https://spring.io/guides/gs/uploading-files @Slf4j @Service -@AllArgsConstructor +@RequiredArgsConstructor public class UploadRestService extends BaseRestService { private final Path uploadDir; @@ -71,6 +73,7 @@ public class UploadRestService extends BaseRestService