vr-shopxo-plugin/shopxo/app/plugins/vr_ticket/hook/AdminGoodsSaveHandle.php

149 lines
8.1 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?php
namespace app\plugins\vr_ticket\hook;
use think\facade\Db;
use app\plugins\vr_ticket\service\SeatSkuService;
class AdminGoodsSaveHandle
{
/**
* 商品保存钩子(同时响应 save_handle 和 save_thing_end 两个时机)
*/
public function handle($params = [])
{
$hookName = $params['hook_name'] ?? '';
// ──────────────────────────────────────────────────────
// 时机 1plugins_service_goods_save_handle事务前修改待保存数据
// - 把 vr_goods_config base64 解码写入 $data
// - 设置 item_type
// - 强制 is_exist_many_spec = 1
// ──────────────────────────────────────────────────────
if ($hookName === 'plugins_service_goods_save_handle') {
$postParams = $params['params'] ?? [];
if (isset($postParams['vr_is_ticket']) && $postParams['vr_is_ticket'] == 1) {
$params['data']['item_type'] = 'ticket';
$params['data']['is_exist_many_spec'] = 1;
$base64Config = $postParams['vr_goods_config_base64'] ?? '';
if (!empty($base64Config)) {
$jsonStr = base64_decode($base64Config);
if ($jsonStr !== false) {
$params['data']['vr_goods_config'] = $jsonStr;
}
}
} else {
$params['data']['item_type'] = 'normal';
$params['data']['vr_goods_config'] = '';
}
return ['code' => 0];
}
// ──────────────────────────────────────────────────────
// 时机 2plugins_service_goods_save_thing_end事务内goods 已落表)
// 关键:此时 GoodsSpecificationsInsert + GoodsSaveBaseUpdate
// 已经执行完毕(它们处理的是表单原生规格数据)。
//
// 对于票务商品,我们需要:
// a) 删除原生流程产生的所有 spec 数据(表单垃圾)
// b) 用 BatchGenerate 重新生成 VR 座位级 SKU
// c) 回写 GoodsSpecType.value让后台正确展示
// d) 重新计算 goods 表的 price/inventory
// ──────────────────────────────────────────────────────
if ($hookName === 'plugins_service_goods_save_thing_end') {
$data = $params['data'] ?? [];
$goodsId = $params['goods_id'] ?? 0;
if ($goodsId > 0 && ($data['item_type'] ?? '') === 'ticket') {
$rawConfig = $data['vr_goods_config'] ?? '';
if (!empty($rawConfig)) {
$configs = json_decode($rawConfig, true);
if (is_array($configs) && !empty($configs)) {
// 0) 填充 template_snapshot前端没传、或 rooms 为空时兜底从 vr_seat_templates 读)
foreach ($configs as $i => &$config) {
if (empty($config['template_snapshot']) || empty($config['template_snapshot']['rooms'])) {
$templateId = intval($config['template_id'] ?? 0);
if ($templateId > 0) {
$template = Db::name('vr_seat_templates')->find($templateId);
if (empty($template)) {
continue;
}
$seatMap = json_decode($template['seat_map'] ?? '{}', true);
$allRooms = $seatMap['rooms'] ?? [];
// ── v1→v3 兼容迁移 ──
// v1 旧格式没有 rooms 嵌套,只有 sections+map 扁平结构
if (empty($allRooms) && !empty($seatMap['sections'])) {
$v1Sections = $seatMap['sections'] ?? [];
$v1Map = $seatMap['map'] ?? [];
$v1Seats = $seatMap['seats'] ?? [];
$v1RoomId = $config['selected_rooms'][0] ?? 'room_1';
$allRooms = [[
'id' => $v1RoomId,
'name' => $seatMap['venue']['name'] ?? '主馆',
'sections' => $v1Sections,
'map' => $v1Map,
'seats' => $v1Seats,
]];
}
// 按 selected_rooms 过滤,只存用户选中的房间
$selectedRoomIds = array_column(
array_filter($allRooms, function ($r) use ($config) {
return isset($r['id']) && in_array($r['id'], $config['selected_rooms'] ?? []);
}), null
);
$config['template_snapshot'] = [
'venue' => $seatMap['venue'] ?? [],
'rooms' => $selectedRoomIds,
];
}
}
}
unset($config); // 解除引用,避免后续误改
// 将填充后的完整 config 写回 goods 表
Db::name('Goods')->where('id', $goodsId)->update([
'vr_goods_config' => json_encode($configs, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),
]);
// a) 清空原生规格数据 —— 避免列偏移
Db::name('GoodsSpecType')->where('goods_id', $goodsId)->delete();
Db::name('GoodsSpecBase')->where('goods_id', $goodsId)->delete();
Db::name('GoodsSpecValue')->where('goods_id', $goodsId)->delete();
// b) 逐模板生成 VR SKUensureAndFillVrSpecTypes 在内部调用type.value 同步写入)
foreach ($configs as $config) {
$templateId = intval($config['template_id'] ?? 0);
$selectedRooms = $config['selected_rooms'] ?? [];
$selectedSections = $config['selected_sections'] ?? [];
$sessions = $config['sessions'] ?? [];
if ($templateId > 0) {
$res = SeatSkuService::BatchGenerate(
$goodsId, $templateId,
$selectedRooms, $selectedSections, $sessions
);
if ($res['code'] !== 0) {
return $res;
}
}
}
// c) 重新计算 goods.price / goods.inventory
SeatSkuService::refreshGoodsBase($goodsId);
}
}
}
return ['code' => 0];
}
return ['code' => 0];
}
}