mirror of
https://github.com/wgh136/nysoure.git
synced 2025-09-27 04:17:23 +00:00
Initial commit
This commit is contained in:
254
server/api/file.go
Normal file
254
server/api/file.go
Normal file
@@ -0,0 +1,254 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/gofiber/fiber/v3/log"
|
||||
"mime/multipart"
|
||||
"nysoure/server/model"
|
||||
"nysoure/server/service"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func AddFileRoutes(router fiber.Router) {
|
||||
fileGroup := router.Group("/files")
|
||||
{
|
||||
fileGroup.Post("/upload/init", initUpload)
|
||||
fileGroup.Post("/upload/block/:id/:index", uploadBlock)
|
||||
fileGroup.Post("/upload/finish/:id", finishUpload)
|
||||
fileGroup.Post("/redirect", createRedirectFile)
|
||||
fileGroup.Get("/:id", getFile)
|
||||
fileGroup.Put("/:id", updateFile)
|
||||
fileGroup.Delete("/:id", deleteFile)
|
||||
}
|
||||
}
|
||||
|
||||
// initUpload 初始化文件上传过程
|
||||
func initUpload(c fiber.Ctx) error {
|
||||
uid := c.Locals("uid").(uint)
|
||||
|
||||
type InitUploadRequest struct {
|
||||
Filename string `json:"filename"`
|
||||
Description string `json:"description"`
|
||||
FileSize int64 `json:"file_size"`
|
||||
ResourceID uint `json:"resource_id"`
|
||||
StorageID uint `json:"storage_id"`
|
||||
}
|
||||
|
||||
var req InitUploadRequest
|
||||
if err := c.Bind().Body(&req); err != nil {
|
||||
return c.JSON(model.Response[any]{
|
||||
Success: false,
|
||||
Message: "无效的请求参数",
|
||||
})
|
||||
}
|
||||
|
||||
result, err := service.CreateUploadingFile(uid, req.Filename, req.Description, req.FileSize, req.ResourceID, req.StorageID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.JSON(model.Response[*model.UploadingFileView]{
|
||||
Success: true,
|
||||
Data: result,
|
||||
})
|
||||
}
|
||||
|
||||
// uploadBlock 上传文件块
|
||||
func uploadBlock(c fiber.Ctx) error {
|
||||
uid := c.Locals("uid").(uint)
|
||||
|
||||
id, err := strconv.ParseUint(c.Params("id"), 10, 32)
|
||||
if err != nil {
|
||||
return c.JSON(model.Response[any]{
|
||||
Success: false,
|
||||
Message: "无效的文件ID",
|
||||
})
|
||||
}
|
||||
|
||||
index, err := strconv.Atoi(c.Params("index"))
|
||||
if err != nil {
|
||||
return c.JSON(model.Response[any]{
|
||||
Success: false,
|
||||
Message: "无效的块索引",
|
||||
})
|
||||
}
|
||||
|
||||
file, err := c.Request().MultipartForm()
|
||||
if err != nil {
|
||||
return c.JSON(model.Response[any]{
|
||||
Success: false,
|
||||
Message: "无效的文件数据",
|
||||
})
|
||||
}
|
||||
|
||||
if len(file.File["block"]) == 0 {
|
||||
return c.JSON(model.Response[any]{
|
||||
Success: false,
|
||||
Message: "没有找到文件块",
|
||||
})
|
||||
}
|
||||
|
||||
fileHeader := file.File["block"][0]
|
||||
fileContent, err := fileHeader.Open()
|
||||
if err != nil {
|
||||
log.Error("打开文件块失败: ", err)
|
||||
return c.JSON(model.Response[any]{
|
||||
Success: false,
|
||||
Message: "打开文件块失败",
|
||||
})
|
||||
}
|
||||
defer func(fileContent multipart.File) {
|
||||
_ = fileContent.Close()
|
||||
}(fileContent)
|
||||
|
||||
data := make([]byte, fileHeader.Size)
|
||||
if _, err := fileContent.Read(data); err != nil {
|
||||
log.Error("读取文件块失败: ", err)
|
||||
return c.JSON(model.Response[any]{
|
||||
Success: false,
|
||||
Message: "读取文件块失败",
|
||||
})
|
||||
}
|
||||
|
||||
if err := service.UploadBlock(uid, uint(id), index, data); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.JSON(model.Response[any]{
|
||||
Success: true,
|
||||
Message: fmt.Sprintf("块 %d 上传成功", index),
|
||||
})
|
||||
}
|
||||
|
||||
// finishUpload 完成文件上传
|
||||
func finishUpload(c fiber.Ctx) error {
|
||||
uid := c.Locals("uid").(uint)
|
||||
|
||||
id, err := strconv.ParseUint(c.Params("id"), 10, 32)
|
||||
if err != nil {
|
||||
return c.JSON(model.Response[any]{
|
||||
Success: false,
|
||||
Message: "无效的文件ID",
|
||||
})
|
||||
}
|
||||
|
||||
result, err := service.FinishUploadingFile(uid, uint(id))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.JSON(model.Response[*model.FileView]{
|
||||
Success: true,
|
||||
Data: result,
|
||||
})
|
||||
}
|
||||
|
||||
// createRedirectFile 创建重定向文件
|
||||
func createRedirectFile(c fiber.Ctx) error {
|
||||
uid := c.Locals("uid").(uint)
|
||||
|
||||
type CreateRedirectFileRequest struct {
|
||||
Filename string `json:"filename"`
|
||||
Description string `json:"description"`
|
||||
ResourceID uint `json:"resource_id"`
|
||||
RedirectURL string `json:"redirect_url"`
|
||||
}
|
||||
|
||||
var req CreateRedirectFileRequest
|
||||
if err := c.Bind().Body(&req); err != nil {
|
||||
return c.JSON(model.Response[any]{
|
||||
Success: false,
|
||||
Message: "无效的请求参数",
|
||||
})
|
||||
}
|
||||
|
||||
result, err := service.CreateRedirectFile(uid, req.Filename, req.Description, req.ResourceID, req.RedirectURL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.JSON(model.Response[*model.FileView]{
|
||||
Success: true,
|
||||
Data: result,
|
||||
})
|
||||
}
|
||||
|
||||
// getFile 获取文件信息
|
||||
func getFile(c fiber.Ctx) error {
|
||||
id, err := strconv.ParseUint(c.Params("id"), 10, 32)
|
||||
if err != nil {
|
||||
return c.JSON(model.Response[any]{
|
||||
Success: false,
|
||||
Message: "无效的文件ID",
|
||||
})
|
||||
}
|
||||
|
||||
file, err := service.GetFile(uint(id))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.JSON(model.Response[*model.FileView]{
|
||||
Success: true,
|
||||
Data: file,
|
||||
})
|
||||
}
|
||||
|
||||
// updateFile 更新文件信息
|
||||
func updateFile(c fiber.Ctx) error {
|
||||
uid := c.Locals("uid").(uint)
|
||||
|
||||
id, err := strconv.ParseUint(c.Params("id"), 10, 32)
|
||||
if err != nil {
|
||||
return c.JSON(model.Response[any]{
|
||||
Success: false,
|
||||
Message: "无效的文件ID",
|
||||
})
|
||||
}
|
||||
|
||||
type UpdateFileRequest struct {
|
||||
Filename string `json:"filename"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
var req UpdateFileRequest
|
||||
if err := c.Bind().Body(&req); err != nil {
|
||||
return c.JSON(model.Response[any]{
|
||||
Success: false,
|
||||
Message: "无效的请求参数",
|
||||
})
|
||||
}
|
||||
|
||||
result, err := service.UpdateFile(uid, uint(id), req.Filename, req.Description)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.JSON(model.Response[*model.FileView]{
|
||||
Success: true,
|
||||
Data: result,
|
||||
})
|
||||
}
|
||||
|
||||
// deleteFile 删除文件
|
||||
func deleteFile(c fiber.Ctx) error {
|
||||
uid := c.Locals("uid").(uint)
|
||||
|
||||
id, err := strconv.ParseUint(c.Params("id"), 10, 32)
|
||||
if err != nil {
|
||||
return c.JSON(model.Response[any]{
|
||||
Success: false,
|
||||
Message: "无效的文件ID",
|
||||
})
|
||||
}
|
||||
|
||||
if err := service.DeleteFile(uid, uint(id)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.JSON(model.Response[any]{
|
||||
Success: true,
|
||||
Message: "文件删除成功",
|
||||
})
|
||||
}
|
Reference in New Issue
Block a user