新增 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>
86 lines
2.4 KiB
Go
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,
|
|
})
|
|
}
|