feat(landing): extract i18n keys + add English translations

Replaces all rendered Chinese strings in LandingView with $t() calls and
<i18n-t> interpolation components; adds landing namespace (62 leaf keys) to
both zh.ts and en.ts.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
mini
2026-04-21 01:30:23 +08:00
parent 6328881801
commit fc7e27671d
3 changed files with 233 additions and 58 deletions

View File

@@ -5598,4 +5598,86 @@ export default {
},
},
landing: {
nav: {
products: 'Products',
docs: 'Docs',
login: 'Sign in',
signup: 'Free trial →',
},
hero: {
badgeNew: 'NEW',
eyebrow: 'Unified access to multiple AI platforms · Zero code change',
title1: 'Your AI subscriptions,',
title2: 'are already paid for.',
sub1: 'Claude Pro · ChatGPT Plus · Codex · Gemini subscriptions',
sub2: 'Aggregated into one unified API — drop-in {openai} / {anthropic} SDK',
ctaLogin: 'Sign in →',
ctaContact: 'Contact us',
micro: 'Verified with Codex CLI · Claude Code · curl · Server egress: Singapore',
},
models: {
kicker: '// providers',
title: 'Reuse your subscriptions directly via OAuth',
sub: 'No official API key needed. No account switching.',
more: 'More',
morePlanned: 'Planned',
},
features: {
kicker: '// capabilities',
title1: 'One subscription,',
title2: 'one unified model pool',
sub: 'Consolidate subscriptions scattered across platforms into infrastructure developers can actually use',
f1Title: 'One key for all models',
f1Desc: 'No more requesting API keys or configuring base_url per provider. One {sk} routes to Claude / GPT / Gemini, auto-dispatched by model to the right account pool.',
f1b1: 'OpenAI Responses API compatible',
f1b2: 'Anthropic Messages API compatible',
f1b3: 'Smart model → provider routing',
f2Title: 'Highly available account pool',
f2Desc: 'Multi-account auto-scheduling with failover. When an upstream hits rate limits or cooldown, traffic switches to the next healthy account — token refresh is fully automatic.',
f2b1: 'Rate-limit / 5xx auto failover',
f2b2: 'OAuth token auto-refresh',
f2b3: 'Weighted round-robin · least connections',
f3Title: 'Usage dashboard',
f3Desc: 'Tokens, cost, upstream account, and latency visualized per request. Model distribution pie + trend curve + top rankings.',
f3b1: 'Per-request audit log',
f3b2: 'Multi-dimension tokens / cost stats',
f3b3: 'Export CSV / Webhook integration',
},
codeDemo: {
kicker: '// integration',
title: 'Change base_url. That\'s it.',
sub: 'Compatible with OpenAI / Anthropic / Gemini SDK — {highlight}',
subHighlight: 'zero code changes',
foot: 'Supports OpenAI Responses API · Anthropic Messages API · Gemini generateContent · Streaming SSE &amp; WebSocket',
},
dashboard: {
kicker: '// observability',
title: 'Every request, fully visible',
sub: 'Unlike opaque third-party API pools — see exactly which account was charged, which model ran, how many tokens were used, and upstream response time at a glance.',
statToday: "Today's requests",
statTokensIn: 'Input tokens',
statTokensOut: 'Output tokens',
statCost: "Today's cost",
chartTrend: 'Usage trend — last 30 days',
tableTime: 'Time',
tableModel: 'Model',
tableUpstream: 'Upstream',
tableStatus: 'Status',
tableUsage: 'Usage',
},
footer: {
tagline1: 'Aggregate multiple AI subscriptions into one unified API.',
tagline2: 'Put your already-paid subscriptions to work.',
colProducts: 'Products',
colAccount: 'Account',
colContact: 'Contact',
linkDocs: 'Docs',
linkFeatures: 'Features',
linkChangelog: 'Changelog',
linkLogin: 'Sign in',
linkRegister: 'Register',
},
},
}

View File

@@ -5791,4 +5791,86 @@ export default {
},
},
landing: {
nav: {
products: '产品',
docs: '文档',
login: '登录',
signup: '免费试用 →',
},
hero: {
badgeNew: 'NEW',
eyebrow: '统一接入多个 AI 平台 · 零改动切换',
title1: '你的 AI 订阅,',
title2: '已经付过钱了。',
sub1: 'Claude Pro · ChatGPT Plus · Codex · Gemini 订阅',
sub2: '聚合成统一 API零改动接入 {openai} / {anthropic} SDK',
ctaLogin: '登录 →',
ctaContact: '联系咨询',
micro: '已验证可用 Codex CLI · Claude Code · curl · 服务器出口新加坡',
},
models: {
kicker: '// providers',
title: '通过 OAuth 直接复用你的订阅',
sub: '无需申请官方 API key也无需切换账号',
more: '更多',
morePlanned: '规划中',
},
features: {
kicker: '// capabilities',
title1: '付一次订阅,',
title2: '用起一整个模型池',
sub: '把散落在各个平台的订阅,整合成开发者真正能用的基础设施',
f1Title: '一个 key 接所有模型',
f1Desc: '不再为每个 provider 申请 API key、配置 base_url。统一 {sk} 走 Claude / GPT / Gemini按 model 自动路由到对应账号池。',
f1b1: 'OpenAI Responses API 兼容',
f1b2: 'Anthropic Messages API 兼容',
f1b3: '智能 model → provider 路由',
f2Title: '账号池高可用',
f2Desc: '支持多账号自动调度与 failover。某个上游触发限流 / 冷却时流量切到下一个健康账号token 刷新全自动。',
f2b1: '限流/5xx 自动 failover',
f2b2: 'OAuth token 自动刷新',
f2b3: '加权轮询 · 最少连接',
f3Title: '用量看板',
f3Desc: '每条请求的 tokens、费用、上游账号、延迟全可视化。模型分布饼图 + 趋势曲线 + Top 排行。',
f3b1: '逐请求审计日志',
f3b2: '多维度 tokens / cost 统计',
f3b3: '导出 CSV / 接 Webhook',
},
codeDemo: {
kicker: '// integration',
title: '把 base_url 一改,就能用',
sub: '兼容 OpenAI / Anthropic / Gemini SDK{highlight}',
subHighlight: '零代码改动',
foot: '支持 OpenAI Responses API · Anthropic Messages API · Gemini generateContent · 流式 SSE &amp; WebSocket',
},
dashboard: {
kicker: '// observability',
title: '每条请求都看得见',
sub: '不像第三方 API 池子那种"扣了多少不告诉你"——扣哪个账号、跑哪个模型、用了多少 tokens、上游响应几秒一目了然。',
statToday: '今日请求',
statTokensIn: '输入 Tokens',
statTokensOut: '输出 Tokens',
statCost: '今日费用',
chartTrend: '近 30 天用量趋势',
tableTime: '时间',
tableModel: '模型',
tableUpstream: '上游',
tableStatus: '状态',
tableUsage: '用量',
},
footer: {
tagline1: '把多个 AI 订阅聚合成统一 API。',
tagline2: '让「已经付过钱」的订阅真正为你工作。',
colProducts: '产品',
colAccount: '账户',
colContact: '联系',
linkDocs: '文档',
linkFeatures: '功能',
linkChangelog: '更新日志',
linkLogin: '登录',
linkRegister: '注册',
},
},
}

View File

@@ -13,13 +13,13 @@
<span>PURO AI</span>
</router-link>
<div class="nav-links">
<a href="#features">产品</a>
<a href="/docs">文档</a>
<a href="#features">{{ $t('landing.nav.products') }}</a>
<a href="/docs">{{ $t('landing.nav.docs') }}</a>
</div>
<div class="nav-cta">
<PuroLocaleSwitcher />
<router-link to="/login" class="btn btn-ghost">登录</router-link>
<router-link to="/register" class="btn btn-primary">免费试用 </router-link>
<router-link to="/login" class="btn btn-ghost">{{ $t('landing.nav.login') }}</router-link>
<router-link to="/register" class="btn btn-primary">{{ $t('landing.nav.signup') }}</router-link>
</div>
</div>
</nav>
@@ -27,32 +27,35 @@
<!-- HERO -->
<section class="hero container">
<div class="hero-eyebrow">
<span class="badge">NEW</span>
<span>统一接入多个 AI 平台 · 零改动切换</span>
<span class="badge">{{ $t('landing.hero.badgeNew') }}</span>
<span>{{ $t('landing.hero.eyebrow') }}</span>
</div>
<h1 class="hero-title">
你的 AI 订阅<br>
<span class="text-puro-cyan">已经付过钱了</span>
{{ $t('landing.hero.title1') }}<br>
<span class="text-puro-cyan">{{ $t('landing.hero.title2') }}</span>
</h1>
<p class="hero-sub">
Claude Pro · ChatGPT Plus · Codex · Gemini 订阅<br>
聚合成统一 API零改动接入 <span class="pill-inline">OpenAI</span> / <span class="pill-inline">Anthropic</span> SDK
{{ $t('landing.hero.sub1') }}<br>
<i18n-t keypath="landing.hero.sub2" tag="span">
<template #openai><span class="pill-inline">OpenAI</span></template>
<template #anthropic><span class="pill-inline">Anthropic</span></template>
</i18n-t>
</p>
<div class="hero-cta">
<router-link to="/login" class="btn btn-primary btn-lg">登录 </router-link>
<a href="mailto:admin@puro.im" class="btn btn-ghost btn-lg">联系咨询</a>
<router-link to="/login" class="btn btn-primary btn-lg">{{ $t('landing.hero.ctaLogin') }}</router-link>
<a href="mailto:admin@puro.im" class="btn btn-ghost btn-lg">{{ $t('landing.hero.ctaContact') }}</a>
</div>
<div class="hero-micro">
已验证可用 Codex CLI · Claude Code · curl · 服务器出口新加坡
{{ $t('landing.hero.micro') }}
</div>
</section>
<!-- 模型墙 -->
<section class="block container" id="models">
<div class="section-header">
<div class="section-kicker">// providers</div>
<h2 class="section-title">通过 OAuth 直接复用你的订阅</h2>
<p class="section-sub">无需申请官方 API key也无需切换账号</p>
<div class="section-kicker">{{ $t('landing.models.kicker') }}</div>
<h2 class="section-title">{{ $t('landing.models.title') }}</h2>
<p class="section-sub">{{ $t('landing.models.sub') }}</p>
</div>
<div class="model-wall">
<div class="model-card">
@@ -100,8 +103,8 @@
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="#94a3b8" stroke-width="1.6" stroke-linecap="round"><circle cx="5" cy="12" r="1.5" fill="#94a3b8"/><circle cx="12" cy="12" r="1.5" fill="#94a3b8"/><circle cx="19" cy="12" r="1.5" fill="#94a3b8"/></svg>
</div>
<div>
<div class="model-name">更多</div>
<div class="model-meta">规划中</div>
<div class="model-name">{{ $t('landing.models.more') }}</div>
<div class="model-meta">{{ $t('landing.models.morePlanned') }}</div>
</div>
</div>
</div>
@@ -110,39 +113,43 @@
<!-- 三特性 -->
<section class="block container" id="features">
<div class="section-header">
<div class="section-kicker">// capabilities</div>
<h2 class="section-title">付一次订阅<br>用起一整个模型池</h2>
<p class="section-sub">把散落在各个平台的订阅整合成开发者真正能用的基础设施</p>
<div class="section-kicker">{{ $t('landing.features.kicker') }}</div>
<h2 class="section-title">{{ $t('landing.features.title1') }}<br>{{ $t('landing.features.title2') }}</h2>
<p class="section-sub">{{ $t('landing.features.sub') }}</p>
</div>
<div class="features">
<div class="feature">
<div class="feature-icon"></div>
<h3>一个 key 接所有模型</h3>
<p>不再为每个 provider 申请 API key配置 base_url统一 <code class="mono">sk-</code> Claude / GPT / Gemini model 自动路由到对应账号池</p>
<h3>{{ $t('landing.features.f1Title') }}</h3>
<p>
<i18n-t keypath="landing.features.f1Desc" tag="span">
<template #sk><code class="mono">sk-</code></template>
</i18n-t>
</p>
<ul class="feature-bullets">
<li>OpenAI Responses API 兼容</li>
<li>Anthropic Messages API 兼容</li>
<li>智能 model provider 路由</li>
<li>{{ $t('landing.features.f1b1') }}</li>
<li>{{ $t('landing.features.f1b2') }}</li>
<li>{{ $t('landing.features.f1b3') }}</li>
</ul>
</div>
<div class="feature">
<div class="feature-icon">🔄</div>
<h3>账号池高可用</h3>
<p>支持多账号自动调度与 failover某个上游触发限流 / 冷却时流量切到下一个健康账号token 刷新全自动</p>
<h3>{{ $t('landing.features.f2Title') }}</h3>
<p>{{ $t('landing.features.f2Desc') }}</p>
<ul class="feature-bullets">
<li>限流/5xx 自动 failover</li>
<li>OAuth token 自动刷新</li>
<li>加权轮询 · 最少连接</li>
<li>{{ $t('landing.features.f2b1') }}</li>
<li>{{ $t('landing.features.f2b2') }}</li>
<li>{{ $t('landing.features.f2b3') }}</li>
</ul>
</div>
<div class="feature">
<div class="feature-icon">📊</div>
<h3>用量看板</h3>
<p>每条请求的 tokens费用上游账号延迟全可视化模型分布饼图 + 趋势曲线 + Top 排行</p>
<h3>{{ $t('landing.features.f3Title') }}</h3>
<p>{{ $t('landing.features.f3Desc') }}</p>
<ul class="feature-bullets">
<li>逐请求审计日志</li>
<li>多维度 tokens / cost 统计</li>
<li>导出 CSV / Webhook</li>
<li>{{ $t('landing.features.f3b1') }}</li>
<li>{{ $t('landing.features.f3b2') }}</li>
<li>{{ $t('landing.features.f3b3') }}</li>
</ul>
</div>
</div>
@@ -151,9 +158,13 @@
<!-- Code Demo -->
<section class="block container" id="code">
<div class="section-header">
<div class="section-kicker">// integration</div>
<h2 class="section-title"> base_url 一改就能用</h2>
<p class="section-sub">兼容 OpenAI / Anthropic / Gemini SDK<span class="text-puro-cyan">零代码改动</span></p>
<div class="section-kicker">{{ $t('landing.codeDemo.kicker') }}</div>
<h2 class="section-title">{{ $t('landing.codeDemo.title') }}</h2>
<p class="section-sub">
<i18n-t keypath="landing.codeDemo.sub" tag="span">
<template #highlight><span class="text-puro-cyan">{{ $t('landing.codeDemo.subHighlight') }}</span></template>
</i18n-t>
</p>
</div>
<div class="code-demo">
<div class="code-block">
@@ -186,15 +197,15 @@ requires_openai_auth = <span class="kw">true</span></code></pre>
-d <span class="str">'{"model":"gpt-5.4","input":"hello"}'</span></code></pre>
</div>
</div>
<div class="code-foot">支持 OpenAI Responses API · Anthropic Messages API · Gemini generateContent · 流式 SSE &amp; WebSocket</div>
<div class="code-foot">{{ $t('landing.codeDemo.foot') }}</div>
</section>
<!-- Dashboard mockup -->
<section class="block container" id="dashboard">
<div class="section-header">
<div class="section-kicker">// observability</div>
<h2 class="section-title">每条请求都看得见</h2>
<p class="section-sub">不像第三方 API 池子那种"扣了多少不告诉你"扣哪个账号跑哪个模型用了多少 tokens上游响应几秒一目了然</p>
<div class="section-kicker">{{ $t('landing.dashboard.kicker') }}</div>
<h2 class="section-title">{{ $t('landing.dashboard.title') }}</h2>
<p class="section-sub">{{ $t('landing.dashboard.sub') }}</p>
</div>
<div class="dash-mock">
<!-- browser chrome header -->
@@ -225,15 +236,15 @@ requires_openai_auth = <span class="kw">true</span></code></pre>
<!-- main content -->
<div class="dash-main">
<div class="stat-row">
<div class="stat"><div class="stat-label">今日请求</div><div class="stat-value">1,842</div><div class="stat-delta">+12.3%</div></div>
<div class="stat"><div class="stat-label">输入 Tokens</div><div class="stat-value">2.1M</div><div class="stat-delta">+8.1%</div></div>
<div class="stat"><div class="stat-label">输出 Tokens</div><div class="stat-value">485K</div><div class="stat-delta">+15.6%</div></div>
<div class="stat"><div class="stat-label">今日费用</div><div class="stat-value">$1.23</div><div class="stat-delta down">-4.2%</div></div>
<div class="stat"><div class="stat-label">{{ $t('landing.dashboard.statToday') }}</div><div class="stat-value">1,842</div><div class="stat-delta">+12.3%</div></div>
<div class="stat"><div class="stat-label">{{ $t('landing.dashboard.statTokensIn') }}</div><div class="stat-value">2.1M</div><div class="stat-delta">+8.1%</div></div>
<div class="stat"><div class="stat-label">{{ $t('landing.dashboard.statTokensOut') }}</div><div class="stat-value">485K</div><div class="stat-delta">+15.6%</div></div>
<div class="stat"><div class="stat-label">{{ $t('landing.dashboard.statCost') }}</div><div class="stat-value">$1.23</div><div class="stat-delta down">-4.2%</div></div>
</div>
<div class="chart-grid">
<div class="chart-card">
<div class="chart-title">
30 天用量趋势
{{ $t('landing.dashboard.chartTrend') }}
<div class="chart-legend">
<span><span class="sw" style="background: var(--cyan)"></span> Claude</span>
<span><span class="sw" style="background: #a855f7"></span> GPT</span>
@@ -278,7 +289,7 @@ requires_openai_auth = <span class="kw">true</span></code></pre>
</div>
<table class="log-table mono">
<thead>
<tr><th>时间</th><th>模型</th><th>上游</th><th>状态</th><th>用量</th></tr>
<tr><th>{{ $t('landing.dashboard.tableTime') }}</th><th>{{ $t('landing.dashboard.tableModel') }}</th><th>{{ $t('landing.dashboard.tableUpstream') }}</th><th>{{ $t('landing.dashboard.tableStatus') }}</th><th>{{ $t('landing.dashboard.tableUsage') }}</th></tr>
</thead>
<tbody>
<tr><td>12:34:07</td><td>gpt-5.4</td><td><span class="provider gpt"><span class="dot"></span>ChatGPT #1</span></td><td class="status-200">200</td><td>2,341</td></tr>
@@ -302,24 +313,24 @@ requires_openai_auth = <span class="kw">true</span></code></pre>
</svg>
<span>PURO AI</span>
</div>
<p class="footer-tagline">把多个 AI 订阅聚合成统一 API<br>已经付过钱的订阅真正为你工作</p>
<p class="footer-tagline">{{ $t('landing.footer.tagline1') }}<br>{{ $t('landing.footer.tagline2') }}</p>
<p class="footer-meta">© 2026 puro.im · MIT License<br>fork of Wei-Shaw/sub2api</p>
<div class="footer-status"><span class="dot-green"></span>all systems operational</div>
</div>
<div class="footer-col">
<div class="footer-col-title">产品</div>
<a href="/docs">文档</a>
<a href="#features">功能</a>
<a href="https://git.puro.im/purovps/sub2api/commits/branch/main" target="_blank" rel="noopener noreferrer">更新日志</a>
<div class="footer-col-title">{{ $t('landing.footer.colProducts') }}</div>
<a href="/docs">{{ $t('landing.footer.linkDocs') }}</a>
<a href="#features">{{ $t('landing.footer.linkFeatures') }}</a>
<a href="https://git.puro.im/purovps/sub2api/commits/branch/main" target="_blank" rel="noopener noreferrer">{{ $t('landing.footer.linkChangelog') }}</a>
</div>
<div class="footer-col">
<div class="footer-col-title">账户</div>
<router-link to="/login">登录</router-link>
<router-link to="/register">注册</router-link>
<div class="footer-col-title">{{ $t('landing.footer.colAccount') }}</div>
<router-link to="/login">{{ $t('landing.footer.linkLogin') }}</router-link>
<router-link to="/register">{{ $t('landing.footer.linkRegister') }}</router-link>
<a href="/dashboard">Dashboard</a>
</div>
<div class="footer-col">
<div class="footer-col-title">联系</div>
<div class="footer-col-title">{{ $t('landing.footer.colContact') }}</div>
<a href="mailto:admin@puro.im">admin@puro.im</a>
<a href="https://git.puro.im" target="_blank" rel="noopener noreferrer">git.puro.im</a>
<a href="https://git.puro.im/purovps/sub2api" target="_blank" rel="noopener noreferrer">GitHub </a>