From f2c115b09c8580c31ec52223889d96bfe26d3546 Mon Sep 17 00:00:00 2001 From: keven1024 <99848979+keven1024@users.noreply.github.com> Date: Wed, 30 Apr 2025 15:08:26 +0800 Subject: [PATCH] refactor(backend): update file info handling to use pointers and enhance upload task validation with expiration checks --- backend/internal/controllers/file.go | 46 ++++++++++++++++++++++++---- backend/internal/models/file.go | 28 +++++++++-------- 2 files changed, 56 insertions(+), 18 deletions(-) diff --git a/backend/internal/controllers/file.go b/backend/internal/controllers/file.go index d3276ec..fa9e9f9 100644 --- a/backend/internal/controllers/file.go +++ b/backend/internal/controllers/file.go @@ -27,7 +27,7 @@ func CreateUploadTask(c echo.Context) error { fileId := utils.GetFileId(r.FileHash, r.FileSize) fileInfo, _ := models.GetRedisFileInfo(fileId) - if fileInfo != (models.RedisFileInfo{}) { + if fileInfo != nil { return utils.HTTPSuccessHandler(c, map[string]any{ "size": fileInfo.FileSize, "mime_type": fileInfo.MimeType, @@ -78,12 +78,20 @@ func UploadFileSlice(c echo.Context) error { if r.FileId == "" || r.FileIndex == 0 || r.FileSlice == nil { return utils.HTTPErrorHandler(c, errors.New("上传文件信息不完整")) } - _, err := models.GetRedisFileInfo(r.FileId) - + fileInfo, err := models.GetRedisFileInfo(r.FileId) if err != nil { return utils.HTTPErrorHandler(c, err) } + now := time.Now().Unix() + if fileInfo.CreatedAt+fileInfo.Expire < now { + return utils.HTTPErrorHandler(c, errors.New("上传任务已过期")) + } + + if fileInfo.FileType != models.FileTypeInit { + return utils.HTTPErrorHandler(c, errors.New("上传任务状态错误")) + } + // 打开文件 file, err := r.FileSlice.Open() if err != nil { @@ -123,6 +131,11 @@ func FinishUploadTask(c echo.Context) error { return utils.HTTPErrorHandler(c, errors.New("上传任务状态错误")) } + now := time.Now().Unix() + if fileInfo.CreatedAt+fileInfo.Expire < now { + return utils.HTTPErrorHandler(c, errors.New("上传任务已过期")) + } + // 合并文件切片 uploadPath, _ := services.GetUploadDirPath() slicesPath := filepath.Join(uploadPath, fmt.Sprintf("%s_%s", r.FileId, "tmp")) @@ -133,12 +146,33 @@ func FinishUploadTask(c echo.Context) error { return utils.HTTPErrorHandler(c, err) } - // 更新文件状态 - // fileInfo.FileType = models.FileTypeComplete - if err := services.MergeFileSlices(r.FileId); err != nil { + // 计算文件MD5 + file, err := os.Open(mergeFilePath) + if err != nil { + file.Close() + os.Remove(mergeFilePath) return utils.HTTPErrorHandler(c, err) } + file_hash, err := utils.GetFileMd5(file) + + if err != nil { + file.Close() + os.Remove(mergeFilePath) + return utils.HTTPErrorHandler(c, err) + } + + if file_hash != fileInfo.FileHash { + file.Close() + os.Remove(mergeFilePath) + return utils.HTTPErrorHandler(c, errors.New("文件MD5不一致")) + } + defer file.Close() + // 更新文件信息 + models.SetRedisFileInfo(r.FileId, models.RedisFileInfo{ + FileType: models.FileTypeUpload, + }) + return utils.HTTPSuccessHandler(c, map[string]any{ "message": "文件上传完成并合并成功", }) diff --git a/backend/internal/models/file.go b/backend/internal/models/file.go index aae3b67..67b1e44 100644 --- a/backend/internal/models/file.go +++ b/backend/internal/models/file.go @@ -3,9 +3,9 @@ package models import ( "backend/internal/utils" "encoding/json" - "errors" "dario.cat/mergo" + "github.com/redis/go-redis/v9" ) type FileInfo struct { @@ -35,18 +35,20 @@ type RedisShareInfo struct { CreatedAt int64 `json:"created_at"` } -func GetRedisFileInfo(fileId string) (RedisFileInfo, error) { +func GetRedisFileInfo(fileId string) (*RedisFileInfo, error) { rdb, ctx := utils.GetRedisClient() - fileInfoUnmarshalData, _ := rdb.HGet(ctx, "015:fileInfoMap", fileId).Result() - - if fileInfoUnmarshalData != "" { - var fileInfoData RedisFileInfo - if err := json.Unmarshal([]byte(fileInfoUnmarshalData), &fileInfoData); err != nil { - return RedisFileInfo{}, err - } - return fileInfoData, nil + fileInfoUnmarshalData, err := rdb.HGet(ctx, "015:fileInfoMap", fileId).Result() + if err == redis.Nil { + return nil, nil } - return RedisFileInfo{}, errors.New("db不存在该文件信息") + if err != nil { + return nil, err + } + var fileInfoData RedisFileInfo + if err := json.Unmarshal([]byte(fileInfoUnmarshalData), &fileInfoData); err != nil { + return nil, err + } + return &fileInfoData, nil } func SetRedisFileInfo(fileId string, fileInfo RedisFileInfo) error { @@ -55,7 +57,9 @@ func SetRedisFileInfo(fileId string, fileInfo RedisFileInfo) error { if err != nil { return err } - mergo.Merge(&fileInfo, old_fileInfo) + if old_fileInfo != nil { + mergo.Merge(&fileInfo, old_fileInfo) + } jsonData, _ := json.Marshal(fileInfo) _, err = rdb.HSet(ctx, "015:fileInfoMap", fileId, string(jsonData)).Result() return err