Files
cloud-chip.cn/resources/views/layouts/app.blade.php
T
2026-08-08 18:27:38 +08:00

300 lines
19 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="csrf-token" content="{{ csrf_token() }}">
@php
$siteName = App\Models\Setting::get('site_name', '深圳市云创芯电子有限公司');
$seoTitleDefault = App\Models\Setting::get('seo_title_default', $siteName . ' - 多口 TypeC 接口IC');
$seoDescDefault = App\Models\Setting::get('seo_description_default', '深圳市云创芯电子有限公司提供多口 TypeC 接口IC。');
$logoUrl = '/images/logo-dark.png'; // 固定品牌 logo,直接指向深色版,不依赖数据库设置(避免服务器库未同步导致回退旧 logo)
$faviconUrl = App\Models\Setting::get('favicon_url', '/images/ccc-icon.ico');
$icpNo = App\Models\Setting::get('icp_no', '');
$securityFilingNo = App\Models\Setting::get('security_filing_no', '粤公网安备44030002015390号');
// 主题配色:后台「站点设置」可切换;默认 azure(沉稳蓝)
$themes = [
'azure' => ['primary' => '#4a8af4', 'hover' => '#76a9f7', 'accent' => '#6fa8f7', 'info' => '#4a8af4', 'rgb' => '74,138,244'],
'slate' => ['primary' => '#6e8cb0', 'hover' => '#8aa6c6', 'accent' => '#7d98ba', 'info' => '#6e8cb0', 'rgb' => '110,140,176'],
'indigo' => ['primary' => '#7b7ef0', 'hover' => '#9b9df6', 'accent' => '#8f86f2', 'info' => '#7b7ef0', 'rgb' => '123,126,240'],
'teal' => ['primary' => '#2bb6a4', 'hover' => '#4fd0bd', 'accent' => '#34c0ad', 'info' => '#2bb6a4', 'rgb' => '43,182,164'],
'amber' => ['primary' => '#e8a13c', 'hover' => '#f2b765', 'accent' => '#ecae52', 'info' => '#e8a13c', 'rgb' => '232,161,60'],
];
$themeKey = App\Models\Setting::get('theme', 'azure');
$theme = $themes[$themeKey] ?? $themes['azure'];
@endphp
<title>@yield('title', $seoTitleDefault)</title>
<meta name="description" content="@yield('description', $seoDescDefault)">
<link rel="canonical" href="{{ url()->current() }}">
<meta property="og:type" content="website">
<meta property="og:site_name" content="{{ $siteName }}">
<meta property="og:title" content="@yield('title', $seoTitleDefault)">
<meta property="og:description" content="@yield('description', $seoDescDefault)">
<meta property="og:url" content="{{ url()->current() }}">
<meta property="og:image" content="{{ asset($logoUrl) }}">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="@yield('title', $seoTitleDefault)">
<meta name="twitter:description" content="@yield('description', $seoDescDefault)">
<meta name="twitter:image" content="{{ asset($logoUrl) }}">
<link rel="icon" href="{{ asset($faviconUrl) }}" sizes="any">
<link rel="stylesheet" href="{{ asset('css/app.css') }}?v={{ filemtime(public_path('css/app.css')) }}">
<!-- 主题配色覆盖:由后台「站点设置 主题」选择,注入后覆盖 app.css 默认 :root 变量(主色 + 光晕同步联动) -->
<style id="theme-override">
:root {
--color-primary: {{ $theme['primary'] }};
--color-primary-hover: {{ $theme['hover'] }};
--color-accent: {{ $theme['accent'] }};
--color-info: {{ $theme['info'] }};
--glow-color: {{ $theme['rgb'] }};
}
</style>
<!-- Tailwind Play CDN(零构建);颜色全部映射到 :root CSS 变量,源码不硬编码颜色 -->
<script src="https://cdn.tailwindcss.com"></script>
<script>
tailwind.config = {
theme: {
extend: {
colors: {
primary: 'var(--color-primary)',
'primary-hover': 'var(--color-primary-hover)',
'primary-soft': 'var(--color-primary-soft)',
surface: 'var(--color-surface)',
'surface-2': 'var(--color-surface-2)',
line: 'var(--color-border)',
fg: 'var(--color-text)',
muted: 'var(--color-text-muted)',
danger: 'var(--color-danger)',
'danger-hover': 'var(--color-danger-hover)',
'danger-soft': 'var(--color-danger-soft)',
success: 'var(--color-success)',
'success-soft': 'var(--color-success-soft)',
warning: 'var(--color-warning)',
'warning-soft': 'var(--color-warning-soft)',
info: 'var(--color-info)',
'info-soft': 'var(--color-info-soft)',
bg: 'var(--color-bg)',
accent: 'var(--color-accent)',
},
fontFamily: {
sans: ['Inter', 'Noto Sans SC', 'system-ui', '-apple-system', 'Segoe UI', 'Roboto', 'Helvetica Neue', 'Arial', 'PingFang SC', 'Microsoft YaHei', 'sans-serif'],
},
borderRadius: {
sm: 'var(--radius-sm)',
DEFAULT: 'var(--radius)',
lg: 'var(--radius-lg)',
},
boxShadow: {
soft: '0 1px 2px rgba(15, 23, 42, 0.06)',
card: '0 4px 14px rgba(15, 23, 42, 0.08)',
},
maxWidth: {
'8xl': '80rem',
},
}
}
};
</script>
<script src="{{ asset('js/vendor/vue.global.prod.js') }}" defer></script>
<script src="{{ asset('js/app.js') }}?v={{ filemtime(public_path('js/app.js')) }}" defer></script>
<script type="application/ld+json">
{
"@@context": "https://schema.org",
"@@type": "Organization",
"name": {!! json_encode($siteName, JSON_UNESCAPED_UNICODE) !!},
"url": {!! json_encode(url('/'), JSON_UNESCAPED_UNICODE) !!},
"logo": {!! json_encode(asset($logoUrl), JSON_UNESCAPED_UNICODE) !!},
"description": {!! json_encode($seoDescDefault, JSON_UNESCAPED_UNICODE) !!}
}
</script>
</head>
<body class="font-sans text-fg bg-surface antialiased">
@php
// 前台顶部导航菜单(后台「导航菜单」可全权管理:显示/隐藏 + 排序)
$navMenus = \App\Models\NavigationMenu::visible()->ordered()->get();
@endphp
<!-- 顶部导航:TI 企业蓝风格,sticky + 留白 + 清晰层级 -->
<header class="sticky top-0 z-50 bg-surface/90 backdrop-blur border-b border-line">
<div class="max-w-8xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex items-center justify-between h-14 lg:h-[68px]">
<a class="flex items-center gap-3 shrink-0" href="{{ url('/') }}" aria-label="{{ $siteName }}">
<img src="{{ asset($logoUrl) }}" alt="{{ $siteName }}" class="h-12 w-auto lg:h-14 drop-shadow-sm">
</a>
<nav class="hidden lg:flex items-center gap-7">
@foreach ($navMenus as $m)
<a href="{{ Str::startsWith($m->url, ['http://', 'https://']) ? $m->url : url($m->url) }}" class="text-lg lg:text-xl font-medium text-muted hover:text-primary transition-colors">{{ $m->label }}</a>
@endforeach
</nav>
<div class="hidden lg:flex items-center gap-5">
<!-- 全站搜索 -->
<form action="{{ url('/search') }}" method="GET" class="relative">
<x-icon name="search" :size="20" class="absolute left-3 top-1/2 -translate-y-1/2 text-muted pointer-events-none" />
<input type="search" name="q" value="{{ request('q', '') }}" placeholder="搜索产品、文章、术语…" class="w-56 rounded-lg border border-line bg-surface-2 pl-10 pr-3 py-2.5 text-lg text-fg placeholder:text-muted focus:border-primary focus:outline-none focus:shadow-[0_0_0_3px_var(--color-primary-soft)]">
</form>
@auth
@if (Auth::user()->role !== 'user')
<a href="{{ url('/admin') }}" class="text-lg lg:text-xl font-medium text-muted hover:text-primary transition-colors">后台</a>
@endif
<a href="{{ route('articles.submit') }}" class="text-lg lg:text-xl font-medium text-muted hover:text-primary transition-colors">投稿</a>
<x-level-badge :user="Auth::user()" />
<span class="text-lg lg:text-xl text-muted">{{ Auth::user()->name }}</span>
<a href="{{ route('auth.settings') }}" class="text-lg lg:text-xl font-medium text-muted hover:text-primary transition-colors">设置</a>
<form method="POST" action="{{ url('/logout') }}" class="inline">
@csrf
<button type="submit" class="text-lg lg:text-xl font-medium text-muted hover:text-danger transition-colors">退出</button>
</form>
@endauth
</div>
<!-- 移动端菜单按钮 -->
<button id="nav-toggle" type="button" class="lg:hidden inline-flex items-center justify-center p-2 rounded-lg text-muted hover:bg-surface-2" aria-label="菜单">
<svg width="26" height="26" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M4 6h16M4 12h16M4 18h16"/></svg>
</button>
</div>
</div>
<!-- 移动端展开菜单 -->
<div id="nav-menu" class="lg:hidden hidden border-t border-line bg-surface">
<div class="max-w-8xl mx-auto px-4 py-3 space-y-1">
<form action="{{ url('/search') }}" method="GET" class="relative mb-2">
<x-icon name="search" :size="20" class="absolute left-3 top-1/2 -translate-y-1/2 text-muted pointer-events-none" />
<input type="search" name="q" value="{{ request('q', '') }}" placeholder="搜索产品、文章、术语…" class="w-full rounded-lg border border-line bg-surface-2 pl-10 pr-3 py-2.5 text-lg text-fg placeholder:text-muted focus:border-primary focus:outline-none focus:shadow-[0_0_0_3px_var(--color-primary-soft)]">
</form>
@foreach ($navMenus as $m)
<a href="{{ Str::startsWith($m->url, ['http://', 'https://']) ? $m->url : url($m->url) }}" class="block px-3 py-2.5 rounded-lg text-lg font-medium text-muted hover:bg-surface-2 hover:text-primary">{{ $m->label }}</a>
@endforeach
@auth
@if (Auth::user()->role !== 'user')
<a href="{{ url('/admin') }}" class="block px-3 py-2.5 rounded-lg text-lg font-medium text-muted hover:bg-surface-2 hover:text-primary">后台</a>
@endif
<a href="{{ route('articles.submit') }}" class="block px-3 py-2.5 rounded-lg text-lg font-medium text-muted hover:bg-surface-2 hover:text-primary">投稿</a>
<div class="px-3 py-2.5"><x-level-badge :user="Auth::user()" /></div>
<a href="{{ route('auth.settings') }}" class="block px-3 py-2.5 rounded-lg text-lg font-medium text-muted hover:bg-surface-2 hover:text-primary">设置</a>
<form method="POST" action="{{ url('/logout') }}" class="block">
@csrf
<button type="submit" class="w-full text-left px-3 py-2.5 rounded-lg text-lg font-medium text-muted hover:bg-surface-2 hover:text-danger">退出({{ Auth::user()->name }}</button>
</form>
@endauth
</div>
</div>
</header>
<main class="min-h-[60vh]">
<div class="max-w-8xl mx-auto px-4 sm:px-6 lg:px-8">
@if (session('success'))
<div class="flex items-center gap-2 my-6 rounded-lg border border-success/30 bg-success-soft px-4 py-3 text-sm text-success">
<x-icon name="check" :size="18" />
<span>{{ session('success') }}</span>
</div>
@endif
@if ($errors?->any())
<div class="flex items-center gap-2 my-6 rounded-lg border border-danger/30 bg-danger-soft px-4 py-3 text-sm text-danger">
<x-icon name="alert" :size="18" />
<span>{{ $errors->first() ?: '表单填写有误,请检查后重试。' }}</span>
</div>
@endif
</div>
@yield('content')
</main>
<footer class="mt-16 border-t border-line bg-surface">
<div class="max-w-8xl mx-auto px-4 sm:px-6 lg:px-8 py-10">
<div class="grid gap-8 md:grid-cols-4">
<div class="md:col-span-2">
<div class="flex items-center gap-3 mb-3">
<img src="{{ asset($logoUrl) }}" alt="{{ $siteName }}" class="h-12 w-auto drop-shadow-sm">
</div>
<p class="text-sm text-muted max-w-md">TypeC 产品顾问|多口 TypeC 接口IC 方案提供商,专注协议转换与同步整流控制芯片,面向充电与外设厂商。</p>
</div>
<div>
<h4 class="text-sm font-semibold text-fg mb-3">产品与资源</h4>
<ul class="space-y-2 text-sm text-muted">
<li><a href="{{ url('/products') }}" class="hover:text-primary transition-colors">产品中心</a></li>
<li><a href="{{ url('/solutions') }}" class="hover:text-primary transition-colors">解决方案</a></li>
<li><a href="{{ url('/about') }}" class="hover:text-primary transition-colors">关于我们</a></li>
<li><a href="{{ url('/articles') }}" class="hover:text-primary transition-colors">技术文章</a></li>
<li><a href="{{ url('/news') }}" class="hover:text-primary transition-colors">新闻动态</a></li>
<li><a href="{{ url('/glossary') }}" class="hover:text-primary transition-colors">术语库</a></li>
<li><a href="{{ url('/forum') }}" class="hover:text-primary transition-colors">技术论坛</a></li>
</ul>
</div>
<div>
<h4 class="text-sm font-semibold text-fg mb-3">联系我们</h4>
<ul class="space-y-2.5 text-sm text-muted">
<li class="flex items-start gap-2">
<x-icon name="box" :size="16" class="mt-0.5 shrink-0 text-muted" />
<span>深圳市云创芯电子有限公司</span>
</li>
<li class="flex items-center gap-2">
<x-icon name="mail" :size="16" class="shrink-0 text-muted" />
<a href="mailto:service@51chip.net" class="hover:text-primary transition-colors">service@51chip.net</a>
</li>
<li class="flex items-center gap-2">
<x-icon name="phone" :size="16" class="shrink-0 text-muted" />
<a href="tel:13510116819" class="hover:text-primary transition-colors">13510116819</a>
</li>
<li><a href="{{ url('/contact') }}" class="hover:text-primary transition-colors">更多联络方式</a></li>
@auth
@if (Auth::user()->role !== 'user')
<li><a href="{{ url('/admin') }}" class="hover:text-primary transition-colors">管理后台</a></li>
@endif
@endauth
</ul>
</div>
</div>
@php $footerContent = App\Models\Setting::get('footer_content'); @endphp
@if ($footerContent)
<div class="mt-8 footer-rich">
{!! \Purifier::clean($footerContent, 'article') !!}
</div>
@endif
<div class="mt-8 pt-6 border-t border-line text-sm text-muted">
<p class="flex flex-wrap items-center gap-x-3 gap-y-1">
<span>© {{ date('Y') }} {{ $siteName }}. 保留所有权利。</span>
<a href="{{ url('/sitemap') }}" class="hover:text-primary transition-colors">网站地图</a>
@if ($icpNo)
<a href="https://beian.miit.gov.cn/" target="_blank" rel="nofollow noopener noreferrer" class="icp-link">{{ $icpNo }}</a>
@endif
@php
// 公安网备号:优先取后台「站点设置」值,缺省内置粤公网安备44030002015390号
$secRaw = trim($securityFilingNo);
if ($secRaw === '') {
$secRaw = '粤公网安备44030002015390号';
}
// 提取数字编号,用于公安网备核验深链
preg_match('/\d{6,}/', $secRaw, $secMatch);
$secCode = $secMatch[0] ?? '44030002015390';
// 规范显示文案:缺「粤公网安备」前缀时自动补上并加「号」
if (!preg_match('/粤公网安备/', $secRaw)) {
$secRaw = '粤公网安备' . preg_replace('/\D/', '', $secRaw) . '号';
}
@endphp
<a href="https://beian.mps.gov.cn/#/query/webSearch?code={{ $secCode }}" target="_blank" rel="nofollow noopener noreferrer" class="icp-link inline-flex items-center gap-1">
<img src="{{ asset('images/gongan_badge.png') }}" width="16" height="17" alt="公安网备" loading="lazy" class="inline-block align-middle" onerror="this.onerror=null;this.outerHTML='<svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;16&quot; height=&quot;17&quot; viewBox=&quot;0 0 24 24&quot;><path d=&quot;M12 2l8 3v6c0 5-4 9-8 11-4-2-8-6-8-11V5l8-3z&quot; fill=&quot;#1a3a8f&quot; stroke=&quot;#d4af37&quot; stroke-width=&quot;1&quot;/><polygon points=&quot;12,7 13.5,10.5 17,10.5 14,12.8 15,16.5 12,14.5 9,16.5 10,12.8 7,10.5 10.5,10.5&quot; fill=&quot;#ffffff&quot;/></svg>'">
{{ $secRaw }}
</a>
</p>
</div>
</div>
</footer>
<script>
(function () {
var btn = document.getElementById('nav-toggle');
var menu = document.getElementById('nav-menu');
if (btn && menu) {
btn.addEventListener('click', function () {
menu.classList.toggle('hidden');
});
}
})();
</script>
</body>
</html>