Files
junhong_cmp_fiber/internal/handler/admin/storage.go
huang 2413c2fe14 feat: 新增批量获取文件下载预签名 URL 接口
新增 POST /api/admin/storage/batch-download-urls,支持一次传入最多 50 个 file_key,返回对应预签名下载 URL 映射。解决列表页批量展示图片需多次请求的问题。

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-18 10:08:45 +08:00

86 lines
2.4 KiB
Go

package admin
import (
"github.com/gofiber/fiber/v2"
"go.uber.org/zap"
"github.com/break/junhong_cmp_fiber/internal/model/dto"
"github.com/break/junhong_cmp_fiber/pkg/errors"
"github.com/break/junhong_cmp_fiber/pkg/logger"
"github.com/break/junhong_cmp_fiber/pkg/response"
"github.com/break/junhong_cmp_fiber/pkg/storage"
)
type StorageHandler struct {
service *storage.Service
}
func NewStorageHandler(service *storage.Service) *StorageHandler {
return &StorageHandler{service: service}
}
// GetBatchDownloadURLs 批量获取文件下载预签名 URL
// POST /api/admin/storage/batch-download-urls
func (h *StorageHandler) GetBatchDownloadURLs(c *fiber.Ctx) error {
if h.service == nil {
return errors.New(errors.CodeInternalError, "对象存储服务未配置")
}
var req dto.GetBatchDownloadURLsRequest
if err := c.BodyParser(&req); err != nil {
return errors.New(errors.CodeInvalidParam)
}
urls := make(map[string]string, len(req.FileKeys))
expiresIn := 0
for _, fileKey := range req.FileKeys {
result, err := h.service.GetDownloadURL(c.UserContext(), fileKey)
if err != nil {
logger.GetAppLogger().Error("获取下载URL失败",
zap.String("file_key", fileKey),
zap.Error(err),
)
return errors.New(errors.CodeInternalError, "获取下载URL失败")
}
urls[fileKey] = result.URL
expiresIn = result.ExpiresIn
}
return response.Success(c, dto.GetBatchDownloadURLsResponse{
URLs: urls,
ExpiresIn: expiresIn,
})
}
// GetUploadURL 获取文件上传预签名 URL
// POST /api/admin/storage/upload-url
func (h *StorageHandler) GetUploadURL(c *fiber.Ctx) error {
if h.service == nil {
return errors.New(errors.CodeInternalError, "对象存储服务未配置")
}
var req dto.GetUploadURLRequest
if err := c.BodyParser(&req); err != nil {
return errors.New(errors.CodeInvalidParam, "请求参数解析失败")
}
result, err := h.service.GetUploadURL(c.UserContext(), req.Purpose, req.FileName, req.ContentType)
if err != nil {
logger.GetAppLogger().Error("获取上传URL失败",
zap.String("path", c.Path()),
zap.String("method", c.Method()),
zap.String("purpose", req.Purpose),
zap.String("fileName", req.FileName),
zap.Error(err),
)
return errors.New(errors.CodeInternalError, "获取上传URL失败")
}
return response.Success(c, dto.GetUploadURLResponse{
UploadURL: result.URL,
FileKey: result.FileKey,
ExpiresIn: result.ExpiresIn,
})
}