package service import ( "database/sql" "errors" "fmt" "strings" "cmautobuy/admin/repository" ) // ErrPddAssociationReplaceRequired 表示当前蝦皮商品已经关联了另一个 PDD 商品。 var ErrPddAssociationReplaceRequired = errors.New("更换 PDD 商品需要明确确认") // AssociateShopeePdd 把蝦皮商品关联到 PDD 商品档案。 // 解析、建档/复活和关联更新在同一事务内完成,任一步失败都不留下半成品。 func AssociateShopeePdd(db *sql.DB, shopeeGoodsID, rawURL string, confirmReplace bool) (string, error) { shopeeGoodsID = strings.TrimSpace(shopeeGoodsID) rawURL = strings.TrimSpace(rawURL) pddGoodsID, err := ParsePddGoodsID(rawURL) if err != nil { return "", err } tx, err := db.Begin() if err != nil { return "", fmt.Errorf("开始关联 PDD 商品事务失败: %w", err) } defer tx.Rollback() product, err := repository.GetShopeeProductByGoodsID(tx, shopeeGoodsID) if err != nil { return "", err } if product == nil { return "", fmt.Errorf("蝦皮商品 %s 不存在", shopeeGoodsID) } if product.PddGoodsID != "" && product.PddGoodsID != pddGoodsID && !confirmReplace { return "", fmt.Errorf("%w:当前是 %s,新链接解析为 %s", ErrPddAssociationReplaceRequired, product.PddGoodsID, pddGoodsID) } if _, err := repository.EnsurePddProduct(tx, pddGoodsID, rawURL); err != nil { return "", err } if err := repository.UpdateShopeePddLink(tx, shopeeGoodsID, pddGoodsID, rawURL); err != nil { return "", err } if err := tx.Commit(); err != nil { return "", fmt.Errorf("提交 PDD 商品关联失败: %w", err) } return pddGoodsID, nil } // CreateShopeePddCollectTask 按蝦皮商品当前关联创建采集任务,避免相信表单里的 PDD ID。 func CreateShopeePddCollectTask(db *sql.DB, shopeeGoodsID string) (CollectTaskResult, error) { product, err := repository.GetShopeeProductByGoodsID(db, strings.TrimSpace(shopeeGoodsID)) if err != nil { return CollectTaskResult{}, err } if product == nil { return CollectTaskResult{}, fmt.Errorf("蝦皮商品不存在") } if product.PddGoodsID == "" { return CollectTaskResult{}, fmt.Errorf("请先关联 PDD 商品") } return CreatePddCollectTasks(db, []string{product.PddGoodsID}) } // AssociateSybPdd 从顺运宝明细解析出可信的蝦皮商品,再复用统一关联逻辑。 func AssociateSybPdd(db *sql.DB, sybID, rawURL string, confirmReplace bool) (string, error) { context, err := repository.GetSybOrderContext(db, strings.TrimSpace(sybID)) if err != nil { return "", err } if context == nil { return "", fmt.Errorf("顺运宝明细不存在") } if context.Order.ShopeeGoodsID == "" { return "", fmt.Errorf("顺运宝未提供蝦皮商品 ID") } if context.Order.SpecKey == "" { return "", fmt.Errorf("顺运宝未提供规格,不能进入采购流程") } return AssociateShopeePdd(db, context.Order.ShopeeGoodsID, rawURL, confirmReplace) } // CreateSybPddCollectTask 按顺运宝明细当前关联创建采集任务。 func CreateSybPddCollectTask(db *sql.DB, sybID string) (CollectTaskResult, error) { context, err := repository.GetSybOrderContext(db, strings.TrimSpace(sybID)) if err != nil { return CollectTaskResult{}, err } if context == nil { return CollectTaskResult{}, fmt.Errorf("顺运宝明细不存在") } return CreateShopeePddCollectTask(db, context.Order.ShopeeGoodsID) }