# Phase 2 — 计划与当前状态

> 版本：v3.0 | 日期：2026-04-20 | 状态：实现准备就绪
> 关联 Issue：#13
> 关联文档：`docs/VR_GOODS_CONFIG_SPEC.md`（v3.0 JSON 格式，已确认）

---

## ⚠️ v3.0 核心变更摘要

- 新增 `template_snapshot` 字段（发布时从 `vr_seat_templates.seat_map` 读取并存储）
- `selected_sections` 保持对象格式 `{ room_id: ["A","B"] }`
- `spec_base_id_map` 不入库，GetGoodsViewData 从 `goods_spec_base.extends->seat_key` 动态构建
- 现有前端编辑体验**完全不受影响**（前端只提交选择项）

完整规格见 `docs/VR_GOODS_CONFIG_SPEC.md`。

---

## 一、vr_goods_config v3.0 结构（已确认）

```json
{
  "version": 3.0,
  "template_id": 4,
  "selected_rooms": ["room_id_xxx"],
  "selected_sections": { "room_id_xxx": ["A", "B"] },
  "sessions": [{ "start": "15:00", "end": "16:59" }],
  "template_snapshot": {
    "venue": { ... },
    "rooms": [{ "id": "...", "name": "...", "map": [...], "sections": [...], "seats": {...} }]
  }
}
```

详细字段说明见 `docs/VR_GOODS_CONFIG_SPEC.md` 第一章。

---

## 二、实现顺序（Issue #13）

### Step 1：AdminGoodsSaveHandle — 保存时填充 template_snapshot

在 `save_thing_end` 时机，BatchGenerate 之前：
1. 用 `template_id` 读取 `vr_seat_templates.seat_map`（最新数据）
2. 按 `selected_rooms` 过滤（只存用户选中的房间）
3. 填充 `config.template_snapshot`

### Step 2：BatchGenerate — 写入 extends

insertGetId 中加入 `extends.seat_key = roomId_rowLabel_colNum`

### Step 3：GetGoodsViewData — 重写

- 读 `vr_goods_config[0]`，透传 `template_snapshot`
- 从 `goods_spec_base.extends` 动态构建 `spec_base_id_map`
- `selected_sections` 适配对象格式
- `goods_spec_data` 按场次聚合

### Step 4：ticket_detail.html JS — seatKey 格式

```javascript
// 改为带 roomId：
var seatKey = seat.roomId + '_' + seat.rowLabel + '_' + seat.colNum;
var specBaseId = self.specBaseIdMap[seatKey] || 0;
```

---

## 三、Phase 2 当前状态

| 任务 | 状态 |
|------|------|
| 模板渲染 | ✅ 正常 |
| 票务 footer | ✅ 已精简 |
| Task 1: C端票夹 | ✅ 完成（2026-04-24，票夹页面 + API + 返回按钮，详见 Issue #21） |
| Issue #13 实现（v3.0 落地） | ⚠️ 待动手 |
| B端核销 API + 页面 | ⏳ 开发中 |
| 后台 4 控制器联调 | ❌ 未开始 |
