package dto // ---------- 请求 ---------- // ArticleQuery 文章列表查询条件。 // // 全部筛选项均支持多值(HBX 风格复选框),由 handler 从 query string 解析后填充。 type ArticleQuery struct { Page int Size int Keyword string // 标题模糊搜索 BrandID string // 单个品牌 id BrandIDs []uint32 // 多个品牌 id(brand_ids 逗号分隔) CollectionTypes []string // rtw / menswear / couture / resort / pre_fall Seasons []string // spring / fall SeasonCode string // SS26 / FW25,精确匹配 Years []int // 年份 Sort string // newest / year_desc / year_asc / image_count WithImages int // 列表附带每篇前 N 张图,0 表示不带 // Locale 语言:cn | en。空时由 service 回落默认 en。 // 决定 title / description / brand_name 出参选取 *_en 还是 *_cn。 Locale string } // 列表分页与附图数量的边界,与原项目保持一致。 const ( articleDefaultSize = 12 articleMaxSize = 100 withImagesMax = 12 ) // Normalize 校正分页与附图参数,防止非法值打穿数据库。 func (q *ArticleQuery) Normalize() { if q.Page < 1 { q.Page = 1 } if q.Size < 1 || q.Size > articleMaxSize { q.Size = articleDefaultSize } if q.WithImages < 0 { q.WithImages = 0 } if q.WithImages > withImagesMax { q.WithImages = withImagesMax } if q.Sort == "" { q.Sort = "newest" } } // Offset 返回 SQL 偏移量。 func (q ArticleQuery) Offset() int { return (q.Page - 1) * q.Size } // ---------- 响应 ---------- // PublicArticleImage 对外展示用的图片结构(仅 url + 名称)。 type PublicArticleImage struct { Image string `json:"image"` Name string `json:"name"` } // PublicArticle 对外展示用的精简文章结构。 // // 刻意剔除后台管理字段(is_deleted / updated_at / description 全文)。 // 对外只暴露编码后的 UID(非自增主键),防止爬虫顺序枚举; // 同时把 brand_id 也编码为 brand_uid,品牌跳转同样不可枚举。 type PublicArticle struct { UID string `json:"id"` // 编码后的文章 id(无序串) BrandUID string `json:"brand_id"` // 编码后的品牌 id(无序串) Title string `json:"title"` Summary string `json:"summary"` // description 截断后的对外摘要 Cover string `json:"cover"` // 封面相对路径,如 /uploads/xxx.jpg BrandName string `json:"brand_name"` // JOIN brand 得到 Year uint16 `json:"year"` ImageCount uint16 `json:"image_count"` CollectionType string `json:"collection_type"` // rtw/menswear/couture/resort/pre_fall Season string `json:"season"` // spring/fall/空 SeasonCode string `json:"season_code"` // SS26/FW25/RES26/PF25 PublishedAt uint32 `json:"published_at"` // = created_at,Unix 秒 Images []PublicArticleImage `json:"images"` // with_images 参数控制,未请求时为 null } // PublicArticleDetail 对外只读文章详情:含正文与完整图片集,不暴露管理字段。 type PublicArticleDetail struct { UID string `json:"id"` // 编码后的文章 id(无序串) BrandUID string `json:"brand_id"` // 编码后的品牌 id(无序串) Title string `json:"title"` Summary string `json:"summary"` Description string `json:"description"` Cover string `json:"cover"` BrandName string `json:"brand_name"` Year uint16 `json:"year"` ImageCount uint16 `json:"image_count"` SourceURL string `json:"source_url"` PublishedAt uint32 `json:"published_at"` Images []PublicArticleImage `json:"images"` }