feat(street): 公开 API 详情新增主副图分组字段
This commit is contained in:
@ -134,14 +134,72 @@ func (s *streetSnapService) Detail(ctx context.Context, id string) (*dto.PublicS
|
||||
return nil, internalErr(err.Error())
|
||||
}
|
||||
|
||||
flat, groups := s.groupSnapImages(imgs)
|
||||
return &dto.PublicStreetSnapDetail{
|
||||
UID: hashid.EncodeWithType(snap.ID, hashid.TypeSnap),
|
||||
Title: snap.Title,
|
||||
Cover: s.img.Compose(snap.Cover),
|
||||
Images: s.toPublicSnapImages(imgs),
|
||||
Images: flat,
|
||||
Groups: groups,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// groupSnapImages 把街拍图片按主副图分组:主图各成一组,副图归入其(存活)主图组。
|
||||
// 父引用指向「副图」时沿链向上归并到该副图所在组的主图;父行缺失(被软删)则把该图按主图渲染(不丢图)。
|
||||
// 返回的 flat(扁平)与 groups 同源同序:groups 中每张主图对应的 Details 顺序,等于 flat 中该主图之后的副图出现顺序。
|
||||
func (s *streetSnapService) groupSnapImages(imgs []model.StreetSnapImage) ([]dto.PublicArticleImage, []dto.PublicStreetSnapGroup) {
|
||||
if len(imgs) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
flat := s.toPublicSnapImages(imgs)
|
||||
|
||||
byID := make(map[uint32]*model.StreetSnapImage, len(imgs))
|
||||
for i := range imgs {
|
||||
byID[imgs[i].ID] = &imgs[i]
|
||||
}
|
||||
|
||||
// resolveRoot 返回 img 所属主图的行 id;自身是主图则返回自身;父行缺失 / 成环则按主图渲染(返回自身)。
|
||||
resolveRoot := func(start uint32) uint32 {
|
||||
cur := start
|
||||
seen := map[uint32]bool{}
|
||||
for {
|
||||
n, ok := byID[cur]
|
||||
if !ok {
|
||||
return start // 父行不存在 → 按主图渲染(返回自身)
|
||||
}
|
||||
if n.IsDetail == 0 {
|
||||
return n.ID
|
||||
}
|
||||
if seen[cur] {
|
||||
return start // 环 → 容错,自成主图
|
||||
}
|
||||
seen[cur] = true
|
||||
cur = n.ParentImageID
|
||||
}
|
||||
}
|
||||
|
||||
groups := make([]dto.PublicStreetSnapGroup, 0, len(imgs))
|
||||
index := make(map[uint32]int, len(imgs))
|
||||
for i, im := range imgs {
|
||||
root := resolveRoot(im.ID)
|
||||
isDetail := root != im.ID
|
||||
ref := flat[i]
|
||||
if !isDetail {
|
||||
groups = append(groups, dto.PublicStreetSnapGroup{Image: ref})
|
||||
index[im.ID] = len(groups) - 1
|
||||
continue
|
||||
}
|
||||
if gi, ok := index[root]; ok {
|
||||
groups[gi].Details = append(groups[gi].Details, ref)
|
||||
} else {
|
||||
// 兜底(理论不发生):主图未先出现,自成一组
|
||||
groups = append(groups, dto.PublicStreetSnapGroup{Image: ref})
|
||||
index[im.ID] = len(groups) - 1
|
||||
}
|
||||
}
|
||||
return flat, groups
|
||||
}
|
||||
|
||||
// IDs 返回全部街拍的编码 uid(供 SSG 枚举详情页路径使用,对外暴露的即编码串)。
|
||||
// Popular 返回热度前 N 个街拍(按图片数降序),供 SSG 首页热门街拍展示。
|
||||
func (s *streetSnapService) Popular(ctx context.Context, limit int) ([]dto.PublicStreetSnap, error) {
|
||||
|
||||
Reference in New Issue
Block a user