diff --git a/server/app/goauto/task/image_search_link.go b/server/app/goauto/task/image_search_link.go new file mode 100644 index 0000000..a10ab59 --- /dev/null +++ b/server/app/goauto/task/image_search_link.go @@ -0,0 +1,50 @@ +package task + +import ( + "context" + "errors" + "strings" + + "go-admin/app/goauto/models" + "gorm.io/gorm" +) + +// autoLinkImageSearch is deliberately a narrow post-result hook. It only +// writes an association when the task was a complete collection, the frozen +// original association is unchanged, and the target product is active. Manual +// changes made while the Agent was running win by the CAS predicate. +func (service *Service) autoLinkImageSearch(ctx context.Context, taskID uint64) error { + var task models.CollectionTask + if err := service.DB.WithContext(ctx).First(&task, taskID).Error; err != nil { + return internalError(err) + } + if task.Source != models.CollectionTaskSourceImageSearch || task.Status != models.TaskStatusCompleted || task.PDDProductID == nil || task.ImageSearchSnapshot == nil { + return nil + } + snapshot, err := loadImageSearchSnapshot(task) + if err != nil { + return err + } + if snapshot.PriceGuardSkipped { + return nil + } + var product models.ShopeeProduct + if err := service.DB.WithContext(ctx).First(&product, snapshot.ShopeeProductID).Error; err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return nil + } + return internalError(err) + } + // PDD products are RMB in the current contract; unlike-currency snapshots + // must remain available for manual review and can never auto-link. + if strings.ToUpper(strings.TrimSpace(product.Currency)) != "CNY" { + return nil + } + result := service.DB.WithContext(ctx).Model(&models.ShopeeProduct{}). + Where("id = ? AND pdd_product_id IS NULL AND image_search_linked = ?", product.ID, false). + Updates(map[string]any{"pdd_product_id": *task.PDDProductID, "image_search_linked": true}) + if result.Error != nil { + return internalError(result.Error) + } + return nil +} diff --git a/server/app/goauto/task/result_service.go b/server/app/goauto/task/result_service.go index 57d8779..8fdd34e 100644 --- a/server/app/goauto/task/result_service.go +++ b/server/app/goauto/task/result_service.go @@ -123,6 +123,9 @@ func (service *Service) SubmitResult(ctx context.Context, taskID uint64, request if err := service.activatePersistedReplacement(ctx, taskID); err != nil { return DetailResponse{}, err } + if err := service.autoLinkImageSearch(ctx, taskID); err != nil { + return DetailResponse{}, err + } detail, err := service.Detail(ctx, taskID) detail.Replayed = replayed return detail, err