package upload import ( "context" "errors" "fmt" "mime/multipart" "strings" "time" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/credentials" "github.com/aws/aws-sdk-go-v2/feature/s3/manager" "github.com/aws/aws-sdk-go-v2/service/s3" "github.com/flipped-aurora/gin-vue-admin/server/global" "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-v2. See https://docs.aws.amazon.com/sdk-for-go/v2/developer-guide/s3-example-basic-bucket-operations.html //@param: file *multipart.FileHeader //@return: string, string, error func (*AwsS3) UploadFile(file *multipart.FileHeader) (string, string, error) { client := newS3Client() uploader := manager.NewUploader(client) 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(context.TODO(), &s3.PutObjectInput{ Bucket: aws.String(global.GVA_CONFIG.AwsS3.Bucket), Key: aws.String(filename), Body: f, ContentType: aws.String(file.Header.Get("Content-Type")), }) 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-v2. See https://docs.aws.amazon.com/sdk-for-go/v2/developer-guide/s3-example-basic-bucket-operations.html //@param: key string //@return: error func (*AwsS3) DeleteFile(key string) error { client := newS3Client() filename := global.GVA_CONFIG.AwsS3.PathPrefix + "/" + key bucket := global.GVA_CONFIG.AwsS3.Bucket _, err := client.DeleteObject(context.TODO(), &s3.DeleteObjectInput{ Bucket: aws.String(bucket), Key: aws.String(filename), }) if err != nil { global.GVA_LOG.Error("function client.DeleteObject() failed", zap.Any("err", err.Error())) return errors.New("function client.DeleteObject() failed, err:" + err.Error()) } waiter := s3.NewObjectNotExistsWaiter(client) _ = waiter.Wait(context.TODO(), &s3.HeadObjectInput{ Bucket: aws.String(bucket), Key: aws.String(filename), }, 30*time.Second) return nil } // newS3Client creates an S3 v2 client with static credentials and optional custom endpoint. // minio在这里设置Endpoint地址,可以兼容 func newS3Client() *s3.Client { cfg := global.GVA_CONFIG.AwsS3 awsCfg, _ := config.LoadDefaultConfig(context.TODO(), config.WithRegion(cfg.Region), config.WithCredentialsProvider(credentials.NewStaticCredentialsProvider( cfg.SecretID, cfg.SecretKey, "", )), ) return s3.NewFromConfig(awsCfg, func(o *s3.Options) { if cfg.Endpoint != "" { endpoint := cfg.Endpoint if !strings.HasPrefix(endpoint, "http://") && !strings.HasPrefix(endpoint, "https://") { if cfg.DisableSSL { endpoint = "http://" + endpoint } else { endpoint = "https://" + endpoint } } o.BaseEndpoint = aws.String(endpoint) } o.UsePathStyle = cfg.S3ForcePathStyle }) }