tkcashgame_v4/pkg/ali/tkoss/client.go

246 lines
6.2 KiB
Go
Raw Normal View History

2025-10-22 10:01:11 +00:00
package tkoss
import (
"bufio"
"bytes"
"fmt"
"io"
"sandc/pkg/ali"
openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
sts20150401 "github.com/alibabacloud-go/sts-20150401/v2/client"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
)
type StsCredentials struct {
RegionId string
Bucket string
AccessKeyId string
AccessKeySecret string
Expiration string
SecurityToken string
}
// 定义sts属性
type stsOption struct {
policy string
roleArn string
roleSessionName string
}
var stsOp = &stsOption{
roleArn: "acs:ram::1280524430176126:role/toukaossram",
roleSessionName: "touka_external",
policy: `{"Version": "1", "Statement": [{"Action": ["oss:PutObject","oss:GetObject"], "Effect": "Allow", "Resource": ["acs:oss:*:*:toukadc-sg/*"]}]}`,
}
type Client struct {
oss *oss.Client
sts *sts20150401.Client
stsOption *stsOption
regionId string
bucket string
}
func NewClient(accessKeyID, accessKeySecret, regionId, bucket string, options ...oss.ClientOption) (*Client, error) {
client, err := oss.New(ali.GetOssEndpointByRegionId(regionId), accessKeyID, accessKeySecret, options...)
if err != nil {
return nil, fmt.Errorf("init ossclient failed: %w", err)
}
stsClient, err := sts20150401.NewClient(&openapi.Config{
AccessKeyId: ali.String(accessKeyID),
AccessKeySecret: ali.String(accessKeySecret),
Endpoint: ali.String(ali.GetStsEndpointByRegionId(regionId)),
})
if err != nil {
return nil, fmt.Errorf("init sts client failed: %w", err)
}
return &Client{
oss: client,
sts: stsClient,
regionId: regionId,
bucket: bucket,
stsOption: stsOp,
}, nil
}
// UplaodFile 上传文件
func (c *Client) UplaodFile(objectKey, filePath string) error {
bucket, err := c.oss.Bucket(c.bucket)
if err != nil {
return err
}
// 用于服务端上传文件。
return bucket.PutObjectFromFile(objectKey, filePath)
}
// UploadByte 上传文件
func (c *Client) UploadByte(objectKey string, data []byte) error {
bucket, err := c.oss.Bucket(c.bucket)
if err != nil {
return err
}
// 用于服务端上传文件。
return bucket.PutObject(objectKey, bytes.NewReader(data))
}
// GenerateSignedUrl 生成临时签名URL
func (c *Client) GenerateSignedUrl(objectKey string, expiredInSec int64) (string, error) {
bucket, err := c.oss.Bucket(c.bucket)
if err != nil {
return "", nil
}
return bucket.SignURL(objectKey, oss.HTTPGet, expiredInSec)
}
// GetObject 获取文件内容
func (c *Client) GetObject(objectKey string) (io.ReadCloser, error) {
bucket, err := c.oss.Bucket(c.bucket)
if err != nil {
return nil, err
}
return bucket.GetObject(objectKey)
}
// GetObjectByte 获取文件byte内容
func (c *Client) GetObjectByte(objectKey string) ([]byte, error) {
bucket, err := c.oss.Bucket(c.bucket)
if err != nil {
return nil, err
}
reader, err := bucket.GetObject(objectKey)
if err != nil {
return nil, fmt.Errorf("reader: %w", err)
}
newReader := bufio.NewReader(reader)
body := make([]byte, 0)
for {
data, err := newReader.ReadBytes('\n')
if err == io.EOF {
body = append(body, data...)
break
}
if err != nil {
return nil, err
}
body = append(body, data...)
}
return body, nil
}
// ListObjectsV2 列举文件
func (c *Client) ListObjectsV2(prefix string) ([]string, error) {
bucket, err := c.oss.Bucket(c.bucket)
if err != nil {
return nil, err
}
res, err := bucket.ListObjectsV2(oss.Prefix(prefix))
if err != nil {
return nil, err
}
var objectKeys []string
for _, object := range res.Objects {
objectKeys = append(objectKeys, object.Key)
}
return objectKeys, nil
}
// UploadFileBySignedUrl 生成签名URL并通过签名URL上传文件
func (c *Client) UploadFileBySignedUrl(objectKey, filePath string, expiredInSec int64) (string, error) {
bucket, err := c.oss.Bucket(c.bucket)
if err != nil {
return "", err
}
signedURL, err := bucket.SignURL(objectKey, oss.HTTPPut, expiredInSec)
if err != nil {
return "", err
}
err = bucket.PutObjectFromFileWithURL(signedURL, filePath)
if err != nil {
return "", err
}
return c.GenerateSignedUrl(objectKey, expiredInSec)
}
// UploadObjectBySignedUrl 通过签名URL上传文件
func (c *Client) UploadObjectBySignedUrl(objectKey string, file []byte, expiredInSec int64) (string, error) {
bucket, err := c.oss.Bucket(c.bucket)
if err != nil {
return "", err
}
signedURL, err := bucket.SignURL(objectKey, oss.HTTPPut, expiredInSec)
if err != nil {
return "", err
}
// filename := os.GetFileName(objectKey) // 没必要保留oss默认的objectKey
// err = bucket.PutObjectWithURL(signedURL, bytes.NewReader(file), oss.ContentDisposition("attachment;filename="+objectKey))
err = bucket.PutObjectWithURL(signedURL, bytes.NewReader(file))
if err != nil {
return "", err
}
return c.GenerateSignedUrl(objectKey, expiredInSec)
}
// CopyObject 复制文件
func (c *Client) CopyObject(srcObjectKey, destObjectKey string) error {
bucket, err := c.oss.Bucket(c.bucket)
if err != nil {
return err
}
_, err = bucket.CopyObject(srcObjectKey, destObjectKey)
if err != nil {
return err
}
return nil
}
// GenerateStsCredentials 生成临时凭证
func (c *Client) GenerateStsCredentials() (*StsCredentials, error) {
assumeRoleRequest := &sts20150401.AssumeRoleRequest{
RoleArn: ali.String(c.stsOption.roleArn),
RoleSessionName: ali.String(c.stsOption.roleSessionName),
Policy: ali.String(c.stsOption.policy),
DurationSeconds: ali.Int64(3600), //默认设置1个小时
}
res, err := c.sts.AssumeRole(assumeRoleRequest)
if err != nil {
return nil, err
}
return &StsCredentials{
RegionId: fmt.Sprintf("oss-%s", c.regionId),
Bucket: c.bucket,
AccessKeyId: ali.StringValue(res.Body.Credentials.AccessKeyId),
AccessKeySecret: ali.StringValue(res.Body.Credentials.AccessKeySecret),
Expiration: ali.StringValue(res.Body.Credentials.Expiration),
SecurityToken: ali.StringValue(res.Body.Credentials.SecurityToken),
}, nil
}
// DeleteObject 删除文件
func (c *Client) DeleteObject(objectKey string) error {
bucket, err := c.oss.Bucket(c.bucket)
if err != nil {
return err
}
return bucket.DeleteObject(objectKey)
}