5.0 KiB
5.0 KiB
甲方新需求文档(2026-04-15)
来源
2026-04-15 下午,甲方补充需求,已与大头确认。
需求内容
需求 1:多座位单订单
一个订单可包含多个座位,每个座位生成独立核销码。
技术要求:
- 每个座位 = 一个 ShopXO SKU(spec_base_id),stock=1
- 一次购买多个不同座位 = 多个 goods_params 条目(同一 goods_id + 不同 spec_base_id)
- ShopXO 原生支持多 spec_base_id 同单购买,各生成独立 order_goods 行 ✅
需求 2:核销码卡夹展示(订单详情页)
订单详情展示多个 QR 核销码,交互如下:
- 手动滑切换(类似轮播,但手动)
- 每个 QR 独立状态:已核销 → 灰掉
- 自动切换到下一张未核销的 QR
- 买了 N 个座位 → 显示 N 个 QR
技术要求:
- 多行
order_goods→ 多张vr_ticketsQR - 前端轮播组件(uni-app)
- Realtime 订阅:核销状态变更 → 前端自动更新
需求 3:商品级必填信息配置
商品 ext 字段声明购买时用户需填写的必填信息。
字段设计(建议):
{
"required_fields": ["id_card", "phone"],
"field_labels": {
"id_card": "身份证号",
"phone": "手机号"
}
}
逻辑:
ext为空 → 下单不弹窗,直接购买ext有内容 → 弹窗要求填写,填写后附在订单备注
需求 4:手机号自动填充(订单级)
- 默认自动填微信认证手机号(wx.getPhoneNumber),可编辑
- 手机号是购买凭据(售后定位用)
- 同一订单多个座位/核销码 → 只需填一份联系信息(订单级,非座位级)
ShopXO 多 Spec_base_id 同单购买验证
源码分析结论
问题:ShopXO 能否在同一次购买中,用同一个 goods_id + 不同 spec_base_id,各买 1 个?
结论:✅ 支持
源码证据
BuyService.php 关键路径:
goods_params = [
{ goods_id: 112, spec_base_id: 1001, stock: 1 }, ← 座位A1
{ goods_id: 112, spec_base_id: 1002, stock: 1 } ← 座位B2
]
- BuyGoods():
foreach($params['goods_data'] as $v)→ 每个 goods_params 条目 → 一个$data[]元素 - OrderSplitService::Run():按 warehouse 分组(非 goods_id 合并)→ 不同 spec_base_id 保留为不同 goods_items[]
- OrderInsert():
foreach($v['goods_items'] as $vs)→ 每个 goods_items 条目 → 一行 order_goods
// BuyService.php:786
foreach($v['goods_items'] as $vs)
{
$order['detail_data'][] = [
'goods_id' => $vs['goods_id'],
'price' => $vs['price'],
'buy_number' => intval($vs['stock']), // = 1
// ...
];
}
结果:
- goods_id=112, spec_base_id=1001 → order_goods 第1行(座位A1)
- goods_id=112, spec_base_id=1002 → order_goods 第2行(座位B2)
- 两个座位,同一订单,各生成独立 vr_tickets QR ✅
与需求对应关系
| 甲方需求 | 技术实现 | 状态 |
|---|---|---|
| 多座位单订单 | 每座位 = 独立 spec_base_id,stock=1 | ✅ |
| 多核销码 | 多行 order_goods → 多张 vr_tickets QR | ✅ |
| ext 必填字段 | extension_data.required_fields | ✅ |
| 手机号订单级 | 联系信息挂 order 备注,非 goods_params | ✅ |
当前数据库状态(已验证)
-- 商品 112 票务商品
is_exist_many_spec = 0 -- ShopXO 认为无多规格
spec_base 表 = 空的 -- 没有任何 SKU
-- vr_seat_templates.spec_base_id_map
-- {"A": 1001, "B": 1002, "C": 1003} ← 这些 ID 在 DB 里不存在!
问题:ShopXO 防超卖机制完全未启用,购买走裸商品逻辑。
spec_value 绑定方案($vr- 前缀)
方案已确认
ShopXO spec name 允许特殊字符($,-,中文),无字符过滤。
插件专用规格命名
$vr-场馆 → 场馆名称(如 $vr-场馆 = "鸟巢")
$vr-分区 → 座位分区(Zone)
$vr-时段 → 场次时间
为什么不会与用户规格冲突
- 插件票务商品使用自定义模板
ticket_detail.html - 前端 UI 不走 ShopXO 默认规格选择器
- 用户无法通过默认界面触碰到
$vr-规格
方案 A(每个座位一个 SPEC)兼容性
结论:方案 A 完全兼容甲方全部 4 项新需求
| 需求 | 方案 A 如何满足 |
|---|---|
| 多座位单订单 | 每座位 = SKU,ShopXO 原生支持多 SKU 同单 ✅ |
| 核销码卡夹 | order_goods × N → vr_tickets × N → N 张 QR ✅ |
| ext 必填字段 | goods.extension_data.required_fields ✅ |
| 手机号订单级 | 联系信息不写在 goods_params,写在 order 备注 ✅ |
待办事项
- Issue #9:方案 A vs B 最终决策
- 紧急修复:is_exist_many_spec → 1 + 正确生成每个座位的 SKU
- 后台批量创建 SKU 实现(方案 A 关键路径)
- ext.required_fields 前端弹窗实现
- 订单详情核销码卡夹组件
- 微信手机号自动填充 API 集成