IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> 基于Go语言实现OSS文件上传(local) -> 正文阅读

[网络协议]基于Go语言实现OSS文件上传(local)

作者:token comment

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"`
	//Email   Email   `mapstructure:"email" json:"email" yaml:"email"`
	//Casbin  Casbin  `mapstructure:"casbin" json:"casbin" yaml:"casbin"`
	System  System  `mapstructure:"system" json:"system" yaml:"system"`
	Captcha Captcha `mapstructure:"captcha" json:"captcha" yaml:"captcha"`
	// auto
	AutoCode Autocode `mapstructure:"autoCode" json:"autoCode" yaml:"autoCode"`
	// gorm
	Mysql Mysql `mapstructure:"mysql" json:"mysql" yaml:"mysql"`
	//Pgsql  Pgsql `mapstructure:"pgsql" json:"pgsql" yaml:"pgsql"`
	//DBList []DB  `mapstructure:"db-list" json:"db-list" yaml:"db-list"`
	// oss
	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"`
	//HuaWeiObs HuaWeiObs `mapstructure:"hua-wei-obs" json:"huaWeiObs" yaml:"hua-wei-obs"`
	//TencentCOS TencentCOS `mapstructure:"tencent-cos" json:"tencentCOS" yaml:"tencent-cos"`
	AwsS3 AwsS3 `mapstructure:"aws-s3" json:"awsS3" yaml:"aws-s3"`
	//
	//Excel Excel `mapstructure:"excel" json:"excel" yaml:"excel"`
	//Timer Timer `mapstructure:"timer" json:"timer" yaml:"timer"`
	//
	// 跨域配置
	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"
)

// OSS 对象存储接口
// Author [SliverHorn](https://github.com/SliverHorn)
// Author [ccfish86](https://github.com/ccfish86)
type OSS interface {
	UploadFile(file *multipart.FileHeader) (string, string, error)
	DeleteFile(key string) error
}

// NewOss OSS的实例化方法
// Author [SliverHorn](https://github.com/SliverHorn)
// Author [ccfish86](https://github.com/ccfish86)
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{}

//@author: [piexlmax](https://github.com/piexlmax)
//@author: [ccfish86](https://github.com/ccfish86)
//@author: [SliverHorn](https://github.com/SliverHorn)
//@object: *Local
//@function: UploadFile
//@description: 上传文件
//@param: file *multipart.FileHeader
//@return: string, string, error

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() // 创建文件 defer 关闭

	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() // 创建文件 defer 关闭

	_, 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
}

//@author: [piexlmax](https://github.com/piexlmax)
//@author: [ccfish86](https://github.com/ccfish86)
//@author: [SliverHorn](https://github.com/SliverHorn)
//@object: *Local
//@function: DeleteFile
//@description: 删除文件
//@param: key string
//@return: error

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

//@author: [piexlmax](https://github.com/piexlmax)
//@function: Upload
//@description: 创建文件上传记录
//@param: file model.ExaFileUploadAndDownload
//@return: error

func (e *FileUploadAndDownloadService) Upload(file example.ExaFileUploadAndDownload) error {
	return global.KBB_DB.Create(&file).Error
}

//@author: [piexlmax](https://github.com/piexlmax)
//@function: UploadFile
//@description: 根据配置文件判断是文件上传到本地或者七牛云
//@param: header *multipart.FileHeader, noSave string
//@return: err error, file model.ExaFileUploadAndDownload

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

// UploadFile @Tags ExaFileUploadAndDownload
// @Summary 上传文件示例
// @Security ApiKeyAuth
// @accept multipart/form-data
// @Produce  application/json
// @Param file formData file true "上传文件示例"
// @Success 200 {object} response.Response{data=exampleRes.ExaFileResponse,msg=string} "上传文件示例,返回包括文件详情"
// @Router /fileUploadAndDownload/upload [post]
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

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-05-05 11:56:47  更:2022-05-05 12:01:35 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 1:31:50-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码