This commit is contained in:
toom1996
2026-08-26 10:45:21 +08:00
parent 3cf1368e68
commit 30c9f21da4
48 changed files with 3442 additions and 0 deletions

View File

@ -0,0 +1,91 @@
package service
import (
"context"
"fashionapi/internal/dto"
"fashionapi/internal/pkg/hashid"
"fashionapi/internal/repository"
)
// BrandService 品牌业务接口。
type BrandService interface {
List(ctx context.Context, q dto.BrandQuery) ([]dto.PublicBrand, int64, error)
// Popular 首页"热门品牌"区块:按图片数排名的前 limit 个品牌,附带代表走秀封面与标题。
// locale 决定品牌名/标题的展示语言(cn/en)。
Popular(ctx context.Context, limit int, locale string) ([]dto.PopularBrand, error)
}
type brandService struct {
brands repository.BrandRepository
}
// NewBrandService 创建品牌服务。
func NewBrandService(brands repository.BrandRepository) BrandService {
return &brandService{brands: brands}
}
// List 查询品牌列表并附带每个品牌的档案数。
//
// featured=1 时先按指标算出"代表品牌"集合,再把列表收敛到该集合内 ——
// 全库 1600+ 有档案品牌对 A-Z 索引来说过多,精选前 200 更符合导航场景。
func (s *brandService) List(ctx context.Context, q dto.BrandQuery) ([]dto.PublicBrand, int64, error) {
q.Normalize()
var restrictIDs []uint32
if q.Featured {
ids, err := s.brands.FeaturedIDs(ctx, q.Metric, q.Limit)
if err != nil {
// 取不到精选集合时交给 repository 收窄为空集,
// 绝不静默退化成"返回全部品牌"——那会让前端索引突然膨胀。
restrictIDs = nil
} else {
restrictIDs = ids
}
}
items, total, err := s.brands.List(ctx, q, restrictIDs)
if err != nil {
return nil, 0, internalErr(err.Error())
}
ids := make([]uint32, 0, len(items))
for _, b := range items {
ids = append(ids, b.ID)
}
counts, err := s.brands.ArticleCountByBrandIDs(ctx, ids)
if err != nil {
return nil, 0, internalErr(err.Error())
}
list := make([]dto.PublicBrand, 0, len(items))
for _, b := range items {
list = append(list, dto.PublicBrand{
UID: hashid.Encode(b.ID),
Name: pickLocale(b.NameEn, b.NameCn, q.Locale),
ShowName: b.NameCn,
ArticleCount: counts[b.ID],
})
}
return list, total, nil
}
// Popular 热门品牌(首页区块用):按图片数排名的前 limit 个品牌,附带代表走秀封面与标题。
// 复用仓储层的 FeaturedIDs 排名逻辑,保持与"代表品牌"一致的"热门"定义。locale 选展示语言。
func (s *brandService) Popular(ctx context.Context, limit int, locale string) ([]dto.PopularBrand, error) {
rows, err := s.brands.PopularWithCover(ctx, limit)
if err != nil {
return nil, internalErr(err.Error())
}
out := make([]dto.PopularBrand, 0, len(rows))
for _, b := range rows {
out = append(out, dto.PopularBrand{
UID: hashid.Encode(b.ID),
ArticleUID: hashid.Encode(b.ArticleID),
Brand: pickLocale(b.BrandEn, b.BrandCn, locale),
Cover: b.Cover,
Title: pickLocale(b.TitleEn, b.TitleCn, locale),
})
}
return out, nil
}