up
This commit is contained in:
@@ -2,12 +2,30 @@ package services
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/aliyun/aliyun-oss-go-sdk/oss"
|
||||
"github.com/sujit-baniya/fiber-boilerplate/pkg/models"
|
||||
)
|
||||
|
||||
// OSSObject representa un objeto/archivo listado en el bucket
|
||||
type OSSObject struct {
|
||||
Key string `json:"key"`
|
||||
Size int64 `json:"size"`
|
||||
LastModified time.Time `json:"last_modified"`
|
||||
ETag string `json:"etag"`
|
||||
}
|
||||
|
||||
// OSSListResult resultado paginado de listado de objetos
|
||||
type OSSListResult struct {
|
||||
Objects []OSSObject `json:"objects"`
|
||||
CommonPrefixes []string `json:"prefixes"` // "carpetas" virtuales
|
||||
IsTruncated bool `json:"is_truncated"`
|
||||
NextMarker string `json:"next_marker"`
|
||||
}
|
||||
|
||||
type OSSService struct {
|
||||
Client *oss.Client
|
||||
Bucket *oss.Bucket
|
||||
@@ -91,3 +109,77 @@ func (s *OSSService) DeleteFile(objectKey string) error {
|
||||
log.Printf("Archivo eliminado de OSS: %s", objectKey)
|
||||
return nil
|
||||
}
|
||||
|
||||
// ListObjects lista objetos del bucket con soporte de prefijo (carpeta), delimitador y paginación.
|
||||
func (s *OSSService) ListObjects(prefix, marker string, maxKeys int) (*OSSListResult, error) {
|
||||
if maxKeys <= 0 || maxKeys > 1000 {
|
||||
maxKeys = 100
|
||||
}
|
||||
opts := []oss.Option{
|
||||
oss.MaxKeys(maxKeys),
|
||||
oss.Delimiter("/"),
|
||||
}
|
||||
if prefix != "" {
|
||||
opts = append(opts, oss.Prefix(prefix))
|
||||
}
|
||||
if marker != "" {
|
||||
opts = append(opts, oss.Marker(marker))
|
||||
}
|
||||
|
||||
resp, err := s.Bucket.ListObjects(opts...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error listando objetos OSS: %w", err)
|
||||
}
|
||||
|
||||
result := &OSSListResult{
|
||||
IsTruncated: resp.IsTruncated,
|
||||
NextMarker: resp.NextMarker,
|
||||
}
|
||||
for _, obj := range resp.Objects {
|
||||
result.Objects = append(result.Objects, OSSObject{
|
||||
Key: obj.Key,
|
||||
Size: obj.Size,
|
||||
LastModified: obj.LastModified,
|
||||
ETag: obj.ETag,
|
||||
})
|
||||
}
|
||||
for _, cp := range resp.CommonPrefixes {
|
||||
result.CommonPrefixes = append(result.CommonPrefixes, cp)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// SignedURL genera una URL firmada temporal para descargar/previsualizar un objeto.
|
||||
func (s *OSSService) SignedURL(objectKey string, expireSeconds int) (string, error) {
|
||||
if expireSeconds <= 0 {
|
||||
expireSeconds = 3600
|
||||
}
|
||||
url, err := s.Bucket.SignURL(objectKey, oss.HTTPGet, int64(expireSeconds))
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error generando URL firmada: %w", err)
|
||||
}
|
||||
return url, nil
|
||||
}
|
||||
|
||||
// UploadFromReader sube un archivo desde un io.Reader con el content-type dado.
|
||||
func (s *OSSService) UploadFromReader(objectKey, contentType string, r io.Reader) error {
|
||||
var opts []oss.Option
|
||||
if contentType != "" {
|
||||
opts = append(opts, oss.ContentType(contentType))
|
||||
}
|
||||
err := s.Bucket.PutObject(objectKey, r, opts...)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error subiendo objeto '%s': %w", objectKey, err)
|
||||
}
|
||||
log.Printf("Objeto subido a OSS: %s", objectKey)
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteObjects elimina múltiples objetos en una sola llamada (batch).
|
||||
func (s *OSSService) DeleteObjects(keys []string) error {
|
||||
_, err := s.Bucket.DeleteObjects(keys)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error eliminando objetos en batch: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user