# Phase 2 — 研究资料归档

> 来源：Council 讨论（BackendArchitect + SecurityEngineer + FrontendDev，5轮）
> 整理：西莉雅（独立执行，非 Council 输出）
> 时间：2026-04-15 CST

---

## 一、后台架构研究（BR-1 ~ BR-5）

### BR-1：ThinkPHP 8 控制器层规范 ✅ 已验证

**Key Questions 结论：**

| 问题 | 答案 |
|------|------|
| ShopXO Admin 控制器基类 | `app\admin\controller\Common`，非 `BaseController` |
| 获取当前 admin id / role | `$this->admin['id']`，由 `Common::__construct()` 注入 |
| API 返回格式 | `\Json::成功()` / `\Json::fail()` 渲染器 |
| 分页参数规范 | `page` + `limit`（ThinkPHP 默认） |
| 新增 controller 路由 | 无需声明，ShopXO 自动扫描 |

**插件 Base 正确写法：**
```php
abstract class Base extends \app\admin\controller\Common {
    public function __construct() {
        parent::__construct(); // 触发 IsLogin + IsPower + ViewInit
    }
}
```

---

### BR-2：多角色鉴权模型 ⚠️ 部分实现

| 问题 | 现状 | 待 Phase 3 |
|------|------|-----------|
| ShopXO admin 角色结构 | `vrt_admin` + `vrt_admin_role`，RBAC | — |
| 核销员复用 admin 表？ | **否**，独立表 `vr_verifiers` | — |
| 权限隔离方案 | 目前所有 admin 可访问所有插件功能 | 实现 RBAC 细化 |

---

### BR-3：数据库查询优化 ✅ 已实现

| 场景 | 解决方案 |
|------|---------|
| 大数据量导出 | `cursor()` 流式游标（防 OOM） |
| 模糊搜索 | ThinkPHP 查询构造器（自动绑定参数） |
| 分页 | `paginate(20)` |
| N+1 | `column()` / `select()` + PHP 拼接 |

---

### BR-4：核销操作事务一致性 ✅ 已实现

```php
Db::transaction(function() {
    $ticket = Db::name('tickets')
        ->where('ticket_code', $ticket_code)
        ->lock(true)  // FOR UPDATE SKIP LOCKED
        ->find();
    // 状态校验 + 更新 + 写入 vr_verifications
});
```

---

### BR-5：事件驱动/异步队列 ❌ 待 Phase 3

- ShopXO 有 `think_queue`（Redis/DB）
- 核销通知同步执行暂无问题，队列化留 Phase 3

---

## 二、安全研究方向（R-1 ~ R-5）

### R1：Admin 控制器鉴权风险 ✅ 已解决

**根因：** 插件 `Base` 只调 `LoginInfo()`，未调用 `IsLogin()` + `IsPower()` + `FormTableInit()`。

**修复后鉴权链：**
```
ThinkPHP → admin.php → Common::__construct()
  1. AdminService::LoginInfo() — 填充 $this->admin
  2. AdminPowerService::PowerMenuInit() — 权限菜单
  3. ViewInit() — 视图初始化
→ 插件控制器（extends Base）→ parent::__construct()
  → 完整继承上述 3 步
```

**Defense-in-Depth 建议：** 在 `Base::__construct()` 末尾显式调用 `$this->IsLogin()`。

---

### R2：SQL 注入风险 ✅ 无注入

| 控制器 | 查询点 | 输入处理 | 结论 |
|--------|--------|----------|------|
| SeatTemplate::list | `name` like, `status` | `null` + `intval()` | ✅ |
| Ticket::list | `keywords` multi-field like | `trim()` + 查询构造器绑定 | ✅ |
| Ticket::verify | `ticket_code`, `verifier_id` | `trim()` + `intval()` | ✅ |
| Verification::list | date range | `strtotime()` 绑定 | ✅ |

---

### R3：XSS / CSRF ✅ 低风险

| 方面 | 状态 |
|------|------|
| CSRF Token (POST) | ✅ ShopXO 保护 |
| XSS（存储型） | ✅ 低风险（admin 上下文） |
| 关键操作 guard | ✅ `delete()` / `verify()` / `export()` 均有 `IS_AJAX_POST` |

---

### R4：敏感操作审计日志 ✅ 已实现

**vr_audit_log 字段：**
`action` / `operator_id` / `operator_name`（冗余） / `target_type` / `target_id` / `target_desc`（冗余） / `client_ip`（IPv6） / `user_agent` / `request_id` / `extra`（JSON快照） / `created_at`

**索引：** `idx_action` / `idx_operator_id` / `idx_target` / `idx_created_at`

**防篡改：** append-only 表，无 UPDATE/DELETE 接口。

---

### R5：水平越权（IDOR）✅ Admin 上下文安全

**潜在盲区（待 Phase 3）：**
- 核销员详情/编辑接口是否校验归属机构？
- 电子票详情接口是否校验持票人身份？
- 核销记录查询是否仅返回当前核销员/机构记录？

---

## 三、前端研究方向（FR-1 ~ FR-5）

### FR-1：ShopXO Admin UI 框架 ✅ Layui

| 选项 | 结论 |
|------|------|
| Layui 2.x | ✅ 继续使用，零迁移成本 |
| Vue 3 | ❌ 不支持，混用会导致冲突 |

---

### FR-2：ShopXO Admin 风格适配 ✅ 已适配

```php
// ✅ 正确
PluginsAdminUrl('vr_ticket/ticket/list')

// ❌ 错误
MyUrl('ticket/list')
```

---

### FR-3：座位图编辑器 ⚠️ 待 Phase 3

- 需产品需求确认（Canvas/SVG/Grid？）
- `seat_map` JSON 字段已预留

---

### FR-4：数据导出方案 ✅ CSV 已实现，.xlsx 待 Phase 3

| 项目 | 现状 |
|------|------|
| CSV 导出 | ✅ `cursor()` 流式，防 OOM |
| 导出按钮 | ✅ POST-only form |
| Excel .xlsx | ❌ 待 Phase 3 |

---

### FR-5：响应式与权限控制 ⚠️ 部分实现

- 权限体系复用 ShopXO RBAC
- 移动端 PAD 核销场景待 Phase 3

---

## 四、Phase 3 待办清单

### 需产品确认
- [ ] FR-3：座位图可视化编辑器需求
- [ ] FR-5：PAD 核销场景是否需要独立移动端页面？
- [ ] BR-2：核销员账号体系（复用 admin 还是独立？）

### 技术待办
- [ ] Defense-in-Depth：`Base::__construct()` 末尾显式调用 `IsLogin()`
- [ ] R5 盲区验证：IDOR 归属校验
- [ ] BR-5：核销通知队列化（think_queue）
- [ ] FR-4：CSV 导出携带搜索条件
- [ ] FR-4：Excel .xlsx 格式支持
- [ ] BR-2：插件独立权限（菜单级/操作级）

---

## 五、关键文件索引

| 文件 | 说明 |
|------|------|
| `app/plugins/vr_ticket/admin/controller/Base.php` | 鉴权基类（已修复） |
| `app/plugins/vr_ticket/service/AuditService.php` | 审计日志服务 |
| `app/plugins/vr_ticket/service/TicketService.php` | 核销事务（含 FOR UPDATE） |
| `app/plugins/vr_ticket/admin/controller/Ticket.php` | 电子票 CRUD + export |
| `app/plugins/vr_ticket/admin/controller/Verifier.php` | 核销员管理 |
| `app/plugins/vr_ticket/EventListener.php` | vr_audit_log 建表 SQL |
| `shopxo/app/admin/controller/Common.php` | ShopXO 鉴权链源码 |
