vr-shopxo-plugin/docs/DEVELOPMENT_LOG.md

369 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# VR 票务插件开发日志
> vr-shopxo-plugin 项目全量记录
> 仓库http://xmhome.ow-my.com:3000/sileya-ai/vr-shopxo-plugin
> 最后更新2026-04-15
---
## 一、项目背景与决策
### 1.1 需求来源2026-04-13
大头受朋友委托,为其合作伙伴调研轻量级商城小程序解决方案。
**核心需求:**
- 订单:外卖配送 / 包邮 / 自提
- 会员:充值、积分、优惠券
- 约束:无程序员/无前端/无后端,要求直接可用,后期能用 AI 改动,架构清晰,部署简单
**调研结论4 个方案对比):**
| 项目 | Stars | 功能 | 部署 | 会员体系 | AI友好 | 综合 |
|------|-------|------|------|---------|--------|------|
| **ShopXO** | 8.5k | ⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐ | **9/10** |
| Bagisto | 14k | ⭐⭐ | ⭐⭐ | ⭐ | ⭐⭐⭐ | 5/10 |
| Saleor | 22.4k | ⭐⭐ | ⭐ | ⭐⭐ | ⭐⭐⭐ | 5/10 |
| Medusa | 23k+ | ⭐⭐ | ⭐ | ⭐ | ⭐⭐⭐ | 4/10 |
**ShopXO 断层第一**,原因:功能完整 + 虚拟主机可部署 + 有 uni-app 前端配套 + MIT 协议可商用。
**票务插件定位:**
票务 = ShopXO 商品类型扩展。item_type = 'ticket' 时走插件逻辑处理座位图/场次/QR票。
### 1.2 技术栈决策
| 层 | 技术选型 | 说明 |
|----|---------|------|
| 商城底座 | ShopXO v6.8.0 | ThinkPHP 8虚拟主机可部署 |
| 前端 | uni-app | 微信小程序 + H5 |
| 票务插件 | PHP 原生 | 插件机制 + Hook 系统 |
| 票务详情页 | 独立 HTML 模板 | 完全独立 UI绕过 ShopXO 主题限制 |
| 数据库 | MySQL与 ShopXO 共用) | 表前缀 vrt_ |
| QR 票 | AES 加密 | 防伪造 |
| 核销 | 扫码枪 + RLS | B 端小程序扫码核销 |
**核心原则(已固化):**
> 怎么快怎么来,怎么方便怎么来,少改动少复杂度,完全允许改 ShopXO 核心代码(自己部署)。
---
## 二、技术调研2026-04-13 白天)
### 2.1 ShopXO 插件机制调研
**调研文件:**
- docs/07_SHOPXO_PLUGIN_MECHANISM.md — 插件开发机制完整手册
- docs/08_SHOPXO_REQUIREMENTS_MAPPING.md — 票务需求 → ShopXO 机制对照矩阵
- docs/09_SHOPXO_HOOKS_REFERENCE.md — 100+ 钩子清单
**插件核心机制:**
1. config.json — 插件元数据(名称/版本/依赖/菜单/权限/静态资源)
2. BaseService — 插件业务服务基类GetDb / 参数校验 / 日志)
3. EventListener.php — 生命周期钩子Install/Uninstall/Upgrade/Index
4. URL 路由 — 后台控制器 plugins_admin 前缀,前台 plugins 前缀
5. 视图 — admin/view/default/plugins_admin/ + view/default/plugins/ 目录
**关键发现(票务用途):**
| 钩子 | 用途 |
|------|------|
| plugins_service_order_pay_success_handle_end | 支付成功 → 生成 QR 票 |
| plugins_view_goods_detail_base_sku_top | 商品详情页顶部(选座 UI |
| plugins_view_user_various_inside_top | 用户中心(票夹) |
| plugins_service_goods_delete_end | 商品删除 → 清理票务数据 |
| plugins_admin_goods_info_init_end | 后台商品编辑 → 加载票务字段 |
### 2.2 票务详情页方案抉择
方案 AURL 劫持 ❌ 放弃
- 缺点:无法继承商品详情页基础样式,改动 ShopXO 核心代码量大
方案 BCSS 隐藏标准 SKU ❌ 放弃
- 缺点Hook 链过长,不可控
方案 C插件模板替换 ❌ 不可行
- 调研结论MyView() 源码确认 ShopXO 插件系统是纯钩子系统config.json 无权覆盖 Goods 控制器模板路径goods/detail.html 写死在控制器里
方案 D最终Goods.php 1 行判断 ✅
- 在 app/index/controller/Goods.php 的 return MyView(); 前插入判断
- item_type == 'ticket' → 加载插件模板路径 + 预查询座位模板数据
- 改动量1 行条件判断 + ~10 行数据注入
- 实测验证:浏览器访问商品详情页,座位图渲染正常
---
## 三、ShopXO 环境配置2026-04-15 凌晨)
### 3.1 Docker 环境
| 服务 | 端口 | 说明 |
|------|------|------|
| shopxo-web | :10000 | Nginx 前端 |
| shopxo-mysql | :10001 | MySQL 8.0 |
| shopxo-php | :9000 | PHP-FPM |
### 3.2 关键配置
- 后台入口adminwatekc.php非标准 admin.php
- 表前缀vrt_非标准 sxo_
- 数据库凭证root=shopxo_root_2024 / user=shopxo_user / pass=shopxo_pass_2024
- 源码路径:~/.openclaw/workspace/council-research/shopxo-eval/.worktrees/shopxo-evaluator/shopxo-src/
- is_develop在 config/shopxo.php 第 41 行改为 true
### 3.3 后台权限修复
admin 用户role_id=1默认缺少插件权限。手动写入 38 条权限到 vrt_role_power
- 应用管理链路340 / 341 及子权限 342-591
### 3.4 模板目录冲突
ThinkPHP 路由用 plugins_admin下划线格式但实际目录为 pluginsadmin无下划线。通过创建符号链接解决。
---
## 四、Phase 0插件骨架2026-04-15 04:36 起)
### 4.1 完成内容
**数据库建表(手动 SQL**
-- 座位模板
CREATE TABLE vrt_vr_seat_templates (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100) NOT NULL COMMENT '模板名称',
category_id INT DEFAULT 0 COMMENT '绑定分类ID',
spec_base JSON COMMENT '座位规格基数据',
qr_data VARCHAR(64) NOT NULL COMMENT 'QR数据前缀',
is_enable TINYINT DEFAULT 1,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
-- 电子票
CREATE TABLE vrt_vr_tickets (
id INT PRIMARY KEY AUTO_INCREMENT,
order_id INT NOT NULL,
order_no VARCHAR(64),
goods_id INT NOT NULL,
user_id INT NOT NULL,
qr_code TEXT NOT NULL COMMENT 'AES加密QR数据',
status ENUM('pending','active','used','cancelled') DEFAULT 'pending',
qr_data VARCHAR(128),
seat_label VARCHAR(32),
verified_at DATETIME,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
-- 核销员
CREATE TABLE vrt_vr_verifiers (
id INT PRIMARY KEY AUTO_INCREMENT,
user_id INT NOT NULL,
name VARCHAR(50),
status TINYINT DEFAULT 1,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
-- 核销记录
CREATE TABLE vrt_vr_verifications (
id INT PRIMARY KEY AUTO_INCREMENT,
ticket_id INT NOT NULL,
verifier_id INT NOT NULL,
verified_at DATETIME DEFAULT CURRENT_TIMESTAMP,
location VARCHAR(200)
);
**插件文件结构:**
app/plugins/vr_ticket/
├── plugin.json # 插件配置3个子菜单
├── EventListener.php # 生命周期Install建表/Uninstall/Upgrade
├── service/
│ ├── BaseService.php # 工具AES/QrData/UUID/日志)
│ ├── TicketService.php # onOrderPaid/verifyTicket/getUserTickets
│ └── SeatTemplateService.php
├── admin/
│ ├── controller/
│ │ ├── SeatTemplate.php # 座位模板 CRUD
│ │ ├── Ticket.php # 电子票列表+详情+导出
│ │ ├── Verifier.php # 核销员管理
│ │ └── Verification.php # 核销记录
│ └── view/default/ # Layui 列表页
└── view/goods/
└── ticket_detail.html # 前端票务详情页独立UI
**测试数据:**
- 商品 ID 112VR演唱会电子票 2024item_type=ticket
- 分类 ID 911VR演唱会
- 座位模板 ID 1Bird Nest - Zone A绑定 category_id=911
- 3排座位A排AAAAAA红色VIP区/ B排BBBBBB蓝色看台区/ C排CCCCCC绿色普通区
---
## 五、Phase 1Goods.php 改法 + 前端验证2026-04-15 白天)
### 5.1 修改内容
文件app/index/controller/Goods.php
位置detail() 方法return MyView(); 前约第 137-139 行
代码改动:
// --- VR 票务处理 start ---
$goods = $result['data']['goods'];
if (!empty($goods['item_type']) && $goods['item_type'] === 'ticket') {
// 加载座位模板
$spec_base = Db::table('vr_seat_templates')
->where('category_id', $goods['category_id'])
->where('is_enable', 1)
->find();
$goods['vr_seat_template'] = $spec_base;
// 加载 goods_spec_data座位动态价格
$goods_spec_data = empty($goods['spec_base']) ? [] : json_decode($goods['spec_base'], true);
$goods['vr_spec_data'] = $goods_spec_data;
// 使用票务专用模板
$this->set_title($goods['title'].' - VR电子票');
return MyView('public/../../../plugins/vr_ticket/view/goods/ticket_detail', [
'common' => $common,
'header' => $header,
'goods' => $goods,
]);
}
// --- VR 票务处理 end ---
### 5.2 前端票务详情页渲染结果
URLhttp://localhost:10000/?s=index/goods/index/id/1商品1改为 item_type=ticket 测试)
渲染效果:
- 舞台(舞 台)
- 座位图三行A排AAAAAA红色VIP区/ B排BBBBBB蓝色看台区/ C排CCCCCC绿色普通区
- 图例VIP区 / 看台 / 普通)
- 选座 UI已选座位计数 + 合计价格)
- 场次选择
- 观演人表单(姓名+手机号)
---
## 六、Council 审议记录2026-04-14
### 6.1 Architect Round 1已合并
评审结论Q2+Q4
- Q2spec 座位共用 vs 独立 → 确认方案
- Q4spec 复用粒度 → 确认粒度
### 6.2 PM Round 2已合并
- 解决 plan.md 合并冲突
### 6.3 待 Council 审议的遗留问题
| 问题 | 状态 | 说明 |
|------|------|------|
| Q2spec座位共用vs独立 | ✅ 已解决 | 见 ARCHITECTURE.md |
| Q3观演人存储位置 | ⏳ 待 Council | 尚未最终确认 |
| Q4spec复用粒度 | ✅ 已解决 | 见 ARCHITECTURE.md |
---
## 七、关键决策固化
| 决策 | 结论 | 备注 |
|------|------|------|
| 改 ShopXO 核心可以吗 | ✅ 可以,自己部署 | 原则已写入 README |
| 票务详情页方案 | ✅ Goods.php 1行判断 → ticket_detail.html | 已验证 |
| spec = 场次 | ✅ 确认 | 无需 vr_sessions 表 |
| 座位模板绑定分类 | ✅ 确认 | Q1 已解决 |
| item_type 字段 | ✅ ticket / normal | 触发票务逻辑开关 |
| 座位图渲染 | ✅ HTML Table + CSS Grid | 不依赖第三方库 |
| QR 安全 | ✅ AES_Encrypt | 防伪造 |
| AI 介入程度 | 90%+ | 模板/Hook/PHP/Vue 均为标准技术 |
---
## 八、当前状态快照2026-04-15 09:00 CST
### 8.1 Git Commit 历史
7508bed docs: 追加 vr-shopxo-plugin Phase 0/1 状态记录
0f5a82d feat(Phase 1): ShopXO Goods.php 修改(实际验证通过)
34f7045 feat(Phase 0): vr_ticket plugin skeleton complete
d5edb76 docs: add guiding principle + Goods.php modification guide
1c6d32b docs: add ShopXO hooks reference (v6.8.0) - extracted from source
e7b7bf9 docs: add plugin mechanism + requirements mapping docs
536ef9e docs: add 项目启动报告 REPORT-KICKOFF.md (issue #5)
8c6878e council(draft): Architect - 合并 Round 1 架构评审结论
9eae259 council(draft): Architect - Round 1 架构评审结论 (Q2+Q4)
### 8.2 Phase 完成度
| Phase | 状态 | 说明 |
|-------|------|------|
| Phase 0骨架 | ✅ 完成 | 14个文件4张表插件已注册 |
| Phase 1前端票务详情页 | ✅ 完成 | Goods.php验证通过座位图渲染正常 |
| Phase 2后台管理页面 | ⏳ 待开始 | 场次管理/座位管理/票务订单列表 |
| Phase 3支付回调 + 发票 | ⏳ 待开始 | 钩子联调 + QR 票生成 |
| Phase 4B端扫码核销 | ⏳ 待开始 | 核销员管理 + 扫码 API |
### 8.3 关键文件路径
ShopXO 容器:
源码:~/.openclaw/workspace/council-research/shopxo-eval/.worktrees/shopxo-evaluator/shopxo-src/
插件shopxo-src/app/plugins/vr_ticket/
Goods.phpshopxo-src/app/index/controller/Goods.php
vr-shopxo-plugin 仓库:
插件代码app/plugins/vr_ticket/
ShopXO 修改shopxo-modifications/app/index/controller/Goods.php
文档docs/
---
## 九、下一步计划
### Phase 2后台管理页面
1. 座位模板管理admin/controller/SeatTemplate.php
- Layui 列表页(已生成 view
- 创建/编辑/删除操作
2. 电子票管理admin/controller/Ticket.php
- 票列表(支持按订单号/手机号搜索)
- 票详情(显示 QR 码)
- 导出功能
3. 核销员管理admin/controller/Verifier.php
- 增删改查
4. 核销记录admin/controller/Verification.php
- 核销历史列表
### Phase 3支付回调 + QR 票生成
1. 实现 TicketService::onOrderPaid() → 支付成功时生成票
2. Hookplugins_service_order_pay_success_handle_end
3. AES 加密 QR 数据
4. ShopXO 站内通知或 Realtime 推送
### Phase 4B 端扫码核销
1. 核销 APIB 端小程序调用)
- POST /api/ticket/verify扫码枪调用
- RLS 策略profiles.role = 'staff' 可核销
2. 核销员注册
- 后台添加核销员(手机号)
- 绑定 user_id
---
## 十、已知问题与待验证项
| 问题 | 优先级 | 状态 |
|------|--------|------|
| 后台插件菜单无权限 | P1 | admin 已有 340/341vr_ticket 控制器权限未单独分配 |
| 观演人存储位置Q3 | P2 | 待 Council 审议 |
| spec_base JSON 结构最终版 | P2 | 已确认 Q4 方案,待落地 |
| 支付回调联调 | P2 | 等待 Phase 2 后台完成后测试 |
| 核销 API RLS | P2 | 待实现 |