Compare commits
2 Commits
6836012ab4
...
00b7755fe1
| Author | SHA1 | Date |
|---|---|---|
|
|
00b7755fe1 | |
|
|
b47ea0dd3a |
|
|
@ -5,7 +5,7 @@ import sys
|
|||
host = "26.0.12.13"
|
||||
user = "root"
|
||||
password = "root@1234"
|
||||
local_dist = r"C:\Users\wangxj\tokenFactory\web\dist"
|
||||
local_dist = r"D:\tuling_new\web\dist"
|
||||
remote_dist = "/root/tokenFactory/web/dist"
|
||||
|
||||
print("Connecting...")
|
||||
|
|
|
|||
|
|
@ -95,6 +95,11 @@ import LuckyBag from './pages/LuckyBag';
|
|||
import Drawing from './pages/Drawing';
|
||||
import ProfitDashboard from './pages/ProfitDashboard';
|
||||
import SettingsAntiAbuse from './pages/Setting/Operation/SettingsAntiAbuse';
|
||||
import Contact from './pages/Contact';
|
||||
import About from './pages/About';
|
||||
import UserAgreement from './pages/UserAgreement';
|
||||
import PrivacyPolicy from './pages/PrivacyPolicy';
|
||||
import Docs from './pages/Docs';
|
||||
|
||||
const Home = lazy(() => import('./pages/Home'));
|
||||
const Dashboard = lazy(() => import('./pages/Dashboard'));
|
||||
|
|
@ -102,10 +107,6 @@ const DistributorApply = lazy(() => import('./pages/DistributorApply'));
|
|||
const DistributorCenter = lazy(() => import('./pages/DistributorCenter'));
|
||||
const DistributorAdmin = lazy(() => import('./pages/DistributorAdmin'));
|
||||
const InviteRedirect = lazy(() => import('./pages/InviteRedirect'));
|
||||
const About = lazy(() => import('./pages/About'));
|
||||
const UserAgreement = lazy(() => import('./pages/UserAgreement'));
|
||||
const PrivacyPolicy = lazy(() => import('./pages/PrivacyPolicy'));
|
||||
const Docs = lazy(() => import('./pages/Docs'));
|
||||
|
||||
function DynamicOAuth2Callback() {
|
||||
const { provider } = useParams();
|
||||
|
|
@ -545,6 +546,14 @@ function App() {
|
|||
</Suspense>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path='/contact'
|
||||
element={
|
||||
<Suspense fallback={<Loading></Loading>} key={location.pathname}>
|
||||
<Contact />
|
||||
</Suspense>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path='/docs'
|
||||
element={
|
||||
|
|
|
|||
|
|
@ -15,16 +15,16 @@ import React, {
|
|||
useRef,
|
||||
useState,
|
||||
} from 'react';
|
||||
import { Modal, Form, Typography, Space, Button } from '@douyinfe/semi-ui';
|
||||
import { IconLock } from '@douyinfe/semi-icons';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { UserContext } from '../../context/User';
|
||||
import { Lock as IconLock } from 'lucide-react';
|
||||
import { Modal, Form, Typography, Space, Button } from '@douyinfe/semi-ui';
|
||||
import {
|
||||
API,
|
||||
showError,
|
||||
showSuccess,
|
||||
mergeSelfResponseIntoLocalUser,
|
||||
} from '../../helpers';
|
||||
import { UserContext } from '../../context/User';
|
||||
import { buildAdminUserPhoneFieldRules } from '../table/users/modals/userPhoneFormRules';
|
||||
|
||||
const { Text, Title } = Typography;
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@ For commercial licensing, please contact support@quantumnous.com
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { Button } from '@douyinfe/semi-ui';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Button } from '@douyinfe/semi-ui';
|
||||
import { useIsMobile } from '../../../hooks/common/useIsMobile';
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
Copyright (C) 2025 QuantumNous
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
For commercial licensing, please contact support@quantumnous.com
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { Inbox } from 'lucide-react';
|
||||
|
||||
const ACC = '#635BFF';
|
||||
const ACC_SOFT = '#EEEBFF';
|
||||
const INK = '#0A2540';
|
||||
const SUB = '#425466';
|
||||
const DIM = '#697386';
|
||||
|
||||
const toText = (v) =>
|
||||
typeof v === 'string'
|
||||
? v
|
||||
: v?.props?.children || '';
|
||||
|
||||
const EmptyState = ({ icon, title, description, children, style }) => {
|
||||
const Icon = icon || Inbox;
|
||||
const titleText = toText(title);
|
||||
const descText = toText(description);
|
||||
return (
|
||||
<div
|
||||
className='flex flex-col items-center justify-center py-12 text-center'
|
||||
style={style}
|
||||
>
|
||||
<div
|
||||
className='inline-flex h-12 w-12 items-center justify-center rounded-2xl'
|
||||
style={{ background: ACC_SOFT, color: ACC }}
|
||||
>
|
||||
<Icon size={22} />
|
||||
</div>
|
||||
{titleText && (
|
||||
<p className='mt-4 text-sm font-semibold' style={{ color: INK }}>
|
||||
{titleText}
|
||||
</p>
|
||||
)}
|
||||
{descText && (
|
||||
<p className='mt-1 text-sm' style={{ color: DIM }}>
|
||||
{descText}
|
||||
</p>
|
||||
)}
|
||||
{!titleText && !descText && (
|
||||
<p className='mt-4 text-sm' style={{ color: DIM }}>
|
||||
暂无数据
|
||||
</p>
|
||||
)}
|
||||
{children && <div className='mt-4'>{children}</div>}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default EmptyState;
|
||||
|
|
@ -19,9 +19,10 @@ For commercial licensing, please contact support@quantumnous.com
|
|||
|
||||
import React, { useEffect } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { reducer, initialState } from './reducer';
|
||||
import { API } from '../../helpers/api';
|
||||
import { initialState, reducer } from './reducer';
|
||||
import { mergeSelfResponseIntoLocalUser } from '../../helpers/data';
|
||||
import { normalizeLanguage } from '../../i18n/language';
|
||||
import { API, mergeSelfResponseIntoLocalUser } from '../../helpers';
|
||||
import AdminInitialSetupModal from '../../components/auth/AdminInitialSetupModal';
|
||||
|
||||
export const UserContext = React.createContext({
|
||||
|
|
|
|||
|
|
@ -18,15 +18,12 @@ For commercial licensing, please contact support@quantumnous.com
|
|||
*/
|
||||
|
||||
import { Toast, Pagination } from '@douyinfe/semi-ui';
|
||||
import { toastConstants } from '../constants';
|
||||
import React from 'react';
|
||||
import { toast } from 'react-toastify';
|
||||
import {
|
||||
THINK_TAG_REGEX,
|
||||
MESSAGE_ROLES,
|
||||
} from '../constants/playground.constants';
|
||||
import { TABLE_COMPACT_MODES_KEY } from '../constants';
|
||||
import { USER_ROLES } from '../constants/user.constants';
|
||||
import { toastConstants } from '../constants/toast.constants';
|
||||
import { MOBILE_BREAKPOINT } from '../hooks/common/useIsMobile';
|
||||
|
||||
const HTMLToastContent = ({ htmlContent }) => {
|
||||
|
|
@ -144,6 +141,15 @@ export function parseCommissionPercentStringToBps(s) {
|
|||
export function getSystemName() {
|
||||
let system_name = localStorage.getItem('system_name');
|
||||
if (!system_name) return 'TuringToken';
|
||||
// 旧品牌名缓存迁移:清掉 TokenFactory / TokenFactoryOpen / 开放词元工厂 等历史默认,避免登录页/控制台标题闪烁。
|
||||
if (
|
||||
system_name === 'TokenFactory' ||
|
||||
system_name === 'TokenFactoryOpen' ||
|
||||
system_name === '开放词元工厂'
|
||||
) {
|
||||
localStorage.setItem('system_name', 'TuringToken');
|
||||
return 'TuringToken';
|
||||
}
|
||||
return system_name;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,17 +39,17 @@ i18n
|
|||
load: 'currentOnly',
|
||||
supportedLngs: supportedLanguages,
|
||||
resources: {
|
||||
en: enTranslation,
|
||||
'zh-CN': zhCNTranslation,
|
||||
'zh-TW': zhTWTranslation,
|
||||
fr: frTranslation,
|
||||
ru: ruTranslation,
|
||||
ja: jaTranslation,
|
||||
vi: viTranslation,
|
||||
id: idTranslation,
|
||||
ms: msTranslation,
|
||||
th: thTranslation,
|
||||
sw: swTranslation,
|
||||
en: { translation: enTranslation },
|
||||
'zh-CN': { translation: zhCNTranslation },
|
||||
'zh-TW': { translation: zhTWTranslation },
|
||||
fr: { translation: frTranslation },
|
||||
ru: { translation: ruTranslation },
|
||||
ja: { translation: jaTranslation },
|
||||
vi: { translation: viTranslation },
|
||||
id: { translation: idTranslation },
|
||||
ms: { translation: msTranslation },
|
||||
th: { translation: thTranslation },
|
||||
sw: { translation: swTranslation },
|
||||
},
|
||||
fallbackLng: 'zh-CN',
|
||||
lng: 'zh-CN',
|
||||
|
|
|
|||
|
|
@ -5695,6 +5695,21 @@
|
|||
"主题切换": "Theme Toggle",
|
||||
"顶栏显示主题切换按钮,允许用户切换亮色/暗色模式": "Show theme toggle in header bar, allowing users to switch between light/dark mode",
|
||||
"语言选择器": "Language Selector",
|
||||
"顶栏显示语言选择器,允许用户切换界面语言": "Show language selector in header bar, allowing users to switch interface language"
|
||||
"顶栏显示语言选择器,允许用户切换界面语言": "Show language selector in header bar, allowing users to switch interface language",
|
||||
"All systems normal": "All systems normal",
|
||||
"调用 AI 像调用函": "Call AI like calling a",
|
||||
"函数": "function",
|
||||
"一样轻。": "— that light.",
|
||||
"把 OpenAI、Claude、Gemini、DeepSeek 等几十个模型收进同一个 base_url,切换模型、改价格、改延迟,不必动客户端。": "Bring OpenAI, Claude, Gemini, DeepSeek and dozens of other models behind a single base_url. Switch models, pricing, latency — no client changes.",
|
||||
"免费注册": "Sign up free",
|
||||
"联系销售": "Contact sales",
|
||||
"注册即送 ¥10": "¥10 free credits on signup",
|
||||
"无月费": "No monthly fee",
|
||||
"比开放透明": "Transparent pricing",
|
||||
"你的客户端只需一句": "Your client only needs one",
|
||||
",其余的事——路由、价格、容灾——都替你做了。": ", and we handle routing, pricing, and failover for you.",
|
||||
"立即接入。": "Integrate now.",
|
||||
"注册送 ¥10 试用金,分键跑完一组 benchmark,一拍压测。": "Get ¥10 trial credit on signup. Run a benchmark, then a load test.",
|
||||
"定价": "Pricing"
|
||||
}
|
||||
}
|
||||
|
|
@ -5554,6 +5554,21 @@
|
|||
"主题切换": "主题切换",
|
||||
"顶栏显示主题切换按钮,允许用户切换亮色/暗色模式": "顶栏显示主题切换按钮,允许用户切换亮色/暗色模式",
|
||||
"语言选择器": "语言选择器",
|
||||
"顶栏显示语言选择器,允许用户切换界面语言": "顶栏显示语言选择器,允许用户切换界面语言"
|
||||
"顶栏显示语言选择器,允许用户切换界面语言": "顶栏显示语言选择器,允许用户切换界面语言",
|
||||
"All systems normal": "All systems normal",
|
||||
"调用 AI 像调用函": "调用 AI 像调用函",
|
||||
"函数": "函数",
|
||||
"一样轻。": "一样轻。",
|
||||
"把 OpenAI、Claude、Gemini、DeepSeek 等几十个模型收进同一个 base_url,切换模型、改价格、改延迟,不必动客户端。": "把 OpenAI、Claude、Gemini、DeepSeek 等几十个模型收进同一个 base_url,切换模型、改价格、改延迟,不必动客户端。",
|
||||
"免费注册": "免费注册",
|
||||
"联系销售": "联系销售",
|
||||
"注册即送 ¥10": "注册即送 ¥10",
|
||||
"无月费": "无月费",
|
||||
"比开放透明": "比开放透明",
|
||||
"你的客户端只需一句": "你的客户端只需一句",
|
||||
",其余的事——路由、价格、容灾——都替你做了。": ",其余的事——路由、价格、容灾——都替你做了。",
|
||||
"立即接入。": "立即接入。",
|
||||
"注册送 ¥10 试用金,分键跑完一组 benchmark,一拍压测。": "注册送 ¥10 试用金,分键跑完一组 benchmark,一拍压测。",
|
||||
"定价": "定价"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,364 @@
|
|||
/*
|
||||
Copyright (C) 2025 QuantumNous
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
For commercial licensing, please contact support@quantumnous.com
|
||||
*/
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import { ArrowRight, Mail, MessageSquare, Building2, ShieldCheck, Check } from 'lucide-react';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
const ACC = '#635BFF';
|
||||
const ACC_SOFT = '#EEEBFF';
|
||||
const BG = '#FFFFFF';
|
||||
const SOFT = '#FBFAF7';
|
||||
const TINT = '#F6F4FF';
|
||||
const INK = '#0A2540';
|
||||
const SUB = '#425466';
|
||||
const DIM = '#697386';
|
||||
const LINE = '#E3E8EE';
|
||||
|
||||
function Field({ label, value, onChange, type = 'text', required = false, placeholder = '' }) {
|
||||
return (
|
||||
<div>
|
||||
<div className="mb-2 text-xs" style={{ color: DIM }}>
|
||||
{label}{required && <span style={{ color: ACC }}> *</span>}
|
||||
</div>
|
||||
<input
|
||||
type={type}
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
required={required}
|
||||
placeholder={placeholder}
|
||||
className="w-full rounded-lg border bg-white px-3.5 py-2.5 text-sm outline-none transition-colors focus:border-[#635BFF]"
|
||||
style={{ borderColor: LINE, color: INK }}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function InfoCard({ icon, title, primary, sub }) {
|
||||
return (
|
||||
<div
|
||||
className="rounded-xl border bg-white p-5 transition-all hover:-translate-y-0.5 hover:shadow-sm"
|
||||
style={{ borderColor: LINE }}
|
||||
>
|
||||
<div className="flex items-center gap-2.5">
|
||||
<div
|
||||
className="inline-flex h-8 w-8 items-center justify-center rounded-lg shrink-0"
|
||||
style={{ background: ACC_SOFT, color: ACC }}
|
||||
>
|
||||
{icon}
|
||||
</div>
|
||||
<div className="text-sm font-semibold tracking-tight" style={{ color: INK }}>{title}</div>
|
||||
</div>
|
||||
<div className="mt-3.5 pl-[42px]">
|
||||
<div className="text-[15px] font-medium" style={{ color: ACC }}>{primary}</div>
|
||||
<div className="mt-1 text-xs leading-[1.6]" style={{ color: DIM }}>{sub}</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function MiniTopBar() {
|
||||
return (
|
||||
<header className="sticky top-0 z-50 border-b border-[#E3E8EE] bg-white/85 backdrop-blur-md">
|
||||
<div className="flex h-16 items-center px-6 lg:px-10 max-w-[1200px] mx-auto">
|
||||
<Link to="/" className="flex items-center gap-2.5">
|
||||
<img src="/logo.jpg" alt="logo" className="h-7 w-7 rounded-full" />
|
||||
<span className="font-heading text-[15px] font-semibold tracking-tight" style={{ color: INK }}>TuringToken</span>
|
||||
</Link>
|
||||
<div className="hidden md:flex items-center gap-2 ml-6 rounded-full px-2.5 py-1 text-[11px]" style={{ background: '#F6F9FC', color: DIM }}>
|
||||
<span className="h-1.5 w-1.5 rounded-full bg-emerald-400" />
|
||||
<span>服务正常 · 99.95%</span>
|
||||
</div>
|
||||
<div className="flex-1" />
|
||||
<Link
|
||||
to="/console"
|
||||
className="inline-flex h-9 items-center rounded-full px-3.5 text-sm hover:bg-[#0A254006]"
|
||||
style={{ color: SUB }}
|
||||
>
|
||||
控制台
|
||||
</Link>
|
||||
<Link
|
||||
to="/register"
|
||||
className="ml-2 inline-flex h-9 items-center gap-1.5 rounded-full px-4 text-sm font-medium text-white hover:opacity-90"
|
||||
style={{ background: INK }}
|
||||
>
|
||||
免费注册 <ArrowRight size={12} />
|
||||
</Link>
|
||||
</div>
|
||||
</header>
|
||||
);
|
||||
}
|
||||
|
||||
export default function Contact() {
|
||||
const [form, setForm] = useState({
|
||||
company: '',
|
||||
name: '',
|
||||
email: '',
|
||||
volume: '',
|
||||
message: '',
|
||||
});
|
||||
const update = (k) => (e) => setForm({ ...form, [k]: e.target.value });
|
||||
const submit = (e) => {
|
||||
e.preventDefault();
|
||||
alert('已收到,我们会在 24 小时内联系你。');
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="min-h-screen" style={{ background: BG, color: INK }}>
|
||||
<MiniTopBar />
|
||||
|
||||
{/* Hero */}
|
||||
<section className="relative overflow-hidden" style={{ background: BG }}>
|
||||
<div
|
||||
className="pointer-events-none absolute inset-x-0 top-0 h-[600px]"
|
||||
style={{ background: 'radial-gradient(80% 60% at 50% 0%, #EEEBFF 0%, transparent 70%)' }}
|
||||
/>
|
||||
<div className="relative max-w-[1200px] mx-auto px-6 lg:px-10 pt-20 pb-14 lg:pt-28 lg:pb-20 text-center">
|
||||
<div className="inline-flex items-center gap-2 rounded-full border px-3 py-1.5 text-xs" style={{ borderColor: LINE, color: DIM }}>
|
||||
<span className="h-1.5 w-1.5 rounded-full" style={{ background: ACC }} />
|
||||
<span>contact sales</span>
|
||||
</div>
|
||||
<h1
|
||||
className="mt-6 font-heading font-semibold leading-[1.04] tracking-[-0.025em]"
|
||||
style={{ fontSize: 'clamp(40px, 5.4vw, 72px)', color: INK }}
|
||||
>
|
||||
告诉我们,<br />
|
||||
你的 <span style={{ color: ACC }}>AI 场景</span>。
|
||||
</h1>
|
||||
<p className="mt-6 mx-auto max-w-2xl text-base leading-[1.65]" style={{ color: SUB }}>
|
||||
大客户、定制路由、长期合约、技术对接 — 都从这里开始。
|
||||
</p>
|
||||
<div className="mt-8 flex flex-wrap items-center justify-center gap-6 text-xs" style={{ color: DIM }}>
|
||||
<span className="inline-flex items-center gap-1.5">
|
||||
<Check size={12} style={{ color: ACC }} /> 24 小时内回复
|
||||
</span>
|
||||
<span className="inline-flex items-center gap-1.5">
|
||||
<Check size={12} style={{ color: ACC }} /> 可签 NDA
|
||||
</span>
|
||||
<span className="inline-flex items-center gap-1.5">
|
||||
<Check size={12} style={{ color: ACC }} /> 无电销骚扰
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Form + Info */}
|
||||
<section style={{ background: BG }}>
|
||||
<div className="max-w-[1200px] mx-auto px-6 lg:px-10 pb-24">
|
||||
<div className="grid gap-8 lg:grid-cols-[1.4fr_1fr]">
|
||||
{/* Form */}
|
||||
<form
|
||||
onSubmit={submit}
|
||||
className="rounded-2xl border bg-white p-8 lg:p-10 shadow-sm"
|
||||
style={{ borderColor: LINE }}
|
||||
>
|
||||
<div className="font-mono text-[11px] uppercase tracking-[0.25em]" style={{ color: DIM }}>get in touch</div>
|
||||
<h2
|
||||
className="mt-4 font-heading text-2xl font-semibold leading-[1.2] tracking-tight lg:text-[32px]"
|
||||
style={{ color: INK }}
|
||||
>
|
||||
填一下,<br />我们 24h 内联系你。
|
||||
</h2>
|
||||
|
||||
<div className="mt-8 grid gap-5 md:grid-cols-2">
|
||||
<Field label="公司名" value={form.company} onChange={update('company')} required />
|
||||
<Field label="你的姓名" value={form.name} onChange={update('name')} required />
|
||||
</div>
|
||||
<div className="mt-5">
|
||||
<Field
|
||||
label="工作邮箱"
|
||||
type="email"
|
||||
value={form.email}
|
||||
onChange={update('email')}
|
||||
required
|
||||
placeholder="you@company.com"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="mt-5">
|
||||
<div className="mb-2 text-xs" style={{ color: DIM }}>月调用量</div>
|
||||
<div className="relative">
|
||||
<select
|
||||
value={form.volume}
|
||||
onChange={update('volume')}
|
||||
className="w-full appearance-none rounded-lg border bg-white pl-3.5 pr-9 py-2.5 text-sm outline-none transition-colors focus:border-[#635BFF]"
|
||||
style={{ borderColor: LINE, color: form.volume ? INK : DIM }}
|
||||
>
|
||||
<option value="">选择大致量级</option>
|
||||
<option>10 万以下</option>
|
||||
<option>10 万 – 100 万</option>
|
||||
<option>100 万 – 1000 万</option>
|
||||
<option>1000 万以上</option>
|
||||
<option>暂未确定</option>
|
||||
</select>
|
||||
<span className="pointer-events-none absolute right-3 top-1/2 -translate-y-1/2 text-xs" style={{ color: DIM }}>▾</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-5">
|
||||
<div className="mb-2 text-xs" style={{ color: DIM }}>你的场景</div>
|
||||
<textarea
|
||||
value={form.message}
|
||||
onChange={update('message')}
|
||||
rows={4}
|
||||
placeholder="例如:做企业知识库客服,需要稳定的 Claude + 国产模型双备援,月调用量约 300 万..."
|
||||
className="w-full rounded-lg border bg-white px-3.5 py-2.5 text-sm outline-none transition-colors focus:border-[#635BFF] resize-y"
|
||||
style={{ borderColor: LINE, color: INK }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="mt-7 flex flex-wrap items-center gap-4">
|
||||
<button
|
||||
type="submit"
|
||||
className="inline-flex h-11 items-center gap-2 rounded-full px-6 text-sm font-semibold text-white hover:opacity-90"
|
||||
style={{ background: INK }}
|
||||
>
|
||||
发送 <ArrowRight size={13} />
|
||||
</button>
|
||||
<span className="text-xs" style={{ color: DIM }}>
|
||||
提交即同意我们通过邮箱回访,仅一次
|
||||
</span>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
{/* Info side */}
|
||||
<div className="space-y-4">
|
||||
<InfoCard
|
||||
icon={<Mail size={16} />}
|
||||
title="销售咨询"
|
||||
primary="sales@turingtoken.ai"
|
||||
sub="工作日 24h 内回复;加急请电话"
|
||||
/>
|
||||
<InfoCard
|
||||
icon={<MessageSquare size={16} />}
|
||||
title="技术支持"
|
||||
primary="support@turingtoken.ai"
|
||||
sub="已签合约客户优先;P0 故障 1h 响应"
|
||||
/>
|
||||
<InfoCard
|
||||
icon={<ShieldCheck size={16} />}
|
||||
title="法务 / NDA"
|
||||
primary="legal@turingtoken.ai"
|
||||
sub="签前可先发 NDA 模板,含双向保密"
|
||||
/>
|
||||
<InfoCard
|
||||
icon={<Building2 size={16} />}
|
||||
title="办公室"
|
||||
primary="上海 · 北京 · 深圳"
|
||||
sub="仅预约接待,不接受 walk-in"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* FAQ */}
|
||||
<section style={{ background: SOFT }}>
|
||||
<div className="max-w-[1100px] mx-auto px-6 lg:px-10 py-24 lg:py-32">
|
||||
<div className="text-center">
|
||||
<div className="font-mono text-[11px] uppercase tracking-[0.25em]" style={{ color: DIM }}>frequently asked</div>
|
||||
<h2
|
||||
className="mt-4 font-heading text-3xl font-semibold tracking-tight lg:text-4xl"
|
||||
style={{ color: INK }}
|
||||
>
|
||||
常见问题。
|
||||
</h2>
|
||||
</div>
|
||||
<div className="mt-14 grid gap-5 md:grid-cols-2">
|
||||
{[
|
||||
{
|
||||
q: '支持私有化部署吗?',
|
||||
a: '支持。签约后 2–4 周内完成,含多模型路由、监控面板、计费、权限管理、SSO。',
|
||||
},
|
||||
{
|
||||
q: '大客户有专属价格吗?',
|
||||
a: '月调用量 100 万以上可谈。多数客户能拿到比 OpenAI 直连便宜 30%+ 的合约价。',
|
||||
},
|
||||
{
|
||||
q: '能签长期合约吗?',
|
||||
a: '可以。年付 / 季付都支持,附 SLA 99.95% 兜底,故障按比例退款。',
|
||||
},
|
||||
{
|
||||
q: '数据合规怎么做?',
|
||||
a: '全链路 TLS 1.3;境内流量走国内供应商;日志 30 天滚动删除;支持 GDPR 与个保法。',
|
||||
},
|
||||
].map((f, i) => (
|
||||
<div
|
||||
key={i}
|
||||
className="rounded-xl border bg-white p-6"
|
||||
style={{ borderColor: LINE }}
|
||||
>
|
||||
<h3 className="font-heading text-lg font-semibold tracking-tight" style={{ color: INK }}>{f.q}</h3>
|
||||
<p className="mt-3 text-sm leading-[1.7]" style={{ color: SUB }}>{f.a}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Closing */}
|
||||
<section className="relative overflow-hidden" style={{ background: BG }}>
|
||||
<div
|
||||
className="pointer-events-none absolute inset-x-0 bottom-0 h-[400px]"
|
||||
style={{ background: 'radial-gradient(60% 60% at 50% 100%, #EEEBFF 0%, transparent 70%)' }}
|
||||
/>
|
||||
<div className="relative mx-auto max-w-3xl px-6 lg:px-10 py-24 lg:py-32 text-center">
|
||||
<h2
|
||||
className="font-heading text-3xl font-semibold leading-tight tracking-[-0.02em] lg:text-[44px]"
|
||||
style={{ color: INK }}
|
||||
>
|
||||
先用起来,再聊。
|
||||
</h2>
|
||||
<p className="mt-5 text-base leading-[1.7]" style={{ color: SUB }}>
|
||||
注册送 ¥10 试跑金,足够跑完一组 benchmark、一轮压测。聊完再决定也不迟。
|
||||
</p>
|
||||
<div className="mt-9 flex flex-wrap items-center justify-center gap-3">
|
||||
<Link
|
||||
to="/register"
|
||||
className="inline-flex h-11 items-center gap-2 rounded-full px-6 text-sm font-semibold text-white hover:opacity-90"
|
||||
style={{ background: INK }}
|
||||
>
|
||||
免费注册 <ArrowRight size={13} />
|
||||
</Link>
|
||||
<Link
|
||||
to="/"
|
||||
className="inline-flex h-11 items-center gap-1.5 rounded-full border px-6 text-sm hover:bg-[#0A254006]"
|
||||
style={{ borderColor: INK, color: INK }}
|
||||
>
|
||||
先看首页
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Footer */}
|
||||
<footer className="border-t" style={{ borderColor: LINE, background: BG }}>
|
||||
<div className="max-w-[1200px] mx-auto px-6 lg:px-10 py-12">
|
||||
<div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
|
||||
<Link to="/" className="inline-flex items-center gap-2.5">
|
||||
<img src="/logo.jpg" alt="logo" className="h-7 w-7 rounded-full" />
|
||||
<span className="font-heading text-base font-semibold tracking-tight" style={{ color: INK }}>TuringToken</span>
|
||||
</Link>
|
||||
<span className="text-xs" style={{ color: DIM }}>© 2026 TuringToken · Made for developers.</span>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue