feat: 虾盘云上线 - 重写 cloud.html,新增 docs.html 开发文档
- cloud.html: 完整重写,加入余额查询、充值流程、全功能 JS - 导航:暂不可用 → 立即充值,新增余额查询/开发文档导航链接 - docs.html: 新增开发者文档页,含接口说明/代码示例/在线测试 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -33,7 +33,7 @@
|
|||||||
position: fixed; top: 0; left: 0; right: 0; z-index: 100;
|
position: fixed; top: 0; left: 0; right: 0; z-index: 100;
|
||||||
display: flex; align-items: center; justify-content: space-between;
|
display: flex; align-items: center; justify-content: space-between;
|
||||||
padding: 0 40px; height: 58px;
|
padding: 0 40px; height: 58px;
|
||||||
background: rgba(10,10,15,0.85);
|
background: rgba(10,10,15,0.9);
|
||||||
backdrop-filter: blur(12px);
|
backdrop-filter: blur(12px);
|
||||||
border-bottom: 1px solid var(--border);
|
border-bottom: 1px solid var(--border);
|
||||||
}
|
}
|
||||||
@@ -43,7 +43,7 @@
|
|||||||
-webkit-background-clip: text; -webkit-text-fill-color: transparent;
|
-webkit-background-clip: text; -webkit-text-fill-color: transparent;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
.nav-links { display: flex; gap: 28px; align-items: center; }
|
.nav-links { display: flex; gap: 24px; align-items: center; }
|
||||||
.nav-links a {
|
.nav-links a {
|
||||||
color: var(--text-dim); text-decoration: none;
|
color: var(--text-dim); text-decoration: none;
|
||||||
font-size: 14px; transition: color 0.2s;
|
font-size: 14px; transition: color 0.2s;
|
||||||
@@ -52,7 +52,7 @@
|
|||||||
.nav-cta {
|
.nav-cta {
|
||||||
background: linear-gradient(135deg, #ef4444, #dc2626) !important;
|
background: linear-gradient(135deg, #ef4444, #dc2626) !important;
|
||||||
color: white !important;
|
color: white !important;
|
||||||
padding: 8px 20px; border-radius: 8px;
|
padding: 7px 18px; border-radius: 8px;
|
||||||
font-weight: 600; font-size: 14px;
|
font-weight: 600; font-size: 14px;
|
||||||
}
|
}
|
||||||
.nav-cta:hover { transform: translateY(-1px); box-shadow: 0 4px 20px rgba(239,68,68,0.3); }
|
.nav-cta:hover { transform: translateY(-1px); box-shadow: 0 4px 20px rgba(239,68,68,0.3); }
|
||||||
@@ -63,7 +63,7 @@
|
|||||||
display: flex; flex-direction: column;
|
display: flex; flex-direction: column;
|
||||||
align-items: center; justify-content: center;
|
align-items: center; justify-content: center;
|
||||||
text-align: center; padding: 80px 20px 60px;
|
text-align: center; padding: 80px 20px 60px;
|
||||||
background: radial-gradient(ellipse at 50% 0%, rgba(239,68,68,0.15) 0%, transparent 60%);
|
background: radial-gradient(ellipse at 50% 0%, rgba(239,68,68,0.12) 0%, transparent 60%);
|
||||||
}
|
}
|
||||||
.hero-emoji { font-size: 72px; margin-bottom: 20px; }
|
.hero-emoji { font-size: 72px; margin-bottom: 20px; }
|
||||||
.hero h1 {
|
.hero h1 {
|
||||||
@@ -74,17 +74,17 @@
|
|||||||
-webkit-background-clip: text; -webkit-text-fill-color: transparent;
|
-webkit-background-clip: text; -webkit-text-fill-color: transparent;
|
||||||
}
|
}
|
||||||
.hero-sub {
|
.hero-sub {
|
||||||
font-size: clamp(18px, 2.5vw, 26px);
|
font-size: clamp(16px, 2.2vw, 22px);
|
||||||
color: var(--text); font-weight: 600; margin-bottom: 16px;
|
color: var(--text); font-weight: 600; margin-bottom: 14px;
|
||||||
}
|
}
|
||||||
.hero-desc {
|
.hero-desc {
|
||||||
font-size: clamp(14px, 1.8vw, 18px);
|
font-size: clamp(14px, 1.6vw, 17px);
|
||||||
color: var(--text-dim); max-width: 520px; margin: 0 auto 40px;
|
color: var(--text-dim); max-width: 500px; margin: 0 auto 36px;
|
||||||
}
|
}
|
||||||
.hero-cta { display: flex; gap: 16px; flex-wrap: wrap; justify-content: center; }
|
.hero-cta { display: flex; gap: 14px; flex-wrap: wrap; justify-content: center; }
|
||||||
.btn {
|
.btn {
|
||||||
padding: 14px 32px; border-radius: 12px;
|
padding: 13px 30px; border-radius: 12px;
|
||||||
font-size: 16px; font-weight: 600; text-decoration: none;
|
font-size: 15px; font-weight: 600; text-decoration: none;
|
||||||
transition: all 0.2s; display: inline-flex; align-items: center; gap: 8px;
|
transition: all 0.2s; display: inline-flex; align-items: center; gap: 8px;
|
||||||
}
|
}
|
||||||
.btn-primary {
|
.btn-primary {
|
||||||
@@ -99,33 +99,33 @@
|
|||||||
.btn-outline:hover { border-color: var(--accent); background: rgba(239,68,68,0.05); }
|
.btn-outline:hover { border-color: var(--accent); background: rgba(239,68,68,0.05); }
|
||||||
|
|
||||||
.hero-stats {
|
.hero-stats {
|
||||||
display: flex; gap: 48px; margin-top: 64px;
|
display: flex; gap: 48px; margin-top: 56px;
|
||||||
flex-wrap: wrap; justify-content: center;
|
flex-wrap: wrap; justify-content: center;
|
||||||
}
|
}
|
||||||
.stat { text-align: center; }
|
.stat { text-align: center; }
|
||||||
.stat-num {
|
.stat-num {
|
||||||
font-size: 34px; font-weight: 800;
|
font-size: 32px; font-weight: 800;
|
||||||
background: linear-gradient(135deg, #ef4444, #f97316);
|
background: linear-gradient(135deg, #ef4444, #f97316);
|
||||||
-webkit-background-clip: text; -webkit-text-fill-color: transparent;
|
-webkit-background-clip: text; -webkit-text-fill-color: transparent;
|
||||||
}
|
}
|
||||||
.stat-label { font-size: 13px; color: var(--text-dim); margin-top: 2px; }
|
.stat-label { font-size: 12px; color: var(--text-dim); margin-top: 2px; }
|
||||||
|
|
||||||
/* CONFIG DEMO */
|
/* CONFIG DEMO */
|
||||||
.config-demo {
|
.config-demo {
|
||||||
margin-top: 56px; width: 100%; max-width: 560px;
|
margin-top: 48px; width: 100%; max-width: 520px;
|
||||||
background: var(--surface); border: 1px solid var(--border);
|
background: var(--surface); border: 1px solid var(--border);
|
||||||
border-radius: 16px; overflow: hidden; text-align: left;
|
border-radius: 16px; overflow: hidden; text-align: left;
|
||||||
}
|
}
|
||||||
.config-header {
|
.config-header {
|
||||||
display: flex; align-items: center; gap: 8px;
|
display: flex; align-items: center; gap: 8px;
|
||||||
padding: 12px 16px; background: var(--bg);
|
padding: 10px 16px; background: var(--bg);
|
||||||
border-bottom: 1px solid var(--border);
|
border-bottom: 1px solid var(--border);
|
||||||
}
|
}
|
||||||
.dot { width: 12px; height: 12px; border-radius: 50%; }
|
.dot { width: 11px; height: 11px; border-radius: 50%; }
|
||||||
.dot.r{background:#ff5f57} .dot.y{background:#febc2e} .dot.g{background:#28c840}
|
.dot.r{background:#ff5f57} .dot.y{background:#febc2e} .dot.g{background:#28c840}
|
||||||
.config-filename { font-size: 12px; color: var(--text-dim); margin-left: 6px; font-family: monospace; }
|
.config-filename { font-size: 12px; color: var(--text-dim); margin-left: 4px; font-family: monospace; }
|
||||||
.config-demo pre {
|
.config-demo pre {
|
||||||
padding: 20px; font-family: 'Fira Code','Courier New',monospace;
|
padding: 18px 20px; font-family: 'Fira Code','Courier New',monospace;
|
||||||
font-size: 13px; line-height: 1.8;
|
font-size: 13px; line-height: 1.8;
|
||||||
}
|
}
|
||||||
.c-comment { color: #4a5568; }
|
.c-comment { color: #4a5568; }
|
||||||
@@ -134,70 +134,71 @@
|
|||||||
.c-url { color: #63b3ed; }
|
.c-url { color: #63b3ed; }
|
||||||
|
|
||||||
/* SECTION */
|
/* SECTION */
|
||||||
section { padding: 96px 20px; }
|
section { padding: 88px 20px; }
|
||||||
.section-inner { max-width: 1080px; margin: 0 auto; }
|
.section-inner { max-width: 1060px; margin: 0 auto; }
|
||||||
.section-tag {
|
.section-tag {
|
||||||
display: inline-block; font-size: 12px; font-weight: 700;
|
display: inline-block; font-size: 11px; font-weight: 700;
|
||||||
letter-spacing: 2px; text-transform: uppercase;
|
letter-spacing: 2px; text-transform: uppercase;
|
||||||
color: var(--accent); margin-bottom: 12px;
|
color: var(--accent); margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
.section-title {
|
.section-title {
|
||||||
font-size: clamp(28px, 4vw, 48px); font-weight: 800;
|
font-size: clamp(26px, 3.5vw, 44px); font-weight: 800;
|
||||||
letter-spacing: -1.5px; margin-bottom: 14px;
|
letter-spacing: -1.5px; margin-bottom: 12px;
|
||||||
}
|
}
|
||||||
.section-desc { font-size: 17px; color: var(--text-dim); max-width: 500px; }
|
.section-desc { font-size: 16px; color: var(--text-dim); max-width: 480px; }
|
||||||
|
|
||||||
/* MODELS */
|
/* MODELS */
|
||||||
.models-grid {
|
.models-grid {
|
||||||
display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
|
display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
|
||||||
gap: 16px; margin-top: 48px;
|
gap: 16px; margin-top: 44px;
|
||||||
}
|
}
|
||||||
.model-card {
|
.model-card {
|
||||||
background: var(--surface); border: 1px solid var(--border);
|
background: var(--surface); border: 1px solid var(--border);
|
||||||
border-radius: 16px; padding: 28px;
|
border-radius: 16px; padding: 26px;
|
||||||
transition: border-color 0.2s, transform 0.2s;
|
transition: border-color 0.2s, transform 0.2s;
|
||||||
}
|
}
|
||||||
.model-card:hover { border-color: var(--accent); transform: translateY(-3px); }
|
.model-card:hover { border-color: var(--accent); transform: translateY(-3px); }
|
||||||
.model-emoji { font-size: 32px; margin-bottom: 14px; }
|
.model-emoji { font-size: 30px; margin-bottom: 12px; }
|
||||||
.model-name { font-size: 17px; font-weight: 700; margin-bottom: 6px; }
|
.model-name { font-size: 16px; font-weight: 700; margin-bottom: 6px; }
|
||||||
.model-desc { font-size: 13px; color: var(--text-dim); margin-bottom: 20px; line-height: 1.5; }
|
.model-id { font-size: 12px; color: var(--text-dim); font-family: monospace; margin-bottom: 10px; }
|
||||||
|
.model-desc { font-size: 13px; color: var(--text-dim); margin-bottom: 18px; line-height: 1.5; }
|
||||||
.model-price-row { display: flex; align-items: baseline; gap: 4px; }
|
.model-price-row { display: flex; align-items: baseline; gap: 4px; }
|
||||||
.model-price { font-size: 26px; font-weight: 800;
|
.model-price { font-size: 24px; font-weight: 800;
|
||||||
background: linear-gradient(135deg, #ef4444, #f97316);
|
background: linear-gradient(135deg, #ef4444, #f97316);
|
||||||
-webkit-background-clip: text; -webkit-text-fill-color: transparent;
|
-webkit-background-clip: text; -webkit-text-fill-color: transparent;
|
||||||
}
|
}
|
||||||
.model-unit { font-size: 12px; color: var(--text-dim); }
|
.model-unit { font-size: 12px; color: var(--text-dim); }
|
||||||
.model-badge {
|
.model-badge {
|
||||||
display: inline-block; margin-top: 12px;
|
display: inline-block; margin-top: 10px;
|
||||||
font-size: 11px; font-weight: 700; padding: 3px 10px; border-radius: 6px;
|
font-size: 11px; font-weight: 700; padding: 3px 10px; border-radius: 6px;
|
||||||
}
|
}
|
||||||
.badge-hot { background: rgba(239,68,68,0.15); color: var(--accent); }
|
.badge-hot { background: rgba(239,68,68,0.15); color: var(--accent); }
|
||||||
.badge-fast { background: rgba(34,197,94,0.15); color: var(--green); }
|
.badge-fast { background: rgba(34,197,94,0.15); color: var(--green); }
|
||||||
.badge-think { background: rgba(168,85,247,0.15); color: var(--purple); }
|
.badge-think { background: rgba(168,85,247,0.15); color: var(--purple); }
|
||||||
|
|
||||||
/* HOW */
|
/* STEPS */
|
||||||
.steps {
|
.steps {
|
||||||
display: grid; grid-template-columns: repeat(auto-fit, minmax(220px,1fr));
|
display: grid; grid-template-columns: repeat(auto-fit, minmax(200px,1fr));
|
||||||
gap: 36px; margin-top: 52px;
|
gap: 32px; margin-top: 48px;
|
||||||
}
|
}
|
||||||
.step-num {
|
.step-num {
|
||||||
width: 48px; height: 48px; border-radius: 14px;
|
width: 44px; height: 44px; border-radius: 12px;
|
||||||
display: flex; align-items: center; justify-content: center;
|
display: flex; align-items: center; justify-content: center;
|
||||||
font-size: 20px; font-weight: 800;
|
font-size: 18px; font-weight: 800;
|
||||||
background: rgba(239,68,68,0.1); border: 1px solid rgba(239,68,68,0.25);
|
background: rgba(239,68,68,0.1); border: 1px solid rgba(239,68,68,0.25);
|
||||||
color: var(--accent); margin-bottom: 18px;
|
color: var(--accent); margin-bottom: 16px;
|
||||||
}
|
}
|
||||||
.step h3 { font-size: 17px; font-weight: 700; margin-bottom: 8px; }
|
.step h3 { font-size: 16px; font-weight: 700; margin-bottom: 8px; }
|
||||||
.step p { font-size: 14px; color: var(--text-dim); line-height: 1.6; }
|
.step p { font-size: 14px; color: var(--text-dim); line-height: 1.6; }
|
||||||
|
|
||||||
/* PRICING */
|
/* PRICING */
|
||||||
.pricing-grid {
|
.pricing-grid {
|
||||||
display: grid; grid-template-columns: repeat(auto-fit, minmax(270px,1fr));
|
display: grid; grid-template-columns: repeat(auto-fit, minmax(260px,1fr));
|
||||||
gap: 20px; margin-top: 52px;
|
gap: 20px; margin-top: 48px;
|
||||||
}
|
}
|
||||||
.plan {
|
.plan {
|
||||||
background: var(--surface); border: 1px solid var(--border);
|
background: var(--surface); border: 1px solid var(--border);
|
||||||
border-radius: 20px; padding: 36px; position: relative;
|
border-radius: 20px; padding: 34px; position: relative;
|
||||||
transition: transform 0.2s;
|
transition: transform 0.2s;
|
||||||
}
|
}
|
||||||
.plan:hover { transform: translateY(-4px); }
|
.plan:hover { transform: translateY(-4px); }
|
||||||
@@ -208,16 +209,16 @@
|
|||||||
color: #fff; font-size: 11px; font-weight: 700;
|
color: #fff; font-size: 11px; font-weight: 700;
|
||||||
padding: 4px 16px; border-radius: 20px; white-space: nowrap;
|
padding: 4px 16px; border-radius: 20px; white-space: nowrap;
|
||||||
}
|
}
|
||||||
.plan-label { font-size: 13px; font-weight: 600; color: var(--text-dim); margin-bottom: 10px; }
|
.plan-label { font-size: 13px; font-weight: 600; color: var(--text-dim); margin-bottom: 8px; }
|
||||||
.plan-price-row { display: flex; align-items: flex-end; gap: 4px; margin-bottom: 6px; }
|
.plan-price-row { display: flex; align-items: flex-end; gap: 4px; margin-bottom: 6px; }
|
||||||
.plan-price {
|
.plan-price {
|
||||||
font-size: 48px; font-weight: 800; letter-spacing: -2px; line-height: 1;
|
font-size: 46px; font-weight: 800; letter-spacing: -2px; line-height: 1;
|
||||||
background: linear-gradient(135deg, #ef4444, #f97316);
|
background: linear-gradient(135deg, #ef4444, #f97316);
|
||||||
-webkit-background-clip: text; -webkit-text-fill-color: transparent;
|
-webkit-background-clip: text; -webkit-text-fill-color: transparent;
|
||||||
}
|
}
|
||||||
.plan-price-unit { font-size: 16px; color: var(--text-dim); margin-bottom: 6px; }
|
.plan-price-unit { font-size: 15px; color: var(--text-dim); margin-bottom: 5px; }
|
||||||
.plan-desc { font-size: 14px; color: var(--text-dim); margin-bottom: 28px; }
|
.plan-desc { font-size: 13px; color: var(--text-dim); margin-bottom: 24px; }
|
||||||
.plan-features { list-style: none; display: flex; flex-direction: column; gap: 11px; margin-bottom: 28px; }
|
.plan-features { list-style: none; display: flex; flex-direction: column; gap: 10px; margin-bottom: 24px; }
|
||||||
.plan-features li { font-size: 14px; display: flex; align-items: center; gap: 10px; }
|
.plan-features li { font-size: 14px; display: flex; align-items: center; gap: 10px; }
|
||||||
.plan-features li::before {
|
.plan-features li::before {
|
||||||
content: ''; width: 18px; height: 18px; flex-shrink: 0; border-radius: 50%;
|
content: ''; width: 18px; height: 18px; flex-shrink: 0; border-radius: 50%;
|
||||||
@@ -227,13 +228,141 @@
|
|||||||
}
|
}
|
||||||
.btn-plan {
|
.btn-plan {
|
||||||
display: block; text-align: center; text-decoration: none;
|
display: block; text-align: center; text-decoration: none;
|
||||||
padding: 13px; border-radius: 10px; font-size: 15px; font-weight: 600; transition: all 0.2s;
|
padding: 12px; border-radius: 10px; font-size: 14px; font-weight: 600; transition: all 0.2s;
|
||||||
}
|
}
|
||||||
.btn-plan-outline { border: 1px solid var(--border); color: var(--text); }
|
.btn-plan-outline { border: 1px solid var(--border); color: var(--text); }
|
||||||
.btn-plan-outline:hover { border-color: var(--accent); color: var(--accent); }
|
.btn-plan-outline:hover { border-color: var(--accent); color: var(--accent); }
|
||||||
.btn-plan-filled { background: linear-gradient(135deg, #ef4444, #dc2626); color: #fff; }
|
.btn-plan-filled { background: linear-gradient(135deg, #ef4444, #dc2626); color: #fff; }
|
||||||
.btn-plan-filled:hover { box-shadow: 0 6px 24px rgba(239,68,68,0.35); transform: translateY(-1px); }
|
.btn-plan-filled:hover { box-shadow: 0 6px 24px rgba(239,68,68,0.35); transform: translateY(-1px); }
|
||||||
|
|
||||||
|
/* BALANCE QUERY */
|
||||||
|
.balance-card {
|
||||||
|
max-width: 620px; margin: 48px auto 0;
|
||||||
|
background: var(--surface); border: 1px solid var(--border);
|
||||||
|
border-radius: 20px; padding: 32px;
|
||||||
|
}
|
||||||
|
.bal-input-row { display: flex; gap: 8px; margin-bottom: 16px; }
|
||||||
|
.bal-input {
|
||||||
|
flex: 1; background: var(--bg); border: 1px solid var(--border);
|
||||||
|
border-radius: 10px; padding: 12px 14px;
|
||||||
|
font-size: 13px; font-family: 'Fira Code','Courier New',monospace;
|
||||||
|
color: var(--text); outline: none; transition: border-color 0.2s;
|
||||||
|
}
|
||||||
|
.bal-input:focus { border-color: var(--accent); }
|
||||||
|
.bal-input::placeholder { color: var(--text-dim); }
|
||||||
|
.btn-query {
|
||||||
|
background: linear-gradient(135deg,#ef4444,#dc2626);
|
||||||
|
color: #fff; border: none; border-radius: 10px;
|
||||||
|
padding: 12px 18px; font-size: 14px; font-weight: 600;
|
||||||
|
cursor: pointer; white-space: nowrap; transition: all 0.2s;
|
||||||
|
}
|
||||||
|
.btn-query:hover { box-shadow: 0 4px 16px rgba(239,68,68,0.35); }
|
||||||
|
.btn-query:disabled { opacity: 0.5; cursor: not-allowed; }
|
||||||
|
.bal-result {
|
||||||
|
display: none; background: var(--bg); border: 1px solid var(--border);
|
||||||
|
border-radius: 14px; padding: 24px; text-align: center;
|
||||||
|
}
|
||||||
|
.bal-result.show { display: block; }
|
||||||
|
.bal-num {
|
||||||
|
font-size: 50px; font-weight: 800; letter-spacing: -2px; line-height: 1;
|
||||||
|
background: linear-gradient(135deg,#22c55e,#16a34a);
|
||||||
|
-webkit-background-clip: text; -webkit-text-fill-color: transparent;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
}
|
||||||
|
.bal-sub { font-size: 13px; color: var(--text-dim); margin-bottom: 16px; }
|
||||||
|
.bal-detail {
|
||||||
|
display: flex; justify-content: center; gap: 32px;
|
||||||
|
flex-wrap: wrap; border-top: 1px solid var(--border); padding-top: 16px;
|
||||||
|
}
|
||||||
|
.bal-detail-item { text-align: center; }
|
||||||
|
.bal-detail-item .val { font-size: 17px; font-weight: 700; color: var(--text); }
|
||||||
|
.bal-detail-item .lbl { font-size: 12px; color: var(--text-dim); margin-top: 2px; }
|
||||||
|
.bal-err { color: var(--accent); font-size: 14px; text-align: center; padding: 12px 0; display: none; }
|
||||||
|
.bal-err.show { display: block; }
|
||||||
|
|
||||||
|
/* RECHARGE */
|
||||||
|
.recharge-box {
|
||||||
|
max-width: 620px; margin: 48px auto 0;
|
||||||
|
background: var(--surface); border: 1px solid var(--border);
|
||||||
|
border-radius: 20px; padding: 36px 32px;
|
||||||
|
}
|
||||||
|
.rs-step { margin-bottom: 28px; }
|
||||||
|
.rs-step:last-child { margin-bottom: 0; }
|
||||||
|
.rs-title {
|
||||||
|
font-size: 15px; font-weight: 700; margin-bottom: 14px;
|
||||||
|
display: flex; align-items: center; gap: 10px;
|
||||||
|
}
|
||||||
|
.rs-num {
|
||||||
|
width: 26px; height: 26px; border-radius: 50%;
|
||||||
|
background: rgba(239,68,68,0.15); border: 1px solid rgba(239,68,68,0.3);
|
||||||
|
color: var(--accent); font-size: 12px; font-weight: 800;
|
||||||
|
display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
|
||||||
|
}
|
||||||
|
.key-row { display: flex; gap: 8px; margin-bottom: 10px; }
|
||||||
|
.key-input {
|
||||||
|
flex: 1; background: var(--bg); border: 1px solid var(--border);
|
||||||
|
border-radius: 10px; padding: 11px 14px;
|
||||||
|
font-size: 13px; font-family: 'Fira Code','Courier New',monospace;
|
||||||
|
color: var(--text); outline: none; transition: border-color 0.2s;
|
||||||
|
}
|
||||||
|
.key-input:focus { border-color: var(--accent); }
|
||||||
|
.key-input::placeholder { color: var(--text-dim); }
|
||||||
|
.btn-gen {
|
||||||
|
background: rgba(239,68,68,0.1); border: 1px solid rgba(239,68,68,0.25);
|
||||||
|
color: var(--accent); border-radius: 10px; padding: 11px 14px;
|
||||||
|
font-size: 13px; font-weight: 600; cursor: pointer; white-space: nowrap;
|
||||||
|
transition: background 0.2s;
|
||||||
|
}
|
||||||
|
.btn-gen:hover { background: rgba(239,68,68,0.18); }
|
||||||
|
.balance-line { font-size: 13px; color: var(--text-dim); min-height: 20px; }
|
||||||
|
.balance-line b { color: var(--green); }
|
||||||
|
.save-tip {
|
||||||
|
display: none; margin-top: 10px;
|
||||||
|
background: rgba(34,197,94,0.08); border: 1px solid rgba(34,197,94,0.25);
|
||||||
|
border-radius: 10px; padding: 10px 14px;
|
||||||
|
font-size: 13px; color: var(--green); line-height: 1.6;
|
||||||
|
}
|
||||||
|
.copy-btn {
|
||||||
|
background: rgba(34,197,94,0.12); border: 1px solid rgba(34,197,94,0.3);
|
||||||
|
color: var(--green); border-radius: 6px; padding: 3px 10px;
|
||||||
|
font-size: 12px; font-weight: 600; cursor: pointer; margin-left: 8px;
|
||||||
|
transition: background 0.2s;
|
||||||
|
}
|
||||||
|
.copy-btn:hover { background: rgba(34,197,94,0.22); }
|
||||||
|
.amount-row { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 14px; }
|
||||||
|
.amt-btn {
|
||||||
|
border: 1px solid var(--border); background: var(--bg);
|
||||||
|
border-radius: 10px; padding: 10px 22px;
|
||||||
|
font-size: 16px; font-weight: 700; cursor: pointer;
|
||||||
|
color: var(--text); transition: all 0.2s;
|
||||||
|
}
|
||||||
|
.amt-btn:hover { border-color: var(--accent); color: var(--accent); }
|
||||||
|
.amt-btn.active {
|
||||||
|
border-color: var(--accent);
|
||||||
|
background: rgba(239,68,68,0.12); color: var(--accent);
|
||||||
|
}
|
||||||
|
.qr-area { display: flex; gap: 20px; align-items: flex-start; }
|
||||||
|
.qr-img {
|
||||||
|
width: 160px; height: auto; border-radius: 12px;
|
||||||
|
border: 1px solid var(--border); object-fit: contain; flex-shrink: 0;
|
||||||
|
}
|
||||||
|
.qr-placeholder {
|
||||||
|
width: 140px; height: 140px; border-radius: 12px;
|
||||||
|
border: 2px dashed var(--border);
|
||||||
|
display: flex; flex-direction: column; align-items: center;
|
||||||
|
justify-content: center; color: var(--text-dim);
|
||||||
|
font-size: 12px; flex-shrink: 0; gap: 6px;
|
||||||
|
}
|
||||||
|
.qr-tips { flex: 1; }
|
||||||
|
.qr-tips p { font-size: 14px; color: var(--text-dim); line-height: 1.7; margin-bottom: 8px; }
|
||||||
|
.hint-key {
|
||||||
|
background: rgba(239,68,68,0.06); border: 1px solid rgba(239,68,68,0.2);
|
||||||
|
border-radius: 10px; padding: 10px 14px;
|
||||||
|
font-size: 13px; font-family: 'Fira Code','Courier New',monospace;
|
||||||
|
color: var(--text); word-break: break-all; line-height: 1.6;
|
||||||
|
}
|
||||||
|
.hint-key em { color: var(--accent); font-style: normal; font-weight: 700; }
|
||||||
|
|
||||||
/* U盘专属 */
|
/* U盘专属 */
|
||||||
.udisk-wrap {
|
.udisk-wrap {
|
||||||
background: var(--surface);
|
background: var(--surface);
|
||||||
@@ -241,20 +370,18 @@
|
|||||||
border-bottom: 1px solid var(--border);
|
border-bottom: 1px solid var(--border);
|
||||||
}
|
}
|
||||||
.udisk-inner {
|
.udisk-inner {
|
||||||
max-width: 1080px; margin: 0 auto;
|
max-width: 1060px; margin: 0 auto;
|
||||||
display: grid; grid-template-columns: 1fr 1fr;
|
display: grid; grid-template-columns: 1fr 1fr;
|
||||||
gap: 64px; align-items: center; padding: 96px 20px;
|
gap: 56px; align-items: center; padding: 88px 20px;
|
||||||
}
|
}
|
||||||
.udisk-inner h2 {
|
.udisk-inner h2 {
|
||||||
font-size: clamp(26px,3.5vw,44px); font-weight: 800;
|
font-size: clamp(24px,3vw,40px); font-weight: 800;
|
||||||
letter-spacing: -1.5px; margin-bottom: 14px;
|
letter-spacing: -1.5px; margin-bottom: 12px;
|
||||||
}
|
|
||||||
.udisk-inner p { color: var(--text-dim); font-size: 16px; margin-bottom: 28px; }
|
|
||||||
.udisk-points { list-style: none; display: flex; flex-direction: column; gap: 14px; }
|
|
||||||
.udisk-points li { font-size: 15px; display: flex; align-items: flex-start; gap: 12px; }
|
|
||||||
.udisk-points li::before {
|
|
||||||
content: '🦞'; font-size: 16px; flex-shrink: 0; margin-top: 1px;
|
|
||||||
}
|
}
|
||||||
|
.udisk-inner p { color: var(--text-dim); font-size: 15px; margin-bottom: 24px; }
|
||||||
|
.udisk-points { list-style: none; display: flex; flex-direction: column; gap: 12px; }
|
||||||
|
.udisk-points li { font-size: 14px; display: flex; align-items: flex-start; gap: 10px; }
|
||||||
|
.udisk-points li::before { content: '🦞'; font-size: 15px; flex-shrink: 0; margin-top: 1px; }
|
||||||
.code-box {
|
.code-box {
|
||||||
background: var(--bg); border: 1px solid var(--border);
|
background: var(--bg); border: 1px solid var(--border);
|
||||||
border-radius: 16px; overflow: hidden;
|
border-radius: 16px; overflow: hidden;
|
||||||
@@ -265,41 +392,40 @@
|
|||||||
display: flex; align-items: center; gap: 8px;
|
display: flex; align-items: center; gap: 8px;
|
||||||
}
|
}
|
||||||
.code-box pre {
|
.code-box pre {
|
||||||
padding: 20px; font-family: 'Fira Code','Courier New',monospace;
|
padding: 18px 20px; font-family: 'Fira Code','Courier New',monospace;
|
||||||
font-size: 13px; line-height: 1.8;
|
font-size: 13px; line-height: 1.8;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FAQ */
|
/* FAQ */
|
||||||
.faq-list { max-width: 700px; margin: 48px auto 0; display: flex; flex-direction: column; gap: 12px; }
|
.faq-list { max-width: 680px; margin: 44px auto 0; display: flex; flex-direction: column; gap: 10px; }
|
||||||
.faq-item {
|
.faq-item {
|
||||||
background: var(--surface); border: 1px solid var(--border);
|
background: var(--surface); border: 1px solid var(--border);
|
||||||
border-radius: 12px; padding: 22px 26px;
|
border-radius: 12px; padding: 20px 24px;
|
||||||
transition: border-color 0.2s;
|
transition: border-color 0.2s;
|
||||||
}
|
}
|
||||||
.faq-item:hover { border-color: rgba(239,68,68,0.3); }
|
.faq-item:hover { border-color: rgba(239,68,68,0.3); }
|
||||||
.faq-q { font-size: 15px; font-weight: 700; margin-bottom: 8px; }
|
.faq-q { font-size: 15px; font-weight: 700; margin-bottom: 6px; }
|
||||||
.faq-a { font-size: 14px; color: var(--text-dim); line-height: 1.6; }
|
.faq-a { font-size: 14px; color: var(--text-dim); line-height: 1.6; }
|
||||||
|
|
||||||
/* CTA */
|
/* CTA */
|
||||||
.cta-wrap {
|
.cta-wrap {
|
||||||
text-align: center; padding: 100px 20px;
|
text-align: center; padding: 96px 20px;
|
||||||
background: radial-gradient(ellipse 60% 80% at 50% 50%, rgba(239,68,68,0.08) 0%, transparent 70%);
|
background: radial-gradient(ellipse 60% 80% at 50% 50%, rgba(239,68,68,0.07) 0%, transparent 70%);
|
||||||
}
|
}
|
||||||
.cta-wrap .hero-emoji { font-size: 56px; margin-bottom: 16px; }
|
|
||||||
.cta-wrap h2 {
|
.cta-wrap h2 {
|
||||||
font-size: clamp(28px,4vw,52px); font-weight: 800;
|
font-size: clamp(26px,4vw,48px); font-weight: 800;
|
||||||
letter-spacing: -2px; margin-bottom: 14px;
|
letter-spacing: -2px; margin-bottom: 12px;
|
||||||
}
|
}
|
||||||
.cta-wrap p { font-size: 18px; color: var(--text-dim); margin-bottom: 36px; }
|
.cta-wrap p { font-size: 17px; color: var(--text-dim); margin-bottom: 32px; }
|
||||||
|
|
||||||
/* FOOTER */
|
/* FOOTER */
|
||||||
footer {
|
footer {
|
||||||
border-top: 1px solid var(--border);
|
border-top: 1px solid var(--border);
|
||||||
padding: 36px 40px;
|
padding: 32px 40px;
|
||||||
display: flex; align-items: center; justify-content: space-between;
|
display: flex; align-items: center; justify-content: space-between;
|
||||||
flex-wrap: wrap; gap: 16px;
|
flex-wrap: wrap; gap: 14px;
|
||||||
}
|
}
|
||||||
.footer-logo { font-size: 16px; font-weight: 800;
|
.footer-logo { font-size: 15px; font-weight: 800;
|
||||||
background: linear-gradient(135deg,#ef4444,#f97316);
|
background: linear-gradient(135deg,#ef4444,#f97316);
|
||||||
-webkit-background-clip:text; -webkit-text-fill-color:transparent;
|
-webkit-background-clip:text; -webkit-text-fill-color:transparent;
|
||||||
}
|
}
|
||||||
@@ -309,10 +435,11 @@
|
|||||||
.footer-copy { font-size: 13px; color: var(--text-dim); }
|
.footer-copy { font-size: 13px; color: var(--text-dim); }
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
nav { padding: 0 20px; }
|
nav { padding: 0 16px; }
|
||||||
.nav-links { display: none; }
|
.nav-links { display: none; }
|
||||||
.udisk-inner { grid-template-columns: 1fr; gap: 32px; }
|
.udisk-inner { grid-template-columns: 1fr; gap: 28px; }
|
||||||
footer { flex-direction: column; align-items: flex-start; }
|
footer { flex-direction: column; align-items: flex-start; }
|
||||||
|
.qr-area { flex-direction: column; }
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
@@ -323,9 +450,11 @@
|
|||||||
<div class="nav-links">
|
<div class="nav-links">
|
||||||
<a href="#models">模型</a>
|
<a href="#models">模型</a>
|
||||||
<a href="#pricing">价格</a>
|
<a href="#pricing">价格</a>
|
||||||
<a href="#howto">接入</a>
|
<a href="#balance">余额查询</a>
|
||||||
|
<a href="#recharge">充值</a>
|
||||||
|
<a href="docs.html">开发文档</a>
|
||||||
<a href="https://u-claw.org">虾盘官网</a>
|
<a href="https://u-claw.org">虾盘官网</a>
|
||||||
<span class="nav-cta" style="opacity:0.5;cursor:not-allowed;">暂不可用</span>
|
<a href="#recharge" class="nav-cta">立即充值</a>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
@@ -336,15 +465,14 @@
|
|||||||
<div class="hero-sub">OpenClaw 官方 AI API 服务</div>
|
<div class="hero-sub">OpenClaw 官方 AI API 服务</div>
|
||||||
<div class="hero-desc">为虾盘 U 盘用户专属打造。接入 DeepSeek、Qwen,按量计费,开箱即用,无需折腾。</div>
|
<div class="hero-desc">为虾盘 U 盘用户专属打造。接入 DeepSeek、Qwen,按量计费,开箱即用,无需折腾。</div>
|
||||||
<div class="hero-cta">
|
<div class="hero-cta">
|
||||||
<span class="btn btn-primary" style="opacity:0.5;cursor:not-allowed;">暂时不可用</span>
|
<a href="#recharge" class="btn btn-primary">立即充值使用 →</a>
|
||||||
<a href="#howto" class="btn btn-outline">查看接入教程</a>
|
<a href="docs.html" class="btn btn-outline">查看开发文档</a>
|
||||||
</div>
|
</div>
|
||||||
<p style="color:#ff6b35;margin-top:8px;font-size:14px;">⚠️ 虾盘云目前暂停服务,敬请期待。</p>
|
|
||||||
|
|
||||||
<div class="hero-stats">
|
<div class="hero-stats">
|
||||||
<div class="stat"><div class="stat-num">¥3</div><div class="stat-label">DeepSeek V3 起</div></div>
|
<div class="stat"><div class="stat-num">¥3</div><div class="stat-label">DeepSeek V3 起</div></div>
|
||||||
<div class="stat"><div class="stat-num">2s</div><div class="stat-label">平均响应时间</div></div>
|
<div class="stat"><div class="stat-num">¥10</div><div class="stat-label">最低充值金额</div></div>
|
||||||
<div class="stat"><div class="stat-num">¥5</div><div class="stat-label">U 盘附赠额度</div></div>
|
<div class="stat"><div class="stat-num">10min</div><div class="stat-label">手动到账时效</div></div>
|
||||||
<div class="stat"><div class="stat-num">5+</div><div class="stat-label">可用模型</div></div>
|
<div class="stat"><div class="stat-num">5+</div><div class="stat-label">可用模型</div></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -357,7 +485,7 @@
|
|||||||
{
|
{
|
||||||
<span class="c-key">"agent"</span>: {
|
<span class="c-key">"agent"</span>: {
|
||||||
<span class="c-key">"model"</span>: <span class="c-str">"deepseek-chat"</span>,
|
<span class="c-key">"model"</span>: <span class="c-str">"deepseek-chat"</span>,
|
||||||
<span class="c-key">"apiKey"</span>: <span class="c-str">"sk-your-key-here"</span>,
|
<span class="c-key">"apiKey"</span>: <span class="c-str">"sk-xp-your-key-here"</span>,
|
||||||
<span class="c-key">"baseUrl"</span>: <span class="c-url">"https://api.u-claw.org/v1"</span>
|
<span class="c-key">"baseUrl"</span>: <span class="c-url">"https://api.u-claw.org/v1"</span>
|
||||||
}
|
}
|
||||||
}</pre>
|
}</pre>
|
||||||
@@ -369,11 +497,12 @@
|
|||||||
<div class="section-inner">
|
<div class="section-inner">
|
||||||
<span class="section-tag">支持模型</span>
|
<span class="section-tag">支持模型</span>
|
||||||
<h2 class="section-title">主流模型,统一接口</h2>
|
<h2 class="section-title">主流模型,统一接口</h2>
|
||||||
<p class="section-desc">OpenAI 兼容格式,切换模型只改一个字段。</p>
|
<p class="section-desc">OpenAI 兼容格式,切换模型只改一个字段,所有工具通用。</p>
|
||||||
<div class="models-grid">
|
<div class="models-grid">
|
||||||
<div class="model-card">
|
<div class="model-card">
|
||||||
<div class="model-emoji">🐋</div>
|
<div class="model-emoji">🐋</div>
|
||||||
<div class="model-name">DeepSeek V3</div>
|
<div class="model-name">DeepSeek V3</div>
|
||||||
|
<div class="model-id">deepseek-chat</div>
|
||||||
<div class="model-desc">日常对话、写作、代码,综合能力最强的主力模型,性价比极高</div>
|
<div class="model-desc">日常对话、写作、代码,综合能力最强的主力模型,性价比极高</div>
|
||||||
<div class="model-price-row">
|
<div class="model-price-row">
|
||||||
<span class="model-price">¥3</span>
|
<span class="model-price">¥3</span>
|
||||||
@@ -384,6 +513,7 @@
|
|||||||
<div class="model-card">
|
<div class="model-card">
|
||||||
<div class="model-emoji">🧠</div>
|
<div class="model-emoji">🧠</div>
|
||||||
<div class="model-name">DeepSeek R1</div>
|
<div class="model-name">DeepSeek R1</div>
|
||||||
|
<div class="model-id">deepseek-reasoner</div>
|
||||||
<div class="model-desc">深度推理模型,复杂逻辑、数学证明、代码调试效果出色</div>
|
<div class="model-desc">深度推理模型,复杂逻辑、数学证明、代码调试效果出色</div>
|
||||||
<div class="model-price-row">
|
<div class="model-price-row">
|
||||||
<span class="model-price">¥12</span>
|
<span class="model-price">¥12</span>
|
||||||
@@ -393,7 +523,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="model-card">
|
<div class="model-card">
|
||||||
<div class="model-emoji">⚡</div>
|
<div class="model-emoji">⚡</div>
|
||||||
<div class="model-name">Qwen-Turbo</div>
|
<div class="model-name">Qwen Turbo</div>
|
||||||
|
<div class="model-id">qwen-turbo</div>
|
||||||
<div class="model-desc">极速响应,适合高频轻量对话,中文表现好</div>
|
<div class="model-desc">极速响应,适合高频轻量对话,中文表现好</div>
|
||||||
<div class="model-price-row">
|
<div class="model-price-row">
|
||||||
<span class="model-price">¥1.8</span>
|
<span class="model-price">¥1.8</span>
|
||||||
@@ -403,7 +534,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="model-card">
|
<div class="model-card">
|
||||||
<div class="model-emoji">🌟</div>
|
<div class="model-emoji">🌟</div>
|
||||||
<div class="model-name">Qwen-Plus</div>
|
<div class="model-name">Qwen Plus</div>
|
||||||
|
<div class="model-id">qwen-plus</div>
|
||||||
<div class="model-desc">长文档理解强,中文语义把握准确,适合写作场景</div>
|
<div class="model-desc">长文档理解强,中文语义把握准确,适合写作场景</div>
|
||||||
<div class="model-price-row">
|
<div class="model-price-row">
|
||||||
<span class="model-price">¥4</span>
|
<span class="model-price">¥4</span>
|
||||||
@@ -424,18 +556,18 @@
|
|||||||
<div class="steps">
|
<div class="steps">
|
||||||
<div class="step">
|
<div class="step">
|
||||||
<div class="step-num">1</div>
|
<div class="step-num">1</div>
|
||||||
<h3>注册账号</h3>
|
<h3>获取 API Key</h3>
|
||||||
<p>访问 api.u-claw.org 注册。有虾盘激活码的直接兑换 ¥5 免费额度,无需充值即可开始。</p>
|
<p>在下方充值区生成或粘贴你的 Key,支付宝扫码充值,备注 Key,10分钟内到账激活。</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="step">
|
<div class="step">
|
||||||
<div class="step-num">2</div>
|
<div class="step-num">2</div>
|
||||||
<h3>创建 API Key</h3>
|
<h3>配置 API 地址</h3>
|
||||||
<p>登录控制台 → 令牌管理 → 新建令牌,复制生成的 Key(格式:sk-xxxx)。</p>
|
<p>Base URL 填 <code style="font-size:12px;color:var(--accent)">https://api.u-claw.org/v1</code>,API Key 填你的 sk-xp- 开头的 Key。</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="step">
|
<div class="step">
|
||||||
<div class="step-num">3</div>
|
<div class="step-num">3</div>
|
||||||
<h3>填入 OpenClaw</h3>
|
<h3>开始使用</h3>
|
||||||
<p>打开 OpenClaw 或 openclaw.json,将 apiKey 填入,baseUrl 填 api.u-claw.org/v1,保存即用。</p>
|
<p>兼容所有 OpenAI 格式工具:OpenClaw、Cherry Studio、Cursor、沉浸式翻译等,直接用。</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -480,64 +612,155 @@
|
|||||||
<p class="section-desc">用多少花多少,没有套路,余额永久有效。</p>
|
<p class="section-desc">用多少花多少,没有套路,余额永久有效。</p>
|
||||||
<div class="pricing-grid">
|
<div class="pricing-grid">
|
||||||
<div class="plan">
|
<div class="plan">
|
||||||
<div class="plan-label">按量充值</div>
|
<div class="plan-label">轻度充值</div>
|
||||||
<div class="plan-price-row">
|
<div class="plan-price-row">
|
||||||
<span class="plan-price">¥10</span>
|
<span class="plan-price">¥10</span>
|
||||||
<span class="plan-price-unit">起充</span>
|
<span class="plan-price-unit">起充</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="plan-desc">适合轻度用户,灵活无压力</div>
|
<div class="plan-desc">适合尝鲜体验,灵活无压力</div>
|
||||||
<ul class="plan-features">
|
<ul class="plan-features">
|
||||||
<li>全模型可用</li>
|
<li>全模型可用</li>
|
||||||
<li>余额永久有效</li>
|
<li>余额永久有效</li>
|
||||||
<li>微信 / 支付宝充值</li>
|
<li>支付宝充值</li>
|
||||||
<li>实时用量统计</li>
|
<li>10分钟内到账</li>
|
||||||
</ul>
|
</ul>
|
||||||
<a href="https://api.u-claw.org/register" class="btn-plan btn-plan-outline">立即注册</a>
|
<a href="#recharge" class="btn-plan btn-plan-outline" onclick="selectAmt(10)">选择此档</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="plan featured">
|
<div class="plan featured">
|
||||||
<div class="plan-top-badge">最受欢迎</div>
|
<div class="plan-top-badge">最受欢迎</div>
|
||||||
<div class="plan-label">月费套餐</div>
|
<div class="plan-label">标准充值</div>
|
||||||
<div class="plan-price-row">
|
<div class="plan-price-row">
|
||||||
<span class="plan-price">¥29</span>
|
<span class="plan-price">¥50</span>
|
||||||
<span class="plan-price-unit">/ 月</span>
|
<span class="plan-price-unit">起充</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="plan-desc">约 500 万 token,日常够用</div>
|
<div class="plan-desc">约 500 万 token,日常够用</div>
|
||||||
<ul class="plan-features">
|
<ul class="plan-features">
|
||||||
<li>500 万 token / 月</li>
|
|
||||||
<li>全模型可用</li>
|
<li>全模型可用</li>
|
||||||
<li>超出后按量计费</li>
|
<li>余额永久有效</li>
|
||||||
<li>优先技术支持</li>
|
<li>支付宝充值</li>
|
||||||
|
<li>10分钟内到账</li>
|
||||||
</ul>
|
</ul>
|
||||||
<a href="https://api.u-claw.org/register" class="btn-plan btn-plan-filled">立即订阅</a>
|
<a href="#recharge" class="btn-plan btn-plan-filled" onclick="selectAmt(50)">选择此档</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="plan">
|
<div class="plan">
|
||||||
<div class="plan-label">U 盘激活码</div>
|
<div class="plan-label">高级充值</div>
|
||||||
<div class="plan-price-row">
|
<div class="plan-price-row">
|
||||||
<span class="plan-price">¥5</span>
|
<span class="plan-price">¥100</span>
|
||||||
<span class="plan-price-unit">随盘附赠</span>
|
<span class="plan-price-unit">起充</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="plan-desc">正版虾盘 U 盘专属福利</div>
|
<div class="plan-desc">约 1000 万 token,重度用户</div>
|
||||||
<ul class="plan-features">
|
<ul class="plan-features">
|
||||||
<li>开箱即有激活码</li>
|
<li>全模型可用</li>
|
||||||
<li>注册后直接兑换</li>
|
<li>余额永久有效</li>
|
||||||
<li>可叠加充值使用</li>
|
<li>支付宝充值</li>
|
||||||
<li>每个 U 盘限一张</li>
|
<li>10分钟内到账</li>
|
||||||
</ul>
|
</ul>
|
||||||
<a href="https://api.u-claw.org/register" class="btn-plan btn-plan-outline">去兑换</a>
|
<a href="#recharge" class="btn-plan btn-plan-outline" onclick="selectAmt(100)">选择此档</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<!-- BALANCE -->
|
||||||
|
<section id="balance" style="border-top: 1px solid var(--border);">
|
||||||
|
<div class="section-inner" style="text-align:center;">
|
||||||
|
<span class="section-tag">余额查询</span>
|
||||||
|
<h2 class="section-title">查询 Key 余额</h2>
|
||||||
|
<p class="section-desc" style="margin:0 auto;">粘贴你的 API Key,实时查询剩余额度</p>
|
||||||
|
<div class="balance-card">
|
||||||
|
<div class="bal-input-row">
|
||||||
|
<input type="text" id="balKey" class="bal-input" placeholder="sk-xp-..." spellcheck="false" autocomplete="off">
|
||||||
|
<button class="btn-query" id="queryBtn" onclick="doQueryBalance()">查询余额</button>
|
||||||
|
</div>
|
||||||
|
<div class="bal-err" id="balErr"></div>
|
||||||
|
<div class="bal-result" id="balResult">
|
||||||
|
<div class="bal-num" id="balNum">¥0.00</div>
|
||||||
|
<div class="bal-sub">当前可用余额(人民币)</div>
|
||||||
|
<div class="bal-detail">
|
||||||
|
<div class="bal-detail-item">
|
||||||
|
<div class="val" id="balTotal">-</div>
|
||||||
|
<div class="lbl">累计充值</div>
|
||||||
|
</div>
|
||||||
|
<div class="bal-detail-item">
|
||||||
|
<div class="val" id="balUsed">-</div>
|
||||||
|
<div class="lbl">已消耗</div>
|
||||||
|
</div>
|
||||||
|
<div class="bal-detail-item">
|
||||||
|
<div class="val" id="balUpdated">-</div>
|
||||||
|
<div class="lbl">查询时间</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- RECHARGE -->
|
||||||
|
<section id="recharge" style="background: var(--surface); border-top: 1px solid var(--border);">
|
||||||
|
<div class="section-inner" style="text-align:center;">
|
||||||
|
<span class="section-tag">充值到账</span>
|
||||||
|
<h2 class="section-title">扫码付款,10 分钟到账</h2>
|
||||||
|
<p class="section-desc" style="margin:0 auto;">无需注册,生成或粘贴 Key,支付宝扫码,备注 Key 即可</p>
|
||||||
|
<div class="recharge-box">
|
||||||
|
|
||||||
|
<!-- Step 1 -->
|
||||||
|
<div class="rs-step">
|
||||||
|
<div class="rs-title"><span class="rs-num">1</span>确认你的 API Key</div>
|
||||||
|
<div class="key-row">
|
||||||
|
<input type="text" id="keyInput" class="key-input" placeholder="粘贴已有 Key,或点右侧自动生成" spellcheck="false" autocomplete="off">
|
||||||
|
<button class="btn-gen" onclick="genKey()">帮我生成一个</button>
|
||||||
|
</div>
|
||||||
|
<div class="balance-line" id="balanceLine">粘贴 Key 后自动查询余额</div>
|
||||||
|
<div class="save-tip" id="saveTip">
|
||||||
|
重要:请复制并保存你的 Key,充值和使用都需要它。<br>
|
||||||
|
<span style="color:var(--text-dim);">虾盘 U 盘用户也可以直接用 U 盘里的 Key。</span>
|
||||||
|
<button class="copy-btn" onclick="copyKey()">复制 Key</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Step 2 -->
|
||||||
|
<div class="rs-step">
|
||||||
|
<div class="rs-title"><span class="rs-num">2</span>选择充值金额</div>
|
||||||
|
<div class="amount-row">
|
||||||
|
<button class="amt-btn" id="amt10" onclick="selectAmt(10)">¥10</button>
|
||||||
|
<button class="amt-btn" id="amt20" onclick="selectAmt(20)">¥20</button>
|
||||||
|
<button class="amt-btn" id="amt50" onclick="selectAmt(50)">¥50</button>
|
||||||
|
<button class="amt-btn" id="amt100" onclick="selectAmt(100)">¥100</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Step 3 -->
|
||||||
|
<div class="rs-step">
|
||||||
|
<div class="rs-title"><span class="rs-num">3</span>支付宝扫码,付款备注你的 Key</div>
|
||||||
|
<div class="qr-area">
|
||||||
|
<img src="alipay-qr.jpg" alt="支付宝收款码" class="qr-img"
|
||||||
|
onerror="this.style.display='none';document.getElementById('qrPh').style.display='flex'">
|
||||||
|
<div class="qr-placeholder" id="qrPh" style="display:none">
|
||||||
|
<div style="font-size:28px">📱</div>
|
||||||
|
<div>支付宝收款码</div>
|
||||||
|
<div>图片待上传</div>
|
||||||
|
</div>
|
||||||
|
<div class="qr-tips">
|
||||||
|
<p>扫码付款后,<strong style="color:var(--text)">务必在付款备注填写你的 Key</strong>,收到后 <strong style="color:var(--accent)">10 分钟内</strong> 手动为你充值到账。</p>
|
||||||
|
<p style="margin-bottom:6px;color:var(--text);">付款备注:</p>
|
||||||
|
<div class="hint-key" id="hintKey"><em>请先在第一步填写或生成你的 Key</em></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
<!-- FAQ -->
|
<!-- FAQ -->
|
||||||
<section style="background: var(--surface); border-top: 1px solid var(--border);">
|
<section style="background: var(--bg); border-top: 1px solid var(--border);">
|
||||||
<div class="section-inner" style="text-align:center;">
|
<div class="section-inner" style="text-align:center;">
|
||||||
<span class="section-tag">常见问题</span>
|
<span class="section-tag">常见问题</span>
|
||||||
<h2 class="section-title">FAQ</h2>
|
<h2 class="section-title">FAQ</h2>
|
||||||
<div class="faq-list">
|
<div class="faq-list">
|
||||||
<div class="faq-item">
|
<div class="faq-item">
|
||||||
<div class="faq-q">虾盘云和直接用 DeepSeek 官方有什么区别?</div>
|
<div class="faq-q">虾盘云和直接用 DeepSeek 官方有什么区别?</div>
|
||||||
<div class="faq-a">虾盘云提供统一入口,人民币充值,多模型一个 Key 搞定,不用单独注册各家账号。对国内用户更友好,配合虾盘 U 盘开箱即用。</div>
|
<div class="faq-a">虾盘云提供统一入口,人民币充值,多模型一个 Key 搞定,不用单独注册各家账号。配合虾盘 U 盘开箱即用,对国内用户更友好。</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="faq-item">
|
<div class="faq-item">
|
||||||
<div class="faq-q">兼容哪些 AI 工具?</div>
|
<div class="faq-q">兼容哪些 AI 工具?</div>
|
||||||
@@ -545,11 +768,15 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="faq-item">
|
<div class="faq-item">
|
||||||
<div class="faq-q">充值余额会过期吗?</div>
|
<div class="faq-q">充值余额会过期吗?</div>
|
||||||
<div class="faq-a">按量充值余额永不过期。月费套餐额度按月重置,未用完不累积。</div>
|
<div class="faq-a">按量充值余额永不过期,用多少扣多少,随时可查余额。</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="faq-item">
|
<div class="faq-item">
|
||||||
<div class="faq-q">激活码可以重复用吗?</div>
|
<div class="faq-q">付款后多久到账?</div>
|
||||||
<div class="faq-a">每个激活码只能用一次,兑换后绑定账号。正版 U 盘每个附赠一张,复制的 U 盘没有激活码。</div>
|
<div class="faq-a">人工处理,工作时间 10 分钟内,非工作时间最长 2 小时。到账后可用余额查询接口验证。</div>
|
||||||
|
</div>
|
||||||
|
<div class="faq-item">
|
||||||
|
<div class="faq-q">Key 格式是什么?可以自己生成吗?</div>
|
||||||
|
<div class="faq-a">格式为 sk-xp- 开头 + 32位随机字符串。点"帮我生成一个"自动生成,也可以粘贴已有的 Key。</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -560,24 +787,24 @@
|
|||||||
<div class="section-inner" style="text-align:center;">
|
<div class="section-inner" style="text-align:center;">
|
||||||
<span class="section-tag">联系我们</span>
|
<span class="section-tag">联系我们</span>
|
||||||
<h2 class="section-title">有问题?找我</h2>
|
<h2 class="section-title">有问题?找我</h2>
|
||||||
<p class="section-desc" style="margin: 0 auto 48px;">余额充值、使用问题、U 盘激活码,直接联系</p>
|
<p class="section-desc" style="margin: 0 auto 44px;">余额充值、使用问题、U 盘激活码,直接联系</p>
|
||||||
<div style="display:flex; flex-wrap:wrap; gap:40px; justify-content:center; align-items:flex-start;">
|
<div style="display:flex; flex-wrap:wrap; gap:40px; justify-content:center; align-items:flex-start;">
|
||||||
<div style="text-align:center;">
|
<div style="text-align:center;">
|
||||||
<img src="wechat-qr.jpg" alt="微信二维码" style="width:180px;height:180px;border-radius:14px;border:1px solid var(--border);">
|
<img src="wechat-qr.jpg" alt="微信二维码" style="width:160px;height:160px;border-radius:14px;border:1px solid var(--border);">
|
||||||
<p style="margin-top:12px;color:var(--text-dim);font-size:14px;">微信扫码添加</p>
|
<p style="margin-top:10px;color:var(--text-dim);font-size:14px;">微信扫码添加</p>
|
||||||
</div>
|
</div>
|
||||||
<div style="text-align:center;">
|
<div style="text-align:center;">
|
||||||
<a href="https://xhslink.com/m/6mf7Mq2M5wP" target="_blank" style="display:flex;flex-direction:column;align-items:center;justify-content:center;width:180px;height:180px;border-radius:14px;background:linear-gradient(135deg,#ff2442,#ff6670);text-decoration:none;">
|
<a href="https://xhslink.com/m/6mf7Mq2M5wP" target="_blank" style="display:flex;flex-direction:column;align-items:center;justify-content:center;width:160px;height:160px;border-radius:14px;background:linear-gradient(135deg,#ff2442,#ff6670);text-decoration:none;">
|
||||||
<span style="font-size:44px;">📕</span>
|
<span style="font-size:40px;">📕</span>
|
||||||
<span style="color:white;font-size:16px;font-weight:700;margin-top:8px;">小红书</span>
|
<span style="color:white;font-size:15px;font-weight:700;margin-top:8px;">小红书</span>
|
||||||
<span style="color:rgba(255,255,255,0.8);font-size:12px;margin-top:4px;">8777+ 赞</span>
|
<span style="color:rgba(255,255,255,0.8);font-size:12px;margin-top:4px;">8777+ 赞</span>
|
||||||
</a>
|
</a>
|
||||||
<p style="margin-top:12px;color:var(--text-dim);font-size:14px;">小红书关注</p>
|
<p style="margin-top:10px;color:var(--text-dim);font-size:14px;">小红书关注</p>
|
||||||
</div>
|
</div>
|
||||||
<div style="text-align:left;display:flex;flex-direction:column;gap:16px;justify-content:center;">
|
<div style="text-align:left;display:flex;flex-direction:column;gap:14px;justify-content:center;">
|
||||||
<p style="font-size:16px;"><span style="color:var(--text-dim);">邮箱:</span><a href="mailto:hefangsheng@gmail.com" style="color:var(--accent);text-decoration:none;">hefangsheng@gmail.com</a></p>
|
<p style="font-size:15px;"><span style="color:var(--text-dim);">邮箱:</span><a href="mailto:hefangsheng@gmail.com" style="color:var(--accent);text-decoration:none;">hefangsheng@gmail.com</a></p>
|
||||||
<p style="font-size:16px;"><span style="color:var(--text-dim);">GitHub:</span><a href="https://github.com/dongsheng123132" style="color:var(--accent);text-decoration:none;">dongsheng123132</a></p>
|
<p style="font-size:15px;"><span style="color:var(--text-dim);">GitHub:</span><a href="https://github.com/dongsheng123132" style="color:var(--accent);text-decoration:none;">dongsheng123132</a></p>
|
||||||
<p style="font-size:16px;"><span style="color:var(--text-dim);">官网:</span><a href="https://u-claw.org" style="color:var(--accent);text-decoration:none;">u-claw.org</a></p>
|
<p style="font-size:15px;"><span style="color:var(--text-dim);">官网:</span><a href="https://u-claw.org" style="color:var(--accent);text-decoration:none;">u-claw.org</a></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -585,21 +812,128 @@
|
|||||||
|
|
||||||
<!-- CTA -->
|
<!-- CTA -->
|
||||||
<div class="cta-wrap">
|
<div class="cta-wrap">
|
||||||
<div class="hero-emoji">🦞</div>
|
<h2>现在就开始用</h2>
|
||||||
<h2>现在开始,免费体验</h2>
|
<p>生成 Key,扫码充值,10 分钟内到账,立刻可用</p>
|
||||||
<p>注册即用,U 盘激活码兑换 ¥5 免费额度</p>
|
<a href="#recharge" class="btn btn-primary" style="font-size:17px;padding:14px 40px;">去充值 →</a>
|
||||||
<a href="https://api.u-claw.org/register" class="btn btn-primary" style="font-size:18px;padding:16px 44px;">免费注册 →</a>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<footer>
|
<footer>
|
||||||
<div class="footer-logo">🦞 虾盘云</div>
|
<div class="footer-logo">🦞 虾盘云</div>
|
||||||
<div class="footer-links">
|
<div class="footer-links">
|
||||||
<a href="https://api.u-claw.org">控制台</a>
|
<a href="https://api.u-claw.org">API 控制台</a>
|
||||||
|
<a href="docs.html">开发文档</a>
|
||||||
<a href="https://u-claw.org">虾盘官网</a>
|
<a href="https://u-claw.org">虾盘官网</a>
|
||||||
<a href="mailto:38004547@qq.com">联系我们</a>
|
<a href="mailto:38004547@qq.com">联系我们</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="footer-copy">© 2026 虾盘云 · api.u-claw.org</div>
|
<div class="footer-copy">© 2026 虾盘云 · api.u-claw.org</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const API_BASE = 'https://api.u-claw.org/v1';
|
||||||
|
|
||||||
|
function genKey() {
|
||||||
|
const hex = Array.from(crypto.getRandomValues(new Uint8Array(16)))
|
||||||
|
.map(b => b.toString(16).padStart(2, '0')).join('');
|
||||||
|
const key = 'sk-xp-' + hex;
|
||||||
|
document.getElementById('keyInput').value = key;
|
||||||
|
updateHint(key);
|
||||||
|
document.getElementById('balanceLine').innerHTML = '<b>已生成新 Key,充值后即可使用。</b>';
|
||||||
|
document.getElementById('saveTip').style.display = 'block';
|
||||||
|
}
|
||||||
|
|
||||||
|
function copyKey() {
|
||||||
|
const key = document.getElementById('keyInput').value.trim();
|
||||||
|
if (!key) return;
|
||||||
|
navigator.clipboard.writeText(key).then(() => {
|
||||||
|
const btn = document.querySelector('.copy-btn');
|
||||||
|
btn.textContent = '已复制 ✓';
|
||||||
|
setTimeout(() => btn.textContent = '复制 Key', 2000);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateHint(key) {
|
||||||
|
const el = document.getElementById('hintKey');
|
||||||
|
if (key && key.startsWith('sk-')) {
|
||||||
|
el.innerHTML = key;
|
||||||
|
} else {
|
||||||
|
el.innerHTML = '<em>请先在第一步填写或生成你的 Key</em>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectAmt(amount) {
|
||||||
|
[10, 20, 50, 100].forEach(a => {
|
||||||
|
const el = document.getElementById('amt' + a);
|
||||||
|
if (el) el.classList.toggle('active', a === amount);
|
||||||
|
});
|
||||||
|
document.getElementById('recharge').scrollIntoView({behavior: 'smooth'});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fetchBalance(key) {
|
||||||
|
const headers = {Authorization: 'Bearer ' + key};
|
||||||
|
const today = new Date().toISOString().slice(0,10);
|
||||||
|
const [subResp, usageResp] = await Promise.all([
|
||||||
|
fetch(API_BASE + '/dashboard/billing/subscription', {headers}),
|
||||||
|
fetch(API_BASE + '/dashboard/billing/usage?start_date=2020-01-01&end_date=' + today, {headers})
|
||||||
|
]);
|
||||||
|
if (!subResp.ok) throw new Error('Key 尚未激活,请先充值并备注此 Key,管理员开通后即可查询。');
|
||||||
|
const sub = await subResp.json();
|
||||||
|
const usage = await usageResp.json();
|
||||||
|
const total = sub.hard_limit_usd || 0;
|
||||||
|
const used = (usage.total_usage || 0) / 100;
|
||||||
|
return { total, used, balance: total - used };
|
||||||
|
}
|
||||||
|
|
||||||
|
async function queryBalance(key) {
|
||||||
|
const line = document.getElementById('balanceLine');
|
||||||
|
line.textContent = '查询中...';
|
||||||
|
try {
|
||||||
|
const {total, used, balance} = await fetchBalance(key);
|
||||||
|
line.innerHTML = '当前余额:<b>¥' + (balance * 7.2).toFixed(2) + '</b>(已用:¥' + (used * 7.2).toFixed(2) + ')';
|
||||||
|
} catch(e) {
|
||||||
|
line.textContent = e.message || '网络错误,无法查询余额';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function doQueryBalance() {
|
||||||
|
const key = document.getElementById('balKey').value.trim();
|
||||||
|
const btn = document.getElementById('queryBtn');
|
||||||
|
const errEl = document.getElementById('balErr');
|
||||||
|
const resEl = document.getElementById('balResult');
|
||||||
|
if (!key || !key.startsWith('sk-')) {
|
||||||
|
errEl.textContent = '请输入有效的 API Key(以 sk- 开头)';
|
||||||
|
errEl.classList.add('show'); resEl.classList.remove('show'); return;
|
||||||
|
}
|
||||||
|
btn.disabled = true; btn.textContent = '查询中...';
|
||||||
|
errEl.classList.remove('show'); resEl.classList.remove('show');
|
||||||
|
try {
|
||||||
|
const {total, used, balance} = await fetchBalance(key);
|
||||||
|
document.getElementById('balNum').textContent = '¥' + (balance * 7.2).toFixed(2);
|
||||||
|
document.getElementById('balTotal').textContent = '¥' + (total * 7.2).toFixed(2);
|
||||||
|
document.getElementById('balUsed').textContent = '¥' + (used * 7.2).toFixed(2);
|
||||||
|
document.getElementById('balUpdated').textContent = new Date().toLocaleTimeString('zh-CN');
|
||||||
|
resEl.classList.add('show');
|
||||||
|
} catch(e) {
|
||||||
|
errEl.textContent = e.message || '网络错误,请稍后重试';
|
||||||
|
errEl.classList.add('show');
|
||||||
|
} finally {
|
||||||
|
btn.disabled = false; btn.textContent = '查询余额';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById('balKey').addEventListener('keydown', function(e) {
|
||||||
|
if (e.key === 'Enter') doQueryBalance();
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById('keyInput').addEventListener('input', function() {
|
||||||
|
const key = this.value.trim();
|
||||||
|
updateHint(key);
|
||||||
|
if (key.length > 10) {
|
||||||
|
clearTimeout(this._t);
|
||||||
|
this._t = setTimeout(() => queryBalance(key), 800);
|
||||||
|
} else {
|
||||||
|
document.getElementById('balanceLine').textContent = '粘贴 Key 后自动查询余额';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
686
website/docs.html
Normal file
686
website/docs.html
Normal file
@@ -0,0 +1,686 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>虾盘云 API 开发文档</title>
|
||||||
|
<meta name="description" content="虾盘云 API 开发文档:接口说明、余额查询、充值流程、模型列表,适合 AI 开发者快速接入。">
|
||||||
|
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>🦞</text></svg>">
|
||||||
|
<style>
|
||||||
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||||
|
:root {
|
||||||
|
--bg: #0a0a0f;
|
||||||
|
--surface: #12121a;
|
||||||
|
--surface2: #16161f;
|
||||||
|
--border: #1e1e2e;
|
||||||
|
--text: #e4e4e7;
|
||||||
|
--text-dim: #71717a;
|
||||||
|
--accent: #ef4444;
|
||||||
|
--green: #22c55e;
|
||||||
|
--blue: #3b82f6;
|
||||||
|
--yellow: #f59e0b;
|
||||||
|
--purple: #a855f7;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
|
||||||
|
background: var(--bg);
|
||||||
|
color: var(--text);
|
||||||
|
line-height: 1.6;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* SIDEBAR */
|
||||||
|
.sidebar {
|
||||||
|
width: 240px; flex-shrink: 0;
|
||||||
|
position: fixed; top: 0; left: 0; bottom: 0;
|
||||||
|
background: var(--surface);
|
||||||
|
border-right: 1px solid var(--border);
|
||||||
|
overflow-y: auto; padding: 0 0 32px;
|
||||||
|
}
|
||||||
|
.sidebar-logo {
|
||||||
|
display: flex; align-items: center; gap: 10px;
|
||||||
|
padding: 18px 20px; border-bottom: 1px solid var(--border);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.sidebar-logo span {
|
||||||
|
font-size: 16px; font-weight: 800;
|
||||||
|
background: linear-gradient(135deg, #ef4444, #f97316);
|
||||||
|
-webkit-background-clip: text; -webkit-text-fill-color: transparent;
|
||||||
|
}
|
||||||
|
.sidebar-back {
|
||||||
|
display: flex; align-items: center; gap: 6px;
|
||||||
|
padding: 10px 20px; font-size: 13px; color: var(--text-dim);
|
||||||
|
text-decoration: none; border-bottom: 1px solid var(--border);
|
||||||
|
transition: color 0.2s;
|
||||||
|
}
|
||||||
|
.sidebar-back:hover { color: var(--text); }
|
||||||
|
.sidebar-section {
|
||||||
|
padding: 20px 20px 6px;
|
||||||
|
font-size: 11px; font-weight: 700; letter-spacing: 1.5px;
|
||||||
|
text-transform: uppercase; color: var(--text-dim);
|
||||||
|
}
|
||||||
|
.sidebar-link {
|
||||||
|
display: block; padding: 7px 20px;
|
||||||
|
font-size: 14px; color: var(--text-dim);
|
||||||
|
text-decoration: none; border-radius: 0;
|
||||||
|
transition: color 0.15s, background 0.15s;
|
||||||
|
border-left: 2px solid transparent;
|
||||||
|
}
|
||||||
|
.sidebar-link:hover { color: var(--text); background: rgba(255,255,255,0.03); }
|
||||||
|
.sidebar-link.active { color: var(--accent); border-left-color: var(--accent); background: rgba(239,68,68,0.05); }
|
||||||
|
|
||||||
|
/* MAIN */
|
||||||
|
.main {
|
||||||
|
margin-left: 240px; flex: 1;
|
||||||
|
max-width: 860px; padding: 48px 56px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* HEADINGS */
|
||||||
|
h1 { font-size: 32px; font-weight: 800; letter-spacing: -1px; margin-bottom: 10px; }
|
||||||
|
h2 {
|
||||||
|
font-size: 22px; font-weight: 700; margin: 52px 0 16px;
|
||||||
|
padding-bottom: 10px; border-bottom: 1px solid var(--border);
|
||||||
|
scroll-margin-top: 32px;
|
||||||
|
}
|
||||||
|
h2:first-of-type { margin-top: 32px; }
|
||||||
|
h3 { font-size: 16px; font-weight: 700; margin: 28px 0 10px; color: var(--text); }
|
||||||
|
p { font-size: 15px; color: var(--text-dim); margin-bottom: 14px; line-height: 1.7; }
|
||||||
|
a { color: var(--accent); text-decoration: none; }
|
||||||
|
a:hover { text-decoration: underline; }
|
||||||
|
|
||||||
|
/* BADGE */
|
||||||
|
.page-badge {
|
||||||
|
display: inline-flex; align-items: center; gap: 6px;
|
||||||
|
background: rgba(34,197,94,0.12); border: 1px solid rgba(34,197,94,0.3);
|
||||||
|
color: var(--green); font-size: 12px; font-weight: 700;
|
||||||
|
padding: 4px 12px; border-radius: 20px; margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
.dot-live { width: 7px; height: 7px; border-radius: 50%; background: var(--green); animation: pulse 2s infinite; }
|
||||||
|
@keyframes pulse { 0%,100%{opacity:1} 50%{opacity:0.4} }
|
||||||
|
|
||||||
|
/* INFO CARD */
|
||||||
|
.info-table {
|
||||||
|
width: 100%; border-collapse: collapse; margin: 16px 0 28px;
|
||||||
|
border: 1px solid var(--border); border-radius: 12px; overflow: hidden;
|
||||||
|
}
|
||||||
|
.info-table th {
|
||||||
|
background: var(--surface); padding: 10px 16px;
|
||||||
|
font-size: 12px; font-weight: 700; color: var(--text-dim);
|
||||||
|
text-align: left; border-bottom: 1px solid var(--border);
|
||||||
|
}
|
||||||
|
.info-table td {
|
||||||
|
padding: 11px 16px; font-size: 14px;
|
||||||
|
border-bottom: 1px solid var(--border);
|
||||||
|
}
|
||||||
|
.info-table tr:last-child td { border-bottom: none; }
|
||||||
|
.info-table td:first-child { color: var(--text-dim); width: 160px; }
|
||||||
|
.info-table code { font-family: 'Fira Code','Courier New',monospace; font-size: 13px; color: var(--accent); }
|
||||||
|
|
||||||
|
/* CODE BLOCK */
|
||||||
|
.code-wrap { position: relative; margin: 12px 0 24px; }
|
||||||
|
.code-label {
|
||||||
|
display: flex; align-items: center; justify-content: space-between;
|
||||||
|
background: #0d0d14; border: 1px solid var(--border);
|
||||||
|
border-bottom: none; border-radius: 10px 10px 0 0;
|
||||||
|
padding: 8px 14px;
|
||||||
|
}
|
||||||
|
.code-lang { font-size: 12px; color: var(--text-dim); font-family: monospace; }
|
||||||
|
.copy-code {
|
||||||
|
background: none; border: 1px solid var(--border);
|
||||||
|
color: var(--text-dim); border-radius: 6px; padding: 3px 10px;
|
||||||
|
font-size: 11px; cursor: pointer; transition: all 0.2s;
|
||||||
|
}
|
||||||
|
.copy-code:hover { border-color: var(--accent); color: var(--accent); }
|
||||||
|
pre {
|
||||||
|
background: #0d0d14; border: 1px solid var(--border);
|
||||||
|
border-radius: 0 0 10px 10px; padding: 18px 20px;
|
||||||
|
font-family: 'Fira Code','Courier New',monospace;
|
||||||
|
font-size: 13px; line-height: 1.75; overflow-x: auto;
|
||||||
|
}
|
||||||
|
.code-wrap pre { margin: 0; }
|
||||||
|
code {
|
||||||
|
font-family: 'Fira Code','Courier New',monospace;
|
||||||
|
font-size: 13px; background: rgba(239,68,68,0.08);
|
||||||
|
border: 1px solid rgba(239,68,68,0.15);
|
||||||
|
color: var(--accent); padding: 1px 6px; border-radius: 4px;
|
||||||
|
}
|
||||||
|
pre code { background: none; border: none; color: inherit; padding: 0; font-size: inherit; }
|
||||||
|
|
||||||
|
/* SYNTAX COLORS */
|
||||||
|
.t-comment { color: #4a5568; }
|
||||||
|
.t-key { color: #68d391; }
|
||||||
|
.t-str { color: #fbd38d; }
|
||||||
|
.t-url { color: #63b3ed; }
|
||||||
|
.t-num { color: #f6ad55; }
|
||||||
|
.t-kw { color: #b794f4; }
|
||||||
|
.t-fn { color: #63b3ed; }
|
||||||
|
.t-var { color: #e4e4e7; }
|
||||||
|
|
||||||
|
/* METHOD BADGE */
|
||||||
|
.method { display: inline-block; font-size: 12px; font-weight: 700; padding: 2px 8px; border-radius: 5px; margin-right: 8px; font-family: monospace; }
|
||||||
|
.method-get { background: rgba(34,197,94,0.15); color: var(--green); }
|
||||||
|
.method-post { background: rgba(59,130,246,0.15); color: var(--blue); }
|
||||||
|
|
||||||
|
/* ENDPOINT BOX */
|
||||||
|
.endpoint {
|
||||||
|
background: var(--surface2); border: 1px solid var(--border);
|
||||||
|
border-radius: 10px; padding: 14px 18px; margin: 12px 0;
|
||||||
|
font-family: 'Fira Code','Courier New',monospace; font-size: 14px;
|
||||||
|
display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
.endpoint .path { color: var(--blue); }
|
||||||
|
.endpoint .query { color: var(--yellow); }
|
||||||
|
|
||||||
|
/* RESPONSE BOX */
|
||||||
|
.response-field {
|
||||||
|
background: var(--surface); border: 1px solid var(--border);
|
||||||
|
border-radius: 10px; overflow: hidden; margin: 12px 0 24px;
|
||||||
|
}
|
||||||
|
.response-field table { width: 100%; border-collapse: collapse; }
|
||||||
|
.response-field th {
|
||||||
|
background: #0d0d14; padding: 8px 16px;
|
||||||
|
font-size: 11px; font-weight: 700; color: var(--text-dim);
|
||||||
|
text-align: left; border-bottom: 1px solid var(--border);
|
||||||
|
}
|
||||||
|
.response-field td {
|
||||||
|
padding: 9px 16px; font-size: 13px;
|
||||||
|
border-bottom: 1px solid var(--border); vertical-align: top;
|
||||||
|
}
|
||||||
|
.response-field tr:last-child td { border-bottom: none; }
|
||||||
|
.field-name { font-family: monospace; color: var(--green); }
|
||||||
|
.field-type { color: var(--purple); font-family: monospace; font-size: 12px; }
|
||||||
|
.field-desc { color: var(--text-dim); }
|
||||||
|
|
||||||
|
/* ALERT BOX */
|
||||||
|
.alert {
|
||||||
|
border-radius: 10px; padding: 14px 18px; margin: 16px 0;
|
||||||
|
font-size: 14px; line-height: 1.6; display: flex; gap: 12px; align-items: flex-start;
|
||||||
|
}
|
||||||
|
.alert-warn { background: rgba(245,158,11,0.08); border: 1px solid rgba(245,158,11,0.25); color: var(--yellow); }
|
||||||
|
.alert-info { background: rgba(59,130,246,0.08); border: 1px solid rgba(59,130,246,0.25); color: var(--blue); }
|
||||||
|
.alert-ok { background: rgba(34,197,94,0.08); border: 1px solid rgba(34,197,94,0.25); color: var(--green); }
|
||||||
|
.alert-icon { font-size: 16px; flex-shrink: 0; margin-top: 1px; }
|
||||||
|
.alert p { color: inherit; margin: 0; }
|
||||||
|
|
||||||
|
/* MODELS TABLE */
|
||||||
|
.models-table {
|
||||||
|
width: 100%; border-collapse: collapse; margin: 16px 0 24px;
|
||||||
|
border: 1px solid var(--border); border-radius: 12px; overflow: hidden;
|
||||||
|
}
|
||||||
|
.models-table th {
|
||||||
|
background: var(--surface); padding: 10px 16px;
|
||||||
|
font-size: 12px; font-weight: 700; color: var(--text-dim);
|
||||||
|
text-align: left; border-bottom: 1px solid var(--border);
|
||||||
|
}
|
||||||
|
.models-table td {
|
||||||
|
padding: 11px 16px; font-size: 14px;
|
||||||
|
border-bottom: 1px solid var(--border);
|
||||||
|
}
|
||||||
|
.models-table tr:last-child td { border-bottom: none; }
|
||||||
|
.models-table td:nth-child(1) { font-family: monospace; color: var(--accent); font-size: 13px; }
|
||||||
|
|
||||||
|
/* LIVE TEST */
|
||||||
|
.live-test {
|
||||||
|
background: var(--surface); border: 1px solid var(--border);
|
||||||
|
border-radius: 14px; padding: 24px; margin: 20px 0;
|
||||||
|
}
|
||||||
|
.live-test h4 { font-size: 14px; font-weight: 700; margin-bottom: 14px; display: flex; align-items: center; gap: 8px; }
|
||||||
|
.test-input-row { display: flex; gap: 8px; margin-bottom: 12px; }
|
||||||
|
.test-input {
|
||||||
|
flex: 1; background: var(--bg); border: 1px solid var(--border);
|
||||||
|
border-radius: 8px; padding: 10px 12px;
|
||||||
|
font-size: 13px; font-family: 'Fira Code','Courier New',monospace;
|
||||||
|
color: var(--text); outline: none; transition: border-color 0.2s;
|
||||||
|
}
|
||||||
|
.test-input:focus { border-color: var(--accent); }
|
||||||
|
.test-input::placeholder { color: var(--text-dim); }
|
||||||
|
.btn-test {
|
||||||
|
background: linear-gradient(135deg, #3b82f6, #2563eb);
|
||||||
|
color: #fff; border: none; border-radius: 8px;
|
||||||
|
padding: 10px 16px; font-size: 13px; font-weight: 600;
|
||||||
|
cursor: pointer; white-space: nowrap; transition: all 0.2s;
|
||||||
|
}
|
||||||
|
.btn-test:hover { box-shadow: 0 4px 14px rgba(59,130,246,0.35); }
|
||||||
|
.btn-test:disabled { opacity: 0.5; cursor: not-allowed; }
|
||||||
|
.test-result {
|
||||||
|
background: #0d0d14; border: 1px solid var(--border);
|
||||||
|
border-radius: 8px; padding: 14px 16px;
|
||||||
|
font-family: 'Fira Code','Courier New',monospace; font-size: 13px; line-height: 1.7;
|
||||||
|
min-height: 60px; color: var(--text-dim); white-space: pre-wrap; word-break: break-all;
|
||||||
|
}
|
||||||
|
.test-result.ok { color: var(--green); }
|
||||||
|
.test-result.err { color: var(--accent); }
|
||||||
|
|
||||||
|
/* QUOTA TABLE */
|
||||||
|
.quota-table {
|
||||||
|
width: 100%; border-collapse: collapse; margin: 12px 0 24px;
|
||||||
|
border: 1px solid var(--border); border-radius: 12px; overflow: hidden;
|
||||||
|
}
|
||||||
|
.quota-table th {
|
||||||
|
background: var(--surface); padding: 9px 16px;
|
||||||
|
font-size: 12px; font-weight: 700; color: var(--text-dim);
|
||||||
|
text-align: left; border-bottom: 1px solid var(--border);
|
||||||
|
}
|
||||||
|
.quota-table td {
|
||||||
|
padding: 10px 16px; font-size: 14px;
|
||||||
|
border-bottom: 1px solid var(--border);
|
||||||
|
}
|
||||||
|
.quota-table tr:last-child td { border-bottom: none; }
|
||||||
|
.quota-table td:nth-child(2) { font-family: monospace; color: var(--green); }
|
||||||
|
|
||||||
|
@media (max-width: 860px) {
|
||||||
|
.sidebar { display: none; }
|
||||||
|
.main { margin-left: 0; padding: 24px 20px; }
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<!-- SIDEBAR -->
|
||||||
|
<nav class="sidebar">
|
||||||
|
<a href="cloud.html" class="sidebar-logo">
|
||||||
|
<span>🦞 虾盘云</span>
|
||||||
|
</a>
|
||||||
|
<a href="cloud.html" class="sidebar-back">← 返回首页</a>
|
||||||
|
|
||||||
|
<div class="sidebar-section">开始</div>
|
||||||
|
<a href="#overview" class="sidebar-link active">基本信息</a>
|
||||||
|
<a href="#auth" class="sidebar-link">认证方式</a>
|
||||||
|
<a href="#models" class="sidebar-link">支持模型</a>
|
||||||
|
|
||||||
|
<div class="sidebar-section">接口</div>
|
||||||
|
<a href="#chat" class="sidebar-link">对话接口</a>
|
||||||
|
<a href="#balance" class="sidebar-link">余额查询</a>
|
||||||
|
<a href="#usage" class="sidebar-link">用量查询</a>
|
||||||
|
|
||||||
|
<div class="sidebar-section">充值</div>
|
||||||
|
<a href="#recharge-flow" class="sidebar-link">充值流程</a>
|
||||||
|
<a href="#quota-calc" class="sidebar-link">Quota 换算</a>
|
||||||
|
|
||||||
|
<div class="sidebar-section">Key 管理</div>
|
||||||
|
<a href="#key-format" class="sidebar-link">Key 格式</a>
|
||||||
|
<a href="#key-gen" class="sidebar-link">前端生成</a>
|
||||||
|
|
||||||
|
<div class="sidebar-section">在线测试</div>
|
||||||
|
<a href="#live-test" class="sidebar-link">实时查询余额</a>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<!-- MAIN CONTENT -->
|
||||||
|
<main class="main">
|
||||||
|
|
||||||
|
<div class="page-badge">
|
||||||
|
<div class="dot-live"></div>
|
||||||
|
API 服务正常运行
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h1>虾盘云 API 开发文档</h1>
|
||||||
|
<p>虾盘云提供 OpenAI 兼容接口,接入 DeepSeek、Qwen 等主流模型。本文档适合 AI 开发者快速接入,也方便 AI 自动读取。</p>
|
||||||
|
<p>更新时间:2026-04-06</p>
|
||||||
|
|
||||||
|
<!-- OVERVIEW -->
|
||||||
|
<h2 id="overview">基本信息</h2>
|
||||||
|
<table class="info-table">
|
||||||
|
<thead><tr><th>项目</th><th>值</th></tr></thead>
|
||||||
|
<tbody>
|
||||||
|
<tr><td>API 端点</td><td><code>https://api.u-claw.org/v1</code></td></tr>
|
||||||
|
<tr><td>接口格式</td><td>兼容 OpenAI(<code>/v1/chat/completions</code> 等)</td></tr>
|
||||||
|
<tr><td>认证方式</td><td><code>Authorization: Bearer <your-key></code></td></tr>
|
||||||
|
<tr><td>Key 前缀</td><td><code>sk-xp-</code></td></tr>
|
||||||
|
<tr><td>计费单位</td><td>quota(500,000 quota = $1 = ¥7.2)</td></tr>
|
||||||
|
<tr><td>汇率</td><td>1 USD = 7.2 CNY(固定)</td></tr>
|
||||||
|
<tr><td>最低充值</td><td>¥10</td></tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<!-- AUTH -->
|
||||||
|
<h2 id="auth">认证方式</h2>
|
||||||
|
<p>所有请求需在 HTTP Header 中携带 API Key:</p>
|
||||||
|
<div class="code-wrap">
|
||||||
|
<div class="code-label"><span class="code-lang">http</span><button class="copy-code" onclick="copyCode(this)">复制</button></div>
|
||||||
|
<pre><code>Authorization: Bearer sk-xp-your-key-here</code></pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="alert alert-warn">
|
||||||
|
<span class="alert-icon">⚠️</span>
|
||||||
|
<p><strong>注意:</strong>Key 需先充值激活才能使用。未激活的 Key 调用接口会返回「无效的令牌」错误。</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- MODELS -->
|
||||||
|
<h2 id="models">支持模型</h2>
|
||||||
|
<table class="models-table">
|
||||||
|
<thead><tr><th>model ID</th><th>对应模型</th><th>输入价格</th><th>输出价格</th><th>特点</th></tr></thead>
|
||||||
|
<tbody>
|
||||||
|
<tr><td>deepseek-chat</td><td>DeepSeek V3</td><td>¥3 / 百万 token</td><td>¥9 / 百万 token</td><td>综合能力强,推荐首选</td></tr>
|
||||||
|
<tr><td>deepseek-reasoner</td><td>DeepSeek R1</td><td>¥12 / 百万 token</td><td>¥36 / 百万 token</td><td>深度推理,复杂逻辑</td></tr>
|
||||||
|
<tr><td>qwen-turbo</td><td>通义千问 Turbo</td><td>¥1.8 / 百万 token</td><td>¥5.4 / 百万 token</td><td>极速响应,高频场景</td></tr>
|
||||||
|
<tr><td>qwen-plus</td><td>通义千问 Plus</td><td>¥4 / 百万 token</td><td>¥12 / 百万 token</td><td>中文优化,长文档</td></tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<!-- CHAT -->
|
||||||
|
<h2 id="chat">对话接口</h2>
|
||||||
|
<div class="endpoint">
|
||||||
|
<span class="method method-post">POST</span>
|
||||||
|
<span class="path">https://api.u-claw.org/v1/chat/completions</span>
|
||||||
|
</div>
|
||||||
|
<p>完全兼容 OpenAI <code>chat/completions</code> 接口格式,直接替换 baseUrl 即可。</p>
|
||||||
|
|
||||||
|
<h3>请求示例</h3>
|
||||||
|
<div class="code-wrap">
|
||||||
|
<div class="code-label"><span class="code-lang">bash (curl)</span><button class="copy-code" onclick="copyCode(this)">复制</button></div>
|
||||||
|
<pre><code>curl https://api.u-claw.org/v1/chat/completions \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-H "Authorization: Bearer sk-xp-your-key-here" \
|
||||||
|
-d '{
|
||||||
|
"model": "deepseek-chat",
|
||||||
|
"messages": [{"role": "user", "content": "你好"}],
|
||||||
|
"stream": false
|
||||||
|
}'</code></pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="code-wrap">
|
||||||
|
<div class="code-label"><span class="code-lang">javascript</span><button class="copy-code" onclick="copyCode(this)">复制</button></div>
|
||||||
|
<pre><code><span class="t-kw">const</span> <span class="t-var">res</span> = <span class="t-kw">await</span> <span class="t-fn">fetch</span>(<span class="t-str">'https://api.u-claw.org/v1/chat/completions'</span>, {
|
||||||
|
<span class="t-key">method</span>: <span class="t-str">'POST'</span>,
|
||||||
|
<span class="t-key">headers</span>: {
|
||||||
|
<span class="t-str">'Content-Type'</span>: <span class="t-str">'application/json'</span>,
|
||||||
|
<span class="t-str">'Authorization'</span>: <span class="t-str">'Bearer sk-xp-your-key-here'</span>
|
||||||
|
},
|
||||||
|
<span class="t-key">body</span>: <span class="t-fn">JSON.stringify</span>({
|
||||||
|
<span class="t-key">model</span>: <span class="t-str">'deepseek-chat'</span>,
|
||||||
|
<span class="t-key">messages</span>: [{ <span class="t-key">role</span>: <span class="t-str">'user'</span>, <span class="t-key">content</span>: <span class="t-str">'你好'</span> }]
|
||||||
|
})
|
||||||
|
});
|
||||||
|
<span class="t-kw">const</span> <span class="t-var">data</span> = <span class="t-kw">await</span> <span class="t-var">res</span>.<span class="t-fn">json</span>();
|
||||||
|
<span class="t-fn">console</span>.<span class="t-fn">log</span>(<span class="t-var">data</span>.<span class="t-var">choices</span>[<span class="t-num">0</span>].<span class="t-var">message</span>.<span class="t-var">content</span>);</code></pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="code-wrap">
|
||||||
|
<div class="code-label"><span class="code-lang">python</span><button class="copy-code" onclick="copyCode(this)">复制</button></div>
|
||||||
|
<pre><code><span class="t-kw">from</span> openai <span class="t-kw">import</span> OpenAI
|
||||||
|
|
||||||
|
client = OpenAI(
|
||||||
|
api_key=<span class="t-str">"sk-xp-your-key-here"</span>,
|
||||||
|
base_url=<span class="t-str">"https://api.u-claw.org/v1"</span>
|
||||||
|
)
|
||||||
|
|
||||||
|
response = client.chat.completions.create(
|
||||||
|
model=<span class="t-str">"deepseek-chat"</span>,
|
||||||
|
messages=[{<span class="t-str">"role"</span>: <span class="t-str">"user"</span>, <span class="t-str">"content"</span>: <span class="t-str">"你好"</span>}]
|
||||||
|
)
|
||||||
|
<span class="t-fn">print</span>(response.choices[<span class="t-num">0</span>].message.content)</code></pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- BALANCE -->
|
||||||
|
<h2 id="balance">余额查询接口</h2>
|
||||||
|
<div class="endpoint">
|
||||||
|
<span class="method method-get">GET</span>
|
||||||
|
<span class="path">https://api.u-claw.org/v1/dashboard/billing/subscription</span>
|
||||||
|
</div>
|
||||||
|
<p>返回该 Key 的总充值额度(USD)。</p>
|
||||||
|
|
||||||
|
<h3>返回字段</h3>
|
||||||
|
<div class="response-field">
|
||||||
|
<table>
|
||||||
|
<thead><tr><th>字段</th><th>类型</th><th>说明</th></tr></thead>
|
||||||
|
<tbody>
|
||||||
|
<tr><td class="field-name">hard_limit_usd</td><td class="field-type">number</td><td class="field-desc">累计充值总额(USD)</td></tr>
|
||||||
|
<tr><td class="field-name">soft_limit_usd</td><td class="field-type">number</td><td class="field-desc">同上(兼容字段)</td></tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h3>返回示例</h3>
|
||||||
|
<div class="code-wrap">
|
||||||
|
<div class="code-label"><span class="code-lang">json</span><button class="copy-code" onclick="copyCode(this)">复制</button></div>
|
||||||
|
<pre><code>{
|
||||||
|
<span class="t-key">"hard_limit_usd"</span>: <span class="t-num">10.2</span>,
|
||||||
|
<span class="t-key">"soft_limit_usd"</span>: <span class="t-num">10.2</span>
|
||||||
|
}</code></pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- USAGE -->
|
||||||
|
<h2 id="usage">用量查询接口</h2>
|
||||||
|
<div class="endpoint">
|
||||||
|
<span class="method method-get">GET</span>
|
||||||
|
<span class="path">https://api.u-claw.org/v1/dashboard/billing/usage</span>
|
||||||
|
<span class="query">?start_date=2020-01-01&end_date=2026-04-06</span>
|
||||||
|
</div>
|
||||||
|
<p>返回该 Key 在指定时间范围内的消耗量。</p>
|
||||||
|
|
||||||
|
<h3>请求参数</h3>
|
||||||
|
<div class="response-field">
|
||||||
|
<table>
|
||||||
|
<thead><tr><th>参数</th><th>类型</th><th>说明</th></tr></thead>
|
||||||
|
<tbody>
|
||||||
|
<tr><td class="field-name">start_date</td><td class="field-type">string</td><td class="field-desc">开始日期 YYYY-MM-DD,建议填 2020-01-01</td></tr>
|
||||||
|
<tr><td class="field-name">end_date</td><td class="field-type">string</td><td class="field-desc">结束日期 YYYY-MM-DD,建议填今天</td></tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h3>返回字段</h3>
|
||||||
|
<div class="response-field">
|
||||||
|
<table>
|
||||||
|
<thead><tr><th>字段</th><th>类型</th><th>说明</th></tr></thead>
|
||||||
|
<tbody>
|
||||||
|
<tr><td class="field-name">total_usage</td><td class="field-type">number</td><td class="field-desc">已消耗量,单位是 USD×100(分),<strong>除以100才是 USD</strong></td></tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h3>余额计算公式</h3>
|
||||||
|
<div class="code-wrap">
|
||||||
|
<div class="code-label"><span class="code-lang">formula</span><button class="copy-code" onclick="copyCode(this)">复制</button></div>
|
||||||
|
<pre><code>已消耗 USD = total_usage / 100
|
||||||
|
剩余 USD = hard_limit_usd - 已消耗 USD
|
||||||
|
剩余 CNY = 剩余 USD × 7.2</code></pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h3>完整余额查询示例(JavaScript)</h3>
|
||||||
|
<div class="code-wrap">
|
||||||
|
<div class="code-label"><span class="code-lang">javascript</span><button class="copy-code" onclick="copyCode(this)">复制</button></div>
|
||||||
|
<pre><code><span class="t-kw">const</span> <span class="t-var">API_BASE</span> = <span class="t-str">'https://api.u-claw.org/v1'</span>;
|
||||||
|
|
||||||
|
<span class="t-kw">async function</span> <span class="t-fn">queryBalance</span>(apiKey) {
|
||||||
|
<span class="t-kw">const</span> <span class="t-var">headers</span> = { Authorization: <span class="t-str">'Bearer '</span> + apiKey };
|
||||||
|
<span class="t-kw">const</span> <span class="t-var">today</span> = <span class="t-kw">new</span> <span class="t-fn">Date</span>().<span class="t-fn">toISOString</span>().<span class="t-fn">slice</span>(<span class="t-num">0</span>, <span class="t-num">10</span>);
|
||||||
|
|
||||||
|
<span class="t-kw">const</span> [<span class="t-var">subRes</span>, <span class="t-var">usageRes</span>] = <span class="t-kw">await</span> Promise.<span class="t-fn">all</span>([
|
||||||
|
<span class="t-fn">fetch</span>(<span class="t-str">`${API_BASE}/dashboard/billing/subscription`</span>, { headers }),
|
||||||
|
<span class="t-fn">fetch</span>(<span class="t-str">`${API_BASE}/dashboard/billing/usage?start_date=2020-01-01&end_date=${today}`</span>, { headers })
|
||||||
|
]);
|
||||||
|
|
||||||
|
<span class="t-kw">if</span> (!subRes.ok) <span class="t-kw">throw new</span> Error(<span class="t-str">'Key 无效或未激活'</span>);
|
||||||
|
|
||||||
|
<span class="t-kw">const</span> <span class="t-var">sub</span> = <span class="t-kw">await</span> subRes.<span class="t-fn">json</span>();
|
||||||
|
<span class="t-kw">const</span> <span class="t-var">usage</span> = <span class="t-kw">await</span> usageRes.<span class="t-fn">json</span>();
|
||||||
|
|
||||||
|
<span class="t-kw">const</span> <span class="t-var">totalUsd</span> = sub.hard_limit_usd || <span class="t-num">0</span>;
|
||||||
|
<span class="t-kw">const</span> <span class="t-var">usedUsd</span> = (usage.total_usage || <span class="t-num">0</span>) / <span class="t-num">100</span>;
|
||||||
|
<span class="t-kw">const</span> <span class="t-var">remainUsd</span> = totalUsd - usedUsd;
|
||||||
|
|
||||||
|
<span class="t-kw">return</span> {
|
||||||
|
totalCny: (totalUsd * <span class="t-num">7.2</span>).<span class="t-fn">toFixed</span>(<span class="t-num">2</span>), <span class="t-comment">// 累计充值(CNY)</span>
|
||||||
|
usedCny: (usedUsd * <span class="t-num">7.2</span>).<span class="t-fn">toFixed</span>(<span class="t-num">2</span>), <span class="t-comment">// 已消耗(CNY)</span>
|
||||||
|
balanceCny: (remainUsd * <span class="t-num">7.2</span>).<span class="t-fn">toFixed</span>(<span class="t-num">2</span>), <span class="t-comment">// 剩余余额(CNY)</span>
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
<span class="t-comment">// 使用示例</span>
|
||||||
|
<span class="t-fn">queryBalance</span>(<span class="t-str">'sk-xp-your-key-here'</span>).<span class="t-fn">then</span>(console.log);
|
||||||
|
<span class="t-comment">// { totalCny: '73.44', usedCny: '1.36', balanceCny: '72.08' }</span></code></pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h3>curl 测试</h3>
|
||||||
|
<div class="code-wrap">
|
||||||
|
<div class="code-label"><span class="code-lang">bash</span><button class="copy-code" onclick="copyCode(this)">复制</button></div>
|
||||||
|
<pre><code>KEY="sk-xp-your-key-here"
|
||||||
|
|
||||||
|
<span class="t-comment"># 查询总充值额</span>
|
||||||
|
curl https://api.u-claw.org/v1/dashboard/billing/subscription \
|
||||||
|
-H "Authorization: Bearer $KEY"
|
||||||
|
|
||||||
|
<span class="t-comment"># 查询已消耗</span>
|
||||||
|
curl "https://api.u-claw.org/v1/dashboard/billing/usage?start_date=2020-01-01&end_date=$(date +%F)" \
|
||||||
|
-H "Authorization: Bearer $KEY"</code></pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- LIVE TEST -->
|
||||||
|
<h2 id="live-test">在线测试:实时查询余额</h2>
|
||||||
|
<p>在这里直接输入你的 Key 测试接口是否正常返回数据。</p>
|
||||||
|
<div class="live-test">
|
||||||
|
<h4>🔬 余额查询测试</h4>
|
||||||
|
<div class="test-input-row">
|
||||||
|
<input type="text" id="testKey" class="test-input" placeholder="sk-xp-..." spellcheck="false">
|
||||||
|
<button class="btn-test" id="testBtn" onclick="runTest()">发送请求</button>
|
||||||
|
</div>
|
||||||
|
<div class="test-result" id="testResult">等待输入 Key...</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- RECHARGE FLOW -->
|
||||||
|
<h2 id="recharge-flow">充值流程</h2>
|
||||||
|
<p>当前为<strong>手工充值</strong>模式,流程如下:</p>
|
||||||
|
<ol style="padding-left:20px;color:var(--text-dim);font-size:15px;line-height:2;">
|
||||||
|
<li>用户在网站生成或粘贴自己的 <code>sk-xp-</code> Key</li>
|
||||||
|
<li>支付宝扫码付款,<strong style="color:var(--text)">付款备注填写 Key</strong></li>
|
||||||
|
<li>管理员收到付款通知后,在 new-api 后台为该 Key 增加 quota</li>
|
||||||
|
<li>用户通过余额查询接口验证是否到账</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<div class="alert alert-info">
|
||||||
|
<span class="alert-icon">ℹ️</span>
|
||||||
|
<p>工作时间 10 分钟内到账,非工作时间最长 2 小时。</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- QUOTA CALC -->
|
||||||
|
<h2 id="quota-calc">Quota 换算</h2>
|
||||||
|
<p>换算公式:<code>quota = 充值CNY / 7.2 × 500,000</code></p>
|
||||||
|
<table class="quota-table">
|
||||||
|
<thead><tr><th>充值金额(CNY)</th><th>增加 quota</th><th>约等于(USD)</th></tr></thead>
|
||||||
|
<tbody>
|
||||||
|
<tr><td>¥10</td><td>694,444</td><td>$1.39</td></tr>
|
||||||
|
<tr><td>¥20</td><td>1,388,888</td><td>$2.78</td></tr>
|
||||||
|
<tr><td>¥50</td><td>3,472,222</td><td>$6.94</td></tr>
|
||||||
|
<tr><td>¥100</td><td>6,944,444</td><td>$13.89</td></tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<!-- KEY FORMAT -->
|
||||||
|
<h2 id="key-format">Key 格式</h2>
|
||||||
|
<p>虾盘云 Key 格式:<code>sk-xp-</code> + 32位十六进制随机字符串(共 38 字符)</p>
|
||||||
|
<div class="code-wrap">
|
||||||
|
<div class="code-label"><span class="code-lang">示例</span><button class="copy-code" onclick="copyCode(this)">复制</button></div>
|
||||||
|
<pre><code>sk-xp-fa3daa78e448871d6ccbffd1540cc07b</code></pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="alert alert-warn">
|
||||||
|
<span class="alert-icon">⚠️</span>
|
||||||
|
<p><strong>重要:</strong>前端生成的 Key 仅是字符串,未在系统中注册。用户付款备注此 Key 后,管理员在 new-api 后台以此名创建 Token,Key 才真正激活生效。</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- KEY GEN -->
|
||||||
|
<h2 id="key-gen">前端生成 Key(JavaScript)</h2>
|
||||||
|
<div class="code-wrap">
|
||||||
|
<div class="code-label"><span class="code-lang">javascript</span><button class="copy-code" onclick="copyCode(this)">复制</button></div>
|
||||||
|
<pre><code><span class="t-kw">function</span> <span class="t-fn">generateKey</span>() {
|
||||||
|
<span class="t-kw">const</span> <span class="t-var">hex</span> = Array.<span class="t-fn">from</span>(crypto.<span class="t-fn">getRandomValues</span>(<span class="t-kw">new</span> <span class="t-fn">Uint8Array</span>(<span class="t-num">16</span>)))
|
||||||
|
.<span class="t-fn">map</span>(b => b.<span class="t-fn">toString</span>(<span class="t-num">16</span>).<span class="t-fn">padStart</span>(<span class="t-num">2</span>, <span class="t-str">'0'</span>)).<span class="t-fn">join</span>(<span class="t-str">''</span>);
|
||||||
|
<span class="t-kw">return</span> <span class="t-str">'sk-xp-'</span> + hex;
|
||||||
|
}
|
||||||
|
|
||||||
|
<span class="t-fn">generateKey</span>();
|
||||||
|
<span class="t-comment">// => "sk-xp-fa3daa78e448871d6ccbffd1540cc07b"</span></code></pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="alert alert-ok">
|
||||||
|
<span class="alert-icon">✅</span>
|
||||||
|
<p>接口测试通过(2026-04-06):余额查询接口实测返回正常,<code>hard_limit_usd</code> 和 <code>total_usage</code> 字段均可用。</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p style="margin-top:48px;padding-top:24px;border-top:1px solid var(--border);color:var(--text-dim);font-size:13px;">
|
||||||
|
虾盘云 · <a href="cloud.html">首页</a> · <a href="mailto:hefangsheng@gmail.com">联系我们</a> · © 2026 api.u-claw.org
|
||||||
|
</p>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// 复制代码
|
||||||
|
function copyCode(btn) {
|
||||||
|
const pre = btn.closest('.code-label').nextElementSibling;
|
||||||
|
navigator.clipboard.writeText(pre.innerText).then(() => {
|
||||||
|
btn.textContent = '已复制 ✓';
|
||||||
|
setTimeout(() => btn.textContent = '复制', 2000);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 侧边栏高亮
|
||||||
|
const links = document.querySelectorAll('.sidebar-link');
|
||||||
|
const sections = document.querySelectorAll('h2[id]');
|
||||||
|
window.addEventListener('scroll', () => {
|
||||||
|
let cur = '';
|
||||||
|
sections.forEach(s => { if (window.scrollY >= s.offsetTop - 80) cur = s.id; });
|
||||||
|
links.forEach(l => {
|
||||||
|
const href = l.getAttribute('href').slice(1);
|
||||||
|
l.classList.toggle('active', href === cur);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// 在线测试
|
||||||
|
async function runTest() {
|
||||||
|
const key = document.getElementById('testKey').value.trim();
|
||||||
|
const btn = document.getElementById('testBtn');
|
||||||
|
const out = document.getElementById('testResult');
|
||||||
|
if (!key || !key.startsWith('sk-')) {
|
||||||
|
out.className = 'test-result err';
|
||||||
|
out.textContent = '错误:请输入有效的 API Key(以 sk- 开头)';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
btn.disabled = true; btn.textContent = '请求中...';
|
||||||
|
out.className = 'test-result';
|
||||||
|
out.textContent = '发送请求中...';
|
||||||
|
try {
|
||||||
|
const headers = { Authorization: 'Bearer ' + key };
|
||||||
|
const today = new Date().toISOString().slice(0,10);
|
||||||
|
const [s, u] = await Promise.all([
|
||||||
|
fetch('https://api.u-claw.org/v1/dashboard/billing/subscription', {headers}),
|
||||||
|
fetch('https://api.u-claw.org/v1/dashboard/billing/usage?start_date=2020-01-01&end_date=' + today, {headers})
|
||||||
|
]);
|
||||||
|
const sub = await s.json();
|
||||||
|
const usage = await u.json();
|
||||||
|
if (!s.ok) {
|
||||||
|
out.className = 'test-result err';
|
||||||
|
out.textContent = 'HTTP ' + s.status + '\n' + JSON.stringify(sub, null, 2);
|
||||||
|
} else {
|
||||||
|
const total = sub.hard_limit_usd || 0;
|
||||||
|
const used = (usage.total_usage || 0) / 100;
|
||||||
|
const bal = total - used;
|
||||||
|
out.className = 'test-result ok';
|
||||||
|
out.textContent = [
|
||||||
|
'// 接口返回正常 ✓',
|
||||||
|
'',
|
||||||
|
'// subscription',
|
||||||
|
JSON.stringify(sub, null, 2),
|
||||||
|
'',
|
||||||
|
'// usage',
|
||||||
|
JSON.stringify(usage, null, 2),
|
||||||
|
'',
|
||||||
|
'// 计算结果',
|
||||||
|
'累计充值:¥' + (total * 7.2).toFixed(2),
|
||||||
|
'已消耗: ¥' + (used * 7.2).toFixed(2),
|
||||||
|
'剩余余额:¥' + (bal * 7.2).toFixed(2),
|
||||||
|
].join('\n');
|
||||||
|
}
|
||||||
|
} catch(e) {
|
||||||
|
out.className = 'test-result err';
|
||||||
|
out.textContent = '网络错误:' + e.message;
|
||||||
|
} finally {
|
||||||
|
btn.disabled = false; btn.textContent = '发送请求';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById('testKey').addEventListener('keydown', e => {
|
||||||
|
if (e.key === 'Enter') runTest();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user