package upload import ( "context" "fmt" "mime/multipart" "path" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/credentials" "github.com/aws/aws-sdk-go-v2/service/s3" ) // CloudflareR2 Cloudflare R2存储 type CloudflareR2 struct { Bucket string BaseURL string Path string AccountID string AccessKeyID string SecretAccessKey string } // NewCloudflareR2 创建Cloudflare R2 func NewCloudflareR2(bucket, baseURL, r2Path, accountID, accessKeyID, secretAccessKey string) *CloudflareR2 { return &CloudflareR2{ Bucket: bucket, BaseURL: baseURL, Path: r2Path, AccountID: accountID, AccessKeyID: accessKeyID, SecretAccessKey: secretAccessKey, } } func (c *CloudflareR2) getClient(ctx context.Context) (*s3.Client, error) { endpoint := fmt.Sprintf("https://%s.r2.cloudflarestorage.com", c.AccountID) cfg, err := config.LoadDefaultConfig(ctx, config.WithCredentialsProvider(credentials.NewStaticCredentialsProvider(c.AccessKeyID, c.SecretAccessKey, "")), config.WithRegion("auto"), ) if err != nil { return nil, err } client := s3.NewFromConfig(cfg, func(o *s3.Options) { o.BaseEndpoint = aws.String(endpoint) }) return client, nil } // UploadFile 上传文件 func (c *CloudflareR2) UploadFile(file *multipart.FileHeader) (string, string, error) { ctx := context.Background() client, err := c.getClient(ctx) if err != nil { return "", "", err } // 生成文件名和路径 fileName := GenerateFileName(file.Filename) filePath := GeneratePath(c.Path) key := path.Join(filePath, fileName) // 打开文件 src, err := file.Open() if err != nil { return "", "", err } defer src.Close() // 上传 contentType := file.Header.Get("Content-Type") _, err = client.PutObject(ctx, &s3.PutObjectInput{ Bucket: aws.String(c.Bucket), Key: aws.String(key), Body: src, ContentType: aws.String(contentType), }) if err != nil { return "", "", err } // 返回访问URL和key accessURL := c.BaseURL + "/" + key return accessURL, key, nil } // DeleteFile 删除文件 func (c *CloudflareR2) DeleteFile(key string) error { ctx := context.Background() client, err := c.getClient(ctx) if err != nil { return err } _, err = client.DeleteObject(ctx, &s3.DeleteObjectInput{ Bucket: aws.String(c.Bucket), Key: aws.String(key), }) return err }