This commit is contained in:
huangjin
2026-06-29 17:34:59 +08:00
commit fe3ad20fe2
271 changed files with 51767 additions and 0 deletions

View File

@@ -0,0 +1,120 @@
// MinIO 对象存储客户端封装
package minio
import (
"bytes"
"context"
"fmt"
"io"
"path/filepath"
"time"
myconfig "com.sclktx/m/v2/internal/pkg/config"
"github.com/google/uuid"
"github.com/minio/minio-go/v7"
"github.com/minio/minio-go/v7/pkg/credentials"
)
// Client MinIO 客户端
type Client struct {
client *minio.Client
config *myconfig.MinIOConfig
}
// NewClient 创建 MinIO 客户端
func NewClient(cfg *myconfig.MinIOConfig) (*Client, error) {
minioClient, 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 存在
ctx := context.Background()
exists, err := minioClient.BucketExists(ctx, cfg.Bucket)
if err != nil {
return nil, fmt.Errorf("检查 bucket 失败:%w", err)
}
if !exists {
// 创建 bucket
err = minioClient.MakeBucket(ctx, cfg.Bucket, minio.MakeBucketOptions{})
if err != nil {
return nil, fmt.Errorf("创建 bucket 失败:%w", err)
}
}
return &Client{
client: minioClient,
config: cfg,
}, nil
}
// UploadFile 上传文件到 MinIO
// 返回文件的公开访问 URL
func (c *Client) UploadFile(ctx context.Context, reader io.Reader, objectName string, contentType string) (string, error) {
// 上传文件
info, err := c.client.PutObject(ctx, c.config.Bucket, objectName, reader, -1, minio.PutObjectOptions{
ContentType: contentType,
})
if err != nil {
return "", fmt.Errorf("上传文件失败:%w", err)
}
// 生成公开访问 URL不带签名永久有效
// 如果配置了 base_url可带协议如 https://),直接使用
// 否则用 endpoint需自行保证协议正确
urlBase := c.config.BaseURL
if urlBase == "" {
urlBase = c.config.Endpoint
}
url := fmt.Sprintf("%s/%s/%s", urlBase, c.config.Bucket, info.Key)
return url, nil
}
// UploadImage 上传图片文件
// 自动生成唯一的文件名UUID + 时间戳 + 扩展名)
func (c *Client) UploadImage(ctx context.Context, data []byte, filename string) (string, error) {
// 生成唯一的文件名
ext := filepath.Ext(filename)
if ext == "" {
ext = ".jpg" // 默认扩展名
}
// 使用 UUID + 时间戳生成唯一文件名
objectName := fmt.Sprintf("images/%s_%s%s",
time.Now().Format("20060102150405"),
uuid.New().String()[:8],
ext,
)
// 判断内容类型
contentType := "image/jpeg"
switch ext {
case ".png":
contentType = "image/png"
case ".gif":
contentType = "image/gif"
case ".webp":
contentType = "image/webp"
case ".jpg", ".jpeg":
contentType = "image/jpeg"
}
// 上传
reader := bytes.NewReader(data)
return c.UploadFile(ctx, reader, objectName, contentType)
}
// GetClient 获取原始 MinIO 客户端
func (c *Client) GetClient() *minio.Client {
return c.client
}
// GetConfig 获取配置
func (c *Client) GetConfig() *myconfig.MinIOConfig {
return c.config
}