From f680c97559742ad8351d516ea15fab75d2eb86b4 Mon Sep 17 00:00:00 2001 From: make Date: Sat, 10 Jan 2026 19:59:40 +0800 Subject: [PATCH] ico --- code/.gitignore | 1 + code/app/common/helper/SiteStyle.php | 117 +++++++++++++++--- code/app/home/view/videoGpt1/base.html | 3 + .../static/favicon/svg_base/base_01.svg | 4 + .../static/favicon/svg_base/base_02.svg | 4 + .../static/favicon/svg_base/base_03.svg | 8 ++ .../static/favicon/svg_base/base_04.svg | 4 + .../static/favicon/svg_base/base_05.svg | 4 + .../static/favicon/svg_base/base_06.svg | 5 + .../static/favicon/svg_base/base_07.svg | 4 + .../static/favicon/svg_base/base_08.svg | 5 + .../static/favicon/svg_base/base_09.svg | 4 + .../static/favicon/svg_base/base_10.svg | 4 + 13 files changed, 153 insertions(+), 14 deletions(-) create mode 100644 code/public/static/favicon/svg_base/base_01.svg create mode 100644 code/public/static/favicon/svg_base/base_02.svg create mode 100644 code/public/static/favicon/svg_base/base_03.svg create mode 100644 code/public/static/favicon/svg_base/base_04.svg create mode 100644 code/public/static/favicon/svg_base/base_05.svg create mode 100644 code/public/static/favicon/svg_base/base_06.svg create mode 100644 code/public/static/favicon/svg_base/base_07.svg create mode 100644 code/public/static/favicon/svg_base/base_08.svg create mode 100644 code/public/static/favicon/svg_base/base_09.svg create mode 100644 code/public/static/favicon/svg_base/base_10.svg diff --git a/code/.gitignore b/code/.gitignore index 503ab2a..24233e4 100644 --- a/code/.gitignore +++ b/code/.gitignore @@ -16,4 +16,5 @@ Thumbs.db /public/initdata/video/url_family_bind.php public/static/css/compiled/* public/static/js/compiled/* +public/static/favicon/generated/* /storage/* diff --git a/code/app/common/helper/SiteStyle.php b/code/app/common/helper/SiteStyle.php index e14e4b7..b501fe8 100644 --- a/code/app/common/helper/SiteStyle.php +++ b/code/app/common/helper/SiteStyle.php @@ -18,6 +18,10 @@ use think\facade\Cache; */ class SiteStyle { + // favicon SVG 母型目录 + private static string $faviconBaseDir = 'public/static/favicon/svg_base/'; + + private static function useCache(): bool { return (bool) config('view.view_site_style_cache'); @@ -268,16 +272,16 @@ class SiteStyle } } - // list_layout 只承载“形态库”(item/shell/grid/layout/行为/itv)。 // title/title_text/更多文案 等“语义”交给 pages.slot/context 决定。 - return [ + $arrCfg = [ 'meta' => [ 'host' => $host, 'seed' => $seed, 'dom_prefix' => $domPrefix, 'static_hash' => $staticHash, 'version' => self::CFG_VERSION, + ], 'global' => [ @@ -289,6 +293,8 @@ class SiteStyle ], ], + 'theme' => [], + 'pages' => [ 'home' => $homePage, 'category_index' => $categoryIndexPage, @@ -347,6 +353,17 @@ class SiteStyle 'seo' => self::buildSeoCfg($seed), ]; + + // 主题色(运行时算,不冻结具体颜色) + $theme = self::buildTheme( + $seed, + $arrCfg['global']['theme']['mode'], + $arrCfg['global']['theme']['variant'] + ); + $arrCfg['theme'] = $theme; + $arrCfg['favicon'] = self::buildFavicon($arrCfg); + + return $arrCfg; } private static function getUrlFamilyPool(): array @@ -445,11 +462,7 @@ class SiteStyle $staticHash = $cfg['meta']['static_hash']; // 主题色(运行时算,不冻结具体颜色) - $theme = self::buildTheme( - $intSeed, - $cfg['global']['theme']['mode'], - $cfg['global']['theme']['variant'] - ); + $theme = $cfg['theme']; // 模板路径(你原来 include 用的方式完全保留) $tpl = $cfg['components']['templates']; @@ -483,6 +496,8 @@ class SiteStyle 'dom_prefix' => $domPrefix, 'static_hash' => $staticHash, + 'favicon' => $cfg['favicon'], + 'lazy_img' => self::pickLazyImg([ 'host' => $strHost, 'seed' => $intSeed, @@ -795,13 +810,13 @@ class SiteStyle 'seo' => '', ]; } - + $pool = require $file; - + $primaryPool = $pool['primary'] ?? []; $secondaryPool = $pool['secondary'] ?? []; $seoPool = $pool['seo'] ?? []; - + // 池兜底(防止被误删 / 配置异常) if (!$primaryPool || !$secondaryPool || !$seoPool) { return [ @@ -810,21 +825,21 @@ class SiteStyle 'seo' => '', ]; } - + // 域名级 + 榜单级稳定 $hP = abs(crc32($seed . '|rkpri|' . $sortType)); $hS = abs(crc32($seed . '|rksec|' . $sortType)); $hE = abs(crc32($seed . '|rkseo|' . $sortType)); - + $primaryTpl = $primaryPool[$hP % count($primaryPool)]; $secondaryTpl = $secondaryPool[$hS % count($secondaryPool)]; $seoTpl = $seoPool[$hE % count($seoPool)]; - + // 统一占位符替换(rank_home 统一用 {name}) $replace = [ '{name}' => $titleName, ]; - + return [ 'primary' => strtr($primaryTpl, $replace), 'secondary' => strtr($secondaryTpl, $replace), @@ -2597,4 +2612,78 @@ class SiteStyle return $memo[$key] = $data; return $memo[$relFile] = (is_array($data) ? $data : []); } + + /** + * 生成并冻结 favicon(与 theme_color / dom_prefix / layout 联动) + * 只在 SiteStyle 构建阶段调用 + */ + private static function buildFavicon(array $TpStyle): string + { + + $domain = $_SERVER['HTTP_HOST'] ?? 'cli'; + $safe = preg_replace('/[^a-z0-9\.\-]/i', '_', $domain); + + // ===== 下面开始“只执行一次”的生成逻辑 ===== + $seed = (int)($TpStyle['meta']['seed'] ?? crc32($domain)); + $bg = (string)($TpStyle['theme']['theme_color'] ?? '#263238'); + $fg = '#ffffff'; + + $strSvgRoute = '/static/favicon/generated/' . $seed . '/'; + $strSvgGenDir = root_path() . 'public/' . $strSvgRoute; + $strTmpSvgDir = $strSvgRoute . 'favicon.svg'; + + $svgFile = $strSvgGenDir . 'favicon.svg'; + $icoFile = $strSvgGenDir . 'favicon.ico'; + + if (!is_dir($strSvgGenDir)) { + @mkdir($strSvgGenDir, 0755, true); + } + + // 已生成过,直接复用(冻结) + if (is_file($icoFile) && is_file($svgFile)) { + return $strTmpSvgDir; + } + + $svgBasePath = root_path() . self::$faviconBaseDir; + $bases = glob($svgBasePath . '*.svg'); + if (!$bases) { + // 兜底,不影响上线 + return '/favicon.ico'; + } + + // 用 dom_prefix + layout 决定母型(稳定、可回放) + $layout = (string)($TpStyle['global']['theme']['layout'] ?? 'A'); + $dom = (string)($TpStyle['meta']['dom_prefix'] ?? ''); + + $idx = abs(crc32($layout . '|' . $dom . '|' . $seed)) % count($bases); + $baseSvg = $bases[$idx]; + + $svg = file_get_contents($baseSvg); + if ($svg === false) { + return '/favicon.ico'; + } + + // 注入主题色 + $svg = str_replace(['VAR_BG', 'VAR_FG'], [$bg, $fg], $svg); + + // 持久化 svg(便于排查、也便于后续升级) + @file_put_contents($svgFile, $svg); + + // 转 ico(16 / 32) + $bin = 'magick'; + if (!shell_exec('which magick')) { + $bin = 'convert'; + } + + $cmd = sprintf( + '%s %s -background none -define icon:auto-resize=16,32 %s', + $bin, + escapeshellarg($svgFile), + escapeshellarg($icoFile) + ); + + @exec($cmd); + + return $strTmpSvgDir; + } } diff --git a/code/app/home/view/videoGpt1/base.html b/code/app/home/view/videoGpt1/base.html index 5c84704..a8bbf7b 100644 --- a/code/app/home/view/videoGpt1/base.html +++ b/code/app/home/view/videoGpt1/base.html @@ -8,6 +8,9 @@ + + + {// 动态主题颜色 }