feat(creator): 监控账号画像采集入库——粉丝/关注/获赞/作品数与作者介绍

抖音 profile/other 响应本就携带画像数据但被丢弃,同步链路也无回填。
- migration 1046: creator_competitor 增加 signature、total_favorited 列及非负约束
- douyin 解析层: TargetProfile 增加签名与计数,total_favorited 兼容字符串大数
- store: UpdateCompetitorProfile 改为画像回填(nil 计数保留原值)
- 同步链路: 作品采集成功后拉取 profile 回填,失败仅记日志不阻断
This commit is contained in:
2026-09-30 16:37:56 +08:00
parent a9358f5c96
commit 3e809c4fc7
11 changed files with 176 additions and 25 deletions
+23
View File
@@ -1285,6 +1285,24 @@ func previewDouyinCompetitor(ctx context.Context, store *creator.Store, phaseASt
}, nil
}
// refreshCompetitorProfile 拉取抖音公开主页画像并回填监控账号画像字段。
// profile/other 响应自带粉丝/关注/获赞/作品数与签名,此前未回填导致详情页画像恒为空。
func refreshCompetitorProfile(ctx context.Context, store *creator.Store, browser creatorGatewayBrowser, competitor creator.Competitor) error {
profile, err := (douyin.CreatorCollector{Browser: browser}).ResolveTarget(ctx, competitor.PlatformAccountKey)
if err != nil {
return err
}
_, err = store.UpdateCompetitorProfile(ctx, competitor.ID, creator.CompetitorProfileUpdate{
AvatarURL: profile.AvatarURL,
Signature: profile.Signature,
FollowerCount: profile.FollowerCount,
FollowingCount: profile.FollowingCount,
TotalFavorited: profile.TotalFavorited,
AwemeCount: profile.AwemeCount,
})
return err
}
func syncCreatorCompetitor(ctx context.Context, store *creator.Store, hubStore *hub.Store, competitorID string) (creator.CollectionReport, error) {
return syncCreatorCompetitorWithClaim(ctx, store, hubStore, competitorID, true)
}
@@ -1349,6 +1367,11 @@ func syncCreatorCompetitorWithClaim(ctx context.Context, store *creator.Store, h
}
report, collectErr := store.CollectSource(ctx, competitor.Platform, creator.SourceCompetitor, competitor.ID, collector, collectionNow)
if collectErr == nil {
// 采集成功后回填监控账号画像(粉丝/关注/获赞/作品数/作者介绍);
// profile 拉取失败只记日志,不影响本次作品同步结果。
if profileErr := refreshCompetitorProfile(ctx, store, creatorGatewayBrowser{gateway: lease.gateway, environment: lease.environment}, competitor); profileErr != nil {
logrus.WithError(profileErr).WithField("competitor_id", competitorID).Warn("creator competitor profile refresh failed")
}
// 采集成功后把缺封面的作品封面缓存到本地(失败只记日志,不影响本次同步结果)。
if coverErr := cacheCompetitorWorkCovers(ctx, store, creatorGatewayBrowser{gateway: lease.gateway, environment: lease.environment}, competitor.ID); coverErr != nil {
logrus.WithError(coverErr).WithField("competitor_id", competitorID).Warn("creator competitor cover cache failed")