From b47ea0dd3a7914b3b11539e9938b9238a52da2c6 Mon Sep 17 00:00:00 2001 From: wxj Date: Fri, 3 Jul 2026 16:40:56 +0800 Subject: [PATCH] =?UTF-8?q?=E9=A6=96=E9=A1=B5=E9=87=8D=E6=9E=84=E4=B8=BA?= =?UTF-8?q?=20TokenDance=20=E8=AE=BE=E8=AE=A1=E7=B3=BB=E7=BB=9F=20+=20Cont?= =?UTF-8?q?act=20=E9=A1=B5=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Home/index.jsx: 替换为 TokenDance 设计(紫色点缀、白色主题、TuringToken 品牌) - Contact/index.jsx: 新增联系销售页面 - EmptyState.jsx: 新增通用空状态组件 - i18n/locales: 中英文 i18n 资源同步新增 - i18n.js, utils.jsx: 配合新页面更新工具函数 - App.jsx, AdminInitialSetupModal.jsx, User context: 注册联系页路由及配套调整 --- web/src/App.jsx | 17 +- .../auth/AdminInitialSetupModal.jsx | 6 +- .../common/ui/CompactModeToggle.jsx | 2 +- web/src/components/common/ui/EmptyState.jsx | 69 ++ web/src/context/User/index.jsx | 5 +- web/src/helpers/utils.jsx | 14 +- web/src/i18n/i18n.js | 22 +- web/src/i18n/locales/en.json | 17 +- web/src/i18n/locales/zh-CN.json | 17 +- web/src/pages/Contact/index.jsx | 364 ++++++++ web/src/pages/Home/index.jsx | 877 +++++------------- 11 files changed, 748 insertions(+), 662 deletions(-) create mode 100644 web/src/components/common/ui/EmptyState.jsx create mode 100644 web/src/pages/Contact/index.jsx diff --git a/web/src/App.jsx b/web/src/App.jsx index 8743d54..f59e05d 100644 --- a/web/src/App.jsx +++ b/web/src/App.jsx @@ -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() { } /> + } key={location.pathname}> + + + } + /> . + +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 ( +
+
+ +
+ {titleText && ( +

+ {titleText} +

+ )} + {descText && ( +

+ {descText} +

+ )} + {!titleText && !descText && ( +

+ 暂无数据 +

+ )} + {children &&
{children}
} +
+ ); +}; + +export default EmptyState; diff --git a/web/src/context/User/index.jsx b/web/src/context/User/index.jsx index befdf8d..55ecd25 100644 --- a/web/src/context/User/index.jsx +++ b/web/src/context/User/index.jsx @@ -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({ diff --git a/web/src/helpers/utils.jsx b/web/src/helpers/utils.jsx index 431a36c..e431323 100644 --- a/web/src/helpers/utils.jsx +++ b/web/src/helpers/utils.jsx @@ -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; } diff --git a/web/src/i18n/i18n.js b/web/src/i18n/i18n.js index beb7e00..b50e1af 100644 --- a/web/src/i18n/i18n.js +++ b/web/src/i18n/i18n.js @@ -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', diff --git a/web/src/i18n/locales/en.json b/web/src/i18n/locales/en.json index 057d9c3..3e01312 100644 --- a/web/src/i18n/locales/en.json +++ b/web/src/i18n/locales/en.json @@ -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" } } \ No newline at end of file diff --git a/web/src/i18n/locales/zh-CN.json b/web/src/i18n/locales/zh-CN.json index ae8ed1d..4f76225 100644 --- a/web/src/i18n/locales/zh-CN.json +++ b/web/src/i18n/locales/zh-CN.json @@ -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,一拍压测。", + "定价": "定价" } } \ No newline at end of file diff --git a/web/src/pages/Contact/index.jsx b/web/src/pages/Contact/index.jsx new file mode 100644 index 0000000..e08e004 --- /dev/null +++ b/web/src/pages/Contact/index.jsx @@ -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 . + +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 ( +
+
+ {label}{required && *} +
+ +
+ ); +} + +function InfoCard({ icon, title, primary, sub }) { + return ( +
+
+
+ {icon} +
+
{title}
+
+
+
{primary}
+
{sub}
+
+
+ ); +} + +function MiniTopBar() { + return ( +
+
+ + logo + TuringToken + +
+ + 服务正常 · 99.95% +
+
+ + 控制台 + + + 免费注册 + +
+
+ ); +} + +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 ( +
+ + + {/* Hero */} +
+
+
+
+ + contact sales +
+

+ 告诉我们,
+ 你的 AI 场景。 +

+

+ 大客户、定制路由、长期合约、技术对接 — 都从这里开始。 +

+
+ + 24 小时内回复 + + + 可签 NDA + + + 无电销骚扰 + +
+
+
+ + {/* Form + Info */} +
+
+
+ {/* Form */} +
+
get in touch
+

+ 填一下,
我们 24h 内联系你。 +

+ +
+ + +
+
+ +
+ +
+
月调用量
+
+ + +
+
+ +
+
你的场景
+