vr-shopxo-plugin/docs/HANDOFF_TREE_API.md

97 lines
3.1 KiB
Markdown
Raw Permalink Normal View History

# 任务交接简报VR Tree API 实现
> 创建时间2026-05-15
> 负责人:西莉雅(统筹),大头(产品决策)
---
## 目标
实现新 API `/api/goods/tree`,解决当前前端 O(n²) 重建层级的问题,同时消除座位模板数据冗余。
---
## 核心设计
### 扁平数据 + 查询管理器
```
扁平 SKUspec_key 索引)
→ 查询管理器(按 group_by 聚合)
→ 层级树(叶节点含 template_key+ 模板去重池 + 扁平 SKU 列表
→ 缓存TTL=60s
→ API 返回
```
### 模板去重原则
同一 `venue + room + section` 的座位图模板在所有场次下共享,只存一份,不按 session 重复。
### 前端交互(全程零额外 API 调用)
```
初始加载GET /api/goods/tree → tree + seat_templates_flat + flat_inventory
用户选座venue → session → room → section → 查 template_key → 查模板 → 渲染座位图
spec_key 前缀匹配:前端在 flat_inventory 里本地过滤
```
---
## 关键文件
| 文件 | 作用 |
|------|------|
| `docs/14_TREE_API_DESIGN.md` | 完整设计文档(必读) |
| `docs/TASK_TREE_API_IMPLEMENTATION.md` | 实施任务清单(执行依据) |
| `docs/15_FLAT_INVENTORY_QUERY_MANAGER.md` | 方案对比与决策记录 |
| `service/SeatSkuService.php` | 数据源(复用,不改) |
| `service/SeatMapService.php` | 数据源(复用,不改) |
| `api/Goods.php` | 新增 `tree()` 接口 |
---
## 技术要点
1. **spec_key 格式**`$vr-场次=X|$vr-场馆=X|$vr-演播室=X|$vr-分区=X|$vr-座位号=X`(固定顺序,`|` 连接)
2. **template_key 格式**`venue_room_section`(由后端生成,前端只引用)
3. **group_by 参数**:前端指定层级顺序,如 `venue,session,room,section`
4. **缓存失效**:订单支付成功后同时清除 tree 缓存
---
## 不需要改动的内容
- `vr_seat_templates` 表结构
- `vr_goods_config` 存储格式
- `SeatSkuService::BatchGenerate()` 逻辑
- 前端选座核心逻辑(只是数据源变了,渲染逻辑不变)
---
## 测试命令
```bash
curl "http://localhost:10000/api.php?s=plugins/index&pluginsname=vr_ticket&pluginscontrol=goods&pluginsaction=tree&goods_id=118&group_by=venue,session,room,section" \
-H "X-Requested-With: XMLHttpRequest"
```
验证:
- `meta.flat_count` > 0SKU 数量)
- `meta.template_count` > 0模板数量<< flat_count
- `tree` 有正确的嵌套层级结构
- `seat_templates_flat` 中每个模板只出现一次
## 已确认的设计决策
| 决策项 | 结论 | 原因 |
|--------|------|------|
| spec_key 排序 | **字母顺序** | 未来扩展新维度时自动融入正确位置,无需修改排序逻辑 |
| tree 层级 | **4层**venue/session/room/section | 座位号第5维保持扁平通过 spec_key 前缀匹配 |
| inventory=0 | **保留** | 已售座位也返回,前端需要知道哪些是已售的 |
---
## 如遇问题
1. **模板去重不生效**:检查 template_key 生成逻辑是否按 venue+room+section 组合
2. **前端匹配失败**:确认前端 spec_key 排序与后端一致(按字母排序)