64 lines
2.5 KiB
Go
64 lines
2.5 KiB
Go
package service
|
||
|
||
import (
|
||
"context"
|
||
|
||
"fashionapi/internal/dto"
|
||
"fashionapi/internal/pkg/hashid"
|
||
"fashionapi/internal/pkg/imgurl"
|
||
"fashionapi/internal/repository"
|
||
)
|
||
|
||
// IndexService 首页(/index/)各区块数据的聚合服务。
|
||
//
|
||
// 首页由多个独立区块(runway 等)组成,每个区块的数据各自组合、互不干扰。
|
||
// 该服务专管「首页区块数据」这一领域,避免把首页数据拼装逻辑散落到 BrandService 等其它服务里。
|
||
type IndexService interface {
|
||
// Runway 首页 runway 区块数据:包含 hotBrand(热门品牌,固定 20 条)等多个模块。
|
||
// 服务端写死各模块数量,不接收任何筛选参数;locale 决定标题展示语言。
|
||
Runway(ctx context.Context, locale string) (IndexRunwayData, error)
|
||
}
|
||
|
||
// IndexRunwayData 首页 runway 区块数据,按模块拆分;hotBrand 为其中之一。
|
||
//
|
||
// 后续新增首页 runway 模块时,在此结构体追加字段即可,前端按需读取,互不影响。
|
||
type IndexRunwayData struct {
|
||
HotBrand []dto.PopularBrand `json:"hotBrand"`
|
||
}
|
||
|
||
type indexService struct {
|
||
brands repository.BrandRepository
|
||
img *imgurl.Composer
|
||
}
|
||
|
||
// NewIndexService 创建首页数据服务。
|
||
// img 负责把库里存储的七牛 key 拼装为可访问 URL(首页统一普通图)。
|
||
func NewIndexService(brands repository.BrandRepository, img *imgurl.Composer) IndexService {
|
||
return &indexService{brands: brands, img: img}
|
||
}
|
||
|
||
// Runway 首页 runway 区块数据。
|
||
//
|
||
// 复用仓储层 PopularWithCover 的「按图片数排名取热门品牌 + 代表走秀封面/标题」逻辑,
|
||
// 保持与品牌「代表品牌」一致的"热门"定义;品牌名强制英文观感,标题按 locale 选列。
|
||
// hotBrand 数量写死 20,接口不接收任何参数。
|
||
func (s *indexService) Runway(ctx context.Context, locale string) (IndexRunwayData, error) {
|
||
const hotBrandLimit = 20
|
||
rows, err := s.brands.PopularWithCover(ctx, hotBrandLimit)
|
||
if err != nil {
|
||
return IndexRunwayData{}, internalErr(err.Error())
|
||
}
|
||
brands := make([]dto.PopularBrand, 0, len(rows))
|
||
for _, b := range rows {
|
||
brands = append(brands, dto.PopularBrand{
|
||
UID: hashid.Encode(b.ID),
|
||
ArticleUID: hashid.Encode(b.ArticleID),
|
||
// 品牌名强制优先英文("en"),不随 locale 切换,保持英文观感。
|
||
Brand: pickLocale(b.BrandEn, b.BrandCn, "en"),
|
||
Cover: s.img.Compose(b.Cover), // 首页热门卡片为大图展示,用高清样式(high)
|
||
Title: pickLocale(b.TitleEn, b.TitleCn, locale),
|
||
})
|
||
}
|
||
return IndexRunwayData{HotBrand: brands}, nil
|
||
}
|