# VR-ShopXO-Plugin 删除逻辑审查报告 **审查时间:** 2026-04-20 **审查人:** 西莉雅审查助手 **审查文件:** - `shopxo/app/plugins/vr_ticket/admin/Admin.php` - `shopxo/app/plugins/vr_ticket/view/venue/list.html` --- ## 一、发现的问题列表 ### 🔴 问题 1:`SeatTemplateDelete` 中使用了不存在的 `is_delete` 列(严重) | 属性 | 值 | |------|-----| | **文件** | `Admin.php` | | **方法** | `SeatTemplateDelete` (第 227 行) | | **行号** | 第 249-251 行 | | **问题** | Goods 查询使用 `is_delete = 0`,但 ShopXO 的 Goods 表使用 `is_delete_time` 进行软删除判断 | ```php // ❌ 错误代码(第 249-251 行) $goods = \think\facade\Db::name('Goods') ->where('vr_goods_config', 'like', '%"template_id":' . $id . '%') ->where('is_delete', 0) // ← ShopXO 没有 is_delete 列! ->find(); ``` **错误信息:** ``` SQLSTATE[42S22]: Column not found: 1054 Unknown column 'is_delete' in 'where clause' ``` **根本原因:** 复制粘贴自 ShopXO 原型代码时遗留的错误字段名。ShopXO 的商品软删除使用 `is_delete_time`(时间戳),`is_delete` 列根本不存在。 --- ### 🔴 问题 2:`VenueDelete` 中同样使用了不存在的 `is_delete` 列 | 属性 | 值 | |------|-----| | **文件** | `Admin.php` | | **方法** | `VenueDelete` (第 857 行) | | **行号** | 第 885-889 行 | | **问题** | 与 `SeatTemplateDelete` 相同的问题 | ```php // ❌ 错误代码(第 885-889 行) $goods = \think\facade\Db::name('Goods') ->where('vr_goods_config', 'like', '%"template_id":' . $id . '%') ->where('is_delete', 0) // ← 同样错误! ->find(); ``` --- ### 🟡 问题 3:`list.html` 残留了旧的 custom JS 删除弹窗代码 | 属性 | 值 | |------|-----| | **文件** | `view/venue/list.html` | | **行号** | 第 137-168 | | **问题** | 删除按钮已改用 `submit-ajax`(正确),但旧的 custom JS 弹窗和 `.btn-open-delete-confirm` 处理器仍残留,造成代码污染 | 删除按钮已正确更新为: ```html ``` 但页面底部仍残留: - `#venue-confirm-delete-modal` 弹窗 HTML(第 137-151 行) - `.btn-open-delete-confirm` 点击处理器(第 155-158 行) - `.btn-do-real-delete` 弹窗确认处理器(第 160-175 行) --- ### 🟢 确认正常:方法命名问题(非 bug) | 观察 | 说明 | |------|-----| | `vr_seat_templates` 表 | 实际上存储的就是"场馆/场地模板"数据,不是"座位模板" | | `VenueDelete` / `SeatTemplateDelete` | 两个方法名不同,但都操作同一张表 `vr_seat_templates` | | **结论** | 表名和方法名的命名不一致是历史遗留的设计问题,但不影响功能 | --- ## 二、根本原因分析 ### 为什么会发生? 1. **复制粘贴错误** — 两个方法从 ShopXO 原型代码复制过来时,`Goods` 表的软删除字段用了错误的名称 `is_delete`,而 ShopXO 实际使用 `is_delete_time` 2. **残留代码未清理** — 前端删除按钮从 custom JS 方式迁移到 `submit-ajax` 后,旧的弹窗 HTML 和 JS 事件处理器没有一起移除 3. **缺少 Code Review** — 没有在 PR 阶段发现字段名错误 ### 软删除 vs 硬删除逻辑梳理 | 方法 | 软删除触发条件 | 硬删除触发条件 | 表 | |------|---------------|---------------|-----| | `SeatTemplateDelete` | `hard_delete=0`(默认) | `hard_delete=1` 或 `value=hard` | `vr_seat_templates` | | `VenueDelete` | `hard_delete=0`(默认) | `hard_delete=1` 或 `value=hard` | `vr_seat_templates` | | `VerifierDelete` | **仅软删除**(无硬删除选项) | 无 | `vr_verifiers` | **注意:** `VerifierDelete` 只有软删除(设置 `status=0`),这是正确的业务设计。 --- ## 三、修复代码(diff 格式) ### 修复 1:`SeatTemplateDelete` 的 `is_delete` 错误 **文件:** `Admin.php` 第 249-251 行 ```diff if ($hardDelete) { - $goods = \think\facade\Db::name('Goods') - ->where('vr_goods_config', 'like', '%"template_id":' . $id . '%') - ->where('is_delete', 0) + // 检查是否有关联商品(ShopXO 使用 is_delete_time 做软删除判断) + $goods = \think\facade\Db::name('Goods') + ->where('vr_goods_config', 'like', '%"template_id":' . $id . '%') + ->where('is_delete_time', 0) ->find(); ``` ### 修复 2:`VenueDelete` 的 `is_delete` 错误 **文件:** `Admin.php` 第 885-889 行 ```diff if ($hardDelete) { - $goods = \think\facade\Db::name('Goods') - ->where('vr_goods_config', 'like', '%"template_id":' . $id . '%') - ->where('is_delete', 0) + // 检查是否有关联商品(ShopXO 使用 is_delete_time 做软删除判断) + $goods = \think\facade\Db::name('Goods') + ->where('vr_goods_config', 'like', '%"template_id":' . $id . '%') + ->where('is_delete_time', 0) ->find(); ``` ### 修复 3:清理 `list.html` 残留的 old custom JS 代码 **文件:** `view/venue/list.html` 第 137-175 行 删除以下残留代码块: ```diff - -