又是很久没写博客了。写点基础的记录一下。
功能
- 上传文件
- 修改文件名称
- 保存到数据库
- 返回一个可访问的静态文件地址
环境
基础环境不太相同的,此博文仅供参考
- gin : 1.7.1
- golang : 1.16
- gorm : 1.21.9
路由
// routes.go
import (
"github.com/gin-gonic/gin"
"net/http"
"项目/controller"
"项目/middleware"
"项目/routes"
)
func collectRoutes(r *gin.Engine) *gin.Engine {
// ------- 1. 使用中间件 这一步可以没有
// r.Use(middleware.CORSMiddleware(),middleware.RecoveryMiddleware())
// ------- 1. over
// routes 是路由嵌套,不懂得可以百度一下
routes.FileRoute(r)
r.StaticFS("/static", http.Dir("./files"))
return r
}
// routes/fileRoute.go
import (
"github.com/gin-gonic/gin"
"项目/controller"
)
func FileRoute(r *gin.Engine) *gin.Engine{
kgFile := r.Group("/file")
//kgFile.Use(middleware.AuthMiddleware())
fileController := controller.NewFileController()
kgFile.POST("",fileController.Upload)
return r
}
controller
import (
"fmt"
"github.com/gin-gonic/gin"
"github.com/spf13/viper"
"gorm.io/gorm"
"math/rand"
"net"
"os"
"path"
"pdmc/common"
"pdmc/model"
"pdmc/response"
"regexp"
"strconv"
"strings"
"time"
)
/*
下面是用MVC思想写的...,其实可以不用
IFileController
FileController
只需要在Upload方法去掉(f FileController)就行,但是后面需要自己想办法获取DB
*/
type IFileController interface {
RestController
Upload(ctx *gin.Context)
Relate(ctx *gin.Context)
}
type FileController struct {
*gorm.DB
}
// 上传文件
func (f FileController) Upload(ctx *gin.Context) {
// 1. 获取文件
// 2. 重命名文件
// 3. 上传/保存到服务器
// 4. 将文件路径保存到数据库
// 5. 返回完整文件路径
// 获取文件
file, err := ctx.FormFile("file")
if err != nil {
panic(err.Error())
return
}
// 重新命名文件
newFileName := strconv.FormatInt(time.Now().Unix(),10) + strconv.Itoa(rand.Intn(999999-100000)+10000) + path.Ext(file.Filename)
// 保存到服务器
uperr := ctx.SaveUploadedFile(file, "./files/"+newFileName)
if uperr != nil {
fmt.Println(uperr)
response.Fail(ctx,nil,"文件上传失败!")
return
}
// 将文件路径保存到数据库
fileInfo := &model.File{
Name: file.Filename,
Address: "/files/"+newFileName,
}
res := f.DB.Create(&fileInfo)
if res.Error != nil {
response.Fail(ctx,nil,"上传文件成功!数据库写入失败!")
return
}
// 获取本机ip地址
ipAddrList,_ := net.InterfaceAddrs()
ipAddr := fetchIPAddr(ipAddrList)
// 本机port
port := viper.GetString("server.port")
// 文件id
fileId := fileInfo.ID
fileAddress := ipAddr+":"+port+"/static/"+newFileName
response.Success(ctx, gin.H{
"file_addr":fileAddress,"id":fileId}, "上传成功!")
}
算了,信不过你们自己改
不存数据库的Controller版本
import (
...
)
// 上传文件
func Upload(ctx *gin.Context) {
// 1. 获取文件
// 2. 重命名文件
// 3. 上传/保存到服务器
// 4. 返回完整文件路径
// 获取文件
file, err := ctx.FormFile("file")
if err != nil {
panic(err.Error())
return
}
// 重新命名文件
newFileName := strconv.FormatInt(time.Now().Unix(),10) + strconv.Itoa(rand.Intn(999999-100000)+10000) + path.Ext(file.Filename)
// 保存到服务器
uperr := ctx.SaveUploadedFile(file, "./files/"+newFileName)
if uperr != nil {
fmt.Println(uperr)
response.Fail(ctx,nil,"文件上传失败!")
return
}
// 获取本机ip地址
ipAddrList,_ := net.InterfaceAddrs()
ipAddr := fetchIPAddr(ipAddrList)
// 本机port 这里的port是写在config文件里面的,这里可以直接替换为port
// port := viper.GetString("server.port")
port := 1438
// 文件id
fileId := fileInfo.ID
fileAddress := ipAddr+":"+port+"/static/"+newFileName
response.Success(ctx, gin.H{
"file_addr":fileAddress,"id":fileId}, "上传成功!")
}
测试结果
ok,继续撸代码。
转载:https://blog.csdn.net/liu_jiachen/article/details/117258137
查看评论