This commit is contained in:
toom1996
2026-08-30 10:45:34 +08:00
parent a6724265ad
commit 9c3403a903
23 changed files with 284 additions and 508 deletions

View File

@ -25,9 +25,6 @@ type BrandRepository interface {
// 供 Hot 等已知 id 列表的场景使用,避免借道 List 的 featured 旗标复用查询。
ListByIDs(ctx context.Context, ids []uint32) ([]model.Brand, error)
// ArticleCountByBrandIDs 批量统计各品牌的走秀档案数,单次分组查询避免 N+1。
ArticleCountByBrandIDs(ctx context.Context, ids []uint32) (map[uint32]int, error)
// PopularWithCover 返回"热门品牌"及其代表走秀的封面/标题/文章 ID。
// 规则:先按品牌总图片数取前 limit 个热门品牌,再为每个品牌取最新一篇走秀。
// 返回的是仓储层裸数据(数字主键),对外编码由 service 层负责。
@ -84,10 +81,12 @@ func (r *brandRepository) brandFilterScope(q dto.BrandQuery, restrictIDs []uint3
db = db.Where("name_en REGEXP ?", latinPrefixRegexp)
}
// 中文分桶不限档案,直接列出全部中文名品牌,便于检索
// 关键词搜索时不限制"必须有走秀档案":用户按名字找品牌,
// 即使该品牌暂无走秀档案也应被命中(如 A Bathing Ape / 猿人头)。
if q.OnlyWithArticles && q.Keyword == "" && q.Letter != "OTHER" {
// 字母索引始终只返回"拥有走秀档案"的品牌(库中有 2 万+ 无档案品牌,
// 不过滤会污染 A-Z 索引)。原 only_with_articles 参数已删除,此过滤无条件生效。
// 例外:关键词搜索时不限制"必须有走秀档案"(用户按名字找品牌,
// 即使该品牌暂无走秀档案也应被命中,如 A Bathing Ape / 猿人头);
// 中文分桶(OTHER)同样列出全部中文名品牌便于检索。
if q.Keyword == "" && q.Letter != "OTHER" {
db = db.Where("id IN (?)", r.hasArticlesSubQuery())
}
@ -177,31 +176,6 @@ func (r *brandRepository) ListByIDs(ctx context.Context, ids []uint32) ([]model.
return items, nil
}
func (r *brandRepository) ArticleCountByBrandIDs(ctx context.Context, ids []uint32) (map[uint32]int, error) {
counts := make(map[uint32]int, len(ids))
if len(ids) == 0 {
return counts, nil
}
var grp []struct {
BrandID uint32 `gorm:"column:brand_id"`
Cnt int `gorm:"column:cnt"`
}
err := r.db.WithContext(ctx).
Model(&model.BrandRunway{}).
Select("brand_id, COUNT(*) AS cnt").
Where("brand_id IN ? AND is_deleted = 0", ids).
Group("brand_id").
Scan(&grp).Error
if err != nil {
return nil, err
}
for _, g := range grp {
counts[g.BrandID] = g.Cnt
}
return counts, nil
}
// PopularWithCover 返回"热门品牌"及其最新走秀的封面与标题。
//
// 规则: