From 0e41000f621c3a644c603d7356500ea22bca8125 Mon Sep 17 00:00:00 2001 From: QiuSW <105186638@qq.com> Date: Thu, 17 Sep 2026 09:42:15 +0800 Subject: [PATCH] =?UTF-8?q?fix(server):=20=E6=B6=88=E6=AD=A7=E5=90=8E?= =?UTF-8?q?=E7=9A=84=E6=96=B0=E9=94=AE=E8=A1=A5=E8=BF=9B=E6=A1=A3=E6=A1=88?= =?UTF-8?q?=20(#301)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit resyncShopeeProductKeys 改了兄弟明细的 target_color,却没把新键写进档案;只有被 直接重解析的那一条走了 mergeParsedSpec。 线上 2026-09-17 的后果:明细已是 `黑色【長袖】`,档案里还是旧的 `黑色`,采购查 映射查不到,明细永远停在「规格待匹配」;而采购员点「一键匹配」匹到的是档案里 剩下的旧键,看起来成功了却没有任何明细在用它。 Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01NTDbDcwbDw1TSAcE6wfh2F --- server/app/goauto/sybimport/resolve_keys.go | 7 ++ .../sybimport/resolve_keys_archive_test.go | 77 +++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 server/app/goauto/sybimport/resolve_keys_archive_test.go diff --git a/server/app/goauto/sybimport/resolve_keys.go b/server/app/goauto/sybimport/resolve_keys.go index 0f12284..596b8e8 100644 --- a/server/app/goauto/sybimport/resolve_keys.go +++ b/server/app/goauto/sybimport/resolve_keys.go @@ -56,6 +56,13 @@ func resyncShopeeProductKeys(tx *gorm.DB, shopeeProductID uint64, incomingRaw st Updates(map[string]any{"target_color": keys.Color, "target_size": keys.Size}).Error; err != nil { return sybspec.ParseResult{}, err } + // `[必须]` 改了明细的键就必须把新键补进档案。映射是按档案里的值建的, + // 档案没有 `黑色【長袖】` 这个条目,采购查映射就查不到,明细永远停在 + // 「规格待匹配」——而采购员点「一键匹配」匹到的是档案里剩下的旧键 + // `黑色`,看起来成功了却没有任何明细在用它。 + if err := mergeParsedSpec(tx, shopeeProductID, keys); err != nil { + return sybspec.ParseResult{}, err + } } return resolved[incomingRaw], nil } diff --git a/server/app/goauto/sybimport/resolve_keys_archive_test.go b/server/app/goauto/sybimport/resolve_keys_archive_test.go new file mode 100644 index 0000000..a0d7bc9 --- /dev/null +++ b/server/app/goauto/sybimport/resolve_keys_archive_test.go @@ -0,0 +1,77 @@ +package sybimport_test + +import ( + "context" + "encoding/json" + "testing" + + "go-admin/app/goauto/models" + "go-admin/app/goauto/shopeeproduct" + "go-admin/app/goauto/sybimport" +) + +func sleeveDetail(id uint64, spec string) sybimport.DetailInput { + raw, _ := json.Marshal(map[string]any{ + "id": id, "productQty": 1, "productPrice": 100.0, "productThumb": 1, + "productTitle": "襯衫", "productSpec": spec, "productId": 24377106095, + }) + return sybimport.DetailInput{ + ID: id, ProductID: 24377106095, ProductQty: 1, ProductPrice: 100.0, + ProductSpec: spec, ProductTitle: "襯衫", ProductThumb: 1, Raw: raw, + } +} + +// `[必须]` 消歧改了明细的键,就必须把新键补进档案。映射是按档案里的值建的, +// 档案没有 `黑色【長袖】` 这个条目,采购查映射就查不到,明细永远停在「规格待匹配」; +// 而采购员点「一键匹配」匹到的是档案里剩下的旧键 `黑色`,看起来成功了却没有任何 +// 明细在用它——线上 2026-09-17 正是这样(#301)。 +func TestDisambiguatedKeysReachTheArchive(t *testing.T) { + db := openTestDB(t) + order := realOrder() + + if _, err := sybimport.ApplyDetail(context.Background(), db, order, + sleeveDetail(900001, "黑色【短袖】,M 【建議42.5-47.5公斤】")); err != nil { + t.Fatal(err) + } + second, err := sybimport.ApplyDetail(context.Background(), db, order, + sleeveDetail(900002, "黑色【長袖】,5XL 【建議72.5-77.5公斤】")) + if err != nil { + t.Fatal(err) + } + if second.SYBProduct.ShopeeProductID == nil { + t.Fatal("未关联虾皮商品") + } + + var product models.ShopeeProduct + if err := db.First(&product, *second.SYBProduct.ShopeeProductID).Error; err != nil { + t.Fatal(err) + } + specs, err := shopeeproduct.Unmarshal(product.SpecsJSON) + if err != nil { + t.Fatal(err) + } + archived := map[string]bool{} + for _, dimension := range specs { + for _, value := range dimension.Values { + archived[value.Name] = true + } + } + + // 两个明细的键都必须能在档案里找到,否则映射无从建立。 + for _, want := range []string{"黑色【短袖】", "黑色【長袖】"} { + if !archived[want] { + t.Fatalf("档案缺少键 %q,现有键: %v", want, archived) + } + } + + // 明细自己的键也必须是拆开后的形式。 + var rows []models.SYBProduct + if err := db.Where("shopee_product_id = ?", *second.SYBProduct.ShopeeProductID).Find(&rows).Error; err != nil { + t.Fatal(err) + } + for _, row := range rows { + if row.TargetColor != "黑色【短袖】" && row.TargetColor != "黑色【長袖】" { + t.Fatalf("明细 %d 的键未消歧: %q", row.ID, row.TargetColor) + } + } +}