Files
backend_v2/internal/dto/article.go
toom1996 30c9f21da4 update
2026-08-26 10:45:21 +08:00

99 lines
4.0 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 文章列表查询条件。
//
// 全部筛选项均支持多值(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"`
}