diff --git a/server/api/file.go b/server/api/file.go index b99fa23..4624924 100644 --- a/server/api/file.go +++ b/server/api/file.go @@ -43,6 +43,7 @@ func initUpload(c fiber.Ctx) error { FileSize int64 `json:"file_size"` ResourceID uint `json:"resource_id"` StorageID uint `json:"storage_id"` + Tag string `json:"tag"` } var req InitUploadRequest @@ -50,7 +51,10 @@ func initUpload(c fiber.Ctx) error { return model.NewRequestError("Invalid request parameters") } - result, err := service.CreateUploadingFile(uid, req.Filename, req.Description, req.FileSize, req.ResourceID, req.StorageID) + req.Filename = strings.TrimSpace(req.Filename) + req.Tag = strings.TrimSpace(req.Tag) + + result, err := service.CreateUploadingFile(uid, req.Filename, req.Description, req.FileSize, req.ResourceID, req.StorageID, req.Tag) if err != nil { return err } @@ -136,6 +140,9 @@ func createRedirectFile(c fiber.Ctx) error { Description string `json:"description"` ResourceID uint `json:"resource_id"` RedirectURL string `json:"redirect_url"` + FileSize int64 `json:"file_size"` + Md5 string `json:"md5"` + Tag string `json:"tag"` } var req CreateRedirectFileRequest @@ -143,7 +150,11 @@ func createRedirectFile(c fiber.Ctx) error { return model.NewRequestError("Invalid request parameters") } - result, err := service.CreateRedirectFile(uid, req.Filename, req.Description, req.ResourceID, req.RedirectURL) + req.Filename = strings.TrimSpace(req.Filename) + req.Md5 = strings.TrimSpace(req.Md5) + req.Tag = strings.TrimSpace(req.Tag) + + result, err := service.CreateRedirectFile(uid, req.Filename, req.Description, req.ResourceID, req.RedirectURL, req.FileSize, req.Md5, req.Tag) if err != nil { return err } @@ -172,6 +183,7 @@ func updateFile(c fiber.Ctx) error { type UpdateFileRequest struct { Filename string `json:"filename"` Description string `json:"description"` + Tag string `json:"tag"` } var req UpdateFileRequest @@ -179,7 +191,10 @@ func updateFile(c fiber.Ctx) error { return model.NewRequestError("Invalid request parameters") } - result, err := service.UpdateFile(uid, c.Params("id"), req.Filename, req.Description) + req.Filename = strings.TrimSpace(req.Filename) + req.Tag = strings.TrimSpace(req.Tag) + + result, err := service.UpdateFile(uid, c.Params("id"), req.Filename, req.Description, req.Tag) if err != nil { return err } @@ -259,13 +274,18 @@ func createServerDownloadTask(c fiber.Ctx) error { Description string `json:"description"` ResourceID uint `json:"resource_id"` StorageID uint `json:"storage_id"` + Tag string `json:"tag"` } var req InitUploadRequest if err := c.Bind().Body(&req); err != nil { return model.NewRequestError("Invalid request parameters") } - result, err := service.CreateServerDownloadTask(uid, req.Url, req.Filename, req.Description, req.ResourceID, req.StorageID) + + req.Filename = strings.TrimSpace(req.Filename) + req.Tag = strings.TrimSpace(req.Tag) + + result, err := service.CreateServerDownloadTask(uid, req.Url, req.Filename, req.Description, req.ResourceID, req.StorageID, req.Tag) if err != nil { return err } diff --git a/server/dao/file.go b/server/dao/file.go index c3f62ec..d8a188c 100644 --- a/server/dao/file.go +++ b/server/dao/file.go @@ -10,7 +10,7 @@ import ( "gorm.io/gorm/clause" ) -func CreateUploadingFile(filename string, description string, fileSize int64, blockSize int64, tempPath string, resourceID, storageID, userID uint) (*model.UploadingFile, error) { +func CreateUploadingFile(filename string, description string, fileSize int64, blockSize int64, tempPath string, resourceID, storageID, userID uint, tag string) (*model.UploadingFile, error) { blocksCount := (fileSize + blockSize - 1) / blockSize uf := &model.UploadingFile{ Filename: filename, @@ -22,6 +22,7 @@ func CreateUploadingFile(filename string, description string, fileSize int64, bl TargetResourceID: resourceID, TargetStorageID: storageID, UserID: userID, + Tag: tag, } if err := db.Create(uf).Error; err != nil { return nil, err @@ -73,7 +74,7 @@ func GetUploadingFilesOlderThan(time time.Time) ([]model.UploadingFile, error) { return files, nil } -func CreateFile(filename string, description string, resourceID uint, storageID *uint, storageKey string, redirectUrl string, size int64, userID uint, hash string) (*model.File, error) { +func CreateFile(filename string, description string, resourceID uint, storageID *uint, storageKey string, redirectUrl string, size int64, userID uint, hash string, tag string) (*model.File, error) { if storageID == nil && redirectUrl == "" { return nil, errors.New("storageID and redirectUrl cannot be both empty") } @@ -89,6 +90,7 @@ func CreateFile(filename string, description string, resourceID uint, storageID Size: size, UserID: userID, Hash: hash, + Tag: tag, } err := db.Transaction(func(tx *gorm.DB) error { @@ -171,7 +173,7 @@ func DeleteFile(id string) error { return nil } -func UpdateFile(id string, filename string, description string) (*model.File, error) { +func UpdateFile(id string, filename string, description string, tag string) (*model.File, error) { f := &model.File{} if err := db.Where("uuid = ?", id).First(f).Error; err != nil { return nil, err @@ -182,6 +184,9 @@ func UpdateFile(id string, filename string, description string) (*model.File, er if description != "" { f.Description = description } + if tag != "" { + f.Tag = tag + } if err := db.Save(f).Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return nil, model.NewNotFoundError("file not found") diff --git a/server/model/file.go b/server/model/file.go index a20f4f5..e22870f 100644 --- a/server/model/file.go +++ b/server/model/file.go @@ -19,6 +19,7 @@ type File struct { User User `gorm:"foreignKey:UserID"` Size int64 Hash string `gorm:"default:null"` + Tag string `gorm:"type:text;default:null"` } type FileView struct { @@ -32,6 +33,7 @@ type FileView struct { Hash string `json:"hash,omitempty"` StorageName string `json:"storage_name,omitempty"` CreatedAt int64 `json:"created_at,omitempty"` + Tag string `json:"tag,omitempty"` } func (f *File) ToView() *FileView { @@ -45,6 +47,7 @@ func (f *File) ToView() *FileView { Hash: f.Hash, StorageName: f.Storage.Name, CreatedAt: f.CreatedAt.Unix(), + Tag: f.Tag, } } @@ -64,5 +67,6 @@ func (f *File) ToViewWithResource() *FileView { User: f.User.ToView(), Resource: resource, Hash: f.Hash, + Tag: f.Tag, } } diff --git a/server/model/uploading_file.go b/server/model/uploading_file.go index b68db7b..23cd6b4 100644 --- a/server/model/uploading_file.go +++ b/server/model/uploading_file.go @@ -21,6 +21,7 @@ type UploadingFile struct { TempPath string Resource Resource `gorm:"foreignKey:TargetResourceID"` Storage Storage `gorm:"foreignKey:TargetStorageID"` + Tag string `gorm:"type:text;default:null"` } func (uf *UploadingFile) BlocksCount() int { diff --git a/server/service/file.go b/server/service/file.go index bbf36ff..5c9171a 100644 --- a/server/service/file.go +++ b/server/service/file.go @@ -80,7 +80,7 @@ func init() { }() } -func CreateUploadingFile(uid uint, filename string, description string, fileSize int64, resourceID, storageID uint) (*model.UploadingFileView, error) { +func CreateUploadingFile(uid uint, filename string, description string, fileSize int64, resourceID, storageID uint, tag string) (*model.UploadingFileView, error) { if filename == "" { return nil, model.NewRequestError("filename is empty") } @@ -113,7 +113,7 @@ func CreateUploadingFile(uid uint, filename string, description string, fileSize log.Error("failed to create temp dir: ", err) return nil, model.NewInternalServerError("failed to create temp dir") } - uploadingFile, err := dao.CreateUploadingFile(filename, description, fileSize, blockSize, tempPath, resourceID, storageID, uid) + uploadingFile, err := dao.CreateUploadingFile(filename, description, fileSize, blockSize, tempPath, resourceID, storageID, uid, tag) if err != nil { log.Error("failed to create uploading file: ", err) _ = os.Remove(tempPath) @@ -245,7 +245,7 @@ func FinishUploadingFile(uid uint, fid uint, md5Str string) (*model.FileView, er return nil, model.NewInternalServerError("failed to finish uploading file. please re-upload") } - dbFile, err := dao.CreateFile(uploadingFile.Filename, uploadingFile.Description, uploadingFile.TargetResourceID, &uploadingFile.TargetStorageID, storageKeyUnavailable, "", uploadingFile.TotalSize, uid, sumStr) + dbFile, err := dao.CreateFile(uploadingFile.Filename, uploadingFile.Description, uploadingFile.TargetResourceID, &uploadingFile.TargetStorageID, storageKeyUnavailable, "", uploadingFile.TotalSize, uid, sumStr, uploadingFile.Tag) if err != nil { log.Error("failed to create file in db: ", err) _ = os.Remove(resultFilePath) @@ -309,7 +309,7 @@ func CancelUploadingFile(uid uint, fid uint) error { return nil } -func CreateRedirectFile(uid uint, filename string, description string, resourceID uint, redirectUrl string) (*model.FileView, error) { +func CreateRedirectFile(uid uint, filename string, description string, resourceID uint, redirectUrl string, fileSize int64, md5 string, tag string) (*model.FileView, error) { u, err := url.Parse(redirectUrl) if err != nil { return nil, model.NewRequestError("URL is not valid") @@ -329,7 +329,7 @@ func CreateRedirectFile(uid uint, filename string, description string, resourceI return nil, model.NewUnAuthorizedError("user cannot upload file") } - file, err := dao.CreateFile(filename, description, resourceID, nil, "", redirectUrl, 0, uid, "") + file, err := dao.CreateFile(filename, description, resourceID, nil, "", redirectUrl, fileSize, uid, md5, tag) if err != nil { log.Error("failed to create file in db: ", err) return nil, model.NewInternalServerError("failed to create file in db") @@ -373,7 +373,7 @@ func DeleteFile(uid uint, fid string) error { return nil } -func UpdateFile(uid uint, fid string, filename string, description string) (*model.FileView, error) { +func UpdateFile(uid uint, fid string, filename string, description string, tag string) (*model.FileView, error) { file, err := dao.GetFile(fid) if err != nil { log.Error("failed to get file: ", err) @@ -390,7 +390,7 @@ func UpdateFile(uid uint, fid string, filename string, description string) (*mod return nil, model.NewUnAuthorizedError("user cannot update file") } - file, err = dao.UpdateFile(fid, filename, description) + file, err = dao.UpdateFile(fid, filename, description, tag) if err != nil { log.Error("failed to update file in db: ", err) return nil, model.NewInternalServerError("failed to update file in db") @@ -575,7 +575,7 @@ func downloadFile(ctx context.Context, url string, path string) (string, error) } } -func CreateServerDownloadTask(uid uint, url, filename, description string, resourceID, storageID uint) (*model.FileView, error) { +func CreateServerDownloadTask(uid uint, url, filename, description string, resourceID, storageID uint, tag string) (*model.FileView, error) { canUpload, err := checkUserCanUpload(uid) if err != nil { log.Error("failed to check user permission: ", err) @@ -596,7 +596,7 @@ func CreateServerDownloadTask(uid uint, url, filename, description string, resou return nil, model.NewRequestError("server is busy, please try again later") } - file, err := dao.CreateFile(filename, description, resourceID, &storageID, storageKeyUnavailable, "", 0, uid, "") + file, err := dao.CreateFile(filename, description, resourceID, &storageID, storageKeyUnavailable, "", 0, uid, "", tag) if err != nil { log.Error("failed to create file in db: ", err) return nil, model.NewInternalServerError("failed to create file in db")