From fb300e00fcf254abbac7fd6bcffd980ffa6294e4 Mon Sep 17 00:00:00 2001 From: Council Date: Tue, 21 Apr 2026 12:03:56 +0800 Subject: [PATCH] =?UTF-8?q?feat(Phase2):=20=E4=BF=AE=E5=A4=8D=20seatSpecMa?= =?UTF-8?q?p=20=E7=94=9F=E6=88=90=20+=20room=20ID=20=E7=A1=AC=E7=BC=96?= =?UTF-8?q?=E7=A0=81=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 关键修复: 1. BatchGenerate(): 新增 extends.seat_key 字段写入 GoodsSpecBase 2. BatchGenerate(): 新增 type 字段写入 GoodsSpecValue(4维spec类型) 3. ticket_detail.html: renderSeatMap() 不再用 room_001_ 硬编码,改用模板实际 roomId 4. Goods.php: seatSpecMap 注入(已在上次提交) 数据库修复: - 为 vrt_goods_spec_value 新增 type 字段 - 重新生成商品 118 的规格数据(含 seat_key 和 type) --- .../app/plugins/vr_ticket/regenerate_spec.php | 111 ++++++++++++++++++ .../vr_ticket/service/SeatSkuService.php | 9 +- .../vr_ticket/view/goods/ticket_detail.html | 6 +- 3 files changed, 123 insertions(+), 3 deletions(-) create mode 100644 shopxo/app/plugins/vr_ticket/regenerate_spec.php diff --git a/shopxo/app/plugins/vr_ticket/regenerate_spec.php b/shopxo/app/plugins/vr_ticket/regenerate_spec.php new file mode 100644 index 0000000..3cf57cd --- /dev/null +++ b/shopxo/app/plugins/vr_ticket/regenerate_spec.php @@ -0,0 +1,111 @@ + 'mysql', + 'connections' => [ + 'mysql' => [ + 'type' => 'mysql', + 'hostname' => '127.0.0.1', + 'hostport' => '10001', + 'database' => 'vrticket', + 'username' => 'root', + 'password' => 'shopxo_root_2024', + 'charset' => 'utf8mb4', + 'prefix' => 'vrt_', + ] + ] +]); + +$goodsId = 118; + +// 1. 读取商品配置 +$goods = Db::name('goods')->find($goodsId); +if (!$goods) { + echo "Goods {$goodsId} not found\n"; + exit(1); +} + +echo "Goods: {$goods['title']}\n"; +echo "Item type: {$goods['item_type']}\n"; + +// 2. 解析 vr_goods_config +$configData = $goods['spec_base'] ?? ''; +if (empty($configData)) { + echo "No spec_base found for goods {$goodsId}\n"; + exit(1); +} + +// 尝试解析 JSON(spec_base 可能是 JSON 字符串) +$configs = json_decode($configData, true); +if (json_last_error() !== JSON_ERROR_NONE || !is_array($configs)) { + echo "Invalid spec_base JSON for goods {$goodsId}\n"; + exit(1); +} + +echo "Found " . count($configs) . " config(s)\n"; + +// 3. 清空现有规格数据 +echo "Clearing existing spec data...\n"; +Db::name('GoodsSpecType')->where('goods_id', $goodsId)->delete(); +Db::name('GoodsSpecBase')->where('goods_id', $goodsId)->delete(); +Db::name('GoodsSpecValue')->where('goods_id', $goodsId)->delete(); + +// 4. 重新生成 SKU +foreach ($configs as $idx => $config) { + $templateId = intval($config['template_id'] ?? 0); + if ($templateId <= 0) { + echo "Skipping config {$idx}: no template_id\n"; + continue; + } + + $selectedRooms = $config['selected_rooms'] ?? []; + $selectedSections = $config['selected_sections'] ?? []; + $sessions = $config['sessions'] ?? []; + + echo "Generating SKU for template {$templateId}...\n"; + $result = SeatSkuService::BatchGenerate( + $goodsId, $templateId, + $selectedRooms, $selectedSections, $sessions + ); + + if ($result['code'] === 0) { + echo " Generated: {$result['data']['generated']} seats\n"; + } else { + echo " Error: {$result['msg']}\n"; + } +} + +// 5. 刷新商品基础信息 +echo "Refreshing goods base info...\n"; +SeatSkuService::refreshGoodsBase($goodsId); + +// 6. 验证结果 +$specCount = Db::name('GoodsSpecBase')->where('goods_id', $goodsId)->count(); +$valueCount = Db::name('GoodsSpecValue')->where('goods_id', $goodsId)->count(); +$typeCount = Db::name('GoodsSpecType')->where('goods_id', $goodsId)->count(); + +echo "\nDone!\n"; +echo "GoodsSpecBase: {$specCount}\n"; +echo "GoodsSpecValue: {$valueCount}\n"; +echo "GoodsSpecType: {$typeCount}\n"; + +// 7. 显示 sample 数据 +echo "\nSample GoodsSpecBase (first 3):\n"; +$sample = Db::name('GoodsSpecBase') + ->where('goods_id', $goodsId) + ->limit(3) + ->select() + ->toArray(); +foreach ($sample as $spec) { + echo " ID: {$spec['id']}, extends: {$spec['extends']}\n"; +} diff --git a/shopxo/app/plugins/vr_ticket/service/SeatSkuService.php b/shopxo/app/plugins/vr_ticket/service/SeatSkuService.php index 300edf1..50759b9 100644 --- a/shopxo/app/plugins/vr_ticket/service/SeatSkuService.php +++ b/shopxo/app/plugins/vr_ticket/service/SeatSkuService.php @@ -152,10 +152,13 @@ class SeatSkuService extends BaseService $val_seat = $venueName . '-' . $roomName . '-' . $char . '-' . $rowLabel . $col; foreach ($sessionStrings as $sessionStr) { - $seatId = $roomId . '_' . $rowLabel . '_' . $col . '_' . md5($sessionStr); + $seatKey = $roomId . '_' . $rowLabel . '_' . $col; + $seatId = $seatKey . '_' . md5($sessionStr); $seatsToInsert[$seatId] = [ 'price' => $seatPrice, + 'seat_key' => $seatKey, // ← 用于前端映射 + 'extends' => json_encode(['seat_key' => $seatKey], JSON_UNESCAPED_UNICODE), 'spec_values' => [ $val_venue, $val_section, @@ -208,6 +211,7 @@ class SeatSkuService extends BaseService 'coding' => '', 'barcode' => '', 'add_time' => $now, + 'extends' => $s['extends'] ?? null, ]); if (!$baseId) { @@ -215,10 +219,11 @@ class SeatSkuService extends BaseService } // 4 条 GoodsSpecValue,每条对应一个维度 - foreach ($s['spec_values'] as $specVal) { + foreach ($s['spec_values'] as $idx => $specVal) { $valueBatch[] = [ 'goods_id' => $goodsId, 'goods_spec_base_id' => $baseId, + 'type' => self::SPEC_DIMS[$idx] ?? '', 'value' => (string)$specVal, 'md5_key' => md5((string)$specVal), 'add_time' => $now, diff --git a/shopxo/app/plugins/vr_ticket/view/goods/ticket_detail.html b/shopxo/app/plugins/vr_ticket/view/goods/ticket_detail.html index c93670d..c20eb44 100644 --- a/shopxo/app/plugins/vr_ticket/view/goods/ticket_detail.html +++ b/shopxo/app/plugins/vr_ticket/view/goods/ticket_detail.html @@ -137,6 +137,9 @@ return; } + // 从模板数据获取房间 ID(可能是 UUID 或 room_xxx 格式) + var rooms = map.rooms || []; + var roomId = (rooms[0] && rooms[0].id) ? rooms[0].id : 'room_001'; var seats = map.seats || (map.rooms && map.rooms[0] ? map.rooms[0].seats || {} : {}); var sections = map.sections || (map.rooms && map.rooms[0] ? map.rooms[0].sections || [] : []); @@ -159,7 +162,8 @@ chars.forEach(function (char, colIndex) { var colNum = colIndex + 1; - var seatKey = 'room_001_' + rowLabel + '_' + colNum; + // 使用实际的 roomId 构建 seatKey + var seatKey = roomId + '_' + rowLabel + '_' + colNum; var seatInfo = app.seatSpecMap[seatKey] || {}; var section = seatInfo.section || {}; var color = section.color || '#409eff';