7.1 KiB
Agent 任务卡 — vr-shopxo-plugin
每次派 agent 任务前,先读本文件和
DEVELOPMENT_GUIDELINES.md。 每次任务以一个小目标为限,做完汇报,不要一次塞太多。
当前项目状态
分支: feat/phase4-ticket-wallet
主分支: main(干净,无 ShopXO 核心修改)
已验证可用: Docker 环境 + ShopXO 后台
已完成的文件(可直接引用/继续开发):
service/WalletService.php— 票夹查询 + QR JWT 签名 + 短码编码(HMAC-XOR)service/TicketService.php— 发票/核销逻辑view/goods/ticket_card.html— 票卡 UI 片段view/goods/ticket_wallet.html— C端票夹整页service/AuditService.php— 核销审计日志database/migrations/001_vr_tables.sql— 表结构(tickets/verifiers/verifications/audit_log)tests/phase4_1_feistel_test.php— 单元测试(HMAC-XOR + QR 签名)
Phase 4 待完成(优先级从高到低):
| # | 任务 | 难度 | 约束 |
|---|---|---|---|
| 1 | C端票夹 API + 挂载到 ShopXO 用户中心 | 中 | 改动在插件内,ShopXO 核心不动 |
| 2 | B端核销 API /?s=api/vr_ticket/verify |
低 | 已有 AuditService,只需写 API 控制器 |
| 3 | B端核销页面 admin 侧边栏入口 + 核销操作页 | 中 | 复用 ShopXO Layui 风格 |
| 4 | 出票链路闭环 order.paid 事件 → issueTicket() |
中 | 参考 Phase 4 Plan §5 |
| 5 | Migration 002 002_ticket_wallet.sql |
低 | 无需存 short_code(实时编码),检查 001 是否完整 |
任务卡 1:C端票夹 API + 前端挂载
目标:用户访问票夹页 /?s=user/wallet 时展示 vr_ticket 票。
Step 1 — API 端点
文件:shopxo/app/plugins/vr_ticket/api/Ticket.php
参考 Phase 4 Plan §3.3,新增两个方法:
// GET /?s=api/vr_ticket/tickets
// 返回:当前用户所有票(已购、未核销)
public function tickets()
{
// 1. 取当前登录用户 $userId
// 2. 调用 WalletService::getUserTickets($userId)
// 3. 返回 JSON: { code: 0, data: [...] }
}
Step 2 — 页面挂载
文件:view/goods/ticket_wallet.html
在 ShopXO 用户中心挂载点(找 ModuleInclude('模块名'))渲染此页面。
参考 ShopXO 现有用户中心模板路径:app/index/view/default/user/wallet.html
约束:
- 不要新建路由,只在现有用户中心挂载
- 使用
{module_include('vr_ticket/wallet')}方式挂载(先查 ShopXO 是否支持此语法) - 如不支持,改为在
User.php控制器渲染时 include 票夹片段
Step 3 — 验证
Docker 内 curl 测试:
curl "http://localhost:10000/?s=api/vr_ticket/tickets&uid=1"
预期:返回 JSON(含 code、data 数组)
任务卡 2:B端核销 API
目标:POST /?s=api/vr_ticket/verify — 核销一张票。
文件
shopxo/app/plugins/vr_ticket/api/Ticket.php
接口规范
POST /?s=api/vr_ticket/verify
Body: { "ticket_id": 482815 }
或 { "short_code": "7J4F9X2M" }
或 { "qr_payload": "eyJpZCI6NDgyODE1L..." }
Response:
成功: { "code": 0, "msg": "核销成功", "data": { "ticket_id": 482815, "verified_at": "..." } }
失败: { "code": 1, "msg": "票不存在/已核销/无权核销" }
实现
public function verify()
{
// 1. 解析请求(支持 ticket_id / short_code / qr_payload 三种入口)
// 2. 短码解码: ShortCodeService::decode($short_code) → [goods_id, ticket_id]
// 3. QR payload 验签: WalletService::verifyQrPayload($qr_payload) → ticket_id
// 4. TicketService::verifyTicket($ticketId, $verifierId)
// 5. AuditService::log() 记录
// 6. 返回结果
}
约束
- 不写死
$verifierId = 1— 从$_POST['verifier_id']或 Session 读取 - 验签失败的 QR payload 返回 code=1(不暴露内部错误)
- 日志必须写入
vr_audit_log表
任务卡 3:B端核销页面
目标:在 ShopXO 后台 admin 侧边栏新增「票务核销」菜单项。
文件
- 控制器:
shopxo/app/plugins/vr_ticket/admin/Admin.php— 新增Verify()方法 - 视图:
shopxo/app/plugins/vr_ticket/view/admin/verify.html
实现要点
- 侧边栏入口:通过
event.php的plugins_service_admin_menu_datahook(如已注册则跳过此步) - 核销页面:两个入口
- 扫码抢扫入 → 输入 QR payload 或 ticket_id
- 手动输入短码
- UI 风格:复用 ShopXO Layui(
am-btn、am-form等 class) - 核销结果展示:成功后显示票面信息(场次/座位/观演人姓名),并更新数据库状态
参考文件
- 已有后台视图:
shopxo/app/plugins/vr_ticket/view/admin/setup.html - 已有后台控制器风格:
shopxo/app/plugins/vr_ticket/admin/Admin.php
任务卡 4:出票链路闭环(支付成功 → 发票)
目标:ShopXO 订单支付成功后,自动触发 TicketService::issueTicket()。
现状分析
- ShopXO 订单表
vrt_orders有order_status字段 vrt_vr_tickets表已存在(001_migration),字段完整TicketService::issueTicket()已实现(需要确认参数格式)
需要做的事
找到 ShopXO 支付成功的事件钩子:
plugins_service_order_pay_success_handle_end
(在 event.php 的 vr_ticket hooks 中已注册,需要确认是否在运行)
- 确认此 hook 能否收到
$params['order_id'] - 确认
$params中有哪些可用数据(收货地址、观演人信息等) - 如 hook 数据不足,改为监听更早的事件(如
plugins_service_orders_save_thing_end)
参考
Phase 4 Plan §5:「支付回调链路」
任务卡 5:Migration 002 — 补全票夹所需表/字段
目标:检查 001_migration 是否缺少票夹必要的字段,补全。
需要确认的字段
vrt_vr_tickets
✅ id (BIGINT PK)
✅ order_id (BIGINT)
✅ goods_id (BIGINT)
✅ user_id (BIGINT)
✅ seat_info (JSON) — 场次/座位信息
✅ verify_status (TINYINT) — 0=未核销 1=已核销
✅ verified_at (DATETIME, NULL)
✅ created_at
❓ user_name (VARCHAR) — 观演人姓名,从哪来?
❓ user_phone (VARCHAR) — 观演人电话,从哪来?
执行方式
- 写
database/migrations/002_ticket_wallet.sql - 确认每个字段的来源(订单表?商品表?支付回调参数?)
- 不要直接执行 — 提交 SQL 文件,用户在本地 Docker 验证后再执行
约束提醒(必读)
- ShopXO 核心文件禁止修改 —
shopxo/app/、shopxo/config/等禁止改动,插件代码放在shopxo/app/plugins/vr_ticket/ - 数据库操作必须以 migration SQL 文件提交 — 不要直接 docker exec mysql 执行
- Docker 操作尽量避免 — 优先在宿主机写文件,重启容器验证
- commit 前必须自检 —
git status,确认没有意外改动 ShopXO 核心文件 - 任务完成后汇报格式:
- ✅ 完成:做了XX
- ⚠️ 阻塞:缺少XX,需要用户确认
- ❌ 失败:XX 报错,尝试了YY未能解决
最后更新:2026-04-24 by 西莉雅