fix(server): 规格同步后只匹配本次明细,补进档案的新规格值从未被匹配 #293

Open
opened 2026-09-16 11:33:52 +08:00 by ila · 1 comment
Owner

来源:2026-09-16 本地验证 #290 时发现其验收项未达成。

问题

#290 的验收写的是「商品首次准备好后,其全部颜色尺码写入档案并完成匹配」。实测:

  • 写入达成:虾皮 1528 的颜色从 11 涨到 16,补进 墨綠色、橘色、湖藍色、薑黃色、黑色
  • 匹配未达成:这 5 个新颜色一次都没被尝试匹配

根因

matchSpecsAfterImageSearch 把本次明细的 id 传给 BatchSpecMatch:

service.syncShopeeSpecs(ctx, linked.ShopeeProductID, linked.PDDProductID)
purchase.NewService(service.DB).BatchSpecMatch(ctx, purchase.BatchSpecMatchRequest{
    SYBProductIDs: linked.SYBProductIDs,
})

BatchSpecMatch 遍历的是 SYB 明细,只匹配当前明细需要的值。同步补进档案的值没有对应明细,因此不会被匹配。

后果

等这些颜色的订单真来了,仍然是 color_mapping,还得人工点一次匹配——正是 #290 想消除的动作。其中 黑色 → 黑色-冰块猫 是唯一对应、完全可以自动匹上的,白白错过。

本地任务 157 的实测:同步后档案 16 色 6 码,但只有 1 色 1 码有映射(因为只传了 1 条明细)。

方案

规格同步成功后,对该虾皮商品档案中所有未映射的规格值跑一轮匹配,而不是只跑本次明细涉及的值。

非目标

  • [必须] 不自动创建采购。匹配只把明细推到「采购就绪」,创建采购仍由人点击——那是整条链上唯一的人工检查点。
  • 不改 BatchSpecMatch 现有入口的语义(SYB 商品页的批量按钮行为不变)。
  • 不改 #289 的塌缩检测。
  • 失败仍然只记录不冒泡,不得让采集结果提交失败。

依赖

依赖 #291(图搜入口可勾选)才能在界面上验证。

验收

  • 同步补进档案的新规格值会被尝试匹配。
  • 能唯一确定的值(如 黑色 → 黑色-冰块猫)自动匹上。
  • 匹配不上的值明确留空,不猜测、不硬凑。
  • 匹配范围扩大不会覆盖或破坏既有的确认映射。
  • 接口不可用或 AI 失败时,采集结果提交不受影响。

验证

go test ./app/goauto/task/... ./app/goauto/purchase/...;本地以虾皮 1528 复验。

文档影响

规格同步后的匹配范围变化,需更新对应 Wiki 业务规则页面。

> 来源:2026-09-16 本地验证 #290 时发现其验收项未达成。 ## 问题 #290 的验收写的是「商品首次准备好后,其**全部**颜色尺码写入档案并**完成匹配**」。实测: - **写入**达成:虾皮 1528 的颜色从 11 涨到 16,补进 墨綠色、橘色、湖藍色、薑黃色、黑色 - **匹配**未达成:这 5 个新颜色一次都没被尝试匹配 ## 根因 `matchSpecsAfterImageSearch` 把本次明细的 id 传给 `BatchSpecMatch`: ```go service.syncShopeeSpecs(ctx, linked.ShopeeProductID, linked.PDDProductID) purchase.NewService(service.DB).BatchSpecMatch(ctx, purchase.BatchSpecMatchRequest{ SYBProductIDs: linked.SYBProductIDs, }) ``` `BatchSpecMatch` 遍历的是 SYB 明细,只匹配**当前明细需要的值**。同步补进档案的值没有对应明细,因此不会被匹配。 ## 后果 等这些颜色的订单真来了,仍然是 `color_mapping`,还得人工点一次匹配——正是 #290 想消除的动作。其中 `黑色 → 黑色-冰块猫` 是唯一对应、完全可以自动匹上的,白白错过。 本地任务 157 的实测:同步后档案 16 色 6 码,但只有 1 色 1 码有映射(因为只传了 1 条明细)。 ## 方案 规格同步成功后,对该虾皮商品档案中**所有未映射的规格值**跑一轮匹配,而不是只跑本次明细涉及的值。 ## 非目标 - `[必须]` 不自动创建采购。匹配只把明细推到「采购就绪」,创建采购仍由人点击——那是整条链上唯一的人工检查点。 - 不改 `BatchSpecMatch` 现有入口的语义(SYB 商品页的批量按钮行为不变)。 - 不改 #289 的塌缩检测。 - 失败仍然只记录不冒泡,不得让采集结果提交失败。 ## 依赖 依赖 #291(图搜入口可勾选)才能在界面上验证。 ## 验收 - [ ] 同步补进档案的新规格值会被尝试匹配。 - [ ] 能唯一确定的值(如 `黑色 → 黑色-冰块猫`)自动匹上。 - [ ] 匹配不上的值明确留空,不猜测、不硬凑。 - [ ] 匹配范围扩大不会覆盖或破坏既有的确认映射。 - [ ] 接口不可用或 AI 失败时,采集结果提交不受影响。 ## 验证 `go test ./app/goauto/task/... ./app/goauto/purchase/...`;本地以虾皮 1528 复验。 ## 文档影响 规格同步后的匹配范围变化,需更新对应 Wiki 业务规则页面。
Author
Owner

实施

提交 1274161,新增 app/goauto/purchase/archive_spec_match.go。

MatchArchiveSpecs(ctx, shopeeProductID) 对档案里每个未确认映射的值逐个匹配,确定性优先、AI 兜底,由 matchSpecsAfterImageSearch 在 BatchSpecMatch 之后调用。

[必须] 只写映射,不创建采购——人工检查点不变。

逐值匹配没有另一半规格,无法校验完整可售组合,因此加了 archiveValueIsSellable:至少要求该值出现在某个在售 SKU 里。完整组合仍由采购预检把关。没有 SKU 证据时放行,与 aiMatchQualificationForDataset 的既有口径一致。

已验证

TestArchiveValueMustAppearInASellableSKU(5 个子用例,含「颜色值不能拿去顶尺码」)、TestArchiveValuePassesWhenThereIsNoSKUEvidence 通过。task / purchase / shopeeproduct / sybspec / shopeespec 全绿;sybimport 仍为 12 条失败,与 #285 基线一致。

未验证

未在本地环境跑通一次真实的图搜 → 同步 → 全档案匹配。验收点是虾皮 1528 同步补进的 墨綠色 / 橘色 / 湖藍色 / 薑黃色 / 黑色 中,黑色 → 黑色-冰块猫(唯一对应)应当自动匹上。

状态

待验收。

## 实施 提交 `1274161`,新增 `app/goauto/purchase/archive_spec_match.go`。 `MatchArchiveSpecs(ctx, shopeeProductID)` 对档案里每个未确认映射的值逐个匹配,确定性优先、AI 兜底,由 `matchSpecsAfterImageSearch` 在 `BatchSpecMatch` 之后调用。 `[必须]` 只写映射,不创建采购——人工检查点不变。 逐值匹配没有另一半规格,无法校验完整可售组合,因此加了 `archiveValueIsSellable`:至少要求该值出现在某个在售 SKU 里。完整组合仍由采购预检把关。没有 SKU 证据时放行,与 `aiMatchQualificationForDataset` 的既有口径一致。 ## 已验证 `TestArchiveValueMustAppearInASellableSKU`(5 个子用例,含「颜色值不能拿去顶尺码」)、`TestArchiveValuePassesWhenThereIsNoSKUEvidence` 通过。`task` / `purchase` / `shopeeproduct` / `sybspec` / `shopeespec` 全绿;`sybimport` 仍为 12 条失败,与 #285 基线一致。 ## 未验证 未在本地环境跑通一次真实的图搜 → 同步 → 全档案匹配。验收点是虾皮 1528 同步补进的 `墨綠色` / `橘色` / `湖藍色` / `薑黃色` / `黑色` 中,`黑色 → 黑色-冰块猫`(唯一对应)应当自动匹上。 ## 状态 待验收。
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: OPC/goauto#293