$hotelCode, 'name' => getv($h, 'profile.name', ''), 'brand' => getv($h, 'brandInfo.brandName', ''), 'brandCode' => getv($h, 'brandInfo.brandCode', ''), 'phone' => getv($h, 'callCenter.phoneNumber', ''), 'address' => trim(implode(' ', array_filter([ getv($h, 'address.street1', ''), getv($h, 'address.street2', ''), getv($h, 'address.street3', ''), getv($h, 'address.city', ''), getv($h, 'address.state.name', ''), getv($h, 'address.zip', ''), ]))), 'km' => getv($h, 'distanceFrom.kilometers', ''), 'miles' => getv($h, 'distanceFrom.miles', ''), 'welcomeMessage' => trim(strip_tags((string)getv($h, 'marketing.marketingText.welcomeMessage', ''))), 'image' => pickImage($h), 'website' => getv($h, 'profile.independentNonIHGWebsiteURL', ''), 'rating' => getv($h, 'profile.averageReview', null), 'reviews' => getv($h, 'profile.totalReviews', null), 'facilities' => array_values(array_filter(array_map( fn($x) => $x['name'] ?? '', $h['facilities'] ?? [] ))), 'tax' => getv($h, 'tax.taxAndFeeDetail', ''), 'price' => getv($h, 'rate.price', getv($h, 'price.amount', null)), 'currency' => getv($h, 'rate.currency', getv($h, 'price.currency', 'CNY')), ]; } function loadHotelsFromFiles(array $jsonFiles): array { $merged = []; foreach ($jsonFiles as $file) { if (!is_file($file)) { echo "跳过不存在文件:{$file}\n"; continue; } $data = json_decode(file_get_contents($file), true); if (!is_array($data)) { echo "跳过无效 JSON:{$file}\n"; continue; } $hotels = getv($data, 'data.getHotels.hotelInfo', []); if (!is_array($hotels)) { echo "跳过无 hotelInfo 文件:{$file}\n"; continue; } foreach ($hotels as $hotel) { if (!is_array($hotel)) { continue; } $hotelCode = trim((string)($hotel['hotelCode'] ?? '')); if ($hotelCode === '') { continue; } // 后读入的同 hotelCode 酒店覆盖前面的 $merged[$hotelCode] = normalizeHotel($hotel); } } return array_values($merged); } function pageName(string $type, int $page): string { if ($type === 'cards') { return $page === 1 ? 'index.html' : "page-{$page}.html"; } return $page === 1 ? 'table.html' : "table-{$page}.html"; } function renderLayout(string $body, string $title): string { return '
| hotelCode | 酒店 | 品牌 | 地址 | 评分 | 电话 | 设施 | 价格 | 税费 |
|---|---|---|---|---|---|---|---|---|
| ' . e($h['hotelCode']) . ' | ' . e($h['name']) . ' | ' . e($h['brand']) . ' | ' . e($h['address']) . ' | ' . e($h['rating'] === null ? 'null' : $h['rating']) . ' | ' . e($h['phone']) . ' | ' . e(implode('、', array_slice($h['facilities'], 0, 8))) . ' | ' . e($price) . ' | ' . e($h['tax']) . ' |