Golang gin 配置腾讯云cos实现单文件与多文件上传

首先下载腾讯云cos sdk:

go get -u github.com/tencentyun/cos-go-sdk-v5

所需要的包:

import (
	"context"
	"project/app/global/my_errors"  // 错误处理 可自行配置
	"project/app/global/variable"  // 公共变量 可自行配置
	"project/app/utils/md5_encrypt"  // md5加密 可自行配置
	"errors"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/tencentyun/cos-go-sdk-v5"
	"mime/multipart"
	"net/http"
	"net/url"
	"path"
	"time"
)

配置使用cos保存文件:


// 保存文件
func saveUploadedFile(file *multipart.FileHeader, newSavePath string) (r bool, saveFilePath string) {
	//COS客户端连接
	cosUrl, _ := url.Parse(variable.ConfigYml.GetString("TencentCos.CosUrl"))
	secretId := variable.ConfigYml.GetString("TencentCos.SecretID")
	secretKey := variable.ConfigYml.GetString("TencentCos.SecretKey")
	b := &cos.BaseURL{BucketURL: cosUrl}
	client := cos.NewClient(b, &http.Client{
		Transport: &cos.AuthorizationTransport{
			SecretID:  secretId,
			SecretKey: secretKey,
		},
	})

	//  保存文件,原始文件名进行全局唯一编码加密、md5 加密,保证在后台存储不重复
	var saveErr error
	if sequence := variable.SnowFlake.GetId(); sequence > 0 {
		saveFileName := fmt.Sprintf("%d%s", sequence, file.Filename)
		saveFileName = md5_encrypt.MD5(saveFileName) + path.Ext(saveFileName)
		saveFilePath := newSavePath + saveFileName
		// 3.通过文件流上传对象
		fd, err := file.Open()
		if err != nil {
			return false, ""
		}
		defer fd.Close()

		_, saveErr = client.Object.Put(context.Background(), saveFilePath, fd, nil)

		if saveErr == nil {
			//  上传成功,返回资源的相对路径,这里请根据实际返回绝对路径或者相对路径
			return true, saveFilePath
		}
	} else {
		saveErr = errors.New(my_errors.ErrorsSnowflakeGetIdFail)
		variable.ZapLog.Error("文件保存出错:" + saveErr.Error())
	}
	return false, ""
}

文件上传可以设置按照 [savePathPre]/xxx年/xx月/xxx.jpg 格式存储为对象键(Key):

func generateYearMonthPath(savePathPre string) string {
	curYearMonth := time.Now().Format("2006/01")
	newSavePathPre := savePathPre + curYearMonth
	return newSavePathPre + "/"
}

开始上传:

//上传多文件
ctx.MultipartForm
//上传单文件
ctx.FormFile(“file”) //file 是文件名

单文件上传:

// 单文件上传
func Upload(ctx *gin.Context, savePath string) (r bool, finnalSavePath interface{}) {
	// 对象键(Key)是对象在存储桶中的唯一标识。
	newSavePath := generateYearMonthPath(savePath)

	//  1.获取上传的文件名(参数验证器已经验证完成了第一步错误,这里简化)
	file, _ := ctx.FormFile(variable.ConfigYml.GetString("FileUploadSetting.UploadFileField")) //  file 是一个文件结构体(文件对象)

	if r, saveFilePath := saveUploadedFile(file, newSavePath); r == true {

		// 上传成功,返回资源的相对路径,这里请根据实际返回绝对路径或者相对路径
		finnalSavePath = gin.H{
			"path": saveFilePath,
		}
		return true, finnalSavePath
	}

	return false, nil
}

多文件上传:


// 多文件上传
func MultUpload(ctx *gin.Context, savePath string) (r bool, multFinnalSavePath interface{}) {

	// 对象键(Key)是对象在存储桶中的唯一标识。
	newSavePath := generateYearMonthPath(savePath)
	//获取到所有的文件
	form, _ := ctx.MultipartForm()
	//获取到所有的文件数组
	files := form.File[variable.ConfigYml.GetString("FileUploadSetting.UploadFileField")]
	var saveFilePaths []string
	//遍历数组进行处理
	for _, file := range files {
		//进行文件保存
		if r, saveFilePath := saveUploadedFile(file, newSavePath); r == true {
			saveFilePaths = append(saveFilePaths, saveFilePath)
		}
	}
	// 上传成功,返回资源的相对路径,这里请根据实际返回绝对路径或者相对路径
	multFinnalSavePath = gin.H{
		"paths": saveFilePaths,
	}
	return true, multFinnalSavePath

}

创建一个Upload控制器:


// 开始上传动态Picture 目录+年份+月份
func (u *CosUpload) StartUploadPic(context *gin.Context) {
	savePath := variable.ConfigYml.GetString("FileUploadSetting.CosPictureSavePath")
	if r, finnalSavePath := upload_cos.MultUpload(context, savePath); r == true {
		response.Success(context, consts.CurdStatusOkMsg, finnalSavePath)
	} else {
		response.Fail(context, consts.FilesUploadFailCode, consts.FilesUploadFailMsg, "")
	}
}

接口示例:
在这里插入图片描述
service/upload_cos/upload_cos.go 完整代码:

package upload_cos

import (
	"context"
	"project/app/global/my_errors"
	"project/app/global/variable"
	"project/app/utils/md5_encrypt"
	"errors"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/tencentyun/cos-go-sdk-v5"
	"mime/multipart"
	"net/http"
	"net/url"
	"path"
	"time"
)

// 单文件上传
func Upload(ctx *gin.Context, savePath string) (r bool, finnalSavePath interface{}) {
	// 对象键(Key)是对象在存储桶中的唯一标识。
	newSavePath := generateYearMonthPath(savePath)

	//  1.获取上传的文件名(参数验证器已经验证完成了第一步错误,这里简化)
	file, _ := ctx.FormFile(variable.ConfigYml.GetString("FileUploadSetting.UploadFileField")) //  file 是一个文件结构体(文件对象)

	if r, saveFilePath := saveUploadedFile(file, newSavePath); r == true {

		// 上传成功,返回资源的相对路径,这里请根据实际返回绝对路径或者相对路径
		finnalSavePath = gin.H{
			"path": saveFilePath,
		}
		return true, finnalSavePath
	}

	return false, nil
}

// 多文件上传
func MultUpload(ctx *gin.Context, savePath string) (r bool, multFinnalSavePath interface{}) {

	// 对象键(Key)是对象在存储桶中的唯一标识。
	newSavePath := generateYearMonthPath(savePath)
	//获取到所有的文件
	form, _ := ctx.MultipartForm()
	//获取到所有的文件数组
	files := form.File[variable.ConfigYml.GetString("FileUploadSetting.UploadFileField")]
	var saveFilePaths []string
	//遍历数组进行处理
	for _, file := range files {
		//进行文件保存
		if r, saveFilePath := saveUploadedFile(file, newSavePath); r == true {
			saveFilePaths = append(saveFilePaths, saveFilePath)
		}
	}
	// 上传成功,返回资源的相对路径,这里请根据实际返回绝对路径或者相对路径
	multFinnalSavePath = gin.H{
		"paths": saveFilePaths,
	}
	return true, multFinnalSavePath

}

// 保存文件
func saveUploadedFile(file *multipart.FileHeader, newSavePath string) (r bool, saveFilePath string) {
	//COS客户端连接
	cosUrl, _ := url.Parse(variable.ConfigYml.GetString("TencentCos.CosUrl"))
	secretId := variable.ConfigYml.GetString("TencentCos.SecretID")
	secretKey := variable.ConfigYml.GetString("TencentCos.SecretKey")
	b := &cos.BaseURL{BucketURL: cosUrl}
	client := cos.NewClient(b, &http.Client{
		Transport: &cos.AuthorizationTransport{
			SecretID:  secretId,
			SecretKey: secretKey,
		},
	})

	//  保存文件,原始文件名进行全局唯一编码加密、md5 加密,保证在后台存储不重复
	var saveErr error
	if sequence := variable.SnowFlake.GetId(); sequence > 0 {
		saveFileName := fmt.Sprintf("%d%s", sequence, file.Filename)
		saveFileName = md5_encrypt.MD5(saveFileName) + path.Ext(saveFileName)
		saveFilePath := newSavePath + saveFileName
		// 3.通过文件流上传对象
		fd, err := file.Open()
		if err != nil {
			return false, ""
		}
		defer fd.Close()

		_, saveErr = client.Object.Put(context.Background(), saveFilePath, fd, nil)

		if saveErr == nil {
			//  上传成功,返回资源的相对路径,这里请根据实际返回绝对路径或者相对路径
			return true, saveFilePath
		}
	} else {
		saveErr = errors.New(my_errors.ErrorsSnowflakeGetIdFail)
		variable.ZapLog.Error("文件保存出错:" + saveErr.Error())
	}
	return false, ""
}

// 文件上传可以设置按照 xxx年/xx月 格式存储 对象键(Key)
func generateYearMonthPath(savePathPre string) string {
	curYearMonth := time.Now().Format("2006/01")
	newSavePathPre := savePathPre + curYearMonth
	return newSavePathPre + "/"
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值