+
diff --git a/web/src/hooks/common/useNavigation.js b/web/src/hooks/common/useNavigation.js
index f7e61a20..cd52e1b8 100644
--- a/web/src/hooks/common/useNavigation.js
+++ b/web/src/hooks/common/useNavigation.js
@@ -45,7 +45,7 @@ export const useNavigation = (t, docsLink, headerNavModules) => {
to: '/console',
},
{
- text: t('模型广场'),
+ text: t('定价'),
itemKey: 'pricing',
to: '/pricing',
},
@@ -59,11 +59,6 @@ export const useNavigation = (t, docsLink, headerNavModules) => {
},
]
: []),
- {
- text: t('关于'),
- itemKey: 'about',
- to: '/about',
- },
];
// 根据配置过滤导航链接
@@ -72,7 +67,6 @@ export const useNavigation = (t, docsLink, headerNavModules) => {
return docsLink && modules.docs;
}
if (link.itemKey === 'pricing') {
- // 支持新的pricing配置格式
return typeof modules.pricing === 'object'
? modules.pricing.enabled
: modules.pricing;
diff --git a/web/src/index.css b/web/src/index.css
index 116ff741..1da3919b 100644
--- a/web/src/index.css
+++ b/web/src/index.css
@@ -18,19 +18,78 @@
--sidebar-width: 180px;
--sidebar-width-collapsed: 60px;
--sidebar-current-width: var(--sidebar-width);
+
+ /* 苹方字体栈:macOS/iOS 用苹方,Windows 用微软雅黑,Linux 用 Noto Sans */
+ --font-sans: 'PingFang SC', 'PingFang HK', 'PingFang TC',
+ -apple-system, BlinkMacSystemFont,
+ 'Microsoft YaHei', 'Microsoft YaHei UI',
+ 'Noto Sans SC', 'Noto Sans CJK SC',
+ 'Helvetica Neue', Arial, sans-serif;
+
+ /* 小方格背景(深色默认) */
+ --grid-line: rgba(255,255,255,0.055);
+ --grid-size: 32px;
+}
+
+/* 浅色主题下格子线改为深色 */
+html.semi-always-light,
+body[theme-mode="light"],
+html:not(.dark) body {
+ --grid-line: rgba(0,0,0,0.06);
+}
+
+/* 深色主题 */
+html.dark,
+body[theme-mode="dark"] {
+ --grid-line: rgba(255,255,255,0.055);
}
body.sidebar-collapsed {
--sidebar-current-width: var(--sidebar-width-collapsed);
}
+/* html/body 只提供背景底色,格子只在首页 .lp-root 内显示 */
+html {
+ background-color: var(--semi-color-bg-0, #0e1520);
+}
+
body {
- font-family: Lato, 'Helvetica Neue', Arial, Helvetica, 'Microsoft YaHei',
- sans-serif;
+ font-family: var(--font-sans);
+ font-weight: 400;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
color: var(--semi-color-text-0);
background-color: var(--semi-color-bg-0);
}
+/* 苹方字重适配:细 / 常规 / 中等 / 粗 */
+h1, h2, h3, h4, h5, h6 {
+ font-family: var(--font-sans);
+ font-weight: 600;
+ letter-spacing: -.01em;
+}
+
+strong, b, th {
+ font-weight: 600;
+}
+
+/* Semi UI 组件字体覆盖 */
+.semi-typography,
+.semi-button,
+.semi-input,
+.semi-select,
+.semi-table,
+.semi-form,
+.semi-navigation,
+.semi-tabs,
+.semi-dropdown,
+.semi-modal,
+.semi-toast,
+.semi-notification,
+.semi-tooltip {
+ font-family: var(--font-sans) !important;
+}
+
.app-layout {
height: 100vh;
height: 100dvh;
@@ -955,7 +1014,198 @@ html.dark .with-pastel-balls::before {
gap: 0.25rem;
}
-/* ==================== 自定义圆角样式 ==================== */
+/* ==================== 自定义顶部导航栏 ==================== */
+.lp-header-bar {
+ height: 56px;
+ display: flex;
+ align-items: center;
+ transition: background .3s, border-color .3s, backdrop-filter .3s;
+}
+
+/* 深色导航栏(首页 + dark模式) */
+.lp-header-dark {
+ background: rgba(10,15,26,.60);
+ border-bottom: 1px solid rgba(255,255,255,.07);
+ backdrop-filter: blur(18px);
+ -webkit-backdrop-filter: blur(18px);
+}
+/* 深色 + 顶部 → 完全透明无模糊 */
+.lp-header-dark.lp-header-top {
+ background: transparent !important;
+ border-bottom: 1px solid transparent !important;
+ backdrop-filter: none !important;
+ -webkit-backdrop-filter: none !important;
+}
+
+/* 浅色导航栏(非首页 + light模式) */
+.lp-header-light {
+ background: rgba(255,255,255,.60);
+ border-bottom: 1px solid rgba(0,0,0,.07);
+ backdrop-filter: blur(18px);
+ -webkit-backdrop-filter: blur(18px);
+}
+/* 浅色 + 顶部 → 完全透明无模糊 */
+.lp-header-light.lp-header-top {
+ background: transparent !important;
+ border-bottom: 1px solid transparent !important;
+ backdrop-filter: none !important;
+ -webkit-backdrop-filter: none !important;
+}
+
+/* ── 导航链接:深色模式 ── */
+.lp-header-dark .lp-nav-link {
+ color: #ffffff !important;
+ text-decoration: none !important;
+ padding: 5px 14px !important;
+ border-radius: 8px !important;
+ font-size: .9rem !important;
+ font-weight: 500 !important;
+ transition: color .2s, background .2s !important;
+ flex-shrink: 0;
+ display: flex;
+ align-items: center;
+}
+.lp-header-dark .lp-nav-link:hover {
+ color: #ffffff !important;
+ background: rgba(255,255,255,.08) !important;
+}
+
+/* ── 导航链接:浅色模式 ── */
+.lp-header-light .lp-nav-link {
+ color: #1a1a2e !important;
+ text-decoration: none !important;
+ padding: 5px 14px !important;
+ border-radius: 8px !important;
+ font-size: .9rem !important;
+ font-weight: 500 !important;
+ transition: color .2s, background .2s !important;
+ flex-shrink: 0;
+ display: flex;
+ align-items: center;
+}
+.lp-header-light .lp-nav-link:hover {
+ color: #000 !important;
+ background: rgba(0,0,0,.06) !important;
+}
+
+/* ── Logo / 用户名文字颜色 ── */
+.lp-header-dark a.group .semi-typography,
+.lp-header-dark .semi-typography { color: #dde3ee !important; }
+
+/* 浅色导航(非首页):深色字 */
+.lp-header-light a.group .semi-typography,
+.lp-header-light .semi-typography { color: #1a1a2e !important; }
+/* 但首页用深色导航,浅色模式下首页导航仍是深色背景,文字要亮色 */
+.lp-header-dark.lp-header-top a.group .semi-typography,
+.lp-header-dark.lp-header-top .semi-typography,
+.lp-header-dark.lp-header-scrolled a.group .semi-typography,
+.lp-header-dark.lp-header-scrolled .semi-typography { color: #dde3ee !important; }
+
+/* ── 右侧图标按钮:深色模式 ── */
+.lp-header-dark .semi-button-tertiary.semi-button-borderless {
+ color: rgba(221,227,238,.7) !important;
+ background: rgba(255,255,255,.04) !important;
+ border: 1px solid rgba(255,255,255,.1) !important;
+}
+.lp-header-dark .semi-button-tertiary.semi-button-borderless:hover {
+ background: rgba(255,255,255,.08) !important;
+ border-color: rgba(255,255,255,.2) !important;
+ color: #dde3ee !important;
+}
+
+/* ── 右侧图标按钮:浅色模式 ── */
+.lp-header-light .semi-button-tertiary.semi-button-borderless {
+ color: rgba(30,30,50,.6) !important;
+ background: rgba(0,0,0,.03) !important;
+ border: 1px solid rgba(0,0,0,.1) !important;
+}
+.lp-header-light .semi-button-tertiary.semi-button-borderless:hover {
+ background: rgba(0,0,0,.07) !important;
+ border-color: rgba(0,0,0,.18) !important;
+ color: #1a1a2e !important;
+}
+
+/* ── 登录按钮:深色模式 ── */
+.lp-header-dark .lp-nav-login-btn {
+ display: inline-flex;
+ align-items: center;
+ padding: 6px 18px;
+ border-radius: 8px;
+ background: transparent;
+ color: rgba(221,227,238,.85) !important;
+ font-size: .88rem;
+ font-weight: 500;
+ text-decoration: none;
+ border: 1px solid rgba(255,255,255,.18) !important;
+ transition: all .2s;
+}
+.lp-header-dark .lp-nav-login-btn:hover {
+ background: rgba(255,255,255,.08) !important;
+ border-color: rgba(255,255,255,.32) !important;
+ color: #fff !important;
+}
+
+/* ── 登录按钮:浅色模式 ── */
+.lp-header-light .lp-nav-login-btn {
+ display: inline-flex;
+ align-items: center;
+ padding: 6px 18px;
+ border-radius: 8px;
+ background: transparent;
+ color: #1a1a2e !important;
+ font-size: .88rem;
+ font-weight: 500;
+ text-decoration: none;
+ border: 1px solid rgba(0,0,0,.18) !important;
+ transition: all .2s;
+}
+.lp-header-light .lp-nav-login-btn:hover {
+ background: rgba(0,0,0,.05) !important;
+ border-color: rgba(0,0,0,.3) !important;
+ color: #000 !important;
+}
+
+/* ── 橙色注册按钮(两种模式通用) ── */
+.lp-header-bar .lp-nav-orange-btn {
+ display: inline-flex;
+ align-items: center;
+ padding: 6px 18px;
+ border-radius: 8px;
+ background: #e8834a !important;
+ color: #fff !important;
+ font-size: .88rem;
+ font-weight: 600;
+ text-decoration: none;
+ border: none !important;
+ cursor: pointer;
+ transition: opacity .2s, transform .15s;
+}
+.lp-header-bar .lp-nav-orange-btn:hover {
+ opacity: .88 !important;
+ transform: translateY(-1px);
+}
+
+/* ── 用户头像区域:浅色模式字色 ── */
+.lp-header-light .semi-avatar { border: 1px solid rgba(0,0,0,.12); }
+.lp-header-light .semi-typography { color: #1a1a2e !important; }
+
+/* ── 用户头像区域:深色模式 ── */
+.lp-header-dark .semi-avatar { border: 1px solid rgba(255,255,255,.15); }
+
+/* 兜底:老class不带 dark/light 子类时也能工作 */
+.lp-header-bar .lp-nav-link {
+ text-decoration: none !important;
+ padding: 5px 14px !important;
+ border-radius: 8px !important;
+ font-size: .9rem !important;
+ font-weight: 500 !important;
+ transition: color .2s, background .2s !important;
+ flex-shrink: 0;
+ display: flex;
+ align-items: center;
+}
+
+
.semi-radio,
.semi-tagInput,
.semi-input-textarea-wrapper,
@@ -994,3 +1244,912 @@ html.dark .with-pastel-balls::before {
opacity: 1;
}
}
+
+/* ==================== 首页 Landing Page 专用样式 ==================== */
+.lp-root {
+ --lp-bg: transparent;
+ --lp-bg2: transparent;
+ --lp-card: #161f2e;
+ --lp-card-b: rgba(255,255,255,.07);
+ --lp-text: #dde3ee;
+ --lp-dim: rgba(221,227,238,.5);
+ --lp-dim2: rgba(221,227,238,.32);
+ /* 首页始终深色背景,格子颜色固定用白色线条 */
+ --grid-line: rgba(255,255,255,0.055);
+ --lp-orange: #e8834a;
+ --lp-teal: #2dd4bf;
+ --lp-purple: #8b5cf6;
+ --lp-blue: #60a5fa;
+ color: var(--lp-text);
+ background: #0a0f1a;
+ font-family: 'Inter','Noto Sans SC',system-ui,sans-serif;
+ overflow-x: hidden;
+ width: 100%;
+ position: relative;
+}
+
+/* 格子仅在首页 .lp-root 内显示,fixed 固定随视口 */
+.lp-root::before {
+ content: '';
+ position: fixed;
+ inset: 0;
+ z-index: 0;
+ pointer-events: none;
+ background-image:
+ linear-gradient(var(--grid-line) 1px, transparent 1px),
+ linear-gradient(90deg, var(--grid-line) 1px, transparent 1px);
+ background-size: var(--grid-size) var(--grid-size);
+}
+
+/* 首页内所有直接子元素在格子之上 */
+.lp-root > * {
+ position: relative;
+ z-index: 1;
+}
+
+/* Hero 区 */
+.lp-hero {
+ position: relative;
+ width: 100%;
+ min-height: 86vh;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ overflow: visible;
+ background: transparent; /* 格子从 html 透上来 */
+ padding-bottom: 72px;
+}
+
+/* Tyndall 光柱动效 */
+.lp-tyndall {
+ position: absolute;
+ inset: 0;
+ overflow: hidden;
+ pointer-events: none;
+ z-index: 1;
+}
+.lp-ty {
+ position: absolute;
+ border-radius: 50%;
+ will-change: transform, opacity;
+}
+@keyframes lp-ty-sweep {
+ 0% { opacity: 0; transform: translate(0,0) scale(.85); }
+ 18% { opacity: 1; }
+ 78% { opacity: .85; }
+ 100% { opacity: 0; transform: translate(-38vw,16vh) scale(1.08); }
+}
+.lp-ty1 {
+ width: 58vw; height: 90vh;
+ background: radial-gradient(ellipse 55% 65% at 55% 35%, rgba(0,200,150,.52) 0%, transparent 70%);
+ filter: blur(72px); left: 55%; top: -12%;
+ animation: lp-ty-sweep 10s cubic-bezier(.45,0,.55,1) infinite;
+}
+.lp-ty2 {
+ width: 52vw; height: 85vh;
+ background: radial-gradient(ellipse 55% 65% at 52% 38%, rgba(118,44,248,.50) 0%, transparent 70%);
+ filter: blur(80px); left: 62%; top: -5%;
+ animation: lp-ty-sweep 12s cubic-bezier(.45,0,.55,1) infinite;
+ animation-delay: -4s;
+}
+.lp-ty3 {
+ width: 48vw; height: 80vh;
+ background: radial-gradient(ellipse 55% 65% at 50% 32%, rgba(196,20,88,.48) 0%, transparent 70%);
+ filter: blur(75px); left: 58%; top: -8%;
+ animation: lp-ty-sweep 14s cubic-bezier(.45,0,.55,1) infinite;
+ animation-delay: -8s;
+}
+.lp-ty4 {
+ width: 54vw; height: 82vh;
+ background: radial-gradient(ellipse 55% 65% at 53% 36%, rgba(8,150,205,.46) 0%, transparent 70%);
+ filter: blur(78px); left: 66%; top: -6%;
+ animation: lp-ty-sweep 11s cubic-bezier(.45,0,.55,1) infinite;
+ animation-delay: -2s;
+}
+.lp-ty5 {
+ width: 44vw; height: 75vh;
+ background: radial-gradient(ellipse 55% 65% at 50% 40%, rgba(50,205,120,.40) 0%, transparent 70%);
+ filter: blur(68px); left: 70%; top: -4%;
+ animation: lp-ty-sweep 13s cubic-bezier(.45,0,.55,1) infinite;
+ animation-delay: -6s;
+}
+
+/* Hero 文字区 */
+.lp-hero-top {
+ position: relative;
+ z-index: 2;
+ text-align: center;
+ padding: 100px 20px 0;
+ width: min(680px, 90vw);
+}
+.lp-hero-title {
+ font-size: clamp(2.6rem,6.5vw,4.8rem);
+ font-weight: 900;
+ letter-spacing: -.5px;
+ line-height: 1.15;
+ margin-bottom: 16px;
+ /* 橙→金→玫瑰红渐变 */
+ background: linear-gradient(135deg, #ff9d4d 0%, #f5c842 45%, #ff6b9d 100%);
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+ background-clip: text;
+}
+.lp-hero-title-sub {
+ display: block;
+ font-size: clamp(1.1rem,2.8vw,1.9rem);
+ font-weight: 700;
+ letter-spacing: .08em;
+ margin-top: 8px;
+ /* 青→蓝渐变 */
+ background: linear-gradient(135deg, #38d9c0 0%, #5b9cf6 100%);
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+ background-clip: text;
+}
+.lp-hero-sub {
+ font-size: clamp(.92rem,1.8vw,1.05rem);
+ color: rgba(221,227,238,.72);
+ font-weight: 500;
+ line-height: 1.75;
+ max-width: 580px;
+ margin: 0 auto;
+}
+
+/* Hero 预览框 */
+.lp-fluid-wrap {
+ position: relative;
+ z-index: 2;
+ width: min(780px,82vw);
+ height: clamp(220px, 44vh, 480px);
+ margin: 36px auto 0;
+ border-radius: 22px;
+ overflow: hidden;
+ flex-shrink: 0;
+ box-shadow: -18px 32px 100px rgba(0,0,0,.72), 0 20px 50px rgba(0,0,0,.45), inset 0 0 0 1px rgba(255,255,255,.08);
+}
+.lp-fluid-card {
+ width: 100%; height: 100%;
+ background: rgba(6,11,20,.85);
+ position: relative; overflow: hidden;
+}
+
+/* 运行时间计时器 — 标题上方 */
+.lp-uptime {
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+ background: rgba(255,255,255,.05);
+ border: 1px solid rgba(255,255,255,.1);
+ border-radius: 100px;
+ padding: 7px 18px 7px 12px;
+ margin-bottom: 22px;
+}
+.lp-uptime-dot {
+ width: 7px; height: 7px;
+ border-radius: 50%;
+ background: #2dd4bf;
+ box-shadow: 0 0 6px #2dd4bf;
+ flex-shrink: 0;
+ animation: lp-dot-pulse 2s ease-in-out infinite;
+}
+@keyframes lp-dot-pulse {
+ 0%,100% { opacity: 1; box-shadow: 0 0 6px #2dd4bf; }
+ 50% { opacity: .4; box-shadow: 0 0 2px #2dd4bf; }
+}
+.lp-uptime-label {
+ font-size: .86rem;
+ font-weight: 500;
+ color: rgba(221,227,238,.55);
+ white-space: nowrap;
+ margin-right: 4px;
+}
+.lp-uptime-block {
+ display: inline-flex;
+ align-items: baseline;
+ gap: 1px;
+ background: rgba(0,0,0,.3);
+ border: 1px solid rgba(255,255,255,.08);
+ border-radius: 6px;
+ padding: 3px 9px;
+ font-size: .92rem;
+ font-weight: 700;
+ color: #e2e8f0;
+ font-variant-numeric: tabular-nums;
+ letter-spacing: .01em;
+}
+.lp-uptime-block em {
+ font-style: normal;
+ font-size: .7rem;
+ font-weight: 400;
+ color: rgba(221,227,238,.4);
+ margin-left: 2px;
+}
+
+/* Hero pills */
+.lp-hero-pills {
+ position: relative; z-index: 2;
+ display: flex; gap: 10px; flex-wrap: wrap; justify-content: center;
+ margin-top: 24px; padding-bottom: 8px;
+}
+.lp-hero-pill {
+ display: inline-flex; align-items: center; gap: 6px;
+ padding: 7px 18px; border-radius: 100px;
+ border: 1px solid rgba(255,255,255,.18);
+ background: rgba(255,255,255,.06);
+ font-size: .83rem; font-weight: 600; color: rgba(221,227,238,.8);
+ transition: border-color .2s, background .2s, color .2s;
+}
+.lp-hero-pill:hover { border-color: rgba(255,255,255,.28); background: rgba(255,255,255,.07); color: var(--lp-text); }
+
+/* 向下滚动箭头 */
+.lp-hero-scroll {
+ position: relative; left: auto; bottom: auto; transform: none;
+ z-index: 3; display: flex; flex-direction: column; align-items: center; gap: 2px; cursor: pointer;
+ margin-top: 20px;
+}
+.lp-hero-scroll span {
+ display: block; width: 18px; height: 18px;
+ border-right: 2px solid rgba(255,255,255,.5);
+ border-bottom: 2px solid rgba(255,255,255,.5);
+ transform: rotate(45deg);
+ animation: lp-chev-bounce 1.8s ease-in-out infinite;
+}
+.lp-hero-scroll span:nth-child(2) { animation-delay: .18s; opacity: .55; }
+.lp-hero-scroll span:nth-child(3) { animation-delay: .36s; opacity: .25; }
+@keyframes lp-chev-bounce {
+ 0%,100% { opacity: .8; transform: rotate(45deg) translate(0,0); }
+ 50% { opacity: .2; transform: rotate(45deg) translate(4px,4px); }
+}
+
+/* Section 基础 */
+.lp-section { padding: 88px 5%; }
+.lp-label {
+ display: block; text-align: center;
+ font-size: .7rem; font-weight: 700; letter-spacing: 2.5px;
+ text-transform: uppercase; color: var(--lp-teal);
+ margin-bottom: 18px;
+}
+.lp-s-title {
+ font-size: clamp(1.6rem,3.5vw,2.4rem);
+ font-weight: 800; letter-spacing: -.5px; line-height: 1.25;
+ text-align: center; margin-bottom: 14px;
+ color: var(--lp-text);
+}
+.lp-s-sub {
+ text-align: center;
+ color: rgba(221,227,238,.65);
+ font-size: .97rem;
+ font-weight: 500;
+ line-height: 1.75;
+ max-width: 520px; margin: 0 auto 56px;
+}
+.lp-divider {
+ height: 1px;
+ background: linear-gradient(90deg, transparent, rgba(255,255,255,.07), transparent);
+}
+
+/* Integrations 区 — 实色 */
+.lp-integrations { background: #080d16; padding: 64px 5%; }
+.lp-int-header {
+ display: flex; align-items: center; justify-content: space-between;
+ margin-bottom: 28px; flex-wrap: wrap; gap: 16px;
+ max-width: 1180px; margin-left: auto; margin-right: auto;
+}
+.lp-int-header .lp-label { margin: 0; text-align: left; }
+.lp-int-note {
+ display: flex; align-items: center; gap: 12px;
+ font-size: .85rem; color: var(--lp-dim);
+}
+.lp-int-note a {
+ display: inline-flex; align-items: center; gap: 6px;
+ padding: 7px 16px; border-radius: 8px;
+ border: 1px solid rgba(255,255,255,.1);
+ background: rgba(255,255,255,.04);
+ color: var(--lp-dim); text-decoration: none; font-size: .83rem; font-weight: 500;
+ transition: all .2s;
+}
+.lp-int-note a:hover { border-color: rgba(255,255,255,.22); color: var(--lp-text); background: rgba(255,255,255,.07); }
+.lp-int-cards {
+ display: grid; grid-template-columns: repeat(3,1fr); gap: 16px;
+ max-width: 1180px; margin-left: auto; margin-right: auto;
+}
+@media(max-width:700px){ .lp-int-cards { grid-template-columns: 1fr; } }
+.lp-int-card {
+ background: var(--lp-card); border: 1px solid var(--lp-card-b);
+ border-radius: 14px; padding: 22px 24px;
+ display: flex; align-items: center; gap: 16px;
+ text-decoration: none; color: var(--lp-text);
+ transition: border-color .25s, background .25s, transform .2s, box-shadow .25s;
+ cursor: pointer; position: relative; overflow: hidden;
+}
+.lp-int-card::before {
+ content: ''; position: absolute; top: 0; left: 0; right: 0; height: 1px;
+ background: linear-gradient(90deg, transparent, var(--lp-ic, rgba(255,255,255,.15)), transparent);
+ opacity: 0; transition: opacity .3s;
+}
+.lp-int-card:hover {
+ border-color: var(--lp-ic, rgba(255,255,255,.2));
+ background: rgba(255,255,255,.05);
+ transform: translateY(-3px);
+ box-shadow: 0 12px 40px rgba(0,0,0,.35);
+}
+.lp-int-card:hover::before { opacity: 1; }
+.lp-int-avatar {
+ width: 42px; height: 42px; border-radius: 10px;
+ display: flex; align-items: center; justify-content: center;
+ font-size: 1.1rem; font-weight: 800; flex-shrink: 0;
+ background: var(--lp-ib, rgba(255,255,255,.08));
+}
+.lp-int-info { flex: 1; }
+.lp-int-name { font-size: .95rem; font-weight: 700; margin-bottom: 3px; }
+.lp-int-org { font-size: .78rem; color: var(--lp-dim2); }
+.lp-int-arrow { color: var(--lp-dim2); font-size: .9rem; flex-shrink: 0; }
+.lp-ic-claude { --lp-ic: rgba(205,133,63,.45); --lp-ib: rgba(205,133,63,.12); }
+.lp-ic-codex { --lp-ic: rgba(16,163,127,.45); --lp-ib: rgba(16,163,127,.12); }
+.lp-ic-gemini { --lp-ic: rgba(66,133,244,.45); --lp-ib: rgba(66,133,244,.12); }
+
+/* Features 区 */
+/* Features 区 — 透明,格子透出 */
+.lp-features { background: transparent; }
+.lp-feat-grid {
+ display: grid; grid-template-columns: repeat(3,1fr); gap: 16px;
+ max-width: 1180px; margin-left: auto; margin-right: auto;
+}
+@media(max-width:900px){ .lp-feat-grid { grid-template-columns: repeat(2,1fr); } }
+@media(max-width:580px){ .lp-feat-grid { grid-template-columns: 1fr; } }
+.lp-feat-card {
+ background: var(--lp-card); border: 1px solid var(--lp-card-b);
+ border-radius: 14px; padding: 26px 24px;
+ transition: border-color .25s, transform .2s;
+}
+.lp-feat-card:hover { border-color: rgba(255,255,255,.14); transform: translateY(-3px); }
+.lp-feat-icon {
+ width: 36px; height: 36px; border-radius: 9px;
+ display: flex; align-items: center; justify-content: center;
+ font-size: 1rem; margin-bottom: 16px;
+}
+.lp-fi-teal { background: rgba(45,212,191,.12); }
+.lp-fi-blue { background: rgba(96,165,250,.12); }
+.lp-fi-green { background: rgba(52,211,153,.12); }
+.lp-fi-purple { background: rgba(139,92,246,.12); }
+.lp-fi-orange { background: rgba(251,146,60,.12); }
+.lp-fi-pink { background: rgba(244,114,182,.12); }
+.lp-feat-card h3 { font-size: .95rem; font-weight: 700; margin-bottom: 8px; color: var(--lp-text); }
+.lp-feat-card p { font-size: .85rem; color: var(--lp-dim); line-height: 1.7; }
+
+/* Comparison 区 */
+/* Comparison 区 — 实色 */
+.lp-comparison { background: #080d16; }
+.lp-cmp-wrap {
+ overflow-x: auto;
+ border: 1px solid var(--lp-card-b); border-radius: 14px; overflow: hidden;
+ max-width: 1180px; margin-left: auto; margin-right: auto;
+}
+.lp-cmp-table {
+ width: 100%; border-collapse: collapse; font-size: .88rem; color: var(--lp-text);
+}
+.lp-cmp-table th,
+.lp-cmp-table td { padding: 15px 22px; text-align: left; border-bottom: 1px solid rgba(255,255,255,.05); }
+.lp-cmp-table thead th {
+ background: rgba(255,255,255,.04);
+ font-size: .78rem; font-weight: 700; letter-spacing: .8px;
+ text-transform: uppercase; color: var(--lp-dim2);
+}
+.lp-cmp-table tbody tr:last-child td { border-bottom: none; }
+.lp-cmp-table tbody tr:nth-child(even) td { background: rgba(255,255,255,.018); }
+.lp-cmp-table tbody tr:hover td { background: rgba(255,255,255,.035); }
+.lp-cmp-table td:first-child { color: var(--lp-dim2); font-weight: 500; width: 140px; }
+.lp-th-claude { color: #e8a87c !important; }
+.lp-th-codex { color: #34d399 !important; }
+.lp-th-gemini { color: #60a5fa !important; }
+.lp-badge {
+ display: inline-flex; align-items: center; gap: 6px;
+ font-size: .78rem; font-weight: 600;
+ padding: 3px 10px; border-radius: 100px; border: 1px solid;
+}
+.lp-cb-claude { color: #e8a87c; border-color: rgba(205,133,63,.35); background: rgba(205,133,63,.08); }
+.lp-cb-codex { color: #34d399; border-color: rgba(52,211,153,.35); background: rgba(52,211,153,.08); }
+.lp-cb-gemini { color: #60a5fa; border-color: rgba(96,165,250,.35); background: rgba(96,165,250,.08); }
+.lp-code-inline {
+ font-size: .83rem; padding: 2px 8px; border-radius: 5px;
+ font-family: 'Fira Code','Courier New',monospace;
+}
+
+/* Steps 区 */
+/* Steps 区 — 透明,格子透出 */
+.lp-steps { background: transparent; }
+.lp-steps-grid {
+ display: grid; grid-template-columns: repeat(3,1fr); gap: 16px;
+ max-width: 1180px; margin-left: auto; margin-right: auto;
+}
+@media(max-width:760px){ .lp-steps-grid { grid-template-columns: 1fr; } }
+.lp-step-card {
+ background: var(--lp-card); border: 1px solid var(--lp-card-b);
+ border-radius: 14px; padding: 28px 24px;
+ transition: border-color .25s, transform .2s; position: relative;
+}
+.lp-step-card:hover { border-color: rgba(45,212,191,.25); transform: translateY(-3px); }
+.lp-step-num {
+ font-size: .7rem; font-weight: 700; letter-spacing: 2px;
+ text-transform: uppercase; color: var(--lp-teal); margin-bottom: 16px;
+}
+.lp-step-icon {
+ width: 44px; height: 44px; border-radius: 12px;
+ background: rgba(45,212,191,.1); border: 1px solid rgba(45,212,191,.2);
+ display: flex; align-items: center; justify-content: center;
+ font-size: 1.2rem; margin-bottom: 18px;
+}
+.lp-step-card h3 { font-size: .95rem; font-weight: 700; margin-bottom: 8px; color: var(--lp-text); }
+.lp-step-card p { font-size: .85rem; color: var(--lp-dim); line-height: 1.7; margin-bottom: 18px; }
+.lp-step-cta {
+ display: inline-flex; align-items: center; gap: 6px;
+ color: var(--lp-teal); font-size: .83rem; font-weight: 600;
+ text-decoration: none; transition: gap .2s;
+}
+.lp-step-cta:hover { gap: 10px; }
+
+/* Steps CTA 块 */
+.lp-steps-cta {
+ margin-top: 36px;
+ background: linear-gradient(135deg, rgba(45,212,191,.08), rgba(139,92,246,.08));
+ border: 1px solid rgba(45,212,191,.18);
+ border-radius: 16px; padding: 36px 32px; text-align: center;
+ max-width: 1180px; margin-left: auto; margin-right: auto;
+}
+.lp-steps-cta h3 { font-size: 1.15rem; font-weight: 700; margin-bottom: 8px; color: var(--lp-text); }
+.lp-steps-cta p { font-size: .88rem; color: var(--lp-dim); margin-bottom: 22px; line-height: 1.65; }
+
+/* 代码块 */
+.lp-code-block {
+ margin: 40px auto 0;
+ background: rgba(255,255,255,.03);
+ border: 1px solid rgba(255,255,255,.07);
+ border-radius: 14px; padding: 24px 28px;
+ max-width: 620px;
+}
+.lp-code-dots { display: flex; gap: 7px; margin-bottom: 16px; align-items: center; }
+.lp-dot-r { width: 11px; height: 11px; border-radius: 50%; background: #ff5f57; flex-shrink: 0; }
+.lp-dot-y { width: 11px; height: 11px; border-radius: 50%; background: #febc2e; flex-shrink: 0; }
+.lp-dot-g { width: 11px; height: 11px; border-radius: 50%; background: #28c840; flex-shrink: 0; }
+.lp-code-block code {
+ display: block; line-height: 1.85;
+ color: #c9d1d9; overflow-x: auto; white-space: pre;
+ font-family: 'Fira Code','Courier New',monospace; font-size: .83rem;
+}
+.lp-ck { color: #7c6aff; }
+.lp-cs { color: #3ecfcf; }
+.lp-cv { color: #f97316; }
+
+/* Big CTA 区 */
+/* Big CTA 区 — 实色 */
+.lp-big-cta { background: #080d16; padding: 88px 5%; text-align: center; }
+.lp-big-cta .lp-s-title { margin-bottom: 12px; }
+.lp-big-cta p { color: var(--lp-dim); font-size: .95rem; margin-bottom: 32px; }
+.lp-cta-btns { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; }
+
+/* 按钮 */
+.lp-btn-teal {
+ display: inline-flex; align-items: center; gap: 8px;
+ padding: 11px 26px; border-radius: 10px;
+ background: var(--lp-teal); color: #0a1a18;
+ font-size: .9rem; font-weight: 700;
+ text-decoration: none; border: none; cursor: pointer;
+ transition: opacity .2s, transform .15s;
+}
+.lp-btn-teal:hover { opacity: .88; transform: translateY(-2px); }
+.lp-btn-outline {
+ display: inline-flex; align-items: center; gap: 8px;
+ padding: 11px 24px; border-radius: 10px;
+ background: transparent; color: var(--lp-dim);
+ font-size: .88rem; font-weight: 500; text-decoration: none;
+ border: 1px solid rgba(255,255,255,.12);
+ transition: all .2s;
+}
+.lp-btn-outline:hover { border-color: rgba(255,255,255,.28); color: var(--lp-text); }
+
+/* FAQ 区 */
+/* FAQ 区 — 透明,格子透出 */
+.lp-faq { background: transparent; padding: 88px 5%; }
+.lp-faq-list {
+ max-width: 760px; margin: 0 auto;
+ display: flex; flex-direction: column; gap: 2px;
+}
+.lp-faq-item {
+ border: 1px solid var(--lp-card-b); border-radius: 12px;
+ background: var(--lp-card); overflow: hidden;
+ transition: border-color .2s;
+}
+.lp-faq-item:hover { border-color: rgba(255,255,255,.13); }
+.lp-faq-item.lp-open { border-color: rgba(45,212,191,.2); }
+.lp-faq-q {
+ width: 100%; display: flex; align-items: center; justify-content: space-between;
+ padding: 18px 22px; background: none; border: none;
+ cursor: pointer; color: var(--lp-text); font-size: .9rem; font-weight: 500;
+ text-align: left; gap: 12px;
+}
+.lp-faq-arrow { color: var(--lp-dim2); flex-shrink: 0; transition: transform .25s; font-size: .8rem; }
+.lp-faq-item.lp-open .lp-faq-arrow { transform: rotate(180deg); }
+.lp-faq-a {
+ max-height: 0; overflow: hidden;
+ transition: max-height .3s ease, padding .3s;
+ padding: 0 22px;
+}
+.lp-faq-item.lp-open .lp-faq-a { max-height: 200px; padding: 0 22px 18px; }
+.lp-faq-a p { font-size: .87rem; color: var(--lp-dim); line-height: 1.75; }
+
+/* Footer — 实色压底 */
+.lp-footer {
+ background: #060a12;
+ border-top: 1px solid rgba(255,255,255,.06);
+ padding: 56px 5% 28px;
+}
+.lp-footer-grid {
+ display: grid; grid-template-columns: 2fr 1fr 1fr 1fr; gap: 40px; margin-bottom: 48px;
+}
+@media(max-width:800px){ .lp-footer-grid { grid-template-columns: 1fr 1fr; } }
+@media(max-width:480px){ .lp-footer-grid { grid-template-columns: 1fr; } }
+.lp-footer-logo {
+ display: flex; align-items: center; gap: 9px;
+ font-size: 1rem; font-weight: 700; color: var(--lp-text);
+ text-decoration: none; margin-bottom: 12px;
+}
+.lp-footer-brand p {
+ font-size: .85rem; color: var(--lp-dim2); line-height: 1.7;
+ max-width: 240px; margin-bottom: 16px;
+}
+.lp-footer-chips { display: flex; gap: 6px; flex-wrap: wrap; }
+.lp-footer-chip {
+ font-size: .74rem; padding: 3px 9px; border-radius: 6px;
+ border: 1px solid rgba(255,255,255,.08); color: var(--lp-dim2);
+}
+.lp-footer-col h4 {
+ font-size: .75rem; font-weight: 700; letter-spacing: 1px;
+ text-transform: uppercase; color: var(--lp-dim2); margin-bottom: 14px;
+}
+.lp-footer-col ul { list-style: none; padding: 0; display: flex; flex-direction: column; gap: 9px; }
+.lp-footer-col ul li a {
+ color: var(--lp-dim2); text-decoration: none; font-size: .86rem; transition: color .2s;
+}
+.lp-footer-col ul li a:hover { color: var(--lp-text); }
+.lp-footer-bottom {
+ display: flex; align-items: center; justify-content: space-between;
+ padding-top: 22px; border-top: 1px solid rgba(255,255,255,.05);
+ font-size: .8rem; color: rgba(255,255,255,.25); flex-wrap: wrap; gap: 8px;
+}
+.lp-footer-bottom a { color: rgba(255,255,255,.25); text-decoration: none; }
+.lp-footer-bottom a:hover { color: var(--lp-dim2); }
+
+/* 登录/注册 深色背景 */
+.lp-auth-page {
+ background:
+ radial-gradient(ellipse 60% 50% at 70% 30%, rgba(0,200,150,.18) 0%, transparent 60%),
+ radial-gradient(ellipse 50% 40% at 30% 70%, rgba(118,44,248,.15) 0%, transparent 60%),
+ #0e1520;
+ color: #dde3ee;
+ font-family: 'Inter', 'Noto Sans SC', system-ui, sans-serif;
+}
+
+/* 登录/注册主区域 */
+.lp-auth-main {
+ flex: 1;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 80px 20px 40px;
+ min-height: inherit;
+}
+
+/* 卡片 */
+.lp-auth-card {
+ position: relative;
+ z-index: 1;
+ width: 100%;
+ max-width: 480px;
+ text-align: center;
+}
+
+/* Logo行 */
+.lp-auth-logo-row {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 9px;
+ margin-bottom: 24px;
+}
+.lp-auth-brand {
+ font-size: 1.05rem;
+ font-weight: 700;
+ color: #dde3ee;
+}
+
+/* 标题 */
+.lp-auth-title {
+ font-size: 1.75rem !important;
+ font-weight: 800 !important;
+ color: #ffffff !important;
+ letter-spacing: -.5px;
+ margin-bottom: 10px;
+}
+
+/* 副标题 */
+.lp-auth-sub {
+ font-size: .9rem;
+ color: rgba(221,227,238,.5);
+ margin-bottom: 28px;
+}
+.lp-auth-link {
+ color: #2dd4bf !important;
+ text-decoration: none !important;
+ font-weight: 500;
+ transition: opacity .2s;
+ cursor: pointer;
+}
+.lp-auth-link:hover { opacity: .75; }
+
+/* 原生 input 样式 */
+.lp-input {
+ width: 100%;
+ padding: 14px 16px 14px 44px;
+ background: rgba(255,255,255,.05);
+ border: 1px solid rgba(255,255,255,.1);
+ border-radius: 10px;
+ color: #dde3ee;
+ font-size: .93rem;
+ font-family: inherit;
+ outline: none;
+ transition: border-color .2s, background .2s;
+}
+.lp-input::placeholder { color: rgba(221,227,238,.32); }
+.lp-input:focus {
+ border-color: rgba(45,212,191,.45);
+ background: rgba(255,255,255,.07);
+}
+
+/* 表单输入行 */
+.lp-form-group {
+ margin-bottom: 16px;
+ position: relative;
+ text-align: left;
+}
+.lp-form-icon {
+ position: absolute;
+ left: 14px;
+ top: 50%;
+ transform: translateY(-50%);
+ color: rgba(221,227,238,.32);
+ font-size: 1rem;
+ pointer-events: none;
+ z-index: 2;
+}
+.lp-form-group .semi-input-wrapper,
+.lp-form-group .semi-input {
+ width: 100% !important;
+ padding: 14px 16px 14px 44px !important;
+ background: rgba(255,255,255,.05) !important;
+ border: 1px solid rgba(255,255,255,.1) !important;
+ border-radius: 10px !important;
+ color: #dde3ee !important;
+ font-size: .93rem !important;
+ outline: none;
+ transition: border-color .2s, background .2s;
+}
+.lp-form-group .semi-input-wrapper:focus-within {
+ border-color: rgba(45,212,191,.45) !important;
+ background: rgba(255,255,255,.07) !important;
+}
+.lp-form-group .semi-input::placeholder { color: rgba(221,227,238,.32) !important; }
+/* 去掉 semi-ui 的 label */
+.lp-form-group .semi-form-field-label { display: none !important; }
+.lp-form-group .semi-form-field { margin-bottom: 0 !important; }
+
+/* 验证码行 */
+.lp-code-row {
+ display: flex;
+ gap: 10px;
+ margin-bottom: 16px;
+ align-items: stretch;
+}
+.lp-btn-send-code {
+ flex-shrink: 0;
+ padding: 0 16px;
+ border-radius: 10px;
+ border: 1px solid rgba(45,212,191,.4);
+ background: rgba(45,212,191,.1);
+ color: #2dd4bf;
+ font-size: .83rem;
+ font-weight: 600;
+ font-family: inherit;
+ cursor: pointer;
+ white-space: nowrap;
+ transition: all .2s;
+}
+.lp-btn-send-code:hover { background: rgba(45,212,191,.2); }
+.lp-btn-send-code:disabled { opacity: .5; cursor: not-allowed; }
+
+/* 协议行 */
+.lp-auth-terms, .lp-terms-row {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ margin-bottom: 20px;
+ text-align: left;
+}
+.lp-auth-terms-text {
+ font-size: .85rem;
+ color: rgba(221,227,238,.5);
+}
+
+/* 提交按钮 */
+.lp-btn-submit {
+ width: 100%;
+ padding: 14px;
+ border: none;
+ border-radius: 10px;
+ background: linear-gradient(135deg, #2dd4bf, #8b5cf6);
+ color: #fff;
+ font-size: 1rem;
+ font-weight: 700;
+ font-family: inherit;
+ cursor: pointer;
+ letter-spacing: .02em;
+ transition: opacity .2s, transform .15s;
+ margin-bottom: 8px;
+}
+.lp-btn-submit:hover { opacity: .88; transform: translateY(-1px); }
+.lp-btn-submit:active { transform: translateY(0); }
+.lp-btn-submit:disabled { opacity: .5; cursor: not-allowed; transform: none; }
+
+/* 忘记密码按钮 */
+.lp-btn-forgot {
+ width: 100%;
+ padding: 10px;
+ border: none;
+ background: transparent;
+ color: #2dd4bf;
+ font-size: .88rem;
+ font-family: inherit;
+ cursor: pointer;
+ transition: opacity .2s;
+ margin-bottom: 4px;
+}
+.lp-btn-forgot:hover { opacity: .75; }
+
+/* 其他选项按钮 */
+.lp-btn-other-options {
+ width: 100%;
+ padding: 12px;
+ border: 1px solid rgba(255,255,255,.12);
+ border-radius: 10px;
+ background: transparent;
+ color: rgba(221,227,238,.6);
+ font-size: .88rem;
+ font-family: inherit;
+ cursor: pointer;
+ transition: all .2s;
+}
+.lp-btn-other-options:hover {
+ border-color: rgba(255,255,255,.25);
+ color: #dde3ee;
+ background: rgba(255,255,255,.04);
+}
+
+/* 分隔线 */
+.lp-auth-divider {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ margin: 18px 0;
+ color: rgba(221,227,238,.3);
+ font-size: .83rem;
+}
+.lp-auth-divider::before,
+.lp-auth-divider::after {
+ content: '';
+ flex: 1;
+ height: 1px;
+ background: rgba(255,255,255,.1);
+}
+
+/* OAuth 按钮列表 */
+.lp-auth-oauth-list { display: flex; flex-direction: column; gap: 10px; }
+.lp-auth-oauth-btn,
+.lp-auth-oauth-list .semi-button {
+ width: 100% !important;
+ height: 48px !important;
+ border-radius: 10px !important;
+ border: 1px solid rgba(255,255,255,.12) !important;
+ background: rgba(255,255,255,.04) !important;
+ color: #dde3ee !important;
+ font-size: .9rem !important;
+ transition: all .2s !important;
+ display: flex !important;
+ align-items: center !important;
+ justify-content: center !important;
+}
+.lp-auth-oauth-btn:hover,
+.lp-auth-oauth-list .semi-button:hover {
+ border-color: rgba(255,255,255,.22) !important;
+ background: rgba(255,255,255,.07) !important;
+}
+/* OAuth 主登录按钮(solid primary)覆盖 */
+.lp-auth-oauth-list .semi-button-primary.semi-button-solid {
+ background: linear-gradient(135deg, #2dd4bf, #8b5cf6) !important;
+ border: none !important;
+ color: #fff !important;
+ font-weight: 700 !important;
+}
+
+/* Semi UI 表单控件在 lp-auth-page 里的深色覆盖 */
+.lp-auth-page .semi-input-wrapper,
+.lp-auth-page .semi-input {
+ background: rgba(255,255,255,.05) !important;
+ border: 1px solid rgba(255,255,255,.1) !important;
+ color: #dde3ee !important;
+}
+.lp-auth-page .semi-input-wrapper:focus-within {
+ border-color: rgba(45,212,191,.45) !important;
+ background: rgba(255,255,255,.07) !important;
+}
+.lp-auth-page .semi-input::placeholder { color: rgba(221,227,238,.32) !important; }
+.lp-auth-page .semi-checkbox-inner { border-color: rgba(255,255,255,.2) !important; }
+.lp-auth-page .semi-checkbox-addon { color: rgba(221,227,238,.5) !important; }
+
+/* Benefits 区块 */
+.lp-benefits {
+ margin-top: 36px;
+ border-top: 1px solid rgba(255,255,255,.07);
+ padding-top: 24px;
+ text-align: left;
+}
+.lp-benefits-title {
+ font-size: .78rem;
+ color: rgba(221,227,238,.32);
+ margin-bottom: 14px;
+ letter-spacing: .5px;
+ text-transform: uppercase;
+}
+.lp-benefit-item {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ font-size: .88rem;
+ color: rgba(221,227,238,.5);
+ margin-bottom: 10px;
+}
+.lp-benefit-item::before {
+ content: '✓';
+ color: #2dd4bf;
+ font-weight: 700;
+ font-size: .9rem;
+ flex-shrink: 0;
+}
+
+/* 旧的 benefits 类名兼容 */
+.lp-auth-benefits {
+ margin-top: 36px;
+ border-top: 1px solid rgba(255,255,255,.07);
+ padding-top: 24px;
+ text-align: left;
+}
+.lp-auth-benefits-title {
+ font-size: .78rem;
+ color: rgba(221,227,238,.32);
+ margin-bottom: 14px;
+ letter-spacing: .5px;
+ text-transform: uppercase;
+}
+.lp-auth-benefit-item {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ font-size: .88rem;
+ color: rgba(221,227,238,.5);
+ margin-bottom: 10px;
+}
+.lp-auth-benefit-item::before {
+ content: '✓';
+ color: #2dd4bf;
+ font-weight: 700;
+ font-size: .9rem;
+ flex-shrink: 0;
+}
diff --git a/web/src/pages/Home/index.jsx b/web/src/pages/Home/index.jsx
index c153c1b3..2776b012 100644
--- a/web/src/pages/Home/index.jsx
+++ b/web/src/pages/Home/index.jsx
@@ -17,103 +17,111 @@ along with this program. If not, see
.
For commercial licensing, please contact support@quantumnous.com
*/
-import React, { useContext, useEffect, useState } from 'react';
-import {
- Button,
- Typography,
- Input,
- ScrollList,
- ScrollItem,
-} from '@douyinfe/semi-ui';
-import { API, showError, copy, showSuccess } from '../../helpers';
-import { useIsMobile } from '../../hooks/common/useIsMobile';
-import { API_ENDPOINTS } from '../../constants/common.constant';
+import React, { useContext, useEffect, useState, useRef } from 'react';
+import { API } from '../../helpers';
import { StatusContext } from '../../context/Status';
import { useActualTheme } from '../../context/Theme';
import { marked } from 'marked';
import { useTranslation } from 'react-i18next';
-import {
- IconGithubLogo,
- IconPlay,
- IconFile,
- IconCopy,
-} from '@douyinfe/semi-icons';
import { Link } from 'react-router-dom';
import NoticeModal from '../../components/layout/NoticeModal';
-import {
- Moonshot,
- OpenAI,
- XAI,
- Zhipu,
- Volcengine,
- Cohere,
- Claude,
- Gemini,
- Suno,
- Minimax,
- Wenxin,
- Spark,
- Qingyan,
- DeepSeek,
- Qwen,
- Midjourney,
- Grok,
- AzureAI,
- Hunyuan,
- Xinference,
-} from '@lobehub/icons';
+import { useIsMobile } from '../../hooks/common/useIsMobile';
-const { Text } = Typography;
+/* ──────────────────────────────────────────────
+ 运行时间计时器(起始时间:2025-01-01 00:00:00)
+────────────────────────────────────────────── */
+const START_TIME = new Date('2025-09-12T00:00:00+08:00').getTime();
+const UptimeCounter = () => {
+ const calc = () => {
+ const diff = Date.now() - START_TIME;
+ const s = Math.floor(diff / 1000);
+ return {
+ days: Math.floor(s / 86400),
+ hours: Math.floor((s % 86400) / 3600),
+ minutes: Math.floor((s % 3600) / 60),
+ seconds: s % 60,
+ };
+ };
+ const [t, setT] = useState(calc);
+ useEffect(() => {
+ const id = setInterval(() => setT(calc()), 1000);
+ return () => clearInterval(id);
+ }, []);
+ const pad = n => String(n).padStart(2, '0');
+ return (
+
+
+ 本站已稳定运行
+ {t.days}天
+ {pad(t.hours)}时
+ {pad(t.minutes)}分
+ {pad(t.seconds)}秒
+
+ );
+};
+const FaqItem = ({ question, children, defaultOpen }) => {
+ const [open, setOpen] = useState(!!defaultOpen);
+ return (
+
+
+
+
+ );
+};
+
+/* ──────────────────────────────────────────────
+ 首页主组件
+────────────────────────────────────────────── */
const Home = () => {
- const { t, i18n } = useTranslation();
+ const { i18n } = useTranslation();
const [statusState] = useContext(StatusContext);
const actualTheme = useActualTheme();
const [homePageContentLoaded, setHomePageContentLoaded] = useState(false);
const [homePageContent, setHomePageContent] = useState('');
const [noticeVisible, setNoticeVisible] = useState(false);
const isMobile = useIsMobile();
- const isDemoSiteMode = statusState?.status?.demo_site_enabled || false;
- const docsLink = statusState?.status?.docs_link || '';
- const serverAddress =
- statusState?.status?.server_address || `${window.location.origin}`;
- const endpointItems = API_ENDPOINTS.map((e) => ({ value: e }));
- const [endpointIndex, setEndpointIndex] = useState(0);
- const isChinese = i18n.language.startsWith('zh');
+ /* 服务端配置的自定义首页内容(Markdown 或外链 URL) */
const displayHomePageContent = async () => {
- setHomePageContent(localStorage.getItem('home_page_content') || '');
- const res = await API.get('/api/home_page_content');
- const { success, message, data } = res.data;
- if (success) {
- let content = data;
- if (!data.startsWith('https://')) {
- content = marked.parse(data);
- }
- setHomePageContent(content);
- localStorage.setItem('home_page_content', content);
-
- // 如果内容是 URL,则发送主题模式
- if (data.startsWith('https://')) {
- const iframe = document.querySelector('iframe');
- if (iframe) {
- iframe.onload = () => {
- iframe.contentWindow.postMessage({ themeMode: actualTheme }, '*');
- iframe.contentWindow.postMessage({ lang: i18n.language }, '*');
- };
+ const cached = localStorage.getItem('home_page_content') || '';
+ setHomePageContent(cached);
+ try {
+ const res = await API.get('/api/home_page_content');
+ const { success, data } = res.data;
+ if (success && data && data.trim() !== '') {
+ let content = data;
+ if (!data.startsWith('https://')) {
+ content = marked.parse(data);
}
- }
- } else {
- showError(message);
- setHomePageContent('加载首页内容失败...');
- }
- setHomePageContentLoaded(true);
- };
+ setHomePageContent(content);
+ localStorage.setItem('home_page_content', content);
- const handleCopyBaseURL = async () => {
- const ok = await copy(serverAddress);
- if (ok) {
- showSuccess(t('已复制到剪切板'));
+ if (data.startsWith('https://')) {
+ const iframe = document.querySelector('iframe');
+ if (iframe) {
+ iframe.onload = () => {
+ iframe.contentWindow.postMessage({ themeMode: actualTheme }, '*');
+ iframe.contentWindow.postMessage({ lang: i18n.language }, '*');
+ };
+ }
+ }
+ setHomePageContentLoaded(true);
+ } else {
+ // 没有自定义内容,显示默认首页
+ localStorage.removeItem('home_page_content');
+ setHomePageContent('');
+ setHomePageContentLoaded(true);
+ }
+ } catch (e) {
+ // 网络错误/无后端,直接显示默认首页,不报错
+ setHomePageContent('');
+ setHomePageContentLoaded(true);
}
};
@@ -133,7 +141,6 @@ const Home = () => {
}
}
};
-
checkNoticeAndShow();
}, []);
@@ -141,214 +148,361 @@ const Home = () => {
displayHomePageContent().then();
}, []);
- useEffect(() => {
- const timer = setInterval(() => {
- setEndpointIndex((prev) => (prev + 1) % endpointItems.length);
- }, 3000);
- return () => clearInterval(timer);
- }, [endpointItems.length]);
+ /* 如果管理员设置了自定义首页内容,则显示那个 */
+ if (homePageContentLoaded && homePageContent !== '') {
+ return (
+
+ {homePageContent.startsWith('https://') ? (
+
+ ) : (
+
+ )}
+
+ );
+ }
+ /* ── 默认 Landing Page ── */
return (
-
+
setNoticeVisible(false)}
isMobile={isMobile}
/>
- {homePageContentLoaded && homePageContent === '' ? (
-
- {/* Banner 部分 */}
-
- {/* 背景模糊晕染球 */}
-
-
-
- {/* 居中内容区 */}
-
-
-
- <>
- {t('统一的')}
-
- {t('大模型接口网关')}
- >
-
-
- {t('更好的价格,更好的稳定性,只需要将模型基址替换为:')}
-
- {/* BASE URL 与端点选择 */}
-
-
-
- setEndpointIndex(index)}
- />
-
- }
- className='!rounded-full'
- />
-
- }
- />
-
-
- {/* 操作按钮 */}
-
-
- }
- >
- {t('获取密钥')}
-
-
- {isDemoSiteMode && statusState?.status?.version ? (
- }
- onClick={() =>
- window.open(
- 'https://github.com/QuantumNous/new-api',
- '_blank',
- )
- }
- >
- {statusState.status.version}
-
- ) : (
- docsLink && (
- }
- onClick={() => window.open(docsLink, '_blank')}
- >
- {t('文档')}
-
- )
- )}
-
+ {/* ═══════════════════ HERO ═══════════════════ */}
+
+
- {/* 框架兼容性图标 */}
-
-
-
- {t('支持众多的大模型供应商')}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 30+
-
-
-
-
-
-
+
+
+
+ OasisRelay
+ 全球加速 · 无需代理 · 物优价宜
+
+
+ 释放开发潜能,提升集成效率。为开发者打造的下一代 AI API 接入体验,让模型调用从未如此简单。
+
+
+
+
+
+
+ ⚡ Claude Code 支持
+ 🧠 Codex / o1 支持
+ 💫 Gemini CLI 支持
+
+
+
document.getElementById('lp-integrations')?.scrollIntoView({ behavior: 'smooth' })}
+ >
+
+
+
+
+
+
+ {/* ═══════════════════ INTEGRATIONS ═══════════════════ */}
+
+
- ) : (
-
- {homePageContent.startsWith('https://') ? (
-
- ) : (
-
- )}
+
- )}
+
+
+
+
+ {/* ═══════════════════ FEATURES ═══════════════════ */}
+
+ FEATURES
+ 开发者工具,专为国内链路优化
+ 享受无限制、更好的链路:代码、调试、计算、设计,一次解决。
+
+
+
🌐
+
专用转发网络
+
企业专级转发架构,国内直连延迟极低,Token 每次请求均走最优节点,稳定无抖动。
+
+
+
⚡
+
一键切换
+
单一端点支持 200+ 模型,更换模型只需改 model 字段,无需重配环境,一行 Token 走天下。
+
+
+
💰
+
超低使用成本
+
价格比官方低 30%~60%,无月费无订阅,按量付费,随充随用,适合个人与企业所有规模。
+
+
+
🛡️
+
省心合规运营
+
无需境外信用卡,支持支付宝/微信支付,合规采购 API 资源,安心用于商业项目。
+
+
+
🔌
+
针对性能优化
+
支持 Claude In Chrome 插件,提供内置 CLI 工具接入优化,针对 Claude Code 专项加速。
+
+
+
📊
+
使用统计
+
精细化使用记录与用量看板,计算账单明细,实时查看余额,轻松做预算规划。
+
+
+
+
+
+
+ {/* ═══════════════════ COMPARISON ═══════════════════ */}
+
+ COMPARISON
+ Claude Code · CodeX · Gemini CLI
+ 快速选择参考:更强调的工作流与集成推荐。
+
+
+
+
+ | 对比项 |
+ Claude Code |
+ CodeX |
+ Gemini CLI |
+
+
+
+
+ | 定位 |
+ 代码理解 / 重构 / 终端工作流 |
+ 代码生成 / 代理式终端工作流 |
+ 检索 · 辅助 · Google 生态工具 |
+
+
+ | 使用命令 |
+ claude |
+ codex |
+ gemini |
+
+
+ | 适合场景 |
+ 大型代码库、代码理解、项目级 |
+ 任务执行、代码生成与执行 |
+ 搜索增强、统筹型、图文理解 |
+
+
+ | 本平台能力 |
+ 国内直连 · 代码理解 · 终端调试 |
+ 国内直连 · 统一入口 · 所有能力 |
+ 国内直连 · 统一入口 · 所有能力 |
+
+
+ | 支持情况 |
+ ✓ 完整支持 |
+ ✓ 完整支持 |
+ ✓ 完整支持 |
+
+
+
+
+
+
+
+
+ {/* ═══════════════════ STEPS ═══════════════════ */}
+
+ QUICKSTART
+ 三步开始使用
+ 注册账号 → 创建 Token → 配置客户端,所有步骤不超过 5 分钟。
+
+
+
E1
+
🛒
+
购买充值
+
前往淘宝店铺选购适合的套餐,支持支付宝/微信支付,充值秒到账,即刻获得 API Token。
+
前往淘宝购买 →
+
+
+
E2
+
⚙️
+
安装客户端
+
根据你的客户端(Claude Code / CodeX / Gemini CLI),按照文档配置 API 端点与密钥。
+
查看安装文档 →
+
+
+
E3
+
🚀
+
开始使用
+
设定 CLI 中 base_url 与 token,运行测试命令,即可调用全球顶级 AI 模型,开始工作。
+
进入控制台 →
+
+
+
+
+
立即注册并进入一键安装页面
+
注册账号后在控制台可找到对应客户端一键配置脚本和详细安装教程链接。
+
🛒 前往淘宝购买
+
查看文档
+
+
+
+
+
+
+
+
+ Python · 快速接入示例
+
+
+
+ from{' openai '}
+ import{' OpenAI\n\n'}
+ {'client = OpenAI(\n'}
+ {' api_key='}
+ "your-api-key"
+ {',\n'}
+ {' base_url='}
+ "{window.location.origin}/v1"
+ {'\n)\n\nresponse = client.chat.completions.create(\n'}
+ {' model='}
+ "claude-sonnet-4-5"
+ {',\n'}
+ {' messages=[{'}
+ "role"
+ {': '}
+ "user"
+ {', '}
+ "content"
+ {': '}
+ "Hello!"
+ {'}]\n)\n'}
+ print
+ {'(response.choices['}
+ 0
+ {'].message.content)'}
+
+
+
+
+
+
+ {/* ═══════════════════ BIG CTA ═══════════════════ */}
+
+ GET STARTED
+ 立即开始使用 Claude Code、CodeX、Gemini CLI
+ 注册账号 · 创建 Token · 配置客户端,一个平台,一键搞定。
+
+
+
+
+
+ {/* ═══════════════════ FAQ ═══════════════════ */}
+
+ FAQ
+ 常见问题
+
+
+ 支持。我们提供按量充值和包月套餐两种方式,包月套餐性价比更高,适合高频使用的开发者。购买后额度即时到账,无需等待审核。
+
+
+ 完全兼容。本平台 100% 实现 OpenAI REST 接口规范,只需将 base_url 替换为本站地址,现有代码无需任何改动。
+
+
+ 请参考文档页面,文档中包含 Claude Code、CodeX、Gemini CLI 的详细接入步骤和配置示例。大多数客户端只需设置环境变量 ANTHROPIC_BASE_URL 和 API_KEY 即可。
+
+
+ 充值后秒级到账,无需等待。购买后的虚拟商品原则上不支持退款,如遇服务故障导致的损失,请联系客服处理。
+
+
+ 支持 Claude 全系列(Sonnet、Opus、Haiku)、GPT-4o / o1 / Codex、Gemini 1.5 Pro / Ultra / Flash、DeepSeek V3 / R1、Llama 3.x、Mistral 等 200+ 模型,并持续更新。
+
+
+
+
+
+
+ {/* ═══════════════════ FOOTER ═══════════════════ */}
+
);
};