Files
web_template/internal/storage/cos.go
2026-07-10 10:06:51 +00:00

73 lines
1.8 KiB
Go

package storage
import (
"context"
"fmt"
"io"
"net/http"
"net/url"
"strings"
"github.com/tencentyun/cos-go-sdk-v5"
"gotest/internal/config"
)
// COSStorage 腾讯云 COS 对象存储实现
type COSStorage struct {
client *cos.Client
baseURL string
}
// NewCOSStorage 创建 COS 存储实例
func NewCOSStorage(cfg *config.COSConfig) (*COSStorage, error) {
// 拼接 bucket 访问地址: https://<bucket>.cos.<region>.myqcloud.com
bucketURL := fmt.Sprintf("https://%s.cos.%s.myqcloud.com", cfg.Bucket, cfg.Region)
u, err := url.Parse(bucketURL)
if err != nil {
return nil, fmt.Errorf("解析 COS bucket 地址失败: %w", err)
}
baseURL := &cos.BaseURL{BucketURL: u}
client := cos.NewClient(baseURL, &http.Client{
Transport: &cos.AuthorizationTransport{
SecretID: cfg.SecretID,
SecretKey: cfg.SecretKey,
},
})
return &COSStorage{
client: client,
baseURL: cfg.BaseURL,
}, nil
}
// Upload 上传文件到 COS
func (s *COSStorage) Upload(key string, reader io.Reader, contentType string) (string, error) {
ctx := context.Background()
opt := &cos.ObjectPutOptions{
ObjectPutHeaderOptions: &cos.ObjectPutHeaderOptions{
ContentType: contentType,
},
}
_, err := s.client.Object.Put(ctx, key, reader, opt)
if err != nil {
return "", fmt.Errorf("上传文件到 COS 失败: %w", err)
}
return s.GetURL(key), nil
}
// Delete 删除 COS 中的文件
func (s *COSStorage) Delete(key string) error {
ctx := context.Background()
_, err := s.client.Object.Delete(ctx, key, nil)
return err
}
// GetURL 获取 COS 文件访问 URL
// 优先使用 BaseURL 拼接,为空时回退到 bucket 地址
func (s *COSStorage) GetURL(key string) string {
base := strings.TrimRight(s.baseURL, "/")
if base == "" {
base = strings.TrimRight(s.client.BaseURL.BucketURL.String(), "/")
}
return base + "/" + key
}