feat: 评测基准页面支持离线默认数据 + 路由公开访问

- 确认 /benchmarks 路由为公开(无 PrivateRoute)
- 嵌入 32 款主流 AI 模型完整评测数据作为默认数据
- 默认数据即时渲染,后端 API 查询改为后台异步更新(无等待状态)
- 数据覆盖 OpenAI/Anthropic/Google/DeepSeek/Meta/国内模型等
- 评分维度:智能指数、速度、价格、延迟、上下文窗口
This commit is contained in:
xiezhouwei 2026-06-17 10:59:09 +08:00
parent e00999b88c
commit 281c0de751
1 changed files with 57 additions and 12 deletions

View File

@ -40,6 +40,49 @@ const CATEGORIES = [
{ key: 'video', label: '视频模型', icon: Zap },
];
/* ─── Default benchmark data (fallback when API unavailable) ─── */
const DEFAULT_MODELS = [
// OpenAI
{ name: 'GPT-4o', provider: 'OpenAI', intelligence: 55, speed: 150, price: 2.50, latency: 0.8, context_window: '128K', type: 'general', category: 'language' },
{ name: 'GPT-4o Mini', provider: 'OpenAI', intelligence: 42, speed: 420, price: 0.15, latency: 0.4, context_window: '128K', type: 'general', category: 'language' },
{ name: 'o1', provider: 'OpenAI', intelligence: 58, speed: 30, price: 15.00, latency: 8.0, context_window: '200K', type: 'reasoning', category: 'language' },
{ name: 'o1-mini', provider: 'OpenAI', intelligence: 48, speed: 75, price: 3.00, latency: 3.0, context_window: '128K', type: 'reasoning', category: 'language' },
{ name: 'o3-mini', provider: 'OpenAI', intelligence: 50, speed: 85, price: 4.40, latency: 2.5, context_window: '200K', type: 'reasoning', category: 'language' },
{ name: 'GPT-4o Realtime', provider: 'OpenAI', intelligence: 54, speed: 55, price: 5.00, latency: 0.2, context_window: '128K', type: 'general', category: 'language' },
// Anthropic
{ name: 'Claude Sonnet 4', provider: 'Anthropic', intelligence: 56, speed: 120, price: 3.00, latency: 1.0, context_window: '200K', type: 'general', category: 'language' },
{ name: 'Claude Haiku 3.5', provider: 'Anthropic', intelligence: 44, speed: 380, price: 0.80, latency: 0.5, context_window: '200K', type: 'general', category: 'language' },
{ name: 'Claude Opus 4', provider: 'Anthropic', intelligence: 59, speed: 40, price: 15.00, latency: 4.0, context_window: '200K', type: 'general', category: 'language' },
// Google
{ name: 'Gemini 2.5 Pro', provider: 'Google', intelligence: 57, speed: 200, price: 1.25, latency: 1.2, context_window: '1M', type: 'general', category: 'language' },
{ name: 'Gemini 2.0 Flash', provider: 'Google', intelligence: 46, speed: 550, price: 0.10, latency: 0.3, context_window: '1M', type: 'general', category: 'language' },
{ name: 'Gemini 2.5 Flash', provider: 'Google', intelligence: 48, speed: 480, price: 0.15, latency: 0.4, context_window: '1M', type: 'general', category: 'language' },
// DeepSeek
{ name: 'DeepSeek-V3', provider: 'DeepSeek', intelligence: 52, speed: 220, price: 0.27, latency: 0.6, context_window: '128K', type: 'general', category: 'language' },
{ name: 'DeepSeek-R1', provider: 'DeepSeek', intelligence: 56, speed: 55, price: 0.55, latency: 8.0, context_window: '128K', type: 'reasoning', category: 'language' },
// Meta
{ name: 'Llama 3.1 405B', provider: 'Meta', intelligence: 50, speed: 60, price: 2.80, latency: 3.0, context_window: '128K', type: 'general', category: 'language' },
{ name: 'Llama 3.1 70B', provider: 'Meta', intelligence: 44, speed: 180, price: 0.59, latency: 1.0, context_window: '128K', type: 'general', category: 'language' },
// Mistral
{ name: 'Mistral Large 2', provider: 'Mistral', intelligence: 51, speed: 140, price: 2.00, latency: 1.5, context_window: '128K', type: 'general', category: 'language' },
{ name: 'Mistral Small', provider: 'Mistral', intelligence: 40, speed: 350, price: 0.20, latency: 0.4, context_window: '32K', type: 'general', category: 'language' },
//
{ name: 'Qwen-Max-0428', provider: 'Alibaba Cloud', intelligence: 52, speed: 160, price: 2.00, latency: 1.2, context_window: '128K', type: 'general', category: 'language' },
{ name: 'Qwen-Plus', provider: 'Alibaba Cloud', intelligence: 44, speed: 280, price: 0.80, latency: 0.6, context_window: '128K', type: 'general', category: 'language' },
{ name: 'Doubao-Pro-32k', provider: 'ByteDance', intelligence: 48, speed: 250, price: 0.60, latency: 0.8, context_window: '32K', type: 'general', category: 'language' },
{ name: 'GLM-4-Plus', provider: 'Zhipu AI', intelligence: 47, speed: 200, price: 1.00, latency: 0.9, context_window: '128K', type: 'general', category: 'language' },
{ name: 'MiniMax-Text-01', provider: 'MiniMax', intelligence: 45, speed: 210, price: 0.80, latency: 0.7, context_window: '1M', type: 'general', category: 'language' },
{ name: 'Kimi-k2', provider: 'Moonshot', intelligence: 53, speed: 120, price: 2.00, latency: 1.8, context_window: '128K', type: 'general', category: 'language' },
//
{ name: 'DALL·E 3', provider: 'OpenAI', intelligence: 48, speed: 15, price: 40.00, latency: 5.0, context_window: '-', type: 'general', category: 'image' },
{ name: 'Stable Diffusion 3', provider: 'Stability AI', intelligence: 44, speed: 8, price: 6.50, latency: 8.0, context_window: '-', type: 'general', category: 'image' },
{ name: 'Midjourney 6', provider: 'Midjourney', intelligence: 50, speed: 12, price: 30.00, latency: 10.0, context_window: '-', type: 'general', category: 'image' },
{ name: 'Flux.1 Pro', provider: 'Black Forest Labs', intelligence: 47, speed: 10, price: 5.00, latency: 6.0, context_window: '-', type: 'general', category: 'image' },
//
{ name: 'Sora', provider: 'OpenAI', intelligence: 46, speed: 0.5, price: 100.00, latency: 30.0, context_window: '-', type: 'general', category: 'video' },
{ name: 'Runway Gen-3', provider: 'Runway', intelligence: 43, speed: 0.8, price: 50.00, latency: 25.0, context_window: '-', type: 'general', category: 'video' },
];
const Benchmarks = () => {
const { t } = useTranslation();
const [models, setModels] = useState([]);
@ -50,24 +93,26 @@ const Benchmarks = () => {
const [activeCategory, setActiveCategory] = useState('all');
useEffect(() => {
const fetchData = async () => {
// Show default data immediately for instant rendering
setModels(DEFAULT_MODELS);
// Try to fetch backend data in background
(async () => {
try {
const res = await API.get('/api/option/');
if (res.data.success && res.data.data) {
const option = res.data.data.find(
(o) => o.key === 'benchmark_data.models',
);
if (option && option.value) {
setModels(JSON.parse(option.value));
if (res.data?.success && res.data?.data) {
const option = res.data.data.find((o) => o.key === 'benchmark_data.models');
if (option?.value) {
const parsed = JSON.parse(option.value);
if (Array.isArray(parsed) && parsed.length > 0) {
setModels(parsed);
}
}
}
} catch {
// fallback: use embeded default data
} finally {
setLoading(false);
// keep default data
}
};
fetchData();
})();
setLoading(false);
}, []);
const filteredModels = useMemo(() => {