vr-shopxo-plugin/docs/AGENT_TASKS.md

216 lines
7.1 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.

# 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 是否完整 |
---
## 任务卡 1C端票夹 API + 前端挂载
**目标**:用户访问票夹页 `/?s=user/wallet` 时展示 vr_ticket 票。
### Step 1 — API 端点
文件:`shopxo/app/plugins/vr_ticket/api/Ticket.php`
参考 Phase 4 Plan §3.3,新增两个方法:
```php
// 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 测试:
```bash
curl "http://localhost:10000/?s=api/vr_ticket/tickets&uid=1"
```
预期:返回 JSON含 code、data 数组)
---
## 任务卡 2B端核销 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": "票不存在/已核销/无权核销" }
```
### 实现
```php
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`
---
## 任务卡 3B端核销页面
**目标**:在 ShopXO 后台 admin 侧边栏新增「票务核销」菜单项。
### 文件
- 控制器:`shopxo/app/plugins/vr_ticket/admin/Admin.php` — 新增 `Verify()` 方法
- 视图:`shopxo/app/plugins/vr_ticket/view/admin/verify.html`
### 实现要点
1. **侧边栏入口**:通过 `event.php``plugins_service_admin_menu_data` hook如已注册则跳过此步
2. **核销页面**:两个入口
- 扫码抢扫入 → 输入 QR payload 或 ticket_id
- 手动输入短码
3. **UI 风格**:复用 ShopXO Layui`am-btn`、`am-form` 等 class
4. **核销结果展示**:成功后显示票面信息(场次/座位/观演人姓名),并更新数据库状态
### 参考文件
- 已有后台视图:`shopxo/app/plugins/vr_ticket/view/admin/setup.html`
- 已有后台控制器风格:`shopxo/app/plugins/vr_ticket/admin/Admin.php`
---
## 任务卡 4出票链路闭环支付成功 → 发票)
**目标**ShopXO 订单支付成功后,自动触发 `TicketService::issueTicket()`
### 现状分析
1. ShopXO 订单表 `vrt_orders``order_status` 字段
2. `vrt_vr_tickets` 表已存在001_migration字段完整
3. `TicketService::issueTicket()` 已实现(需要确认参数格式)
### 需要做的事
找到 ShopXO 支付成功的事件钩子:
```
plugins_service_order_pay_success_handle_end
```
(在 `event.php` 的 vr_ticket hooks 中已注册,需要确认是否在运行)
1. 确认此 hook 能否收到 `$params['order_id']`
2. 确认 `$params` 中有哪些可用数据(收货地址、观演人信息等)
3. 如 hook 数据不足,改为监听更早的事件(如 `plugins_service_orders_save_thing_end`
### 参考
Phase 4 Plan §5「支付回调链路」
---
## 任务卡 5Migration 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) — 观演人电话,从哪来?
```
### 执行方式
1.`database/migrations/002_ticket_wallet.sql`
2. 确认每个字段的来源(订单表?商品表?支付回调参数?)
3. **不要直接执行** — 提交 SQL 文件,用户在本地 Docker 验证后再执行
---
## 约束提醒(必读)
1. **ShopXO 核心文件禁止修改**`shopxo/app/`、`shopxo/config/` 等禁止改动,插件代码放在 `shopxo/app/plugins/vr_ticket/`
2. **数据库操作必须以 migration SQL 文件提交** — 不要直接 docker exec mysql 执行
3. **Docker 操作尽量避免** — 优先在宿主机写文件,重启容器验证
4. **commit 前必须自检**`git status`,确认没有意外改动 ShopXO 核心文件
5. **任务完成后汇报格式**
- ✅ 完成做了XX
- ⚠️ 阻塞缺少XX需要用户确认
- ❌ 失败XX 报错尝试了YY未能解决
---
*最后更新2026-04-24 by 西莉雅*