feat(portal): i18n-ify DocsView + auth narrative panels
Extract all Chinese from DocsView.vue into docs.* namespace and add auth.narrative.* sub-namespace for LoginView/RegisterView narrative slots. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -499,7 +499,39 @@ export default {
|
||||
invalidResetLink: 'Invalid Reset Link',
|
||||
invalidResetLinkHint: 'This password reset link is invalid or has expired. Please request a new one.',
|
||||
requestNewResetLink: 'Request New Reset Link',
|
||||
invalidOrExpiredToken: 'The password reset link is invalid or has expired. Please request a new one.'
|
||||
invalidOrExpiredToken: 'The password reset link is invalid or has expired. Please request a new one.',
|
||||
narrative: {
|
||||
common: {
|
||||
statusLive: 'live',
|
||||
},
|
||||
login: {
|
||||
kicker: '// you already paid for your subscriptions',
|
||||
headlineN: 'N',
|
||||
headlineOne: '1',
|
||||
headlineSep: 'subscriptions →',
|
||||
headlineSuffix: 'key',
|
||||
sub1: 'No more juggling accounts,',
|
||||
sub2: 'no more paying twice for overlapping subscriptions.',
|
||||
tagline: 'PURO — AI calls, back to basics.',
|
||||
},
|
||||
register: {
|
||||
kicker: '// up and running in 5 minutes',
|
||||
headlineN: 'N',
|
||||
headlineOne: '1',
|
||||
headlineSep: 'subscriptions →',
|
||||
headlineSuffix: 'key',
|
||||
sub1: 'No more juggling accounts,',
|
||||
sub2: 'no more paying twice for overlapping subscriptions.',
|
||||
tagline: 'PURO — AI calls, back to basics.',
|
||||
stepsTitle: '// next steps',
|
||||
step1Title: 'Create account',
|
||||
step1Desc: 'Email + password, or LinuxDO OAuth',
|
||||
step2Title: 'Connect subscription',
|
||||
step2Desc: 'OAuth into your existing Claude Pro / ChatGPT Plus',
|
||||
step3Title: 'Get your API key',
|
||||
step3Desc: 'Grab your sk-puro-… and swap the SDK\'s base_url',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
// Dashboard
|
||||
@@ -5680,4 +5712,61 @@ export default {
|
||||
},
|
||||
},
|
||||
|
||||
docs: {
|
||||
nav: {
|
||||
products: 'Product',
|
||||
pricing: 'Pricing',
|
||||
docs: 'Docs',
|
||||
login: 'Sign in',
|
||||
signup: 'Sign up',
|
||||
},
|
||||
hero: {
|
||||
title: 'Quickstart — PURO AI',
|
||||
subtitle: 'Three steps: get a key → set base_url → send a request',
|
||||
},
|
||||
sections: {
|
||||
getKey: {
|
||||
heading: '1. Get your API key',
|
||||
desc: 'PURO AI is currently invite-only. Contact the admin to get access:',
|
||||
note: 'Subscription self-purchase via the iShare portal is coming soon.',
|
||||
},
|
||||
codex: {
|
||||
heading: '2. Codex CLI setup',
|
||||
configIntro: 'Edit ~/.codex/config.toml:',
|
||||
authIntro: 'Then ~/.codex/auth.json:',
|
||||
verifyIntro: 'Verify:',
|
||||
copy: 'Copy',
|
||||
copied: 'Copied',
|
||||
},
|
||||
claudeCode: {
|
||||
heading: '3. Claude Code setup',
|
||||
configIntro: 'Edit ~/.claude/settings.json:',
|
||||
note: 'Claude Code calls the Anthropic-compatible API via the /v1/messages endpoint.',
|
||||
copy: 'Copy',
|
||||
copied: 'Copied',
|
||||
},
|
||||
curl: {
|
||||
heading: '4. curl quick test',
|
||||
openaiIntro: 'OpenAI Responses API:',
|
||||
anthropicIntro: 'Anthropic Messages API:',
|
||||
copy: 'Copy',
|
||||
copied: 'Copied',
|
||||
},
|
||||
models: {
|
||||
heading: '5. Available models',
|
||||
colModel: 'Model',
|
||||
colPlatform: 'Platform / source',
|
||||
colContext: 'Context',
|
||||
colStatus: 'Status',
|
||||
codexDedicated: 'OpenAI Codex dedicated',
|
||||
note: 'Pricing is tracked live from model-price-repo. Full list available in the dashboard after signing in.',
|
||||
noteConsole: 'dashboard',
|
||||
},
|
||||
feedback: {
|
||||
heading: '6. Feedback',
|
||||
desc: 'Run into an issue or want a new platform added:',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
@@ -505,6 +505,38 @@ export default {
|
||||
puroRegisterTitle: '创建账户',
|
||||
puroRegisterSub: '5 分钟开始用 PURO AI',
|
||||
confirmPasswordLabel: '确认密码',
|
||||
narrative: {
|
||||
common: {
|
||||
statusLive: 'live',
|
||||
},
|
||||
login: {
|
||||
kicker: '// 你的订阅,已经付过钱了',
|
||||
headlineN: 'N',
|
||||
headlineOne: '1',
|
||||
headlineSep: '个订阅 →',
|
||||
headlineSuffix: '个 key',
|
||||
sub1: '省去切换账号的繁琐,',
|
||||
sub2: '省去为多个高昂订阅重复买单。',
|
||||
tagline: 'PURO(纯粹)—— 让 AI 调用回归本质。',
|
||||
},
|
||||
register: {
|
||||
kicker: '// 5 分钟开始用',
|
||||
headlineN: 'N',
|
||||
headlineOne: '1',
|
||||
headlineSep: '个订阅 →',
|
||||
headlineSuffix: '个 key',
|
||||
sub1: '省去切换账号的繁琐,',
|
||||
sub2: '省去为多个高昂订阅重复买单。',
|
||||
tagline: 'PURO(纯粹)—— 让 AI 调用回归本质。',
|
||||
stepsTitle: '// 下一步',
|
||||
step1Title: '创建账户',
|
||||
step1Desc: '邮箱 + 密码,或用 LinuxDO OAuth',
|
||||
step2Title: '绑定订阅',
|
||||
step2Desc: 'OAuth 接入你现有的 Claude Pro / ChatGPT Plus',
|
||||
step3Title: '生成 key',
|
||||
step3Desc: '拿到 sk-puro-…,换掉 SDK 的 base_url',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
// Dashboard
|
||||
@@ -5873,4 +5905,61 @@ export default {
|
||||
},
|
||||
},
|
||||
|
||||
docs: {
|
||||
nav: {
|
||||
products: '产品',
|
||||
pricing: '定价',
|
||||
docs: '文档',
|
||||
login: '登录',
|
||||
signup: '注册',
|
||||
},
|
||||
hero: {
|
||||
title: '快速接入 PURO AI',
|
||||
subtitle: '三步走:拿 key → 配 base_url → 发请求',
|
||||
},
|
||||
sections: {
|
||||
getKey: {
|
||||
heading: '1. 获取 API key',
|
||||
desc: '当前 PURO AI 不开放自助注册付费。联系管理员获取:',
|
||||
note: '未来通过 iShare 入口开放订阅购买。',
|
||||
},
|
||||
codex: {
|
||||
heading: '2. Codex CLI 接入',
|
||||
configIntro: '修改 ~/.codex/config.toml:',
|
||||
authIntro: '然后 ~/.codex/auth.json:',
|
||||
verifyIntro: '验证:',
|
||||
copy: '复制',
|
||||
copied: '已复制',
|
||||
},
|
||||
claudeCode: {
|
||||
heading: '3. Claude Code 接入',
|
||||
configIntro: '修改 ~/.claude/settings.json:',
|
||||
note: 'Claude Code 通过 /v1/messages endpoint 调用 Anthropic 兼容 API。',
|
||||
copy: '复制',
|
||||
copied: '已复制',
|
||||
},
|
||||
curl: {
|
||||
heading: '4. curl 直连测试',
|
||||
openaiIntro: 'OpenAI Responses API:',
|
||||
anthropicIntro: 'Anthropic Messages API:',
|
||||
copy: '复制',
|
||||
copied: '已复制',
|
||||
},
|
||||
models: {
|
||||
heading: '5. 支持的模型',
|
||||
colModel: '模型',
|
||||
colPlatform: '平台 / 来源',
|
||||
colContext: '上下文',
|
||||
colStatus: '状态',
|
||||
codexDedicated: 'OpenAI Codex 专用',
|
||||
note: '后端 pricing 表实时跟进 model-price-repo,完整清单登录后在控制台查看。',
|
||||
noteConsole: '控制台',
|
||||
},
|
||||
feedback: {
|
||||
heading: '6. 问题反馈',
|
||||
desc: '遇到问题或希望补接某个平台:',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
@@ -11,15 +11,17 @@
|
||||
</router-link>
|
||||
|
||||
<div>
|
||||
<div class="n-kicker">// 你的订阅,已经付过钱了</div>
|
||||
<div class="n-kicker">{{ t('auth.narrative.login.kicker') }}</div>
|
||||
<div class="auth-narrative-headline" style="margin-top: 12px;">
|
||||
<span class="num-n">N</span> 个订阅<br>
|
||||
→ <span class="num-1">1</span> 个 key
|
||||
<span class="num-n">{{ t('auth.narrative.login.headlineN') }}</span>
|
||||
{{ ' ' + t('auth.narrative.login.headlineSep') + ' ' }}
|
||||
<span class="num-1">{{ t('auth.narrative.login.headlineOne') }}</span>
|
||||
{{ ' ' + t('auth.narrative.login.headlineSuffix') }}
|
||||
</div>
|
||||
<p class="auth-narrative-sub">
|
||||
省去切换账号的繁琐,<br>
|
||||
省去为多个高昂订阅重复买单。<br>
|
||||
<span class="auth-narrative-tagline">PURO(纯粹)—— 让 AI 调用回归本质。</span>
|
||||
{{ t('auth.narrative.login.sub1') }}<br>
|
||||
{{ t('auth.narrative.login.sub2') }}<br>
|
||||
<span class="auth-narrative-tagline">{{ t('auth.narrative.login.tagline') }}</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -11,31 +11,33 @@
|
||||
</router-link>
|
||||
|
||||
<div>
|
||||
<div class="n-kicker">// 5 分钟开始用</div>
|
||||
<div class="n-kicker">{{ t('auth.narrative.register.kicker') }}</div>
|
||||
<div class="auth-narrative-headline" style="margin-top: 12px;">
|
||||
<span class="num-n">N</span> 个订阅<br>
|
||||
→ <span class="num-1">1</span> 个 key
|
||||
<span class="num-n">{{ t('auth.narrative.register.headlineN') }}</span>
|
||||
{{ ' ' + t('auth.narrative.register.headlineSep') + ' ' }}
|
||||
<span class="num-1">{{ t('auth.narrative.register.headlineOne') }}</span>
|
||||
{{ ' ' + t('auth.narrative.register.headlineSuffix') }}
|
||||
</div>
|
||||
<p class="auth-narrative-sub">
|
||||
省去切换账号的繁琐,<br>
|
||||
省去为多个高昂订阅重复买单。<br>
|
||||
<span class="auth-narrative-tagline">PURO(纯粹)—— 让 AI 调用回归本质。</span>
|
||||
{{ t('auth.narrative.register.sub1') }}<br>
|
||||
{{ t('auth.narrative.register.sub2') }}<br>
|
||||
<span class="auth-narrative-tagline">{{ t('auth.narrative.register.tagline') }}</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="steps">
|
||||
<div class="steps-title">// 下一步</div>
|
||||
<div class="steps-title">{{ t('auth.narrative.register.stepsTitle') }}</div>
|
||||
<div class="step active">
|
||||
<div class="step-num">1</div>
|
||||
<div class="step-text"><b>创建账户</b> · 邮箱 + 密码,或用 LinuxDO OAuth</div>
|
||||
<div class="step-text"><b>{{ t('auth.narrative.register.step1Title') }}</b> · {{ t('auth.narrative.register.step1Desc') }}</div>
|
||||
</div>
|
||||
<div class="step">
|
||||
<div class="step-num">2</div>
|
||||
<div class="step-text"><b>绑定订阅</b> · OAuth 接入你现有的 Claude Pro / ChatGPT Plus</div>
|
||||
<div class="step-text"><b>{{ t('auth.narrative.register.step2Title') }}</b> · {{ t('auth.narrative.register.step2Desc') }}</div>
|
||||
</div>
|
||||
<div class="step">
|
||||
<div class="step-num">3</div>
|
||||
<div class="step-text"><b>生成 key</b> · 拿到 <span class="k">sk-puro-…</span>,换掉 SDK 的 <span class="k">base_url</span></div>
|
||||
<div class="step-text"><b>{{ t('auth.narrative.register.step3Title') }}</b> · {{ t('auth.narrative.register.step3Desc') }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -11,36 +11,36 @@
|
||||
<span>PURO AI</span>
|
||||
</router-link>
|
||||
<div class="nav-links">
|
||||
<router-link to="/">产品</router-link>
|
||||
<router-link to="/pricing">定价</router-link>
|
||||
<router-link to="/docs" class="active">文档</router-link>
|
||||
<router-link to="/">{{ $t('docs.nav.products') }}</router-link>
|
||||
<router-link to="/pricing">{{ $t('docs.nav.pricing') }}</router-link>
|
||||
<router-link to="/docs" class="active">{{ $t('docs.nav.docs') }}</router-link>
|
||||
</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('docs.nav.login') }}</router-link>
|
||||
<router-link to="/register" class="btn btn-primary">{{ $t('docs.nav.signup') }}</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<section class="docs-hero container">
|
||||
<h1>快速接入 PURO AI</h1>
|
||||
<p class="subtitle">三步走:拿 key → 配 base_url → 发请求</p>
|
||||
<h1>{{ $t('docs.hero.title') }}</h1>
|
||||
<p class="subtitle">{{ $t('docs.hero.subtitle') }}</p>
|
||||
</section>
|
||||
|
||||
<div class="container docs-body">
|
||||
<section id="get-key" class="docs-section">
|
||||
<h2>1. 获取 API key</h2>
|
||||
<p>当前 PURO AI 不开放自助注册付费。联系管理员获取:</p>
|
||||
<h2>{{ $t('docs.sections.getKey.heading') }}</h2>
|
||||
<p>{{ $t('docs.sections.getKey.desc') }}</p>
|
||||
<div class="callout">
|
||||
<a href="mailto:admin@puro.im">admin@puro.im</a>
|
||||
</div>
|
||||
<p class="note">未来通过 iShare 入口开放订阅购买。</p>
|
||||
<p class="note">{{ $t('docs.sections.getKey.note') }}</p>
|
||||
</section>
|
||||
|
||||
<section id="codex" class="docs-section">
|
||||
<h2>2. Codex CLI 接入</h2>
|
||||
<p>修改 <code class="mono">~/.codex/config.toml</code>:</p>
|
||||
<h2>{{ $t('docs.sections.codex.heading') }}</h2>
|
||||
<p>{{ $t('docs.sections.codex.configIntro') }}</p>
|
||||
<div class="code-panel">
|
||||
<div class="code-head">
|
||||
<div class="traffic">
|
||||
@@ -54,7 +54,7 @@
|
||||
<path d="M4 1.5h5a.5.5 0 0 1 .5.5v1h1V2a1.5 1.5 0 0 0-1.5-1.5H4A1.5 1.5 0 0 0 2.5 2v8A1.5 1.5 0 0 0 4 11.5h1v-1H4a.5.5 0 0 1-.5-.5V2a.5.5 0 0 1 .5-.5z"/>
|
||||
<path d="M7 4.5A1.5 1.5 0 0 1 8.5 3h5A1.5 1.5 0 0 1 15 4.5v9a1.5 1.5 0 0 1-1.5 1.5h-5A1.5 1.5 0 0 1 7 13.5v-9z"/>
|
||||
</svg>
|
||||
复制
|
||||
{{ $t('docs.sections.codex.copy') }}
|
||||
</button>
|
||||
</div>
|
||||
<pre class="mono"><code>model_provider = <span class="str">"OpenAI"</span>
|
||||
@@ -67,7 +67,7 @@ base_url = <span class="str">"https://ai.puro.im"</span>
|
||||
wire_api = <span class="str">"responses"</span>
|
||||
requires_openai_auth = <span class="kw">true</span></code></pre>
|
||||
</div>
|
||||
<p>然后 <code class="mono">~/.codex/auth.json</code>:</p>
|
||||
<p>{{ $t('docs.sections.codex.authIntro') }}</p>
|
||||
<div class="code-panel">
|
||||
<div class="code-head">
|
||||
<div class="traffic">
|
||||
@@ -81,14 +81,14 @@ requires_openai_auth = <span class="kw">true</span></code></pre>
|
||||
<path d="M4 1.5h5a.5.5 0 0 1 .5.5v1h1V2a1.5 1.5 0 0 0-1.5-1.5H4A1.5 1.5 0 0 0 2.5 2v8A1.5 1.5 0 0 0 4 11.5h1v-1H4a.5.5 0 0 1-.5-.5V2a.5.5 0 0 1 .5-.5z"/>
|
||||
<path d="M7 4.5A1.5 1.5 0 0 1 8.5 3h5A1.5 1.5 0 0 1 15 4.5v9a1.5 1.5 0 0 1-1.5 1.5h-5A1.5 1.5 0 0 1 7 13.5v-9z"/>
|
||||
</svg>
|
||||
复制
|
||||
{{ $t('docs.sections.codex.copy') }}
|
||||
</button>
|
||||
</div>
|
||||
<pre class="mono"><code>{
|
||||
<span class="str">"OPENAI_API_KEY"</span>: <span class="str">"sk-xxxxxxxxxxxxxxxx"</span>
|
||||
}</code></pre>
|
||||
</div>
|
||||
<p>验证:</p>
|
||||
<p>{{ $t('docs.sections.codex.verifyIntro') }}</p>
|
||||
<div class="code-panel">
|
||||
<div class="code-head">
|
||||
<div class="traffic">
|
||||
@@ -102,7 +102,7 @@ requires_openai_auth = <span class="kw">true</span></code></pre>
|
||||
<path d="M4 1.5h5a.5.5 0 0 1 .5.5v1h1V2a1.5 1.5 0 0 0-1.5-1.5H4A1.5 1.5 0 0 0 2.5 2v8A1.5 1.5 0 0 0 4 11.5h1v-1H4a.5.5 0 0 1-.5-.5V2a.5.5 0 0 1 .5-.5z"/>
|
||||
<path d="M7 4.5A1.5 1.5 0 0 1 8.5 3h5A1.5 1.5 0 0 1 15 4.5v9a1.5 1.5 0 0 1-1.5 1.5h-5A1.5 1.5 0 0 1 7 13.5v-9z"/>
|
||||
</svg>
|
||||
复制
|
||||
{{ $t('docs.sections.codex.copy') }}
|
||||
</button>
|
||||
</div>
|
||||
<pre class="mono"><code><span class="cm">$</span> codex exec --sandbox read-only <span class="str">"say hi"</span></code></pre>
|
||||
@@ -110,8 +110,8 @@ requires_openai_auth = <span class="kw">true</span></code></pre>
|
||||
</section>
|
||||
|
||||
<section id="claude-code" class="docs-section">
|
||||
<h2>3. Claude Code 接入</h2>
|
||||
<p>修改 <code class="mono">~/.claude/settings.json</code>:</p>
|
||||
<h2>{{ $t('docs.sections.claudeCode.heading') }}</h2>
|
||||
<p>{{ $t('docs.sections.claudeCode.configIntro') }}</p>
|
||||
<div class="code-panel">
|
||||
<div class="code-head">
|
||||
<div class="traffic">
|
||||
@@ -125,7 +125,7 @@ requires_openai_auth = <span class="kw">true</span></code></pre>
|
||||
<path d="M4 1.5h5a.5.5 0 0 1 .5.5v1h1V2a1.5 1.5 0 0 0-1.5-1.5H4A1.5 1.5 0 0 0 2.5 2v8A1.5 1.5 0 0 0 4 11.5h1v-1H4a.5.5 0 0 1-.5-.5V2a.5.5 0 0 1 .5-.5z"/>
|
||||
<path d="M7 4.5A1.5 1.5 0 0 1 8.5 3h5A1.5 1.5 0 0 1 15 4.5v9a1.5 1.5 0 0 1-1.5 1.5h-5A1.5 1.5 0 0 1 7 13.5v-9z"/>
|
||||
</svg>
|
||||
复制
|
||||
{{ $t('docs.sections.claudeCode.copy') }}
|
||||
</button>
|
||||
</div>
|
||||
<pre class="mono"><code>{
|
||||
@@ -133,12 +133,12 @@ requires_openai_auth = <span class="kw">true</span></code></pre>
|
||||
<span class="str">"api_key"</span>: <span class="str">"sk-xxxxxxxxxxxxxxxx"</span>
|
||||
}</code></pre>
|
||||
</div>
|
||||
<p class="note">Claude Code 通过 <code class="mono">/v1/messages</code> endpoint 调用 Anthropic 兼容 API。</p>
|
||||
<p class="note">{{ $t('docs.sections.claudeCode.note') }}</p>
|
||||
</section>
|
||||
|
||||
<section id="curl" class="docs-section">
|
||||
<h2>4. curl 直连测试</h2>
|
||||
<p>OpenAI Responses API:</p>
|
||||
<h2>{{ $t('docs.sections.curl.heading') }}</h2>
|
||||
<p>{{ $t('docs.sections.curl.openaiIntro') }}</p>
|
||||
<div class="code-panel">
|
||||
<div class="code-head">
|
||||
<div class="traffic">
|
||||
@@ -152,7 +152,7 @@ requires_openai_auth = <span class="kw">true</span></code></pre>
|
||||
<path d="M4 1.5h5a.5.5 0 0 1 .5.5v1h1V2a1.5 1.5 0 0 0-1.5-1.5H4A1.5 1.5 0 0 0 2.5 2v8A1.5 1.5 0 0 0 4 11.5h1v-1H4a.5.5 0 0 1-.5-.5V2a.5.5 0 0 1 .5-.5z"/>
|
||||
<path d="M7 4.5A1.5 1.5 0 0 1 8.5 3h5A1.5 1.5 0 0 1 15 4.5v9a1.5 1.5 0 0 1-1.5 1.5h-5A1.5 1.5 0 0 1 7 13.5v-9z"/>
|
||||
</svg>
|
||||
复制
|
||||
{{ $t('docs.sections.curl.copy') }}
|
||||
</button>
|
||||
</div>
|
||||
<pre class="mono"><code><span class="cm">$</span> curl https://ai.puro.im/responses \
|
||||
@@ -160,7 +160,7 @@ requires_openai_auth = <span class="kw">true</span></code></pre>
|
||||
-H <span class="str">"Content-Type: application/json"</span> \
|
||||
-d <span class="str">'{"model":"gpt-5.4","input":"hello"}'</span></code></pre>
|
||||
</div>
|
||||
<p>Anthropic Messages API:</p>
|
||||
<p>{{ $t('docs.sections.curl.anthropicIntro') }}</p>
|
||||
<div class="code-panel">
|
||||
<div class="code-head">
|
||||
<div class="traffic">
|
||||
@@ -174,7 +174,7 @@ requires_openai_auth = <span class="kw">true</span></code></pre>
|
||||
<path d="M4 1.5h5a.5.5 0 0 1 .5.5v1h1V2a1.5 1.5 0 0 0-1.5-1.5H4A1.5 1.5 0 0 0 2.5 2v8A1.5 1.5 0 0 0 4 11.5h1v-1H4a.5.5 0 0 1-.5-.5V2a.5.5 0 0 1 .5-.5z"/>
|
||||
<path d="M7 4.5A1.5 1.5 0 0 1 8.5 3h5A1.5 1.5 0 0 1 15 4.5v9a1.5 1.5 0 0 1-1.5 1.5h-5A1.5 1.5 0 0 1 7 13.5v-9z"/>
|
||||
</svg>
|
||||
复制
|
||||
{{ $t('docs.sections.curl.copy') }}
|
||||
</button>
|
||||
</div>
|
||||
<pre class="mono"><code><span class="cm">$</span> curl https://ai.puro.im/v1/messages \
|
||||
@@ -186,15 +186,15 @@ requires_openai_auth = <span class="kw">true</span></code></pre>
|
||||
</section>
|
||||
|
||||
<section id="models" class="docs-section">
|
||||
<h2>5. 支持的模型</h2>
|
||||
<h2>{{ $t('docs.sections.models.heading') }}</h2>
|
||||
<div class="table-wrap">
|
||||
<table class="models-table mono">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>模型</th>
|
||||
<th>平台 / 来源</th>
|
||||
<th>上下文</th>
|
||||
<th>状态</th>
|
||||
<th>{{ $t('docs.sections.models.colModel') }}</th>
|
||||
<th>{{ $t('docs.sections.models.colPlatform') }}</th>
|
||||
<th>{{ $t('docs.sections.models.colContext') }}</th>
|
||||
<th>{{ $t('docs.sections.models.colStatus') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@@ -206,7 +206,7 @@ requires_openai_auth = <span class="kw">true</span></code></pre>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>gpt-5.4-codex</code></td>
|
||||
<td><span class="provider gpt"><span class="dot"></span>OpenAI Codex 专用</span></td>
|
||||
<td><span class="provider gpt"><span class="dot"></span>{{ $t('docs.sections.models.codexDedicated') }}</span></td>
|
||||
<td>272K</td>
|
||||
<td><span class="badge-ok">OK</span></td>
|
||||
</tr>
|
||||
@@ -237,12 +237,12 @@ requires_openai_auth = <span class="kw">true</span></code></pre>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<p class="note">后端 pricing 表实时跟进 <code class="mono">model-price-repo</code>,完整清单登录后在 <router-link to="/dashboard">控制台</router-link> 查看。</p>
|
||||
<p class="note">{{ $t('docs.sections.models.note') }}</p>
|
||||
</section>
|
||||
|
||||
<section id="feedback" class="docs-section">
|
||||
<h2>6. 问题反馈</h2>
|
||||
<p>遇到问题或希望补接某个平台:</p>
|
||||
<h2>{{ $t('docs.sections.feedback.heading') }}</h2>
|
||||
<p>{{ $t('docs.sections.feedback.desc') }}</p>
|
||||
<div class="callout">
|
||||
<a href="mailto:admin@puro.im">admin@puro.im</a>
|
||||
</div>
|
||||
@@ -252,8 +252,11 @@ requires_openai_auth = <span class="kw">true</span></code></pre>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import PuroLocaleSwitcher from '@/components/puro/PuroLocaleSwitcher.vue'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
async function copyCode(ev: MouseEvent) {
|
||||
const button = ev.currentTarget as HTMLButtonElement
|
||||
const panel = button.closest('.code-panel')
|
||||
@@ -262,7 +265,7 @@ async function copyCode(ev: MouseEvent) {
|
||||
try {
|
||||
await navigator.clipboard.writeText(codeEl.innerText)
|
||||
const original = button.innerHTML
|
||||
button.innerHTML = '<svg viewBox="0 0 16 16" width="12" height="12" fill="currentColor"><path d="M13.854 3.646a.5.5 0 0 1 0 .708l-7 7a.5.5 0 0 1-.708 0l-3.5-3.5a.5.5 0 1 1 .708-.708L6.5 10.293l6.646-6.647a.5.5 0 0 1 .708 0z"/></svg> 已复制'
|
||||
button.innerHTML = `<svg viewBox="0 0 16 16" width="12" height="12" fill="currentColor"><path d="M13.854 3.646a.5.5 0 0 1 0 .708l-7 7a.5.5 0 0 1-.708 0l-3.5-3.5a.5.5 0 1 1 .708-.708L6.5 10.293l6.646-6.647a.5.5 0 0 1 .708 0z"/></svg> ${t('docs.sections.codex.copied')}`
|
||||
button.classList.add('copied')
|
||||
setTimeout(() => {
|
||||
button.innerHTML = original
|
||||
|
||||
Reference in New Issue
Block a user