Files
web_template/web/dist/shop4/index.html
Geliebte 10979351f8 feat: 默认语言改为英语 + 导航页添加i18n三语支持
- 导航页(index.html)添加完整i18n引擎,支持zh-CN/zh-TW/en
- 导航页添加语言切换按钮(EN/中/繁)
- 所有20个前端模板默认语言从zh-CN改为en
- 导航页SEO meta标签改为英文
2026-09-09 19:48:45 +08:00

1261 lines
66 KiB
HTML
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="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>古树商城 · TreeShop</title>
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><rect width='100' height='100' rx='20' fill='%231a1a2e'/><text x='50' y='68' font-size='50' fill='%2380d8' text-anchor='middle'>🌳</text></svg>">
<style>
*,*::before,*::after{margin:0;padding:0;box-sizing:border-box}
:root{
--bg:#0a0e0a;--bg2:#121810;--surface:rgba(255,255,255,.04);--card:rgba(255,255,255,.06);
--border:rgba(255,255,255,.08);--text:#e6edf3;--text-muted:#7d8590;
--primary:#58d68d;--primary-glow:rgba(88,214,141,.25);--accent:#f0c674;
--radius:16px;--blur-amount:8px;
}
[data-theme="light"]{
--bg:#f5f3f0;--bg2:#ffffff;--surface:rgba(0,0,0,.03);--card:rgba(0,0,0,.04);
--border:rgba(0,0,0,.08);--text:#1a1a2e;--text-muted:#6b7280;
--primary:#2d7a4e;--primary-glow:rgba(45,122,78,.2);--accent:#b8860b;
}
body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Noto Sans SC,sans-serif;background:var(--bg);color:var(--text);overflow-x:hidden;transition:background .4s,color .4s}
a{color:inherit;text-decoration:none}
/* ========== 导航栏 ========== */
.navbar{position:fixed;top:0;left:0;right:0;z-index:200;display:flex;align-items:center;justify-content:space-between;padding:16px 32px;background:rgba(10,14,10,.6);backdrop-filter:blur(20px);border-bottom:1px solid var(--border);transition:all .4s}
[data-theme="light"] .navbar{background:rgba(255,255,255,.7)}
.nav-brand{font-size:22px;font-weight:800;display:flex;align-items:center;gap:8px}
.nav-brand .tree-icon{font-size:26px}
.nav-links{display:flex;gap:28px}
.nav-links a{font-size:14px;font-weight:500;color:var(--text-muted);transition:color .2s;cursor:pointer}
.nav-links a:hover{color:var(--text)}
.nav-actions{display:flex;align-items:center;gap:16px}
.cart-btn{position:relative;background:var(--surface);border:1px solid var(--border);border-radius:50%;width:40px;height:40px;display:flex;align-items:center;justify-content:center;cursor:pointer;font-size:18px;color:var(--text)}
.cart-badge{position:absolute;top:-4px;right:-4px;background:var(--primary);color:#fff;font-size:11px;font-weight:700;min-width:18px;height:18px;border-radius:9px;display:flex;align-items:center;justify-content:center;padding:0 4px}
/* ========== 黑白模式切换 ========== */
.theme-toggle{position:relative;width:44px;height:44px;border-radius:50%;border:1px solid var(--border);background:var(--surface);cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .3s;overflow:hidden}
.theme-toggle:hover{border-color:var(--primary);box-shadow:0 0 16px var(--primary-glow)}
.theme-toggle .sun-icon{position:absolute;font-size:22px;transition:all .4s cubic-bezier(.4,0,.2,1)}
[data-theme="dark"] .sun-icon{transform:translateY(0) rotate(0);opacity:1}
[data-theme="light"] .sun-icon{transform:translateY(-40px) rotate(180deg);opacity:0}
.theme-toggle .moon-icon{position:absolute;font-size:20px;transition:all .4s cubic-bezier(.4,0,.2,1)}
[data-theme="dark"] .moon-icon{transform:translateY(40px) rotate(180deg);opacity:0}
[data-theme="light"] .moon-icon{transform:translateY(0) rotate(0);opacity:1}
/* ========== 语言切换器 ========== */
.lang-switcher{position:relative}
.lang-btn{display:flex;align-items:center;gap:6px;padding:8px 14px;border-radius:10px;font-size:13px;font-weight:600;color:var(--text-muted);cursor:pointer;background:var(--surface);border:1px solid var(--border);transition:all .25s}
.lang-btn:hover{color:var(--text);background:var(--card);border-color:var(--primary)}
.lang-btn svg{width:16px;height:16px}
.lang-dropdown{position:absolute;top:calc(100% + 8px);right:0;min-width:160px;background:var(--bg2);backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);border:1px solid var(--border);border-radius:var(--radius);box-shadow:0 12px 40px rgba(0,0,0,.5);overflow:hidden;opacity:0;transform:translateY(-8px);pointer-events:none;transition:all .25s;z-index:1001}
.lang-dropdown.open{opacity:1;transform:none;pointer-events:auto}
.lang-option{display:flex;align-items:center;gap:10px;padding:12px 16px;font-size:14px;color:var(--text-muted);cursor:pointer;transition:all .2s}
.lang-option:hover{background:var(--surface);color:var(--text)}
.lang-option.active{color:var(--primary);font-weight:600}
.lang-option .check{width:16px;height:16px;opacity:0;transition:opacity .2s}
.lang-option.active .check{opacity:1}
/* ========== Hero 横向动态 ========== */
.hero{position:relative;width:100%;height:100vh;min-height:640px;overflow:hidden;background:#060a06}
#treeCanvas{position:absolute;inset:0;width:100%;height:100%;z-index:1}
.hero-overlay{position:absolute;inset:0;z-index:2;background:linear-gradient(180deg,rgba(6,10,6,.1) 0%,rgba(6,10,6,.35) 55%,var(--bg) 100%);pointer-events:none;transition:background .4s}
[data-theme="light"] .hero-overlay{background:linear-gradient(180deg,rgba(245,243,240,.05) 0%,rgba(245,243,240,.3) 55%,var(--bg) 100%)}
/* 横向滚动容器 */
.hero-scroll-wrap{position:absolute;inset:0;z-index:3;display:flex;align-items:center;overflow-x:auto;overflow-y:hidden;scroll-snap-type:x mandatory;scrollbar-width:none}
.hero-scroll-wrap::-webkit-scrollbar{display:none}
.hero-panel{min-width:100vw;height:100vh;display:flex;align-items:center;justify-content:center;scroll-snap-align:start;position:relative;padding:0 8vw}
.hero-panel-content{max-width:680px}
.hero-badge{display:inline-flex;align-items:center;gap:8px;padding:6px 18px;border-radius:100px;background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.12);font-size:13px;color:rgba(255,255,255,.7);margin-bottom:24px;backdrop-filter:blur(10px)}
.hero-badge .dot{width:6px;height:6px;border-radius:50%;background:var(--primary);box-shadow:0 0 8px var(--primary);animation:pulse 2s infinite}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.3}}
.hero-panel h1{font-size:64px;font-weight:900;line-height:1.08;letter-spacing:-2px;color:#fff;margin-bottom:20px;text-shadow:0 4px 30px rgba(0,0,0,.5)}
[data-theme="light"] .hero-panel h1{color:#1a1a2e;text-shadow:0 4px 30px rgba(0,0,0,.1)}
.hero-panel h1 .accent{background:linear-gradient(135deg,var(--primary) 0%,var(--accent) 100%);-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text}
.hero-panel p{font-size:18px;color:rgba(255,255,255,.55);line-height:1.7;margin-bottom:32px;max-width:520px}
[data-theme="light"] .hero-panel p{color:rgba(26,26,46,.6)}
.hero-panel-actions{display:flex;gap:14px;align-items:center}
.btn-primary{display:inline-flex;align-items:center;gap:8px;background:linear-gradient(135deg,var(--primary),#3da56a);color:#fff;padding:14px 36px;border-radius:100px;font-size:15px;font-weight:700;border:none;cursor:pointer;transition:all .3s;box-shadow:0 8px 28px var(--primary-glow)}
.btn-primary:hover{transform:translateY(-2px);box-shadow:0 12px 36px var(--primary-glow)}
.btn-ghost{display:inline-flex;align-items:center;gap:8px;background:rgba(255,255,255,.06);color:#fff;padding:14px 28px;border-radius:100px;font-size:14px;font-weight:600;border:1px solid rgba(255,255,255,.15);cursor:pointer;backdrop-filter:blur(10px);transition:all .3s}
[data-theme="light"] .btn-ghost{color:#1a1a2e;background:rgba(0,0,0,.04);border-color:rgba(0,0,0,.1)}
.btn-ghost:hover{background:rgba(255,255,255,.12)}
[data-theme="light"] .btn-ghost:hover{background:rgba(0,0,0,.08)}
/* 横向指示器 */
.hero-dots{position:absolute;bottom:40px;left:50%;transform:translateX(-50%);z-index:5;display:flex;gap:10px}
.hero-dot{width:8px;height:8px;border-radius:50%;background:rgba(255,255,255,.2);cursor:pointer;transition:all .3s}
.hero-dot.active{width:28px;border-radius:4px;background:var(--primary)}
.hero-arrow{position:absolute;bottom:20px;right:40px;z-index:5;color:rgba(255,255,255,.4);font-size:12px;display:flex;align-items:center;gap:6px;animation:bounce-h 2s infinite}
@keyframes bounce-h{0%,100%{transform:translateX(0)}50%{transform:translateX(8px)}}
/* 面板2/3 样式 */
.hero-features{display:grid;grid-template-columns:repeat(2,1fr);gap:20px;margin-top:32px}
.hero-feature{background:rgba(255,255,255,.04);border:1px solid rgba(255,255,255,.08);border-radius:var(--radius);padding:24px;backdrop-filter:blur(10px)}
[data-theme="light"] .hero-feature{background:rgba(0,0,0,.03);border-color:rgba(0,0,0,.06)}
.hero-feature .icon{font-size:32px;margin-bottom:12px}
.hero-feature h3{font-size:16px;font-weight:700;color:#fff;margin-bottom:6px}
[data-theme="light"] .hero-feature h3{color:#1a1a2e}
.hero-feature p{font-size:13px;color:rgba(255,255,255,.5);line-height:1.5}
[data-theme="light"] .hero-feature p{color:rgba(26,26,46,.55)}
/* ========== 商品表格区域 ========== */
.products-section{position:relative;min-height:100vh;padding:80px 0;z-index:10}
.products-bg{position:absolute;inset:0;z-index:0;overflow:hidden}
.products-bg canvas{width:100%;height:100%;display:block}
.products-bg::after{content:'';position:absolute;inset:0;background:var(--bg);opacity:.82}
.products-content{position:relative;z-index:1;max-width:1280px;margin:0 auto;padding:0 32px}
.section-header{text-align:center;margin-bottom:48px}
.section-header h2{font-size:36px;font-weight:800;letter-spacing:-1px;margin-bottom:12px}
.section-header h2 .accent{color:var(--primary)}
.section-header p{font-size:15px;color:var(--text-muted)}
/* 筛选条 */
.filter-bar{display:flex;gap:12px;align-items:center;flex-wrap:wrap;margin-bottom:32px;justify-content:center}
.filter-chip{padding:8px 20px;border-radius:100px;background:var(--surface);border:1px solid var(--border);font-size:13px;font-weight:500;color:var(--text-muted);cursor:pointer;transition:all .2s}
.filter-chip:hover{border-color:var(--primary);color:var(--text)}
.filter-chip.active{background:var(--primary);color:#fff;border-color:var(--primary)}
.search-box{display:flex;align-items:center;gap:8px;background:var(--surface);border:1px solid var(--border);border-radius:100px;padding:8px 20px;min-width:240px}
.search-box input{background:none;border:none;outline:none;color:var(--text);font-size:14px;flex:1}
.search-box svg{width:16px;height:16px;color:var(--text-muted)}
/* 表格 */
.table-wrap{background:var(--bg2);border-radius:var(--radius);overflow:hidden;border:1px solid var(--border);box-shadow:0 8px 32px rgba(0,0,0,.15)}
.product-table{width:100%;border-collapse:collapse}
.product-table th{background:var(--surface);padding:16px 20px;text-align:left;font-size:13px;font-weight:700;color:var(--text-muted);text-transform:uppercase;letter-spacing:.5px;border-bottom:1px solid var(--border);white-space:nowrap}
.product-table td{padding:14px 20px;border-bottom:1px solid var(--border);font-size:14px;vertical-align:middle}
.product-table tbody tr{transition:background .2s;cursor:pointer}
.product-table tbody tr:hover{background:var(--surface)}
.product-table tbody tr:last-child td{border-bottom:none}
.td-img{width:60px;height:60px;border-radius:10px;overflow:hidden;display:flex;align-items:center;justify-content:center;flex-shrink:0}
.td-img img{width:100%;height:100%;object-fit:cover}
.td-img .placeholder{width:100%;height:100%;display:flex;align-items:center;justify-content:center;font-size:24px;background:var(--surface)}
.td-name{font-weight:600;color:var(--text)}
.td-price{font-weight:700;color:var(--primary);font-size:15px}
.td-category{color:var(--text-muted);font-size:13px}
.td-rating{display:flex;align-items:center;gap:4px}
.td-rating .star{color:var(--accent)}
.td-actions{display:flex;gap:8px}
.td-btn{padding:6px 16px;border-radius:8px;font-size:12px;font-weight:600;border:none;cursor:pointer;transition:all .2s}
.td-btn-primary{background:var(--primary);color:#fff}
.td-btn-primary:hover{opacity:.85}
.td-btn-ghost{background:var(--surface);color:var(--text);border:1px solid var(--border)}
.td-btn-ghost:hover{border-color:var(--primary)}
/* 分页 */
.pagination{display:flex;gap:8px;justify-content:center;align-items:center;margin-top:32px}
.page-btn{min-width:40px;height:40px;border-radius:10px;border:1px solid var(--border);background:var(--surface);color:var(--text-muted);font-size:14px;font-weight:600;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .2s}
.page-btn:hover:not(:disabled){border-color:var(--primary);color:var(--text)}
.page-btn.active{background:var(--primary);color:#fff;border-color:var(--primary)}
.page-btn:disabled{opacity:.4;cursor:not-allowed}
/* ========== Footer ========== */
.footer{background:var(--bg2);border-top:1px solid var(--border);padding:48px 32px 32px}
.footer-content{max-width:1280px;margin:0 auto;display:grid;grid-template-columns:2fr 1fr 1fr 1fr;gap:40px}
.footer-brand h3{font-size:20px;font-weight:800;margin-bottom:12px;display:flex;align-items:center;gap:8px}
.footer-brand p{font-size:13px;color:var(--text-muted);line-height:1.6;max-width:320px}
.footer-col h4{font-size:14px;font-weight:700;margin-bottom:14px}
.footer-col a{display:block;font-size:13px;color:var(--text-muted);padding:4px 0;cursor:pointer;transition:color .2s}
.footer-col a:hover{color:var(--text)}
.footer-bottom{text-align:center;padding:24px 0 0;margin-top:32px;border-top:1px solid var(--border);font-size:12px;color:var(--text-muted)}
/* ========== Modal ========== */
.modal-overlay{position:fixed;inset:0;background:rgba(0,0,0,.6);backdrop-filter:blur(8px);z-index:300;display:none;align-items:center;justify-content:center;padding:24px}
.modal-overlay.active{display:flex}
.modal{background:var(--bg2);border-radius:var(--radius);max-width:640px;width:100%;max-height:85vh;overflow-y:auto;border:1px solid var(--border)}
.modal-header{display:flex;align-items:center;justify-content:space-between;padding:24px;border-bottom:1px solid var(--border)}
.modal-header h3{font-size:20px;font-weight:700}
.modal-close{background:var(--surface);border:1px solid var(--border);border-radius:50%;width:36px;height:36px;display:flex;align-items:center;justify-content:center;cursor:pointer;font-size:18px;color:var(--text)}
.modal-body{padding:24px}
.modal-body img{width:100%;border-radius:12px;margin-bottom:16px}
.modal-info{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-bottom:16px}
.modal-info-item{font-size:13px}
.modal-info-item .label{color:var(--text-muted);margin-bottom:2px}
.modal-info-item .value{font-weight:600}
.modal-desc{font-size:14px;line-height:1.6;color:var(--text-muted);margin-bottom:20px}
.modal-actions{display:flex;gap:12px}
/* Toast */
.toast{position:fixed;top:80px;left:50%;transform:translateX(-50%) translateY(-20px);background:var(--bg2);border:1px solid var(--primary);border-radius:12px;padding:12px 24px;font-size:14px;font-weight:600;z-index:400;opacity:0;transition:all .3s;pointer-events:none}
.toast.show{opacity:1;transform:translateX(-50%) translateY(0)}
/* Cart drawer */
.cart-overlay{position:fixed;inset:0;background:rgba(0,0,0,.5);z-index:280;display:none}
.cart-overlay.active{display:block}
.cart-drawer{position:fixed;top:0;right:0;width:400px;max-width:90vw;height:100vh;background:var(--bg2);border-left:1px solid var(--border);z-index:290;transform:translateX(100%);transition:transform .3s;display:flex;flex-direction:column}
.cart-drawer.active{transform:translateX(0)}
.cart-drawer-header{padding:20px 24px;border-bottom:1px solid var(--border);display:flex;align-items:center;justify-content:space-between}
.cart-drawer-header h3{font-size:18px;font-weight:700}
.cart-items{flex:1;overflow-y:auto;padding:16px 24px}
.cart-item{display:flex;gap:12px;padding:12px 0;border-bottom:1px solid var(--border)}
.cart-item-img{width:50px;height:50px;border-radius:8px;overflow:hidden;background:var(--surface);display:flex;align-items:center;justify-content:center;font-size:20px;flex-shrink:0}
.cart-item-img img{width:100%;height:100%;object-fit:cover}
.cart-item-info{flex:1}
.cart-item-name{font-size:14px;font-weight:600;margin-bottom:2px}
.cart-item-price{font-size:13px;color:var(--primary);font-weight:700}
.cart-item-qty{display:flex;align-items:center;gap:8px;margin-top:4px}
.qty-btn{width:24px;height:24px;border-radius:6px;border:1px solid var(--border);background:var(--surface);cursor:pointer;color:var(--text);font-size:14px}
.cart-empty{text-align:center;padding:40px 0;color:var(--text-muted)}
.cart-drawer-footer{padding:20px 24px;border-top:1px solid var(--border)}
.cart-total{display:flex;justify-content:space-between;margin-bottom:16px;font-size:16px;font-weight:700}
.cart-total .price{color:var(--primary)}
.checkout-btn{width:100%;padding:14px;border-radius:12px;background:var(--primary);color:#fff;font-size:15px;font-weight:700;border:none;cursor:pointer;transition:opacity .2s}
.checkout-btn:hover{opacity:.85}
.checkout-btn:disabled{opacity:.4;cursor:not-allowed}
/* Responsive */
@media(max-width:768px){
.hero-panel h1{font-size:36px}
.hero-features{grid-template-columns:1fr}
.footer-content{grid-template-columns:1fr 1fr}
.nav-links{display:none}
.product-table{font-size:12px}
.product-table th,.product-table td{padding:10px 12px}
.td-img{width:40px;height:40px}
}
</style>
</head>
<body data-theme="dark">
<!-- 导航栏 -->
<nav class="navbar">
<div class="nav-brand"><span class="tree-icon">🌳</span> TreeShop</div>
<div class="nav-links">
<a onclick="scrollToProducts()" data-i18n="nav_all">全部商品</a>
<a onclick="scrollToProducts()" data-i18n="nav_cat">分类</a>
<a onclick="showToast(t('toast_about'))" data-i18n="nav_about">关于</a>
<a onclick="showToast(t('toast_contact'))" data-i18n="nav_contact">联系</a>
</div>
<div class="nav-actions">
<div class="lang-switcher" id="langSwitcher">
<button class="lang-btn" onclick="toggleLangDropdown()">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><path d="M2 12h20M12 2a15 15 0 0 1 0 20 15 15 0 0 1 0-20z"/></svg>
<span id="langLabel">中文</span>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="width:12px;height:12px"><path d="m6 9 6 6 6-6"/></svg>
</button>
<div class="lang-dropdown" id="langDropdown">
<div class="lang-option active" data-lang="zh-CN" onclick="switchLang('zh-CN')">
<svg class="check" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3"><polyline points="20 6 9 17 4 12"/></svg>
中文
</div>
<div class="lang-option" data-lang="zh-TW" onclick="switchLang('zh-TW')">
<svg class="check" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3"><polyline points="20 6 9 17 4 12"/></svg>
繁體中文
</div>
<div class="lang-option" data-lang="en" onclick="switchLang('en')">
<svg class="check" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3"><polyline points="20 6 9 17 4 12"/></svg>
English
</div>
</div>
</div>
<button class="theme-toggle" onclick="toggleTheme()" title="切换黑白模式">
<span class="sun-icon">☀️</span>
<span class="moon-icon">🌙</span>
</button>
<button class="cart-btn" onclick="toggleCart()">
🛒 <span class="cart-badge" id="cartBadge" style="display:none">0</span>
</button>
</div>
</nav>
<!-- Hero 横向动态 -->
<div class="hero">
<canvas id="treeCanvas"></canvas>
<div class="hero-overlay"></div>
<div class="hero-scroll-wrap" id="heroScroll">
<!-- 面板1 -->
<div class="hero-panel">
<div class="hero-panel-content">
<div class="hero-badge"><span class="dot"></span> <span data-i18n="hero_badge1">古树商城 · 2026 新季</span></div>
<h1><span data-i18n="hero_title1_line1">扎根全球</span><br><span class="accent" data-i18n="hero_title1_line2">枝连万物</span></h1>
<p data-i18n="hero_desc1">如古树般扎根品质,如枝叶般连接全球好物。精选电子工具品类,从榨汁机到搅拌机,每一件产品都经过严选,为您带来高效纯粹的厨房体验。</p>
<div class="hero-panel-actions">
<button class="btn-primary" onclick="scrollToProducts()">
<span data-i18n="hero_cta1">探索商品</span>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="width:18px;height:18px"><path d="M5 12h14M12 5l7 7-7 7"/></svg>
</button>
<button class="btn-ghost" onclick="scrollToPanel(1)"><span data-i18n="hero_more">了解更多</span> →</button>
</div>
</div>
</div>
<!-- 面板2 -->
<div class="hero-panel">
<div class="hero-panel-content">
<div class="hero-badge"><span class="dot"></span> <span data-i18n="hero_badge2">品质承诺</span></div>
<h1><span data-i18n="hero_title2_line1">四大根基</span><br><span class="accent" data-i18n="hero_title2_line2">品质如树</span></h1>
<div class="hero-features">
<div class="hero-feature"><div class="icon">🌍</div><h3 data-i18n="feat1_title">全球直邮</h3><p data-i18n="feat1_desc">满 $99 免运费,覆盖全球 200+ 国家和地区</p></div>
<div class="hero-feature"><div class="icon">✅</div><h3 data-i18n="feat2_title">正品保障</h3><p data-i18n="feat2_desc">品牌授权直供,假一赔十承诺</p></div>
<div class="hero-feature"><div class="icon">🔄</div><h3 data-i18n="feat3_title">7天退换</h3><p data-i18n="feat3_desc">无理由退货,购物零风险</p></div>
<div class="hero-feature"><div class="icon">🔒</div><h3 data-i18n="feat4_title">安全支付</h3><p data-i18n="feat4_desc">多渠道加密,保障支付安全</p></div>
</div>
<div class="hero-panel-actions" style="margin-top:32px">
<button class="btn-primary" onclick="scrollToProducts()"><span data-i18n="hero_browse">浏览商品</span></button>
<button class="btn-ghost" onclick="scrollToPanel(0)">← <span data-i18n="hero_back">返回</span></button>
</div>
</div>
</div>
<!-- 面板3 -->
<div class="hero-panel">
<div class="hero-panel-content" style="text-align:center">
<div class="hero-badge" style="margin:0 auto 24px"><span class="dot"></span> <span data-i18n="hero_badge3">数据一览</span></div>
<h1 style="text-align:center"><span data-i18n="hero_title3_line1">数字见证</span><br><span class="accent" data-i18n="hero_title3_line2">用户信赖</span></h1>
<div class="hero-features" style="grid-template-columns:repeat(4,1fr);margin-top:40px">
<div class="hero-feature" style="text-align:center"><div class="icon">📦</div><h3 style="font-size:28px;color:var(--primary)">18+</h3><p data-i18n="stat1">品类好物</p></div>
<div class="hero-feature" style="text-align:center"><div class="icon">👥</div><h3 style="font-size:28px;color:var(--primary)">50万</h3><p data-i18n="stat2">全球用户</p></div>
<div class="hero-feature" style="text-align:center"><div class="icon">⭐</div><h3 style="font-size:28px;color:var(--primary)">99%</h3><p data-i18n="stat3">好评率</p></div>
<div class="hero-feature" style="text-align:center"><div class="icon">🌿</div><h3 style="font-size:28px;color:var(--primary)">7天</h3><p data-i18n="stat4">无理由退换</p></div>
</div>
<div class="hero-panel-actions" style="margin-top:32px;justify-content:center">
<button class="btn-primary" onclick="scrollToProducts()"><span data-i18n="hero_buy">立即选购</span></button>
</div>
</div>
</div>
</div>
<div class="hero-dots" id="heroDots">
<div class="hero-dot active" onclick="scrollToPanel(0)"></div>
<div class="hero-dot" onclick="scrollToPanel(1)"></div>
<div class="hero-dot" onclick="scrollToPanel(2)"></div>
</div>
<div class="hero-arrow"><span data-i18n="hero_scroll">横向滚动</span> →</div>
</div>
<!-- 商品表格区域 -->
<div class="products-section" id="productsSection">
<div class="products-bg" id="productsBg"></div>
<div class="products-content">
<div class="section-header">
<h2><span data-i18n="section_title1">电子工具</span><span class="accent" data-i18n="section_title2">精选</span></h2>
<p data-i18n="section_desc">高效厨房好物,品质如树,扎根全球</p>
</div>
<div class="filter-bar" id="filterBar">
<button class="filter-chip active" data-cat="0" onclick="filterCategory(0,this)" data-i18n="cat_all">全部分类</button>
<button class="filter-chip" data-cat="1" onclick="filterCategory(1,this)" data-i18n="cat_juice">榨汁搅拌</button>
<button class="filter-chip" data-cat="2" onclick="filterCategory(2,this)" data-i18n="cat_cook">烹饪烘焙</button>
<button class="filter-chip" data-cat="3" onclick="filterCategory(3,this)" data-i18n="cat_life">生活电器</button>
<div class="search-box">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg>
<input type="text" id="searchInput" data-i18n-placeholder="search_placeholder" placeholder="搜索商品..." oninput="onSearch()">
</div>
</div>
<div class="table-wrap">
<table class="product-table">
<thead>
<tr>
<th data-i18n="th_img">图片</th>
<th data-i18n="th_name">商品名称</th>
<th data-i18n="th_cat">分类</th>
<th data-i18n="th_price">价格</th>
<th data-i18n="th_rating">评分</th>
<th data-i18n="th_sales">销量</th>
<th data-i18n="th_actions">操作</th>
</tr>
</thead>
<tbody id="productTbody"></tbody>
</table>
</div>
<div class="pagination" id="pagination"></div>
</div>
</div>
<!-- Footer -->
<footer class="footer">
<div class="footer-content">
<div class="footer-brand">
<h3>🌳 TreeShop</h3>
<p data-i18n="footer_desc">如古树般扎根品质,如枝叶般连接全球。精选电子工具好物,为您带来高效纯粹的跨境购物体验。</p>
</div>
<div class="footer-col">
<h4 data-i18n="footer_guide">购物指南</h4>
<a data-i18n="guide_flow">购物流程</a><a data-i18n="guide_member">会员介绍</a><a data-i18n="guide_faq">常见问题</a><a data-i18n="guide_service">联系客服</a>
</div>
<div class="footer-col">
<h4 data-i18n="footer_shipping">配送退换</h4>
<a data-i18n="ship_method">配送方式</a><a data-i18n="ship_fee">运费规则</a><a data-i18n="ship_return">退换货政策</a><a data-i18n="ship_refund">退款说明</a>
</div>
<div class="footer-col">
<h4 data-i18n="footer_about">关于我们</h4>
<a data-i18n="about_intro">公司简介</a><a data-i18n="about_join">加入我们</a><a data-i18n="about_privacy">隐私政策</a><a data-i18n="about_terms">用户协议</a>
</div>
</div>
<div class="footer-bottom">© 2026 TreeShop · <span data-i18n="footer_copy">古树商城 · 电子工具精选</span></div>
</footer>
<!-- Cart -->
<div class="cart-overlay" id="cartOverlay" onclick="toggleCart()"></div>
<div class="cart-drawer" id="cartDrawer">
<div class="cart-drawer-header">
<h3 data-i18n="cart_title">购物车</h3>
<button class="modal-close" onclick="toggleCart()">×</button>
</div>
<div class="cart-items" id="cartItems"></div>
<div class="cart-drawer-footer">
<div class="cart-total"><span data-i18n="cart_total">合计</span><span class="price" id="cartTotal">$0</span></div>
<button class="checkout-btn" id="checkoutBtn" disabled onclick="showToast(t('toast_checkout'))"><span data-i18n="cart_checkout">去结算</span></button>
</div>
</div>
<!-- Modal -->
<div class="modal-overlay" id="modalOverlay" onclick="if(event.target===this)closeModal()">
<div class="modal" id="modal"></div>
</div>
<!-- Toast -->
<div class="toast" id="toast"><span id="toastMsg"></span></div>
<script>
// ========== I18N ==========
var I18N_LOCALES = {
'zh-CN': {
nav_all: '全部商品', nav_cat: '分类', nav_about: '关于', nav_contact: '联系',
hero_badge1: '古树商城 · 2026 新季', hero_title1_line1: '扎根全球', hero_title1_line2: '枝连万物',
hero_desc1: '如古树般扎根品质,如枝叶般连接全球好物。精选电子工具品类,从榨汁机到搅拌机,每一件产品都经过严选,为您带来高效纯粹的厨房体验。',
hero_cta1: '探索商品', hero_more: '了解更多',
hero_badge2: '品质承诺', hero_title2_line1: '四大根基', hero_title2_line2: '品质如树',
feat1_title: '全球直邮', feat1_desc: '满 $99 免运费,覆盖全球 200+ 国家和地区',
feat2_title: '正品保障', feat2_desc: '品牌授权直供,假一赔十承诺',
feat3_title: '7天退换', feat3_desc: '无理由退货,购物零风险',
feat4_title: '安全支付', feat4_desc: '多渠道加密,保障支付安全',
hero_browse: '浏览商品', hero_back: '返回',
hero_badge3: '数据一览', hero_title3_line1: '数字见证', hero_title3_line2: '用户信赖',
stat1: '品类好物', stat2: '全球用户', stat3: '好评率', stat4: '无理由退换',
hero_buy: '立即选购', hero_scroll: '横向滚动',
section_title1: '电子工具', section_title2: '精选', section_desc: '高效厨房好物,品质如树,扎根全球',
cat_all: '全部分类', cat_juice: '榨汁搅拌', cat_cook: '烹饪烘焙', cat_life: '生活电器',
search_placeholder: '搜索商品...',
th_img: '图片', th_name: '商品名称', th_cat: '分类', th_price: '价格', th_rating: '评分', th_sales: '销量', th_actions: '操作',
btn_add_cart: '加购', btn_detail: '详情', btn_empty: '暂无商品',
footer_desc: '如古树般扎根品质,如枝叶般连接全球。精选电子工具好物,为您带来高效纯粹的跨境购物体验。',
footer_guide: '购物指南', guide_flow: '购物流程', guide_member: '会员介绍', guide_faq: '常见问题', guide_service: '联系客服',
footer_shipping: '配送退换', ship_method: '配送方式', ship_fee: '运费规则', ship_return: '退换货政策', ship_refund: '退款说明',
footer_about: '关于我们', about_intro: '公司简介', about_join: '加入我们', about_privacy: '隐私政策', about_terms: '用户协议',
footer_copy: '古树商城 · 电子工具精选',
cart_title: '购物车', cart_total: '合计', cart_checkout: '去结算',
cart_empty_line1: '购物车是空的', cart_empty_line2: '快去挑选心仪的商品吧',
modal_cat: '分类', modal_price: '价格', modal_rating: '评分', modal_sales: '销量', modal_unit: '件',
modal_add_cart: '加入购物车', modal_close: '关闭',
toast_theme_light: '已切换至明亮模式', toast_theme_dark: '已切换至暗黑模式',
toast_added: '已加入购物车', toast_about: '关于我们', toast_contact: '联系方式', toast_checkout: '结算功能开发中',
catName_juice: '榨汁搅拌', catName_cook: '烹饪烘焙', catName_life: '生活电器'
},
'en': {
nav_all: 'All Products', nav_cat: 'Categories', nav_about: 'About', nav_contact: 'Contact',
hero_badge1: 'TreeShop · 2026 New Season', hero_title1_line1: 'Rooted Globally', hero_title1_line2: 'Connected to All',
hero_desc1: 'Rooted in quality like an ancient tree, connected to global goods like its branches. Curated electronics from juicers to blenders — every product selected for a pure, efficient kitchen experience.',
hero_cta1: 'Explore Products', hero_more: 'Learn More',
hero_badge2: 'Quality Promise', hero_title2_line1: 'Four Pillars', hero_title2_line2: 'Quality Like a Tree',
feat1_title: 'Global Shipping', feat1_desc: 'Free shipping on orders over $99, covering 200+ countries',
feat2_title: 'Authentic Guarantee', feat2_desc: 'Authorized brand supply, 10x compensation promise',
feat3_title: '7-Day Returns', feat3_desc: 'No-reason returns, zero-risk shopping',
feat4_title: 'Secure Payment', feat4_desc: 'Multi-channel encryption for payment security',
hero_browse: 'Browse Products', hero_back: 'Back',
hero_badge3: 'Data Overview', hero_title3_line1: 'Numbers Speak', hero_title3_line2: 'User Trust',
stat1: 'Categories', stat2: 'Global Users', stat3: 'Satisfaction', stat4: 'Free Returns',
hero_buy: 'Shop Now', hero_scroll: 'Scroll Horizontally',
section_title1: 'Kitchen Electronics', section_title2: ' Selection', section_desc: 'Quality kitchen essentials, rooted like a tree, connected to the world',
cat_all: 'All Categories', cat_juice: 'Juicers & Blenders', cat_cook: 'Cooking & Baking', cat_life: 'Home Appliances',
search_placeholder: 'Search products...',
th_img: 'Image', th_name: 'Product Name', th_cat: 'Category', th_price: 'Price', th_rating: 'Rating', th_sales: 'Sales', th_actions: 'Actions',
btn_add_cart: 'Add', btn_detail: 'Details', btn_empty: 'No products found',
footer_desc: 'Rooted in quality like an ancient tree, connected to global goods. Curated electronics for an efficient, pure cross-border shopping experience.',
footer_guide: 'Shopping Guide', guide_flow: 'How to Buy', guide_member: 'Membership', guide_faq: 'FAQ', guide_service: 'Customer Service',
footer_shipping: 'Shipping & Returns', ship_method: 'Shipping Methods', ship_fee: 'Shipping Fees', ship_return: 'Return Policy', ship_refund: 'Refund Info',
footer_about: 'About Us', about_intro: 'Company Info', about_join: 'Join Us', about_privacy: 'Privacy Policy', about_terms: 'Terms of Use',
footer_copy: 'TreeShop · Curated Kitchen Electronics',
cart_title: 'Shopping Cart', cart_total: 'Total', cart_checkout: 'Checkout',
cart_empty_line1: 'Your cart is empty', cart_empty_line2: 'Find something you love!',
modal_cat: 'Category', modal_price: 'Price', modal_rating: 'Rating', modal_sales: 'Sales', modal_unit: 'pcs',
modal_add_cart: 'Add to Cart', modal_close: 'Close',
toast_theme_light: 'Switched to light mode', toast_theme_dark: 'Switched to dark mode',
toast_added: 'Added to cart', toast_about: 'About Us', toast_contact: 'Contact Us', toast_checkout: 'Checkout coming soon',
catName_juice: 'Juicers & Blenders', catName_cook: 'Cooking & Baking', catName_life: 'Home Appliances'
},
'zh-TW': {
nav_all: '全部商品', nav_cat: '分類', nav_about: '關於', nav_contact: '聯絡',
hero_badge1: '古樹商城 · 2026 新季', hero_title1_line1: '扎根全球', hero_title1_line2: '枝連萬物',
hero_desc1: '如古樹般扎根品質,如枝葉般連接全球好物。精選電子工具品類,從榨汁機到攪拌機,每一件產品都經過嚴選,為您帶來高效純粹的廚房體驗。',
hero_cta1: '探索商品', hero_more: '了解更多',
hero_badge2: '品質承諾', hero_title2_line1: '四大根基', hero_title2_line2: '品質如樹',
feat1_title: '全球直郵', feat1_desc: '滿 $99 免運費,覆蓋全球 200+ 國家和地區',
feat2_title: '正品保障', feat2_desc: '品牌授權直供,假一賠十承諾',
feat3_title: '7天退換', feat3_desc: '無理由退貨,購物零風險',
feat4_title: '安全支付', feat4_desc: '多渠道加密,保障支付安全',
hero_browse: '瀏覽商品', hero_back: '返回',
hero_badge3: '數據一覽', hero_title3_line1: '數字見證', hero_title3_line2: '用戶信賴',
stat1: '品類好物', stat2: '全球用戶', stat3: '好評率', stat4: '無理由退換',
hero_buy: '立即選購', hero_scroll: '橫向滾動',
section_title1: '電子工具', section_title2: '精選', section_desc: '高效廚房好物,品質如樹,扎根全球',
cat_all: '全部分類', cat_juice: '榨汁攪拌', cat_cook: '烹飪烘焙', cat_life: '生活電器',
search_placeholder: '搜尋商品...',
th_img: '圖片', th_name: '商品名稱', th_cat: '分類', th_price: '價格', th_rating: '評分', th_sales: '銷量', th_actions: '操作',
btn_add_cart: '加購', btn_detail: '詳情', btn_empty: '暫無商品',
footer_desc: '如古樹般扎根品質,如枝葉般連接全球。精選電子工具好物,為您帶來高效純粹的跨境購物體驗。',
footer_guide: '購物指南', guide_flow: '購物流程', guide_member: '會員介紹', guide_faq: '常見問題', guide_service: '聯絡客服',
footer_shipping: '配送退換', ship_method: '配送方式', ship_fee: '運費規則', ship_return: '退換貨政策', ship_refund: '退款說明',
footer_about: '關於我們', about_intro: '公司簡介', about_join: '加入我們', about_privacy: '隱私政策', about_terms: '用戶協議',
footer_copy: '古樹商城 · 電子工具精選',
cart_title: '購物車', cart_total: '合計', cart_checkout: '去結算',
cart_empty_line1: '購物車是空的', cart_empty_line2: '快去挑選心儀的商品吧',
modal_cat: '分類', modal_price: '價格', modal_rating: '評分', modal_sales: '銷量', modal_unit: '件',
modal_add_cart: '加入購物車', modal_close: '關閉',
toast_theme_light: '已切換至明亮模式', toast_theme_dark: '已切換至暗黑模式',
toast_added: '已加入購物車', toast_about: '關於我們', toast_contact: '聯絡方式', toast_checkout: '結算功能開發中',
catName_juice: '榨汁攪拌', catName_cook: '烹飪烘焙', catName_life: '生活電器'
}
};
var LANG_LABELS = {'zh-CN':'中文','en':'EN','zh-TW':'繁中'};
var currentLang = (function(){
try{
var u=new URLSearchParams(location.search).get('lang');
if(u&&I18N_LOCALES[u]) return u;
}catch(e){}
try{var s=localStorage.getItem('lang');if(s&&I18N_LOCALES[s]) return s;}catch(e){}
var b=navigator.language||navigator.userLanguage||'';
if(b.startsWith('zh-TW')||b.startsWith('zh-Hant')) return 'zh-TW';
if(b.startsWith('zh')) return 'en';
return 'en';
})();
function t(key){return (I18N_LOCALES[currentLang]&&I18N_LOCALES[currentLang][key])||(I18N_LOCALES['zh-CN'][key])||key;}
function applyI18n(){
document.querySelectorAll('[data-i18n]').forEach(function(el){
var key=el.getAttribute('data-i18n');
el.textContent=t(key);
});
document.querySelectorAll('[data-i18n-placeholder]').forEach(function(el){
var key=el.getAttribute('data-i18n-placeholder');
el.placeholder=t(key);
});
document.documentElement.lang=currentLang==='zh-TW'?'zh-TW':currentLang==='zh-CN'?'zh-CN':'en';
document.getElementById('langLabel').textContent=LANG_LABELS[currentLang]||currentLang;
document.querySelectorAll('.lang-option').forEach(function(opt){
opt.classList.toggle('active',opt.getAttribute('data-lang')===currentLang);
});
document.title = t('section_title1') + t('section_title2') + ' · TreeShop';
}
function switchLang(lang){
if(!I18N_LOCALES[lang]) return;
currentLang=lang;
try{localStorage.setItem('lang',lang);}catch(e){}
applyI18n();
if(typeof onLangChange==='function') onLangChange(lang);
document.getElementById('langDropdown').classList.remove('open');
}
function toggleLangDropdown(){
document.getElementById('langDropdown').classList.toggle('open');
}
document.addEventListener('click',function(e){
var sw=document.getElementById('langSwitcher');
if(sw&&!sw.contains(e.target)) document.getElementById('langDropdown').classList.remove('open');
});
// ========== 全局状态 ==========
var currentPage = 1, pageSize = 10, totalPages = 1, currentCat = 0, searchKey = '';
var cart = [];
// ========== 电子工具商品数据 ==========
var allProducts = [
{ id:1, name:'冷压慢速榨汁机 Pro Max', cat:1, catName:'榨汁搅拌', price:189.99, rating:4.9, sales:12800, icon:'🥤', desc:'采用冷压慢速技术,保留90%以上营养。75mm大口径整果压榨,无需切块。陶瓷螺旋杆,果汁更细腻。' },
{ id:2, name:'多功能破壁料理机 1200W', cat:1, catName:'榨汁搅拌', price:159.99, rating:4.8, sales:9600, icon:'🌀', desc:'8叶精钢刀片,38000转/分钟高速破壁。冷热双杯配置,一机多用,支持豆浆、浓汤、冰沙。' },
{ id:3, name:'便携式电动榨汁杯 USB充电', cat:1, catName:'榨汁搅拌', price:39.99, rating:4.6, sales:35000, icon:'🔋', desc:'口袋便携设计,USB充电续航30次。6叶刀头强力搅拌,30秒出汁,Tritan材质安全无忧。' },
{ id:4, name:'手持搅拌棒 700W 免拆洗', cat:1, catName:'榨汁搅拌', price:69.99, rating:4.7, sales:21000, icon:'✋', desc:'700W大功率,一键拆卸。不锈钢刀头防锈耐用,配备打蛋器和量杯配件。' },
{ id:5, name:'空气炸锅 5.5L 无油低脂', cat:2, catName:'烹饪烘焙', price:119.99, rating:4.8, sales:18500, icon:'🍟', desc:'360°热风循环,无需翻面。5.5L大容量满足全家需求。8大预设菜单,触控操作一键烹饪。' },
{ id:6, name:'智能电烤箱 32L 风炉发酵', cat:2, catName:'烹饪烘焙', price:229.99, rating:4.7, sales:7800, icon:'🔥', desc:'上下管独立控温,风炉均匀烘烤。内置发酵功能,360°旋转烤叉。搪瓷内胆易清洁。' },
{ id:7, name:'全自动咖啡机 15Bar 浓缩', cat:2, catName:'烹饪烘焙', price:299.99, rating:4.9, sales:5600, icon:'☕', desc:'15Bar压力萃取,奶泡一体。PID温控精准±1°C。豆粉双用,支持自定义杯量和浓度。' },
{ id:8, name:'多功能厨师机 1000W 和面', cat:2, catName:'烹饪烘焙', price:259.99, rating:4.8, sales:6200, icon:'👨‍🍳', desc:'1000W大功率直流电机,10级调速。行星搅拌轨迹,配搅拌/打蛋/和面三配件。5.5L不锈钢盆。' },
{ id:9, name:'智能电饭煲 4L IH电磁加热', cat:3, catName:'生活电器', price:179.99, rating:4.9, sales:24000, icon:'🍚', desc:'IH电磁环绕加热,米饭粒粒分明。12大烹饪菜单,支持柴火饭、煲仔饭、蛋糕。APP远程控制。' },
{ id:10, name:'桌面冷风扇 遥控加湿', cat:3, catName:'生活电器', price:89.99, rating:4.5, sales:15000, icon:'❄️', desc:'三档风速,冰晶制冷快速降温。内置加湿功能,7L大水箱。远程遥控,定时12小时。' },
{ id:11, name:'破壁豆浆机 加热免滤', cat:1, catName:'榨汁搅拌', price:149.99, rating:4.7, sales:13000, icon:'🫘', desc:'加热免滤一体,干豆直接打。8叶刀头高速破壁,医用级304不锈钢内胆。防溢防糊双重保护。' },
{ id:12, name:'真空封口机 干湿两用', cat:3, catName:'生活电器', price:49.99, rating:4.6, sales:8900, icon:'📦', desc:'干湿双模式抽真空,保鲜延长5倍。一键操作,支持连续封口。附送10个真空袋。' }
];
// ========== 工具函数 ==========
function showToast(msg) {
var el = document.getElementById('toast');
document.getElementById('toastMsg').textContent = msg;
el.classList.add('show');
clearTimeout(window._tt);
window._tt = setTimeout(function(){ el.classList.remove('show'); }, 2500);
}
function fmtPrice(p) { return '$' + Number(p).toFixed(2); }
function starsHTML(r) {
var s = '';
for (var i = 0; i < 5; i++) s += i < Math.round(r) ? '<span class="star">★</span>' : '<span style="color:var(--text-muted)">★</span>';
return s;
}
function productImgHTML(p) {
return '<div class="placeholder">' + (p.icon || '🔌') + '</div>';
}
// ========== 黑白模式切换 ==========
function toggleTheme() {
var body = document.body;
var current = body.getAttribute('data-theme');
body.setAttribute('data-theme', current === 'dark' ? 'light' : 'dark');
showToast(current === 'dark' ? t('toast_theme_light') : t('toast_theme_dark'));
}
// ========== Hero 横向滚动 ==========
function scrollToPanel(idx) {
document.getElementById('heroScroll').scrollTo({ left: idx * window.innerWidth, behavior: 'smooth' });
}
document.getElementById('heroScroll').addEventListener('scroll', function() {
var idx = Math.round(this.scrollLeft / window.innerWidth);
document.querySelectorAll('.hero-dot').forEach(function(d, i) { d.classList.toggle('active', i === idx); });
});
function scrollToProducts() {
document.getElementById('productsSection').scrollIntoView({ behavior: 'smooth' });
}
// ========== 商品加载(本地数据)==========
function getFilteredProducts() {
var list = allProducts;
if (currentCat > 0) list = list.filter(function(p){ return p.cat === currentCat; });
if (searchKey) {
var k = searchKey.toLowerCase();
list = list.filter(function(p){ return p.name.toLowerCase().indexOf(k) >= 0 || p.catName.indexOf(searchKey) >= 0; });
}
return list;
}
function loadProducts() {
var all = getFilteredProducts();
totalPages = Math.ceil(all.length / pageSize);
if (currentPage > totalPages) currentPage = 1;
var start = (currentPage - 1) * pageSize;
var list = all.slice(start, start + pageSize);
renderTable(list);
renderPagination();
}
function renderTable(list) {
var tbody = document.getElementById('productTbody');
if (!list.length) {
tbody.innerHTML = '<tr><td colspan="7" style="text-align:center;padding:48px;color:var(--text-muted)">' + t('btn_empty') + '</td></tr>';
return;
}
tbody.innerHTML = list.map(function(p) {
return '<tr onclick="showDetail(' + p.id + ')">' +
'<td><div class="td-img">' + productImgHTML(p) + '</div></td>' +
'<td class="td-name">' + p.name + '</td>' +
'<td class="td-category">' + p.catName + '</td>' +
'<td class="td-price">' + fmtPrice(p.price) + '</td>' +
'<td><div class="td-rating">' + starsHTML(p.rating) + ' <span style="font-size:12px;color:var(--text-muted)">' + p.rating.toFixed(1) + '</span></div></td>' +
'<td style="color:var(--text-muted)">' + p.sales.toLocaleString() + '</td>' +
'<td><div class="td-actions" onclick="event.stopPropagation()">' +
'<button class="td-btn td-btn-primary" onclick="addToCart(' + p.id + ')">' + t('btn_add_cart') + '</button>' +
'<button class="td-btn td-btn-ghost" onclick="showDetail(' + p.id + ')">' + t('btn_detail') + '</button>' +
'</div></td>' +
'</tr>';
}).join('');
}
function renderPagination() {
var pag = document.getElementById('pagination');
var html = '<button class="page-btn" ' + (currentPage <= 1 ? 'disabled' : '') + ' onclick="goPage(' + (currentPage - 1) + ')">‹</button>';
for (var i = 1; i <= totalPages; i++) {
html += '<button class="page-btn ' + (i === currentPage ? 'active' : '') + '" onclick="goPage(' + i + ')">' + i + '</button>';
}
html += '<button class="page-btn" ' + (currentPage >= totalPages ? 'disabled' : '') + ' onclick="goPage(' + (currentPage + 1) + ')">›</button>';
pag.innerHTML = html;
}
function goPage(p) { currentPage = p; loadProducts(); }
function filterCategory(cat, el) {
currentCat = cat; currentPage = 1;
document.querySelectorAll('.filter-chip').forEach(function(c){ c.classList.remove('active'); });
el.classList.add('active');
loadProducts();
}
function onSearch() {
clearTimeout(window._st);
window._st = setTimeout(function() {
searchKey = document.getElementById('searchInput').value;
currentPage = 1;
loadProducts();
}, 380);
}
function showDetail(id) {
var p = allProducts.find(function(x){ return x.id === id; });
if (!p) return;
var modal = document.getElementById('modal');
modal.innerHTML =
'<div class="modal-header"><h3>' + p.name + '</h3><button class="modal-close" onclick="closeModal()">×</button></div>' +
'<div class="modal-body">' +
'<div style="width:100%;height:200px;border-radius:12px;margin-bottom:16px;display:flex;align-items:center;justify-content:center;font-size:72px;background:var(--surface)">' + (p.icon || '🔌') + '</div>' +
'<div class="modal-info">' +
'<div class="modal-info-item"><div class="label">' + t('modal_cat') + '</div><div class="value">' + p.catName + '</div></div>' +
'<div class="modal-info-item"><div class="label">' + t('modal_price') + '</div><div class="value" style="color:var(--primary);font-size:18px">' + fmtPrice(p.price) + '</div></div>' +
'<div class="modal-info-item"><div class="label">' + t('modal_rating') + '</div><div class="value">' + starsHTML(p.rating) + ' ' + p.rating.toFixed(1) + '</div></div>' +
'<div class="modal-info-item"><div class="label">' + t('modal_sales') + '</div><div class="value">' + p.sales.toLocaleString() + ' ' + t('modal_unit') + '</div></div>' +
'</div>' +
'<div class="modal-desc">' + p.desc + '</div>' +
'<div class="modal-actions">' +
'<button class="btn-primary" style="flex:1" onclick="addToCart(' + p.id + ');closeModal()">' + t('modal_add_cart') + '</button>' +
'<button class="btn-ghost" onclick="closeModal()">' + t('modal_close') + '</button>' +
'</div>' +
'</div>';
document.getElementById('modalOverlay').classList.add('active');
}
function closeModal() { document.getElementById('modalOverlay').classList.remove('active'); }
// ========== 购物车 ==========
function addToCart(id) {
var p = allProducts.find(function(x){ return x.id === id; });
if (!p) return;
var existing = cart.find(function(c){ return c.id === id; });
if (existing) { existing.qty++; } else { cart.push({ id: id, name: p.name, price: p.price, icon: p.icon, qty: 1 }); }
updateCartUI();
showToast(t('toast_added') + ': ' + p.name);
}
function updateCartUI() {
var badge = document.getElementById('cartBadge');
var totalQty = cart.reduce(function(s, c){ return s + c.qty; }, 0);
badge.textContent = totalQty;
badge.style.display = totalQty > 0 ? 'flex' : 'none';
var items = document.getElementById('cartItems');
if (!cart.length) {
items.innerHTML = '<div class="cart-empty">' + t('cart_empty_line1') + '<br>' + t('cart_empty_line2') + '</div>';
} else {
items.innerHTML = cart.map(function(c) {
return '<div class="cart-item">' +
'<div class="cart-item-img">' + (c.icon || '🔌') + '</div>' +
'<div class="cart-item-info">' +
'<div class="cart-item-name">' + c.name + '</div>' +
'<div class="cart-item-price">' + fmtPrice(c.price) + '</div>' +
'<div class="cart-item-qty">' +
'<button class="qty-btn" onclick="changeQty(' + c.id + ',-1)">−</button>' +
'<span>' + c.qty + '</span>' +
'<button class="qty-btn" onclick="changeQty(' + c.id + ',1)">+</button>' +
'</div>' +
'</div>' +
'</div>';
}).join('');
}
var total = cart.reduce(function(s, c){ return s + c.price * c.qty; }, 0);
document.getElementById('cartTotal').textContent = fmtPrice(total);
document.getElementById('checkoutBtn').disabled = cart.length === 0;
}
function changeQty(id, delta) {
var item = cart.find(function(c){ return c.id === id; });
if (!item) return;
item.qty += delta;
if (item.qty <= 0) cart = cart.filter(function(c){ return c.id !== id; });
updateCartUI();
}
function toggleCart() {
document.getElementById('cartOverlay').classList.toggle('active');
document.getElementById('cartDrawer').classList.toggle('active');
}
// ========== AAA级古树 Canvas 壁画 + 光追生命力 ==========
(function() {
var canvas = document.getElementById('treeCanvas');
var ctx = canvas.getContext('2d');
var W = 0, H = 0, dpr = window.devicePixelRatio || 1;
var mx = 0, my = 0, hasMouse = false;
var branches = [];
var leafClusters = [];
var fireflies = [];
var energyPulses = [];
var spores = [];
var godRays = [];
function resize() {
var rect = canvas.getBoundingClientRect();
W = rect.width; H = rect.height;
canvas.width = W * dpr; canvas.height = H * dpr;
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
mx = W / 2; my = H / 2;
buildTree();
initAtmosphere();
}
function buildTree() {
branches = [];
leafClusters = [];
fireflies = [];
energyPulses = [];
var trunkX = W * 0.5;
var trunkY = H * 0.92;
var trunkH = H * 0.32;
function branch(x, y, angle, length, depth, width, parentIdx) {
if (depth <= 0 || length < 6) {
var clusterSize = 4 + Math.floor(Math.random() * 4);
for (var i = 0; i < clusterSize; i++) {
var lx = x + (Math.random() - 0.5) * 40;
var ly = y + (Math.random() - 0.5) * 35;
var leaves = 3 + Math.floor(Math.random() * 4);
for (var j = 0; j < leaves; j++) {
leafClusters.push({
x: lx + (Math.random() - 0.5) * 18,
y: ly + (Math.random() - 0.5) * 18,
size: 2 + Math.random() * 5,
hue: 95 + Math.random() * 55,
sat: 45 + Math.random() * 25,
lit: 35 + Math.random() * 20,
alpha: 0.35 + Math.random() * 0.3,
sway: Math.random() * Math.PI * 2,
swaySpeed: 0.5 + Math.random() * 0.5
});
}
}
return;
}
var ex = x + Math.cos(angle) * length;
var ey = y + Math.sin(angle) * length;
var branchIdx = branches.length;
branches.push({
x1: x, y1: y, x2: ex, y2: ey,
width: width, depth: depth,
parentIdx: parentIdx,
sway: Math.random() * Math.PI * 2,
swayAmount: (8 - depth) * 0.5,
baseAngle: angle
});
var fireflyCount = depth > 4 ? 2 : 1;
for (var f = 0; f < fireflyCount; f++) {
fireflies.push({
x: x, y: y, baseX: x, baseY: y,
tx: ex, ty: ey,
branchIdx: branchIdx,
progress: Math.random(),
speed: 0.0015 + Math.random() * 0.003,
size: 1 + Math.random() * 2,
hue: 110 + Math.random() * 50,
offset: Math.random() * Math.PI * 2
});
}
if (depth >= 3 && Math.random() < 0.4) {
energyPulses.push({
branchIdx: branchIdx,
progress: Math.random(),
speed: 0.005 + Math.random() * 0.008,
size: 2 + Math.random() * 2,
life: 1
});
}
var nChildren = depth > 5 ? 2 : (Math.random() < 0.35 ? 3 : 2);
for (var i = 0; i < nChildren; i++) {
var spread = 0.3 + Math.random() * 0.25;
var newAngle = angle + (i / (nChildren - 1) - 0.5) * spread * 2 + (Math.random() - 0.5) * 0.12;
var newLen = length * (0.68 + Math.random() * 0.12);
branch(ex, ey, newAngle, newLen, depth - 1, width * 0.72, branchIdx);
}
}
branch(trunkX, trunkY, -Math.PI / 2, trunkH, 8, 16, -1);
for (var r = 0; r < 6; r++) {
var rAngle = -Math.PI / 2 + (r - 2.5) * 0.25;
var rLen = trunkH * 0.3;
branches.push({
x1: trunkX, y1: trunkY,
x2: trunkX + Math.cos(rAngle) * rLen,
y2: trunkY + Math.sin(rAngle) * rLen * 0.2,
width: 7, depth: 0, isRoot: true,
sway: 0, swayAmount: 0, baseAngle: rAngle
});
}
}
function initAtmosphere() {
spores = [];
for (var i = 0; i < 40; i++) {
spores.push({
x: Math.random() * W,
y: Math.random() * H,
vx: (Math.random() - 0.5) * 0.3,
vy: -0.1 - Math.random() * 0.3,
size: 0.5 + Math.random() * 1.5,
alpha: 0.1 + Math.random() * 0.3,
hue: 90 + Math.random() * 40
});
}
godRays = [];
for (var i = 0; i < 5; i++) {
godRays.push({
x: W * (0.2 + i * 0.15),
angle: -Math.PI / 2 + (Math.random() - 0.5) * 0.3,
width: 80 + Math.random() * 60,
opacity: 0.04 + Math.random() * 0.04
});
}
}
canvas.parentElement.addEventListener('mousemove', function(e) {
var rect = canvas.getBoundingClientRect();
mx = e.clientX - rect.left;
my = e.clientY - rect.top;
hasMouse = true;
});
canvas.parentElement.addEventListener('mouseleave', function() { hasMouse = false; });
function drawTree() {
var isDark = document.body.getAttribute('data-theme') === 'dark';
var time = Date.now() * 0.001;
var skyGrad = ctx.createLinearGradient(0, 0, 0, H);
if (isDark) {
skyGrad.addColorStop(0, '#040806');
skyGrad.addColorStop(0.3, '#080f0a');
skyGrad.addColorStop(0.6, '#0a120a');
skyGrad.addColorStop(1, '#060a06');
} else {
skyGrad.addColorStop(0, '#e8e4d8');
skyGrad.addColorStop(0.3, '#f0ede2');
skyGrad.addColorStop(0.6, '#f5f3ec');
skyGrad.addColorStop(1, '#efece2');
}
ctx.fillStyle = skyGrad;
ctx.fillRect(0, 0, W, H);
if (isDark) {
godRays.forEach(function(gr) {
var len = H * 0.9;
var ex = gr.x + Math.cos(gr.angle) * len;
var ey = Math.sin(gr.angle) * len;
var rg = ctx.createLinearGradient(gr.x, 0, ex, ey);
rg.addColorStop(0, 'rgba(180,220,140,' + gr.opacity + ')');
rg.addColorStop(0.5, 'rgba(150,200,120,' + (gr.opacity * 0.5) + ')');
rg.addColorStop(1, 'transparent');
ctx.fillStyle = rg;
ctx.beginPath();
ctx.moveTo(gr.x - gr.width / 2, 0);
ctx.lineTo(gr.x + gr.width / 2, 0);
ctx.lineTo(ex + gr.width, ey);
ctx.lineTo(ex - gr.width, ey);
ctx.closePath();
ctx.fill();
});
}
var fogGrad = ctx.createLinearGradient(0, H * 0.6, 0, H);
if (isDark) {
fogGrad.addColorStop(0, 'transparent');
fogGrad.addColorStop(1, 'rgba(20,35,18,0.5)');
} else {
fogGrad.addColorStop(0, 'transparent');
fogGrad.addColorStop(1, 'rgba(180,175,155,0.3)');
}
ctx.fillStyle = fogGrad;
ctx.fillRect(0, H * 0.6, W, H * 0.4);
branches.forEach(function(b) {
var swayX = 0, swayY = 0;
if (!b.isRoot && b.swayAmount > 0) {
swayX = Math.sin(time * 0.8 + b.sway) * b.swayAmount;
swayY = Math.cos(time * 0.6 + b.sway) * b.swayAmount * 0.3;
}
b._sx2 = b.x2 + swayX;
b._sy2 = b.y2 + swayY;
var midX = (b.x1 + b._sx2) / 2;
var midY = (b.y1 + b._sy2) / 2;
var dx = mx - midX, dy = my - midY;
var dist = Math.sqrt(dx * dx + dy * dy);
var lightBoost = hasMouse && dist < 180 ? (1 - dist / 180) : 0;
ctx.beginPath();
ctx.moveTo(b.x1, b.y1);
ctx.lineTo(b._sx2, b._sy2);
var baseColor, r, g, bl;
if (b.isRoot) {
r = isDark ? 60 + lightBoost * 40 : 90;
g = isDark ? 45 + lightBoost * 30 : 70;
bl = isDark ? 30 + lightBoost * 20 : 45;
} else {
var depthFactor = b.depth / 8;
r = (isDark ? 80 : 110) + lightBoost * 50 + depthFactor * 20;
g = (isDark ? 65 : 90) + lightBoost * 35 + depthFactor * 15;
bl = (isDark ? 45 : 60) + lightBoost * 20;
}
ctx.strokeStyle = 'rgba(' + Math.round(r) + ',' + Math.round(g) + ',' + Math.round(bl) + ',' + (0.65 + lightBoost * 0.25) + ')';
ctx.lineWidth = b.width;
ctx.lineCap = 'round';
ctx.stroke();
if (b.depth >= 6 && !b.isRoot) {
ctx.beginPath();
ctx.moveTo(b.x1 - b.width * 0.2, b.y1);
ctx.lineTo(b._sx2 - b.width * 0.2, b._sy2);
ctx.strokeStyle = 'rgba(' + Math.round(r + 30) + ',' + Math.round(g + 25) + ',' + Math.round(bl + 15) + ',0.3)';
ctx.lineWidth = b.width * 0.3;
ctx.stroke();
}
});
leafClusters.forEach(function(l) {
var sway = Math.sin(time * l.swaySpeed + l.sway) * 3;
var x = l.x + sway;
var y = l.y + Math.cos(time * 0.7 + l.sway) * 2;
var dx = mx - x, dy = my - y;
var dist = Math.sqrt(dx * dx + dy * dy);
var glow = hasMouse && dist < 160 ? (1 - dist / 160) : 0;
var lit = l.lit + glow * 25;
var alpha = l.alpha + glow * 0.4;
ctx.beginPath();
ctx.arc(x, y, l.size, 0, Math.PI * 2);
ctx.fillStyle = 'hsla(' + l.hue + ',' + l.sat + '%,' + lit + '%,' + alpha + ')';
ctx.fill();
if (glow > 0.2) {
ctx.beginPath();
ctx.arc(x, y, l.size * 2.5, 0, Math.PI * 2);
var lg = ctx.createRadialGradient(x, y, 0, x, y, l.size * 2.5);
lg.addColorStop(0, 'hsla(' + l.hue + ',70%,55%,' + (glow * 0.35) + ')');
lg.addColorStop(1, 'transparent');
ctx.fillStyle = lg;
ctx.fill();
}
});
energyPulses.forEach(function(ep) {
var b = branches[ep.branchIdx];
if (!b || !b._sx2) return;
ep.progress += ep.speed;
if (ep.progress > 1) { ep.progress = 0; ep.life = 1; }
var px = b.x1 + (b._sx2 - b.x1) * ep.progress;
var py = b.y1 + (b._sy2 - b.y1) * ep.progress;
var dx = mx - px, dy = my - py;
var dist = Math.sqrt(dx * dx + dy * dy);
var boost = hasMouse && dist < 250 ? (1 - dist / 250) : 0;
var brightness = 0.5 + boost * 0.5;
ctx.beginPath();
ctx.arc(px, py, ep.size * (1 + boost), 0, Math.PI * 2);
ctx.fillStyle = 'rgba(150,255,120,' + brightness + ')';
ctx.fill();
ctx.beginPath();
ctx.arc(px, py, ep.size * 4, 0, Math.PI * 2);
var pg = ctx.createRadialGradient(px, py, 0, px, py, ep.size * 4);
pg.addColorStop(0, 'rgba(120,255,100,' + (brightness * 0.4) + ')');
pg.addColorStop(1, 'transparent');
ctx.fillStyle = pg;
ctx.fill();
});
fireflies.forEach(function(f) {
f.progress += f.speed;
if (f.progress > 1) f.progress = 0;
var b = branches[f.branchIdx];
if (!b || !b._sx2) return;
var px = b.x1 + (b._sx2 - b.x1) * f.progress;
var py = b.y1 + (b._sy2 - b.y1) * f.progress;
px += Math.sin(time * 2 + f.offset) * 3;
py += Math.cos(time * 1.5 + f.offset) * 2;
var dx = mx - px, dy = my - py;
var dist = Math.sqrt(dx * dx + dy * dy);
var activate = hasMouse && dist < 220 ? (1 - dist / 220) : 0;
var brightness = 0.35 + activate * 0.65;
var size = f.size * (1 + activate * 1.8);
var hue = activate > 0.3 ? 50 + activate * 30 : f.hue;
ctx.beginPath();
ctx.arc(px, py, size, 0, Math.PI * 2);
ctx.fillStyle = 'hsla(' + hue + ',95%,' + (55 + activate * 20) + '%,' + brightness + ')';
ctx.fill();
ctx.beginPath();
ctx.arc(px, py, size * 5, 0, Math.PI * 2);
var gl = ctx.createRadialGradient(px, py, 0, px, py, size * 5);
gl.addColorStop(0, 'hsla(' + hue + ',90%,60%,' + (brightness * 0.35) + ')');
gl.addColorStop(1, 'transparent');
ctx.fillStyle = gl;
ctx.fill();
if (activate > 0.15) {
ctx.beginPath();
ctx.moveTo(px, py);
ctx.lineTo(mx, my);
var lg = ctx.createLinearGradient(px, py, mx, my);
lg.addColorStop(0, 'hsla(' + hue + ',80%,60%,' + (activate * 0.3) + ')');
lg.addColorStop(1, 'hsla(' + hue + ',80%,70%,' + (activate * 0.05) + ')');
ctx.strokeStyle = lg;
ctx.lineWidth = 1;
ctx.stroke();
}
});
spores.forEach(function(s) {
s.x += s.vx;
s.y += s.vy;
if (s.y < -10) { s.y = H + 10; s.x = Math.random() * W; }
if (s.x < -10) s.x = W + 10;
if (s.x > W + 10) s.x = -10;
var dx = mx - s.x, dy = my - s.y;
var dist = Math.sqrt(dx * dx + dy * dy);
var boost = hasMouse && dist < 150 ? (1 - dist / 150) : 0;
ctx.beginPath();
ctx.arc(s.x, s.y, s.size * (1 + boost), 0, Math.PI * 2);
ctx.fillStyle = 'hsla(' + s.hue + ',60%,70%,' + (s.alpha + boost * 0.3) + ')';
ctx.fill();
});
if (hasMouse) {
var outerGlow = ctx.createRadialGradient(mx, my, 0, mx, my, 180);
outerGlow.addColorStop(0, 'rgba(140,255,110,0.12)');
outerGlow.addColorStop(0.4, 'rgba(120,220,90,0.05)');
outerGlow.addColorStop(1, 'transparent');
ctx.fillStyle = outerGlow;
ctx.beginPath();
ctx.arc(mx, my, 180, 0, Math.PI * 2);
ctx.fill();
ctx.beginPath();
ctx.arc(mx, my, 60, 0, Math.PI * 2);
var midGlow = ctx.createRadialGradient(mx, my, 0, mx, my, 60);
midGlow.addColorStop(0, 'rgba(160,255,120,0.25)');
midGlow.addColorStop(1, 'transparent');
ctx.fillStyle = midGlow;
ctx.fill();
for (var k = 0; k < 8; k++) {
var angle = (k / 8) * Math.PI * 2 + time * 0.25;
var len = 80 + Math.sin(time * 2 + k) * 20;
var ex = mx + Math.cos(angle) * len;
var ey = my + Math.sin(angle) * len;
var rg = ctx.createLinearGradient(mx, my, ex, ey);
rg.addColorStop(0, 'rgba(140,255,100,0.15)');
rg.addColorStop(1, 'transparent');
ctx.beginPath();
ctx.moveTo(mx, my);
ctx.lineTo(ex, ey);
ctx.strokeStyle = rg;
ctx.lineWidth = 2;
ctx.stroke();
}
ctx.beginPath();
ctx.arc(mx, my, 4, 0, Math.PI * 2);
ctx.fillStyle = 'rgba(200,255,170,0.95)';
ctx.fill();
ctx.beginPath();
ctx.arc(mx, my, 8, 0, Math.PI * 2);
ctx.fillStyle = 'rgba(160,255,130,0.4)';
ctx.fill();
}
requestAnimationFrame(drawTree);
}
resize();
window.addEventListener('resize', resize);
drawTree();
})();
// ========== 商品区域背景 — 模糊古树 ==========
(function() {
var bg = document.getElementById('productsBg');
var canvas = document.createElement('canvas');
bg.appendChild(canvas);
var ctx = canvas.getContext('2d');
var W = 0, H = 0;
function resize() {
W = bg.offsetWidth; H = bg.offsetHeight;
canvas.width = W; canvas.height = H;
draw();
}
function draw() {
var isDark = document.body.getAttribute('data-theme') === 'dark';
ctx.clearRect(0, 0, W, H);
var trunkX = W * 0.5, trunkY = H * 0.98;
var trunkH = H * 0.45;
var bgGrad = ctx.createRadialGradient(W * 0.5, H * 0.6, 0, W * 0.5, H * 0.6, W * 0.7);
if (isDark) {
bgGrad.addColorStop(0, 'rgba(15,25,15,0.15)');
bgGrad.addColorStop(1, 'rgba(8,12,8,0.1)');
} else {
bgGrad.addColorStop(0, 'rgba(200,195,175,0.12)');
bgGrad.addColorStop(1, 'rgba(180,175,155,0.08)');
}
ctx.fillStyle = bgGrad;
ctx.fillRect(0, 0, W, H);
function branch(x, y, angle, length, depth, width) {
if (depth <= 0 || length < 5) {
for (var i = 0; i < 5; i++) {
ctx.beginPath();
ctx.arc(x + (Math.random() - 0.5) * 30, y + (Math.random() - 0.5) * 25, 3 + Math.random() * 4, 0, Math.PI * 2);
ctx.fillStyle = isDark ? 'rgba(80,130,60,0.12)' : 'rgba(100,140,70,0.08)';
ctx.fill();
}
return;
}
var ex = x + Math.cos(angle) * length;
var ey = y + Math.sin(angle) * length;
ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineTo(ex, ey);
ctx.strokeStyle = isDark ? 'rgba(90,70,50,0.2)' : 'rgba(100,85,60,0.12)';
ctx.lineWidth = width;
ctx.lineCap = 'round';
ctx.stroke();
var n = 2;
for (var i = 0; i < n; i++) {
var a2 = angle + (i - 0.5) * 0.4 + (Math.random() - 0.5) * 0.1;
branch(ex, ey, a2, length * 0.7, depth - 1, width * 0.7);
}
}
branch(trunkX, trunkY, -Math.PI / 2, trunkH, 7, 14);
if (canvas.width > 0 && canvas.height > 0) {
ctx.filter = 'blur(4px)';
ctx.globalAlpha = 0.6;
ctx.drawImage(canvas, 0, 0);
ctx.filter = 'none';
ctx.globalAlpha = 1;
}
}
resize();
window.addEventListener('resize', resize);
document.body.addEventListener('click', function() { setTimeout(resize, 100); }, true);
})();
// ========== onLangChange ==========
function onLangChange(lang) {
loadProducts();
updateCartUI();
}
// ========== 初始化 ==========
applyI18n();
loadProducts();
updateCartUI();
</script>
</body>
</html>