[P0] Fix plugin Base controller to extend ShopXO Common class:
- Now extends Common instead of standalone class
- Automatically gets IsLogin() + IsPower() + ViewInit()
- All child controllers (SeatTemplate/Ticket/Verifier/Verification) inherit fix
[P1] Fix code bugs found during codebase analysis:
- Verifier.php: column('nickname|username', 'id') → CONCAT SQL (syntax error)
- SeatTemplate.php: countSeats() wrong logic (count × rows → per-row scan)
- Ticket.php: verify() returned view on POST → always JSON
- Ticket.php: detail() returned view on error → JSON
- SeatTemplate.php: delete() returned view on POST → JSON, plus soft-delete
[P1] Fix verifyTicket() in TicketService:
- Wrap in Db::transaction() for atomicity
- Add SELECT ... FOR UPDATE pessimistic lock to prevent double-verify
- Add try/catch with error logging
[P2] Fix export() memory issue:
- Replace select() with cursor() to avoid OOM on large datasets
Also: update plan.md with Round 2 findings, claim Task B1/B2/B3/B5
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
||
|---|---|---|
| .. | ||
| admin | ||
| service | ||
| view/goods | ||
| EventListener.php | ||
| README.md | ||
| plugin.json | ||
README.md
VR票务插件 - vr_ticket
⚡ 核心原则:怎么快怎么来,怎么方便怎么来
安装
- 将本目录上传到 ShopXO 插件目录:
cp -r vr_ticket /path/to/shopxo/app/plugins/ - 后台 → 应用中心 → 插件管理 → 找到「VR票务」→ 点击安装
- 数据库表自动创建
目录结构
vr_ticket/
├── plugin.json # 插件配置(名称、菜单、钩子)
├── EventListener.php # 安装/卸载/升级生命周期
├── service/
│ ├── BaseService.php # 基础工具(AES加密、QR生成)
│ └── TicketService.php # 核心票务逻辑(发票、核销)
├── admin/
│ ├── controller/
│ │ ├── SeatTemplate.php # 座位模板 CRUD
│ │ ├── Ticket.php # 电子票管理
│ │ ├── Verifier.php # 核销员管理
│ │ └── Verification.php # 核销记录
│ └── view/ # 后台视图模板
│ ├── seat_template/
│ ├── ticket/
│ ├── verifier/
│ └── verification/
└── view/
└── goods/
└── ticket_detail.html # 前端票务详情页(独立模板)
关键钩子
| 钩子 | 作用 |
|---|---|
plugins_service_order_pay_success_handle_end |
支付成功 → 自动发放 QR 电子票 |
plugins_service_order_delete_success |
订单删除 → 清理票务数据 |
前端票务详情页
需要在 ShopXO 核心文件 app/index/controller/Goods.php 中加 1 行:
// 在 return MyView(); 之前(约第 440 行)
if (!empty($assign['goods']['item_type']) && $assign['goods']['item_type'] == 'ticket') {
return MyView('/../../../plugins/vr_ticket/view/goods/ticket_detail');
}
详见 docs/GOODS_PHP_MODIFICATION.md
数据库表
| 表名 | 用途 |
|---|---|
vrt_vr_seat_templates |
座位模板(绑定分类) |
vrt_vr_tickets |
电子票(含观演人) |
vrt_vr_verifiers |
核销员 |
vrt_vr_verifications |
核销记录 |
API
| URL | 方法 | 作用 |
|---|---|---|
/plugins/vr_ticket/admin/seat_template/list |
GET | 座位模板列表 |
/plugins/vr_ticket/admin/seat_template/save |
GET/POST | 添加/编辑模板 |
/plugins/vr_ticket/admin/ticket/list |
GET | 电子票列表 |
/plugins/vr_ticket/admin/verification/list |
GET | 核销记录 |