docs: add guiding principle + Goods.php modification guide
核心原则:怎么快怎么来,怎么方便怎么来,少改动少复杂度,完全允许改核心 - README.md: 写入核心原则,更新技术发现,标注 Goods.php 方案为推荐 - docs/GOODS_PHP_MODIFICATION.md: 票务模板替换的具体修改步骤(Phase 2 关键文档)refactor/vr-ticket-20260416
parent
1c6d32b4c1
commit
d5edb76f33
58
README.md
58
README.md
|
|
@ -2,19 +2,33 @@
|
|||
|
||||
> 基于 ShopXO 生态的 VR 演唱会票务解决方案(Plan B)
|
||||
|
||||
---
|
||||
|
||||
## ⚡ 核心原则
|
||||
|
||||
**怎么快怎么来。怎么方便怎么来。尽可能少改动,少引入复杂度。但完全允许修改 ShopXO 核心代码。**
|
||||
|
||||
- 我们是自己部署 ShopXO,核心代码完全可以改
|
||||
- 改动的优先级:改核心 < 用 Hook < 引入新复杂度
|
||||
- 改核心文件时,写清楚「升级 ShopXO 后需重新应用的位置」
|
||||
|
||||
---
|
||||
|
||||
## 核心能力
|
||||
|
||||
| 能力 | 实现方式 |
|
||||
|---|---|
|
||||
| 场次管理 | 插件独立表 `vr_events` / `vr_sessions` |
|
||||
| 商品详情页定制 | 30+ 钩子注入,或 1 行控制器代码替换模板 |
|
||||
| 场次管理 | ShopXO spec = 场次(无需独立表) |
|
||||
| 商品详情页定制 | **改 `Goods.php` 1 行** + 自定义模板 |
|
||||
| 选座 UI | 自定义 Vue 组件,Fork shopxo-uniapp |
|
||||
| 观演人收集 | 插件钩子收集,下单时写入 `vr_tickets` 表 |
|
||||
| QR 电子票 | ShopXO 内置 `\base\Qrcode` + phpqrcode |
|
||||
| 观演人收集 | 插件钩子,下单时写入 `vr_tickets` 表 |
|
||||
| QR 电子票 | 支付成功后钩子生成,AES 加密 |
|
||||
| 微信小程序 | shopxo-uniapp 已支持,HBuilderX 一键发行 |
|
||||
| B 端核销 | Fork `realstore/check/check.vue`,完整参考 |
|
||||
| 会员/积分/优惠券 | 全部复用 ShopXO 内置能力 |
|
||||
|
||||
---
|
||||
|
||||
## 快速开始
|
||||
|
||||
```bash
|
||||
|
|
@ -22,21 +36,30 @@
|
|||
git clone http://xmhome.ow-my.com:3000/sileya-ai/vr-shopxo-plugin.git
|
||||
|
||||
# 2. 上传插件到 ShopXO
|
||||
cp -r vr-shopxo-plugin/app/plugins/vr_ticket /path/to/shopxo/app/plugins/
|
||||
cp -r vr_ticket /path/to/shopxo/app/plugins/
|
||||
|
||||
# 3. 数据库迁移
|
||||
# 访问 /admin/plugins/vr_ticket/migrate 或手动执行 SQL
|
||||
# 3. 数据库迁移(Phase 1)
|
||||
mysql -u root -p < database/migrations/001_vr_seat_templates.sql
|
||||
mysql -u root -p < database/migrations/002_vr_tickets.sql
|
||||
mysql -u root -p < database/migrations/003_vr_verifiers.sql
|
||||
mysql -u root -p < database/migrations/004_vr_verifications.sql
|
||||
|
||||
# 4. 后台安装
|
||||
# 管理后台 → 应用中心 → 插件管理 → 安装 VR票务插件
|
||||
|
||||
# 5. shopxo-uniapp 改造
|
||||
# 5. 修改 Goods.php(Phase 2)
|
||||
# 在 ShopXO 源码 app/index/controller/Goods.php 的 Index() 方法中:
|
||||
# 在 return MyView(); 之前加入 ticket 类型判断(见 docs/GOODS_PHP_MODIFICATION.md)
|
||||
|
||||
# 6. shopxo-uniapp 改造
|
||||
# HBuilderX 导入 shopxo-uniapp
|
||||
# 添加 pages/ticket-buy/ 和 pages/ticket-verify/
|
||||
# 配置 manifest.json 的 AppID
|
||||
# 发行 → 微信小程序
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 官方文档(开发前必查)
|
||||
|
||||
| 资源 | URL |
|
||||
|
|
@ -46,22 +69,27 @@ cp -r vr-shopxo-plugin/app/plugins/vr_ticket /path/to/shopxo/app/plugins/
|
|||
| **开发文档索引** | https://doc.shopxo.net/article/4.html |
|
||||
| uniapp 打包教程 | https://doc.shopxo.net/article/1/293727233598554112.html |
|
||||
| shopxo-uniapp Gitee | https://gitee.com/zongzhige/shopxo-uniapp |
|
||||
| 完整官方文档索引 | [docs/OFFICIAL_DOCS.md](docs/OFFICIAL_DOCS.md) |
|
||||
|
||||
## 技术调研文档
|
||||
|
||||
- [ShopXO 技术能力调研](docs/01_SHOPXO_TECHNICAL_RESEARCH.md) — DIY/CustomView/钩子/插件完整分析
|
||||
- [uni-app 前端定制](docs/02_FRONTEND_CUSTOMIZATION.md) — 小程序编译与自定义组件
|
||||
- [核销系统设计](docs/03_VERIFICATION_SYSTEM.md) — QR 生成/核销 API/票夹
|
||||
- [实施路线图](docs/04_IMPLEMENTATION_ROADMAP.md) — Agent 分工与开发计划
|
||||
- [docs/01_SHOPXO_TECHNICAL_RESEARCH.md](docs/01_SHOPXO_TECHNICAL_RESEARCH.md) — ShopXO 技术能力调研
|
||||
- [docs/02_FRONTEND_CUSTOMIZATION.md](docs/02_FRONTEND_CUSTOMIZATION.md) — uni-app 前端定制
|
||||
- [docs/03_VERIFICATION_SYSTEM.md](docs/03_VERIFICATION_SYSTEM.md) — 核销系统设计
|
||||
- [docs/04_IMPLEMENTATION_ROADMAP.md](docs/04_IMPLEMENTATION_ROADMAP.md) — 实施路线图
|
||||
- [docs/07_SHOPXO_PLUGIN_MECHANISM.md](docs/07_SHOPXO_PLUGIN_MECHANISM.md) — 插件开发机制
|
||||
- [docs/08_SHOPXO_REQUIREMENTS_MAPPING.md](docs/08_SHOPXO_REQUIREMENTS_MAPPING.md) — 票务需求 → ShopXO 机制映射
|
||||
- [docs/09_SHOPXO_HOOKS_REFERENCE.md](docs/09_SHOPXO_HOOKS_REFERENCE.md) — ShopXO 全部钩子清单(从源码提取)
|
||||
|
||||
## 关键发现(2026-04-14)
|
||||
## 关键发现(2026-04-14/15)
|
||||
|
||||
- ✅ ShopXO 内置 **CustomView Ace 编辑器**(全代码自定义页面)
|
||||
- ✅ 商品详情页 **30+ 插件钩子**,最佳注入点 `plugins_view_goods_detail_base_sku_top`
|
||||
- ✅ 商品详情页 **30+ 插件钩子**
|
||||
- ✅ shopxo-uniapp **已支持微信小程序**,条件编译已配置
|
||||
- ✅ ShopXO 内置 **phpqrcode** QR 码生成库
|
||||
- ✅ `realstore/check/check.vue` 是 **B 端核销页最佳参考**
|
||||
- ✅ `site_type=3`(虚拟商品)可绕过地址选择弹出
|
||||
- ✅ ShopXO 完全支持修改核心代码(自己部署原则)
|
||||
- ✅ **推荐:改 Goods.php 1 行**,比 Hook 方案更干净(符合核心原则)
|
||||
|
||||
## 项目状态
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,130 @@
|
|||
# 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('/goods/ticket_detail');
|
||||
}
|
||||
// === VR票务插件 END ===
|
||||
|
||||
return MyView();
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 新建票务模板文件
|
||||
|
||||
路径:`{SHOPXO_ROOT}/app/index/view/default/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"
|
||||
]
|
||||
}
|
||||
```
|
||||
Loading…
Reference in New Issue