From eab133d4f06f85726be425853779a35251563245 Mon Sep 17 00:00:00 2001 From: ata <17314593+asdxzaaaaa@user.noreply.gitee.com> Date: Fri, 10 Jul 2026 10:06:51 +0000 Subject: [PATCH] Add internal/storage/cos.go --- internal/storage/cos.go | 72 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 internal/storage/cos.go diff --git a/internal/storage/cos.go b/internal/storage/cos.go new file mode 100644 index 0000000..77f02da --- /dev/null +++ b/internal/storage/cos.go @@ -0,0 +1,72 @@ +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://.cos..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 +}