This commit is contained in:
Lizandro Guarnizo
2026-05-26 21:28:35 -05:00
parent 7a374340c1
commit d8f38a6669
4 changed files with 486 additions and 42 deletions
+102
View File
@@ -2,11 +2,14 @@ package controllers
import (
"math"
"mime"
"path/filepath"
"strconv"
"strings"
"github.com/gofiber/fiber/v2"
"github.com/sujit-baniya/fiber-boilerplate/pkg/models"
"github.com/sujit-baniya/fiber-boilerplate/pkg/services"
)
// OssApiIndex renderiza la vista del panel de gestión de Alibaba Cloud OSS.
@@ -157,3 +160,102 @@ func DeleteOssApiConfig(c *fiber.Ctx) error {
}
return c.JSON(fiber.Map{"ok": true})
}
// ─── Explorador de archivos OSS ──────────────────────────────────────────────
// OssBrowserList lista los objetos del bucket activo con soporte de carpetas virtuales.
// Query params: prefix (carpeta actual), marker (paginación), max_keys
func OssBrowserList(c *fiber.Ctx) error {
svc, err := services.NewOSSServiceFromDB()
if err != nil {
return c.Status(fiber.StatusServiceUnavailable).JSON(fiber.Map{"error": "Sin configuración OSS activa: " + err.Error()})
}
prefix := c.Query("prefix", "")
marker := c.Query("marker", "")
maxKeys, _ := strconv.Atoi(c.Query("max_keys", "100"))
result, err := svc.ListObjects(prefix, marker, maxKeys)
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
}
return c.JSON(result)
}
// OssBrowserSignedURL genera una URL firmada temporal (1 hora) para previsualizar o descargar un objeto.
// Query param: key (objeto)
func OssBrowserSignedURL(c *fiber.Ctx) error {
key := strings.TrimSpace(c.Query("key", ""))
if key == "" {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "key es requerido"})
}
svc, err := services.NewOSSServiceFromDB()
if err != nil {
return c.Status(fiber.StatusServiceUnavailable).JSON(fiber.Map{"error": "Sin configuración OSS activa: " + err.Error()})
}
url, err := svc.SignedURL(key, 3600)
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
}
return c.JSON(fiber.Map{"url": url})
}
// OssBrowserDelete elimina un objeto del bucket activo.
// Body JSON: { "key": "ruta/al/archivo.jpg" }
func OssBrowserDelete(c *fiber.Ctx) error {
type Req struct {
Key string `json:"key"`
}
var req Req
if err := c.BodyParser(&req); err != nil || strings.TrimSpace(req.Key) == "" {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "key es requerido"})
}
svc, err := services.NewOSSServiceFromDB()
if err != nil {
return c.Status(fiber.StatusServiceUnavailable).JSON(fiber.Map{"error": "Sin configuración OSS activa: " + err.Error()})
}
if err := svc.DeleteFile(req.Key); err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
}
return c.JSON(fiber.Map{"ok": true})
}
// OssBrowserUpload sube un archivo al bucket activo.
// Form field: file (multipart), prefix (carpeta destino opcional)
func OssBrowserUpload(c *fiber.Ctx) error {
prefix := strings.TrimSpace(c.FormValue("prefix", ""))
fh, err := c.FormFile("file")
if err != nil {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "archivo requerido"})
}
f, err := fh.Open()
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "error abriendo archivo"})
}
defer f.Close()
objectKey := fh.Filename
if prefix != "" {
objectKey = strings.TrimRight(prefix, "/") + "/" + fh.Filename
}
ct := mime.TypeByExtension(filepath.Ext(fh.Filename))
if ct == "" {
ct = "application/octet-stream"
}
svc, err := services.NewOSSServiceFromDB()
if err != nil {
return c.Status(fiber.StatusServiceUnavailable).JSON(fiber.Map{"error": "Sin configuración OSS activa: " + err.Error()})
}
if err := svc.UploadFromReader(objectKey, ct, f); err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
}
return c.JSON(fiber.Map{"ok": true, "key": objectKey})
}