274 lines
7.4 KiB
Markdown
274 lines
7.4 KiB
Markdown
|
|
# ShopXO VR票务插件 — 架构文档
|
|||
|
|
|
|||
|
|
## 项目概述
|
|||
|
|
|
|||
|
|
基于 ShopXO 生态的 VR 演唱会票务插件(Plan B)。
|
|||
|
|
|
|||
|
|
当 vr-ticket-mp 主线项目因维护成本或架构限制无法继续时,此插件作为 Plan B:
|
|||
|
|
- **完全复用** ShopXO 已有能力(会员体系/积分/优惠券/微信支付)
|
|||
|
|
- **仅扩展** 票务专属逻辑(场次/观演人/QR核销)
|
|||
|
|
- **不修改** ShopXO 核心代码,通过插件机制隔离
|
|||
|
|
|
|||
|
|
### 目标用户
|
|||
|
|
朋友的合作伙伴:需要一个可上线、后期可 AI 改动的轻量商城小程序。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 核心设计思路
|
|||
|
|
|
|||
|
|
### 商品模型统一
|
|||
|
|
|
|||
|
|
票务作为 ShopXO 商品类型的扩展:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
ShopXO items 表
|
|||
|
|
└── item_type = 'ticket' 时,启用插件逻辑
|
|||
|
|
├── 关联 vr_events(场次表)
|
|||
|
|
├── 关联 vr_sessions(场次时间)
|
|||
|
|
└── 关联 vr_attendees(观演人)
|
|||
|
|
|
|||
|
|
ShopXO orders 表
|
|||
|
|
└── 订单项 item_type='ticket' → 插件处理履约
|
|||
|
|
└── 触发 vr_tickets 表写入 → 生成 QR 票
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 与 ShopXO 的边界
|
|||
|
|
|
|||
|
|
| 能力 | 来源 | 说明 |
|
|||
|
|
|------|------|------|
|
|||
|
|
| 商品目录/上下架 | ShopXO | 复用 items 表 |
|
|||
|
|
| 会员体系/充值/积分 | ShopXO | 复用 user/wallet/integral 表 |
|
|||
|
|
| 优惠券 | ShopXO | 复用 coupons 表 |
|
|||
|
|
| 微信支付 | ShopXO | 复用 payment 表 + 回调 |
|
|||
|
|
| 场次/日期管理 | **插件** | 独立表 vr_events/sessions |
|
|||
|
|
| 观演人信息 | **插件** | 独立表 vr_attendees |
|
|||
|
|
| QR 电子票 | **插件** | 独立表 vr_tickets |
|
|||
|
|
| 核销组件 | **插件** | 独立 B 端页面 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 数据库设计
|
|||
|
|
|
|||
|
|
### 插件独立表
|
|||
|
|
|
|||
|
|
```sql
|
|||
|
|
-- 场次表
|
|||
|
|
vr_events (
|
|||
|
|
id, goods_id, -- 关联 ShopXO items.id
|
|||
|
|
name, -- "周杰伦2026巡回演唱会"
|
|||
|
|
venue, -- 场馆
|
|||
|
|
cover_image,
|
|||
|
|
status,
|
|||
|
|
created_at
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
-- 场次时间表
|
|||
|
|
vr_sessions (
|
|||
|
|
id, event_id,
|
|||
|
|
session_time, -- 2026-06-01 20:00
|
|||
|
|
total_stock, -- 总库存
|
|||
|
|
available_stock, -- 可用库存(扣减用 FOR UPDATE SKIP LOCKED)
|
|||
|
|
price,
|
|||
|
|
status,
|
|||
|
|
created_at
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
-- 观演人表
|
|||
|
|
vr_attendees (
|
|||
|
|
id, order_id, order_item_id,
|
|||
|
|
session_id,
|
|||
|
|
real_name,
|
|||
|
|
id_card, -- 可选
|
|||
|
|
phone,
|
|||
|
|
ticket_code, -- UUID,唯一
|
|||
|
|
qr_data, -- 加密后的 QR 内容
|
|||
|
|
status, -- pending/issued/used/cancelled
|
|||
|
|
created_at
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
-- QR 票表
|
|||
|
|
vr_tickets (
|
|||
|
|
id, attendee_id,
|
|||
|
|
ticket_code,
|
|||
|
|
qr_image_path, -- QR码图片路径
|
|||
|
|
issued_at, -- 支付成功时生成
|
|||
|
|
used_at, -- 核销时间
|
|||
|
|
created_at
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
-- 核销记录表
|
|||
|
|
vr_verifications (
|
|||
|
|
id, ticket_id, verifier_id,
|
|||
|
|
verified_at,
|
|||
|
|
ip_address,
|
|||
|
|
location
|
|||
|
|
)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 插件目录结构
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
shopxo-vr-ticket-plugin/
|
|||
|
|
├── plugin.json # 插件声明
|
|||
|
|
├── app/
|
|||
|
|
│ ├── Admin/ # 管理端
|
|||
|
|
│ │ ├── Controller/
|
|||
|
|
│ │ │ ├── EventController.php
|
|||
|
|
│ │ │ ├── SessionController.php
|
|||
|
|
│ │ │ └── TicketController.php
|
|||
|
|
│ │ ├── Route.php # 管理端路由
|
|||
|
|
│ │ └── View/ # 管理页面
|
|||
|
|
│ │ ├── event_list.html
|
|||
|
|
│ │ ├── session_edit.html
|
|||
|
|
│ │ └── ticket_list.html
|
|||
|
|
│ ├── Api/ # C端API
|
|||
|
|
│ │ ├── EventController.php # 场次详情
|
|||
|
|
│ │ ├── SessionController.php # 可用场次
|
|||
|
|
│ │ ├── CheckoutController.php# 下单钩子(收集观演人)
|
|||
|
|
│ │ └── TicketController.php # 我的票/票夹
|
|||
|
|
│ ├── EventListener.php # 监听 ShopXO 支付成功事件
|
|||
|
|
│ ├── Model/
|
|||
|
|
│ │ ├── VrEvent.php
|
|||
|
|
│ │ ├── VrSession.php
|
|||
|
|
│ │ ├── VrAttendee.php
|
|||
|
|
│ │ └── VrTicket.php
|
|||
|
|
│ └── Service/
|
|||
|
|
│ ├── EventService.php
|
|||
|
|
│ ├── TicketService.php # QR 生成 + 发放
|
|||
|
|
│ └── VerificationService.php# 核销逻辑
|
|||
|
|
├── database/
|
|||
|
|
│ └── migrations/ # 插件数据库迁移
|
|||
|
|
│ ├── 001_create_vr_events.php
|
|||
|
|
│ ├── 002_create_vr_sessions.php
|
|||
|
|
│ ├── 003_create_vr_attendees.php
|
|||
|
|
│ └── 004_create_vr_tickets.php
|
|||
|
|
├── static/
|
|||
|
|
│ └── admin/ # 管理端静态资源
|
|||
|
|
└── README.md
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 核心流程
|
|||
|
|
|
|||
|
|
### 1. 票务发布流程
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
商家后台 → 插件菜单 → 新建活动
|
|||
|
|
→ 关联 ShopXO 商品(填写价格/库存)
|
|||
|
|
→ 添加场次(时间+价格+库存)
|
|||
|
|
→ 上架
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. 用户购票流程
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
首页浏览 → 商品详情 → 选择场次 → 立即购买
|
|||
|
|
→ 填写观演人信息(1-N人,场次配置决定)
|
|||
|
|
→ 提交订单(插件收集 attendees)
|
|||
|
|
→ 微信支付
|
|||
|
|
→ 支付回调 → 插件生成 QR 票
|
|||
|
|
→ 票夹页显示电子票
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3. 核销流程
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
B端核销员 → 扫码页面 → 扫描 QR
|
|||
|
|
→ API 校验 ticket_code
|
|||
|
|
→ 标记 used_at
|
|||
|
|
→ 返回核销结果
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 关键技术决策
|
|||
|
|
|
|||
|
|
### 库存扣减
|
|||
|
|
|
|||
|
|
采用 `FOR UPDATE SKIP LOCKED`(与 vr-ticket-mp 相同策略):
|
|||
|
|
|
|||
|
|
```sql
|
|||
|
|
BEGIN;
|
|||
|
|
SELECT available_stock FROM vr_sessions
|
|||
|
|
WHERE id = ? AND available_stock >= ? FOR UPDATE SKIP LOCKED;
|
|||
|
|
-- 若成功,执行 UPDATE available_stock = available_stock - ?
|
|||
|
|
COMMIT;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### QR 票安全
|
|||
|
|
|
|||
|
|
```php
|
|||
|
|
// qr_data = AES_Encrypt(json_encode([
|
|||
|
|
// 'code' => $attendee->ticket_code,
|
|||
|
|
// 'event_id' => $event_id,
|
|||
|
|
// 'exp' => time() + 86400 * 30 // 30天有效期
|
|||
|
|
// ]), $secret_key)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
核销时解密验证,防止伪造。
|
|||
|
|
|
|||
|
|
### 与 ShopXO 的事件对接
|
|||
|
|
|
|||
|
|
```php
|
|||
|
|
// EventListener.php
|
|||
|
|
class EventListener
|
|||
|
|
{
|
|||
|
|
// 监听 ShopXO 支付成功事件
|
|||
|
|
public function onOrderPaid($order_id)
|
|||
|
|
{
|
|||
|
|
$items = $this->orderService->getOrderItems($order_id);
|
|||
|
|
foreach ($items as $item) {
|
|||
|
|
if ($item->item_type === 'ticket') {
|
|||
|
|
$this->ticketService->issueTickets($item);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 与 vr-ticket-mp 的对比
|
|||
|
|
|
|||
|
|
| 维度 | vr-ticket-mp(主线) | ShopXO 插件(Plan B) |
|
|||
|
|
|------|---------------------|---------------------|
|
|||
|
|
| 后端 | Go + Gin(自建) | PHP + ThinkPHP(ShopXO) |
|
|||
|
|
| 数据库 | Supabase Postgres | ShopXO MySQL |
|
|||
|
|
| 前端 | uni-app(自建) | shopxo-uniapp(已有) |
|
|||
|
|
| 会员体系 | Supabase Auth | ShopXO 内置 |
|
|||
|
|
| 积分/优惠券 | 自建 | ShopXO 内置 |
|
|||
|
|
| 微信支付 | 自建 | ShopXO 内置 |
|
|||
|
|
| 部署 | Docker | 虚拟主机即可 |
|
|||
|
|
| 开发成本 | 高(全部自建) | 低(复用 ShopXO) |
|
|||
|
|
| 适合场景 | 票务为主,商城为辅 | 商城为主,票务为辅 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 技术栈
|
|||
|
|
|
|||
|
|
- **语言**:PHP 8+
|
|||
|
|
- **框架**:ThinkPHP 8(ShopXO 生态)
|
|||
|
|
- **前端**:Vue.js(插件管理端)+ uni-app(ShopXO 已有)
|
|||
|
|
- **数据库**:MySQL(ShopXO 同一实例)
|
|||
|
|
- **QR生成**:phpqrcode / endroid/qr-code
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 开发计划(Agent 集群并行)
|
|||
|
|
|
|||
|
|
| 阶段 | 工作内容 | 负责人 |
|
|||
|
|
|------|---------|--------|
|
|||
|
|
| Phase 0 | 插件骨架 + 本地跑通 demo | 李狗蛋 |
|
|||
|
|
| Phase 1 | 数据库设计 + 迁移脚本 | 妮可 |
|
|||
|
|
| Phase 2 | 场次管理 CRUD + API | 李狗蛋 |
|
|||
|
|
| Phase 3 | 下单钩子 + 观演人收集 | 小老D |
|
|||
|
|
| Phase 4 | 支付回调 + QR 票生成 | 西莉娅 |
|
|||
|
|
| Phase 5 | B端核销页 + 扫码API | 小老D |
|
|||
|
|
| Phase 6 | Uni-app 改造(观演人表单 + 票夹) | 妮可 |
|
|||
|
|
| Phase 7 | 联调 + 测试 + 部署文档 | 西莉娅 |
|
|||
|
|
|
|||
|
|
预计:**2-3 周 MVP**,**1 个月**完整上线。
|