diff --git a/frontend/src/network/network.ts b/frontend/src/network/network.ts index 9c249af..355f694 100644 --- a/frontend/src/network/network.ts +++ b/frontend/src/network/network.ts @@ -456,6 +456,19 @@ class Network { } } + async cancelFileUpload(fileId: number): Promise> { + try { + const response = await axios.post(`${this.apiBaseUrl}/files/upload/cancel/${fileId}`); + return response.data; + } catch (e: any) { + console.error(e); + return { + success: false, + message: e.toString(), + }; + } + } + async createRedirectFile(filename: string, description: string, resourceId: number, redirectUrl: string): Promise> { try { diff --git a/server/api/file.go b/server/api/file.go index 4d59faf..7f93a3e 100644 --- a/server/api/file.go +++ b/server/api/file.go @@ -14,6 +14,7 @@ func AddFileRoutes(router fiber.Router) { fileGroup.Post("/upload/init", initUpload) fileGroup.Post("/upload/block/:id/:index", uploadBlock) fileGroup.Post("/upload/finish/:id", finishUpload) + fileGroup.Post("/upload/cancel/:id", cancelUpload) fileGroup.Post("/redirect", createRedirectFile) fileGroup.Get("/:id", getFile) fileGroup.Put("/:id", updateFile) @@ -92,7 +93,24 @@ func finishUpload(c fiber.Ctx) error { }) } -// createRedirectFile 创建重定向文件 +func cancelUpload(c fiber.Ctx) error { + uid := c.Locals("uid").(uint) + + id, err := strconv.ParseUint(c.Params("id"), 10, 32) + if err != nil { + return model.NewRequestError("Invalid file ID") + } + + if err := service.CancelUploadingFile(uid, uint(id)); err != nil { + return err + } + + return c.JSON(model.Response[any]{ + Success: true, + Message: "Upload cancelled successfully", + }) +} + func createRedirectFile(c fiber.Ctx) error { uid := c.Locals("uid").(uint) diff --git a/server/service/file.go b/server/service/file.go index a358f03..8688eff 100644 --- a/server/service/file.go +++ b/server/service/file.go @@ -230,6 +230,34 @@ func FinishUploadingFile(uid uint, fid uint) (*model.FileView, error) { return dbFile.ToView(), nil } +func CancelUploadingFile(uid uint, fid uint) error { + uploadingFile, err := dao.GetUploadingFile(fid) + if err != nil { + log.Error("failed to get uploading file: ", err) + return model.NewNotFoundError("file not found") + } + if uploadingFile.UserID != uid { + return model.NewUnAuthorizedError("user cannot cancel uploading file") + } + + if err := dao.DeleteUploadingFile(fid); err != nil { + log.Error("failed to delete uploading file: ", err) + return model.NewInternalServerError("failed to delete uploading file") + } + + go func() { + // Wait for 1 second to ensure there is no block being uploading + time.Sleep(time.Second) + if err := os.RemoveAll(uploadingFile.TempPath); err != nil { + log.Error("failed to remove temp dir: ", err) + } + }() + + updateUploadingSize(-uploadingFile.TotalSize) + + return nil +} + func CreateRedirectFile(uid uint, filename string, description string, resourceID uint, redirectUrl string) (*model.FileView, error) { canUpload, err := checkUserCanUpload(uid) if err != nil {