Files
hfb_sys/backend/internal/modules/listing/handler_public.go
T
yml2213 8dc21d2757 refactor(sitecode): 统一各模块分销站点编码解析为公共包
- 新增 internal/sitecode 包:FromRequest 头优先解析、FromQueryThenHeader
  探测接口专用、ExtractHost/IsLocalHost 提取 Host 域名
- 替换 auth/order/listing/chat/notification/withdrawal/wallet/distribution
  八模块 17 处各自内联的解析逻辑,统一优先级与 TrimSpace 行为
- 修复 notification 漏 TrimSpace、探测接口会话头压过显式 query、
  GetPublicSiteInfo 把 localhost Host 当站点域名查库等不一致
- 顺手清理 auth 中无引用的 extractHost 死代码
- gofmt 修复 withdrawal/presenter、chat/file/payment 测试四个历史遗留格式问题
2026-09-17 14:54:38 +08:00

106 lines
2.5 KiB
Go

package listing
import (
"net/http"
"strconv"
filemodule "hfb_sys/backend/internal/modules/file"
"hfb_sys/backend/internal/sitecode"
"hfb_sys/backend/pkg/response"
"github.com/gin-gonic/gin"
)
func (h *Handler) ListPublic(c *gin.Context) {
items, err := h.service.ListPublic(c.Request.Context(), parsePublicListQuery(c))
if err != nil {
writeListingError(c, err)
return
}
response.OK(c, items)
}
func (h *Handler) FindPublic(c *gin.Context) {
id, ok := parseID(c)
if !ok {
return
}
siteCode := sitecode.FromRequest(c)
item, err := h.service.FindPublic(c.Request.Context(), id, siteCode)
if err != nil {
writeListingError(c, err)
return
}
response.OK(c, item)
}
func (h *Handler) Cover(c *gin.Context) {
id, ok := parseID(c)
if !ok {
return
}
key, err := h.service.FindPublicCoverKey(c.Request.Context(), id)
if err != nil {
writeListingError(c, err)
return
}
h.writePublicObject(c, filemodule.ImageVariantFallbackKeys(key, filemodule.ImageVariantThumb)...)
}
func (h *Handler) Screenshot(c *gin.Context) {
id, ok := parseID(c)
if !ok {
return
}
index, err := strconv.Atoi(c.Param("index"))
if err != nil || index < 0 {
response.BadRequest(c, "截图序号不正确")
return
}
key, err := h.service.FindPublicScreenshotKey(c.Request.Context(), id, index)
if err != nil {
writeListingError(c, err)
return
}
variant := c.Query("variant")
var fallbackKeys []string
switch variant {
case "thumb":
fallbackKeys = filemodule.ImageVariantFallbackKeys(key, filemodule.ImageVariantThumb)
case "raw":
fallbackKeys = []string{key}
default:
fallbackKeys = filemodule.ImageVariantFallbackKeys(key, filemodule.ImageVariantMedium)
}
h.writePublicObject(c, fallbackKeys...)
}
func (h *Handler) writePublicObject(c *gin.Context, keys ...string) {
if h.storage == nil {
response.ServiceUnavailable(c, "文件存储未连接")
return
}
var object *filemodule.Object
for _, key := range keys {
nextObject, err := h.storage.Get(c.Request.Context(), key)
if err == nil {
object = nextObject
break
}
}
if object == nil {
response.Error(c, http.StatusNotFound, "not_found", "图片不存在或暂不可访问")
return
}
defer func() {
_ = object.Reader.Close()
}()
contentType := object.ContentType
if contentType == "" {
contentType = "application/octet-stream"
}
c.Header("Content-Type", contentType)
c.Header("Cache-Control", "public, max-age=300")
c.DataFromReader(http.StatusOK, object.Size, contentType, object.Reader, nil)
}