diff --git a/server/config.yaml b/server/config.yaml index ebb438b8..36582e34 100644 --- a/server/config.yaml +++ b/server/config.yaml @@ -78,6 +78,14 @@ qiniu: secret-key: 'pgdbqEsf7ooZh7W3xokP833h3dZ_VecFXPDeG5JY' use-cdn-domains: false +# aliyun oss configuration +aliyun-oss: + endpoint: 'yourEndpoint' + access-key-id: 'yourAccessKeyId' + access-key-secret: 'yourAccessKeySecret' + bucket-name: 'yourBucketName' + bucket-url: 'yourBucketUrl' + # excel configuration excel: dir: './resource/excel/' \ No newline at end of file diff --git a/server/config/config.go b/server/config/config.go index 7ead08b0..9f9168f4 100644 --- a/server/config/config.go +++ b/server/config/config.go @@ -9,9 +9,10 @@ type Server struct { System System `mapstructure:"system" json:"system" yaml:"system"` Captcha Captcha `mapstructure:"captcha" json:"captcha" yaml:"captcha"` // gorm - Mysql Mysql `mapstructure:"mysql" json:"mysql" yaml:"mysql"` + Mysql Mysql `mapstructure:"mysql" json:"mysql" yaml:"mysql"` // oss - Local Local `mapstructure:"local" json:"local" yaml:"local"` - Qiniu Qiniu `mapstructure:"qiniu" json:"qiniu" yaml:"qiniu"` - Excel Excel `mapstructure:"excel" json:"excel" yaml:"excel"` + Local Local `mapstructure:"local" json:"local" yaml:"local"` + Qiniu Qiniu `mapstructure:"qiniu" json:"qiniu" yaml:"qiniu"` + AliyunOSS AliyunOSS `mapstructure:"aliyun-oss" json:"aliyunOSS" yaml:"aliyun-oss"` + Excel Excel `mapstructure:"excel" json:"excel" yaml:"excel"` } diff --git a/server/config/oss.go b/server/config/oss.go index 2c1d7cda..74326b07 100644 --- a/server/config/oss.go +++ b/server/config/oss.go @@ -13,3 +13,11 @@ type Qiniu struct { SecretKey string `mapstructure:"secret-key" json:"secretKey" yaml:"secret-key"` UseCdnDomains bool `mapstructure:"use-cdn-domains" json:"useCdnDomains" yaml:"use-cdn-domains"` } + +type AliyunOSS struct { + Endpoint string `mapstructure:"endpoint" json:"endpoint" yaml:"endpoint"` + AccessKeyId string `mapstructure:"access-key-id" json:"accessKeyId" yaml:"access-key-id"` + AccessKeySecret string `mapstructure:"access-key-secret" json:"accessKeySecret" yaml:"access-key-secret"` + BucketName string `mapstructure:"bucket-name" json:"bucketName" yaml:"bucket-name"` + BucketUrl string `mapstructure:"bucket-url" json:"bucketUrl" yaml:"bucket-url"` +} diff --git a/server/go.mod b/server/go.mod index c1b0bf9b..bf9bab48 100644 --- a/server/go.mod +++ b/server/go.mod @@ -6,6 +6,8 @@ require ( github.com/360EntSecGroup-Skylar/excelize/v2 v2.3.2 github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 + github.com/aliyun/aliyun-oss-go-sdk v2.1.6+incompatible + github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f // indirect github.com/casbin/casbin v1.9.1 github.com/casbin/casbin/v2 v2.11.0 github.com/casbin/gorm-adapter/v3 v3.0.2 diff --git a/server/utils/upload/aliyun_oss.go b/server/utils/upload/aliyun_oss.go new file mode 100644 index 00000000..8187e606 --- /dev/null +++ b/server/utils/upload/aliyun_oss.go @@ -0,0 +1,74 @@ +package upload + +import ( + "errors" + "gin-vue-admin/global" + "github.com/aliyun/aliyun-oss-go-sdk/oss" + "go.uber.org/zap" + "mime/multipart" + "path/filepath" + "time" +) + +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()) + } + + //上传阿里云路径 文件名格式 自己可以改 建议保证唯一性 + yunFileTmpPath := filepath.Join("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() Filed", zap.Any("err", err.Error())) + return errors.New("function bucketManager.Delete() Filed, 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 +}