'init'
This commit is contained in:
120
sc-lktx-backend/internal/pkg/minio/client.go
Normal file
120
sc-lktx-backend/internal/pkg/minio/client.go
Normal 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
|
||||
}
|
||||
Reference in New Issue
Block a user