Files
sub2api/docs/design-drafts/v2/Binding.html
puro design 3a16b3ecde
Some checks failed
CI / test (push) Has been cancelled
CI / golangci-lint (push) Has been cancelled
Security Scan / backend-security (push) Has been cancelled
Security Scan / frontend-security (push) Has been cancelled
docs: archive Claude Design v2 output [CI SKIP]
10 HTML pages + puro.css + HANDOFF.md + 2 images (~810KB total).
Reference artifacts for Stage 3 Vue 3 translation.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 18:05:27 +08:00

562 lines
21 KiB
HTML

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="color-scheme" content="dark">
<title>绑定订阅 — PURO AI</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<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=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
<link rel="stylesheet" href="puro.css">
<style>
.wrap {
max-width: 840px;
margin: 0 auto;
padding: 48px 24px 80px;
}
.head { text-align: center; margin-bottom: 40px; }
.head h1 { font-size: 34px; font-weight: 700; letter-spacing: -0.02em; margin-bottom: 10px; }
.head p { color: var(--text-2); font-size: 15px; max-width: 560px; margin: 0 auto; line-height: 1.6; }
/* stepper */
.steps {
display: flex; align-items: center; justify-content: center;
gap: 0; margin-bottom: 40px;
}
.step {
display: flex; align-items: center; gap: 10px;
padding: 6px 0;
}
.step .num {
width: 26px; height: 26px; border-radius: 50%;
background: rgba(2, 6, 23, 0.6);
border: 1px solid var(--border);
color: var(--text-3);
display: inline-flex; align-items: center; justify-content: center;
font-family: var(--font-mono); font-size: 12px; font-weight: 600;
}
.step.done .num { background: var(--cyan); color: #042f2e; border-color: var(--cyan); }
.step.active .num { border-color: var(--cyan); color: var(--cyan); background: rgba(34,211,238,0.08); }
.step .label { font-size: 13px; color: var(--text-3); }
.step.done .label, .step.active .label { color: var(--text-0); }
.step-line {
width: 80px; height: 1px; background: var(--border);
margin: 0 14px;
}
.step-line.done { background: var(--cyan); }
/* platform picker */
.platform-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 14px;
margin-bottom: 20px;
}
.platform-card {
padding: 22px 20px;
border: 1px solid var(--border);
border-radius: var(--r-lg);
background: rgba(15, 23, 42, 0.5);
cursor: pointer;
transition: all .15s;
position: relative;
}
.platform-card:hover { border-color: var(--border-2); transform: translateY(-2px); }
.platform-card.selected {
border-color: var(--cyan);
background:
radial-gradient(400px 200px at 50% 0%, rgba(34,211,238,0.1), transparent 60%),
rgba(15, 23, 42, 0.8);
}
.platform-card.selected::after {
content: "✓"; position: absolute; top: 12px; right: 12px;
width: 20px; height: 20px; border-radius: 50%;
background: var(--cyan); color: #042f2e;
display: inline-flex; align-items: center; justify-content: center;
font-size: 12px; font-weight: 700;
}
.platform-logo {
width: 40px; height: 40px;
border-radius: 8px;
display: flex; align-items: center; justify-content: center;
margin-bottom: 14px;
}
.platform-logo.claude { background: rgba(217, 119, 87, 0.12); }
.platform-logo.gpt { background: rgba(16, 163, 127, 0.12); }
.platform-logo.gemini { background: rgba(66, 133, 244, 0.12); }
.platform-logo.codex { background: rgba(240, 160, 48, 0.12); }
.platform-name {
font-size: 15px; font-weight: 600;
margin-bottom: 4px;
}
.platform-tier {
font-size: 11px; color: var(--text-3);
font-family: var(--font-mono);
margin-bottom: 14px;
}
.platform-tiers {
display: flex; gap: 4px; flex-wrap: wrap;
}
.platform-tiers .pill {
font-size: 10px;
}
/* selected detail panel */
.detail-panel {
border: 1px solid var(--border);
border-radius: var(--r-xl);
background:
radial-gradient(600px 300px at 0% 0%, rgba(34,211,238,0.06), transparent 60%),
rgba(15, 23, 42, 0.4);
overflow: hidden;
}
.detail-head {
padding: 22px 26px;
border-bottom: 1px solid var(--border);
display: flex;
align-items: center;
gap: 14px;
}
.detail-head .platform-logo { margin: 0; }
.detail-head h2 {
font-size: 18px;
font-weight: 600;
letter-spacing: -0.01em;
}
.detail-head .sub {
font-size: 12px;
color: var(--text-3);
font-family: var(--font-mono);
margin-top: 2px;
}
.detail-head .secure-tag {
margin-left: auto;
display: inline-flex; align-items: center; gap: 6px;
padding: 4px 10px;
font-size: 11px; font-family: var(--font-mono);
color: var(--green);
background: rgba(52,211,153,0.08);
border: 1px solid rgba(52,211,153,0.2);
border-radius: 4px;
}
.detail-body { padding: 24px 26px; }
.tier-picker {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 10px;
margin-bottom: 22px;
}
.tier-opt {
padding: 14px 16px;
border: 1px solid var(--border);
border-radius: var(--r-md);
background: rgba(2, 6, 23, 0.4);
cursor: pointer;
position: relative;
transition: all .12s;
}
.tier-opt:hover { border-color: var(--border-2); }
.tier-opt.selected {
border-color: var(--cyan);
background: rgba(34,211,238,0.05);
}
.tier-opt .t-name { font-size: 13px; font-weight: 600; margin-bottom: 4px; }
.tier-opt .t-price {
font-family: var(--font-mono); font-size: 18px;
font-weight: 700; letter-spacing: -0.02em;
color: var(--cyan); margin-bottom: 4px;
}
.tier-opt .t-price .unit {
font-size: 11px; color: var(--text-3);
font-weight: 500; margin-left: 3px;
}
.tier-opt .t-desc {
font-size: 11px; color: var(--text-3);
}
/* method cards */
.method-section h3 {
font-size: 13px; font-weight: 600;
margin-bottom: 10px;
color: var(--text-1);
}
.method-section h3 .hint {
color: var(--text-3); font-weight: 400;
font-family: var(--font-mono); font-size: 11px;
margin-left: 6px;
}
.method-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 12px;
margin-bottom: 14px;
}
.method-card {
padding: 18px;
border: 1px solid var(--border);
border-radius: var(--r-md);
background: rgba(2, 6, 23, 0.4);
cursor: pointer;
transition: all .12s;
position: relative;
}
.method-card:hover { border-color: var(--border-2); background: rgba(2, 6, 23, 0.6); }
.method-card.selected {
border-color: var(--cyan);
background: rgba(34, 211, 238, 0.04);
}
.method-card.selected::after {
content: ""; position: absolute; top: 12px; right: 12px;
width: 16px; height: 16px; border-radius: 50%;
background: var(--cyan);
background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 24 24' fill='none' stroke='%23042f2e' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'><path d='M5 12l5 5L20 7'/></svg>");
background-repeat: no-repeat; background-position: center;
}
.method-title {
display: flex; align-items: center; gap: 8px;
font-size: 14px; font-weight: 600;
margin-bottom: 6px;
}
.method-title .tag {
font-size: 10px; font-family: var(--font-mono);
padding: 1px 6px; border-radius: 3px;
background: rgba(52,211,153,0.12); color: var(--green);
}
.method-title .tag.beta { background: rgba(251,191,36,0.12); color: var(--amber); }
.method-desc { font-size: 12px; color: var(--text-2); line-height: 1.55; }
.method-steps {
font-family: var(--font-mono); font-size: 11px;
color: var(--text-3); margin-top: 10px;
display: flex; gap: 6px; flex-wrap: wrap;
}
.method-steps span::after {
content: "→"; margin-left: 6px; color: var(--border-2);
}
.method-steps span:last-child::after { display: none; }
/* OAuth preview */
.oauth-preview {
margin-top: 14px;
padding: 18px;
background: rgba(2, 6, 23, 0.5);
border: 1px solid var(--border);
border-radius: var(--r-md);
display: flex; gap: 16px; align-items: center;
}
.oauth-preview .flow {
flex: 1;
display: flex; align-items: center; gap: 10px;
font-family: var(--font-mono); font-size: 12px;
color: var(--text-2);
}
.oauth-preview .flow .arrow {
color: var(--cyan);
}
.oauth-preview .flow .node {
padding: 4px 10px;
background: rgba(255,255,255,0.04);
border: 1px solid var(--border);
border-radius: 4px;
}
.oauth-preview .flow .node.puro { color: var(--cyan); border-color: rgba(34,211,238,0.25); background: rgba(34,211,238,0.06); }
/* actions */
.actions {
display: flex; justify-content: space-between; align-items: center;
margin-top: 26px;
padding-top: 22px;
border-top: 1px dashed var(--border);
}
.actions .left {
font-size: 12px; color: var(--text-3);
display: flex; align-items: center; gap: 8px;
}
.actions .right { display: flex; gap: 10px; }
/* bound summary panel (step 3 preview) */
.bound-list {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 10px;
margin-top: 14px;
}
.bound-item {
display: flex; align-items: center; gap: 10px;
padding: 10px 12px;
background: rgba(2, 6, 23, 0.4);
border: 1px solid var(--border);
border-radius: var(--r-sm);
font-size: 12px;
}
.bound-item .tick {
width: 16px; height: 16px; border-radius: 50%;
background: var(--green);
color: #042f2e;
display: inline-flex; align-items: center; justify-content: center;
font-size: 10px; font-weight: 700;
}
.bound-item .name { flex: 1; color: var(--text-0); }
.bound-item .tag { color: var(--text-3); font-family: var(--font-mono); font-size: 11px; }
/* topbar user menu (minimal) */
.topbar-user {
margin-left: auto;
display: flex; align-items: center; gap: 10px;
}
.user-menu {
display: flex; align-items: center; gap: 8px;
padding: 4px 10px 4px 4px;
border-radius: 100px;
background: rgba(255,255,255,0.03);
border: 1px solid var(--border);
cursor: pointer;
}
.user-menu .name { font-size: 13px; font-weight: 500; }
</style>
</head>
<body>
<div class="bg-glow soft"></div>
<div class="app-shell">
<aside class="app-side">
<a class="brand" href="Landing.html">
<svg class="hex" viewBox="0 0 24 24" fill="none">
<path d="M12 2L21 7V17L12 22L3 17V7L12 2Z" stroke="currentColor" stroke-width="1.8" fill="rgba(34, 211, 238, 0.08)"/>
<path d="M12 7L17 9.5V14.5L12 17L7 14.5V9.5L12 7Z" fill="currentColor"/>
</svg>
PURO
</a>
<div class="side-group">
<div class="side-label">Workspace</div>
<a class="side-item" href="Dashboard.html"><span class="ico"></span>Dashboard</a>
<a class="side-item" href="API Keys.html"><span class="ico"></span>API Keys<span class="count">3</span></a>
<a class="side-item active" href="#"><span class="ico"></span>订阅账号<span class="count">7</span></a>
<a class="side-item" href="#"><span class="ico"></span>调用日志</a>
<a class="side-item" href="#"><span class="ico">$</span>账单 & 充值</a>
</div>
<div class="side-group">
<div class="side-label">Resources</div>
<a class="side-item" href="Docs.html"><span class="ico">📖</span>文档</a>
<a class="side-item" href="Design System.html"><span class="ico"></span>Design System</a>
</div>
</aside>
<div class="app-main">
<header class="app-topbar">
<a href="Dashboard.html" style="color:var(--text-3); display:inline-flex; align-items:center; gap:6px; font-size:13px;">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M19 12H5"/><path d="M12 19l-7-7 7-7"/></svg>
返回 Dashboard
</a>
<div class="topbar-user">
<div class="user-menu"><span class="avatar">Z</span><span class="name">zane</span></div>
</div>
</header>
<div class="app-content">
<div class="wrap">
<div class="head">
<div class="section-kicker">// 绑定订阅 · 3 步完成</div>
<h1>把你已有的 AI 订阅,变成 API</h1>
<p>我们支持 OAuth 授权和 Cookie 托管两种方式接入 Claude / ChatGPT / Gemini。所有凭证使用 AES-256 加密存储,你可以随时一键解绑。</p>
</div>
<!-- stepper -->
<div class="steps">
<div class="step done">
<span class="num"></span>
<span class="label">选择平台</span>
</div>
<div class="step-line done"></div>
<div class="step active">
<span class="num">2</span>
<span class="label">授权绑定</span>
</div>
<div class="step-line"></div>
<div class="step">
<span class="num">3</span>
<span class="label">完成 & 加入池</span>
</div>
</div>
<!-- platform picker -->
<div class="platform-grid">
<div class="platform-card">
<div class="platform-logo claude">
<svg width="22" height="22" viewBox="0 0 24 24" fill="#d97757"><path d="M4.5 19L12 4l7.5 15H16l-4-8.5L8 19H4.5z"/></svg>
</div>
<div class="platform-name">Claude</div>
<div class="platform-tier">Anthropic · OAuth</div>
<div class="platform-tiers">
<span class="pill">Pro · $20</span>
<span class="pill">Max · $100</span>
<span class="pill">Team</span>
</div>
</div>
<div class="platform-card selected">
<div class="platform-logo gpt">
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="#10a37f" stroke-width="1.8"><circle cx="12" cy="12" r="9"/><path d="M12 3v18M3 12h18"/></svg>
</div>
<div class="platform-name">ChatGPT</div>
<div class="platform-tier">OpenAI · OAuth + Cookie</div>
<div class="platform-tiers">
<span class="pill">Plus · $20</span>
<span class="pill">Pro · $200</span>
<span class="pill">Team</span>
</div>
</div>
<div class="platform-card">
<div class="platform-logo gemini">
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="#4285f4" stroke-width="1.8"><path d="M12 2 L15 9 L22 10 L17 15 L19 22 L12 18 L5 22 L7 15 L2 10 L9 9 Z"/></svg>
</div>
<div class="platform-name">Gemini</div>
<div class="platform-tier">Google · Cookie</div>
<div class="platform-tiers">
<span class="pill">Advanced · $20</span>
<span class="pill">Workspace</span>
</div>
</div>
</div>
<!-- detail panel for selected platform (ChatGPT) -->
<div class="detail-panel">
<div class="detail-head">
<div class="platform-logo gpt">
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="#10a37f" stroke-width="1.8"><circle cx="12" cy="12" r="9"/><path d="M12 3v18M3 12h18"/></svg>
</div>
<div>
<h2>绑定 ChatGPT 账号</h2>
<div class="sub">支持 Plus / Pro / Team · 接入后可用 gpt-5 / gpt-5-codex / gpt-4.1</div>
</div>
<span class="secure-tag">
<svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="18" height="11" x="3" y="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>
AES-256 加密存储
</span>
</div>
<div class="detail-body">
<!-- tier picker -->
<div class="ds-label" style="font-family:var(--font-mono); font-size:11px; color:var(--text-3); text-transform:uppercase; letter-spacing:0.14em; margin-bottom:10px;">
订阅档位
</div>
<div class="tier-picker">
<div class="tier-opt">
<div class="t-name">Plus</div>
<div class="t-price">$20<span class="unit">/月</span></div>
<div class="t-desc">~500k tokens · 约值 $0.08/k</div>
</div>
<div class="tier-opt selected">
<div class="t-name">Pro</div>
<div class="t-price">$200<span class="unit">/月</span></div>
<div class="t-desc">~5M tokens · 约值 $0.04/k</div>
</div>
<div class="tier-opt">
<div class="t-name">Team</div>
<div class="t-price">$30<span class="unit">/user</span></div>
<div class="t-desc">按席位池化,稳定性更高</div>
</div>
</div>
<!-- methods -->
<div class="method-section">
<h3>绑定方式 <span class="hint">选择一种即可 · 可以在绑定后随时更换</span></h3>
<div class="method-grid">
<div class="method-card selected">
<div class="method-title">
OAuth 授权登录
<span class="tag">推荐</span>
</div>
<div class="method-desc">
跳转到 ChatGPT 登录页,登录后自动回跳。不经过我们的密码表单,最接近"官方授权"体验。
</div>
<div class="method-steps">
<span>点击跳转</span>
<span>ChatGPT 登录</span>
<span>授权回调</span>
<span>加入池</span>
</div>
</div>
<div class="method-card">
<div class="method-title">
粘贴 Session Cookie
<span class="tag beta">兼容模式</span>
</div>
<div class="method-desc">
用浏览器扩展一键导出 <code class="mono" style="color:var(--cyan)">__Secure-next-auth.session-token</code> 并粘贴到这里。适合多账号批量绑定。
</div>
<div class="method-steps">
<span>安装扩展</span>
<span>登录 chatgpt.com</span>
<span>导出 cookie</span>
<span>粘贴绑定</span>
</div>
</div>
</div>
<!-- OAuth flow preview -->
<div class="oauth-preview">
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="#22d3ee" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" style="flex-shrink:0">
<rect width="18" height="11" x="3" y="11" rx="2"/>
<path d="M7 11V7a5 5 0 0 1 10 0v4"/>
</svg>
<div class="flow">
<span class="node"></span>
<span class="arrow"></span>
<span class="node puro">PURO</span>
<span class="arrow"></span>
<span class="node">chatgpt.com/oauth</span>
<span class="arrow"></span>
<span class="node puro">PURO</span>
</div>
<div class="mono text-xs text-3">约 15 秒</div>
</div>
</div>
<!-- bound preview (done state, hidden unless step 3) -->
<div class="method-section" style="margin-top:22px">
<h3>本次绑定预览 <span class="hint">授权成功后会自动加入池</span></h3>
<div class="bound-list">
<div class="bound-item">
<span class="tick"></span>
<span class="name">gpt-plus-7</span>
<span class="tag">加入 GPT 池</span>
</div>
<div class="bound-item">
<span class="tick"></span>
<span class="name">gpt-plus-8</span>
<span class="tag">加入 GPT 池</span>
</div>
</div>
</div>
<!-- actions -->
<div class="actions">
<div class="left">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M12 8v4M12 16h.01"/></svg>
凭证仅用于代理请求,不会用于训练或泄露给第三方。
</div>
<div class="right">
<a class="btn btn-ghost" href="Dashboard.html">稍后再说</a>
<button class="btn btn-primary btn-lg">
使用 OAuth 绑定
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M7 17L17 7M7 7h10v10"/></svg>
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>