This commit is contained in:
toom1996
2026-09-13 00:52:35 +08:00
parent 10d8a96e8c
commit dbee704c95
44 changed files with 755 additions and 1148 deletions

View File

@ -27,7 +27,7 @@ type ReviewRepository interface {
UpdateDraft(ctx context.Context, id uint32, fields map[string]any) error
// SetDraftStatus 设置草稿状态(通过/驳回)与审核人/驳回理由。
SetDraftStatus(ctx context.Context, id uint32, status, reviewer, reason string) error
// SaveRunwayFromDraft 晋升:按 source_url 幂等 upsert 到 brand_runway 正式表并替换图片,返回正式表主键。
// SaveRunwayFromDraft 晋升:按实体键(brand_id + season_code + collection_type)幂等 upsert 到 brand_runway 正式表并替换图片,返回正式表主键。
SaveRunwayFromDraft(ctx context.Context, draftID uint32) (uint32, error)
// 街拍草稿镜像方法(与 runway 同构,但对象为 street_snap_draft / street_snap)。
ListStreetDrafts(ctx context.Context, status string, page, size int) ([]model.StreetSnapDraft, int64, error)
@ -42,8 +42,6 @@ type ReviewRepository interface {
UpdateStreetDraft(ctx context.Context, id uint32, fields map[string]any) error
SetStreetDraftStatus(ctx context.Context, id uint32, status, reviewer, reason string) error
SaveStreetSnapFromDraft(ctx context.Context, draftID uint32) (uint32, error)
// CountPending 统计 pending 草稿数(合并 runway + street,仪表盘卡片用)。
CountPending(ctx context.Context) (int64, error)
// CountDraftPending 统计某草稿表(dest 传表对应的零值指针,如 &model.BrandRunwayDraft{})中指定状态的草稿数。
// 供各 ReviewModule 复用,新增模块无需再单独写计数方法。
CountDraftPending(ctx context.Context, status string, dest any) (int64, error)
@ -150,7 +148,7 @@ func (r *reviewRepository) SetDraftStatus(ctx context.Context, id uint32, status
}
// SaveRunwayFromDraft 晋升草稿到正式表:
// 1. 按 source_url 查找已存在的正式走秀(幂等:重审同一草稿只更新,不重复建行);
// 1. 按实体键(brand_id + season_code + collection_type)查找已存在的正式走秀(幂等:重审同一草稿只更新,不重复建行);
// 2. 存在则更新全部可编辑字段 + 图片数;不存在则新建;
// 3. 替换图片:软删旧图(is_deleted=1)+ 按草稿图片重建;
// 4. 返回正式表主键。
@ -176,10 +174,19 @@ func (r *reviewRepository) SaveRunwayFromDraft(ctx context.Context, draftID uint
}
imgs := unionRunwayDraftImages(curImgs, sibImgs)
// image_count 仅计主图(is_detail=0):对外列表卡片「N 张」与详情默认画廊都只展示主图,
// 细节图作为主图的附属按需展开,不计入主图数。
mainCount := 0
for _, im := range imgs {
if im.IsDetail == 0 {
mainCount++
}
}
now := uint32(time.Now().Unix())
var runwayID uint32
err = r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
// 1) 按 source_url 查找既有正式走秀
// 1) 按实体键查找既有正式走秀
var existing model.BrandRunway
if eErr := tx.Where("brand_id = ? AND season_code = ? AND collection_type = ? AND is_deleted = 0", draft.BrandID, draft.SeasonCode, draft.CollectionType).
Limit(1).Find(&existing).Error; eErr != nil {
@ -196,8 +203,7 @@ func (r *reviewRepository) SaveRunwayFromDraft(ctx context.Context, draftID uint
"collection_type": draft.CollectionType,
"season_code": draft.SeasonCode,
"cover": draft.Cover,
"source_url": draft.SourceURL,
"image_count": uint16(len(imgs)),
"image_count": uint16(mainCount),
"updated_at": now,
}
@ -219,8 +225,7 @@ func (r *reviewRepository) SaveRunwayFromDraft(ctx context.Context, draftID uint
CollectionType: draft.CollectionType,
SeasonCode: draft.SeasonCode,
Cover: draft.Cover,
SourceURL: draft.SourceURL,
ImageCount: uint16(len(imgs)),
ImageCount: uint16(mainCount),
CreatedAt: now,
UpdatedAt: now,
}
@ -245,6 +250,8 @@ func (r *reviewRepository) SaveRunwayFromDraft(ctx context.Context, draftID uint
Image: im.Image,
Name: im.Name,
SortOrder: uint32(i + 1),
LookIndex: im.LookIndex,
IsDetail: im.IsDetail,
CreatedAt: now,
UpdatedAt: now,
})
@ -261,23 +268,6 @@ func (r *reviewRepository) SaveRunwayFromDraft(ctx context.Context, draftID uint
return runwayID, nil
}
func (r *reviewRepository) CountPending(ctx context.Context) (int64, error) {
var n1, n2 int64
if err := r.db.WithContext(ctx).
Model(&model.BrandRunwayDraft{}).
Where("status = ? AND is_deleted = 0", model.DraftStatusPending).
Count(&n1).Error; err != nil {
return 0, err
}
if err := r.db.WithContext(ctx).
Model(&model.StreetSnapDraft{}).
Where("status = ? AND is_deleted = 0", model.DraftStatusPending).
Count(&n2).Error; err != nil {
return 0, err
}
return n1 + n2, nil
}
// CountDraftPending 统计传入表(dest 零值指针)中指定状态的草稿数;供各 ReviewModule 复用。
func (r *reviewRepository) CountDraftPending(ctx context.Context, status string, dest any) (int64, error) {
var n int64
@ -377,7 +367,7 @@ func (r *reviewRepository) SetStreetDraftStatus(ctx context.Context, id uint32,
}).Error
}
// SaveStreetSnapFromDraft 晋升街拍草稿到正式表 street_snap(按 source_url 幂等 upsert,替换图片)。
// SaveStreetSnapFromDraft 晋升街拍草稿到正式表 street_snap(按实体键 city+year 幂等 upsert,替换图片)。
// 逻辑与 SaveRunwayFromDraft 同构,但无 brand_id、有 city,图片明细落到 street_snap_images。
// 在事务内完成,保证草稿与正式表一致性。
func (r *reviewRepository) SaveStreetSnapFromDraft(ctx context.Context, draftID uint32) (uint32, error) {
@ -412,7 +402,6 @@ func (r *reviewRepository) SaveStreetSnapFromDraft(ctx context.Context, draftID
"year": draft.Year,
"city": draft.City,
"cover": draft.Cover,
"source_url": draft.SourceURL,
"image_count": uint16(len(imgs)),
"updated_at": now,
}
@ -428,7 +417,6 @@ func (r *reviewRepository) SaveStreetSnapFromDraft(ctx context.Context, draftID
Year: draft.Year,
City: draft.City,
Cover: draft.Cover,
SourceURL: draft.SourceURL,
ImageCount: uint16(len(imgs)),
CreatedAt: now,
UpdatedAt: now,