10篇带你手摸手封装gin框架(10)- Minio资源文件管理与上传头像接口开发

前言

大家好,我是作曲家种太阳
上一章节我们介绍了常用中间件的开发,相信你对中间件又有新的了解
资源文件的上传和下载的管理,在服务端是必须的功能,我们这一节开发一个上传用户头像的接口开发,来讲文件管理基本功能~

1. minio的介绍

对象存储系统,类似于阿里oss
特点:
1.高性能
2.可扩展性
3.云的原生支持
4.开放全部源代码 + 企业级支持
5.与Amazon S3 兼容
6. 非常简单易用
minio官网
image.png

关系图:

image.png

1. 前期准备工作

之前的文章我们讲述很多次怎么配置路由yaml配置文件的设置与读取,这篇不在手摸手教这些,更关本篇功能实现上,所以你要准备前期工作:

  1. 编写上传文件的路由,并写controller的函数
  2. 配置yaml中minio的struct字段(config/config.go),参考
minio:
endpoint: "127.0.0.1:9000"
accessKeyID: "minioadmin"
secretAccessKey: "minioadmin"
复制代码

3.安装minio
官网安装文档,推荐docker安装:docs.minio.org.cn/docs/

4.尝试登陆minio的界面:
http://127.0.0.1:9000/

image.png

2. 编写minio初始化链接

(1).在 initialize/minio中

package initialize

import (
	"github.com/minio/minio-go"
	_ "github.com/minio/minio-go/pkg/encrypt"
	"go_gin/global"
	"go_gin/utils"
	"log"
)

func InitMinIO() {
	minioInfo := global.Settings.MinioInfo
	// 初使化 minio client对象。false是关闭https证书校验
	minioClient, err := minio.New(minioInfo.Endpoint, minioInfo.AccessKeyID, minioInfo.SecretAccessKey, false )
	if err != nil {
		log.Fatalln(err)
	}
	//客户端注册到全局变量中
	global.MinioClient = minioClient
	//创建一个叫userheader的存储桶。
	utils.CreateMinoBuket("userheader")
}

复制代码

ps: utils.CreateMinoBuket()还未编写,先注释掉,后面写好再打开 \

(2). 添加global.MinioClient \

在global.globalVar中

MinioClient *minio.Client
复制代码

(3). 在main.go中调用

	// 7. 初始化minIO
	initialize.InitMinIO()
复制代码

3. 编写minio的操作函数

在utils/minio.go中编写

package utils
import (
	"fmt"
	"github.com/minio/minio-go"
	"github.com/minio/minio-go/v6/pkg/policy"
	"go.uber.org/zap"
	"go_gin/global"
	"io"
	"net/url"
	"time"
)
// CreateMinoBuket 创建minio 桶
func CreateMinoBuket(bucketName string) {
	location := "us-east-1"
	err := global.MinioClient.MakeBucket(bucketName, location)
	if err != nil {
		// 检查存储桶是否已经存在。
		exists, err := global.MinioClient.BucketExists(bucketName)
		fmt.Println(exists)
		if err == nil && exists {
			fmt.Printf("We already own %s\n", bucketName)
		} else {
			fmt.Println(err, exists)
			return
		}
	}
	//
	err = global.MinioClient.SetBucketPolicy(bucketName, policy.BucketPolicyReadWrite)

	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Printf("Successfully created %s\n", bucketName)
}
// UploadFile 上传文件给minio指定的桶中
func UploadFile(bucketName, objectName string, reader io.Reader, objectSize int64) (ok bool) {
	n, err := global.MinioClient.PutObject(bucketName, objectName, reader, objectSize, minio.PutObjectOptions{ContentType: "application/octet-stream"})
	if err != nil {
		fmt.Println(err)
		return false
	}
	fmt.Println("Successfully uploaded bytes: ", n)
	return true
}
//  GetFileUrl 获取文件url
func GetFileUrl(bucketName string, fileName string, expires time.Duration) string {
	//time.Second*24*60*60
	reqParams := make(url.Values)
	presignedURL, err := global.MinioClient.PresignedGetObject(bucketName, fileName, expires, reqParams)
	if err != nil {
		zap.L().Error(err.Error())
		return ""
	}
	return fmt.Sprintf("%s", presignedURL)
}
复制代码

ps: 这里写了三个函数:
1.CreateMinoBuket 在minio创建桶
2. UploadFile 上传文件
3. GetFileUrl 获取到下载文件的url

4.编写上传头像的接口

在 controller/user.go中

// PutHeaderImage 上传用户头像
func PutHeaderImage(c *gin.Context) {
	file, _ := c.FormFile("file")
	fileObj, err := file.Open()
	if err != nil {
		fmt.Println(err)
		return
	}
	// 把文件上传到minio对应的桶中
	ok := utils.UploadFile("userheader", file.Filename, fileObj, file.Size)
	if !ok {
		Response.Err(c, 401, 401, "头像上传失败", "")
		return
	}
	headerUrl := utils.GetFileUrl("userheader", file.Filename, time.Second*24*60*60)
	if headerUrl == "" {
		Response.Success(c, 400, "获取用户头像失败", "headerMap")
		return
	}
	//TODO 把用户的头像地址存入到对应user表中head_url 中
	Response.Success(c, 200, "头像上传成功", map[string]interface{}{
		"userheaderUrl": headerUrl,
	})
}
复制代码

可以完善的地方:

  1. 当获取到头像的url,应该把地址存入mysql当中
  2. 文件名加上uuid防止覆盖(看具有需求)

ps:别忘记给container加入路由!

最后-验证结果环节

(1).在postman请求上传文件路由:
image.png
使用userheaderUrl的值在浏览器上请求,文件成功下载
(2).在minio中查看:
http://127.0.0.1:9000/
image.png
minio成功添加了上传文件

如果这系列的文章对你有有用,请点赞和留言吧~

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享