vr-shopxo-plugin/docs/VR_GOODS_CONFIG_SPEC.md

6.2 KiB
Raw Blame History

vr_goods_config JSON 规格说明

版本v2.0 | 日期2026-04-20 | 状态:已确认,待实现


一、设计原则

  1. 商品发布时快照:用户在后端选择场馆房间后,将完整的房间数据复制一份存入 goods.vr_goods_config。不从 vr_seat_templates 实时读取。
  2. 绝对一致性:修改 vr_seat_templates 不影响已发布的商品。SKUspec_basevr_goods_config 一起过时、一起更新。
  3. 向下兼容:保留 template_id 字段(用于标识来源),但不再用它去查 vr_seat_templates 表。
  4. 单一真相源:前端渲染所需的所有数据(座位图、场次、价格)全部来自 vr_goods_config 的快照,不跨表查询。

二、vr_goods_config JSON 结构

[
  {
    "template_id": 4,
    "selected_rooms": ["room_id_1776341371905"],
    "selected_sections": {
      "room_id_1776341371905": ["A", "B"]
    },
    "rooms": [
      {
        "id": "room_id_1776341371905",
        "name": "1号放映室VV",
        "map": [
          "AAAAB__BBB_BAAAA",
          "AAAAB__BBB_BAAAA",
          "AAAAB__BBB_BAAAA"
        ],
        "sections": [
          { "char": "A", "name": "VIP区",  "price": 100, "color": "#f06292" },
          { "char": "B", "name": "看台区", "price": 50,  "color": "#4fc3f7" }
        ],
        "seats": {
          "A": { "char": "A", "name": "VIP区",  "price": 100, "color": "#f06292" },
          "B": { "char": "B", "name": "看台区", "price": 50,  "color": "#4fc3f7" }
        }
      }
    ],
    "sessions": [
      { "start": "15:00", "end": "16:59" },
      { "start": "18:00", "end": "21:59" }
    ]
  }
]

字段说明

字段 类型 必填 说明
template_id int 来源场馆模板 ID用于溯源不用于查询
selected_rooms string[] 本商品启用的房间 ID 列表
selected_sections object key=房间IDvalue=启用的分区字符列表(如 ["A","B"]
rooms object[] 房间完整数据快照(直接复制自 vr_seat_templates.rooms
sessions object[] 本商品的场次列表

rooms.seats 字段说明

seatssections 的快捷索引key = char(座位字符),格式与 sections 条目相同:

"seats": {
  "A": { "char": "A", "name": "VIP区", "price": 100, "color": "#f06292" },
  "B": { "char": "B", "name": "看台区", "price": 50,  "color": "#4fc3f7" }
}

向下兼容(旧格式迁移)

旧格式(有 vr_seat_templates 表关联逻辑):

{
  "template_id": 4,
  "sessions": [{"start": "...", "end": "..."}]
}

识别方式:rooms 字段不存在 → 降级读取 vr_seat_templates 表。


三、SKU 生成逻辑AdminGoodsSaveHandle Hook

商品保存时,根据 selected_rooms 数组,从 vr_seat_templates.rooms 取出对应房间,展开每个房间的 map 座位,生成 SKU 条目到 goods_spec_base + goods_spec_value

rooms[room_id].map
  └─ 每行字符串(如 "AAAAB__BBB_BAAAA"
       └─ 每个非 _ / - 的字符 → 一个 SKU
            ├─ goods_spec_base.id → 库存主键
            ├─ goods_spec_base.spec_name → "排:row, 座:colNum"
            ├─ goods_spec_base.price → seats[char].price
            └─ goods_spec_base.spec_type → "vrseat:{room_id}:{char}"

spec_base_id_map存到 vr_goods_config 的 rooms[] 中)格式:

{
  "{room_id}_{row}_{colNum}": goods_spec_base.id
}

注:具体 SKU 生成字段名/存储位置待 AdminGoodsSaveHandle 实现时确认。


四、前端渲染数据流

goods.vr_goods_config快照
  └─ [0].rooms[] → 前端 JS rooms[]
  └─ [0].sessions[] → 场次卡片
  └─ [0].selected_sections{} → 控制哪些分区渲染

前端数据结构

// GetGoodsViewData() 注入给模板
{
  vr_seat_template: {
    rooms: [...],        // rooms 快照数组
    sessions: [...],    // 场次列表
    selected_sections: {} // 分区过滤
  },
  goods_spec_data: [...], // 场次规格price 来自 goods_spec_base
  goods_config: { ... }   // 原始 vr_goods_config[0]
}

loadSoldSeats已选座位

vr_tickets 表查询该商品+当前场次已生成的票:

SELECT seat_info FROM vrt_vr_tickets
WHERE goods_id = :goods_id AND verify_status != 1

seat_info 格式:"room_id/rowLabel/colNum"(例:room_id_xxx/A/3


五、GetGoodsViewData() 重写要点

输入goods_id

输出

[
  'vr_seat_template' => [
    'rooms' => [...],              // 来自 vr_goods_config[0].rooms
    'sessions' => [...],           // 来自 vr_goods_config[0].sessions
    'selected_sections' => {...},  // 来自 vr_goods_config[0].selected_sections
  ],
  'goods_spec_data' => [...],      // 场次+价格(用于前端场次卡片)
  'goods_config' => {...}           // 原始 vr_goods_config[0]
]

逻辑

  1. 读取 goods.vr_goods_config JSON
  2. rooms 字段存在 → 直接使用(新格式)
  3. rooms 不存在 → 降级:按旧逻辑查 vr_seat_templates 表(旧格式兼容)
  4. 场次价格从 goods_spec_base 表读取

六、需要更新的文件

文件 操作 说明
SeatSkuService.php 重写 GetGoodsViewData() 新 JSON 格式解析
ticket_detail.html 更新 JS rooms[] 结构渲染 + loadSoldSeats
docs/VR_GOODS_CONFIG_SPEC.md 新建 本文档,记录 JSON 规格
docs/PHASE2_PLAN.md 更新 补充新格式 + 待办
docs/DEVELOPMENT_LOG.md 追加 记录本次 JSON 格式升级

七、已确认的设计决策

  1. 商品发布时快照 vr_seat_templates.roomsgoods.vr_goods_config.rooms
  2. vr_goods_config 包含完整的座位图+sections+seats 数据
  3. 前端不跨表查询,全部数据来自 vr_goods_config 快照
  4. spec_base_id_map 格式:{room_id}_{row}_{colNum}spec_base_id
  5. 座位已售状态:查 vr_tickets.seat_info(格式:room_id/rowLabel/colNum
  6. ⚠️ SKU 生成字段名/存储位置:待 AdminGoodsSaveHandle 实现时确认