From bb32895a84ed5d86b33112cfb791dd8380dcff66 Mon Sep 17 00:00:00 2001 From: ata <17314593+asdxzaaaaa@user.noreply.gitee.com> Date: Fri, 10 Jul 2026 10:06:50 +0000 Subject: [PATCH] Add internal/storage/minio.go --- internal/storage/minio.go | 79 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 internal/storage/minio.go diff --git a/internal/storage/minio.go b/internal/storage/minio.go new file mode 100644 index 0000000..5be6501 --- /dev/null +++ b/internal/storage/minio.go @@ -0,0 +1,79 @@ +package storage + +import ( + "context" + "fmt" + "io" + "log" + "strings" + + "github.com/minio/minio-go/v7" + "github.com/minio/minio-go/v7/pkg/credentials" + "gotest/internal/config" +) + +// MinIOStorage MinIO 对象存储实现 +type MinIOStorage struct { + client *minio.Client + bucket string + publicURL string +} + +// NewMinIOStorage 创建 MinIO 存储实例 +// 当 AutoCreateBucket 为 true 时自动创建 bucket +func NewMinIOStorage(cfg *config.MinIOConfig) (*MinIOStorage, error) { + client, err := minio.New(cfg.Endpoint, &minio.Options{ + Creds: credentials.NewStaticV4(cfg.AccessKey, cfg.SecretKey, ""), + Secure: cfg.UseSSL, + }) + if err != nil { + return nil, fmt.Errorf("创建 MinIO 客户端失败: %w", err) + } + // 自动创建 bucket + if cfg.AutoCreateBucket { + ctx := context.Background() + exists, err := client.BucketExists(ctx, cfg.Bucket) + if err != nil { + return nil, fmt.Errorf("检查 bucket 是否存在失败: %w", err) + } + if !exists { + if err := client.MakeBucket(ctx, cfg.Bucket, minio.MakeBucketOptions{}); err != nil { + return nil, fmt.Errorf("创建 bucket 失败: %w", err) + } + log.Printf("MinIO bucket %s 已自动创建\n", cfg.Bucket) + } + } + return &MinIOStorage{ + client: client, + bucket: cfg.Bucket, + publicURL: cfg.PublicURL, + }, nil +} + +// Upload 上传文件到 MinIO +func (s *MinIOStorage) Upload(key string, reader io.Reader, contentType string) (string, error) { + ctx := context.Background() + _, err := s.client.PutObject(ctx, s.bucket, key, reader, -1, minio.PutObjectOptions{ + ContentType: contentType, + }) + if err != nil { + return "", fmt.Errorf("上传文件到 MinIO 失败: %w", err) + } + return s.GetURL(key), nil +} + +// Delete 删除 MinIO 中的文件 +func (s *MinIOStorage) Delete(key string) error { + ctx := context.Background() + return s.client.RemoveObject(ctx, s.bucket, key, minio.RemoveObjectOptions{}) +} + +// GetURL 获取 MinIO 文件访问 URL +// 优先使用 PublicURL 拼接,为空时回退到 endpoint +func (s *MinIOStorage) GetURL(key string) string { + base := strings.TrimRight(s.publicURL, "/") + if base == "" { + base = strings.TrimRight(s.client.EndpointURL().String(), "/") + } + return base + "/" + s.bucket + "/" + key +}