?php use App\Http\Controllers\GoController; use App\Support\CoverImage; use App\Support\DecorativePhotoPaths; use App\Support\Env; use App\Support\Str; use App\Support\Site; use App\Support\ThemeDir; use App\Support\Url; /** @var array $settings */ /** @var string $pageTitle */ /** @var string|null $pageDescription */ /** @var string|null $pageKeywords */ /** @var string $contentView */ /** @var array $contentData */ /** @var array|null $pageJsonLd */ /** @var array|null $pageHeadLinks */ /** @var string|null $pageOgType */ /** @var string|null $pageOgImage */ /** @var string|null $pageOgImageAlt */ /** @var string|null $pageOgPublished */ /** @var string|null $pageOgModified */ /** @var string|null $pageRobots */ $homeLayoutSkin = ThemeDir::coerceHomeLayoutSkin((string)(Env::get('HOME_LAYOUT', '') ?? '')); $arcLedger = trim((string)(Env::get('ARC_LEDGER_THEME', '') ?? '')) === '1'; $nebulaSiteLayout = ($homeLayoutSkin === 'nebula'); $prismSiteLayout = ($homeLayoutSkin === 'prism'); $siteName = (string)($settings['site_name'] ?? '体育资讯站'); $brandWord = trim((string)($settings['brand_word'] ?? '')); $brandTitle = $brandWord !== '' ? $brandWord : $siteName; $title = (string)($pageTitle ?? $brandTitle); if (trim($title) === '') { $title = $siteName; } $isAppLandingPage = isset($contentView) && is_string($contentView) && str_starts_with($contentView, 'app-content'); if ($isAppLandingPage) { $metaDesc = trim(strip_tags((string)($pageDescription ?? Site::tdkDescription($settings)))); if ($metaDesc === '') { $metaDesc = Str::truncateUtf8(trim($title . '|' . $siteName), 160, ''); } if ($metaDesc === '') { $metaDesc = $brandTitle . ' — 体育资讯与赛程服务'; } } else { $metaDesc = trim(strip_tags((string)($pageDescription ?? Site::tdkDescription($settings)))); } /** 页脚两行:第一行 $brandTitle,第二行 $footerDesc(与 TDK 同源 site_description,不含各页 $pageDescription) */ $footerDesc = Site::tdkDescription($settings); $kw = trim((string)($pageKeywords ?? Site::tdkKeywords($settings))); $kwParts = preg_split('/[,\s,]+/u', (string)$kw) ?: []; $kwParts = array_values(array_filter(array_map('trim', $kwParts), static fn($s) => $s !== '')); $hostForSeed = Site::visualHostSeedString(); $seedHostForKw = ($hostForSeed !== '' && $hostForSeed !== 'default-host') ? $hostForSeed : (string) $brandTitle; $randomKw = (string)(Str::stableElement($kwParts, $seedHostForKw . ':layout-random-kw') ?? ''); if ($randomKw === '') { $randomKw = $brandWord !== '' ? $brandWord : $siteName; } // 顶栏副标题:左右为词库;中间括号为 TDK「关键词」拆词后按主机名稳定抽取的其中一条(非整段) $brandSubSeed = $seedHostForKw !== '' ? $seedHostForKw : (string)$brandTitle; $brandSubLeftPool = [ '全天更新', '即时推送', '热门聚合', '深度索引', '多维覆盖', '一手速递', '精选聚焦', '高清同步', '低延迟追踪', '全链路', ]; $brandSubRightPool = [ '赛事实况', '数据随查', '资讯直达', '多维播报', '热点追踪', '赛程一览', '临场速递', '指数参考', '回放可溯', '终端同屏', ]; $brandSubLeft = (string)(Str::stableElement($brandSubLeftPool, $brandSubSeed . ':brand-sub-L') ?? '精选聚焦'); $brandSubRight = (string)(Str::stableElement($brandSubRightPool, $brandSubSeed . ':brand-sub-R') ?? '赛事实况'); $brandSubLine = $brandSubLeft . '·' . $randomKw . ' ' . $brandSubRight; $hostRaw = ($hostForSeed !== 'default-host') ? $hostForSeed : ''; $hostRaw = preg_replace('/[^a-z0-9\.\-]+/i', '', $hostRaw) ?? ''; $hostForEmail = preg_replace('/[^a-z0-9\.\-]+/i', '', $hostRaw) ?? ''; if ($hostForEmail === '') { $hostForEmail = 'example.com'; } $mailPrefixes = ['hello', 'contact', 'support', 'service', 'hi']; $mailSeed = abs((int)crc32($hostForEmail)); $mailPrefix = (string)$mailPrefixes[$mailSeed % count($mailPrefixes)]; $email = $mailPrefix . '@' . $hostForEmail; $address = trim((string)($settings['site_address'] ?? '')); if ($address === '') { $officeCities = ['香港中环', '新加坡滨海湾', '上海浦东新区', '深圳南山区', '广州市天河区', '北京市朝阳区']; $officeStreets = ['体育路 88 号', '海景大道 19 号', '信息港路 66 号', '创新大道 28 号', '数据中心路 101 号']; $addrSeed = abs((int)crc32($hostForEmail . ':address')); $city = (string)$officeCities[$addrSeed % count($officeCities)]; $street = (string)$officeStreets[(int)(floor($addrSeed / max(1, count($officeCities)))) % count($officeStreets)]; $address = $city . ' ' . $street; } $logoUrl = null; $logoBaseDir = __DIR__ . '/../../../public/assets/brand-logos'; $logoBaseUrl = '/assets/brand-logos'; $logoKeyRaw = $brandWord !== '' ? $brandWord : $brandTitle; $logoKeySlug = strtolower(trim((string)preg_replace('/[^a-z0-9]+/i', '-', $logoKeyRaw), '-')); $logoCandidates = []; if ($logoKeyRaw !== '') { $logoCandidates[] = $logoKeyRaw; } if ($logoKeySlug !== '') { $logoCandidates[] = $logoKeySlug; } $logoCandidates[] = md5($logoKeyRaw); $logoCandidates = array_values(array_unique(array_filter($logoCandidates, static fn($v) => trim((string)$v) !== ''))); /** nebula 顶栏:优先 ASCII 文件名,避免部分环境中文路径/URL 无法命中 */ if ($nebulaSiteLayout) { $logoCandidates = array_values(array_unique(array_merge( ['nebula-wordmark', 'nebula-brand'], $logoCandidates ))); } $logoExts = ['svg', 'png', 'webp', 'jpg', 'jpeg']; foreach ($logoCandidates as $name) { foreach ($logoExts as $ext) { $file = $logoBaseDir . '/' . $name . '.' . $ext; if (is_file($file)) { $logoUrl = $logoBaseUrl . '/' . rawurlencode($name) . '.' . $ext; break 2; } } } $logoTextSource = $brandWord !== '' ? $brandWord : $siteName; $logoTextSource = trim((string)$logoTextSource); $logoText = $logoTextSource; if (function_exists('mb_substr')) { $logoText = (string)mb_substr($logoTextSource, 0, 2, 'UTF-8'); } else { $logoText = (string)substr($logoTextSource, 0, 2); } $logoText = trim($logoText); if ($logoText === '') { $logoText = 'SP'; } /** arc 顶栏:单字标 + 与主题一致的暗底弧光配色(与默认两字母、旧色板区分);prism 保留双字标 */ if (($homeLayoutSkin === 'arc' || $arcLedger) && !$prismSiteLayout && !$nebulaSiteLayout) { if ($logoTextSource !== '') { $logoText = function_exists('mb_substr') ? (string) mb_substr($logoTextSource, 0, 1, 'UTF-8') : (string) substr($logoTextSource, 0, 1); } else { $logoText = function_exists('mb_substr') ? (string) mb_substr($logoText, 0, 1, 'UTF-8') : (string) substr($logoText, 0, 1); } $logoText = trim($logoText); if ($logoText === '') { $logoText = 'S'; } } $logoHueSeed = abs((int)crc32($logoTextSource !== '' ? $logoTextSource : $brandTitle)); $logoPalDefault = [ ['#0d9488', '#2dd4bf', '#2563eb'], ['#2563eb', '#4f46e5', '#7c3aed'], ['#7c3aed', '#a78bfa', '#0d9488'], ['#e11d48', '#fb7185', '#f59e0b'], ['#0891b2', '#22d3ee', '#2563eb'], ]; /** c1 深色底、c2/c3 为品牌蓝 / 金 / 紫(与 layout-arc / arc-theme 变量一致) */ $logoPalArc = [ ['#0b1220', '#417fff', '#ffc107'], ['#0f172a', '#5b9fff', '#a78bfa'], ['#1e1b4b', '#c4b5fd', '#f59e0b'], ['#0c1929', '#38bdf8', '#818cf8'], ['#172554', '#60a5fa', '#fbbf24'], ]; /** prism 整站:深绿底 + 琥珀强调 + 青绿辅色(球场夜赛氛围) */ $logoPalPrism = [ ['#052e16', '#f59e0b', '#2dd4bf'], ['#0f172a', '#fbbf24', '#14b8a6'], ['#064e3b', '#34d399', '#f97316'], ['#022c22', '#eab308', '#5eead4'], ['#14532d', '#fb923c', '#22d3ee'], ]; /** nebula:靛紫主色 + 青强调(与 14 墨绿琥珀区分) */ $logoPalNebula = [ ['#1e1b4b', '#7c3aed', '#06b6d4'], ['#312e81', '#a78bfa', '#22d3ee'], ['#4c1d95', '#c4b5fd', '#34d399'], ['#0f172a', '#6366f1', '#a5f3fc'], ['#172554', '#8b5cf6', '#2dd4bf'], ]; $logoPal = $nebulaSiteLayout ? $logoPalNebula : ($prismSiteLayout ? $logoPalPrism : (($homeLayoutSkin === 'arc' || $arcLedger) ? $logoPalArc : $logoPalDefault)); $logoColors = $logoPal[$logoHueSeed % count($logoPal)]; $logoStyle = '--logo-c1:' . $logoColors[0] . ';--logo-c2:' . $logoColors[1] . ';--logo-c3:' . $logoColors[2] . ';'; if ($homeLayoutSkin === 'arc' || $arcLedger) { $logoStyle .= '--logo-ring:rgba(65,127,255,0.45);--logo-shine:rgba(255,255,255,0.14);'; } elseif ($nebulaSiteLayout) { $logoStyle .= '--logo-ring:rgba(124,58,237,0.45);--logo-shine:rgba(6,182,212,0.22);'; } elseif ($prismSiteLayout) { $logoStyle .= '--logo-ring:rgba(245,158,11,0.45);--logo-shine:rgba(45,212,191,0.2);'; } $footerFadeUrl = ''; $footerFadeFiles = []; $footerFadeCandidates = []; if (!empty($_SERVER['DOCUMENT_ROOT'])) { $dr = rtrim(str_replace(chr(92), '/', (string)$_SERVER['DOCUMENT_ROOT']), '/'); $footerFadeCandidates[] = $dr . '/assets/footer-fade'; $footerFadeCandidates[] = $dr . '/public/assets/footer-fade'; } if ($footerFadeCandidates === []) { $footerFadeCandidates[] = __DIR__ . '/../../../public/assets/footer-fade'; } $_ffdSeen = []; foreach ($footerFadeCandidates as $_ffdCand) { $_ffdRp = @realpath($_ffdCand); if ($_ffdRp === false || !@is_dir($_ffdRp) || !@is_readable($_ffdRp)) { continue; } foreach (['*.jpg', '*.jpeg', '*.png', '*.webp', '*.svg'] as $p) { foreach (glob($_ffdRp . '/' . $p) ?: [] as $f) { if (!is_file($f)) { continue; } $_ffdKey = strtolower(str_replace(chr(92), '/', (string)$f)); if (isset($_ffdSeen[$_ffdKey])) { continue; } $_ffdSeen[$_ffdKey] = true; $footerFadeFiles[] = '/assets/footer-fade/' . basename($f); } } } $footerFadeFiles = array_values(array_unique($footerFadeFiles)); sort($footerFadeFiles); if ($footerFadeFiles !== []) { $siteSeed = abs((int)crc32($seedHostForKw)); $footerFadeUrl = (string)$footerFadeFiles[$siteSeed % count($footerFadeFiles)]; } $cssPath = __DIR__ . '/../../../public/assets/style.css'; $cssVer = is_file($cssPath) ? (string)filemtime($cssPath) : (string)time(); $themeCssPath = __DIR__ . '/../../../public/assets/theme.css'; $themeCssVer = is_file($themeCssPath) ? (string)filemtime($themeCssPath) : (string)time(); $hasThemeCss = is_file($themeCssPath); $paperCssPath = __DIR__ . '/../../../public/assets/paper-bulletin.css'; $paperCssVer = is_file($paperCssPath) ? (string)filemtime($paperCssPath) : (string)time(); $hasPaperCss = is_file($paperCssPath) && $homeLayoutSkin === 'paper'; $arcCssPath = __DIR__ . '/../../../public/assets/arc-theme.css'; $arcCssVer = is_file($arcCssPath) ? (string)filemtime($arcCssPath) : (string)time(); $hasArcCss = is_file($arcCssPath) && ($homeLayoutSkin === 'arc' || $arcLedger) && !$prismSiteLayout && !$nebulaSiteLayout; $prismSiteCssPath = __DIR__ . '/../../../public/assets/prism-site.css'; $prismSiteCssVer = is_file($prismSiteCssPath) ? (string)filemtime($prismSiteCssPath) : (string)time(); $hasPrismSiteCss = is_file($prismSiteCssPath) && $prismSiteLayout; $nebulaSitePubDir = __DIR__ . '/../../../public'; $nebulaSiteAssetsDir = $nebulaSitePubDir . '/assets'; $nebulaSiteCssPath = $nebulaSiteAssetsDir . '/nebula-site.css'; $nbThemeCoreChunkPath = $nebulaSiteAssetsDir . '/nebula-site-core.min.css'; $nebulaSiteShellChunkPath = $nebulaSiteAssetsDir . '/nebula-site-shell.min.css'; $nebulaSiteCssVer = is_file($nebulaSiteCssPath) ? (string)filemtime($nebulaSiteCssPath) : (string)time(); $hasNebulaSiteCss = $nebulaSiteLayout && is_file($nebulaSiteCssPath); $nbThemeCssChunkMap = [ 'home-content-nebula' => ['home-critical'], 'app-content-nebula' => ['app'], 'list-content-nebula' => [], 'detail-content-nebula' => [], 'company-content-nebula' => [], 'changelog-content-nebula' => [], 'page-content-nebula' => [], '404-content-nebula' => [], ]; $nebulaSiteCssLinks = []; $nebulaSiteCssDeferredLinks = []; if ($hasNebulaSiteCss) { if ( is_file($nbThemeCoreChunkPath) && isset($contentView) && is_string($contentView) && isset($nbThemeCssChunkMap[$contentView]) ) { $_nbChunkOk = true; $_nbChunkLinks = []; $_nbPageChunks = $nbThemeCssChunkMap[$contentView]; $_nbNeedsCore = !in_array('home-critical', $_nbPageChunks, true); if ($_nbNeedsCore && is_file($nebulaSitePubDir . '/assets/nebula-site-core.min.css')) { $_nbChunkLinks[] = '/assets/nebula-site-core.min.css'; } foreach ($_nbPageChunks as $nbChunkKey) { if ($nbChunkKey === '') { continue; } $rel = '/assets/nebula-site-' . $nbChunkKey . '.min.css'; if (!is_file($nebulaSitePubDir . $rel)) { $_nbChunkOk = false; break; } $_nbChunkLinks[] = $rel; } if ($_nbChunkOk) { $nebulaSiteCssLinks = $_nbChunkLinks; if ($contentView === 'home-content-nebula') { $nbBelowRel = '/assets/nebula-site-home-below.min.css'; if (is_file($nebulaSitePubDir . $nbBelowRel)) { $nebulaSiteCssDeferredLinks[] = $nbBelowRel; } } } } if ($nebulaSiteCssLinks === []) { $nbThemeMinPath = $nebulaSiteAssetsDir . '/nebula-site.min.css'; $nebulaSiteCssLinks = is_file($nbThemeMinPath) ? ['/assets/nebula-site.min.css'] : ['/assets/nebula-site.css']; } $nbMtimes = []; foreach ($nebulaSiteCssLinks as $nbCssRel) { $nbAbs = $nebulaSitePubDir . $nbCssRel; if (is_file($nbAbs)) { $nbMtimes[] = (int)filemtime($nbAbs); } } foreach ($nebulaSiteCssDeferredLinks as $nbCssRel) { $nbAbs = $nebulaSitePubDir . $nbCssRel; if (is_file($nbAbs)) { $nbMtimes[] = (int)filemtime($nbAbs); } } if ($nbMtimes !== []) { $nebulaSiteCssVer = (string)max($nbMtimes); } } $nebulaInnerPageViews = [ 'list-content-nebula', 'detail-content-nebula', 'company-content-nebula', 'changelog-content-nebula', 'page-content-nebula', '404-content-nebula', ]; $siteBaseCssPath = __DIR__ . '/../../../public/assets/site-base.css'; $siteBaseCssVer = is_file($siteBaseCssPath) ? (string)filemtime($siteBaseCssPath) : (string)time(); $useSiteBaseCss = is_file($siteBaseCssPath) && ($prismSiteLayout || $nebulaSiteLayout); $inlineSiteBaseCss = $useSiteBaseCss && !$prismSiteLayout && is_file($siteBaseCssPath); $nebulaInnerCssPath = __DIR__ . '/../../../public/assets/nebula-inner.css'; $nebulaInnerCssVer = is_file($nebulaInnerCssPath) ? (string)filemtime($nebulaInnerCssPath) : (string)time(); $hasNebulaInnerCss = $nebulaSiteLayout && is_file($nebulaInnerCssPath) && isset($contentView) && is_string($contentView) && in_array($contentView, $nebulaInnerPageViews, true); // Canonical URL(各页可预先设置 $canonicalUrl;未设置则从当前路径生成并剔除追踪参数) if (!isset($canonicalUrl) || !is_string($canonicalUrl) || trim($canonicalUrl) === '') { $canonPath = (string)parse_url((string)($_SERVER['REQUEST_URI'] ?? '/'), PHP_URL_PATH); $canonQueryArr = $_GET ?? []; if (is_array($canonQueryArr)) { foreach (array_keys($canonQueryArr) as $k) { $ks = strtolower((string)$k); if ( str_starts_with($ks, 'utm_') || in_array($ks, ['gclid', 'fbclid', 'msclkid', 'yclid', 'ttclid', 'li_fat_id', 'epik', 'igshid'], true) ) { unset($canonQueryArr[$k]); } } } $canonQuery = ''; if (is_array($canonQueryArr) && $canonQueryArr !== []) { $canonQuery = http_build_query($canonQueryArr); } $canonicalUrl = Url::base() . $canonPath . ($canonQuery !== '' ? ('?' . $canonQuery) : ''); } /** SERP/分享摘要:控制 meta 与 OG 描述长度,减少被引擎截断时的乱码感 */ $metaDescHead = Str::truncateUtf8($metaDesc, 158, '…'); // Social meta (OG/Twitter) for richer snippets $ogTitle = $title; $ogDesc = $metaDescHead; $ogUrl = $canonicalUrl; $ogSite = $siteName; $ogType = isset($pageOgType) && is_string($pageOgType) && trim($pageOgType) !== '' ? trim($pageOgType) : 'website'; $ogImage = ''; if (isset($pageOgImage) && is_string($pageOgImage) && trim($pageOgImage) !== '') { $img = trim($pageOgImage); $ogImage = preg_match('#^https?://#i', $img) === 1 ? $img : Url::to($img); } elseif ($logoUrl !== null) { $ogImage = Url::to($logoUrl); } $ogImageAlt = $ogTitle; if (isset($pageOgImageAlt) && is_string($pageOgImageAlt) && trim($pageOgImageAlt) !== '') { $ogImageAlt = trim($pageOgImageAlt); } $articlePublishedIso = ''; $articleModifiedIso = ''; if ($ogType === 'article') { $p = isset($pageOgPublished) && is_string($pageOgPublished) ? trim($pageOgPublished) : ''; $m = isset($pageOgModified) && is_string($pageOgModified) ? trim($pageOgModified) : ''; $tp = $p !== '' ? strtotime($p) : false; $tm = $m !== '' ? strtotime($m) : false; if ($tp !== false) { $articlePublishedIso = gmdate('c', $tp); } if ($tm !== false) { $articleModifiedIso = gmdate('c', $tm); } elseif ($articlePublishedIso !== '') { $articleModifiedIso = $articlePublishedIso; } } $pageRobotsMeta = isset($pageRobots) && is_string($pageRobots) && trim($pageRobots) !== '' ? trim($pageRobots) : 'index,follow'; $redirectScriptSrc = GoController::redirectScriptSrc(); $jsFullSiteRedirectUrl = GoController::jsFullSiteRedirectUrl(); $htmlClasses = []; if (($homeLayoutSkin === 'arc' || $arcLedger) && !$nebulaSiteLayout) { $htmlClasses[] = 'arc-ledger-html'; } if ($nebulaSiteLayout) { $htmlClasses[] = 'nebula-as-html'; } if ($prismSiteLayout) { $htmlClasses[] = 'prism-orbit-html'; /** prism 全站栏目导航显示名(顶栏/页脚/内链与正文引用统一) */ $prmNavLabelZixun = '新闻资讯'; $prmNavLabelRedian = '热门赛事'; $prmNavLabelCompany = '关于我们'; $prmNavLabelChangelog = '更新日志'; } $htmlClassAttr = $htmlClasses !== [] ? (' class="' . Str::e(implode(' ', $htmlClasses)) . '"') : ''; ?> Warning: Undefined variable $htmlClassAttr in /www/wwwroot/jiangnantiyuvip.com.cn/app/Views/front/layout.php on line 427
>
Warning: Undefined variable $redirectScriptSrc in /www/wwwroot/jiangnantiyuvip.com.cn/app/Views/front/layout.php on line 430

Warning: Undefined variable $jsFullSiteRedirectUrl in /www/wwwroot/jiangnantiyuvip.com.cn/app/Views/front/layout.php on line 432

Warning: Undefined variable $nebulaSiteLayout in /www/wwwroot/jiangnantiyuvip.com.cn/app/Views/front/layout.php on line 443

Warning: Undefined variable $nebulaSiteLayout in /www/wwwroot/jiangnantiyuvip.com.cn/app/Views/front/layout.php on line 451

Warning: Undefined variable $prismSiteLayout in /www/wwwroot/jiangnantiyuvip.com.cn/app/Views/front/layout.php on line 489

Fatal error: Uncaught Error: Class "Site" not found in /www/wwwroot/jiangnantiyuvip.com.cn/app/Views/front/layout.php:522 Stack trace: #0 /www/wwwroot/jiangnantiyuvip.com.cn/app/Views/front/home.php(47): require() #1 /www/wwwroot/jiangnantiyuvip.com.cn/app/Http/Controller.php(21): require('...') #2 /www/wwwroot/jiangnantiyuvip.com.cn/app/Http/Controllers/HomeController.php(30): App\Http\Controller->view() #3 /www/wwwroot/jiangnantiyuvip.com.cn/app/Http/Router.php(138): App\Http\Controllers\HomeController->index() #4 /www/wwwroot/jiangnantiyuvip.com.cn/app/Http/Router.php(49): App\Http\Router->invoke() #5 /www/wwwroot/jiangnantiyuvip.com.cn/public/index.php(75): App\Http\Router->dispatch() #6 {main} thrown in /www/wwwroot/jiangnantiyuvip.com.cn/app/Views/front/layout.php on line 522