From 829564b019ec544f919780060d965b627d695604 Mon Sep 17 00:00:00 2001 From: Council Date: Wed, 15 Apr 2026 18:51:51 +0800 Subject: [PATCH] docs: add SPEC_DESIGN_DECISION - architecture decision log for Issue #9 Records the core finding from P0-2 discussion: - ShopXO SPEC system: multi-dimension cross-product generates SKUs - Original design: each seat = SPEC, stock=1, ShopXO native oversell prevention - Current implementation: zone-level spec_base_id, bypasses ShopXO validation - Two architecture options documented, decision pending --- docs/SPEC_DESIGN_DECISION.md | 89 ++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 docs/SPEC_DESIGN_DECISION.md diff --git a/docs/SPEC_DESIGN_DECISION.md b/docs/SPEC_DESIGN_DECISION.md new file mode 100644 index 0000000..cbc431b --- /dev/null +++ b/docs/SPEC_DESIGN_DECISION.md @@ -0,0 +1,89 @@ +# SPEC 设计方向决策 + +> 创建:2026-04-15 +> 关联 Issue:#9 + +--- + +## 核心发现 + +Phase 0-2 实现与原始设计文档(`docs/06_SEAT_MAP_INTEGRATIONATION.md`)存在架构偏差。 + +--- + +## ShopXO SPEC 机制 + +### 机制说明 +- 商品有**多个 SPEC 维度**(场馆/分区/时段/座位),每个维度有多个 VALUE +- `goods_spec_base` 表:每行 = 一个完整 SKU(spec_base_id = SKU ID),含 inventory + price +- `goods_spec_value` 表:(spec_base_id, value) 对 +- ShopXO 购买流程:`BuyGoods` → `GoodsSpecDetail` → 用 spec 值数组查对应 spec_base_id → 原子扣 inventory + +### 关键代码路径 +``` +BuyService.php:94 GoodsSpecificationsHandle($v) + → 提取 spec 字段({type, value} 对) + → GoodsService.php:2763 GoodsSpecDetail() + → goods_spec_value 表查 spec_base_id + → goods_spec_base 表读 inventory + price +``` + +--- + +## 原始设计(文档) + +`spec_base_id_map` = `{seat_id: {spec_base_id, row, col, price}}` + +- key = 具体座位("1_1" = 第1排第1座) +- spec_base_id = ShopXO 里该座位的完整 SPEC 组合的 SKU ID +- stock = 1(每个座位独立库存) +- 购买:每个座位单独 spec_base_id → ShopXO 原生防超卖 + +--- + +## 当前代码实现 + +`submit()` 发送: +```javascript +{ + spec_base_id: this.sessionSpecId, // ← zone 级别,不是每个座位 + stock: this.selectedSeats.length, // ← 座位总数 + extension_data: { seats: [所有选中座位] } +} +``` + +**问题**: +- spec_base_id 是 zone 级别的,ShopXO 只能检查该 zone 的库存 +- seats[] 里包含所有 Zone 的座位,与 spec_base_id 不匹配 +- 绕过了 ShopXO spec 验证 + +--- + +## 两种方向 + +### 方案 A:每个座位一个 SPEC(原始设计) +- spec_base_id_map:每个座位一个 key,spec_base_id = 该座位在 ShopXO 的 SKU ID +- 后台:批量在 ShopXO 生成 N 个 SPEC(inventory=1) +- submit():按 spec_base_id 分组,每组单独一行 goods_params +- ShopXO 原生防超卖 + +### 方案 B:每个 Zone 一个 SPEC(当前实现) +- spec_base_id_map:每个 Zone 一个 key +- submit():每个 Zone 单独一行 goods_params +- 自建 FOR UPDATE 锁(在 onOrderPaid) +- Zone 间混买需前端分组 + +--- + +## 待确认问题 + +1. **spec_base_id_map 实际存储格式**:Zone 级还是座位级? + - 查 ShopXO 数据库:`SELECT id, goods_id, inventory FROM sxo_goods_spec_base WHERE goods_id = ?` +2. **ShopXO SPEC 数量上限**:5000 座 × 多 Zone × 多时段 = 大量 SPEC,上限? +3. **决策**:选择方案 A 还是 B + +--- + +## 关联 +- Issue #6:P0-2 价格验证(相关) +- Issue #7:M-04 loadSoldSeats 未实现(取决于 SPEC 方向)