polish about page experience

This commit is contained in:
boos
2026-06-06 17:25:31 +08:00
parent f026582008
commit 13756adc9d
3 changed files with 833 additions and 239 deletions
+277 -120
View File
@@ -1,170 +1,327 @@
import { useEffect, useRef } from 'react';
import { gsap } from 'gsap';
import { tr } from '../i18n.js';
const VERSION = '1.3.0';
const FEATURES = [
{ icon: 'GW', title: '统一模型网关', desc: '一个入口聚合 OpenAI / Claude / Gemini / 方舟等兼容上游,统一鉴权、计费与日志。' },
{ icon: 'RT', title: '模型路由与容灾', desc: '按模型、账号、站点和通道优先级调度,失败后自动冷却并切换到可用通道。' },
{ icon: 'AC', title: '站点与账号管理', desc: '集中维护站点、账号、API Key、OAuth、下游 Key 和普通用户可用模型。' },
{ icon: 'MD', title: '模型广场', desc: '聚合各站点模型可用性、账号覆盖、绑定令牌与路由状态,便于快速修路由。' },
{ icon: 'WF', title: '工作流画布', desc: '内嵌 ComfyUI 前端,支持 Comfy Cloud、RunningHub、外部 ComfyUI 与 BoosAPI API-native 执行器。' },
{ icon: 'AG', title: '视频助手', desc: '面向工作流创作的对话助手,支持附件、多会话、用户 API Key 和模型路由选择。' },
{ icon: 'PI', title: '生图助手', desc: '提供提示词模板、比例尺寸控制和图像模型调用,管理员与普通用户均可使用。' },
{ icon: 'VD', title: '视频任务模板', desc: '支持火山方舟 Step1 创建视频任务、Step2 查询任务结果,并可复用 BoosAPI 模型路由。' },
{ icon: 'CK', title: '签到与余额刷新', desc: '按站点/账号执行签到、余额刷新、健康检查和连接状态追踪。' },
{ icon: 'NT', title: '通知与审计', desc: 'Webhook / Bark / Server酱 / Telegram / SMTP 告警,配合代理日志和程序事件排障。' },
const HERO_TAGS = [
'Unified API Gateway',
'Intelligent Routing',
'Cloud Workflow',
'Workspace Archive',
'Multimodal Agents',
];
const TECH_STACK = [
{ name: 'Rust', desc: '后端核心服务,提供代理、路由、认证、任务和静态资源服务。' },
{ name: 'Axum / Tokio', desc: '异步 HTTP 服务、SSE、后台任务和代理执行。' },
{ name: 'SQLx', desc: '类型化数据库访问与迁移管理。' },
{ name: 'SQLite', desc: '默认嵌入式数据库,适合单机部署和低运维成本场景。' },
{ name: 'React / Vite', desc: '管理后台、普通用户面板、模型测试器和 Agent 界面。' },
{ name: 'Workflow UI', desc: '内嵌官方 ComfyUI 前端资产,按后端模式代理 Cloud、RunningHub 或外部 ComfyUI。' },
{ name: 'Multi Backend', desc: '支持 cloud / runninghub / external / boosapi / docker 五种工作流后端配置。' },
const HERO_SIGNALS = [
{ value: 'OpenAI', label: '兼容协议' },
{ value: 'Claude', label: '消息入口' },
{ value: 'Comfy', label: '工作流前端' },
];
const CAPABILITIES = [
{
label: 'Gateway',
title: '统一模型入口',
desc: 'OpenAI、Claude、Responses、图像和视频接口集中到一套鉴权、计费和日志体系。',
stat: '/v1/*',
},
{
label: 'Routing',
title: '模型路由中枢',
desc: '按站点、账号、成本、健康度和冷却状态选择通道,失败后自动避让。',
stat: 'P0 / P1',
},
{
label: 'Workflow',
title: '工作流执行面',
desc: '嵌入官方 ComfyUI 前端,同时接入 Cloud、RunningHub、外部 ComfyUI 和 BoosAPI 执行器。',
stat: '5 modes',
},
{
label: 'Agents',
title: '多模态应用层',
desc: '生图助手、视频助手、数字人和短视频工厂复用同一套模型路由与用户 Key。',
stat: '4 apps',
},
];
const OPERATIONS = [
{ title: '站点与账号', desc: '维护上游站点、账号、OAuth、API Key、余额和连接状态。' },
{ title: '模型广场', desc: '聚合模型可用性、价格、账号覆盖、绑定令牌和路由健康度。' },
{ title: '用户体系', desc: '普通用户拥有独立 API Key、使用日志、工作空间和可见模型范围。' },
{ title: '审计告警', desc: '使用日志、程序日志、通知渠道和运行事件集中留痕。' },
{ title: '工作空间', desc: '只归档最终产出,按用户隔离图片、视频、音频和工作流资产。' },
{ title: '任务编排', desc: '后台生成、取消、查询、归档和失败原因追踪保持一致体验。' },
];
const ENDPOINTS = [
{ path: '/v1/chat/completions', desc: 'OpenAI 兼容对话代理,支持非流式与流式。' },
{ path: '/v1/messages', desc: 'Claude Messages API 兼容入口,支持 Anthropic 请求、响应和流式事件。' },
{ path: '/v1/responses', desc: 'Responses API 兼容代理,可接入支持该协议的上游。' },
{ path: '/v1/images/generations', desc: '图像生成代理,供生图助手和工作流图像节点使用。' },
{ path: '/v1/videos', desc: '视频生成任务入口,已适配火山方舟任务创建。' },
{ path: '/v1/videos/{id}', desc: '视频任务查询入口,已适配火山方舟任务轮询。' },
{ path: '/v1/models', desc: '仅暴露当前可路由、未冷却、账号有效的模型列表。' },
{ path: '/v1/chat/completions', desc: 'OpenAI 对话兼容入口,支持流式与非流式。' },
{ path: '/v1/messages', desc: 'Claude Messages API 兼容入口,支持 Anthropic 请求和事件。' },
{ path: '/v1/responses', desc: 'Responses API 入口,适配支持该协议的上游。' },
{ path: '/v1/images/generations', desc: '图像生成入口,供生图助手与工作流节点调用。' },
{ path: '/v1/videos', desc: '视频任务创建入口,可接火山方舟或 Comfy 视频模板。' },
{ path: '/v1/models', desc: '只暴露当前可路由、未冷却且账号有效的模型。' },
];
const WORKFLOW_BACKENDS = [
{ name: 'cloud', desc: 'Comfy Cloud API 后端,适合使用官方订阅能力和云端执行。' },
{ name: 'runninghub', desc: 'RunningHub API 后端,适合复用 RunningHub 插件、模型与工作流生态。' },
{ name: 'external', desc: '连接你自己部署的完整版 ComfyUI,BoosAPI 负责统一代理与嵌入。' },
{ name: 'boosapi', desc: '使用 Rust API-native 工作流执行器,直接调用后台模型路由。' },
{ name: 'docker', desc: '本地完整版 ComfyUI 模式,适合有本地 GPU 和完整模型目录的环境。' },
{ name: 'cloud', desc: 'Comfy Cloud API 后端,适合官方订阅和云端执行。' },
{ name: 'runninghub', desc: 'RunningHub API 后端,适合复用插件、模型和模板生态。' },
{ name: 'external', desc: '连接自部署完整版 ComfyUI,由 BossAI 统一代理和嵌入。' },
{ name: 'boosapi', desc: 'Rust API-native 执行器,直接调用后台模型路由。' },
{ name: 'docker', desc: '本地完整版 ComfyUI 模式,适合有 GPU 和完整模型目录的环境。' },
];
const TECH_STACK = [
'Rust',
'Axum',
'Tokio',
'SQLx',
'React',
'Vite',
'GSAP',
'ComfyUI Frontend',
];
export default function About() {
const rootRef = useRef<HTMLDivElement>(null);
useEffect(() => {
const root = rootRef.current;
if (!root) return undefined;
const mm = gsap.matchMedia();
mm.add(
{
reduceMotion: '(prefers-reduced-motion: reduce)',
isDesktop: '(min-width: 900px)',
},
(context) => {
const conditions = context.conditions || {};
const motionItems = Array.from(root.querySelectorAll<HTMLElement>('.about-motion-item'));
const orbitItems = Array.from(root.querySelectorAll<HTMLElement>('.about-orbit-card'));
const orbitCore = root.querySelector<HTMLElement>('.about-orbit-core');
if (conditions.reduceMotion) {
gsap.set([...motionItems, ...orbitItems, orbitCore].filter(Boolean), {
autoAlpha: 1,
clearProps: 'transform,opacity,visibility',
});
return undefined;
}
const enterTween = gsap.fromTo(
motionItems,
{ autoAlpha: 0, y: conditions.isDesktop ? 18 : 10, scale: 0.99 },
{
autoAlpha: 1,
y: 0,
scale: 1,
duration: 0.54,
ease: 'power2.out',
stagger: 0.045,
clearProps: 'transform,opacity,visibility',
},
);
const orbitTween = orbitItems.length
? gsap.fromTo(
orbitItems,
{ autoAlpha: 0, y: 12 },
{
autoAlpha: 1,
y: 0,
duration: 0.48,
ease: 'power2.out',
stagger: { each: 0.06, from: 'center' },
delay: 0.12,
clearProps: 'transform,opacity,visibility',
},
)
: null;
const floatTween = orbitCore
? gsap.to(orbitCore, {
y: -4,
duration: 2.4,
ease: 'sine.inOut',
repeat: -1,
yoyo: true,
})
: null;
return () => {
enterTween.kill();
orbitTween?.kill();
floatTween?.kill();
};
},
);
return () => mm.revert();
}, []);
return (
<div className="about-page animate-fade-in">
<div className="page-header about-header">
<div>
<h2 className="page-title">{tr('关于 BoosAPI')}</h2>
<p className="page-subtitle">{tr('统一网关、模型路由、工作流与多模态助手的运行概览。')}</p>
</div>
<span className="about-version">v{VERSION}</span>
</div>
<div ref={rootRef} className="about-page">
<section className="about-hero about-motion-item">
<div className="about-hero-copy-block">
<div className="about-brand">
<img src="/logo.png" alt="BossAI" className="about-logo" />
<div>
<div className="about-brand-name">BossAI</div>
<div className="about-brand-meta">{tr('BoosAPI 网关内核驱动')}</div>
</div>
</div>
<section className="about-hero animate-slide-up stagger-1">
<div className="about-brand">
<img
src="/logo.png"
alt="BoosAPI"
className="about-logo"
/>
<div>
<div className="about-brand-name">BoosAPI</div>
<div className="about-brand-meta">{tr('自托管 AI 模型网关与工作台')}</div>
<h1>{tr('一个平台,接住模型、工作流和多模态生产。')}</h1>
<p>
{tr('BossAI 把多站点账号、模型路由、兼容 API、ComfyUI 工作流、创作助手和普通用户工作空间收进同一个自托管控制台。')}
</p>
<div className="about-proof-row" aria-label={tr('核心兼容能力')}>
{HERO_SIGNALS.map((item) => (
<div key={item.value}>
<strong>{item.value}</strong>
<span>{tr(item.label)}</span>
</div>
))}
</div>
<div className="about-chip-row">
{HERO_TAGS.map((tag) => (
<span key={tag} className="about-chip">{tag}</span>
))}
</div>
</div>
<p className="about-hero-copy">
{tr('BoosAPI 是一个自托管 AI 模型网关与工作台。它把多站点账号、下游 Key、模型路由、图像生成、视频任务、ComfyUI 风格工作流和普通用户面板收束到同一个 Rust 服务中,让前端、Agent、Workflow Studio 和外部 API 都能使用后台已经配置好的模型。')}
</p>
<div className="about-chip-row">
{['Rust Backend', 'OpenAI Compatible', 'Claude Messages', 'ComfyUI Frontend', 'Comfy Cloud', 'RunningHub'].map((tag) => (
<span key={tag} className="about-chip">
{tag}
</span>
))}
<div className="about-platform-card" aria-label={tr('平台运行结构')}>
<div className="about-version">{tr('当前版本')} v{VERSION}</div>
<div className="about-orbit">
<div className="about-orbit-core">
<img src="/logo.png" alt="" />
<span>BossAI</span>
</div>
<div className="about-orbit-card orbit-card-1">API Gateway</div>
<div className="about-orbit-card orbit-card-2">Route Engine</div>
<div className="about-orbit-card orbit-card-3">Workflow UI</div>
<div className="about-orbit-card orbit-card-4">Agent Apps</div>
</div>
<div className="about-signal-grid" aria-label={tr('平台能力概览')}>
<div>
<strong>7</strong>
<span>{tr('兼容入口')}</span>
</div>
<div>
<strong>5</strong>
<span>{tr('工作流后端')}</span>
</div>
<div>
<strong>1</strong>
<span>{tr('自托管服务')}</span>
</div>
</div>
</div>
</section>
<section className="about-section animate-slide-up stagger-2">
<section className="about-capability-grid about-motion-item">
{CAPABILITIES.map((item) => (
<article key={item.title} className="about-capability-card">
<div className="about-capability-topline">
<span>{item.label}</span>
<code>{item.stat}</code>
</div>
<h3>{tr(item.title)}</h3>
<p>{tr(item.desc)}</p>
</article>
))}
</section>
<section className="about-section about-motion-item">
<div className="about-section-heading">
<h3>{tr('核心特色')}</h3>
<p>{tr('围绕网关、模型、工作流和运维审计组织能力。')}</p>
<h2>{tr('运行能力')}</h2>
<p>{tr('围绕接入、路由、创作和运维,把 AI 应用需要的底座放在一个控制台里。')}</p>
</div>
<div className="about-feature-grid">
{FEATURES.map((f) => (
<div key={f.title} className="about-feature-row">
<span className="about-feature-mark">
{f.icon}
</span>
<div>
<div className="about-feature-title">{tr(f.title)}</div>
<div className="about-feature-desc">
{tr(f.desc)}
</div>
</div>
<div className="about-ops-grid">
{OPERATIONS.map((item) => (
<div key={item.title} className="about-ops-item">
<span>{tr(item.title)}</span>
<p>{tr(item.desc)}</p>
</div>
))}
</div>
</section>
<div className="about-two-column animate-slide-up stagger-3">
<section className="about-flow about-motion-item" aria-label={tr('请求处理路径')}>
<div className="about-flow-step">
<span>01</span>
<strong>{tr('接入请求')}</strong>
<p>{tr('下游 Key、用户身份和协议类型先进入统一网关。')}</p>
</div>
<div className="about-flow-step">
<span>02</span>
<strong>{tr('选择通道')}</strong>
<p>{tr('结合路由优先级、账号状态、成本、延迟和冷却策略选择上游。')}</p>
</div>
<div className="about-flow-step">
<span>03</span>
<strong>{tr('执行生产')}</strong>
<p>{tr('对话、生图、视频、工作流和数字人任务共享同一套执行链路。')}</p>
</div>
<div className="about-flow-step">
<span>04</span>
<strong>{tr('记录归档')}</strong>
<p>{tr('调用日志、费用、延迟和最终产出进入用户隔离的工作空间。')}</p>
</div>
</section>
<div className="about-two-column about-motion-item">
<section className="about-section">
<div className="about-section-heading">
<h3>{tr('工作流后端模式')}</h3>
<h2>{tr('工作流后端')}</h2>
</div>
<div className="about-definition-list">
{WORKFLOW_BACKENDS.map((backend) => (
<div
key={backend.name}
className="about-definition-row"
>
<code>
{backend.name}
</code>
<div>
{tr(backend.desc)}
{WORKFLOW_BACKENDS.map((backend) => (
<div key={backend.name} className="about-definition-row">
<code>{backend.name}</code>
<div>{tr(backend.desc)}</div>
</div>
</div>
))}
))}
</div>
</section>
<section className="about-section">
<section className="about-section about-api-section">
<div className="about-section-heading">
<h3>{tr('兼容入口')}</h3>
<h2>{tr('兼容入口')}</h2>
</div>
<div className="about-definition-list">
{ENDPOINTS.map((endpoint) => (
<div
key={endpoint.path}
className="about-definition-row about-endpoint-row"
>
<code>
{endpoint.path}
</code>
<div>
{tr(endpoint.desc)}
{ENDPOINTS.map((endpoint) => (
<div key={endpoint.path} className="about-definition-row about-endpoint-row">
<code>{endpoint.path}</code>
<div>{tr(endpoint.desc)}</div>
</div>
</div>
))}
))}
</div>
</section>
</div>
<section className="about-section animate-slide-up stagger-4">
<div className="about-section-heading">
<h3>{tr('技术栈')}</h3>
<section className="about-bottom-grid about-motion-item">
<div className="about-section about-tech-panel">
<div className="about-section-heading">
<h2>{tr('技术底座')}</h2>
<p>{tr('后端、前端和工作流资产都由同一个 Rust 服务统一托管。')}</p>
</div>
<div className="about-tech-strip">
{TECH_STACK.map((item) => (
<span key={item}>{item}</span>
))}
</div>
</div>
<div className="about-tech-grid">
{TECH_STACK.map((t) => (
<div key={t.name} className="about-tech-item">
<div className="about-tech-name">{t.name}</div>
<div className="about-tech-desc">
{tr(t.desc)}
</div>
</div>
))}
</div>
</section>
<section className="about-privacy animate-slide-up stagger-5">
<h3>{tr('数据与隐私')}</h3>
<p>
{tr('BoosAPI 完全自托管,账号、令牌、路由、日志、普通用户和工作台状态均保存在你的运行环境中。代理请求只在你的服务器、可选外部 ComfyUI 与已配置上游之间流转;内置系统 Key 会被保护,后台列表中只展示脱敏值。')}
</p>
<div className="about-section about-privacy">
<h2>{tr('数据与隐私')}</h2>
<p>
{tr('BossAI 完全自托管。账号、令牌、路由、日志、用户资产和工作台状态都保存在你的运行环境中,系统 Key 默认脱敏并受保护。')}
</p>
</div>
</section>
</div>
);