This commit is contained in:
toom1996
2026-10-18 17:42:10 +08:00
parent 1b06bd5bda
commit 1de1ec46a6
58 changed files with 5281 additions and 19191 deletions

View File

@ -30,8 +30,6 @@ type ArticleService interface {
AdminList(ctx context.Context, q dto.ArticleQuery) ([]dto.AdminRunway, int64, error)
// GetForEdit 取原始走秀记录与图片,供后台编辑表单预填。
GetForEdit(ctx context.Context, id uint32) (*model.BrandRunway, []model.BrandRunwayImage, error)
// GetRunwayDupSources 批量反查走秀重复源(见仓储注释),供编辑页标记重复图。
GetRunwayDupSources(ctx context.Context, imageIDs []uint32) (map[uint32]dto.DupSource, error)
// UpdateRunway 审核/编辑后更新字段(字段白名单在仓储层强制)。
UpdateRunway(ctx context.Context, id uint32, fields map[string]any) error
// DeleteImage 软删单张走秀图片。
@ -241,11 +239,6 @@ func (s *articleService) GetForEdit(ctx context.Context, id uint32) (*model.Bran
return rw, orderRunwayImagesForEdit(imgs), nil
}
// GetRunwayDupSources 批量反查走秀重复源(见仓储注释)。
func (s *articleService) GetRunwayDupSources(ctx context.Context, imageIDs []uint32) (map[uint32]dto.DupSource, error) {
return s.articles.GetRunwayDupSources(ctx, imageIDs)
}
// orderRunwayImagesForEdit 走秀图片按 parent_image_id 重排为「主图后紧跟其细节图」的扁平顺序。
// 同一主图内的细节图按 sort_order 升序;孤儿细节图(parent 缺失)追加末尾,不丢图。
func orderRunwayImagesForEdit(imgs []model.BrandRunwayImage) []model.BrandRunwayImage {
@ -294,17 +287,6 @@ func (s *articleService) DeleteImage(ctx context.Context, imageID uint32) error
if key != "" {
purgeOrphanImages(ctx, s.media, s.deleter, []string{key})
}
// 删图后重算本画廊去重:避免删除源图后剩余图仍挂陈旧 dup_of,误显「重复」且源图打不开。
if runwayID, err := s.articles.GetRunwayImageRunwayID(ctx, imageID); err == nil && runwayID != 0 {
if err := s.articles.ReresolveRunwayDedup(ctx, runwayID); err != nil {
log.Printf("[warn] 重算走秀 %d 去重失败(重复标记可能陈旧): %v", runwayID, err)
}
}
// 跨文章清理:本图若是其它文章近重复的「源」,那些文章的 dup_of 需重算/清除
// (ReresolveRunwayDedup 只算本集内,不会碰其它文章指向本图的标记)。
if err := s.articles.ReresolveRunwayDupOfSources(ctx, []uint32{imageID}); err != nil {
log.Printf("[warn] 跨文章重算走秀图 %d 去重失败(重复标记可能陈旧): %v", imageID, err)
}
return nil
}
@ -334,11 +316,6 @@ func (s *articleService) SetDeleted(ctx context.Context, id uint32, deleted uint
// 仍被其他图集引用的 key 不会被误删(内容寻址共享 key 安全);入队失败仅告警,
// 图集已下架、图片已软删,S4文件留待后续手动清理或周期性兜底扫描。
func (s *articleService) PurgeGallery(ctx context.Context, id uint32) error {
// 下架前先取存活图片 id:删整篇后,其它文章中 dup_of 指向本篇图片的标记需跨文章重算/清除。
delIDs, err := s.articles.GetRunwayLiveImageIDs(ctx, id)
if err != nil {
return err
}
keys, err := s.articles.SoftDeleteRunwayImages(ctx, id)
if err != nil {
return err
@ -351,12 +328,6 @@ func (s *articleService) PurgeGallery(ctx context.Context, id uint32) error {
log.Printf("[warn] 下架图集 %d 入队清理S4失败(文件将暂留): %v", id, err)
}
}
// 跨文章去重清理:删除整篇后,其它文章中 dup_of 指向本篇图片的标记重算/清除。
if len(delIDs) > 0 {
if err := s.articles.ReresolveRunwayDupOfSources(ctx, delIDs); err != nil {
log.Printf("[warn] 跨文章重算走秀 %d 去重失败(重复标记可能陈旧): %v", id, err)
}
}
return nil
}
@ -372,11 +343,11 @@ func (s *articleService) toPublicImages(imgs []model.BrandRunwayImage) []dto.Pub
out := make([]dto.PublicArticleImage, 0, len(imgs))
for _, im := range imgs {
out = append(out, dto.PublicArticleImage{
ID: hashid.EncodeWithType(im.ID, hashid.TypeRunwayImage),
Image: s.img.Compose(im.Image),
Thumb: s.img.ComposeThumb(im.Image),
Name: im.Name,
IsDetail: im.IsDetail,
ID: hashid.EncodeWithType(im.ID, hashid.TypeRunwayImage),
Image: s.img.Compose(im.Image),
Thumb: s.img.ComposeThumb(im.Image),
Name: im.Name,
IsDetail: im.IsDetail,
})
}
return out
@ -391,10 +362,10 @@ func (s *articleService) toThumbImages(imgs []model.BrandRunwayImage) []dto.Publ
out := make([]dto.PublicArticleImage, 0, len(imgs))
for _, im := range imgs {
out = append(out, dto.PublicArticleImage{
ID: hashid.EncodeWithType(im.ID, hashid.TypeRunwayImage),
Image: s.img.ComposeThumb(im.Image),
Name: im.Name,
IsDetail: im.IsDetail,
ID: hashid.EncodeWithType(im.ID, hashid.TypeRunwayImage),
Image: s.img.ComposeThumb(im.Image),
Name: im.Name,
IsDetail: im.IsDetail,
})
}
return out