feat: 全站20个模板添加国际化(i18n)支持 - 简体中文/繁体中文/英文三语切换
- 所有18套前端模板 + 管理后台共20个HTML文件添加i18n引擎 - 前端JavaScript方案:I18N_LOCALES翻译字典 + data-i18n属性 + t()函数调用 - 语言切换器UI:下拉菜单选择,匹配各模板主题风格 - 语言持久化:localStorage存储 + URL参数覆盖 + 浏览器语言自动检测 - onLangChange回调:语言切换时动态重新渲染所有内容 - 支持语言:zh-CN(简体中文) / zh-TW(繁体中文) / en(English)
This commit is contained in:
514
web/dist/food3/index.html
vendored
514
web/dist/food3/index.html
vendored
@@ -740,6 +740,34 @@ a { color: inherit; text-decoration: none; }
|
||||
.nav-cta { display: none; }
|
||||
.section { padding: 40px 0; }
|
||||
}
|
||||
|
||||
/* ===== LANGUAGE SWITCHER ===== */
|
||||
.lang-switcher{position:relative;margin-left:8px}
|
||||
.lang-btn{
|
||||
display:flex;align-items:center;gap:6px;padding:8px 14px;border-radius:12px;
|
||||
font-size:13px;font-weight:600;color:var(--muted);cursor:pointer;
|
||||
background:#fff;border:1.5px solid var(--line);
|
||||
transition:all .25s;
|
||||
}
|
||||
.lang-btn:hover{border-color:var(--green);color:var(--green);background:var(--green-mist)}
|
||||
.lang-btn svg{width:16px;height:16px}
|
||||
.lang-dropdown{
|
||||
position:absolute;top:calc(100% + 8px);right:0;min-width:160px;
|
||||
background:#fff;border:1.5px solid var(--green-100);border-radius:14px;
|
||||
box-shadow:var(--shadow);overflow:hidden;
|
||||
opacity:0;transform:translateY(-8px);pointer-events:none;
|
||||
transition:all .25s;z-index:100;
|
||||
}
|
||||
.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(--muted);cursor:pointer;transition:all .2s;
|
||||
}
|
||||
.lang-option:hover{background:var(--green-mist);color:var(--green-deep)}
|
||||
.lang-option.active{color:var(--green);font-weight:700}
|
||||
.lang-option .check{width:16px;height:16px;opacity:0;transition:opacity .2s}
|
||||
.lang-option.active .check{opacity:1}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -749,16 +777,37 @@ a { color: inherit; text-decoration: none; }
|
||||
<div class="container nav-inner">
|
||||
<div class="logo" onclick="scrollToTop()">
|
||||
<div class="logo-mark" id="logoMark"></div>
|
||||
<div class="logo-text">绿野<span>鲜送</span></div>
|
||||
<div class="logo-text" data-i18n="logo_text">绿野<span>鲜送</span></div>
|
||||
</div>
|
||||
<div class="search-wrap">
|
||||
<input id="searchInput" class="search-box" type="text" placeholder="搜索餐厅或美食,如 轻食、寿司、奶茶…" autocomplete="off" />
|
||||
<input id="searchInput" class="search-box" type="text" data-i18n-placeholder="search_placeholder" placeholder="搜索餐厅或美食,如 轻食、寿司、奶茶…" autocomplete="off" />
|
||||
<button class="search-btn" id="searchBtn" aria-label="搜索"></button>
|
||||
</div>
|
||||
<div class="nav-actions">
|
||||
<button class="nav-cta" onclick="scrollToRestaurants()">
|
||||
<span id="navCtaIcon"></span> 立即点餐
|
||||
<span id="navCtaIcon"></span> <span data-i18n="nav_cta">立即点餐</span>
|
||||
</button>
|
||||
<div class="lang-switcher" id="langSwitcher">
|
||||
<button class="lang-btn" id="langBtn" onclick="toggleLangDropdown()">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><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" stroke-linecap="round" stroke-linejoin="round" style="width:12px;height:12px"><polyline points="6 9 12 15 18 9"/></svg>
|
||||
</button>
|
||||
<div class="lang-dropdown" id="langDropdown">
|
||||
<div class="lang-option" data-lang="zh-CN" onclick="switchLang('zh-CN')">
|
||||
<svg class="check" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
|
||||
<span>简体中文</span>
|
||||
</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="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
|
||||
<span>繁體中文</span>
|
||||
</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="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
|
||||
<span>English</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button class="cart-btn" id="cartBtn" aria-label="购物车">
|
||||
<span id="cartBtnIcon"></span>
|
||||
<span class="cart-badge" id="cartBadge">0</span>
|
||||
@@ -775,26 +824,26 @@ a { color: inherit; text-decoration: none; }
|
||||
<div class="container">
|
||||
<div class="hero-card">
|
||||
<div class="hero-text">
|
||||
<span class="hero-tag"><span class="dot"></span> 当日鲜配 · 0 防腐剂</span>
|
||||
<h1 class="hero-title">新鲜好味 <em>·</em> 绿色送达</h1>
|
||||
<p class="hero-desc">甄选本地优质餐厅,从农场到餐桌的轻盈之旅。低卡轻食、匠心料理,用一份自然的绿意,点亮每一餐。</p>
|
||||
<span class="hero-tag"><span class="dot"></span> <span data-i18n="hero_tag">当日鲜配 · 0 防腐剂</span></span>
|
||||
<h1 class="hero-title"><span data-i18n="hero_title_1">新鲜好味</span> <em>·</em> <span data-i18n="hero_title_2">绿色送达</span></h1>
|
||||
<p class="hero-desc" data-i18n="hero_desc">甄选本地优质餐厅,从农场到餐桌的轻盈之旅。低卡轻食、匠心料理,用一份自然的绿意,点亮每一餐。</p>
|
||||
<div class="hero-actions">
|
||||
<button class="btn-primary" onclick="scrollToRestaurants()">
|
||||
<span id="heroCtaIcon"></span> 开始点餐
|
||||
<span id="heroCtaIcon"></span> <span data-i18n="hero_cta1">开始点餐</span>
|
||||
</button>
|
||||
<button class="btn-ghost" onclick="scrollToCategories()">浏览分类</button>
|
||||
<button class="btn-ghost" onclick="scrollToCategories()"><span data-i18n="hero_cta2">浏览分类</span></button>
|
||||
</div>
|
||||
<div class="hero-stats">
|
||||
<div class="hero-stat"><div class="num" id="statRest">12+</div><div class="lbl">精选餐厅</div></div>
|
||||
<div class="hero-stat"><div class="num">30min</div><div class="lbl">平均送达</div></div>
|
||||
<div class="hero-stat"><div class="num">4.7★</div><div class="lbl">平均评分</div></div>
|
||||
<div class="hero-stat"><div class="num" id="statRest">12+</div><div class="lbl" data-i18n="stat_restaurants">精选餐厅</div></div>
|
||||
<div class="hero-stat"><div class="num">30min</div><div class="lbl" data-i18n="stat_delivery">平均送达</div></div>
|
||||
<div class="hero-stat"><div class="num">4.7★</div><div class="lbl" data-i18n="stat_rating">平均评分</div></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hero-visual">
|
||||
<div class="hero-bowl" id="heroBowl"></div>
|
||||
<div class="hero-float f1"><span class="ic" id="floatIc1"></span>低卡轻食</div>
|
||||
<div class="hero-float f2"><span class="ic" id="floatIc2"></span>新鲜直送</div>
|
||||
<div class="hero-float f3"><span class="ic" id="floatIc3"></span>绿色包装</div>
|
||||
<div class="hero-float f1"><span class="ic" id="floatIc1"></span><span data-i18n="float_1">低卡轻食</span></div>
|
||||
<div class="hero-float f2"><span class="ic" id="floatIc2"></span><span data-i18n="float_2">新鲜直送</span></div>
|
||||
<div class="hero-float f3"><span class="ic" id="floatIc3"></span><span data-i18n="float_3">绿色包装</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -806,8 +855,8 @@ a { color: inherit; text-decoration: none; }
|
||||
<div class="section-head">
|
||||
<div class="section-title">
|
||||
<span class="kicker">CATEGORIES</span>
|
||||
<h2>美食分类</h2>
|
||||
<p>挑你所爱,一键直达心仪风味</p>
|
||||
<h2 data-i18n="cat_title">美食分类</h2>
|
||||
<p data-i18n="cat_desc">挑你所爱,一键直达心仪风味</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cat-grid" id="catGrid"></div>
|
||||
@@ -820,10 +869,10 @@ a { color: inherit; text-decoration: none; }
|
||||
<div class="section-head">
|
||||
<div class="section-title">
|
||||
<span class="kicker">FEATURED</span>
|
||||
<h2>人气推荐</h2>
|
||||
<p>本月销量领先,大家都在点</p>
|
||||
<h2 data-i18n="feat_title">人气推荐</h2>
|
||||
<p data-i18n="feat_desc">本月销量领先,大家都在点</p>
|
||||
</div>
|
||||
<a class="link-more" href="javascript:scrollToRestaurants()">查看全部 →</a>
|
||||
<a class="link-more" href="javascript:scrollToRestaurants()"><span data-i18n="feat_more">查看全部 →</span></a>
|
||||
</div>
|
||||
<div class="featured-scroller" id="featuredScroller"></div>
|
||||
</div>
|
||||
@@ -835,27 +884,27 @@ a { color: inherit; text-decoration: none; }
|
||||
<div class="section-head">
|
||||
<div class="section-title">
|
||||
<span class="kicker">RESTAURANTS</span>
|
||||
<h2>全部餐厅</h2>
|
||||
<p id="listSubtitle">为你找到附近优质好店</p>
|
||||
<h2 data-i18n="rest_title">全部餐厅</h2>
|
||||
<p id="listSubtitle" data-i18n="rest_subtitle">为你找到附近优质好店</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="toolbar">
|
||||
<div class="sort-group" id="sortGroup">
|
||||
<button class="sort-btn active" data-sort="">综合</button>
|
||||
<button class="sort-btn" data-sort="rating">评分</button>
|
||||
<button class="sort-btn" data-sort="sales">销量</button>
|
||||
<button class="sort-btn" data-sort="delivery_time">送达</button>
|
||||
<button class="sort-btn active" data-sort="" data-i18n="sort_comprehensive">综合</button>
|
||||
<button class="sort-btn" data-sort="rating" data-i18n="sort_rating">评分</button>
|
||||
<button class="sort-btn" data-sort="sales" data-i18n="sort_sales">销量</button>
|
||||
<button class="sort-btn" data-sort="delivery_time" data-i18n="sort_delivery">送达</button>
|
||||
</div>
|
||||
<button class="chip-clear" id="chipClear">
|
||||
<span id="chipClearIcon"></span> <span id="chipClearText">清除筛选</span>
|
||||
<span id="chipClearIcon"></span> <span id="chipClearText" data-i18n="chip_clear">清除筛选</span>
|
||||
</button>
|
||||
<div class="result-info">共 <b id="resultCount">0</b> 家餐厅</div>
|
||||
<div class="result-info"><span data-i18n="result_prefix">共</span> <b id="resultCount">0</b> <span data-i18n="result_suffix">家餐厅</span></div>
|
||||
</div>
|
||||
<div id="restListWrap">
|
||||
<div class="rest-grid" id="restGrid"></div>
|
||||
</div>
|
||||
<div class="load-more-wrap" id="loadMoreWrap" style="display:none">
|
||||
<button class="load-more" id="loadMoreBtn">加载更多</button>
|
||||
<button class="load-more" id="loadMoreBtn" data-i18n="load_more">加载更多</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -869,7 +918,7 @@ a { color: inherit; text-decoration: none; }
|
||||
<div class="logo-mark" id="footerLogo"></div>
|
||||
<div class="logo-text">绿野<span>鲜送</span></div>
|
||||
</div>
|
||||
<p>新鲜好味,绿色送达。致力于连接本地优质餐厅与健康食材,让每一餐都自然、轻盈、安心。</p>
|
||||
<p data-i18n="footer_brand_desc">新鲜好味,绿色送达。致力于连接本地优质餐厅与健康食材,让每一餐都自然、轻盈、安心。</p>
|
||||
<div class="footer-social" style="margin-top:16px">
|
||||
<a href="javascript:void(0)" aria-label="微信" id="socialWx"></a>
|
||||
<a href="javascript:void(0)" aria-label="微博" id="socialWb"></a>
|
||||
@@ -877,30 +926,30 @@ a { color: inherit; text-decoration: none; }
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer-col">
|
||||
<h4>关于我们</h4>
|
||||
<a href="javascript:void(0)">品牌故事</a>
|
||||
<a href="javascript:void(0)">绿色承诺</a>
|
||||
<a href="javascript:void(0)">加入我们</a>
|
||||
<a href="javascript:void(0)">联系合作</a>
|
||||
<h4 data-i18n="footer_about">关于我们</h4>
|
||||
<a href="javascript:void(0)"><span data-i18n="footer_story">品牌故事</span></a>
|
||||
<a href="javascript:void(0)"><span data-i18n="footer_green">绿色承诺</span></a>
|
||||
<a href="javascript:void(0)"><span data-i18n="footer_join">加入我们</span></a>
|
||||
<a href="javascript:void(0)"><span data-i18n="footer_partner">联系合作</span></a>
|
||||
</div>
|
||||
<div class="footer-col">
|
||||
<h4>帮助中心</h4>
|
||||
<a href="javascript:void(0)">下单指南</a>
|
||||
<a href="javascript:void(0)">配送说明</a>
|
||||
<a href="javascript:void(0)">退款规则</a>
|
||||
<a href="javascript:void(0)">常见问题</a>
|
||||
<h4 data-i18n="footer_help">帮助中心</h4>
|
||||
<a href="javascript:void(0)"><span data-i18n="footer_guide">下单指南</span></a>
|
||||
<a href="javascript:void(0)"><span data-i18n="footer_delivery_info">配送说明</span></a>
|
||||
<a href="javascript:void(0)"><span data-i18n="footer_refund">退款规则</span></a>
|
||||
<a href="javascript:void(0)"><span data-i18n="footer_faq">常见问题</span></a>
|
||||
</div>
|
||||
<div class="footer-col">
|
||||
<h4>商家合作</h4>
|
||||
<a href="javascript:void(0)">入驻平台</a>
|
||||
<a href="javascript:void(0)">商家后台</a>
|
||||
<a href="javascript:void(0)">营销推广</a>
|
||||
<a href="javascript:void(0)">开放接口</a>
|
||||
<h4 data-i18n="footer_biz">商家合作</h4>
|
||||
<a href="javascript:void(0)"><span data-i18n="footer_platform">入驻平台</span></a>
|
||||
<a href="javascript:void(0)"><span data-i18n="footer_backend">商家后台</span></a>
|
||||
<a href="javascript:void(0)"><span data-i18n="footer_marketing">营销推广</span></a>
|
||||
<a href="javascript:void(0)"><span data-i18n="footer_api">开放接口</span></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer-bottom">
|
||||
<span>© 2026 绿野鲜送 FreshGreen · 用心连接每一份新鲜</span>
|
||||
<span>新鲜 · 健康 · 自然 · 轻盈</span>
|
||||
<span>data-i18n="copyright">© 2026 绿野鲜送 FreshGreen · 用心连接每一份新鲜</span>
|
||||
<span>data-i18n="copyright_slogan">新鲜 · 健康 · 自然 · 轻盈</span>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
@@ -918,7 +967,7 @@ a { color: inherit; text-decoration: none; }
|
||||
<div class="cart-drawer" id="cartDrawer">
|
||||
<div class="cart-drawer-head">
|
||||
<div class="cart-drawer-title">
|
||||
<span id="drawerTitleIcon"></span> 购物车 <span class="cnt" id="drawerCount"></span>
|
||||
<span id="drawerTitleIcon"></span> <span data-i18n="drawer_title">购物车</span> <span class="cnt" id="drawerCount"></span>
|
||||
</div>
|
||||
<button class="cart-clear" id="cartClearBtn">
|
||||
<span id="clearIcon"></span> 清空
|
||||
@@ -936,15 +985,380 @@ a { color: inherit; text-decoration: none; }
|
||||
</div>
|
||||
<div class="cart-bar-text" id="cartBarText">
|
||||
<div class="cart-bar-total"><small>¥</small><span id="cartBarTotal">0</span></div>
|
||||
<div class="cart-bar-sub" id="cartBarSub">购物车是空的</div>
|
||||
<div class="cart-bar-sub" id="cartBarSub" data-i18n="cart_empty">购物车是空的</div>
|
||||
</div>
|
||||
<button class="cart-checkout" id="cartCheckoutBtn">去结算</button>
|
||||
<button class="cart-checkout" id="cartCheckoutBtn" data-i18n="cart_checkout">去结算</button>
|
||||
</div>
|
||||
|
||||
<!-- ===== Toast ===== -->
|
||||
<div class="toast-wrap" id="toastWrap"></div>
|
||||
|
||||
<script>
|
||||
|
||||
/* =========================================================
|
||||
i18n 国际化引擎
|
||||
========================================================= */
|
||||
const I18N_LOCALES = {
|
||||
'zh-CN': {
|
||||
logo_text: '绿野鲜送',
|
||||
search_placeholder: '搜索餐厅或美食,如 轻食、寿司、奶茶…',
|
||||
nav_cta: '立即点餐',
|
||||
hero_tag: '当日鲜配 · 0 防腐剂',
|
||||
hero_title_1: '新鲜好味',
|
||||
hero_title_2: '绿色送达',
|
||||
hero_desc: '甄选本地优质餐厅,从农场到餐桌的轻盈之旅。低卡轻食、匠心料理,用一份自然的绿意,点亮每一餐。',
|
||||
hero_cta1: '开始点餐',
|
||||
hero_cta2: '浏览分类',
|
||||
stat_restaurants: '精选餐厅',
|
||||
stat_delivery: '平均送达',
|
||||
stat_rating: '平均评分',
|
||||
float_1: '低卡轻食',
|
||||
float_2: '新鲜直送',
|
||||
float_3: '绿色包装',
|
||||
cat_title: '美食分类',
|
||||
cat_desc: '挑你所爱,一键直达心仪风味',
|
||||
cat_all: '全部',
|
||||
feat_title: '人气推荐',
|
||||
feat_desc: '本月销量领先,大家都在点',
|
||||
feat_more: '查看全部 →',
|
||||
rest_title: '全部餐厅',
|
||||
rest_subtitle: '为你找到附近优质好店',
|
||||
sort_comprehensive: '综合',
|
||||
sort_rating: '评分',
|
||||
sort_sales: '销量',
|
||||
sort_delivery: '送达',
|
||||
chip_clear: '清除筛选',
|
||||
result_prefix: '共',
|
||||
result_suffix: '家餐厅',
|
||||
load_more: '加载更多',
|
||||
footer_brand_desc: '新鲜好味,绿色送达。致力于连接本地优质餐厅与健康食材,让每一餐都自然、轻盈、安心。',
|
||||
footer_about: '关于我们',
|
||||
footer_story: '品牌故事',
|
||||
footer_green: '绿色承诺',
|
||||
footer_join: '加入我们',
|
||||
footer_partner: '联系合作',
|
||||
footer_help: '帮助中心',
|
||||
footer_guide: '下单指南',
|
||||
footer_delivery_info: '配送说明',
|
||||
footer_refund: '退款规则',
|
||||
footer_faq: '常见问题',
|
||||
footer_biz: '商家合作',
|
||||
footer_platform: '入驻平台',
|
||||
footer_backend: '商家后台',
|
||||
footer_marketing: '营销推广',
|
||||
footer_api: '开放接口',
|
||||
copyright: '© 2026 绿野鲜送 FreshGreen · 用心连接每一份新鲜',
|
||||
copyright_slogan: '新鲜 · 健康 · 自然 · 轻盈',
|
||||
drawer_title: '购物车',
|
||||
cart_clear: '清空',
|
||||
cart_empty: '购物车是空的',
|
||||
cart_checkout: '去结算',
|
||||
status_open: '营业中',
|
||||
status_closed: '休息',
|
||||
monthly_sales: 't('monthly_sales')',
|
||||
delivery_time_suffix: t('delivery_time_suffix'),
|
||||
min_order_prefix: '起送',
|
||||
delivery_prefix: '配送',
|
||||
rating_label: '评分',
|
||||
all_dishes: '全部菜品',
|
||||
dish_count_suffix: '道',
|
||||
no_restaurants: '暂无符合条件的餐厅',
|
||||
no_restaurants_hint: '试试切换分类或调整搜索关键词',
|
||||
load_failed: '加载失败',
|
||||
load_failed_hint: '请检查网络后刷新',
|
||||
cat_load_failed: '分类加载失败',
|
||||
menu_load_failed: '菜单加载失败',
|
||||
loading: '加载中…',
|
||||
preparing_menu: '正在准备菜单…',
|
||||
no_dishes: '暂无菜品',
|
||||
no_dishes_hint: '该餐厅还未上架菜品',
|
||||
added_to_cart: '已加入',
|
||||
cart_cleared: '购物车已清空',
|
||||
cart_empty_warn: '购物车还是空的',
|
||||
switched_restaurant: '已切换餐厅,购物车已更新',
|
||||
order_success: '下单成功!共',
|
||||
order_delivery_hint: '预计 30 分钟送达',
|
||||
subtotal_with_delivery: '合计 (含配送费',
|
||||
min_order_warn: '还差',
|
||||
min_order_reached: '满起送价',
|
||||
from_restaurant: '来自',
|
||||
delivery_fee_label: '另需配送费',
|
||||
meets_min_order: '已满起送价',
|
||||
cart_drawer_empty: '购物车空空如也',
|
||||
cart_drawer_empty_hint: '快去挑选心仪美食吧',
|
||||
items_label: '件',
|
||||
price_per_serving: '/ 份',
|
||||
current_filter: '当前筛选:',
|
||||
no_filter: '为你找到附近优质好店',
|
||||
clear_prefix: '清除:',
|
||||
clear_all: '清除筛选',
|
||||
new_total_label: '新合计',
|
||||
checkout_btn: '去结算',
|
||||
},
|
||||
'en': {
|
||||
logo_text: 'FreshGreen',
|
||||
search_placeholder: 'Search restaurants or food, e.g. salad, sushi, bubble tea…',
|
||||
nav_cta: 'Order Now',
|
||||
hero_tag: 'Same-Day Delivery · Zero Preservatives',
|
||||
hero_title_1: 'Fresh Taste',
|
||||
hero_title_2: 'Green Delivery',
|
||||
hero_desc: 'Curating local quality restaurants for a light farm-to-table journey. Low-calorie meals, artisan dishes — a touch of natural green for every meal.',
|
||||
hero_cta1: 'Start Ordering',
|
||||
hero_cta2: 'Browse Categories',
|
||||
stat_restaurants: 'Top Restaurants',
|
||||
stat_delivery: 'Avg Delivery',
|
||||
stat_rating: 'Avg Rating',
|
||||
float_1: 'Low-Cal Meals',
|
||||
float_2: 'Fresh Delivery',
|
||||
float_3: 'Eco Packaging',
|
||||
cat_title: 'Food Categories',
|
||||
cat_desc: 'Find what you love, one tap to your favorite flavor',
|
||||
cat_all: 'All',
|
||||
feat_title: 'Popular Picks',
|
||||
feat_desc: 'Top sellers this month, everyone is ordering',
|
||||
feat_more: 'View All →',
|
||||
rest_title: 'All Restaurants',
|
||||
rest_subtitle: 'Quality restaurants near you',
|
||||
sort_comprehensive: 'Default',
|
||||
sort_rating: 'Rating',
|
||||
sort_sales: 'Sales',
|
||||
sort_delivery: 'Delivery',
|
||||
chip_clear: 'Clear Filter',
|
||||
result_prefix: '',
|
||||
result_suffix: 'restaurants',
|
||||
load_more: 'Load More',
|
||||
footer_brand_desc: 'Fresh taste, green delivery. Connecting local quality restaurants and healthy ingredients for a natural, light, and safe meal every time.',
|
||||
footer_about: 'About',
|
||||
footer_story: 'Our Story',
|
||||
footer_green: 'Green Promise',
|
||||
footer_join: 'Join Us',
|
||||
footer_partner: 'Contact',
|
||||
footer_help: 'Help Center',
|
||||
footer_guide: 'Ordering Guide',
|
||||
footer_delivery_info: 'Delivery Info',
|
||||
footer_refund: 'Refund Policy',
|
||||
footer_faq: 'FAQ',
|
||||
footer_biz: 'Partners',
|
||||
footer_platform: 'Join Platform',
|
||||
footer_backend: 'Merchant Portal',
|
||||
footer_marketing: 'Marketing',
|
||||
footer_api: 'Open API',
|
||||
copyright: '© 2026 FreshGreen · Connecting freshness with care',
|
||||
copyright_slogan: 'Fresh · Healthy · Natural · Light',
|
||||
drawer_title: 'Cart',
|
||||
cart_clear: 'Clear',
|
||||
cart_empty: 'Cart is empty',
|
||||
cart_checkout: 'Checkout',
|
||||
status_open: 'Open',
|
||||
status_closed: 'Closed',
|
||||
monthly_sales: 'sales',
|
||||
delivery_time_suffix: 'min',
|
||||
min_order_prefix: 'Min',
|
||||
delivery_prefix: 'Delivery',
|
||||
rating_label: 'Rating',
|
||||
all_dishes: 'All Dishes',
|
||||
dish_count_suffix: '',
|
||||
no_restaurants: 'No restaurants found',
|
||||
no_restaurants_hint: 'Try different categories or search keywords',
|
||||
load_failed: 'Load Failed',
|
||||
load_failed_hint: 'Please check your network',
|
||||
cat_load_failed: 'Failed to load categories',
|
||||
menu_load_failed: 'Failed to load menu',
|
||||
loading: 'Loading…',
|
||||
preparing_menu: 'Preparing menu…',
|
||||
no_dishes: 'No dishes available',
|
||||
no_dishes_hint: 'This restaurant has no dishes yet',
|
||||
added_to_cart: 'Added',
|
||||
cart_cleared: 'Cart cleared',
|
||||
cart_empty_warn: 'Cart is still empty',
|
||||
switched_restaurant: 'Restaurant changed, cart updated',
|
||||
order_success: 'Order placed! Total',
|
||||
order_delivery_hint: 'Estimated 30 min delivery',
|
||||
subtotal_with_delivery: 'Total (incl. delivery',
|
||||
min_order_warn: 'Still need',
|
||||
min_order_reached: 'to reach minimum',
|
||||
from_restaurant: 'From',
|
||||
delivery_fee_label: 'delivery fee',
|
||||
meets_min_order: 'Minimum met',
|
||||
cart_drawer_empty: 'Cart is empty',
|
||||
cart_drawer_empty_hint: 'Pick some delicious food!',
|
||||
items_label: 'items',
|
||||
price_per_serving: '/ serving',
|
||||
current_filter: 'Filtering:',
|
||||
no_filter: 'Quality restaurants near you',
|
||||
clear_prefix: 'Clear: ',
|
||||
clear_all: 'Clear Filter',
|
||||
new_total_label: 'New total',
|
||||
checkout_btn: 'Checkout',
|
||||
},
|
||||
'zh-TW': {
|
||||
logo_text: '綠野鮮送',
|
||||
search_placeholder: '搜尋餐廳或美食,如 輕食、壽司、奶茶…',
|
||||
nav_cta: '立即點餐',
|
||||
hero_tag: '當日鮮配 · 0 防腐劑',
|
||||
hero_title_1: '新鮮好味',
|
||||
hero_title_2: '綠色送達',
|
||||
hero_desc: '甄選本地優質餐廳,從農場到餐桌的輕盈之旅。低卡輕食、匠心料理,用一份自然的綠意,點亮每一餐。',
|
||||
hero_cta1: '開始點餐',
|
||||
hero_cta2: '瀏覽分類',
|
||||
stat_restaurants: '精選餐廳',
|
||||
stat_delivery: '平均送達',
|
||||
stat_rating: '平均評分',
|
||||
float_1: '低卡輕食',
|
||||
float_2: '新鮮直送',
|
||||
float_3: '綠色包裝',
|
||||
cat_title: '美食分類',
|
||||
cat_desc: '挑你所愛,一鍵直達心儀風味',
|
||||
cat_all: '全部',
|
||||
feat_title: '人氣推薦',
|
||||
feat_desc: '本月銷量領先,大家都在點',
|
||||
feat_more: '查看全部 →',
|
||||
rest_title: '全部餐廳',
|
||||
rest_subtitle: '為你找到附近優質好店',
|
||||
sort_comprehensive: '綜合',
|
||||
sort_rating: '評分',
|
||||
sort_sales: '銷量',
|
||||
sort_delivery: '送達',
|
||||
chip_clear: '清除篩選',
|
||||
result_prefix: '共',
|
||||
result_suffix: '家餐廳',
|
||||
load_more: '載入更多',
|
||||
footer_brand_desc: '新鮮好味,綠色送達。致力於連接本地優質餐廳與健康食材,讓每一餐都自然、輕盈、安心。',
|
||||
footer_about: '關於我們',
|
||||
footer_story: '品牌故事',
|
||||
footer_green: '綠色承諾',
|
||||
footer_join: '加入我們',
|
||||
footer_partner: '聯繫合作',
|
||||
footer_help: '幫助中心',
|
||||
footer_guide: '下單指南',
|
||||
footer_delivery_info: '配送說明',
|
||||
footer_refund: '退款規則',
|
||||
footer_faq: '常見問題',
|
||||
footer_biz: '商家合作',
|
||||
footer_platform: '入駐平台',
|
||||
footer_backend: '商家後台',
|
||||
footer_marketing: '行銷推廣',
|
||||
footer_api: '開放接口',
|
||||
copyright: '© 2026 綠野鮮送 FreshGreen · 用心連接每一份新鮮',
|
||||
copyright_slogan: '新鮮 · 健康 · 自然 · 輕盈',
|
||||
drawer_title: '購物車',
|
||||
cart_clear: '清空',
|
||||
cart_empty: '購物車是空的',
|
||||
cart_checkout: '去結算',
|
||||
status_open: '營業中',
|
||||
status_closed: '休息',
|
||||
monthly_sales: '月售',
|
||||
delivery_time_suffix: '分鐘',
|
||||
min_order_prefix: '起送',
|
||||
delivery_prefix: '配送',
|
||||
rating_label: '評分',
|
||||
all_dishes: '全部菜品',
|
||||
dish_count_suffix: '道',
|
||||
no_restaurants: '暫無符合條件的餐廳',
|
||||
no_restaurants_hint: '試試切換分類或調整搜尋關鍵詞',
|
||||
load_failed: '載入失敗',
|
||||
load_failed_hint: '請檢查網路後重新整理',
|
||||
cat_load_failed: '分類載入失敗',
|
||||
menu_load_failed: '菜單載入失敗',
|
||||
loading: '載入中…',
|
||||
preparing_menu: '正在準備菜單…',
|
||||
no_dishes: '暫無菜品',
|
||||
no_dishes_hint: '該餐廳還未上架菜品',
|
||||
added_to_cart: '已加入',
|
||||
cart_cleared: '購物車已清空',
|
||||
cart_empty_warn: '購物車還是空的',
|
||||
switched_restaurant: '已切換餐廳,購物車已更新',
|
||||
order_success: '下單成功!共',
|
||||
order_delivery_hint: '預計 30 分鐘送達',
|
||||
subtotal_with_delivery: '合計 (含配送費',
|
||||
min_order_warn: '還差',
|
||||
min_order_reached: '滿起送價',
|
||||
from_restaurant: '來自',
|
||||
delivery_fee_label: '另需配送費',
|
||||
meets_min_order: '已滿起送價',
|
||||
cart_drawer_empty: '購物車空空如也',
|
||||
cart_drawer_empty_hint: '快去挑選心儀美食吧',
|
||||
items_label: '件',
|
||||
price_per_serving: '/ 份',
|
||||
current_filter: '當前篩選:',
|
||||
no_filter: '為你找到附近優質好店',
|
||||
clear_prefix: '清除:',
|
||||
clear_all: '清除篩選',
|
||||
new_total_label: '新合計',
|
||||
checkout_btn: '去結算',
|
||||
}
|
||||
};
|
||||
|
||||
const LANG_LABELS = {'zh-CN':'中文','en':'EN','zh-TW':'繁中'};
|
||||
|
||||
let 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 'zh-CN';
|
||||
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');
|
||||
if(key==='logo_text'){el.innerHTML=t(key);}
|
||||
else{el.textContent=t(key);}
|
||||
});
|
||||
document.querySelectorAll('[data-i18n-placeholder]').forEach(function(el){
|
||||
var key=el.getAttribute('data-i18n-placeholder');
|
||||
el.placeholder=t(key);
|
||||
});
|
||||
document.querySelectorAll('[data-i18n-title]').forEach(function(el){
|
||||
var key=el.getAttribute('data-i18n-title');
|
||||
el.title=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);
|
||||
});
|
||||
}
|
||||
|
||||
function switchLang(lang){
|
||||
if(!I18N_LOCALES[lang]) return;
|
||||
currentLang=lang;
|
||||
try{localStorage.setItem('lang',lang);}catch(e){}
|
||||
|
||||
/* --- I18N: language change handler --- */
|
||||
var onLangChange = function(){
|
||||
data._idx = {}; buildIdx(); updateFilter(); renderCategories(); renderFeatured(); renderRestaurants(true);
|
||||
var u = currentRest && restaurants[currentRest];
|
||||
if(u){
|
||||
restDetailName.textContent = u.name;
|
||||
restDetailBadge.textContent = t(u.open?'status_open':'status_closed');
|
||||
restDetailBadge.className = 'badge '+(u.open?'open':'closed');
|
||||
restDetailRating.textContent = u.rating;
|
||||
restDetailSales.textContent = t('monthly_sales')+' '+u.monthly_sales;
|
||||
}
|
||||
applyI18n();
|
||||
};
|
||||
|
||||
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');
|
||||
});
|
||||
|
||||
|
||||
/* ============================================================
|
||||
绿野鲜送 — 前端逻辑
|
||||
============================================================ */
|
||||
@@ -1194,7 +1608,7 @@ a { color: inherit; text-decoration: none; }
|
||||
<div class="rest-info">
|
||||
<div class="rest-head">
|
||||
<div class="rest-name">${escapeHtml(r.name)}</div>
|
||||
<div class="rest-status ${open ? 'open' : 'closed'}">${open ? '营业中' : '休息'}</div>
|
||||
<div class="rest-status ${open ? 'open' : 'closed'}">${open ? t('status_open') : t('status_closed')}</div>
|
||||
</div>
|
||||
<div class="rest-cat">${escapeHtml(r.category_name || '美食')}</div>
|
||||
${tags.length ? `<div class="rest-tags">${tags.map(t => `<span class="t">${escapeHtml(t)}</span>`).join('')}</div>` : ''}
|
||||
|
||||
Reference in New Issue
Block a user