From 5dcf4286c8567e186bdb082ce8cb3d10f8cd69c6 Mon Sep 17 00:00:00 2001 From: Council Date: Wed, 15 Apr 2026 14:59:30 +0800 Subject: [PATCH] docs: add Phase 2 development log + research archive MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - PHASE2_DEVELOPMENT_LOG.md: 完整交付物清单、修复记录、安全审计 - PHASE2_RESEARCH_ARCHIVE.md: Council 研究方向归档(BR-1~BR-5 / R-1~R-5 / FR-1~FR-5) - .gitignore: 排除 .worktrees/ 目录 --- .gitignore | 6 + docs/PHASE2_DEVELOPMENT_LOG.md | 223 ++++++++++++++++++++++++++++++++ docs/PHASE2_RESEARCH_ARCHIVE.md | 211 ++++++++++++++++++++++++++++++ 3 files changed, 440 insertions(+) create mode 100644 .gitignore create mode 100644 docs/PHASE2_DEVELOPMENT_LOG.md create mode 100644 docs/PHASE2_RESEARCH_ARCHIVE.md diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0c3b3f5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +# git worktree metadata (do not commit worktrees) +.worktrees/ + +# ShopXO runtime files +shopxo/runtime/ +shopxo/vendor/ (if not committed) diff --git a/docs/PHASE2_DEVELOPMENT_LOG.md b/docs/PHASE2_DEVELOPMENT_LOG.md new file mode 100644 index 0000000..180bf36 --- /dev/null +++ b/docs/PHASE2_DEVELOPMENT_LOG.md @@ -0,0 +1,223 @@ +# Phase 2 — 后台管理开发日志 + +> 状态:✅ 完成 +> 时间:2026-04-15 04:36 — 14:30 CST +> 执行方式:Council 讨论(BackendArchitect + SecurityEngineer + FrontendDev,5轮)+ 西莉雅独立资料归档 + +--- + +## 1. 目标 + +完成 vr-shopxo-plugin 后台管理页面开发,涵盖: + +1. 座位模板管理(CRUD) +2. 电子票列表 / 详情 / 导出 +3. 核销员管理(增删改查) +4. 核销记录查询 +5. Admin 控制器鉴权修复(P1) +6. 审计日志(敏感操作记录) + +--- + +## 2. 交付物清单 + +### 2.1 数据库层 + +| 表名 | 说明 | 关键字段 | +|------|------|---------| +| `vr_seat_templates` | 座位模板 | name, category_id, seat_map, spec_base_id_map, status | +| `vr_tickets` | 电子票 | ticket_code, qr_data, verify_status, verifier_id, real_name/phone/id_card | +| `vr_verifiers` | 核销员 | user_id, name, status | +| `vr_verifications` | 核销记录 | ticket_id, verifier_id, verifier_name, goods_id, created_at | +| `vr_audit_log` | 审计日志(append-only) | action, operator_id, target_type, target_id, client_ip, user_agent, request_id, extra | + +**索引:** +```sql +vr_tickets: KEY idx_goods_id(id), idx_ticket_code(ticket_code), idx_verify_status(verify_status) +vr_verifications: KEY idx_ticket_id(ticket_id), idx_verifier_id(verifier_id) +vr_audit_log: KEY idx_action, idx_operator_id, idx_target, idx_created_at +``` + +--- + +### 2.2 控制器层 + +| 文件 | 职责 | 关键方法 | +|------|------|---------| +| `admin/controller/Base.php` | 鉴权基类(继承 Common) | `__construct()` → IsLogin + IsPower | +| `admin/controller/SeatTemplate.php` | 座位模板 CRUD | list / save / delete | +| `admin/controller/Ticket.php` | 电子票管理 | list / detail / verify / export | +| `admin/controller/Verifier.php` | 核销员管理 | list / save / delete | +| `admin/controller/Verification.php` | 核销记录查询 | list | + +--- + +### 2.3 服务层 + +| 文件 | 职责 | +|------|------| +| `service/BaseService.php` | 基础工具(table前缀/UUID/AES QR加密/AdminPowerMenu) | +| `service/TicketService.php` | 核销事务(含 FOR UPDATE 悲观锁) | +| `service/AuditService.php` | 审计日志(12种操作类型,append-only) | + +--- + +### 2.4 视图层 + +| 路径 | 说明 | +|------|------| +| `admin/view/seat_template/list.html` | 座位模板列表 | +| `admin/view/seat_template/save.html` | 座位模板新增/编辑 | +| `admin/view/ticket/list.html` | 电子票列表(含搜索/筛选/导出) | +| `admin/view/ticket/detail.html` | 电子票详情 + QR码 + 手动核销 | +| `admin/view/verifier/list.html` | 核销员列表 | +| `admin/view/verifier/save.html` | 核销员新增/编辑 | +| `admin/view/verification/list.html` | 核销记录列表 | + +--- + +## 3. 关键修复记录 + +### P0:插件后台鉴权失败(卡死 4-5 小时的历史问题) + +**根因:** 插件 `Base` 只调用 `AdminService::LoginInfo()`,跳过了 ShopXO `Common` 的完整鉴权链(`IsLogin()` + `IsPower()` + `FormTableInit()`)。 + +**修复:** +```php +// 修复前(错误) +class Base { + public function __construct() { + \app\service\AdminService::LoginInfo(); // 只填充 $this->admin,跳过权限检查 + } +} + +// 修复后(正确) +abstract class Base extends \app\admin\controller\Common { + public function __construct() { + parent::__construct(); // 触发完整鉴权链 + } +} +``` + +**修复后鉴权链:** +``` +ThinkPHP → admin.php → Common::__construct() + → AdminService::LoginInfo() 填充 $this->admin + → AdminPowerService::PowerMenuInit() 权限菜单 + → ViewInit() 视图初始化 +→ 插件控制器(extends Base) + → parent::__construct() → 自动获得上述所有鉴权 +``` + +--- + +### P1:Verifier.php CONCAT SQL 语法错误 + +**问题:** `column('CONCAT(nickname, "/", username)')` — ThinkPHP `column()` 不支持原始 SQL。 + +**修复:** 改用 `select()` + PHP 遍历拼接: +```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'] ?: ''); +} +``` + +--- + +### P1:Verification.php column() 多字段映射 Bug + +**问题:** `column('seat_info,real_name,goods_id', 'id')` — 返回结构与代码预期不符。 + +**修复:** 同样改用 `select()` + PHP 关联数组。 + +--- + +### P1:导出按钮 GET → POST + +**问题:** `ticket/list.html` 的导出按钮是 `` GET 链接,但 `Ticket::export()` 要求 `IS_AJAX_POST`。 + +**修复:** 改为 `