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 pendingrefactor/vr-ticket-20260416
parent
098bcfe780
commit
829564b019
|
|
@ -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 方向)
|
||||||
Loading…
Reference in New Issue