vr-shopxo-plugin/plan.md

128 lines
6.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# vr-shopxo-plugin Issue #9 — 架构决策评议计划
> 版本v1.0 | 日期2026-04-15 | Agentcouncil/FrontendDev主笔
## 任务背景
Phase 0/1/2 已完成骨架,但暴露了 P0 架构问题:当前商品 112 的 spec_base 表为空broken statespec_base_id_map 中的 ID 在 DB 不存在ShopXO 原生防超卖机制完全未启用。需要评议方案 A vs B 并给出明确推荐。
---
## 核心问题4问
### Q1: 方案 A 的后台批量生成 SKU 路径是否可行?
- 具体实现方式ShopXO 是否有批量创建 SKU 的 API/代码路径?
- 前端uni-app如何配合
### Q2: 当前商品 112 的 broken 状态需要立即修复吗?最小修复集是什么?
- `is_exist_many_spec=0` + `spec_base` 空的根因是什么?
- 最小修复:不改 spec_base 表,仅改 `is_exist_many_spec` flag还是重建 SKU
### Q3: $vr- 前缀方案是否有隐患?
- ShopXO 内部逻辑是否对带 `$` 的 spec name 做特殊处理?
- spec_value 的 name/label 字段是否允许 `$` 字符?
### Q4: 方案 A vs 方案 B 的最终推荐
- 考虑:实现成本、安全性(防超卖)、可维护性、多 Zone 混买体验
---
## 阶段划分
| 阶段 | 内容 | 负责 |
|------|------|------|
| **Round 1**(本轮)| 分析 4 个问题,建立共识框架,输出推荐 | FrontendDev + BackendArchitect + SecurityEngineer 独立输出 |
| **Round 2** | 交叉评审其他成员的分析,补充或反驳 | 所有成员 |
| **Round 3** | 最终报告合并,输出 `council-output/ARCHITECTURE_DECISION.md` | FrontendDev 主笔 |
---
## 任务清单
- [ ] **Task FD-1**: FrontendDev — 分析 Q1-Q4输出推荐plan.md 本文件)
- [ ] **Task FD-2**: FrontendDev — 评审 BackendArchitect / SecurityEngineer 的分析
- [ ] **Task FD-3**: FrontendDev — 撰写最终报告 `council-output/ARCHITECTURE_DECISION.md`
- [ ] **Task FD-4**: FrontendDev — 更新 plan.md 和 ARCHITECTURE.md合并到 main
---
## 依赖关系
- BackendArchitect 输出后端视角ShopXO spec_base 机制、批量生成可能性)
- SecurityEngineer 输出安全视角($vr- 前缀风险、防超卖方案安全性)
- FrontendDev 输出前端视角(多 Zone 混买 UX、$vr- 前端处理)
- 三方分析完成后,合并为最终报告
---
## 行动项FrontendDev Round 1 输出)
### Q1 分析:方案 A 批量生成 SKU 路径
**结论:可行,但实现路径复杂。**
ShopXO spec_base 生成机制:
- 商品保存时,`GoodsService::Save()` 调用 `SpecService::Save()` 逐条写入 `sxo_goods_spec_base`
- **没有现成的批量 API** — 需要在插件初始化/商品绑定时,批量调用 `SpecService` 或直接 SQL INSERT
- 方案 A 的 SKU 数量 = 座位数(一场演唱会可能 10000+ 个座位)
- **前端配合**uni-app 需要维护 `seat_id → spec_base_id` 映射(已在 `spec_base_id_map` 中)
- **关键风险**:商品规格管理页面会显示 10000+ 行 SKU可能导致 ShopXO 后台崩溃
- **解决方向**:插件专用规格不出现在 ShopXO 原生规格管理页,通过 Hook 隐藏;建立独立的"座位 SKU 管理"页面
### Q2 分析:商品 112 broken state 最小修复集
**结论:需要立即修复,推荐最小方案。**
根因:`is_exist_many_spec=0` 意味着 ShopXO 认为此商品无多规格spec_base 表自然为空(从未生成过 SKU
最小修复路径(不破坏现有数据):
1. 方案甲(最小侵入):在 `plugins_service_goods_save_end` Hook 中,检测商品有 `venue_data``$vr-` spec 存在时,强制将 `is_exist_many_spec` 设为 1但不写 spec_base 表(绕过 ShopXO spec 机制,完全走插件自定义逻辑)
2. 方案乙(规范做法):调用 `SpecService::Save()` 为每个座位生成一条 spec_base 记录inventory=1, price 从 seat_type 读取)
**推荐方案甲**(最小修复):
- 优势:无需重建 SKU不影响现有订单数据
- 代价:`is_exist_many_spec` 变成"脏 flag",但这是 ShopXO 的内部状态,插件不依赖它做业务
- 操作:一条 UPDATE + 一条 Hook 注入
### Q3 分析:$vr- 前缀隐患
**结论:低风险,但需实测确认。**
ShopXO spec name 字段无字符过滤,数据库 `varchar` 类型允许 `$` 字符。潜在风险点:
- ThinkPHP 的 `__isset()` / 动态属性访问可能对 `$` 敏感(但 spec name 存 DB 而非 PHP 属性,低风险)
- 前端模板渲染时,`$vr-` 字符串可能触发 Vue/JS 的变量插值解析(`{{ $vr-场馆 }}`)—— **这是真实风险**
- ShopXO 原生规格管理页面可能将 `$` 视为特殊字符处理
**需要验证**uni-app 端 spec value 的渲染方式(是纯文本还是模板字符串?)
### Q4 最终推荐:方案 A vs 方案 B
**推荐:方案 A每个座位一个 SPEC/SKU**
理由:
1. **安全性**ShopXO 原生原子扣库存防超卖,经过大量生产验证;方案 B 的自建 FOR UPDATE 锁在高并发下有死锁风险
2. **数据一致性**:方案 A 的 stock = 1ShopXO 购买流程自带事务保护;方案 B 的 Zone stock 需要插件自己维护一致性和并发安全
3. **多 Zone 混买**:方案 A 前端每 Zone 一个 goods_params 行,后端按 seat_id 原子购买,体验流畅;方案 B 前端分组但后端共享 Zone stock反而增加了前端分组逻辑的复杂度与我们"多 Zone 混买前端分组"的初衷不符)
4. **维护性**:方案 A 依赖 ShopXO 原生机制,故障排查有据可查;方案 B 是"黑盒",出问题只能靠插件自己
5. **$vr- 前缀**spec_base_id_map 的 key 可以是 seat_id无需改 ShopXO spec name 存储
**方案 B 的唯一优势**SKU 数量少Zone 数量 vs 座位数量),后台管理简单。但这个优势在演唱会 10000 座场景下不如安全和一致性重要。
---
## 行动项(优先级排序)
1. **【P0】紧急修复商品 112 broken state**Hook 注入 `is_exist_many_spec=1`,使插件能正常识别票务商品(推荐方案甲,最小侵入)
2. **【P1】实现方案 A 批量 SKU 生成**:在 `SeatTemplateService::BindToGoods()` 中,座位模板绑定商品时,批量 INSERT spec_base 记录inventory=1, price 从 seat_type 读取)
3. **【P2】隔离 ShopXO 规格管理页面**Hook 隐藏票务商品的原生规格列表,建立独立座位 SKU 管理视图
---
## 共识投票
[CONSENSUS: NO] — 本轮仅完成分析,执行待后续阶段
---
*Round 1 完成,输出存档。等待 BackendArchitect 和 SecurityEngineer 的分析结果。*