mirror of
https://github.com/keven1024/015.git
synced 2026-05-26 07:08:02 +00:00
refactor(backend): enhance file upload logic by merging file slices and improving Redis file info handling
This commit is contained in:
@@ -3,6 +3,7 @@ module backend
|
||||
go 1.23.1
|
||||
|
||||
require (
|
||||
dario.cat/mergo v1.0.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
github.com/gofrs/uuid v4.0.0+incompatible // indirect
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s=
|
||||
dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
|
||||
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
|
||||
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
@@ -69,3 +71,4 @@ golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
||||
@@ -4,9 +4,11 @@ import (
|
||||
"backend/internal/models"
|
||||
"backend/internal/services"
|
||||
"backend/internal/utils"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"mime/multipart"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
@@ -22,7 +24,6 @@ func CreateUploadTask(c echo.Context) error {
|
||||
if r.FileSize == 0 || r.MimeType == "" || r.FileHash == "" {
|
||||
return utils.HTTPErrorHandler(c, errors.New("上传文件信息不完整"))
|
||||
}
|
||||
rdb, ctx := utils.GetRedisClient()
|
||||
fileId := utils.GetFileId(r.FileHash, r.FileSize)
|
||||
fileInfo, _ := models.GetRedisFileInfo(fileId)
|
||||
|
||||
@@ -47,8 +48,10 @@ func CreateUploadTask(c echo.Context) error {
|
||||
CreatedAt: time.Now().Unix(),
|
||||
Expire: 3600,
|
||||
}
|
||||
jsonData, _ := json.Marshal(newFileInfo)
|
||||
rdb.HSet(ctx, "015:fileInfoMap", fileId, string(jsonData)).Result()
|
||||
err := models.SetRedisFileInfo(fileId, newFileInfo)
|
||||
if err != nil {
|
||||
return utils.HTTPErrorHandler(c, err)
|
||||
}
|
||||
|
||||
return utils.HTTPSuccessHandler(c, map[string]any{
|
||||
"size": newFileInfo.FileSize,
|
||||
@@ -119,8 +122,14 @@ func FinishUploadTask(c echo.Context) error {
|
||||
if fileInfo.FileType != models.FileTypeInit {
|
||||
return utils.HTTPErrorHandler(c, errors.New("上传任务状态错误"))
|
||||
}
|
||||
|
||||
// 合并文件切片
|
||||
if err := services.MergeFileSlices(r.FileId); err != nil {
|
||||
uploadPath, _ := services.GetUploadDirPath()
|
||||
slicesPath := filepath.Join(uploadPath, fmt.Sprintf("%s_%s", r.FileId, "tmp"))
|
||||
|
||||
// 最终合并后的文件路径
|
||||
mergeFilePath := filepath.Join(uploadPath, r.FileId)
|
||||
if err := services.MergeFileSlices(slicesPath, mergeFilePath); err != nil {
|
||||
return utils.HTTPErrorHandler(c, err)
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ import (
|
||||
"backend/internal/utils"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"dario.cat/mergo"
|
||||
)
|
||||
|
||||
type FileInfo struct {
|
||||
@@ -46,3 +48,15 @@ func GetRedisFileInfo(fileId string) (RedisFileInfo, error) {
|
||||
}
|
||||
return RedisFileInfo{}, errors.New("db不存在该文件信息")
|
||||
}
|
||||
|
||||
func SetRedisFileInfo(fileId string, fileInfo RedisFileInfo) error {
|
||||
rdb, ctx := utils.GetRedisClient()
|
||||
old_fileInfo, err := GetRedisFileInfo(fileId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
mergo.Merge(&fileInfo, old_fileInfo)
|
||||
jsonData, _ := json.Marshal(fileInfo)
|
||||
_, err = rdb.HSet(ctx, "015:fileInfoMap", fileId, string(jsonData)).Result()
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ func CreateFileSlice(fileSlice io.Reader, fileId string, fileIndex int64) error
|
||||
return err
|
||||
}
|
||||
|
||||
filePath := filepath.Join(uploadPath, fmt.Sprintf("%s_%s", fileId, "_tmp"))
|
||||
filePath := filepath.Join(uploadPath, fmt.Sprintf("%s_%s", fileId, "tmp"))
|
||||
if err := os.MkdirAll(filePath, 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -45,28 +45,16 @@ func CreateFileSlice(fileSlice io.Reader, fileId string, fileIndex int64) error
|
||||
}
|
||||
|
||||
// MergeFileSlices 合并文件切片
|
||||
func MergeFileSlices(fileId string) error {
|
||||
// 获取上传目录路径
|
||||
uploadPath, err := GetUploadDirPath()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 切片所在目录
|
||||
slicePath := filepath.Join(uploadPath, fileId)
|
||||
|
||||
// 最终合并后的文件路径
|
||||
finalPath := filepath.Join(uploadPath, fileId+".tmp")
|
||||
|
||||
func MergeFileSlices(slicesPath string, mergeFilePath string) error {
|
||||
// 创建最终文件
|
||||
destFile, err := os.Create(finalPath)
|
||||
destFile, err := os.Create(mergeFilePath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("创建合并文件失败: %v", err)
|
||||
}
|
||||
defer destFile.Close()
|
||||
|
||||
// 读取目录下的所有文件
|
||||
files, err := os.ReadDir(slicePath)
|
||||
files, err := os.ReadDir(slicesPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("读取切片目录失败: %v", err)
|
||||
}
|
||||
@@ -78,7 +66,7 @@ func MergeFileSlices(fileId string) error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("无效的切片文件名: %v", err)
|
||||
}
|
||||
sliceFiles[index-1] = filepath.Join(slicePath, file.Name())
|
||||
sliceFiles[index-1] = filepath.Join(slicesPath, file.Name())
|
||||
}
|
||||
|
||||
// 合并文件
|
||||
@@ -107,13 +95,6 @@ func MergeFileSlices(fileId string) error {
|
||||
|
||||
sf.Close()
|
||||
}
|
||||
|
||||
// 清理切片文件夹
|
||||
defer os.RemoveAll(slicePath)
|
||||
|
||||
// 重命名临时文件
|
||||
finalFilePath := filepath.Join(uploadPath, fileId)
|
||||
defer os.Rename(finalPath, finalFilePath)
|
||||
|
||||
defer os.RemoveAll(slicesPath)
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user