Config:
server/config/oss.go
package config
type Local struct {
Path string `mapstructure:"path" json:"path" yaml:"path" `
}
type Qiniu struct {
Zone string `mapstructure:"zone" json:"zone" yaml:"zone"`
Bucket string `mapstructure:"bucket" json:"bucket" yaml:"bucket"`
ImgPath string `mapstructure:"img-path" json:"imgPath" yaml:"img-path"`
UseHTTPS bool `mapstructure:"use-https" json:"useHttps" yaml:"use-https"`
AccessKey string `mapstructure:"access-key" json:"accessKey" yaml:"access-key"`
SecretKey string `mapstructure:"secret-key" json:"secretKey" yaml:"secret-key"`
UseCdnDomains bool `mapstructure:"use-cdn-domains" json:"useCdnDomains" yaml:"use-cdn-domains"`
}
type Minio struct {
Id string `mapstructure:"id" json:"id" yaml:"id"`
Path string `mapstructure:"path" json:"path" yaml:"path"`
Token string `mapstructure:"token" json:"token" yaml:"token"`
Bucket string `mapstructure:"bucket" json:"bucket" yaml:"bucket"`
UseSsl bool `mapstructure:"use-ssl" json:"useSsl" yaml:"use-ssl"`
Secret string `mapstructure:"secret" json:"secret" yaml:"secret"`
Endpoint string `mapstructure:"endpoint" json:"endpoint" yaml:"endpoint"`
}
type Aliyun struct {
Path string `mapstructure:"path" json:"path" yaml:"path"`
Bucket string `mapstructure:"bucket" json:"bucket" yaml:"bucket"`
ACLType string `mapstructure:"acl-type" json:"aclType" yaml:"acl-type"`
Endpoint string `mapstructure:"endpoint" json:"endpoint" yaml:"endpoint"`
AccessKeyID string `mapstructure:"access-key-id" json:"accessKeyId" yaml:"access-key-id"`
SecretAccessKey string `mapstructure:"secret-access-key" json:"secretAccessKey" yaml:"secret-access-key"`
StorageClassType string `mapstructure:"storage-class-type" json:"storageClassType" yaml:"storage-class-type"`
}
server/config/config.go
type Server struct {
JWT JWT `mapstructure:"jwt" json:"jwt" yaml:"jwt"`
Zap Zap `mapstructure:"zap" json:"zap" yaml:"zap"`
Redis Redis `mapstructure:"redis" json:"redis" yaml:"redis"`
System System `mapstructure:"system" json:"system" yaml:"system"`
Captcha Captcha `mapstructure:"captcha" json:"captcha" yaml:"captcha"`
AutoCode Autocode `mapstructure:"autoCode" json:"autoCode" yaml:"autoCode"`
Mysql Mysql `mapstructure:"mysql" json:"mysql" yaml:"mysql"`
Local Local `mapstructure:"local" json:"local" yaml:"local"`
AwsS3 AwsS3 `mapstructure:"aws-s3" json:"awsS3" yaml:"aws-s3"`
Cors CORS `mapstructure:"cors" json:"cors" yaml:"cors"`
}
server/config.yaml
# local configuration
local:
path: 'uploads/file'
# qiniu configuration (请自行七牛申请对应的 公钥 私钥 bucket 和 域名地址)
qiniu:
zone: 'ZoneHuadong'
bucket: 'qm-plus-img'
img-path: 'http://qmplusimg.henrongyi.top'
use-https: false
access-key: '25j8dYBZ2wuiy0yhwShytjZDTX662b8xiFguwxzZ'
secret-key: 'pgdbqEsf7ooZh7W3xokP833h3dZ_VecFXPDeG5JY'
use-cdn-domains: false
# minio configuration
minio:
id: 'minio'
path: 'http://localhost:9000'
token: ''
bucket: 'public'
use-ssl: false
secret: 'minio1234'
endpoint: 'localhost:9000'
# aliyun configuration
aliyun:
path : 'https://xxx.oss-cn-beijing.aliyuncs.com'
bucket : 'xxx'
acl-type : ''
endpoint : 'https://oss-cn-beijing.aliyuncs.com'
access-key-id : 'xxxxxxx'
secret-access-key : 'xxxxxxx'
storage-class-type : 'Standard' # 存储桶存储类型
Model:
server/model/example/exa_file_upload_and_download.go
package example
import (
"Project/global"
)
type ExaFileUploadAndDownload struct {
global.KBB_MODEL
Name string `json:"name" gorm:"comment:文件名"`
Url string `json:"url" gorm:"comment:文件地址"`
Tag string `json:"tag" gorm:"comment:文件标签"`
Key string `json:"key" gorm:"comment:编号"`
}
func (E ExaFileUploadAndDownload) TableName() string {
return "exa_file_upload_and_download"
}
Utils:
server/utils/upload.go
package upload
import (
"mime/multipart"
"Project/global"
)
type OSS interface {
UploadFile(file *multipart.FileHeader) (string, string, error)
DeleteFile(key string) error
}
func NewOss() OSS {
switch global.KBB_CONFIG.System.OssType {
case "local":
return &Local{}
case "aws-s3":
return &AwsS3{}
default:
return &Local{}
}
}
server/utils/local.go
package upload
import (
"errors"
"io"
"mime/multipart"
"os"
"path"
"strings"
"time"
"Project/global"
"Project/utils"
"go.uber.org/zap"
)
type Local struct{}
func (*Local) UploadFile(file *multipart.FileHeader) (string, string, error) {
ext := path.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.KBB_CONFIG.Local.Path, os.ModePerm)
if mkdirErr != nil {
global.KBB_LOG.Error("function os.MkdirAll() Filed", zap.Any("err", mkdirErr.Error()))
return "", "", errors.New("function os.MkdirAll() Filed, err:" + mkdirErr.Error())
}
p := global.KBB_CONFIG.Local.Path + "/" + filename
f, openError := file.Open()
if openError != nil {
global.KBB_LOG.Error("function file.Open() Filed", zap.Any("err", openError.Error()))
return "", "", errors.New("function file.Open() Filed, err:" + openError.Error())
}
defer f.Close()
out, createErr := os.Create(p)
if createErr != nil {
global.KBB_LOG.Error("function os.Create() Filed", zap.Any("err", createErr.Error()))
return "", "", errors.New("function os.Create() Filed, err:" + createErr.Error())
}
defer out.Close()
_, copyErr := io.Copy(out, f)
if copyErr != nil {
global.KBB_LOG.Error("function io.Copy() Filed", zap.Any("err", copyErr.Error()))
return "", "", errors.New("function io.Copy() Filed, err:" + copyErr.Error())
}
return p, filename, nil
}
func (*Local) DeleteFile(key string) error {
p := global.KBB_CONFIG.Local.Path + "/" + key
if strings.Contains(p, global.KBB_CONFIG.Local.Path) {
if err := os.Remove(p); err != nil {
return errors.New("本地文件删除失败, err:" + err.Error())
}
}
return nil
}
Service:
server/service/example/exa_file_upload_download.go
func (e *FileUploadAndDownloadService) Upload(file example.ExaFileUploadAndDownload) error {
return global.KBB_DB.Create(&file).Error
}
func (e *FileUploadAndDownloadService) UploadFile(header *multipart.FileHeader, noSave string) (err error, file example.ExaFileUploadAndDownload) {
oss := upload.NewOss()
filePath, key, uploadErr := oss.UploadFile(header)
if uploadErr != nil {
panic(err)
}
if noSave == "0" {
s := strings.Split(header.Filename, ".")
f := example.ExaFileUploadAndDownload{
Url: filePath,
Name: header.Filename,
Tag: s[len(s)-1],
Key: key,
}
return e.Upload(f), f
}
return
}
Controller:
server/api/exa_file_upload_download.go
func (u *FileUploadAndDownloadApi) UploadFile(c *gin.Context) {
var file example.ExaFileUploadAndDownload
noSave := c.DefaultQuery("noSave", "0")
_, header, err := c.Request.FormFile("file")
if err != nil {
global.KBB_LOG.Error("接收文件失败!", zap.Error(err))
utils.FailWithMessage("接收文件失败", c)
return
}
err, file = fileUploadAndDownloadService.UploadFile(header, noSave)
if err != nil {
global.KBB_LOG.Error("修改数据库链接失败!", zap.Error(err))
utils.FailWithMessage("修改数据库链接失败", c)
return
}
utils.OkWithDetailed(exampleRes.ExaFileResponse{File: file}, "上传成功", c)
}
接口测试:
由于资金有限,甲方没有提供OSS服务器,所以此接口,只用于上传到local。 gin-vue-admin官方提供了qiniu、minio、aliyun等utils工具。
【面向校招】全力备战2023Golang实习与校招
欢迎群共同进步: QQ群:1007576722
|