vr-shopxo-uniapp/docs/vr-ticket-integration-plan.md

442 lines
17 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票务详情页面 UniApp 移植规划文档
> 创建时间2026-05-13
> 状态:**Phase 3 导航优化完成(防闪烁/缓存预检查)**
---
## 📌 背景与目标
### 背景
- 后端 VR Ticket 插件 (`vr_ticket`) 已实现票务商品详情页模板 `ticket_detail.html`
- 前端参考项目 [show-start](file:///Users/bigemon/WorkSpace/vr-shopxo-uniapp/references/show-start/src/App.vue) 提供了高质量的 UI 设计
- 需要将参考项目的 UI 移植到 UniApp 环境中并整合票务商品的4维选择逻辑
### 用户需求
1. **保持 show-start 的 popup 交互模式** 作为购票弹窗基础
2. **点击"立即购票"按钮** 后弹出购票弹窗
3. 弹窗内容包含:场次选择、场馆/演播室/分区选择、"选座"按钮
4. **选座功能**:独立的全屏遮罩座位选择器,选完后返回已选座位 tags
---
## 📋 数据结构规范Phase 2 核心)
### VR 票务扩展字段
从后端 API 返回的商品扩展数据中,票务商品会包含以下关键字段:
```typescript
interface VRTicketGoods {
id: number;
title: string;
images: string[];
is_vr_ticket: 1; // 票务商品标识
// VR 票务扩展数据(来自 vr_config 或 extension_data
vr_config?: {
// 场次规格列表(从 goods_spec_data 解析)
spec_list?: Array<{
spec_name: string; // 场次名称,如 "2026-06-01 14:00"
price: number; // 价格
inventory: number; // 库存
}>;
// 座位规格映射(从 seat_spec_map 解析)
seat_spec_map?: Record<string, {
spec: Array<{ type: string; value: string }>; // 4维规格
price: number;
inventory: number;
section: { name: string; color: string };
}>;
// 座位模板(座位图数据)
seat_template?: {
venue: { name: string; address: string; location: { lng: string; lat: string } };
rooms: Array<{
id: string;
name: string;
map: string[]; // 座位矩阵,如 ["AAAAA", "AAB__AA"]
sections: Array<{ char: string; name: string; price: number; color: string }>;
}>;
};
};
}
```
### 4维规格体系
票务商品的选座流程采用 **4维规格级联选择**
| 维度 | 字段名 | 说明 | 示例 |
|------|--------|------|------|
| 1 | `$vr-场次` | 演出场次/时间 | "2026-06-01 14:00" |
| 2 | `$vr-场馆` | 演出场馆 | "北京凯迪拉克中心" |
| 3 | `$vr-演播室` | 室内演出厅 | "主要展厅" |
| 4 | `$vr-分区` | 座位分区 | "VIP区"、"普通区" |
**选择级联逻辑**:选择场次 → 筛选可用场馆 → 选择场馆 → 筛选可用演播室 → 选择演播室 → 筛选可用分区 → 选择分区 → 加载座位图
---
## 📐 UI/UX 设计概览
### 页面结构
```
┌─────────────────────────────────────┐
│ Header Banner (海报 + 标题 + 收藏) │
├─────────────────────────────────────┤
│ Location Card (最近场馆) │
├─────────────────────────────────────┤
│ Service Tags (服务说明) │
├─────────────────────────────────────┤
│ 演出详情 Section │
├─────────────────────────────────────┤
│ 购票须知 Section │
├─────────────────────────────────────┤
│ 观演须知 Section │
├─────────────────────────────────────┤
│ Bottom Bar (客服 + 立即购票) │ ← Fixed 底部
└─────────────────────────────────────┘
```
### 购票弹窗 Popup 交互(核心功能区)
```
┌─────────────────────────────────────┐
│ [场次选择 - 横向卡片滚动] │ ← vr-session-grid
├─────────────────────────────────────┤
│ [选择场馆] │ ← vr-booking-block
├─────────────────────────────────────┤
│ [选择演播室] → [选择分区] │ ← 级联选择
├─────────────────────────────────────┤
│ [选座] 按钮 ← 打开座位选择器 │
│ │
│ 未选座时:尚未选择 [立刻选座] │
│ 已选座时: │
│ ┌─────┐ ┌─────┐ ┌─────┐ │
│ │ A1 │ │ A2 │ │ A3 │ │ ← 已选座位 tags
│ └─────┘ └─────┘ └─────┘ │
│ 【重新选座】 │
├─────────────────────────────────────┤
│ 合计: ¥888 [确认购票] │ ← 底部购买栏
└─────────────────────────────────────┘
```
### 座位选择器(全屏遮罩)
```
┌─────────────────────────────────────┐
│ ← 返回 选择座位 [已完成 3 座] │
├─────────────────────────────────────┤
│ 🎵 舞 台 │ ← 舞台指示
├─────────────────────────────────────┤
│ A ■ ■ ■ ■ ■ │ ← 座位行A排
│ B ■ ■ ■ ■ ■ ■ ■ │ ← 可用座位:■ 点击选中
│ C ■ _ _ ■ ■ ■ │ ← 过道_
│ D ■ ■ ■ ■ ■ │ ← 已售:灰色
├─────────────────────────────────────┤
│ 图例: [VIP] [普通] [已售] │
└─────────────────────────────────────┘
```
### 座位状态定义
- **可用座位**:可点击选择,带分区颜色
- **已选座位**:高亮边框,数字标识
- **已售座位**:灰色,不可点击
- **过道/空位**:占位符,不渲染
---
## 🔄 阶段进展记录
### Phase 1: 基础 UI 移植 ✅ 已完成
- [x]`pages.json` 中注册新页面路由
- [x] 创建 `pages/goods-vr-ticket/` 目录
- [x] 搬运 `App.vue` 内容到 `goods-vr-ticket.vue`
- [x] 适配 UniApp 语法scrollable、navigation 等)
- [x] 替换内联 SVG → iconfont 组件兼容<E585BC><E5AEB9>信小程序
- [x] 添加 popup 容器左右留白padding: 16px
- [x] 修复 popup-content 溢出问题overflow-x, word-break
### Phase 2: 购票弹窗与4维选择开发中
- [x] 购票弹窗基础结构(当前 popupType='buy'
- [ ] 接入商品 API 数据vr_config 解析)
- [ ] 场次选择器实现(横向滚动卡片)
- [ ] 场馆选择器实现
- [ ] 演播室/分区级联选择
- [ ] 座位选择器组件开发
- [ ] 已选座位 UI 展示
- [ ] 底部总价计算
### Phase 3: 完整购票流程(待开发)
- [ ] 观演人信息表单(每座必填)
- [ ] 订单提交 API 集成
- [ ] 跳转支付流程
### Phase 4: 优化与测试
- [ ] 滚动穿透处理catchtouchmove
- [ ] 真机/小程序测试
- [ ] 性能优化
---
## 📝 待办事项
### ✅ 已完成
- [x]`pages.json` 中注册新页面路由
- [x] 创建 `pages/goods-vr-ticket/` 目录
- [x] 搬运 `App.vue` 内容到 `goods-vr-ticket.vue`
- [x] 适配 UniApp 语法scrollable、navigation 等)
- [x] 替换内联 SVG → iconfont 组件(兼容微信小程序)
- [x] 添加 popup 容器左右留白padding: 16px
- [x] 修复 popup-content 溢出问题overflow-x, word-break
- [x] 购票弹窗基础框架popupType='buy' 判断)
### ⏳ 后续待办
- [x]`goods-detail.vue` 中添加跳转判断逻辑
- [ ] 解析商品数据中的 vr_config 等扩展字段
- [ ] 实现场次选择器(横向滚动卡片)
- [ ] 实现场馆选择器(场次筛选后可用)
- [ ] 实现演播室→分区级联选择
- [ ] 实现选座按钮与座位选择器(全屏遮罩)
- [ ] 实现已选座位 tags 展示
- [ ] 实现重新选座功能
- [ ] 连接后端 BuyService API 获取动态票务数据
- [ ] 实现底部购买栏联动(已选座数、总价)
- [ ] 添加 popup 滚动事件处理(:catchtouchmove
- [ ] 观演人信息表单(姓名/手机/身份证)
- [ ] 订单提交入口
- [ ] 测试页面在真机/小程序环境运行
---
## 🔌 API 接口规范
### 商品详情接口(扩展字段)
请求商品详情时,后端返回 `vr_config` 扩展数据:
```javascript
// GET /api/goods/detail?id=xxx
{
"code": 0,
"data": {
"id": 100,
"title": "王一浩「To U」巡演北京收官站",
"images": "[\"xxx.jpg\"]",
"is_vr_ticket": 1,
// VR 票务扩展
"vr_config": {
"goods_spec_data": [
{ "spec_name": "2026-06-01 14:00", "price": 580, "inventory": 100 },
{ "spec_name": "2026-06-01 20:00", "price": 680, "inventory": 50 }
],
"seat_spec_map": {
"room_001_A_1": {
"spec": [
{ "type": "$vr-场次", "value": "2026-06-01 14:00" },
{ "type": "$vr-场馆", "value": "北京凯迪拉克中心" },
{ "type": "$vr-演播室", "value": "主要展厅" },
{ "type": "$vr-分区", "value": "VIP区" }
],
"price": 580,
"inventory": 1,
"section": { "name": "VIP区", "color": "#ff4d4f" }
}
},
"vr_seat_template": {
"venue": { "name": "北京凯迪拉克中心", "address": "...", "location": { "lng": "116.4", "lat": "39.9" } },
"rooms": [...]
}
}
}
}
```
### 订单提交接口
```javascript
// POST /api/buy/add
{
"goods_data": [
{
"goods_id": 100,
"spec": [...], // 4维规格数组
"stock": 1,
"order_base": {
"extension_data": {
"attendee": {
"real_name": "张三",
"phone": "13800138000",
"id_card": "110101199001011234"
}
}
}
}
],
"buy_type": "goods",
"address_id": "0",
"site_model": "2"
}
```
---
## 🛠️ 技术实现要点
### 1. 4维规格筛选逻辑
参考 `ticket_detail.html` 中的 `filterSeats` 方法:
```javascript
// 根据当前选择的4维过滤可用座位
filterSeats: function() {
var matchSession = this.currentSession != null;
var matchVenue = this.currentVenue != null;
var matchRoom = this.currentRoom != null;
var matchSection = this.currentSection != null;
// 遍历所有座位,检查是否满足当前选择条件
for (var i = 0; i < seatInfo.spec.length; i++) {
if (seatInfo.spec[i].type === '$vr-场次' && seatInfo.spec[i].value === this.currentSession) {
matchSession = true;
}
// ... 同理其他维度
}
}
```
### 2. 座位状态管理
- `selectedSeats[]`:已选座位数组
- `soldSeats{}`:已售座位映射
- 切换场次时清空已选座位
### 3. 级联选择
- 选择「场次」后 → 重置「场馆/演播室/分区」,重新计算可选场馆
- 选择「场馆」后 → 筛选出<E98089><E587BA>场馆下的演播室
- 选择「演播室」后 → 筛选出该演播室下的分区,显示分区选择器
### 4. 座位渲染
座位图使用字符矩阵渲染:
- `A`/`B`/...:座位字符
- `_`:过道/空位
---
## 📦 文件结构
```
pages/goods-vr-ticket/
├── goods-vr-ticket.vue # 主页面(已移植 Phase 1
├── goods-vr-ticket.css # 独立样式(可选)
└── components/
├── vr-session-select/ # 场次选择器组件
├── vr-venue-select/ # 场馆选择器组件
├── vr-seat-selector/ # 座位选择器(全屏遮罩)
└── vr-attendee-form/ # 观演人表单
```
---
## 🔗 相关参考
| 文件 | 说明 |
|------|------|
| [references/show-start/src/App.vue](file:///Users/bigemon/WorkSpace/vr-shopxo-uniapp/references/show-start/src/App.vue) | 源 UI 参考Vue 2 |
| [pages/goods-detail/goods-detail.vue](file:///Users/bigemon/WorkSpace/vr-shopxo-uniapp/pages/goods-detail/goods-detail.vue) | 商品详情页(跳转入口) |
| [vr_ticket/ticket_detail.html](file:///Users/bigemon/WorkSpace/vr-shopxo-plugin/shopxo/app/plugins/vr_ticket/view/goods/ticket_detail.html) | 后端票务模板参考4维选择+座位图) |
| [pages.json](file:///Users/bigemon/WorkSpace/vr-shopxo-uniapp/pages.json) | 页面路由配置 |
---
## 🎯 关键文件
| 文件 | 状态 | 说明 |
|------|------|------|
| pages/goods-vr-ticket/goods-vr-ticket.vue | ✅ 已移植 | 主页面Phase 1 完成) |
| pages/goods-detail/goods-detail.vue | ⏳ 待修改 | 添加 is_vr_ticket 跳转判断 |
| components/iconfont/iconfont.vue | ✅ 已加固 | iconfont 组件 |
---
> ⚠️ **注意**:当前 Phase 2 正在开发中,核心为 4维规格选择器 + 座位选择器。Phase 3 将实现观演人表单和订单提交。座时:尚未选择 [立刻选座] │
│ 已选座时: │
│ [A区-2排-3号] [A区-2排-4号] │
│ 【重新选座】 │
├─────────────────────────────────────┤
│ [确认购票] │
└─────────────────────────────────────┘
点击[选座] → 打开座位选择器(全屏遮罩)
```
---
## 🗂️ 文件结构Phase 1 完成后)
```
pages/goods-vr-ticket/
├── goods-vr-ticket.vue # 主页面(移植自 App.vue
└── goods-vr-ticket.css # 独立样式文件(可选)
```
---
## 📝 待办事项
### ✅ 已完成
- [x]`pages.json` 中注册新页面路由
- [x] 创建 `pages/goods-vr-ticket/` 目录
- [x] 搬运 `App.vue` 内容到 `goods-vr-ticket.vue`
- [x] 适配 UniApp 语法scrollable、navigation 等)
- [x] 替换内联 SVG → iconfont 组件(兼容微信小程序)
- [x] 添加 popup 容器左右留白padding: 16px
- [x] 修复 popup-content 溢出问题overflow-x, word-break
### ⏳ 后续待办
- [ ]`goods-detail.vue` 中添加跳转判断逻辑
- [ ] 对 商品数据里的vr_config 等数据进行解析,
- [ ] 实现购票弹窗 Popup 交互移植老的4 维规格选择到新的购票弹窗 Popup 中。
- [ ] 实现购票弹窗内的选座逻辑
- [ ] 连接后端 BuyService API动态票务数据
- [ ] 优化 popup 滚动事件处理(:catchtouchmove
- [ ] 测试页面在真机/小程序环境运行
---
## 🔄 阶段进展记录
### 2026-05-13 样式迁移完成
- ✅ 移除 inline SVG改用 iconfont 组件
- ✅ map-icon 容器添加边框
- ✅ venue-popup-info 添加地址图标icon-location
- ✅ popup-container 添加 padding: 0 16px
- ✅ popup-content 修复溢出word-break, box-sizing
### 2026-05-14 导航优化完成
- ✅ goods-detail.vue 添加白色遮罩初始覆盖200ms后渐变消失
- ✅ 添加缓存预检查快速判断VR票务无需等待API
- ✅ goods-vr-ticket.vue 加载遮罩 + pageShow 显示控制
- ✅ 修复返回导航:智能判断页面栈,无历史则跳转首页
- ✅ goods-detail 使用 redirectTo 替代 navigateTo避免循环
### 关键文件
| 文件 | 状态 |
|------|------|
| pages/goods-vr-ticket/goods-vr-ticket.vue | ✅ 已移植 |
| pages/goods-vr-ticket/goods-vr-ticket.css | ✅ 已移植 |
| pages/goods-vr-ticket/components/ticket-header/index.vue | ✅ 已移植 |
| pages/goods-vr-ticket/components/venue-card/index.vue | ✅ 已移植 |
| pages/goods-vr-ticket/components/ticket-popup/index.vue | ✅ 已移植 |
| components/iconfont/iconfont.vue | ✅ 已加固尺寸 |
| pages/goods-detail/goods-detail.vue | ✅ 已加固导航 |
---
## 🔗 相关参考
| 文件 | 说明 |
|------|------|
| [references/show-start/src/App.vue](file:///Users/bigemon/WorkSpace/vr-shopxo-uniapp/references/show-start/src/App.vue) | 源 UI 参考Vue 2 |
| [pages/goods-detail/goods-detail.vue](file:///Users/bigemon/WorkSpace/vr-shopxo-uniapp/pages/goods-detail/goods-detail.vue) | 商品详情页(跳转入口) |
| [vr_ticket/ticket_detail.html](file:///Users/bigemon/WorkSpace/vr-shopxo-plugin/shopxo/app/plugins/vr_ticket/view/goods/ticket_detail.html) | 后端票务模板参考 |
| [pages.json](file:///Users/bigemon/WorkSpace/vr-shopxo-uniapp/pages.json) | 页面路由配置 |
---
> ⚠️ **注意**:当前为 Phase 1 规划,仅实现初步移植和测试环境搭建。后续 Phase 2-4 将逐步实现座位选择器、4维规格选择、完整购票流程等高级功能。