go-web(gin框架)中实现本地文件上传

gin-web本地文件上传

在web开发中我们一般会进行一些让用户进行文件上传的操作,本章节主要结合gin框架进行搭建一个文件上传的操作,以多文件上传为主,因为多文件也可以上传单文件,一些特殊的场景可能使用的是单文件上传,但是也可以根据判断上传文件的len()进行取舍是否同意通过改请求。下列的写法是参照go-vue-admin开源项目(gva)的写法进行创建的

yaml配置文件

upload:
    size: 2 # 设置限制上传的大小
    path: uploads/file # 上传的路径

定义结构体struct{}

通过读取yaml文件的配置信息进行定义结构体,我们在config包下创建一个conf_upload.go 来装我们的结构体

package config

type Upload struct {
	Size int    `json:"size" yaml:"size"` // 图片上传的大小
	Path string `json:"path" yaml:"path"` // 图片上传的目录
}

虽然我们在config包下进行创建一个入口文件enter.go,将我们的结构体帮定进去

type Config struct {
	Upload   Upload   `yaml:"upload"`
}

然后在根目录创建一个global文件夹,并且创建global.go 文件,将其注册为全局。这样的好处是我们在拓展多个业务的时候方便我们进行快速的拓展,比如我们的全局DB也可以放置在这里,初始化的时候就可以附值。该方法做了:文件限制的大小,是否重复上传,是否有存储路径等判断!

var (
	Config *config.Config
	// DB     *gorm.DB 
)

创建接口

根目录下创建api包并且创建一个images_api/settings_upload.go

package images_api

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"gvb-server/global"
	"gvb-server/models/response"
	"io/fs"
	"os"
	"path"
)

type FileUploadResponse struct {
	IsSuccess bool   `json:"is_success"` // 是否上传成功
	FileName  string `json:"file_name"`  // 文件名
	Msg       string `json:"msg"`        // 消息
}

// ImagesUploadApi 上传单个图片,返回的是图片的url地址
func (ImagesApi) ImagesUploadApi(c *gin.Context) {
	// 上传多个文件
	form, err := c.MultipartForm()
	if err != nil {
		response.FailWithMessage(response.ErrorUploadImage, c)
		return
	}
	// 前端的字段定义是images
	fileList, ok := form.File["images"]
	if !ok {
		response.FailWithMessage(response.ErrorNotMessage, c)
		return
	}

	// 判断路径是否存在
	basePath := global.Config.Upload.Path
	_, err = os.ReadDir(basePath)
	if err != nil {
		// 递归创建
		err = os.MkdirAll(basePath, fs.ModePerm)
		if err != nil {
			global.Log.Error(err)
		}
	}
	// 不存在就创建
	var resultList []FileUploadResponse

	for _, file := range fileList {
		filePath := path.Join(basePath, file.Filename)
		// 判断大小
		size := float64(file.Size) / float64(1024*1024)
		if size >= float64(global.Config.Upload.Size) {
			resultList = append(resultList, FileUploadResponse{
				IsSuccess: false,
				FileName:  file.Filename,
				Msg:       fmt.Sprintf("图片大小超过设定大小为:%dMB,当前图片大小为%.2fMB", global.Config.Upload.Size, size),
			})
			continue
		}

		err = c.SaveUploadedFile(file, filePath)
		if err != nil {
			resultList = append(resultList, FileUploadResponse{
				IsSuccess: false,
				FileName:  file.Filename,
				Msg:       err.Error(),
			})
		}

		resultList = append(resultList, FileUploadResponse{
			IsSuccess: true,
			FileName:  filePath,
			Msg:       "上传成功",
		})
	}
	// 自己封装的输出方法
	response.SuccessDate(resultList, c)
}

注册路由

在根目录创建一个router文件,先创建一个入口文件enter.go文件,然后创建一个images_router.go

// enter.go 
package router

type RouterGroup struct {
	*gin.RouterGroup
}

func InitRouter() *gin.Engine {
	gin.SetMode(global.Config.System.Env)
	router := gin.Default()

	apiRouterGroup := router.Group("api")
	routerGroupApp := RouterGroup{apiRouterGroup}
	routerGroupApp.ImagesRouter()
	return router
}
// images_router.go 
package router

func (router RouterGroup) ImagesRouter() {
	app := api.ApiGroupApp.ImagesApi
	router.POST("images", app.ImagesUploadApi)
}

测试接口

使用apifox进行测试接口,然后查看本地上传的结果
go-web(gin框架)中实现本地文件上传_第1张图片
查看目录文件出现我们上传的图片了!
在这里插入图片描述

你可能感兴趣的:(前端,golang,gin)