router层
package router
import (
"homepage/controller"
"homepage/middleware"
"github.com/gin-gonic/gin"
)
func InitRouter(r *gin.Engine) {
file := r.Group("api/file")
{
fileAndAudioController := controller.FileAudio{}
file.POST("/upload", fileAndAudioController.HandleUpload)
}
}
用于给前端提供相应的接口
controller层
package controller
import (
"homepage/service"
"net/http"
"github.com/gin-gonic/gin"
)
type FileAudio struct{}
func (f FileAudio) HandleUpload(c *gin.Context) {
fileAudioService := service.FileAudioService{}
resp, err := fileAudioService.HandleFileUpload(c)
if err != nil {
c.Error(&gin.Error{
Err: err,
Type: service.SysErr,
})
return
}
c.JSON(http.StatusOK, gin.H{
"success": true,
"data": resp,
})
}
这段代码是一个处理音频或者文件上传的函数 HandleUpload,它使用了 gin 框架。以下是对代码的详细解释:
func (f FileAudio) HandleUpload(c *gin.Context):这是一个方法,其接收者是类型FileAudio。这意味着HandleUpload是FileAudio的一个方法。fileAudioService := service.FileAudioService{}:这里创建了一个service.FileAudioService的实例fileAudioService。这个实例用于处理音频文件的上传操作。resp, err := fileAudioService.HandleFileUpload(c):调用fileAudioService的HandleFileUpload方法来处理上传的文件。c是gin.Context对象,用于接收上传的文件。if err != nil { ... }:如果在文件上传处理过程中出现错误,会进入这个条件分支。c.Error(&gin.Error{ ... }):使用gin.Context的Error方法将错误信息包装成gin.Error对象,并返回给客户端。c.JSON(http.StatusOK, gin.H{ ... }):在没有错误的情况下,使用c.JSON方法返回一个 JSON 响应给客户端。http.StatusOK表示 HTTP 状态码 200(请求成功),gin.H{ ... }是一个gin.H类型的 Map,用于构建响应的键值对。
总结:这个函数的作用是在接收到客户端上传的音频文件后,调用 fileAudioService 对象处理上传的文件,并根据处理结果返回相应的 JSON 响应给客户端。如果在文件上传处理过程中出现错误,将返回错误信息给客户端。
service层
package service
import (
"fmt"
"homepage/model"
"mime/multipart"
"os"
"path/filepath"
"strings"
"time"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
)
type FileAudioService struct {
// 定义你的 FileAudioService 结构体
}
func (f FileAudioService) HandleFileUpload(c *gin.Context) (*model.FileUpload, error) {
var request struct {
File *multipart.FileHeader `form:"file" binding:"required"`
Title string `form:"title"`
Content string `form:"content"`
Type int `form:"type" binding:"required"`
}
if err := c.ShouldBind(&request); err != nil {
return nil, err
}
// 生成保存文件的路径和文件名
uuidFilename := generateUUIDFilename(request.File.Filename)
var destinationPath string
var destinationPathForOthers string = "./file/others"
var destinationPathForAudio string = "./file/audio"
if err := createFolderIfNotExists(destinationPathForOthers); err != nil {
return nil, err
}
if err := createFolderIfNotExists(destinationPathForAudio); err != nil {
return nil, err
}
if request.Type == 1 {
// 音频文件
destinationPath = filepath.Join(destinationPathForAudio, uuidFilename)
fmt.Println(destinationPath)
} else {
destinationPath = filepath.Join(destinationPathForOthers, uuidFilename)
fmt.Println(destinationPath)
}
// 保存上传文件到本地
if err := c.SaveUploadedFile(request.File, destinationPath); err != nil {
return nil, err
}
fmt.Println("File saved to:", destinationPath)
// 提取文件后缀作为 type 字段的一部分
fileExtension := getFileExtension(request.File.Filename)
// 构建保存到数据库的数据
now := time.Now()
fileUpload := model.FileUpload{
Title: request.Title,
Content: request.Content,
Url: destinationPath,
Type: fileExtension,
Sort: 0,
Status: 1,
CreateAt: int(now.Unix()),
}
// TODO: 在此处执行数据库保存操作
// yourDB.Save(&fileUpload)
if err := model.DB.Create(&fileUpload).Error; err != nil {
return nil, err
}
return &fileUpload, nil
}
func generateUUIDFilename(originalFilename string) string {
extension := getFileExtension(originalFilename)
uuidString := uuid.New().String()
return uuidString + "." + extension
}
func getFileExtension(filename string) string {
return strings.TrimPrefix(filepath.Ext(filename), ".")
}
func createFolderIfNotExists(folderPath string) error {
// 检查文件夹是否存在
if _, err := os.Stat(folderPath); os.IsNotExist(err) {
// 文件夹不存在,创建文件夹
err := os.MkdirAll(folderPath, 0755)
if err != nil {
return fmt.Errorf("无法创建文件夹: %v", err)
}
}
return nil
}
这段代码是对文件上传功能的具体逻辑实现
这段代码定义了一个 FileAudioService 结构体和其关联的方法 HandleFileUpload 以及一些辅助函数。
type FileAudioService struct { ... }:定义了一个FileAudioService结构体,该结构体可以用于封装与音频文件相关的操作和功能。func (f FileAudioService) HandleFileUpload(c *gin.Context) (*model.FileUpload, error) { ... }:这是一个方法,接收者是FileAudioService结构体。该方法用于处理文件上传请求。具体流程如下:- 创建了一个空结构体
request来接收包含form表单字段的请求数据。 - 使用
c.ShouldBind(&request)方法将请求数据绑定到request结构体中。 - 根据请求的
Type字段判断文件类型,生成保存文件的路径和文件名。 - 调用
createFolderIfNotExists函数来检查并创建文件夹。 - 使用
c.SaveUploadedFile方法保存上传的文件到本地指定的路径。 - 根据文件名获取文件扩展名,并构建保存到数据库中的文件信息。
- 在数据库中保存文件信息。
- 返回保存成功的文件信息。
- 创建了一个空结构体
func generateUUIDFilename(originalFilename string) string { ... }:这个函数用于生成一个以 UUID 为文件名的唯一文件名,文件名包含原始文件名的扩展名。func getFileExtension(filename string) string { ... }:此函数用于从文件名中提取文件的扩展名。func createFolderIfNotExists(folderPath string) error { ... }:该函数用于检查文件夹是否存在,如果不存在则创建文件夹。
总结:这段代码定义了一个 FileAudioService 结构体及其关联方法,用于处理音频文件上传请求。它将上传的文件保存到本地指定的路径并将文件信息保存到数据库。另外,它还包含了一些辅助函数,用于生成文件名和获取文件扩展名,以及检查并创建文件夹