diff --git a/docs/DEVELOPMENT_LOG.md b/docs/DEVELOPMENT_LOG.md index 4906863..5765c3a 100644 --- a/docs/DEVELOPMENT_LOG.md +++ b/docs/DEVELOPMENT_LOG.md @@ -600,3 +600,79 @@ c894e7018 fix: 复制 ShopXO public 模板 ``` bbea35d83 feat(AdminGoodsSaveHandle): 保存时自动填充 template_snapshot ``` + +--- + +### 13.7 Issue #13 根因修复 — template_snapshot.rooms 为空(2026-04-20) + +**问题现象**:商品保存后 `vr_goods_config` 里 `template_snapshot.rooms = []`,但 `selected_rooms = ["room_0"]` 有值。 + +**三层根因及修复**: + +#### 根因 1:前端不发送 template_snapshot + +`outputBase64` 的 JSON 结构里不包含 `template_snapshot`,后端 `save_thing_end` 拿到的数据里 `template_snapshot` 可能是旧的或空的。 + +**修复**(AdminGoodsSaveHandle.php):`save_thing_end` 时改为**永远从 DB 重建** template_snapshot(而非等它为空才读)。条件:`selected_rooms 有值 || template_snapshot 为空 || template_snapshot.rooms 为空`。 + +#### 根因 2:`save_thing_end` 的 `$params['data']` 是值拷贝 + +ShopXO 的 `save_thing_end` 传入 `$data` 是事务快照(值传递),不是引用。`$params['data']['vr_goods_config']` 里的值可能和 DB 里不一致。 + +**修复**:改用 `Db::name('Goods')->find($goodsId)` 直接从 DB 读,加 fallback 到 `$params['data']`。 + +#### 根因 3:room.id 为空导致 ID 匹配失败 + +模板5的 `rooms[0].id = ""`(空字符串),前端发 `selected_rooms = ["room_0"]`,filter 里的匹配逻辑找不到对应房间(空id无法通过前缀匹配或直接匹配)。 + +**修复**(AdminGoodsSaveHandle.php):空 id 时用数组索引替代 `room_N`(N 从0开始)。 + +#### 根因 4:幽灵配置(软删除场馆仍出现在表单) + +模板软删除后,前端 `getRooms()` 返回 `[]`,但已保存配置里的 template_snapshot.venue 信息还在,导致 checkbox 选中却无法操作。 + +**修复**(AdminGoodsSave.php):加载时用 `Set(validTemplateIds)` 过滤掉 `status=0` 模板的配置。 + +**提交**: +``` +05b69588f chore: remove debug logging from AdminGoodsSaveHandle +c03737308 fix(Admin): 改用 random_int() CSPRNG,修正 UUID v4 版本/变体位 +1244adfaa feat(Admin): SeatTemplateSave 时为无 id 的 room 生成 UUID +8a33e7fa2 fix(AdminGoodsSaveHandle): 空id房间用数组索引匹配 room_0/room_1 +da001797a fix(vr_ticket): template_snapshot 重建逻辑重写 + 幽灵配置过滤 +``` + +--- + +### 13.8 room.id 生成逻辑(2026-04-20) + +**问题**:早期模板数据的 `room.id` 为空(老格式无 id 字段),导致前端 selected_rooms 无法正确匹配。 + +**修复**(Admin.php → `SeatTemplateSave`):保存场馆模板时,若 `room.id` 为空则生成 UUID v4 格式。 + +```php +if (empty($room['id'])) { + $room['id'] = sprintf('%08x-%04x-%04x-%04x-%04x%08x', + time(), + random_int(0, 0xffff), + random_int(0, 0xffff), + (random_int(0, 0x3fff) & 0x0fff) | 0x4000, // 版本4 + 变体10xx + random_int(0, 0xffff), + random_int(0, 0xffffffff)); +} +``` + +- `random_int()`:PHP 7+ CSPRNG,优于 `mt_rand()`(可被种子预测) +- 版本 nibble = 4(UUID v4),变体 = 10xx(RFC 4122) +- 已有房间编辑保存时会自动补上 id,不影响已有数据 + +**已有兜底兼容逻辑(无需改动)**: +- AdminGoodsSave.php 第36-40行:`room.id` 为空时用 `room_N` 索引兼容 +- SeatSkuService.php 第100行:`id` 为空时用 `room_{index}` 兼容 + +--- + +### 13.9 Debug 代码清理(2026-04-20) + +移除了 AdminGoodsSaveHandle.php 中所有调试日志代码(vr_debug.log 写入),不影响正常功能。 +