191 lines
5.6 KiB
Go
191 lines
5.6 KiB
Go
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
|
||
}
|
||
|
||
// GetPutSignUrl 获取上传签名
|
||
func (c *ALiYunOSSClient) GetPutSignUrl(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
|
||
}
|
||
|
||
// GetPutSignUrlByPutObjectRequest 根据PutObjectRequest生成PutObject的预签名URL
|
||
func (c *ALiYunOSSClient) GetPutSignUrlByPutObjectRequest(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
|
||
}
|
||
|
||
// GetSignUrlByGetObjectRequest 根据GetObjectRequest生成GetObject的预签名URL
|
||
func (c *ALiYunOSSClient) GetSignUrlByGetObjectRequest(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
|
||
}
|