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

92 lines
2.9 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 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
}