This commit is contained in:
toom1996
2026-08-30 11:23:17 +08:00
parent 9c3403a903
commit ec1ee702bd
6 changed files with 540 additions and 0 deletions

View File

@ -0,0 +1,83 @@
package handler
import (
"net/http"
"strconv"
"strings"
"fashionapi/internal/dto"
"fashionapi/internal/pkg/hashid"
"fashionapi/internal/pkg/response"
"fashionapi/internal/service"
"github.com/gin-gonic/gin"
)
// StreetSnapHandler 对外公开的街拍接口。
type StreetSnapHandler struct {
svc service.StreetSnapService
}
// NewStreetSnapHandler 创建街拍 handler。
func NewStreetSnapHandler(svc service.StreetSnapService) *StreetSnapHandler {
return &StreetSnapHandler{svc: svc}
}
// List 街拍列表(分页 + 排序 + 年份过滤)。
//
// GET /api/public/street-snaps
//
// 查询参数:
// - page 页码,默认 1(服务端固定每页 StreetSnapFixedSize=24 条)
// - year 年份(整数),0 表示不过滤
// - sort image_count(默认,按图片数降序)/ year_desc / year_asc
// - locale cn / en
//
// 每条附带前 StreetSnapFixedImages=6 张缩略图(服务端固定,不进参数)。
// 列表接口挂在 public 组,受 ClientSign 中间件保护(与 runway-looks / brands 同批批量接口)。
func (h *StreetSnapHandler) List(c *gin.Context) {
q := h.parseListQuery(c)
q.Normalize()
list, total, err := h.svc.List(c.Request.Context(), q)
if err != nil {
fail(c, err)
return
}
response.Page(c, http.StatusOK, list, total, q.Size)
}
func (h *StreetSnapHandler) parseListQuery(c *gin.Context) dto.StreetSnapQuery {
return dto.StreetSnapQuery{
Page: queryInt(c, "page", 1),
Size: dto.StreetSnapFixedSize, // 服务端固定,前端不传
Year: queryInt(c, "year", 0),
Sort: c.DefaultQuery("sort", "image_count"),
Images: dto.StreetSnapFixedImages, // 服务端固定,前端不传
Locale: parseLocale(c),
}
}
// Detail 街拍详情(含完整图片集)。
//
// GET /api/public/street-snaps/:id
// :id 是对外编码串(无序),需先解码为数字主键再查库;非法串视为不存在。
// 不走前端 JS 签名,单独挂载(与 runway 详情一致),单篇枚举防护由 HashID 承担。
func (h *StreetSnapHandler) Detail(c *gin.Context) {
raw := strings.TrimSpace(c.Param("id"))
if raw == "" {
response.Error(c, http.StatusBadRequest, "缺少街拍 id")
return
}
numeric, err := hashid.Decode(raw)
if err != nil {
response.Error(c, http.StatusNotFound, "街拍不存在")
return
}
detail, err := h.svc.Detail(c.Request.Context(), strconv.FormatUint(uint64(numeric), 10))
if err != nil {
fail(c, err)
return
}
response.Data(c, http.StatusOK, detail)
}