# 实施路线图 > 规划时间:2026-04-14 > 目标:基于 ShopXO 的 VR 演唱会票务 MVP --- ## 一、整体时间估算 | 阶段 | 内容 | 人天 | 可并行 | 累计 | |---|---|---|---|---| | Phase 0 | 环境搭建 + 插件骨架 | 2天 | — | 2天 | | Phase 1 | 数据库设计 + 迁移 | 2天 | ✅ Phase 0 | 2天 | | Phase 2 | 场次管理 CRUD + API | 3天 | ✅ Phase 1 | 3天 | | Phase 3 | 下单钩子 + 观演人收集 | 3天 | ✅ Phase 2 | 4天 | | Phase 4 | 支付回调 + QR 票生成 | 2天 | ✅ Phase 3 | 5天 | | Phase 5 | uni-app 票务页面 | 3天 | ✅ Phase 3 | 6天 | | Phase 6 | B 端核销页 + API | 2天 | ✅ Phase 4 | 6天 | | Phase 7 | 联调 + 测试 + 部署 | 3天 | 需串行 | 9天 | **预估**:Agent 集群并行 **1-2 周 MVP**,**3 周完整流程** --- ## 二、Phase 0 — 环境搭建 ### 目标 本地跑通 ShopXO + shopxo-uniapp 开发环境 ### 任务 1. **Docker 部署 ShopXO**(参考 `DEPLOYMENT.md`) - PHP 8.0+ / MySQL 5.7+ / nginx - 或使用虚拟主机安装包 2. **安装 shopxo-uniapp** - HBuilderX 导入项目 - 配置 `request_url` 和 `static_url` - 本地 H5 预览验证 3. **创建插件骨架** ```bash mkdir -p app/plugins/vr_ticket/ cp plugin.json app/plugins/vr_ticket/ mkdir -p app/plugins/vr_ticket/{service,view,Admin/Controller,Api/Controller} mkdir -p static/vr_ticket/ mkdir -p database/migrations/ ``` 4. **在 ShopXO 后台安装插件** - 访问 `/admin/plugins/index` - 上传插件 zip 或手动放置到 `app/plugins/vr_ticket/` - 点击安装 ### 验收 - ShopXO H5 前端正常访问 - shopxo-uniapp H5 预览正常 - 插件在后台可见 --- ## 三、Phase 1 — 数据库设计 ### 任务 创建插件迁移文件: ```sql -- database/migrations/001_create_vr_events.sql CREATE TABLE `vr_events` ( `id` int UNSIGNED PRIMARY KEY AUTO_INCREMENT, `goods_id` int UNSIGNED NOT NULL COMMENT 'ShopXO商品ID', `name` varchar(255) NOT NULL COMMENT '活动名称', `venue` varchar(255) COMMENT '场馆', `cover_image` varchar(255) COMMENT '封面图', `status` tinyint DEFAULT 1 COMMENT '状态(0禁用, 1启用)', `created_at` int UNSIGNED DEFAULT 0, `updated_at` int UNSIGNED DEFAULT 0, KEY `goods_id` (`goods_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- database/migrations/002_create_vr_sessions.sql CREATE TABLE `vr_sessions` ( `id` int UNSIGNED PRIMARY KEY AUTO_INCREMENT, `event_id` int UNSIGNED NOT NULL, `session_time` datetime NOT NULL COMMENT '场次时间', `total_stock` int UNSIGNED DEFAULT 0 COMMENT '总库存', `available_stock` int UNSIGNED DEFAULT 0 COMMENT '可用库存', `price` decimal(10,2) UNSIGNED DEFAULT 0 COMMENT '票价', `status` tinyint DEFAULT 1, `created_at` int UNSIGNED DEFAULT 0, `updated_at` int UNSIGNED DEFAULT 0, KEY `event_id` (`event_id`), KEY `session_time` (`session_time`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- database/migrations/003_create_vr_tickets.sql CREATE TABLE `vr_tickets` ( `id` int UNSIGNED PRIMARY KEY AUTO_INCREMENT, `order_id` int UNSIGNED NOT NULL COMMENT '订单ID', `order_no` char(60) NOT NULL, `goods_id` int UNSIGNED NOT NULL, `user_id` int UNSIGNED NOT NULL, `event_id` int UNSIGNED NOT NULL, `session_id` int UNSIGNED NOT NULL, `ticket_code` char(36) NOT NULL COMMENT 'UUID票码', `qr_data` text COMMENT '加密QR内容', `seat_info` varchar(255) COMMENT '座位信息', `real_name` varchar(60) COMMENT '观演人姓名', `phone` char(15) COMMENT '手机号', `verify_status` tinyint DEFAULT 0 COMMENT '0未核销, 1已核销', `verify_time` int UNSIGNED DEFAULT 0, `verifier_id` int UNSIGNED DEFAULT 0, `issued_at` int UNSIGNED DEFAULT 0, `created_at` int UNSIGNED DEFAULT 0, `updated_at` int UNSIGNED DEFAULT 0, UNIQUE KEY `ticket_code` (`ticket_code`), KEY `order_id` (`order_id`), KEY `user_id` (`user_id`), KEY `verify_status` (`verify_status`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- database/migrations/004_create_vr_verifiers.sql CREATE TABLE `vr_verifiers` ( `id` int UNSIGNED PRIMARY KEY AUTO_INCREMENT, `user_id` int UNSIGNED NOT NULL COMMENT 'ShopXO用户ID', `name` varchar(60) NOT NULL, `status` tinyint DEFAULT 1, `created_at` int UNSIGNED DEFAULT 0, KEY `user_id` (`user_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- database/migrations/005_create_vr_verifications.sql CREATE TABLE `vr_verifications` ( `id` int UNSIGNED PRIMARY KEY AUTO_INCREMENT, `ticket_id` int UNSIGNED NOT NULL, `ticket_code` char(36) NOT NULL, `verifier_id` int UNSIGNED NOT NULL, `verifier_name` varchar(60), `event_id` int UNSIGNED, `created_at` int UNSIGNED DEFAULT 0, KEY `ticket_id` (`ticket_id`), KEY `created_at` (`created_at`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ``` ### AI 参与度 ✅ **90% AI 可生成**(妮可 agent 主导) --- ## 四、Phase 2 — 场次管理 CRUD ### 任务 1. **管理端页面**(后台) - `Admin/Controller/EventController.php` — 活动管理 - `Admin/Controller/SessionController.php` — 场次管理 - `Admin/View/event_list.html` — 活动列表 - `Admin/View/session_edit.html` — 场次编辑 2. **C 端 API** - `Api/Controller/EventController.php` — 活动详情 - `Api/Controller/SessionController.php` — 可用场次列表 ### API 设计 ``` GET /?s=admin/vrticket/event/list POST /?s=admin/vrticket/event/save DELETE /?s=admin/vrticket/event/delete GET /?s=admin/vrticket/session/list&event_id=8 POST /?s=admin/vrticket/session/save DELETE /?s=admin/vrticket/session/delete GET /?s=api/vrticket/event/detail&id=8 GET /?s=api/vrticket/session/available&goods_id=123 ``` ### AI 参与度 ✅ **85% AI 可生成**(标准 CRUD,可套模板) --- ## 五、Phase 3 — 下单钩子 + 观演人收集 ### 5.1 目标 在 ShopXO 下单流程中收集观演人信息 ### 5.2 方案 利用 ShopXO 的「订单商品扩展表单」机制(`ordergoodsform` 插件的思路): 在 `plugins_view_goods_detail_base_sku_top` 注入观演人表单: ```html
观演人信息 + 添加观演人
``` ### 5.3 数据收集流程 1. 用户在前端填写观演人信息 2. 前端将观演人数据存入本地(`uni.setStorage`) 3. 点击购买时,将观演人数据通过插件 API 暂存 4. 插件在 `plugins_service_buy_order_insert_begin` 钩子中将观演人数据写入 `vr_tickets` 表 ### 5.4 钩子实现 ```php // 插件 Service/TicketService.php public static function OnBeforeOrderInsert(&$params, &$order_data) { // 检查是否有票务商品 $items = $order_data['items'] ?? []; foreach ($items as $item) { if (self::IsTicketGoods($item['goods_id'])) { // 收集观演人信息,生成票码 $attendees = self::CollectAttendees($item); self::CreateTickets($order_data['order_id'], $item, $attendees); } } } ``` ### AI 参与度 ✅ **80% AI 可生成**(逻辑稍复杂,需与 ShopXO 订单流程对接) --- ## 六、Phase 4 — 支付回调 + QR 票生成 ### 6.1 目标 支付成功后自动发放 QR 电子票 ### 6.2 触发点 ShopXO 支付成功 → `plugins_service_buy_order_insert_success` 钩子 ### 6.3 任务 ```php // 插件 Service/TicketService.php public static function OnOrderPaid($order_id, $order_no) { // 1. 查询该订单的所有票务商品 $tickets = self::GetPendingTickets($order_id); foreach ($tickets as $ticket) { // 2. 生成加密票码 $ticket_code = self::GenerateTicketCode(); // UUID v4 // 3. 加密 QR 内容 $qr_data = self::EncryptQrData([ 'id' => $ticket['id'], 'code' => $ticket_code, 'event' => $ticket['event_id'], 'exp' => time() + 86400 * 30, // 30天有效期 ]); // 4. 更新数据库 Db::name('vr_tickets') ->where('id', $ticket['id']) ->update([ 'ticket_code' => $ticket_code, 'qr_data' => $qr_data, 'issued_at' => time(), ]); } // 5. 发送通知(可选) self::NotifyUser($order_id); } ``` ### AI 参与度 ✅ **90% AI 可生成**(标准业务逻辑) --- ## 七、Phase 5 — uni-app 票务页面 ### 7.1 任务 | 页面 | 文件 | 说明 | |---|---|---| | 选座 + 购票 | `pages/ticket-buy/ticket-buy.vue` | 参考 goods-detail.vue | | 座位选择组件 | `pages/ticket-buy/components/seat-selector.vue` | SVG/Canvas 座位图 | | 观演人表单 | `pages/ticket-buy/components/attendee-form.vue` | 动态表单项 | | 票夹 | `pages/ticket-wallet/ticket-wallet.vue` | 参考 user/order-list | ### 7.2 关键组件实现 **座位选择器**(最简单的 SVG 实现): ```vue ``` ### 7.3 接入商品详情页 修改 `pages/goods-detail/goods-detail.vue`: - 检测 `goods.item_type === 'ticket'` - 跳转到 `pages/ticket-buy/ticket-buy?goods_id=xxx` 或通过插件钩子注入选座 UI,覆盖原有的规格选择器。 ### AI 参与度 ✅ **90% AI 可生成**(标准 Vue 组件) --- ## 八、Phase 6 — B 端核销页 ### 任务 1. **插件 API**:`Api/Controller/TicketController.php` - `verify()` — 核销验证 2. **uni-app 核销页**: - Fork `pages/plugins/realstore/check/check.vue` - 改造成 `pages/plugins/vr-ticket-verify/check/check.vue` - 调整 API 路径和返回处理 3. **后台核销统计**: - `Admin/Controller/TicketController.php` - `Admin/View/verification_list.html` ### AI 参与度 ✅ **90% AI 可生成**(核心逻辑已参考 realstore 完整实现) --- ## 九、Phase 7 — 联调 + 测试 + 部署 ### 9.1 联调清单 - [ ] 活动创建 → 商品关联 - [ ] 场次库存 → 商品 SKU 映射 - [ ] 前端选座 → 后端扣库存 - [ ] 微信支付 → 回调 → QR 票生成 - [ ] 票夹显示 → QR 码展示 - [ ] B 端扫码 → 核销状态更新 - [ ] C 端状态实时刷新 ### 9.2 测试用例 | 用例 | 预期 | |---|---| | 正常购票流程 | 支付成功 → 收到 QR 票 | | 并发抢票 | 库存不超卖 | | 核销同一张票两次 | 第二次报错「已核销」 | | QR 码过期 | 核销时报「票已过期」 | | 退款后票失效 | 票状态更新为已退款 | ### 9.3 部署 - **PHP 虚拟主机**:上传插件 zip → 后台安装 - **shopxo-uniapp**:HBuilderX 发行 → 微信审核 --- ## 十、Agent 分工建议 | Agent | 负责任务 | |---|---| | **李狗蛋**(MacBook Pro VM) | Phase 0 + Phase 2(场次 CRUD) | | **妮可**(Intel MacBook) | Phase 1(数据库迁移脚本) | | **小老D**(Proxmox Linux) | Phase 3 + Phase 6(钩子 + 核销) | | **西莉娅**(本地 Hub) | Phase 4(QR 生成)+ Phase 7(联调)+ 文档整合 | --- ## 十一、里程碑 | 里程碑 | 日期 | 交付物 | |---|---|---| | M1 | 第 1 周 | 插件跑通、数据库就绪 | | M2 | 第 2 周 | 场次管理 + 购票流程 + QR 票发放 | | M3 | 第 3 周 | B 端核销 + 票夹 + 联调测试 | | M4 | 第 4 周 | 微信审核 + 正式上线 |