Files
backend_v2/internal/dto/article.go
toom1996 dbee704c95 update
2026-09-13 00:52:35 +08:00

135 lines
6.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package dto
// ---------- 请求 ----------
// ArticleQuery 走秀列表查询条件(GET /public/runways)。
//
// 设计原则:参数尽可能少、不复用。
// - 所有筛选均为单值(前端已全改为单选),不再支持多选数组;
// - 按品牌过滤走查询参数 brand_id(hashid 编码串),不再使用独立嵌套路由;
// - 关键词搜索已移除(无前端调用);season_code 冗余(season+year 已覆盖)也已移除。
// - 分页 size 与附图 images 由服务端固定(ArticleFixedSize / ArticleFixedImages),前端不传、不可调。
type ArticleQuery struct {
Page int
Size int // 服务端固定为 ArticleFixedSize,不从 query 读取
Collection string // 单值:rtw / menswear / couture / resort / pre_fall
Season string // 单值:spring / fall
Year int // 单值年份,0 表示不过滤
Sort string // newest(默认)/ year_desc / year_asc
Images int // 服务端固定为 ArticleFixedImages,不从 query 读取
// Locale 语言:cn | en。空时由 service 回落默认 en。
// 决定 title / description / brand_name 出参选取 *_en 还是 *_cn。
Locale string
// BrandIDs 由列表接口从查询参数 brand_id(hashid 编码串)解码注入;为空表示不过滤。
BrandIDs []uint32
}
// 列表分页与附图数量由服务端固定(前端无调整入口),不再从 query 读取。
const (
ArticleFixedSize = 24 // 每页条数(runway-looks 分页固定值)
articleMaxSize = 100
ArticleFixedImages = 6 // 列表每篇附带前 N 张缩略图
imagesMax = 12
// PreviewLimit 未登录用户在列表接口可见的预览条数上限;
// 超过部分由前端登录门禁提示,避免公开接口一次性吐出全部图集。
PreviewLimit = 5
)
// Normalize 校正分页与附图参数,防止非法值打穿数据库。
func (q *ArticleQuery) Normalize() {
if q.Page < 1 {
q.Page = 1
}
if q.Size < 1 || q.Size > articleMaxSize {
q.Size = ArticleFixedSize
}
if q.Images < 0 {
q.Images = 0
}
if q.Images > imagesMax {
q.Images = imagesMax
}
if q.Sort == "" {
q.Sort = "newest"
}
}
// Offset 返回 SQL 偏移量。
func (q ArticleQuery) Offset() int { return (q.Page - 1) * q.Size }
// ---------- 响应 ----------
// PublicArticleImage 对外展示用的图片结构。
//
// ID 是图片自身的编码 id(hashid,i=走秀单图 / j=街拍单图),供「单图收藏」定位到具体某一张;
// 此前只有 image + name,前端无法稳定标识单张图片,故补充该字段。
//
// Image 与 Thumb 的关系:
// - Image 是「该接口场景下的主用地址」——详情接口给展示样式(high),列表接口直接给缩略图(thumb,
// 列表只需小图,不给大图以免浪费带宽)。
// - Thumb 恒为缩略图地址(thumb 样式),**仅详情接口填充**:详情返回的是展示样式大图,
// 但大图灯箱左栏缩略图条 / 右下角细节缩略图只要几十到一百多像素,用大图纯属浪费,
// 故额外给出 Thumb 供这些「小尺寸场景」使用。列表接口不填(其 Image 本身就是缩略图)。
type PublicArticleImage struct {
ID string `json:"id"`
Image string `json:"image"`
Thumb string `json:"thumb,omitempty"`
Name string `json:"name"`
IsDetail uint8 `json:"is_detail"` // 0=主图 1=细节图(详情接口 images 仅含主图;细节在 Details 分组)
LookIndex uint32 `json:"look_index"` // 细节图归属的主图序号(用于前端分组展开)
}
// RunwayLookDetails 某个主图(look)对应的细节图集合,供详情页「细节入口」按需展开。
type RunwayLookDetails struct {
LookIndex uint32 `json:"look_index"` // 主图序号(与 images 中对应主图的 look_index 一致)
Images []PublicArticleImage `json:"images"` // 该主图的细节图列表
}
// PublicArticle 对外展示用的精简文章结构(走秀列表)。
//
// 只返回前端真正渲染的字段:id / brand_id / title / cover / brand_name / image_count / images。
// year / season / season_code / collection_type / published_at / summary 前端从不展示,
// 且排序已由后端按真实走秀新旧(year + season 优先级)完成,故响应不再携带这些元数据。
// 对外只暴露编码后的 UID(非自增主键),防止爬虫顺序枚举;brand_id 同样编码为 brand_uid。
type PublicArticle struct {
UID string `json:"id"` // 编码后的文章 id(无序串)
BrandUID string `json:"brand_id"` // 编码后的品牌 id(无序串)
Title string `json:"title"`
Cover string `json:"cover"` // 封面相对路径,如 /uploads/xxx.jpg
BrandName string `json:"brand_name"` // JOIN brand 得到
ImageCount uint16 `json:"image_count"` // 该走秀图片总数(列表卡片 "N+" 角标用)
Images []PublicArticleImage `json:"images"` // 列表附带的每篇前 N 张缩略图
}
// PublicArticleDetail 对外只读文章详情:含正文与完整图片集,不暴露管理字段。
//
// 与列表一致,只返回前端渲染所需的字段;后台管理用的额外元数据(季节 / 年份 / 系列等)
// 见 AdminRunway,由后台列表接口单独返回。
type PublicArticleDetail struct {
UID string `json:"id"` // 编码后的文章 id(无序串)
BrandUID string `json:"brand_id"` // 编码后的品牌 id(无序串)
Title string `json:"title"`
Description string `json:"description"`
Cover string `json:"cover"`
BrandName string `json:"brand_name"`
Images []PublicArticleImage `json:"images"` // 仅主图(look 图),默认展示
Details []RunwayLookDetails `json:"details"` // 按主图分组的细节图(「细节入口」展开用);无细节时为空
}
// AdminRunway 后台管理用的走秀列表项:在 PublicArticle 基础上补回管理字段,
// 供后台按季节 / 年份 / 系列筛选与展示(对外 PublicArticle 刻意不暴露这些元数据)。
type AdminRunway struct {
UID string `json:"id"` // 编码后的文章 id(无序串)
BrandUID string `json:"brand_id"` // 编码后的品牌 id(无序串)
BrandName string `json:"brand_name"` // JOIN brand 得到(优先 en)
Title string `json:"title"`
Year uint16 `json:"year"` // 年份(如 2024)
Season string `json:"season"` // spring / fall
CollectionType string `json:"collection_type"` // rtw / menswear / couture / resort / pre_fall
SeasonCode string `json:"season_code"` // SS26 / FW25 / RES26 / PF25
ImageCount uint16 `json:"image_count"`
}