2023-08-09 03:46:24 +00:00
|
|
|
|
package file
|
|
|
|
|
|
|
|
|
|
import (
|
2023-11-20 06:34:12 +00:00
|
|
|
|
"bytes"
|
2023-08-09 03:46:24 +00:00
|
|
|
|
"context"
|
|
|
|
|
"fusenapi/model/gmodel"
|
|
|
|
|
"fusenapi/utils/basic"
|
2023-11-20 06:34:12 +00:00
|
|
|
|
"io"
|
2023-08-09 07:15:12 +00:00
|
|
|
|
"net/http"
|
2023-08-09 03:46:24 +00:00
|
|
|
|
"time"
|
|
|
|
|
|
2023-11-20 06:34:12 +00:00
|
|
|
|
"github.com/aliyun/aliyun-oss-go-sdk/oss"
|
2023-08-09 03:46:24 +00:00
|
|
|
|
"github.com/aws/aws-sdk-go/aws"
|
|
|
|
|
"github.com/aws/aws-sdk-go/aws/request"
|
|
|
|
|
"github.com/aws/aws-sdk-go/aws/session"
|
|
|
|
|
"github.com/aws/aws-sdk-go/service/s3"
|
|
|
|
|
"github.com/zeromicro/go-zero/core/logx"
|
|
|
|
|
"gorm.io/gorm"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type Upload struct {
|
|
|
|
|
Ctx context.Context
|
|
|
|
|
MysqlConn *gorm.DB
|
|
|
|
|
AwsSession *session.Session
|
2023-11-20 06:34:12 +00:00
|
|
|
|
UploadType string
|
|
|
|
|
AliyunOSS AliyunOSS
|
|
|
|
|
}
|
|
|
|
|
type AliyunOSS struct {
|
|
|
|
|
Endpoint string `json:"endpoint"`
|
|
|
|
|
AccessKeyId string `json:"access_key_id"`
|
|
|
|
|
AccessKeySecret string `json:"access_key_secret"`
|
|
|
|
|
BucketName string `json:"bucket_name"`
|
|
|
|
|
BucketUrl string `json:"bucket_url"`
|
|
|
|
|
BasePath string `json:"base_path"`
|
2023-08-09 03:46:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type UploadBaseReq struct {
|
2023-11-02 07:58:13 +00:00
|
|
|
|
ResourceId string `json:"resource_id"`
|
|
|
|
|
Refresh int64 `json:"refresh"`
|
|
|
|
|
Source string `json:"source"`
|
|
|
|
|
FileHash string `json:"file_hash"`
|
|
|
|
|
FileData string `json:"file_data"`
|
|
|
|
|
Metadata string `json:"metadata"`
|
|
|
|
|
UploadBucket int64 `json:"upload_bucket"`
|
|
|
|
|
ApiType int64 `json:"api_type"`
|
|
|
|
|
UserId int64 `json:"user_id"`
|
|
|
|
|
GuestId int64 `json:"guest_id"`
|
|
|
|
|
FileByte []byte `json:"file_byte"`
|
2023-08-09 03:46:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type UploadBaseRes struct {
|
|
|
|
|
Key string `json:"key"`
|
|
|
|
|
Status int64 `json:"status"`
|
|
|
|
|
ApiType int64 `json:"api_type"`
|
|
|
|
|
ResourceId string `json:"resource_id"`
|
|
|
|
|
ResourceType string `json:"resource_type"`
|
|
|
|
|
ResourceUrl string `json:"resource_url"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (upload *Upload) UploadFileByBase64(req *UploadBaseReq) (*UploadBaseRes, error) {
|
2023-09-07 03:28:06 +00:00
|
|
|
|
var metadataB []byte
|
|
|
|
|
if req.Metadata != "" {
|
|
|
|
|
metadataB = []byte(req.Metadata)
|
|
|
|
|
}
|
2023-08-09 03:46:24 +00:00
|
|
|
|
// 定义存储桶名称
|
|
|
|
|
var bucketName *string
|
|
|
|
|
var apiType int64 = req.ApiType
|
|
|
|
|
|
|
|
|
|
// 根据类别选择存储桶
|
|
|
|
|
switch req.UploadBucket {
|
|
|
|
|
case 2:
|
|
|
|
|
bucketName = basic.TempfileBucketName
|
2023-10-26 06:48:25 +00:00
|
|
|
|
case 3:
|
2023-10-26 07:36:28 +00:00
|
|
|
|
bucketName = basic.StorageBucketName
|
2023-08-09 03:46:24 +00:00
|
|
|
|
default:
|
|
|
|
|
bucketName = basic.StorageBucketName
|
|
|
|
|
}
|
2023-10-26 07:36:28 +00:00
|
|
|
|
// 设置AWS会话的区域
|
|
|
|
|
upload.AwsSession.Config.Region = aws.String("us-east-2")
|
2023-08-09 03:46:24 +00:00
|
|
|
|
|
|
|
|
|
// 创建新的S3服务实例
|
|
|
|
|
svc := s3.New(upload.AwsSession)
|
|
|
|
|
|
|
|
|
|
// 定义S3请求和当前时间
|
|
|
|
|
var s3req *request.Request
|
|
|
|
|
|
|
|
|
|
var resourceId string = req.FileHash
|
|
|
|
|
|
|
|
|
|
var uploadBaseRes = UploadBaseRes{}
|
2023-08-23 07:19:49 +00:00
|
|
|
|
|
2023-08-23 09:51:51 +00:00
|
|
|
|
// 是否强制刷新
|
2023-08-23 07:44:59 +00:00
|
|
|
|
var refresh bool
|
|
|
|
|
if req.ResourceId != "" {
|
|
|
|
|
resourceId = req.ResourceId
|
|
|
|
|
}
|
2023-08-23 09:51:51 +00:00
|
|
|
|
if req.Refresh == 1 {
|
|
|
|
|
refresh = true
|
|
|
|
|
}
|
2023-08-22 02:48:10 +00:00
|
|
|
|
err := upload.MysqlConn.Transaction(func(tx *gorm.DB) (err error) {
|
2023-08-10 08:13:06 +00:00
|
|
|
|
var resourceInfo *gmodel.FsResource
|
2023-08-22 02:48:10 +00:00
|
|
|
|
|
2023-08-23 07:44:59 +00:00
|
|
|
|
if !refresh {
|
2023-08-22 02:48:10 +00:00
|
|
|
|
err = tx.Where("resource_id =?", resourceId).Take(&resourceInfo).Error
|
2023-08-23 07:44:59 +00:00
|
|
|
|
if err == nil && resourceInfo.ResourceId != "" {
|
|
|
|
|
uploadBaseRes.Status = 1
|
|
|
|
|
uploadBaseRes.ResourceId = resourceId
|
|
|
|
|
uploadBaseRes.ResourceUrl = *resourceInfo.ResourceUrl
|
|
|
|
|
} else {
|
|
|
|
|
refresh = true
|
2023-08-23 07:10:22 +00:00
|
|
|
|
}
|
2023-08-23 07:44:59 +00:00
|
|
|
|
}
|
|
|
|
|
if refresh {
|
2023-08-09 06:58:20 +00:00
|
|
|
|
dist, contentType, err := FileBase64ToByte(req.FileData)
|
2023-08-09 03:46:24 +00:00
|
|
|
|
|
2023-08-09 06:58:20 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
logx.Errorf("err:%+v,desc:%+v", err, "fail.upload.resourceInfoGet.mysql")
|
|
|
|
|
return err
|
|
|
|
|
}
|
2023-08-09 03:46:24 +00:00
|
|
|
|
|
2023-08-09 06:58:20 +00:00
|
|
|
|
// 创建S3对象存储请求
|
|
|
|
|
s3req, _ = svc.PutObjectRequest(
|
|
|
|
|
&s3.PutObjectInput{
|
2023-08-28 08:11:54 +00:00
|
|
|
|
Bucket: bucketName,
|
|
|
|
|
Key: &resourceId,
|
2023-10-26 06:46:22 +00:00
|
|
|
|
CacheControl: aws.String("no-cache"),
|
2023-08-09 06:58:20 +00:00
|
|
|
|
},
|
|
|
|
|
)
|
2023-08-09 03:46:24 +00:00
|
|
|
|
|
2023-08-09 06:58:20 +00:00
|
|
|
|
// 设置请求体为文件数据
|
|
|
|
|
s3req.SetBufferBody(dist)
|
2023-08-09 03:46:24 +00:00
|
|
|
|
|
2023-08-09 06:58:20 +00:00
|
|
|
|
// 发送请求
|
2023-08-09 07:15:12 +00:00
|
|
|
|
err = s3req.Send()
|
|
|
|
|
|
|
|
|
|
// 检查是否有错误
|
|
|
|
|
if err != nil {
|
|
|
|
|
logx.Errorf("err:%+v,desc:%+v", err, "fail.upload.s3req")
|
|
|
|
|
return err
|
|
|
|
|
} else {
|
|
|
|
|
var url = s3req.HTTPRequest.URL.String()
|
|
|
|
|
// 打印请求URL
|
|
|
|
|
logx.Info(url)
|
|
|
|
|
uploadBaseRes.Status = 1
|
|
|
|
|
uploadBaseRes.ResourceId = resourceId
|
|
|
|
|
uploadBaseRes.ResourceUrl = url
|
|
|
|
|
var version string = "0.0.1"
|
2023-08-22 02:54:33 +00:00
|
|
|
|
var nowTime = time.Now().UTC()
|
2023-08-23 07:44:59 +00:00
|
|
|
|
if refresh {
|
2023-08-23 03:41:02 +00:00
|
|
|
|
err = tx.Save(&gmodel.FsResource{
|
|
|
|
|
ResourceId: resourceId,
|
|
|
|
|
UserId: &req.UserId,
|
|
|
|
|
GuestId: &req.GuestId,
|
|
|
|
|
ResourceType: &contentType,
|
|
|
|
|
ResourceUrl: &url,
|
|
|
|
|
Version: &version,
|
|
|
|
|
UploadedAt: &nowTime,
|
2023-09-07 03:28:06 +00:00
|
|
|
|
Metadata: &metadataB,
|
2023-08-23 03:41:02 +00:00
|
|
|
|
ApiType: &apiType,
|
|
|
|
|
BucketName: bucketName,
|
|
|
|
|
Source: &req.Source,
|
|
|
|
|
}).Error
|
|
|
|
|
} else {
|
|
|
|
|
err = tx.Create(&gmodel.FsResource{
|
|
|
|
|
ResourceId: resourceId,
|
|
|
|
|
UserId: &req.UserId,
|
|
|
|
|
GuestId: &req.GuestId,
|
|
|
|
|
ResourceType: &contentType,
|
|
|
|
|
ResourceUrl: &url,
|
|
|
|
|
Version: &version,
|
|
|
|
|
UploadedAt: &nowTime,
|
2023-09-07 03:28:06 +00:00
|
|
|
|
Metadata: &metadataB,
|
2023-08-23 03:41:02 +00:00
|
|
|
|
ApiType: &apiType,
|
|
|
|
|
BucketName: bucketName,
|
|
|
|
|
Source: &req.Source,
|
|
|
|
|
}).Error
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-09 07:15:12 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
logx.Errorf("err:%+v,desc:%+v", err, "fail.upload.resourceInfoAdd.mysql")
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-08-10 06:49:46 +00:00
|
|
|
|
|
|
|
|
|
// 返回 nil 提交事务
|
2023-08-09 07:15:12 +00:00
|
|
|
|
return nil
|
|
|
|
|
})
|
2023-08-10 06:49:46 +00:00
|
|
|
|
|
2023-08-09 07:15:12 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return &uploadBaseRes, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (upload *Upload) UploadFileByByte(req *UploadBaseReq) (*UploadBaseRes, error) {
|
2023-09-07 03:28:06 +00:00
|
|
|
|
var metadataB []byte
|
|
|
|
|
if req.Metadata != "" {
|
|
|
|
|
metadataB = []byte(req.Metadata)
|
|
|
|
|
}
|
2023-08-09 07:15:12 +00:00
|
|
|
|
// 定义存储桶名称
|
|
|
|
|
var bucketName *string
|
|
|
|
|
var apiType int64 = req.ApiType
|
|
|
|
|
|
|
|
|
|
// 根据类别选择存储桶
|
|
|
|
|
switch req.UploadBucket {
|
|
|
|
|
case 2:
|
|
|
|
|
bucketName = basic.TempfileBucketName
|
2023-10-26 06:46:22 +00:00
|
|
|
|
case 3:
|
2023-10-26 07:36:28 +00:00
|
|
|
|
bucketName = basic.StorageBucketName
|
2023-08-09 07:15:12 +00:00
|
|
|
|
default:
|
|
|
|
|
bucketName = basic.StorageBucketName
|
|
|
|
|
}
|
2023-10-26 07:36:28 +00:00
|
|
|
|
// 设置AWS会话的区域
|
|
|
|
|
upload.AwsSession.Config.Region = aws.String("us-east-2")
|
2023-08-09 07:15:12 +00:00
|
|
|
|
|
|
|
|
|
// 创建新的S3服务实例
|
|
|
|
|
svc := s3.New(upload.AwsSession)
|
|
|
|
|
|
|
|
|
|
// 定义S3请求和当前时间
|
|
|
|
|
var s3req *request.Request
|
|
|
|
|
|
|
|
|
|
var resourceId string = req.FileHash
|
|
|
|
|
|
|
|
|
|
var uploadBaseRes = UploadBaseRes{}
|
2023-08-10 08:13:06 +00:00
|
|
|
|
|
2023-08-23 09:51:51 +00:00
|
|
|
|
// 是否强制刷新
|
|
|
|
|
var refresh bool
|
|
|
|
|
if req.ResourceId != "" {
|
|
|
|
|
resourceId = req.ResourceId
|
|
|
|
|
}
|
|
|
|
|
if req.Refresh == 1 {
|
|
|
|
|
refresh = true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err := upload.MysqlConn.Transaction(func(tx *gorm.DB) (err error) {
|
2023-08-10 08:13:06 +00:00
|
|
|
|
var resourceInfo *gmodel.FsResource
|
2023-08-23 09:51:51 +00:00
|
|
|
|
if !refresh {
|
|
|
|
|
err = tx.Where("resource_id =?", resourceId).Take(&resourceInfo).Error
|
|
|
|
|
if err == nil && resourceInfo.ResourceId != "" {
|
|
|
|
|
uploadBaseRes.Status = 1
|
|
|
|
|
uploadBaseRes.ResourceId = resourceId
|
|
|
|
|
uploadBaseRes.ResourceUrl = *resourceInfo.ResourceUrl
|
|
|
|
|
} else {
|
|
|
|
|
refresh = true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if refresh {
|
2023-08-09 07:15:12 +00:00
|
|
|
|
contentType := http.DetectContentType(req.FileByte)
|
|
|
|
|
// 创建S3对象存储请求
|
|
|
|
|
s3req, _ = svc.PutObjectRequest(
|
|
|
|
|
&s3.PutObjectInput{
|
2023-08-28 08:11:54 +00:00
|
|
|
|
Bucket: bucketName,
|
|
|
|
|
Key: &resourceId,
|
2023-10-26 06:46:22 +00:00
|
|
|
|
CacheControl: aws.String("no-cache"),
|
2023-08-09 07:15:12 +00:00
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// 设置请求体为文件数据
|
|
|
|
|
s3req.SetBufferBody(req.FileByte)
|
|
|
|
|
|
|
|
|
|
// 发送请求
|
2023-08-09 06:58:20 +00:00
|
|
|
|
err = s3req.Send()
|
|
|
|
|
|
|
|
|
|
// 检查是否有错误
|
2023-08-09 03:46:24 +00:00
|
|
|
|
if err != nil {
|
2023-08-09 06:58:20 +00:00
|
|
|
|
logx.Errorf("err:%+v,desc:%+v", err, "fail.upload.s3req")
|
|
|
|
|
return err
|
|
|
|
|
} else {
|
|
|
|
|
var url = s3req.HTTPRequest.URL.String()
|
|
|
|
|
// 打印请求URL
|
|
|
|
|
logx.Info(url)
|
|
|
|
|
uploadBaseRes.Status = 1
|
|
|
|
|
uploadBaseRes.ResourceId = resourceId
|
|
|
|
|
uploadBaseRes.ResourceUrl = url
|
|
|
|
|
var version string = "0.0.1"
|
2023-08-22 02:54:33 +00:00
|
|
|
|
var nowTime = time.Now().UTC()
|
2023-08-23 09:51:51 +00:00
|
|
|
|
if refresh {
|
|
|
|
|
err = tx.Save(&gmodel.FsResource{
|
|
|
|
|
ResourceId: resourceId,
|
|
|
|
|
UserId: &req.UserId,
|
|
|
|
|
GuestId: &req.GuestId,
|
|
|
|
|
ResourceType: &contentType,
|
|
|
|
|
ResourceUrl: &url,
|
|
|
|
|
Version: &version,
|
|
|
|
|
UploadedAt: &nowTime,
|
2023-09-07 03:28:06 +00:00
|
|
|
|
Metadata: &metadataB,
|
2023-08-23 09:51:51 +00:00
|
|
|
|
ApiType: &apiType,
|
|
|
|
|
BucketName: bucketName,
|
|
|
|
|
Source: &req.Source,
|
|
|
|
|
}).Error
|
|
|
|
|
} else {
|
|
|
|
|
err = tx.Create(&gmodel.FsResource{
|
|
|
|
|
ResourceId: resourceId,
|
|
|
|
|
UserId: &req.UserId,
|
|
|
|
|
GuestId: &req.GuestId,
|
|
|
|
|
ResourceType: &contentType,
|
|
|
|
|
ResourceUrl: &url,
|
|
|
|
|
Version: &version,
|
|
|
|
|
UploadedAt: &nowTime,
|
2023-09-07 03:28:06 +00:00
|
|
|
|
Metadata: &metadataB,
|
2023-08-23 09:51:51 +00:00
|
|
|
|
ApiType: &apiType,
|
|
|
|
|
BucketName: bucketName,
|
|
|
|
|
Source: &req.Source,
|
|
|
|
|
}).Error
|
|
|
|
|
}
|
2023-08-09 06:58:20 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
logx.Errorf("err:%+v,desc:%+v", err, "fail.upload.resourceInfoAdd.mysql")
|
|
|
|
|
return err
|
|
|
|
|
}
|
2023-08-09 03:46:24 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2023-08-09 06:58:20 +00:00
|
|
|
|
return nil
|
|
|
|
|
})
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
2023-08-09 03:46:24 +00:00
|
|
|
|
}
|
2023-08-09 06:58:20 +00:00
|
|
|
|
|
2023-08-09 03:46:24 +00:00
|
|
|
|
return &uploadBaseRes, err
|
|
|
|
|
}
|
2023-11-20 06:34:12 +00:00
|
|
|
|
|
|
|
|
|
// 根据URL上传文件
|
2023-11-20 09:16:14 +00:00
|
|
|
|
func (upload *Upload) UploadFileByUrl(fileHash string, url string, uploadBucket int64) error {
|
|
|
|
|
// 定义存储桶名称
|
|
|
|
|
var bucketName string
|
|
|
|
|
|
|
|
|
|
// 根据类别选择存储桶
|
|
|
|
|
switch uploadBucket {
|
|
|
|
|
case 2:
|
|
|
|
|
bucketName = *basic.TempfileBucketName
|
|
|
|
|
case 3:
|
|
|
|
|
bucketName = *basic.StorageBucketName
|
|
|
|
|
default:
|
|
|
|
|
bucketName = *basic.StorageBucketName
|
|
|
|
|
}
|
2023-11-20 06:34:12 +00:00
|
|
|
|
switch upload.UploadType {
|
|
|
|
|
case "oss":
|
2023-11-20 09:16:14 +00:00
|
|
|
|
yunFileTmpPath := fileHash
|
2023-11-20 06:34:12 +00:00
|
|
|
|
// 创建OSSClient实例。
|
2023-11-20 09:16:14 +00:00
|
|
|
|
clientOss, err := oss.New(upload.AliyunOSS.Endpoint, upload.AliyunOSS.AccessKeyId, upload.AliyunOSS.AccessKeySecret)
|
2023-11-20 06:34:12 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
2023-11-20 09:16:14 +00:00
|
|
|
|
bucket, err := clientOss.Bucket(bucketName)
|
2023-11-20 06:34:12 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
2023-11-20 09:16:14 +00:00
|
|
|
|
|
|
|
|
|
// 创建一个 HTTP 客户端
|
|
|
|
|
client := &http.Client{}
|
|
|
|
|
// 发送一个 GET 请求
|
|
|
|
|
resp, err := client.Get(url)
|
2023-11-20 06:34:12 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
2023-11-20 09:16:14 +00:00
|
|
|
|
// 关闭响应
|
|
|
|
|
defer resp.Body.Close()
|
|
|
|
|
|
|
|
|
|
// 读取响应内容
|
|
|
|
|
buffer, err := io.ReadAll(resp.Body)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err = bucket.PutObject(yunFileTmpPath, bytes.NewReader(buffer))
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
2023-11-20 06:34:12 +00:00
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
default:
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
}
|