package config import ( "encoding/json" "fmt" "mime/multipart" "time" "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/s3manager" "github.com/pkg/errors" ) // File 文件存储配置 type File struct { OssType string `mapstructure:"oss-type" json:"oss-type" yaml:"oss-type"` Path string `mapstructure:"path" json:"path" yaml:"path"` ProxyPath string `mapstructure:"proxy-path" json:"proxy-path" yaml:"proxy-path"` StorePath string `mapstructure:"store-path" json:"store-path" yaml:"store-path"` OriginConf map[string]interface{} `mapstructure:"origin-conf" json:"origin-conf" yaml:"origin-conf"` } // AwsS3 AWS S3配置(兼容MinIO) type AwsS3 struct { Bucket string `mapstructure:"bucket" json:"bucket" yaml:"bucket"` Region string `mapstructure:"region" json:"region" yaml:"region"` Endpoint string `mapstructure:"endpoint" json:"endpoint" yaml:"endpoint"` SecretID string `mapstructure:"secret-id" json:"secret-id" yaml:"secret-id"` SecretKey string `mapstructure:"secret-key" json:"secret-key" yaml:"secret-key"` BaseURL string `mapstructure:"base-url" json:"base-url" yaml:"base-url"` PathPrefix string `mapstructure:"path-prefix" json:"path-prefix" yaml:"path-prefix"` S3ForcePathStyle bool `mapstructure:"s3-force-path-style" json:"s3-force-path-style" yaml:"s3-force-path-style"` DisableSSL bool `mapstructure:"disable-ssl" json:"disable-ssl" yaml:"disable-ssl"` } // newSession 创建S3 session func (a *AwsS3) newSession() *session.Session { sess, _ := session.NewSession(&aws.Config{ Region: aws.String(a.Region), Endpoint: aws.String(a.Endpoint), S3ForcePathStyle: aws.Bool(a.S3ForcePathStyle), DisableSSL: aws.Bool(a.DisableSSL), Credentials: credentials.NewStaticCredentials( a.SecretID, a.SecretKey, "", ), }) return sess } // UploadFile 上传文件 func (a *AwsS3) UploadFile(file *multipart.FileHeader) (string, string, error) { _session := a.newSession() uploader := s3manager.NewUploader(_session) // 生成文件名 fileKey := fmt.Sprintf("%d%s", time.Now().Unix(), file.Filename) filename := a.PathPrefix + "/" + fileKey f, openError := file.Open() if openError != nil { return "", "", errors.New("function file.Open() failed, err:" + openError.Error()) } defer f.Close() _, err := uploader.Upload(&s3manager.UploadInput{ Bucket: aws.String(a.Bucket), Key: aws.String(filename), Body: f, }) if err != nil { return "", "", err } return a.BaseURL + "/" + filename, fileKey, nil } // UploadFileToStorage 上传文件到存储 func UploadFileToStorage(file *multipart.FileHeader) (string, error) { conf := EnvConf().File if conf == nil { return "", fmt.Errorf("file config not found") } if conf.OssType != "aws" { return "", fmt.Errorf("only aws/minio storage type is supported") } // 解析 OriginConf 到 AwsS3 结构 engine := new(AwsS3) byteData, err := json.Marshal(conf.OriginConf) if err != nil { return "", err } err = json.Unmarshal(byteData, engine) if err != nil { return "", err } viewPath, _, err := engine.UploadFile(file) if err != nil { return "", err } return viewPath, nil }