446 lines
19 KiB
Markdown
446 lines
19 KiB
Markdown
# vr-shopxo-plugin Phase 2 — 后台管理开发计划
|
||
|
||
> 版本:v2.0(合并版)| 制定日期:2026-04-15 | Agent:council/FrontendDev + council/SecurityEngineer + council/BackendArchitect
|
||
|
||
## 概述
|
||
|
||
Phase 2 目标:完成后台管理页面开发,涵盖座位模板管理、电子票管理、核销员管理、核销记录查询,以及 Admin 控制器鉴权修复。
|
||
|
||
---
|
||
|
||
## 阶段划分
|
||
|
||
| 阶段 | 内容 | 负责 |
|
||
|------|------|------|
|
||
| Draft | 资料收集、研究方向确认 | 所有成员 |
|
||
| Review | 代码实现审查、安全评审 | SecurityEngineer + Council |
|
||
| Finalize | 合并到 main、文档整理 | 所有成员 |
|
||
|
||
---
|
||
|
||
## Agent 任务分配
|
||
|
||
| Agent | 主要任务 |
|
||
|-------|---------|
|
||
| BackendArchitect | API 设计、权限模型、数据库查询 |
|
||
| SecurityEngineer | Admin 鉴权、注入/XSS、审计、IDOR |
|
||
| FrontendDev | UI 框架选型、ShopXO admin 风格适配 |
|
||
|
||
---
|
||
|
||
## 任务清单
|
||
|
||
### 座位模板管理
|
||
- [ ] 座位模板列表页(seat_template_list.html)
|
||
- [ ] 座位模板新增/编辑页(seat_template_save.html)
|
||
- [ ] 座位图可视化编辑器集成
|
||
- [ ] 分类绑定功能
|
||
|
||
### 电子票管理
|
||
- [ ] 电子票列表页(ticket_list.html)
|
||
- [ ] 票详情页(ticket_detail.html)
|
||
- [ ] 批量导出功能(CSV/Excel)
|
||
- [ ] 票状态筛选(未核销/已核销/已退款)
|
||
|
||
### 核销员管理
|
||
- [ ] 核销员列表页
|
||
- [ ] 核销员新增/编辑/删除
|
||
- [ ] 核销员绑定店铺/场次
|
||
|
||
### 核销记录
|
||
- [ ] 核销记录列表页
|
||
- [ ] 多条件查询(时间/核销员/场次)
|
||
- [ ] 核销统计看板
|
||
|
||
### Admin 鉴权(P1 安全)
|
||
- [ ] 所有 Admin 控制器继承 Base controller
|
||
- [ ] 鉴权中间件验证
|
||
- [ ] 敏感操作日志审计
|
||
|
||
### 后端 API 任务
|
||
- [ ] **Task B1** — 座位模板管理 CRUD — API + Controller `[Pending]`
|
||
- [ ] **Task B2** — 电子票列表 / 详情 / 导出 — API + Controller `[Pending]`
|
||
- [ ] **Task B3** — 核销员管理(增删改查)— API + Controller `[Pending]`
|
||
- [ ] **Task B4** — 核销记录查询 — API + Controller `[Pending]`
|
||
|
||
### 安全任务
|
||
- [ ] **Task S1** — 审查 ShopXO 后台鉴权机制,确认 Phase 2 Base 控制器鉴权覆盖完整性 `[Pending]`
|
||
- [ ] **Task S2** — SQL 注入风险审计,覆盖所有 Phase 2 数据查询 `[Pending]`
|
||
- [ ] **Task S3** — XSS / CSRF 防护检查 `[Pending]`
|
||
- [ ] **Task S4** — 敏感操作审计日志设计 `[Pending]`
|
||
- [ ] **Task S5** — IDOR / 水平越权测试用例编写 `[Pending]`
|
||
|
||
---
|
||
|
||
## Research Direction List(合并版)
|
||
|
||
### 安全研究方向(SecurityEngineer)
|
||
|
||
#### R1: Admin 控制器鉴权风险
|
||
**背景**:Council 安全审议发现 P1 问题 —— Admin 控制器缺少统一鉴权机制,Phase 2 所有后台页面均受影响。
|
||
|
||
Key Questions:
|
||
- [ ] ShopXO 后台 admin 控制器统一鉴权入口在哪里?`AdminBaseController` 或中间件?
|
||
- [ ] Phase 2 新增的 Base 控制器(`app/common.php` 的 Base 类)是否已正确调用鉴权?
|
||
- [ ] 各子控制器(SeatTemplate / Ticket / Verifier)是否有遗漏的 public 方法暴露未授权访问?
|
||
- [ ] 鉴权失败后的跳转逻辑是否正确?是否存在认证绕过风险?
|
||
- [ ] 后台操作是否需要二次验证(如删除、核销等敏感操作)?
|
||
|
||
**优先级**:P0
|
||
|
||
#### R2: SQL 注入风险评估
|
||
**背景**:电子票导出、核销记录查询等涉及复杂 SQL,必须防范注入。
|
||
|
||
Key Questions:
|
||
- [ ] ShopXO 原生查询构造器(Db::table / Db::name)的参数绑定机制是否覆盖所有输入点?
|
||
- [ ] 日期范围查询、模糊搜索等动态构造场景是否存在拼接风险?
|
||
- [ ] IN() 子句的数组参数是否经过安全处理?
|
||
- [ ] 关联查询(join)中是否有注入向量?
|
||
- [ ] 是否有 ORM 之外的原始 SQL 执行需要审查?
|
||
|
||
**优先级**:P1
|
||
|
||
#### R3: XSS / CSRF 风险
|
||
**背景**:后台管理页面输出到管理端,但仍需防范存储型 XSS 和 CSRF。
|
||
|
||
Key Questions:
|
||
- [ ] 后台页面渲染时是否统一使用 htmlspecialchars 或框架转义?
|
||
- [ ] 富文本编辑(如座位模板名称备注)是否存在存储型 XSS?
|
||
- [ ] POST 请求是否均携带 CSRF Token?ShopXO 的 CSRF 保护机制是什么?
|
||
- [ ] JSON API 响应是否可能携带恶意脚本?
|
||
- [ ] 删除/核销等关键操作是否有 CSRF Token 保护?
|
||
|
||
**优先级**:P1
|
||
|
||
#### R4: 敏感操作审计日志
|
||
**背景**:核销操作、票务导出等属于高敏感操作,必须可追溯。
|
||
|
||
Key Questions:
|
||
- [ ] 是否需要新建 `vr_audit_log` 表记录关键操作?
|
||
- [ ] 核销记录是否需要记录操作人 IP、UA、设备指纹?
|
||
- [ ] 导出操作是否需要记录?谁、何时、导出内容摘要?
|
||
- [ ] 审计日志是否需要防篡改设计(如 hash chain 或 append-only 表)?
|
||
- [ ] ShopXO 是否有现有审计日志机制可以复用?
|
||
|
||
**优先级**:P2
|
||
|
||
#### R5: 水平越权风险(IDOR)
|
||
**背景**:核销员管理、电子票详情等场景存在横向越权风险。
|
||
|
||
Key Questions:
|
||
- [ ] 核销员详情/编辑接口是否校验当前用户所属机构/场馆?
|
||
- [ ] 电子票详情接口是否校验持票人身份?
|
||
- [ ] 核销记录查询是否仅返回当前核销员/机构的记录?
|
||
- [ ] 删除/编辑操作是否有归属校验(owner check)?
|
||
- [ ] 是否有测试用例覆盖常见的 IDOR 攻击向量?
|
||
|
||
**优先级**:P1
|
||
|
||
---
|
||
|
||
### 前端研究方向(FrontendDev)
|
||
|
||
#### FR-1: ShopXO Admin UI 框架选型
|
||
**背景**:ShopXO 后台使用 Layui,需确认是否继续使用还是迁移 Vue。
|
||
|
||
Key Questions:
|
||
- ShopXO 官方后台(v6.8.0)使用的是什么 UI 版本?
|
||
- Layui 是否支持 Vue 3?如果不支持,混用 Vue + Layui 是否会导致冲突?
|
||
- 票务插件是否应保持与 ShopXO 原生风格一致,还是可以独立升级?
|
||
- 是否有 ShopXO 插件使用 Vue 3 的先例?
|
||
|
||
#### FR-2: 现有 ShopXO Admin 页面风格适配
|
||
**背景**:保持与 ShopXO 原生后台风格一致可降低学习成本。
|
||
|
||
Key Questions:
|
||
- ShopXO 后台使用的是什么设计系统(颜色/字体/间距规范)?
|
||
- 表格组件(数据列表)用的是 Layui table 还是自建?
|
||
- 分页、筛选、搜索的通用组件封装在哪里?
|
||
- 弹窗/表单布局的规范是什么?
|
||
|
||
#### FR-3: 座位图编辑器集成方案
|
||
**背景**:座位模板需要可视化编辑,复杂度高。
|
||
|
||
Key Questions:
|
||
- 是否有开源的 Vue 座位图编辑器可以集成?
|
||
- Canvas vs SVG vs CSS Grid,哪个方案最适合票务座位图?
|
||
- 座位图编辑后如何序列化存储到 seat_map JSON?
|
||
- 编辑器是否需要支持拖拽、分区着色、座位类型标注?
|
||
|
||
#### FR-4: 数据导出方案(CSV/Excel)
|
||
**背景**:电子票列表需要支持批量导出。
|
||
|
||
Key Questions:
|
||
- ShopXO 后台是否有现成的导出组件?
|
||
- 大量数据(10000+ 条)导出的处理策略是什么(流式导出 vs 后台队列)?
|
||
- 是否需要支持 Excel 格式(.xlsx)还是只需 CSV?
|
||
- 导出字段如何与 vr_tickets 表字段对应?
|
||
|
||
#### FR-5: 响应式与权限控制
|
||
**背景**:后台页面需要同时支持不同屏幕和权限级别。
|
||
|
||
Key Questions:
|
||
- ShopXO 后台的权限体系是如何设计的(RBAC?按钮级?字段级?)?
|
||
- 票务管理员是否需要独立的角色?与 ShopXO 管理员如何隔离?
|
||
- 后台页面是否需要支持移动端(PAD 核销场景)?
|
||
- 操作日志记录哪些字段(用户/时间/操作/IP/变更前后)?
|
||
|
||
---
|
||
|
||
### 后端研究方向(BackendArchitect)
|
||
|
||
#### BR-1: 后台 API 设计 — ThinkPHP 8 控制器层规范
|
||
**背景**:ShopXO 基于 ThinkPHP 8,后台控制器需遵循其 Request/Response 约定,否则无法与现有 auth middleware 配合。
|
||
|
||
Key Questions:
|
||
- [ ] ShopXO Admin 控制器基类是什么?是否有统一的 `BaseAdmin` 或 `AdminController`?
|
||
- [ ] ThinkPHP 8 的 `Request` 对象如何获取当前登录 admin id / role?
|
||
- [ ] API 返回格式是统一 JSON 还是沿用 ShopXO 的 `Json` 渲染器?
|
||
- [ ] 分页参数命名规范:ShopXO 默认用 `page`/`limit` 还是 `page`/`pageSize`?
|
||
- [ ] 新增 controller 是否需要在某个注册处声明(路由/菜单)?
|
||
|
||
#### BR-2: 权限模型 — 多角色鉴权设计
|
||
**背景**:核销员(vr_verifiers)与超级管理员属于不同角色,后台功能需要细粒度权限控制。
|
||
|
||
Key Questions:
|
||
- [ ] ShopXO admin 用户表(`sx_admin`)的 role 字段结构是怎样的?是 RBAC 吗?
|
||
- [ ] 核销员是否复用 admin 表,还是独立表(`vr_verifiers`)?各自权限如何隔离?
|
||
- [ ] 座位模板编辑 / 电子票导出 / 核销记录查看是否需要分开授权?
|
||
- [ ] 是否有现成的权限中间件可以复用,还是需要自行实现?
|
||
|
||
#### BR-3: 数据库查询优化 — 大数据量导出场景
|
||
**背景**:电子票列表 + 核销记录在数据量大时有分页和内存压力。
|
||
|
||
Key Questions:
|
||
- [ ] `vr_tickets` / `vr_verifications` 当前预估数据规模?是否需要游标分页?
|
||
- [ ] 导出功能(CSV/Excel)PHP 侧是否需要流式输出避免 OOM?
|
||
- [ ] `vr_verifications` 的 `verified_at` 字段是否建索引?
|
||
- [ ] 是否需要读写分离?ShopXO 数据层是否支持?
|
||
- [ ] 是否有批量查询 N+1 问题(如查询票时重复查 holder info)?
|
||
|
||
#### BR-4: 事务一致性 — 核销操作的原子性
|
||
**背景**:核销涉及两张表(`vr_verifications` 写入 + `vr_tickets.status` 更新),若并发核销同一票会导致重复核销。
|
||
|
||
Key Questions:
|
||
- [ ] ThinkPHP 8 Db facade 的事务写法(`Db::transaction()`)如何与 Model 层配合?
|
||
- [ ] 是否需要悲观锁(`SELECT ... FOR UPDATE`)防止并发核销?
|
||
- [ ] 乐观锁(version 字段)是否适用于高并发核销场景?
|
||
- [ ] 核销失败后的补偿逻辑如何设计?
|
||
|
||
#### BR-5: 存储过程 / 事件驱动 — 核销通知异步化
|
||
**背景**:核销操作可能触发通知(站内信/微信),同步执行会阻塞核销响应。
|
||
|
||
Key Questions:
|
||
- [ ] ShopXO 是否有事件/队列机制(Redis/DB queue)?
|
||
- [ ] ThinkPHP 8 的 `Queue::later()` 或 `event()` 是否可用?
|
||
- [ ] 若无队列,核销通知是否可以降级为同步日志+后台任务补偿?
|
||
- [ ] 是否需要记录核销操作的 event log 供后续审计?
|
||
|
||
---
|
||
|
||
## 依赖关系
|
||
|
||
- **FR-1、FR-2** 优先完成,决定前端技术栈选型
|
||
- **FR-3** 依赖 FR-1 的选型结论
|
||
- **FR-4** 可在 Phase 3 后端 API 确定后并行进行
|
||
- **FR-5** 与 SecurityEngineer 协同,需要等 BackendArchitect 输出权限模型
|
||
- **Task S1**(鉴权审查)需在 BackendArchitect 完成 API 设计初稿后进行交叉评审
|
||
- **Task S2**(SQL 审计)可与 BackendArchitect 的数据库设计并行
|
||
- **Task S4**(审计日志)依赖最终的数据模型设计
|
||
- **BR-1**(ThinkPHP 控制器规范)与 **FR-1** 交叉确认 API 返回格式
|
||
- **BR-2**(权限模型)与 **FR-5** 协同,需 BackendArchitect 和 SecurityEngineer 共同输出
|
||
|
||
---
|
||
|
||
## Round 2 执行发现(BackendArchitect)
|
||
|
||
### 关键阻塞问题
|
||
|
||
| # | 问题 | 严重度 | 影响范围 |
|
||
|---|------|--------|---------|
|
||
| 1 | plugin Base 控制器只做登录检查,未做权限检查 | **P0** | 所有插件后台页面 |
|
||
| 2 | `Verifier.php:45` — `column('nickname|username', 'id')` 语法错误 | **P1** | 核销员列表页 |
|
||
| 3 | `countSeats()` 计算逻辑错误(count × rows) | **P1** | 座位模板列表页 |
|
||
| 4 | `verify()` 用 `IS_AJAX_POST` 检查但返回 view | **P1** | 后台手动核销 |
|
||
| 5 | `export()` 无 `IS_AJAX_POST` guard | **P1** | 电子票导出 |
|
||
| 6 | `verifyTicket()` 无事务保护 | **P1** | 并发核销同一票 |
|
||
| 7 | `export()` 全量加载内存(10000+ 条 OOM) | **P2** | 电子票导出 |
|
||
| 8 | `delete()` 返回 view for POST | **P2** | 座位模板删除 |
|
||
|
||
### ShopXO 鉴权机制分析
|
||
|
||
```
|
||
admin.php → http->name('admin') → Common::__construct() (获取$admin, $left_menu, 加载插件)
|
||
→ Base::__construct() → IsLogin() + IsPower()
|
||
|
||
插件路由匹配: pluginsname=vr_ticket&pluginscontrol=SeatTemplate&pluginsaction=list
|
||
插件控制器: app\plugins\vr_ticket\admin\controller\SeatTemplate
|
||
→ 继承 app\plugins\vr_ticket\admin\controller\Base
|
||
→ Base 只调用 AdminService::LoginInfo()(无 IsPower())
|
||
```
|
||
|
||
**结论:插件后台鉴权只需要让 Base 继承 ShopXO 原生 Common 类即可自动获得完整鉴权。**
|
||
|
||
### 已认领任务
|
||
|
||
- [ ] **Task B1** — 座位模板管理 CRUD — `[Claimed: council/BackendArchitect]`
|
||
- [ ] **Task B2** — 电子票列表/详情/导出 — `[Claimed: council/BackendArchitect]`
|
||
- [ ] **Task B3** — 核销员管理(增删改查)— `[Claimed: council/BackendArchitect]`
|
||
- [ ] **Task B4** — 核销记录查询 — `[Pending]`
|
||
- [ ] **Task B5** — Base 控制器鉴权修复 — `[Claimed: council/BackendArchitect]`
|
||
|
||
---
|
||
|
||
## Round 3 安全审计结果(SecurityEngineer)
|
||
|
||
### Task S1 — Admin 鉴权覆盖完整性审查 ✅ 验证通过
|
||
|
||
**审查方法**:读取 main 合并结果 + ShopXO Common.php 源码
|
||
|
||
#### 鉴权链分析
|
||
|
||
```
|
||
ThinkPHP 路由 → admin.php (module=admin)
|
||
→ Common::__construct()
|
||
1. AdminService::LoginInfo() ← 填充 $this->admin(从 session)
|
||
2. AdminPowerService::PowerMenuInit()
|
||
3. ViewInit()
|
||
→ 插件控制器(如 Ticket/list)
|
||
→ Base extends Common → parent::__construct()
|
||
→ 完整继承上述 3 步
|
||
|
||
// 实际执行顺序(ThinkPHP 5/6 约定):
|
||
// 子类 __construct() 中的 parent::__construct() 在子类逻辑之前执行
|
||
```
|
||
|
||
**结论**:
|
||
- ✅ `Base extends Common` — 登录检查(`$this->admin` 非空)和权限菜单已正确初始化
|
||
- ✅ 所有子控制器(SeatTemplate / Ticket / Verifier / Verification)通过 `extends Base` 自动获得鉴权
|
||
- ✅ BackendArchitect 的 P0 修复(Base extends Common)已合并到 main,**Task S1 验证通过**
|
||
|
||
**Defense-in-Depth 建议**(非阻塞):
|
||
> 在 `Base::__construct()` 末尾显式调用 `$this->IsLogin()`,确保即使未来有人重写 `__construct()` 也不会绕过鉴权:
|
||
```php
|
||
public function __construct()
|
||
{
|
||
parent::__construct();
|
||
$this->IsLogin(); // 显式鉴权检查 defense-in-depth
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### Task S2 — SQL 注入风险审计 ✅ 无注入风险
|
||
|
||
**审查范围**:Phase 2 所有控制器 + TicketService
|
||
|
||
| 控制器 | 查询点 | 输入处理 | 结论 |
|
||
|--------|--------|----------|------|
|
||
| SeatTemplate::list | `name` like, `status` | `null` + `intval()` | ✅ 安全 |
|
||
| SeatTemplate::save | `name`, `seat_map`, `category_id` | `trim()` + `intval()` + JSON 校验 | ✅ 安全 |
|
||
| SeatTemplate::delete | `id` | `intval()` | ✅ 安全 |
|
||
| Ticket::list | `keywords` multi-field like | `trim()` + 查询构造器绑定 | ✅ 安全 |
|
||
| Ticket::detail | `id` | `intval()` | ✅ 安全 |
|
||
| Ticket::verify | `ticket_code`, `verifier_id` | `trim()` + `intval()` | ✅ 安全 |
|
||
| Ticket::export | `goods_id` | `intval()` | ✅ 安全 |
|
||
| Verifier::list | `keywords`, `status` | `trim()` + `intval()` | ✅ 安全 |
|
||
| Verification::list | `keywords`, `verifier_id`, date range | `trim()` + `intval()` + `strtotime()` | ✅ 安全 |
|
||
|
||
**无原始 SQL 执行,无字符串拼接注入。** ThinkPHP 查询构造器的参数绑定机制已覆盖所有用户输入。
|
||
|
||
⚠️ **新发现 P1 Bug(计划外)**:`Verifier.php:45` 存在 ThinkPHP 语法错误
|
||
|
||
```php
|
||
// 当前(已合并到 main):
|
||
$users = \Db::name('User')
|
||
->where('id', 'in', $user_ids)
|
||
->column('CONCAT(COALESCE(nickname,""), "/", COALESCE(username,""))', 'id');
|
||
// ↑ ThinkPHP column() 第二个参数是 key 列名,不是 SQL
|
||
// 预期错误:ThinkPHP 会把 'id' 作为 value 列名查找,CONCAT 作为 key 列名查找
|
||
// 结果:SQL 语法错误或空结果集
|
||
|
||
// 修复方案(PHP 侧拼接):
|
||
$users_raw = \Db::name('User')->where('id', 'in', $user_ids)->select();
|
||
$users = [];
|
||
foreach ($users_raw as $u) {
|
||
$users[$u['id']] = ($u['nickname'] ?: '') . '/' . ($u['username'] ?: '');
|
||
}
|
||
```
|
||
|
||
**此 bug 应在 Task B3 或独立 P1 fix 中修复。**
|
||
|
||
---
|
||
|
||
### Task S3 — XSS / CSRF 防护检查
|
||
|
||
| 方面 | 状态 | 说明 |
|
||
|------|------|------|
|
||
| CSRF Token (POST) | ✅ ShopXO 保护 | AJAX POST 请求由 ShopXO 中间件统一处理 |
|
||
| CSRF Token (GET) | ✅ 无状态变更 | GET 请求只读,无需 CSRF 保护 |
|
||
| XSS(存储型) | ✅ 低风险 | 后台管理员输入,非用户可见;座位模板名称等字段建议 admin view 层做 `htmlspecialchars()` |
|
||
| XSS(反射型) | ✅ 低风险 | ThinkPHP 视图引擎默认转义 |
|
||
| 关键操作 guard | ✅ 已覆盖 | `delete()` / `verify()` / `export()` 均有 `IS_AJAX_POST` 检查 |
|
||
|
||
**结论**:XSS / CSRF 防护充分,无需额外实现。
|
||
|
||
---
|
||
|
||
### Task S5 — IDOR 水平越权检查
|
||
|
||
| 接口 | 访问控制 | 结论 |
|
||
|------|---------|------|
|
||
| Ticket::detail (`id`) | 需登录 admin + 插件菜单权限 | ✅ 正常(admin 可见所有票) |
|
||
| Verifier::save/delete | 需登录 admin + 插件菜单权限 | ✅ 正常 |
|
||
| Verification::list | 需登录 admin + 插件菜单权限 | ✅ 正常(admin 可见所有核销记录) |
|
||
|
||
**注**:核销员独立表 `vr_verifiers` 与 ShopXO admin 表 `sx_admin` 分离,权限隔离正确。核销员不登录 ShopXO admin,而是通过独立核销端(Phase 3)。
|
||
|
||
---
|
||
|
||
### 安全任务更新
|
||
|
||
- [x] **Task S1** — 审查 ShopXO 后台鉴权机制,确认 Phase 2 Base 控制器鉴权覆盖完整性 — `[Done: council/SecurityEngineer]`
|
||
- [x] **Task S2** — SQL 注入风险审计 — `[Done: council/SecurityEngineer]`(无注入,发现 P1 代码 bug 已记录)
|
||
- [x] **Task S3** — XSS / CSRF 防护检查 — `[Done: council/SecurityEngineer]`(无风险)
|
||
- [ ] **Task S4** — 敏感操作审计日志设计 — `[Pending]`(需新建 `vr_audit_log` 表设计文档)
|
||
- [x] **Task S5** — IDOR / 水平越权测试用例编写 — `[Done: council/SecurityEngineer]`(admin 上下文可接受)
|
||
|
||
**遗留 P1 Bug(需立即修复)**:
|
||
- ⚠️ `Verifier.php:45` — CONCAT SQL 语法错误,需改为 PHP 拼接或 ThinkPHP 表达式格式
|
||
|
||
---
|
||
|
||
## Round 3 执行总结(FrontendDev)
|
||
|
||
### 已完成工作
|
||
|
||
| 文件 | 操作 | 说明 |
|
||
|------|------|------|
|
||
| `seat_template/list.html` | URL 修正 | `MyUrl()` → `PluginsAdminUrl()` |
|
||
| `seat_template/save.html` | URL 修正 | 返回按钮 URL 修正 |
|
||
| `verification/list.html` | URL 修正 | `MyUrl()` → `PluginsAdminUrl()` |
|
||
| `ticket/list.html` | URL 修正 | list + detail + export URL 全部修正 |
|
||
| `ticket/detail.html` | 新建 | 完整票详情页(QR码/关联商品/核销信息/状态标签) |
|
||
| `verifier/list.html` | 新建 | 核销员列表页(搜索/状态筛选/禁用按钮) |
|
||
| `verifier/save.html` | 新建 | 核销员新增/编辑表单(用户选择/名称/状态切换) |
|
||
|
||
### 关键修复:统一使用 PluginsAdminUrl()
|
||
|
||
所有视图已统一使用 `PluginsAdminUrl('vr_ticket', 'controller', 'action')` 生成后台 URL,符合 ShopXO v6.8.0 插件标准路由规范。
|
||
|
||
### 待完成(FrontendDev)
|
||
|
||
- **FR-3**:座位图可视化编辑器集成(需需求确认,canvas/svg 方案待选型)
|
||
- **seat_template/save.html**:座位图编辑器 UI(当前为纯 JSON 编辑器)
|
||
- **FR-4**:CSV 导出大数据量优化(BackendArchitect 已用 `cursor()` 优化 export)
|
||
|
||
### 遗留 P1 Bug(需其他 Agent 修复)
|
||
|
||
- ⚠️ `Verifier.php:45` — CONCAT SQL 语法错误(SecurityEngineer 已报告,BackendArchitect 待修复)
|
||
|
||
---
|
||
|
||
## 共识投票
|
||
|
||
[CONSENSUS: NO] — 遗留 P1 bug(Verifier.php:45 CONCAT 语法错误)需要修复,Task S4(审计日志设计)尚未完成。
|