package oss_tool import ( "context" "errors" "fmt" cf "git.ssgfgtfy.com/public/ssgf_utils/common_fun" "github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss" "github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials" "image" "image/jpeg" "image/png" "io" "os" "time" ) type ALiYunOSSClient struct { AccessKeyID string AccessKeySecret string Region string ossClient *oss.Client } // NewAliYunOSS 创建阿里云OSS客户端 func (c *ALiYunOSSClient) NewAliYunOSS() (err error) { if c.AccessKeyID == "" || c.AccessKeySecret == "" { return errors.New("请配置 oss accessKeyID accessKeySecret") } if c.Region == "" { return errors.New("请配置 oss region") } provider := credentials.NewStaticCredentialsProvider(c.AccessKeyID, c.AccessKeySecret) cfg := oss.LoadDefaultConfig().WithSignatureVersion(oss.SignatureVersionV4).WithCredentialsProvider(provider).WithRegion(c.Region) c.ossClient = oss.NewClient(cfg) return nil } // BuildPutSignUrl 获取上传签名 func (c *ALiYunOSSClient) BuildPutSignUrl(bucket string, key string, expires time.Duration) (result *oss.PresignResult, err error) { // 生成PutObject的预签名URL result, err = c.ossClient.Presign( context.Background(), &oss.PutObjectRequest{ Bucket: oss.Ptr(bucket), Key: oss.Ptr(key), }, oss.PresignExpires(expires), ) if err != nil { return nil, err } return } // BuildPutSignUrlByPutObjectRequest 根据PutObjectRequest生成PutObject的预签名URL func (c *ALiYunOSSClient) BuildPutSignUrlByPutObjectRequest(req *oss.PutObjectRequest, expires time.Duration) (result *oss.PresignResult, err error) { // 生成PutObject的预签名URL result, err = c.ossClient.Presign( context.Background(), req, oss.PresignExpires(expires), ) if err != nil { return nil, err } return } // BuildSignUrlByGetObjectRequest 根据GetObjectRequest生成GetObject的预签名URL func (c *ALiYunOSSClient) BuildSignUrlByGetObjectRequest(req *oss.GetObjectRequest) (result *oss.PresignResult, err error) { // 生成PutObject的预签名URL result, err = c.ossClient.Presign( context.Background(), req, ) if err != nil { return nil, err } return } // PutForLocalFile 上传本地文件 func (c *ALiYunOSSClient) PutForLocalFile(bucket, key, path string) (result *oss.PutObjectResult, err error) { // 创建上传对象的请求 putRequest := &oss.PutObjectRequest{ Bucket: oss.Ptr(bucket), // 存储空间名称 Key: oss.Ptr(key), // 对象名称 StorageClass: oss.StorageClassStandard, // 指定对象的存储类型为标准存储 ContentType: oss.Ptr("application/octet-stream"), } // 执行上传对象的请求 result, err = c.ossClient.PutObjectFromFile(context.Background(), putRequest, path) if err != nil { return nil, err } return } // GetObject 下载文件,返回的是一个*oss.GetObjectResult (不推荐使用,如果使用的话,需要手动调用object.Body.Close()手动关闭资源) func (c *ALiYunOSSClient) GetObject(bucket string, key string) (object *oss.GetObjectResult, body io.ReadCloser, err error) { getRequest := &oss.GetObjectRequest{ Bucket: oss.Ptr(bucket), // 存储空间名称 Key: oss.Ptr(key), // 对象名称 } // 执行获取对象的操作并处理结果 result, err := c.ossClient.GetObject(context.TODO(), getRequest) if err != nil { return nil, nil, err } //defer func() { // _ = result.Body.Close() // 确保在函数结束时关闭响应体 //}() return result, result.Body, nil } // GetObjectToFile 获取对象并保存到本地 func (c *ALiYunOSSClient) GetObjectToFile(bucket string, key string, path string) (err error) { getRequest := &oss.GetObjectRequest{ Bucket: oss.Ptr(bucket), // 存储空间名称 Key: oss.Ptr(key), // 对象名称 } // 执行获取对象的操作并处理结果 result, err := c.ossClient.GetObject(context.TODO(), getRequest) if err != nil { return err } defer func() { _ = result.Body.Close() // 确保在函数结束时关闭响应体 }() // 确保文件目录存在 err = cf.EnsureParentDirExists(path) if err != nil { return err } // 创建目标文件 file, err := os.Create(path) if err != nil { return err } defer file.Close() // 将 reader 中的内容复制到文件中 _, err = io.Copy(file, result.Body) return nil } // GetObjectToImage 获取对象并保存为图片对象 func (c *ALiYunOSSClient) GetObjectToImage(bucket string, key string) (img image.Image, err error) { getRequest := &oss.GetObjectRequest{ Bucket: oss.Ptr(bucket), // 存储空间名称 Key: oss.Ptr(key), // 对象名称 } // 执行获取对象的操作并处理结果 result, err := c.ossClient.GetObject(context.TODO(), getRequest) if err != nil { return nil, err } defer func() { _ = result.Body.Close() // 确保在函数结束时关闭响应体 }() img, _, err = image.Decode(result.Body) if err != nil { // 尝试 JPEG 解码 img, err = jpeg.Decode(result.Body) if err != nil { // 尝试 PNG 解码 img, err = png.Decode(result.Body) if err != nil { return nil, fmt.Errorf("图片解码失败(支持的格式:JPEG/PNG): %v", err) } } } return img, nil } // DelObject 删除对象 func (c *ALiYunOSSClient) DelObject(bucket string, key string) (result *oss.DeleteObjectResult, err error) { // 创建删除对象的请求 request := &oss.DeleteObjectRequest{ Bucket: oss.Ptr(bucket), // 存储空间名称 Key: oss.Ptr(key), // 对象名称 } // 执行删除对象的操作并处理结果 result, err = c.ossClient.DeleteObject(context.TODO(), request) if err != nil { return nil, err } return result, err }