vr-shopxo-plugin/plan.md

4.0 KiB
Raw Blame History

Plan — DebugAgent: "Undefined array key 'id'" 调试计划

版本v1.0 | 日期2026-04-20 | Agentcouncil/DebugAgent


任务概述

调查 ShopXO 后台编辑票务商品goods_id=118保存时报错

Undefined array key "id"

根因分析摘要Round 1 快速结论)

1. 最可能触发点

AdminGoodsSaveHandle.php 第 71 行

$template = Db::name('vr_seat_templates')->find($templateId);
$seatMap  = json_decode($template['seat_map'] ?? '{}', true);  // ← 危险
  • find() 查不到记录时返回 null
  • ?? 操作符只防御 $templatenull不防御 $template 存在但键 'seat_map' 缺失
  • PHP 8+ 会报 Undefined array key "seat_map",而非 "id"

真正报 "id" 的位置——第 77 行 array_filter 回调内:

return in_array($r['id'], $config['selected_rooms'] ?? []);
//          ^^^^^^ 如果 $rroom 对象)缺少 'id' 键则触发

但如果 room 数据正常(有 id则第 71 行是实际断路点。

2. 表前缀问题(核心根因)

代码 表名方法 实际 SQL 表
BaseService::table('seat_templates') 'vr_' + 'seat_templates' vr_seat_templates
Db::name('vr_seat_templates') ThinkPHP Db::name() 取决于 database.php 配置前缀
Db::name('Goods') ThinkPHP Db::name() sxo_goods ShopXO 系统表)

ShopXO 数据库配置(需确认 shopxo/config/database.php

  • prefix = 'sxo_':则 Db::name('vr_seat_templates') → 查表 sxo_vr_seat_templates(不存在)
  • prefix = 'vrt_':则 Db::name('vr_seat_templates') → 查表 vrt_vr_seat_templates(不存在)
  • 正确表名应来自 ThinkPHP 原始前缀ShopXO 插件表一般不带前缀或用独立前缀)

SeatSkuService 使用 BaseService::table()vr_seat_templates(正确) AdminGoodsSaveHandle 使用 Db::name('vr_seat_templates') → 可能查错表(错误)

3. 如果 find($templateId) 返回 null

第 71 行:$template['seat_map']Undefined array key 'seat_map'(不是 'id' 第 72 行:$allRooms = $seatMap['rooms'] ?? []; → 此行安全(?? 防御)

4. vr_goods_config JSON 解码

$configs = json_decode($rawConfig, true);  // → array|null
if (is_array($configs) && !empty($configs)) { ... }  // 防御正确

$configs 是数组时 $config['template_id'] 访问安全(不会触发 "id" 错误)。

5. selected_rooms 数据类型

  • selected_rooms: string[]room id 数组e.g. ["room_id_xxx"]
  • $r['id']: 来自 seat_map.rooms[].id,通常是字符串
  • 类型匹配:无类型强制问题,但若 room.idnull 或缺失则触发 "id"

6. $data['item_type'] 访问安全

第 59 行:($data['item_type'] ?? '') === 'ticket' — 有 ?? 防御,安全。


任务清单Round 2 执行)

  • Task 1: 读取 shopxo/config/database.php,确认 prefix 配置值
  • Task 2: 读取 AdminGoodsSaveHandle.php 第 70-72 行,确认 $template 为 null 时实际报错信息
  • Task 3: 确认 ShopXO Db::name() 表前缀行为(查 ShopXO 源码或文档)
  • Task 4: 编写根因报告 reports/DebugAgent-ROOT_CAUSE.md
  • Task 5: 给出修复建议(用 BaseService::table() 替代 Db::name()

阶段划分

阶段 内容 状态
Draft Round 1代码静态分析定位可疑行 完成
Review Round 2读取配置文件确认表前缀输出根因报告 待做
Finalize Round 3合并报告到 main提交调试结论 待做

依赖

  • Task 1-3 必须按顺序执行(需读取配置文件)
  • 不需要 BackendArchitect / SecurityEngineer 配合,可独立完成

执行顺序

Task 1 → Task 2 → Task 3串行每步确认后立即 commit→ Task 4 → Task 5


声称

  • [Claimed: council/DebugAgent] — Task 1-5 全部