Files
vps_web/templates/index.html
ddrwode ce25e6b0f8 哈哈
2026-02-10 16:54:06 +08:00

242 lines
13 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' if lang == 'zh' else 'en' }}">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ t.meta_title }}</title>
<link rel="icon" type="image/svg+xml" href="{{ url_for('static', filename='img/site-logo-mark.svg') }}">
<meta name="description" content="{{ t.meta_description }}">
<meta name="keywords" content="{{ t.meta_keywords }}">
<link rel="canonical" href="{{ site_url }}/">
<!-- Open Graph / 社交分享 -->
<meta property="og:type" content="website">
<meta property="og:url" content="{{ site_url }}/">
<meta property="og:title" content="{{ t.og_title }}">
<meta property="og:description" content="{{ t.og_description }}">
<meta property="og:locale" content="{{ t.og_locale }}">
<!-- JSON-LD 结构化数据,便于搜索引擎理解 -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "WebApplication",
"name": "{{ site_name }}",
"description": "{{ t.schema_webapp_description }}",
"url": "{{ site_url }}",
"applicationCategory": "UtilitiesApplication"
}
</script>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Table",
"about": "{{ t.schema_table_about }}",
"name": "{{ t.schema_table_name }}",
"description": "{{ t.schema_table_description }}"
}
</script>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600&family=Noto+Sans+SC:wght@400;500;700&family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap" rel="stylesheet">
<link rel="stylesheet" href="/static/css/style.css">
</head>
<body data-lang="{{ lang }}" class="homepage-body">
<header class="header">
<div class="header-inner">
<div class="header-brand">
<a href="{{ url_for('index', lang=lang) }}" class="site-logo-link" aria-label="{{ site_name }}">
<img src="{{ url_for('static', filename='img/site-logo.svg') }}" alt="{{ site_name }} Logo" class="site-logo">
</a>
<p class="tagline">{{ t.tagline }}</p>
</div>
<nav class="header-nav">
<span class="lang-switch">
<a href="{{ url_for('index', lang='zh') }}" class="{{ 'active' if lang == 'zh' else '' }}" title="切换到中文">中文</a>
<span class="lang-sep">|</span>
<a href="{{ url_for('index', lang='en') }}" class="{{ 'active' if lang == 'en' else '' }}" title="Switch to English">English</a>
</span>
<a href="{{ url_for('forum_index') }}">{{ '论坛' if lang == 'zh' else 'Forum' }}</a>
{% if current_user %}
<span class="header-user">{{ ('你好' if lang == 'zh' else 'Hello') }}{{ current_user.username }}</span>
<a href="{{ url_for('user_profile') }}">{{ '个人中心' if lang == 'zh' else 'Profile' }}</a>
<a href="{{ url_for('user_notifications') }}" class="nav-link-with-badge">{{ '通知' if lang == 'zh' else 'Notifications' }}{% if notifications_unread_count %}<span class="nav-badge">{{ notifications_unread_count }}</span>{% endif %}</a>
<a href="{{ url_for('user_logout') }}">{{ '退出' if lang == 'zh' else 'Logout' }}</a>
{% else %}
<a href="{{ url_for('user_login') }}">{{ '登录' if lang == 'zh' else 'Login' }}</a>
<a href="{{ url_for('user_register') }}">{{ '注册' if lang == 'zh' else 'Register' }}</a>
{% endif %}
</nav>
</div>
<!-- 广告位 1页头横幅。接入 Google AdSense 时,将下方注释替换为您的广告代码 -->
<div class="ad-slot ad-slot-header" id="ad-slot-1">
<!-- 示例Google AdSense 横幅
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-XXXXXX" crossorigin="anonymous"></script>
<ins class="adsbygoogle" style="display:block" data-ad-client="ca-pub-XXXXXX" data-ad-slot="XXXXXX" data-ad-format="auto"></ins>
<script>(adsbygoogle = window.adsbygoogle || []).push({});</script>
-->
</div>
</header>
<main class="main homepage-main">
<section class="hero-panel">
<div class="hero-copy">
<p class="hero-kicker">{{ t.hero_kicker }}</p>
<h1 class="hero-title">{{ t.hero_title }}</h1>
<p class="hero-lede">{{ t.hero_lede }}</p>
<div class="hero-trust-row">
<span>{{ t.hero_trust_1 }}</span>
<span>{{ t.hero_trust_2 }}</span>
<span>{{ t.hero_trust_3 }}</span>
</div>
</div>
<div class="hero-metrics">
<article class="metric-card">
<p class="metric-label">{{ t.metric_total_plans }}</p>
<p class="metric-value" id="metric-total-plans">--</p>
</article>
<article class="metric-card">
<p class="metric-label">{{ t.metric_providers }}</p>
<p class="metric-value" id="metric-providers">--</p>
</article>
<article class="metric-card">
<p class="metric-label">{{ t.metric_regions }}</p>
<p class="metric-value" id="metric-regions">--</p>
</article>
<article class="metric-card">
<p class="metric-label">{{ t.metric_lowest }}</p>
<p class="metric-value" id="metric-lowest">--</p>
</article>
</div>
</section>
<section class="filters">
<div class="filters-head">
<div>
<h2 class="filters-title">{{ t.filters_title }}</h2>
<p class="filters-subtitle">{{ t.filters_subtitle }}</p>
</div>
<p class="result-count" id="result-count">--</p>
</div>
<div class="filter-grid">
<div class="filter-group">
<label for="filter-provider">{{ t.filter_provider }}</label>
<select id="filter-provider">
<option value="">{{ t.all }}</option>
</select>
</div>
<div class="filter-group">
<label for="filter-region">{{ t.filter_region }}</label>
<select id="filter-region">
<option value="">{{ t.all }}</option>
</select>
</div>
<div class="filter-group">
<label for="filter-memory">{{ t.filter_memory }}</label>
<select id="filter-memory">
<option value="0">{{ t.unlimited }}</option>
<option value="1">1 GB</option>
<option value="2">2 GB</option>
<option value="4">4 GB</option>
<option value="8">8 GB</option>
</select>
</div>
<div class="filter-group">
<label for="filter-price">{{ t.filter_price }}</label>
<select id="filter-price">
<option value="0">{{ t.unlimited }}</option>
<option value="0-50">{{ t.price_under50 }}</option>
<option value="50-100">{{ t.price_50_100 }}</option>
<option value="100-300">{{ t.price_100_300 }}</option>
<option value="300-500">{{ t.price_300_500 }}</option>
<option value="500-99999">{{ t.price_over500 }}</option>
</select>
</div>
<div class="filter-group">
<label for="filter-currency">{{ t.filter_currency }}</label>
<select id="filter-currency">
<option value="CNY">{{ t.cny }}</option>
<option value="USD">{{ t.usd }}</option>
</select>
</div>
<div class="filter-group filter-group-search">
<label for="search-input">{{ t.search_label }}</label>
<input type="text" id="search-input" placeholder="{{ t.search_placeholder }}" />
</div>
<div class="filter-actions">
<button type="button" class="btn-reset" id="btn-reset">{{ t.btn_reset }}</button>
</div>
</div>
</section>
<!-- 广告位 2表格上方。可放置矩形或横条广告 -->
<div class="ad-slot ad-slot-inline" id="ad-slot-2">
<!-- 在此处粘贴 Google AdSense 代码 -->
</div>
<!-- 服务器列表 -->
<section class="table-wrap">
<div class="table-wrap-head">
<p class="table-caption">{{ t.table_caption }}</p>
</div>
<table class="price-table">
<thead>
<tr>
<th>{{ t.th_provider }}</th>
<th>{{ t.th_country }}</th>
<th>{{ t.th_config }}</th>
<th data-sort="vcpu" class="sortable">vCPU <span class="sort-icon"></span></th>
<th data-sort="memory_gb" class="sortable">{{ t.th_memory }} <span class="sort-icon"></span></th>
<th data-sort="storage_gb" class="sortable">{{ t.th_storage }} <span class="sort-icon"></span></th>
<th>{{ t.th_bandwidth }}</th>
<th>{{ t.th_traffic }}</th>
<th data-sort="price" class="col-price sortable">{{ t.th_price }} <span class="sort-icon"></span></th>
<th class="col-link">{{ t.th_action }}</th>
</tr>
</thead>
<tbody id="table-body">
<!-- 由 JS 填充 -->
</tbody>
</table>
</section>
<p class="disclaimer">{{ t.disclaimer }}</p>
</main>
<footer class="footer">
<!-- 广告位 3页脚前 -->
<div class="ad-slot ad-slot-footer" id="ad-slot-3">
<!-- 在此处粘贴 Google AdSense 代码 -->
</div>
<p>{{ t.footer_note }}</p>
<div class="contact-section">
<p class="contact-label">{{ t.contact_label }}</p>
<a href="https://t.me/dockerse" target="_blank" rel="noopener" class="contact-link">
<svg class="contact-icon" width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
<path d="M12 0C5.373 0 0 5.373 0 12s5.373 12 12 12 12-5.373 12-12S18.627 0 12 0zm5.562 8.161c-.18 1.897-.962 6.502-1.359 8.627-.168.9-.5 1.201-.82 1.23-.697.064-1.226-.461-1.901-.903-1.056-.692-1.653-1.123-2.678-1.799-1.185-.781-.417-1.21.258-1.911.177-.184 3.247-2.977 3.307-3.23.007-.032.014-.15-.056-.212s-.174-.041-.249-.024c-.106.024-1.793 1.139-5.062 3.345-.479.329-.913.489-1.302.481-.428-.009-1.252-.242-1.865-.442-.752-.244-1.349-.374-1.297-.789.027-.216.325-.437.893-.663 3.498-1.524 5.831-2.529 6.998-3.014 3.332-1.386 4.025-1.627 4.476-1.635.099-.002.321.023.465.141.121.099.155.232.171.326.016.094.036.308.02.475z"/>
</svg>
<span>@dockerse</span>
</a>
</div>
</footer>
<!-- 浮动联系按钮 -->
<a href="https://t.me/dockerse" target="_blank" rel="noopener" class="floating-contact-btn" title="{{ ('联系我们 - Telegram' if lang == 'zh' else 'Contact us - Telegram') }}">
<svg class="floating-contact-icon" width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
<path d="M12 0C5.373 0 0 5.373 0 12s5.373 12 12 12 12-5.373 12-12S18.627 0 12 0zm5.562 8.161c-.18 1.897-.962 6.502-1.359 8.627-.168.9-.5 1.201-.82 1.23-.697.064-1.226-.461-1.901-.903-1.056-.692-1.653-1.123-2.678-1.799-1.185-.781-.417-1.21.258-1.911.177-.184 3.247-2.977 3.307-3.23.007-.032.014-.15-.056-.212s-.174-.041-.249-.024c-.106.024-1.793 1.139-5.062 3.345-.479.329-.913.489-1.302.481-.428-.009-1.252-.242-1.865-.442-.752-.244-1.349-.374-1.297-.789.027-.216.325-.437.893-.663 3.498-1.524 5.831-2.529 6.998-3.014 3.332-1.386 4.025-1.627 4.476-1.635.099-.002.321.023.465.141.121.099.155.232.171.326.016.094.036.308.02.475z"/>
</svg>
</a>
<script>
window.LANG = {{ lang|tojson }};
window.I18N_JS = {
empty_state: {{ t.empty_state|tojson }},
load_error: {{ t.load_error|tojson }},
btn_visit: {{ t.btn_visit|tojson }},
result_count_pattern: {{ t.result_count_pattern|tojson }}
};
// 首屏直出数据,避免等待 /api/plans 再渲染表格,加快首屏
window.__INITIAL_PLANS__ = {{ initial_plans_json|tojson }};
</script>
<script src="/static/js/main-simple.js"></script>
</body>
</html>