79 lines
2.7 KiB
Go
79 lines
2.7 KiB
Go
package handler
|
|
|
|
import (
|
|
"context"
|
|
"io"
|
|
"net/http"
|
|
|
|
"eslogad-be/internal/appcontext"
|
|
"eslogad-be/internal/contract"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
type FileService interface {
|
|
UploadProfileAvatar(ctx context.Context, userID uuid.UUID, filename string, content []byte, contentType string) (string, error)
|
|
UploadDocument(ctx context.Context, userID uuid.UUID, filename string, content []byte, contentType string) (string, string, error)
|
|
}
|
|
|
|
type FileHandler struct {
|
|
service FileService
|
|
}
|
|
|
|
func NewFileHandler(service FileService) *FileHandler {
|
|
return &FileHandler{service: service}
|
|
}
|
|
|
|
func (h *FileHandler) UploadProfileAvatar(c *gin.Context) {
|
|
appCtx := appcontext.FromGinContext(c.Request.Context())
|
|
if appCtx.UserID == uuid.Nil {
|
|
c.JSON(http.StatusUnauthorized, &contract.ErrorResponse{Error: "Unauthorized", Code: http.StatusUnauthorized})
|
|
return
|
|
}
|
|
file, header, err := c.Request.FormFile("file")
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, &contract.ErrorResponse{Error: "file is required", Code: http.StatusBadRequest})
|
|
return
|
|
}
|
|
defer file.Close()
|
|
content, err := io.ReadAll(io.LimitReader(file, 10<<20))
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, &contract.ErrorResponse{Error: "failed to read file", Code: http.StatusBadRequest})
|
|
return
|
|
}
|
|
ct := header.Header.Get("Content-Type")
|
|
url, err := h.service.UploadProfileAvatar(c.Request.Context(), appCtx.UserID, header.Filename, content, ct)
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, &contract.ErrorResponse{Error: err.Error(), Code: http.StatusInternalServerError})
|
|
return
|
|
}
|
|
c.JSON(http.StatusOK, contract.BuildSuccessResponse(map[string]string{"url": url}))
|
|
}
|
|
|
|
func (h *FileHandler) UploadDocument(c *gin.Context) {
|
|
appCtx := appcontext.FromGinContext(c.Request.Context())
|
|
if appCtx.UserID == uuid.Nil {
|
|
c.JSON(http.StatusUnauthorized, &contract.ErrorResponse{Error: "Unauthorized", Code: http.StatusUnauthorized})
|
|
return
|
|
}
|
|
file, header, err := c.Request.FormFile("file")
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, &contract.ErrorResponse{Error: "file is required", Code: http.StatusBadRequest})
|
|
return
|
|
}
|
|
defer file.Close()
|
|
content, err := io.ReadAll(io.LimitReader(file, 20<<20))
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, &contract.ErrorResponse{Error: "failed to read file", Code: http.StatusBadRequest})
|
|
return
|
|
}
|
|
ct := header.Header.Get("Content-Type")
|
|
url, key, err := h.service.UploadDocument(c.Request.Context(), appCtx.UserID, header.Filename, content, ct)
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, &contract.ErrorResponse{Error: err.Error(), Code: http.StatusInternalServerError})
|
|
return
|
|
}
|
|
c.JSON(http.StatusOK, contract.BuildSuccessResponse(map[string]string{"url": url, "key": key}))
|
|
}
|