# Goods.php 票务模板替换修改

> ⚡ 核心原则：怎么快怎么来。改核心文件是允许的。
> 适用范围：ShopXO v6.8.0，文件：`app/index/controller/Goods.php`

---

## 修改位置

文件：`{SHOPXO_ROOT}/app/index/controller/Goods.php`
方法：`Index()`（商品详情页主方法）
位置：在 `return MyView();` 之前插入判断逻辑

---

## 修改内容

### 1. 在方法开头加载票务插件数据（可选，用于传递 venue_data 给模板）

在 `$assign` 数组构建部分（约 line 110-130），在 `MyViewAssign($assign);` 之前加入：

```php
// === VR票务插件：注入票务数据到模板 ===
// 票务商品（item_type=ticket 或 venue_data 非空）注入座位图数据
if (!empty($goods['venue_data']) || (isset($goods['item_type']) && $goods['item_type'] == 'ticket')) {
    // 加载 vr_seat_templates 中的座位图配置
    $category_id = $goods['category_id'] ?? 0;
    if ($category_id > 0) {
        $seat_template = Db::name('plugins_vr_seat_templates')
            ->where('category_id', $category_id)
            ->where('status', 1)
            ->find();
        if (!empty($seat_template)) {
            $assign['vr_seat_template'] = $seat_template;
            $assign['vr_is_ticket_goods'] = 1;
        }
    }
}
// === VR票务插件 END ===
```

### 2. 在 `return MyView();` 之前加入模板判断（约 line 437-440）

找到：
```php
// 商品详情
$assign = array_merge($assign, GetGoodsDetails($goods_id, $params));
MyViewAssign($assign);
return MyView();
```

替换为：
```php
// 商品详情
$assign = array_merge($assign, GetGoodsDetails($goods_id, $params));
MyViewAssign($assign);

// === VR票务插件：票务商品使用独立模板 ===
// 判断依据：venue_data 非空 或 item_type == 'ticket'
$is_ticket = false;
if (!empty($assign['goods']['venue_data']) || !empty($assign['goods']['item_type'])) {
    $is_ticket = ($assign['goods']['item_type'] ?? '') === 'ticket'
        || !empty($assign['goods']['venue_data']);
}
if (!empty($is_ticket) && !empty($assign['vr_is_ticket_goods'])) {
    return MyView('/../../../plugins/vr_ticket/view/goods/ticket_detail');
}
// === VR票务插件 END ===

return MyView();
```

---

## 新建票务模板文件

路径：`{SHOPXO_ROOT}/app/plugins/vr_ticket/view/goods/ticket_detail.html`

参考 `app/index/view/default/goods/detail.html`，重写以下部分：

1. **隐藏**标准规格选择器（`.goods-detail-spec`）
2. **隐藏**原价/现价区域（`.goods-detail-panel-price`）
3. **隐藏**购物车/立即购买按钮（`.goods-detail-buy-nav`）
4. **注入**票务选座 UI（使用 `$vr_seat_template.seat_map` 数据）
5. **保留**商品相册、商品详情 tab、商品参数 tab

---

## 升级 ShopXO 后的重应用步骤

当升级 ShopXO 后，此修改需要重新应用：

1. 下载新版本 ShopXO
2. 对比旧版本 `app/index/controller/Goods.php` 和新版本，找到 `return MyView();` 的位置
3. 重新应用上述修改
4. 模板文件 `ticket_detail.html` 不受影响（独立文件）

建议：将此修改内容写入 `docs/GOODS_PHP_MODIFICATION.md`，升级前对照检查。

---

## 为什么不只用 Hook？

Hook 方案（`plugins_view_goods_detail_base_sku_top` 注入）的缺点：
- 仍需加载完整标准模板（CSS/JS 全部加载）
- 需要 CSS 选择器隐藏标准元素（脆弱，ShopXO 升级后选择器可能失效）
- 注入位置固定，不够灵活

改 Goods.php 方案的优点：
- 1 行判断，模板完全自控
- 零无用 CSS/JS 加载
- 性能更好

---

## 备选方案：纯 Hook（ShopXO 升级时不需重应用）

如果不修改 Goods.php，可用 Hook 方案（但需接受上述缺点）：

```php
// config.json hook 注册
"hook": {
    "plugins_view_goods_detail_base_sku_top": [
        "\\app\\plugins\\vr_ticket\\view\\Goods::InjectTicketUI"
    ],
    "plugins_service_goods_data": [
        "\\app\\plugins\\vr_ticket\\service\\GoodsService::InjectVenueData"
    ]
}
```
