init project

This commit is contained in:
2025-04-09 12:17:33 +08:00
parent 6840d5d5e3
commit f6622a4e98
392 changed files with 55744 additions and 3 deletions

View File

@@ -0,0 +1,75 @@
package upload
import (
"errors"
"mime/multipart"
"time"
"git.echol.cn/loser/lckt/global"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
"go.uber.org/zap"
)
type AliyunOSS struct{}
func (*AliyunOSS) UploadFile(file *multipart.FileHeader) (string, string, error) {
bucket, err := NewBucket()
if err != nil {
global.GVA_LOG.Error("function AliyunOSS.NewBucket() Failed", zap.Any("err", err.Error()))
return "", "", errors.New("function AliyunOSS.NewBucket() Failed, err:" + err.Error())
}
// 读取本地文件。
f, openError := file.Open()
if openError != nil {
global.GVA_LOG.Error("function file.Open() Failed", zap.Any("err", openError.Error()))
return "", "", errors.New("function file.Open() Failed, err:" + openError.Error())
}
defer f.Close() // 创建文件 defer 关闭
// 上传阿里云路径 文件名格式 自己可以改 建议保证唯一性
// yunFileTmpPath := filepath.Join("uploads", time.Now().Format("2006-01-02")) + "/" + file.Filename
yunFileTmpPath := global.GVA_CONFIG.AliyunOSS.BasePath + "/" + "uploads" + "/" + time.Now().Format("2006-01-02") + "/" + file.Filename
// 上传文件流。
err = bucket.PutObject(yunFileTmpPath, f)
if err != nil {
global.GVA_LOG.Error("function formUploader.Put() Failed", zap.Any("err", err.Error()))
return "", "", errors.New("function formUploader.Put() Failed, err:" + err.Error())
}
return global.GVA_CONFIG.AliyunOSS.BucketUrl + "/" + yunFileTmpPath, yunFileTmpPath, nil
}
func (*AliyunOSS) DeleteFile(key string) error {
bucket, err := NewBucket()
if err != nil {
global.GVA_LOG.Error("function AliyunOSS.NewBucket() Failed", zap.Any("err", err.Error()))
return errors.New("function AliyunOSS.NewBucket() Failed, err:" + err.Error())
}
// 删除单个文件。objectName表示删除OSS文件时需要指定包含文件后缀在内的完整路径例如abc/efg/123.jpg。
// 如需删除文件夹请将objectName设置为对应的文件夹名称。如果文件夹非空则需要将文件夹下的所有object删除后才能删除该文件夹。
err = bucket.DeleteObject(key)
if err != nil {
global.GVA_LOG.Error("function bucketManager.Delete() failed", zap.Any("err", err.Error()))
return errors.New("function bucketManager.Delete() failed, err:" + err.Error())
}
return nil
}
func NewBucket() (*oss.Bucket, error) {
// 创建OSSClient实例。
client, err := oss.New(global.GVA_CONFIG.AliyunOSS.Endpoint, global.GVA_CONFIG.AliyunOSS.AccessKeyId, global.GVA_CONFIG.AliyunOSS.AccessKeySecret)
if err != nil {
return nil, err
}
// 获取存储空间。
bucket, err := client.Bucket(global.GVA_CONFIG.AliyunOSS.BucketName)
if err != nil {
return nil, err
}
return bucket, nil
}

97
utils/upload/aws_s3.go Normal file
View File

@@ -0,0 +1,97 @@
package upload
import (
"errors"
"fmt"
"mime/multipart"
"time"
"git.echol.cn/loser/lckt/global"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/s3"
"github.com/aws/aws-sdk-go/service/s3/s3manager"
"go.uber.org/zap"
)
type AwsS3 struct{}
//@author: [WqyJh](https://github.com/WqyJh)
//@object: *AwsS3
//@function: UploadFile
//@description: Upload file to Aws S3 using aws-sdk-go. See https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/s3-example-basic-bucket-operations.html#s3-examples-bucket-ops-upload-file-to-bucket
//@param: file *multipart.FileHeader
//@return: string, string, error
func (*AwsS3) UploadFile(file *multipart.FileHeader) (string, string, error) {
session := newSession()
uploader := s3manager.NewUploader(session)
fileKey := fmt.Sprintf("%d%s", time.Now().Unix(), file.Filename)
filename := global.GVA_CONFIG.AwsS3.PathPrefix + "/" + fileKey
f, openError := file.Open()
if openError != nil {
global.GVA_LOG.Error("function file.Open() failed", zap.Any("err", openError.Error()))
return "", "", errors.New("function file.Open() failed, err:" + openError.Error())
}
defer f.Close() // 创建文件 defer 关闭
_, err := uploader.Upload(&s3manager.UploadInput{
Bucket: aws.String(global.GVA_CONFIG.AwsS3.Bucket),
Key: aws.String(filename),
Body: f,
})
if err != nil {
global.GVA_LOG.Error("function uploader.Upload() failed", zap.Any("err", err.Error()))
return "", "", err
}
return global.GVA_CONFIG.AwsS3.BaseURL + "/" + filename, fileKey, nil
}
//@author: [WqyJh](https://github.com/WqyJh)
//@object: *AwsS3
//@function: DeleteFile
//@description: Delete file from Aws S3 using aws-sdk-go. See https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/s3-example-basic-bucket-operations.html#s3-examples-bucket-ops-delete-bucket-item
//@param: file *multipart.FileHeader
//@return: string, string, error
func (*AwsS3) DeleteFile(key string) error {
session := newSession()
svc := s3.New(session)
filename := global.GVA_CONFIG.AwsS3.PathPrefix + "/" + key
bucket := global.GVA_CONFIG.AwsS3.Bucket
_, err := svc.DeleteObject(&s3.DeleteObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(filename),
})
if err != nil {
global.GVA_LOG.Error("function svc.DeleteObject() failed", zap.Any("err", err.Error()))
return errors.New("function svc.DeleteObject() failed, err:" + err.Error())
}
_ = svc.WaitUntilObjectNotExists(&s3.HeadObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(filename),
})
return nil
}
// newSession Create S3 session
func newSession() *session.Session {
sess, _ := session.NewSession(&aws.Config{
Region: aws.String(global.GVA_CONFIG.AwsS3.Region),
Endpoint: aws.String(global.GVA_CONFIG.AwsS3.Endpoint), //minio在这里设置地址,可以兼容
S3ForcePathStyle: aws.Bool(global.GVA_CONFIG.AwsS3.S3ForcePathStyle),
DisableSSL: aws.Bool(global.GVA_CONFIG.AwsS3.DisableSSL),
Credentials: credentials.NewStaticCredentials(
global.GVA_CONFIG.AwsS3.SecretID,
global.GVA_CONFIG.AwsS3.SecretKey,
"",
),
})
return sess
}

View File

@@ -0,0 +1,85 @@
package upload
import (
"errors"
"fmt"
"mime/multipart"
"time"
"git.echol.cn/loser/lckt/global"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/s3"
"github.com/aws/aws-sdk-go/service/s3/s3manager"
"go.uber.org/zap"
)
type CloudflareR2 struct{}
func (c *CloudflareR2) UploadFile(file *multipart.FileHeader) (fileUrl string, fileName string, err error) {
session := c.newSession()
client := s3manager.NewUploader(session)
fileKey := fmt.Sprintf("%d_%s", time.Now().Unix(), file.Filename)
fileName = fmt.Sprintf("%s/%s", global.GVA_CONFIG.CloudflareR2.Path, fileKey)
f, openError := file.Open()
if openError != nil {
global.GVA_LOG.Error("function file.Open() failed", zap.Any("err", openError.Error()))
return "", "", errors.New("function file.Open() failed, err:" + openError.Error())
}
defer f.Close() // 创建文件 defer 关闭
input := &s3manager.UploadInput{
Bucket: aws.String(global.GVA_CONFIG.CloudflareR2.Bucket),
Key: aws.String(fileName),
Body: f,
}
_, err = client.Upload(input)
if err != nil {
global.GVA_LOG.Error("function uploader.Upload() failed", zap.Any("err", err.Error()))
return "", "", err
}
return fmt.Sprintf("%s/%s", global.GVA_CONFIG.CloudflareR2.BaseURL,
fileName),
fileKey,
nil
}
func (c *CloudflareR2) DeleteFile(key string) error {
session := newSession()
svc := s3.New(session)
filename := global.GVA_CONFIG.CloudflareR2.Path + "/" + key
bucket := global.GVA_CONFIG.CloudflareR2.Bucket
_, err := svc.DeleteObject(&s3.DeleteObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(filename),
})
if err != nil {
global.GVA_LOG.Error("function svc.DeleteObject() failed", zap.Any("err", err.Error()))
return errors.New("function svc.DeleteObject() failed, err:" + err.Error())
}
_ = svc.WaitUntilObjectNotExists(&s3.HeadObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(filename),
})
return nil
}
func (*CloudflareR2) newSession() *session.Session {
endpoint := fmt.Sprintf("%s.r2.cloudflarestorage.com", global.GVA_CONFIG.CloudflareR2.AccountID)
return session.Must(session.NewSession(&aws.Config{
Region: aws.String("auto"),
Endpoint: aws.String(endpoint),
Credentials: credentials.NewStaticCredentials(
global.GVA_CONFIG.CloudflareR2.AccessKeyID,
global.GVA_CONFIG.CloudflareR2.SecretAccessKey,
"",
),
}))
}

109
utils/upload/local.go Normal file
View File

@@ -0,0 +1,109 @@
package upload
import (
"errors"
"io"
"mime/multipart"
"os"
"path/filepath"
"strings"
"sync"
"time"
"git.echol.cn/loser/lckt/global"
"git.echol.cn/loser/lckt/utils"
"go.uber.org/zap"
)
var mu sync.Mutex
type Local struct{}
//@author: [piexlmax](https://github.com/piexlmax)
//@author: [ccfish86](https://github.com/ccfish86)
//@author: [SliverHorn](https://github.com/SliverHorn)
//@object: *Local
//@function: UploadFile
//@description: 上传文件
//@param: file *multipart.FileHeader
//@return: string, string, error
func (*Local) UploadFile(file *multipart.FileHeader) (string, string, error) {
// 读取文件后缀
ext := filepath.Ext(file.Filename)
// 读取文件名并加密
name := strings.TrimSuffix(file.Filename, ext)
name = utils.MD5V([]byte(name))
// 拼接新文件名
filename := name + "_" + time.Now().Format("20060102150405") + ext
// 尝试创建此路径
mkdirErr := os.MkdirAll(global.GVA_CONFIG.Local.StorePath, os.ModePerm)
if mkdirErr != nil {
global.GVA_LOG.Error("function os.MkdirAll() failed", zap.Any("err", mkdirErr.Error()))
return "", "", errors.New("function os.MkdirAll() failed, err:" + mkdirErr.Error())
}
// 拼接路径和文件名
p := global.GVA_CONFIG.Local.StorePath + "/" + filename
filepath := global.GVA_CONFIG.Local.Path + "/" + filename
f, openError := file.Open() // 读取文件
if openError != nil {
global.GVA_LOG.Error("function file.Open() failed", zap.Any("err", openError.Error()))
return "", "", errors.New("function file.Open() failed, err:" + openError.Error())
}
defer f.Close() // 创建文件 defer 关闭
out, createErr := os.Create(p)
if createErr != nil {
global.GVA_LOG.Error("function os.Create() failed", zap.Any("err", createErr.Error()))
return "", "", errors.New("function os.Create() failed, err:" + createErr.Error())
}
defer out.Close() // 创建文件 defer 关闭
_, copyErr := io.Copy(out, f) // 传输(拷贝)文件
if copyErr != nil {
global.GVA_LOG.Error("function io.Copy() failed", zap.Any("err", copyErr.Error()))
return "", "", errors.New("function io.Copy() failed, err:" + copyErr.Error())
}
return filepath, filename, nil
}
//@author: [piexlmax](https://github.com/piexlmax)
//@author: [ccfish86](https://github.com/ccfish86)
//@author: [SliverHorn](https://github.com/SliverHorn)
//@object: *Local
//@function: DeleteFile
//@description: 删除文件
//@param: key string
//@return: error
func (*Local) DeleteFile(key string) error {
// 检查 key 是否为空
if key == "" {
return errors.New("key不能为空")
}
// 验证 key 是否包含非法字符或尝试访问存储路径之外的文件
if strings.Contains(key, "..") || strings.ContainsAny(key, `\/:*?"<>|`) {
return errors.New("非法的key")
}
p := filepath.Join(global.GVA_CONFIG.Local.StorePath, key)
// 检查文件是否存在
if _, err := os.Stat(p); os.IsNotExist(err) {
return errors.New("文件不存在")
}
// 使用文件锁防止并发删除
mu.Lock()
defer mu.Unlock()
err := os.Remove(p)
if err != nil {
return errors.New("文件删除失败: " + err.Error())
}
return nil
}

99
utils/upload/minio_oss.go Normal file
View File

@@ -0,0 +1,99 @@
package upload
import (
"bytes"
"context"
"errors"
"io"
"mime/multipart"
"path/filepath"
"strings"
"time"
"git.echol.cn/loser/lckt/global"
"git.echol.cn/loser/lckt/utils"
"github.com/minio/minio-go/v7"
"github.com/minio/minio-go/v7/pkg/credentials"
"go.uber.org/zap"
)
var MinioClient *Minio // 优化性能,但是不支持动态配置
type Minio struct {
Client *minio.Client
bucket string
}
func GetMinio(endpoint, accessKeyID, secretAccessKey, bucketName string, useSSL bool) (*Minio, error) {
if MinioClient != nil {
return MinioClient, nil
}
// Initialize minio client object.
minioClient, err := minio.New(endpoint, &minio.Options{
Creds: credentials.NewStaticV4(accessKeyID, secretAccessKey, ""),
Secure: useSSL, // Set to true if using https
})
if err != nil {
return nil, err
}
// 尝试创建bucket
err = minioClient.MakeBucket(context.Background(), bucketName, minio.MakeBucketOptions{})
if err != nil {
// Check to see if we already own this bucket (which happens if you run this twice)
exists, errBucketExists := minioClient.BucketExists(context.Background(), bucketName)
if errBucketExists == nil && exists {
// log.Printf("We already own %s\n", bucketName)
} else {
return nil, err
}
}
MinioClient = &Minio{Client: minioClient, bucket: bucketName}
return MinioClient, nil
}
func (m *Minio) UploadFile(file *multipart.FileHeader) (filePathres, key string, uploadErr error) {
f, openError := file.Open()
// mutipart.File to os.File
if openError != nil {
global.GVA_LOG.Error("function file.Open() Failed", zap.Any("err", openError.Error()))
return "", "", errors.New("function file.Open() Failed, err:" + openError.Error())
}
filecontent := bytes.Buffer{}
_, err := io.Copy(&filecontent, f)
if err != nil {
global.GVA_LOG.Error("读取文件失败", zap.Any("err", err.Error()))
return "", "", errors.New("读取文件失败, err:" + err.Error())
}
f.Close() // 创建文件 defer 关闭
// 对文件名进行加密存储
ext := filepath.Ext(file.Filename)
filename := utils.MD5V([]byte(strings.TrimSuffix(file.Filename, ext))) + ext
if global.GVA_CONFIG.Minio.BasePath == "" {
filePathres = "uploads" + "/" + time.Now().Format("2006-01-02") + "/" + filename
} else {
filePathres = global.GVA_CONFIG.Minio.BasePath + "/" + time.Now().Format("2006-01-02") + "/" + filename
}
// 设置超时10分钟
ctx, cancel := context.WithTimeout(context.Background(), time.Minute*10)
defer cancel()
// Upload the file with PutObject 大文件自动切换为分片上传
info, err := m.Client.PutObject(ctx, global.GVA_CONFIG.Minio.BucketName, filePathres, &filecontent, file.Size, minio.PutObjectOptions{ContentType: "application/octet-stream"})
if err != nil {
global.GVA_LOG.Error("上传文件到minio失败", zap.Any("err", err.Error()))
return "", "", errors.New("上传文件到minio失败, err:" + err.Error())
}
return global.GVA_CONFIG.Minio.BucketUrl + "/" + info.Key, filePathres, nil
}
func (m *Minio) DeleteFile(key string) error {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
defer cancel()
// Delete the object from MinIO
err := m.Client.RemoveObject(ctx, m.bucket, key, minio.RemoveObjectOptions{})
return err
}

69
utils/upload/obs.go Normal file
View File

@@ -0,0 +1,69 @@
package upload
import (
"mime/multipart"
"git.echol.cn/loser/lckt/global"
"github.com/huaweicloud/huaweicloud-sdk-go-obs/obs"
"github.com/pkg/errors"
)
var HuaWeiObs = new(Obs)
type Obs struct{}
func NewHuaWeiObsClient() (client *obs.ObsClient, err error) {
return obs.New(global.GVA_CONFIG.HuaWeiObs.AccessKey, global.GVA_CONFIG.HuaWeiObs.SecretKey, global.GVA_CONFIG.HuaWeiObs.Endpoint)
}
func (o *Obs) UploadFile(file *multipart.FileHeader) (string, string, error) {
// var open multipart.File
open, err := file.Open()
if err != nil {
return "", "", err
}
defer open.Close()
filename := file.Filename
input := &obs.PutObjectInput{
PutObjectBasicInput: obs.PutObjectBasicInput{
ObjectOperationInput: obs.ObjectOperationInput{
Bucket: global.GVA_CONFIG.HuaWeiObs.Bucket,
Key: filename,
},
HttpHeader: obs.HttpHeader{
ContentType: file.Header.Get("content-type"),
},
},
Body: open,
}
var client *obs.ObsClient
client, err = NewHuaWeiObsClient()
if err != nil {
return "", "", errors.Wrap(err, "获取华为对象存储对象失败!")
}
_, err = client.PutObject(input)
if err != nil {
return "", "", errors.Wrap(err, "文件上传失败!")
}
filepath := global.GVA_CONFIG.HuaWeiObs.Path + "/" + filename
return filepath, filename, err
}
func (o *Obs) DeleteFile(key string) error {
client, err := NewHuaWeiObsClient()
if err != nil {
return errors.Wrap(err, "获取华为对象存储对象失败!")
}
input := &obs.DeleteObjectInput{
Bucket: global.GVA_CONFIG.HuaWeiObs.Bucket,
Key: key,
}
var output *obs.DeleteObjectOutput
output, err = client.DeleteObject(input)
if err != nil {
return errors.Wrapf(err, "删除对象(%s)失败!, output: %v", key, output)
}
return nil
}

96
utils/upload/qiniu.go Normal file
View File

@@ -0,0 +1,96 @@
package upload
import (
"context"
"errors"
"fmt"
"mime/multipart"
"time"
"git.echol.cn/loser/lckt/global"
"github.com/qiniu/go-sdk/v7/auth/qbox"
"github.com/qiniu/go-sdk/v7/storage"
"go.uber.org/zap"
)
type Qiniu struct{}
//@author: [piexlmax](https://github.com/piexlmax)
//@author: [ccfish86](https://github.com/ccfish86)
//@author: [SliverHorn](https://github.com/SliverHorn)
//@object: *Qiniu
//@function: UploadFile
//@description: 上传文件
//@param: file *multipart.FileHeader
//@return: string, string, error
func (*Qiniu) UploadFile(file *multipart.FileHeader) (string, string, error) {
putPolicy := storage.PutPolicy{Scope: global.GVA_CONFIG.Qiniu.Bucket}
mac := qbox.NewMac(global.GVA_CONFIG.Qiniu.AccessKey, global.GVA_CONFIG.Qiniu.SecretKey)
upToken := putPolicy.UploadToken(mac)
cfg := qiniuConfig()
formUploader := storage.NewFormUploader(cfg)
ret := storage.PutRet{}
putExtra := storage.PutExtra{Params: map[string]string{"x:name": "github logo"}}
f, openError := file.Open()
if openError != nil {
global.GVA_LOG.Error("function file.Open() failed", zap.Any("err", openError.Error()))
return "", "", errors.New("function file.Open() failed, err:" + openError.Error())
}
defer f.Close() // 创建文件 defer 关闭
fileKey := fmt.Sprintf("%d%s", time.Now().Unix(), file.Filename) // 文件名格式 自己可以改 建议保证唯一性
putErr := formUploader.Put(context.Background(), &ret, upToken, fileKey, f, file.Size, &putExtra)
if putErr != nil {
global.GVA_LOG.Error("function formUploader.Put() failed", zap.Any("err", putErr.Error()))
return "", "", errors.New("function formUploader.Put() failed, err:" + putErr.Error())
}
return global.GVA_CONFIG.Qiniu.ImgPath + "/" + ret.Key, ret.Key, nil
}
//@author: [piexlmax](https://github.com/piexlmax)
//@author: [ccfish86](https://github.com/ccfish86)
//@author: [SliverHorn](https://github.com/SliverHorn)
//@object: *Qiniu
//@function: DeleteFile
//@description: 删除文件
//@param: key string
//@return: error
func (*Qiniu) DeleteFile(key string) error {
mac := qbox.NewMac(global.GVA_CONFIG.Qiniu.AccessKey, global.GVA_CONFIG.Qiniu.SecretKey)
cfg := qiniuConfig()
bucketManager := storage.NewBucketManager(mac, cfg)
if err := bucketManager.Delete(global.GVA_CONFIG.Qiniu.Bucket, key); err != nil {
global.GVA_LOG.Error("function bucketManager.Delete() failed", zap.Any("err", err.Error()))
return errors.New("function bucketManager.Delete() failed, err:" + err.Error())
}
return nil
}
//@author: [SliverHorn](https://github.com/SliverHorn)
//@object: *Qiniu
//@function: qiniuConfig
//@description: 根据配置文件进行返回七牛云的配置
//@return: *storage.Config
func qiniuConfig() *storage.Config {
cfg := storage.Config{
UseHTTPS: global.GVA_CONFIG.Qiniu.UseHTTPS,
UseCdnDomains: global.GVA_CONFIG.Qiniu.UseCdnDomains,
}
switch global.GVA_CONFIG.Qiniu.Zone { // 根据配置文件进行初始化空间对应的机房
case "ZoneHuadong":
cfg.Zone = &storage.ZoneHuadong
case "ZoneHuabei":
cfg.Zone = &storage.ZoneHuabei
case "ZoneHuanan":
cfg.Zone = &storage.ZoneHuanan
case "ZoneBeimei":
cfg.Zone = &storage.ZoneBeimei
case "ZoneXinjiapo":
cfg.Zone = &storage.ZoneXinjiapo
}
return &cfg
}

View File

@@ -0,0 +1,61 @@
package upload
import (
"context"
"errors"
"fmt"
"mime/multipart"
"net/http"
"net/url"
"time"
"git.echol.cn/loser/lckt/global"
"github.com/tencentyun/cos-go-sdk-v5"
"go.uber.org/zap"
)
type TencentCOS struct{}
// UploadFile upload file to COS
func (*TencentCOS) UploadFile(file *multipart.FileHeader) (string, string, error) {
client := NewClient()
f, openError := file.Open()
if openError != nil {
global.GVA_LOG.Error("function file.Open() failed", zap.Any("err", openError.Error()))
return "", "", errors.New("function file.Open() failed, err:" + openError.Error())
}
defer f.Close() // 创建文件 defer 关闭
fileKey := fmt.Sprintf("%d%s", time.Now().Unix(), file.Filename)
_, err := client.Object.Put(context.Background(), global.GVA_CONFIG.TencentCOS.PathPrefix+"/"+fileKey, f, nil)
if err != nil {
panic(err)
}
return global.GVA_CONFIG.TencentCOS.BaseURL + "/" + global.GVA_CONFIG.TencentCOS.PathPrefix + "/" + fileKey, fileKey, nil
}
// DeleteFile delete file form COS
func (*TencentCOS) DeleteFile(key string) error {
client := NewClient()
name := global.GVA_CONFIG.TencentCOS.PathPrefix + "/" + key
_, err := client.Object.Delete(context.Background(), name)
if err != nil {
global.GVA_LOG.Error("function bucketManager.Delete() failed", zap.Any("err", err.Error()))
return errors.New("function bucketManager.Delete() failed, err:" + err.Error())
}
return nil
}
// NewClient init COS client
func NewClient() *cos.Client {
urlStr, _ := url.Parse("https://" + global.GVA_CONFIG.TencentCOS.Bucket + ".cos." + global.GVA_CONFIG.TencentCOS.Region + ".myqcloud.com")
baseURL := &cos.BaseURL{BucketURL: urlStr}
client := cos.NewClient(baseURL, &http.Client{
Transport: &cos.AuthorizationTransport{
SecretID: global.GVA_CONFIG.TencentCOS.SecretID,
SecretKey: global.GVA_CONFIG.TencentCOS.SecretKey,
},
})
return client
}

46
utils/upload/upload.go Normal file
View File

@@ -0,0 +1,46 @@
package upload
import (
"mime/multipart"
"git.echol.cn/loser/lckt/global"
)
// OSS 对象存储接口
// Author [SliverHorn](https://github.com/SliverHorn)
// Author [ccfish86](https://github.com/ccfish86)
type OSS interface {
UploadFile(file *multipart.FileHeader) (string, string, error)
DeleteFile(key string) error
}
// NewOss OSS的实例化方法
// Author [SliverHorn](https://github.com/SliverHorn)
// Author [ccfish86](https://github.com/ccfish86)
func NewOss() OSS {
switch global.GVA_CONFIG.System.OssType {
case "local":
return &Local{}
case "qiniu":
return &Qiniu{}
case "tencent-cos":
return &TencentCOS{}
case "aliyun-oss":
return &AliyunOSS{}
case "huawei-obs":
return HuaWeiObs
case "aws-s3":
return &AwsS3{}
case "cloudflare-r2":
return &CloudflareR2{}
case "minio":
minioClient, err := GetMinio(global.GVA_CONFIG.Minio.Endpoint, global.GVA_CONFIG.Minio.AccessKeyId, global.GVA_CONFIG.Minio.AccessKeySecret, global.GVA_CONFIG.Minio.BucketName, global.GVA_CONFIG.Minio.UseSSL)
if err != nil {
global.GVA_LOG.Warn("你配置了使用minio但是初始化失败请检查minio可用性或安全配置: " + err.Error())
panic("minio初始化失败") // 建议这样做用户自己配置了minio如果报错了还要把服务开起来使用起来也很危险
}
return minioClient
default:
return &Local{}
}
}