Files
2026-05-21 19:52:45 +08:00

160 lines
4.2 KiB
Go

package v1
import (
"fmt"
"net/http"
"strings"
"github.com/google/uuid"
"github.com/labstack/echo/v4"
"github.com/chaitin/panda-wiki/config"
"github.com/chaitin/panda-wiki/domain"
"github.com/chaitin/panda-wiki/handler"
"github.com/chaitin/panda-wiki/log"
"github.com/chaitin/panda-wiki/middleware"
"github.com/chaitin/panda-wiki/store/s3"
"github.com/chaitin/panda-wiki/usecase"
"github.com/chaitin/panda-wiki/utils"
)
type FileHandler struct {
*handler.BaseHandler
logger *log.Logger
auth middleware.AuthMiddleware
config *config.Config
fileUsecase *usecase.FileUsecase
}
func NewFileHandler(echo *echo.Echo, baseHandler *handler.BaseHandler, logger *log.Logger, auth middleware.AuthMiddleware, minioClient *s3.MinioClient, config *config.Config, fileUsecase *usecase.FileUsecase) *FileHandler {
h := &FileHandler{
BaseHandler: baseHandler,
logger: logger.WithModule("handler.v1.file"),
auth: auth,
config: config,
fileUsecase: fileUsecase,
}
group := echo.Group("/api/v1/file")
group.POST("/upload", h.Upload, h.auth.Authorize)
group.POST("/upload/url", h.UploadByUrl, h.auth.Authorize)
group.POST("/upload/anydoc", h.UploadAnydoc)
return h
}
// Upload
//
// @Summary Upload File
// @Description Upload File
// @Tags file
// @Accept multipart/form-data
// @Param file formData file true "File"
// @Param kb_id formData string false "Knowledge Base ID"
// @Success 200 {object} domain.ObjectUploadResp
// @Router /api/v1/file/upload [post]
func (h *FileHandler) Upload(c echo.Context) error {
cxt := c.Request().Context()
kbID := c.FormValue("kb_id")
if kbID == "" {
kbID = uuid.New().String()
}
file, err := c.FormFile("file")
if err != nil {
return h.NewResponseWithError(c, "failed to get file", err)
}
key, err := h.fileUsecase.UploadFile(cxt, kbID, file)
if err != nil {
return h.NewResponseWithError(c, "upload failed", err)
}
return h.NewResponseWithData(c, domain.ObjectUploadResp{
Key: key,
Filename: file.Filename,
})
}
// UploadByUrl
//
// @Summary Upload File By Url
// @Description Upload File By Url
// @Tags file
// @Accept json
// @Produce json
// @Param body body domain.UploadByUrlReq true "Request Body"
// @Success 200 {object} domain.Response{data=domain.ObjectUploadResp}
// @Router /api/v1/file/upload/url [post]
func (h *FileHandler) UploadByUrl(c echo.Context) error {
ctx := c.Request().Context()
var req domain.UploadByUrlReq
if err := c.Bind(&req); err != nil {
return h.NewResponseWithError(c, "invalid request parameters", err)
}
if err := c.Validate(req); err != nil {
return h.NewResponseWithError(c, "validate request body failed", err)
}
kbID := req.KbId
if kbID == "" {
kbID = uuid.New().String()
}
key, err := h.fileUsecase.UploadFileByUrl(ctx, kbID, req.Url)
if err != nil {
return h.NewResponseWithError(c, "upload failed", err)
}
return h.NewResponseWithData(c, domain.ObjectUploadResp{
Key: key,
})
}
// UploadAnydoc
//
// @Summary Upload Anydoc File
// @Description Upload Anydoc File
// @Tags file
// @Accept multipart/form-data
// @Param file formData file true "File"
// @Param path formData string true "File Path"
// @Success 200 {object} domain.AnydocUploadResp
// @Router /api/v1/file/upload/anydoc [post]
func (h *FileHandler) UploadAnydoc(c echo.Context) error {
clientIP := fmt.Sprintf("%s.17", h.config.SubnetPrefix)
if utils.GetClientIPFromRemoteAddr(c) != clientIP {
return c.JSON(http.StatusUnauthorized, domain.AnydocUploadResp{
Code: 1,
Err: "invalid required",
})
}
file, err := c.FormFile("file")
if err != nil {
return c.JSON(http.StatusBadRequest, domain.AnydocUploadResp{
Code: 1,
Err: "invalid required",
})
}
path := c.FormValue("path")
if path == "" {
return c.JSON(http.StatusBadRequest, domain.AnydocUploadResp{
Code: 1,
Err: "invalid required",
})
}
h.logger.Debug("AnydocUpload file", "path", path)
_, err = h.fileUsecase.AnyDocUploadFile(c.Request().Context(), file, path)
if err != nil {
return h.NewResponseWithError(c, "upload failed", err)
}
url := fmt.Sprintf("/static-file/%s", strings.TrimPrefix(path, "/"))
h.logger.Debug("AnydocUpload file", "path", url)
return c.JSON(http.StatusOK, domain.AnydocUploadResp{
Code: 0,
Data: url,
})
}