118 lines
5.8 KiB
PHP
118 lines
5.8 KiB
PHP
<?php
|
|
namespace Core;
|
|
|
|
/**
|
|
* 主题引擎:后台可设置任意网页风格(颜色 / 字体 / 圆角 / 容器 / 导航 / 明暗 / 自定义CSS)
|
|
* 渲染前台时通过 CSS 变量注入;保存后重新生成 public/assets/css/theme.css
|
|
*/
|
|
class Theme
|
|
{
|
|
private static $cache = null;
|
|
private static $cssPath = BASE_PATH . '/public/assets/css/theme.css';
|
|
|
|
public static function defaults(): array
|
|
{
|
|
return [
|
|
// 站点信息
|
|
'site_name' => '酷冰甲 · 降温服',
|
|
'site_slogan' => '科技降温 · 清凉一夏',
|
|
'site_logo' => '',
|
|
'contact_phone' => '400-1783-998',
|
|
'contact_email' => 'service@coolcoth.com',
|
|
'contact_address'=> '江苏省苏州市工业园区',
|
|
'icp' => '',
|
|
'seo_title' => '酷冰甲降温服 - 科技降温服装定制',
|
|
'seo_keywords' => '降温服, cooling clothing, 降温工作服, 清凉服定制',
|
|
'seo_description'=> '酷冰甲专注降温服研发与定制,采用相变蓄冷与循环水冷技术,为高温作业人群提供清凉解决方案。',
|
|
// 主题风格
|
|
'preset' => 'ocean',
|
|
'primary' => '#0ea5e9',
|
|
'primary_600' => '#0284c7',
|
|
'secondary' => '#14b8a6',
|
|
'accent' => '#f59e0b',
|
|
'bg' => '#ffffff',
|
|
'surface' => '#f8fafc',
|
|
'text' => '#0f172a',
|
|
'muted' => '#64748b',
|
|
'border' => '#e2e8f0',
|
|
'nav_bg' => 'rgba(255,255,255,0.72)',
|
|
'font' => "'Noto Sans SC', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif",
|
|
'radius' => '16',
|
|
'container' => '1200',
|
|
'header' => 'center', // center | left | transparent
|
|
'default_mode' => 'light', // light | dark
|
|
'custom_css' => '',
|
|
];
|
|
}
|
|
|
|
/** 合并默认值与数据库设置 */
|
|
public static function all(): array
|
|
{
|
|
if (self::$cache !== null) return self::$cache;
|
|
$def = self::defaults();
|
|
$setting = new \App\Models\Setting();
|
|
$saved = $setting->allKV();
|
|
self::$cache = array_merge($def, $saved);
|
|
return self::$cache;
|
|
}
|
|
|
|
public static function get(string $key, $default = '')
|
|
{
|
|
$all = self::all();
|
|
return $all[$key] ?? $default;
|
|
}
|
|
|
|
public static function clearCache(): void
|
|
{
|
|
self::$cache = null;
|
|
}
|
|
|
|
/** 预设主题(后台一键套用) */
|
|
public static function presets(): array
|
|
{
|
|
return [
|
|
'ocean' => ['label' => '海洋蓝', 'vars' => ['primary'=>'#0ea5e9','primary_600'=>'#0284c7','secondary'=>'#14b8a6','accent'=>'#f59e0b','bg'=>'#ffffff','surface'=>'#f8fafc','text'=>'#0f172a','muted'=>'#64748b','border'=>'#e2e8f0','nav_bg'=>'rgba(255,255,255,0.72)']],
|
|
'forest' => ['label' => '森野绿', 'vars' => ['primary'=>'#16a34a','primary_600'=>'#15803d','secondary'=>'#0d9488','accent'=>'#f97316','bg'=>'#ffffff','surface'=>'#f6fdf8','text'=>'#0f172a','muted'=>'#5b7065','border'=>'#dcefe2','nav_bg'=>'rgba(255,255,255,0.72)']],
|
|
'aurora' => ['label' => '极光紫', 'vars' => ['primary'=>'#8b5cf6','primary_600'=>'#7c3aed','secondary'=>'#06b6d4','accent'=>'#ec4899','bg'=>'#ffffff','surface'=>'#faf7ff','text'=>'#1e1b2e','muted'=>'#6b6480','border'=>'#ece6f7','nav_bg'=>'rgba(255,255,255,0.72)']],
|
|
'sunset' => ['label' => '日落橙', 'vars' => ['primary'=>'#f97316','primary_600'=>'#ea580c','secondary'=>'#ef4444','accent'=>'#facc15','bg'=>'#ffffff','surface'=>'#fffaf3','text'=>'#1c1917','muted'=>'#78716c','border'=>'#faead7','nav_bg'=>'rgba(255,255,255,0.72)']],
|
|
'mono' => ['label' => '极简黑金', 'vars' => ['primary'=>'#111827','primary_600'=>'#000000','secondary'=>'#ca8a04','accent'=>'#ca8a04','bg'=>'#ffffff','surface'=>'#fafafa','text'=>'#111827','muted'=>'#6b7280','border'=>'#e5e7eb','nav_bg'=>'rgba(255,255,255,0.75)']],
|
|
'ice' => ['label' => '冰晶青', 'vars' => ['primary'=>'#06b6d4','primary_600'=>'#0891b2','secondary'=>'#3b82f6','accent'=>'#22d3ee','bg'=>'#ffffff','surface'=>'#f0fbfd','text'=>'#0c1a24','muted'=>'#5b7686','border'=>'#d3eef5','nav_bg'=>'rgba(255,255,255,0.72)']],
|
|
];
|
|
}
|
|
|
|
/** 生成 theme.css 文本 */
|
|
public static function buildCss(): string
|
|
{
|
|
$t = self::all();
|
|
$v = function ($k) use ($t) { return $t[$k] ?? ''; };
|
|
$css = ":root{\n";
|
|
$css .= " --c-primary:{$v('primary')};\n";
|
|
$css .= " --c-primary-600:{$v('primary_600')};\n";
|
|
$css .= " --c-secondary:{$v('secondary')};\n";
|
|
$css .= " --c-accent:{$v('accent')};\n";
|
|
$css .= " --c-bg:{$v('bg')};\n";
|
|
$css .= " --c-surface:{$v('surface')};\n";
|
|
$css .= " --c-text:{$v('text')};\n";
|
|
$css .= " --c-muted:{$v('muted')};\n";
|
|
$css .= " --c-border:{$v('border')};\n";
|
|
$css .= " --nav-bg:{$v('nav_bg')};\n";
|
|
$css .= " --font-base:{$v('font')};\n";
|
|
$css .= " --radius:{$v('radius')}px;\n";
|
|
$css .= " --container:{$v('container')}px;\n";
|
|
$css .= "}\n";
|
|
$css .= "[data-theme=\"dark\"]{\n";
|
|
$css .= " --c-bg:#0b1120;--c-surface:#111827;--c-text:#e5e7eb;--c-muted:#94a3b8;--c-border:#1f2937;--nav-bg:rgba(11,17,32,0.72);\n";
|
|
$css .= "}\n";
|
|
$css .= $v('custom_css') . "\n";
|
|
return $css;
|
|
}
|
|
|
|
/** 重新生成主题 CSS 文件 */
|
|
public static function regenerate(): bool
|
|
{
|
|
$dir = dirname(self::$cssPath);
|
|
if (!is_dir($dir)) mkdir($dir, 0755, true);
|
|
return (bool) file_put_contents(self::$cssPath, self::buildCss());
|
|
}
|
|
}
|