/** * Admin Settings Page - Enhanced with API Configuration */ import React, { useState, useEffect } from 'react' import { useNavigate } from 'react-router-dom' import { adminAPI } from '../api/client' import { useAuth } from '../context/AuthContext' import { Settings, Save, Loader, Key, Link as LinkIcon, Eye, EyeOff, ArrowLeft } from 'lucide-react' import toast from 'react-hot-toast' export const AdminSettings = () => { const { user } = useAuth() const navigate = useNavigate() const [loading, setLoading] = useState(true) const [saving, setSaving] = useState(false) const [showApiKeys, setShowApiKeys] = useState({ openai: false, anthropic: false, qwen: false, gemini: false }) const [config, setConfig] = useState({ allow_registration: true, max_upload_size_mb: 10, max_daily_uploads: 20, ai_provider: 'gemini', // OpenAI openai_api_key: '', openai_base_url: 'https://api.openai.com/v1', openai_model: 'gpt-4o-mini', // Anthropic anthropic_api_key: '', anthropic_model: 'claude-3-haiku-20240307', // Qwen qwen_api_key: '', qwen_base_url: 'https://dashscope.aliyuncs.com/compatible-mode/v1', qwen_model: 'qwen-plus', // Gemini gemini_api_key: '', gemini_base_url: '', gemini_model: 'gemini-2.0-flash-exp' }) useEffect(() => { loadConfig() }, []) const loadConfig = async () => { try { const response = await adminAPI.getConfig() setConfig(response.data) } catch (error) { console.error('Failed to load config:', error) toast.error('加载配置失败') } finally { setLoading(false) } } const handleSave = async () => { setSaving(true) try { await adminAPI.updateConfig(config) toast.success('配置保存成功!') } catch (error) { console.error('Failed to save config:', error) toast.error('保存配置失败') } finally { setSaving(false) } } const handleChange = (key, value) => { setConfig({ ...config, [key]: value }) } const toggleApiKeyVisibility = (provider) => { setShowApiKeys({ ...showApiKeys, [provider]: !showApiKeys[provider] }) } // Get complete API endpoint URL const getCompleteEndpoint = (provider) => { const endpoints = { openai: '/chat/completions', anthropic: '/messages', qwen: '/chat/completions' } let baseUrl = '' if (provider === 'openai') { baseUrl = config.openai_base_url || 'https://api.openai.com/v1' } else if (provider === 'anthropic') { baseUrl = 'https://api.anthropic.com/v1' } else if (provider === 'qwen') { baseUrl = config.qwen_base_url || 'https://dashscope.aliyuncs.com/compatible-mode/v1' } // Remove trailing slash baseUrl = baseUrl.replace(/\/$/, '') return `${baseUrl}${endpoints[provider]}` } if (loading) { return (
管理员:{user?.username}
关闭后新用户无法注册
建议:5-20 MB
建议:10-50 次
选择后在下方配置对应的 API 密钥。Gemini 支持原生 PDF 解析
⚠️ OpenAI 仅支持文本解析,不支持 PDF 原生理解。PDF 文件将通过文本提取处理,可能丢失格式和图片信息。
从 https://platform.openai.com/api-keys 获取
完整 endpoint: {getCompleteEndpoint('openai')}
可输入自定义模型名称,或从建议中选择
⚠️ Anthropic 仅支持文本解析,不支持 PDF 原生理解。PDF 文件将通过文本提取处理,可能丢失格式和图片信息。
从 https://console.anthropic.com/settings/keys 获取
完整 endpoint: {getCompleteEndpoint('anthropic')}
可输入自定义模型名称,或从建议中选择
⚠️ 通义千问 仅支持文本解析,不支持 PDF 原生理解。PDF 文件将通过文本提取处理,可能丢失格式和图片信息。
从 https://dashscope.console.aliyun.com/apiKey 获取
完整 endpoint: {getCompleteEndpoint('qwen')}
可输入自定义模型名称,或从建议中选择
✅ Gemini 支持原生 PDF 理解,可直接处理 PDF 文件(最多 1000 页),完整保留图片、表格、公式等内容。
从 https://aistudio.google.com/apikey 获取
可配置自定义代理或中转服务(支持 Key 轮训等)。留空则使用 Google 官方 API
可输入自定义模型名称,或从建议中选择