feat(storage): 实现本地存储功能,包括文件上传和下载接口
This commit is contained in:
@@ -44,6 +44,7 @@ func Provide(opts ...opt.Option) error {
|
||||
content *Content,
|
||||
creator *Creator,
|
||||
middlewares *middlewares.Middlewares,
|
||||
storage *Storage,
|
||||
tenant *Tenant,
|
||||
transaction *Transaction,
|
||||
user *User,
|
||||
@@ -54,6 +55,7 @@ func Provide(opts ...opt.Option) error {
|
||||
content: content,
|
||||
creator: creator,
|
||||
middlewares: middlewares,
|
||||
storage: storage,
|
||||
tenant: tenant,
|
||||
transaction: transaction,
|
||||
user: user,
|
||||
@@ -66,6 +68,13 @@ func Provide(opts ...opt.Option) error {
|
||||
}, atom.GroupRoutes); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := container.Container.Provide(func() (*Storage, error) {
|
||||
obj := &Storage{}
|
||||
|
||||
return obj, nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := container.Container.Provide(func() (*Tenant, error) {
|
||||
obj := &Tenant{}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ type Routes struct {
|
||||
common *Common
|
||||
content *Content
|
||||
creator *Creator
|
||||
storage *Storage
|
||||
tenant *Tenant
|
||||
transaction *Transaction
|
||||
user *User
|
||||
@@ -168,6 +169,21 @@ func (r *Routes) Register(router fiber.Router) {
|
||||
r.creator.UpdateSettings,
|
||||
Body[dto.Settings]("form"),
|
||||
))
|
||||
// Register routes for controller: Storage
|
||||
r.log.Debugf("Registering route: Get /v1/storage/:key -> storage.Download")
|
||||
router.Get("/v1/storage/:key"[len(r.Path()):], Func3(
|
||||
r.storage.Download,
|
||||
PathParam[string]("key"),
|
||||
QueryParam[string]("expires"),
|
||||
QueryParam[string]("sign"),
|
||||
))
|
||||
r.log.Debugf("Registering route: Put /v1/storage/:key -> storage.Upload")
|
||||
router.Put("/v1/storage/:key"[len(r.Path()):], DataFunc3(
|
||||
r.storage.Upload,
|
||||
PathParam[string]("key"),
|
||||
QueryParam[string]("expires"),
|
||||
QueryParam[string]("sign"),
|
||||
))
|
||||
// Register routes for controller: Tenant
|
||||
r.log.Debugf("Registering route: Delete /v1/tenants/:id/follow -> tenant.Unfollow")
|
||||
router.Delete("/v1/tenants/:id/follow"[len(r.Path()):], Func1(
|
||||
|
||||
84
backend/app/http/v1/storage.go
Normal file
84
backend/app/http/v1/storage.go
Normal file
@@ -0,0 +1,84 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"quyun/v2/app/services"
|
||||
|
||||
"github.com/gofiber/fiber/v3"
|
||||
)
|
||||
|
||||
// @provider
|
||||
type Storage struct{}
|
||||
|
||||
// Upload file
|
||||
//
|
||||
// @Router /v1/storage/:key [put]
|
||||
// @Summary Upload file
|
||||
// @Tags Storage
|
||||
// @Accept octet-stream
|
||||
// @Produce json
|
||||
// @Param key path string true "Object Key"
|
||||
// @Param expires query string true "Expiry"
|
||||
// @Param sign query string true "Signature"
|
||||
// @Success 200 {string} string "success"
|
||||
// @Bind key path key(key)
|
||||
// @Bind expires query
|
||||
// @Bind sign query
|
||||
func (s *Storage) Upload(ctx fiber.Ctx, key, expires, sign string) (string, error) {
|
||||
if err := services.Storage.Verify("PUT", key, expires, sign); err != nil {
|
||||
return "", fiber.NewError(fiber.StatusForbidden, err.Error())
|
||||
}
|
||||
|
||||
// Save file
|
||||
localPath := services.Storage.Config.LocalPath
|
||||
if localPath == "" {
|
||||
localPath = "./storage"
|
||||
}
|
||||
fullPath := filepath.Join(localPath, key)
|
||||
if err := os.MkdirAll(filepath.Dir(fullPath), 0o755); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
f, err := os.Create(fullPath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
if _, err := io.Copy(f, ctx.Request().BodyStream()); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return "success", nil
|
||||
}
|
||||
|
||||
// Download file
|
||||
//
|
||||
// @Router /v1/storage/:key [get]
|
||||
// @Summary Download file
|
||||
// @Tags Storage
|
||||
// @Accept json
|
||||
// @Produce octet-stream
|
||||
// @Param key path string true "Object Key"
|
||||
// @Param expires query string true "Expiry"
|
||||
// @Param sign query string true "Signature"
|
||||
// @Success 200 {file} file
|
||||
// @Bind key path key(key)
|
||||
// @Bind expires query
|
||||
// @Bind sign query
|
||||
func (s *Storage) Download(ctx fiber.Ctx, key, expires, sign string) error {
|
||||
if err := services.Storage.Verify("GET", key, expires, sign); err != nil {
|
||||
return fiber.NewError(fiber.StatusForbidden, err.Error())
|
||||
}
|
||||
|
||||
localPath := services.Storage.Config.LocalPath
|
||||
if localPath == "" {
|
||||
localPath = "./storage"
|
||||
}
|
||||
fullPath := filepath.Join(localPath, key)
|
||||
|
||||
return ctx.SendFile(fullPath)
|
||||
}
|
||||
Reference in New Issue
Block a user