fix(server): 规格键消歧——剥离 【...】 会使不同商品塌缩成同一采购键 #301

Open
opened 2026-09-17 09:12:53 +08:00 by ila · 0 comments
Owner

依据 #288 的评估与 2026-09-16 的方案讨论(用户选定处置方式 A)。#289 的塌缩检测已上线并持续拦截,本单解决其根因。

问题

stripBrackets 无差别剥离 【...】,把款式标识和真备注一起扔掉。同一虾皮商品下两个不同商品因此塌缩成同一个采购键:

黑色【短袖】,3XL 【建議62.5-67.5公斤】   →  键 "黑色"
黑色【長袖】,5XL 【建議72.5-77.5公斤】   →  键 "黑色"

【短袖】/【長袖】 是商品本身,不是备注。档案里只有一个 黑色 条目,人工匹配也救不了——键本身是坏的,不是映射缺失。用户实测:26091557JR6ESB 人工匹配成功后仍被 #289 拦下。

线上现状(2026-09-17 实测)

塌缩键                59 个
涉及虾皮商品          45 个
被拦住的 SYB 明细    344 条
其中已建映射的键       7 个    ← 改键后会失效
落在塌缩键上的 order_created   0 笔
order_result_unknown           1 笔(已单独核对,PDD 商品即短袖款,非买错)

[必须] 零成功下单,没有既成的买错事实,因此本单不需要回溯复核历史订单。

方案

只在会产生歧义时保留 【...】。

同一虾皮商品下,若两个不同的原始规格在剥离后塌缩到同一个键,则该组保留括号内容作为键的一部分:

黑色【短袖】  →  键 "黑色【短袖】"
黑色【長袖】  →  键 "黑色【長袖】"
2XL 【建議57.5-62.5公斤】  →  键仍为 "2XL"(不塌缩,行为不变)

[必须] 不塌缩的键行为完全不变。线上 14400 余条 success 明细中绝大多数不受影响,改动面严格限定在 59 个塌缩键。

[必须] 键的消歧需要同一虾皮商品下全部明细的上下文,单条明细无法独立判断。实现必须在能看到兄弟明细的层面完成,并保证新明细导入时同组既有明细的键随之一致,不得出现同组内一半旧键一半新键。

既有数据处置(方案 A)

重新解析受影响明细,键按新规则重算;那 7 个映射失效,由采购员重新匹配。

[必须] 不做映射迁移(方案 B)。旧映射建立在 黑色 这个混同了两个商品的键上,系统内不存在任何信息可判断它属于短袖还是长袖——迁移等于猜测,并把结果标记为 confirmed,正是 #289 要防的静默买错,且盖上确认章。重新匹配时采购员看到 黑色【短袖】/黑色【長袖】 两个独立选项,是在做真实选择。

非目标

  • 不改 #289 的塌缩检测。它是最后一道防线,改键后若仍有塌缩(括号内容也相同的真重复)必须继续拦截。
  • 不改尺码侧的既有归类策略(#274)。
  • 不迁移既有映射。
  • 不回溯已完成的采购任务。
  • 不动 app/goauto/sybimport 的 12 个既有失败用例(#285)。

风险

  • 键定义变化会使既有映射查不到。已量化为 7 个,可接受。
  • #290 的虾皮完整规格同步同样按剥离后的键写入档案,必须与新规则保持同一套逻辑,否则档案键与明细键错开、映射全部落空。

验收

  • 黑色【短袖】 与 黑色【長袖】 成为两个独立的采购键,各自可建映射。
  • 26091557JR6ESB 在重新匹配后可创建采购。
  • 不塌缩的键取值与行为完全不变(回归)。
  • 同一虾皮商品下新导入明细与既有明细的键保持一致。
  • 规格同步(#290)写入档案的键与明细键一致。
  • #289 的检测仍对真重复生效。

验证

go test ./app/goauto/sybspec/... ./app/goauto/sybimport/... ./app/goauto/purchase/... ./app/goauto/task/...;线上以 45 个受影响商品抽样复核。

文档影响

采购键定义变化,需更新业务规则与规格解析相关 Wiki 页面。

> 依据 #288 的评估与 2026-09-16 的方案讨论(用户选定处置方式 A)。#289 的塌缩检测已上线并持续拦截,本单解决其根因。 ## 问题 `stripBrackets` 无差别剥离 `【...】`,把款式标识和真备注一起扔掉。同一虾皮商品下两个不同商品因此塌缩成同一个采购键: ``` 黑色【短袖】,3XL 【建議62.5-67.5公斤】 → 键 "黑色" 黑色【長袖】,5XL 【建議72.5-77.5公斤】 → 键 "黑色" ``` `【短袖】`/`【長袖】` 是商品本身,不是备注。档案里只有一个 `黑色` 条目,人工匹配也救不了——**键本身是坏的**,不是映射缺失。用户实测:`26091557JR6ESB` 人工匹配成功后仍被 #289 拦下。 ## 线上现状(2026-09-17 实测) ``` 塌缩键 59 个 涉及虾皮商品 45 个 被拦住的 SYB 明细 344 条 其中已建映射的键 7 个 ← 改键后会失效 落在塌缩键上的 order_created 0 笔 order_result_unknown 1 笔(已单独核对,PDD 商品即短袖款,非买错) ``` `[必须]` **零成功下单**,没有既成的买错事实,因此本单不需要回溯复核历史订单。 ## 方案 **只在会产生歧义时保留 `【...】`。** 同一虾皮商品下,若两个不同的原始规格在剥离后塌缩到同一个键,则该组保留括号内容作为键的一部分: ``` 黑色【短袖】 → 键 "黑色【短袖】" 黑色【長袖】 → 键 "黑色【長袖】" 2XL 【建議57.5-62.5公斤】 → 键仍为 "2XL"(不塌缩,行为不变) ``` `[必须]` 不塌缩的键行为**完全不变**。线上 14400 余条 success 明细中绝大多数不受影响,改动面严格限定在 59 个塌缩键。 `[必须]` 键的消歧需要同一虾皮商品下全部明细的上下文,单条明细无法独立判断。实现必须在能看到兄弟明细的层面完成,并保证新明细导入时同组既有明细的键随之一致,不得出现同组内一半旧键一半新键。 ## 既有数据处置(方案 A) 重新解析受影响明细,键按新规则重算;那 7 个映射失效,由采购员重新匹配。 `[必须]` 不做映射迁移(方案 B)。旧映射建立在 `黑色` 这个混同了两个商品的键上,系统内**不存在**任何信息可判断它属于短袖还是长袖——迁移等于猜测,并把结果标记为 `confirmed`,正是 #289 要防的静默买错,且盖上确认章。重新匹配时采购员看到 `黑色【短袖】`/`黑色【長袖】` 两个独立选项,是在做真实选择。 ## 非目标 - 不改 #289 的塌缩检测。它是最后一道防线,改键后若仍有塌缩(括号内容也相同的真重复)必须继续拦截。 - 不改尺码侧的既有归类策略(#274)。 - 不迁移既有映射。 - 不回溯已完成的采购任务。 - 不动 `app/goauto/sybimport` 的 12 个既有失败用例(#285)。 ## 风险 - 键定义变化会使既有映射查不到。已量化为 7 个,可接受。 - #290 的虾皮完整规格同步同样按剥离后的键写入档案,必须与新规则保持同一套逻辑,否则档案键与明细键错开、映射全部落空。 ## 验收 - [ ] `黑色【短袖】` 与 `黑色【長袖】` 成为两个独立的采购键,各自可建映射。 - [ ] `26091557JR6ESB` 在重新匹配后可创建采购。 - [ ] 不塌缩的键取值与行为完全不变(回归)。 - [ ] 同一虾皮商品下新导入明细与既有明细的键保持一致。 - [ ] 规格同步(#290)写入档案的键与明细键一致。 - [ ] #289 的检测仍对真重复生效。 ## 验证 `go test ./app/goauto/sybspec/... ./app/goauto/sybimport/... ./app/goauto/purchase/... ./app/goauto/task/...`;线上以 45 个受影响商品抽样复核。 ## 文档影响 采购键定义变化,需更新业务规则与规格解析相关 Wiki 页面。
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: OPC/goauto#301