import React, { useState, useEffect } from 'react'; import axios from 'axios'; import { toast } from 'react-hot-toast'; import { Settings, Save, RefreshCw, Cpu, Brain } from 'lucide-react'; const ConfigManager = ({ adminToken }) => { const [loading, setLoading] = useState(false); const [saving, setSaving] = useState(false); const [formData, setFormData] = useState({ POLISH_MODEL: '', POLISH_API_KEY: '', POLISH_BASE_URL: '', ENHANCE_MODEL: '', ENHANCE_API_KEY: '', ENHANCE_BASE_URL: '', EMOTION_MODEL: '', EMOTION_API_KEY: '', EMOTION_BASE_URL: '', MAX_CONCURRENT_USERS: '', HISTORY_COMPRESSION_THRESHOLD: '', COMPRESSION_MODEL: '', COMPRESSION_API_KEY: '', COMPRESSION_BASE_URL: '', DEFAULT_USAGE_LIMIT: '', SEGMENT_SKIP_THRESHOLD: '', MAX_UPLOAD_FILE_SIZE_MB: '', THINKING_MODE_ENABLED: true, THINKING_MODE_EFFORT: 'high' }); useEffect(() => { fetchConfig(); }, []); const fetchConfig = async () => { setLoading(true); try { const response = await axios.get('/api/admin/config', { headers: { Authorization: `Bearer ${adminToken}` } }); // 填充表单,直接使用返回的值 setFormData({ POLISH_MODEL: response.data.polish.model || '', POLISH_API_KEY: response.data.polish.api_key || '', POLISH_BASE_URL: response.data.polish.base_url || '', ENHANCE_MODEL: response.data.enhance.model || '', ENHANCE_API_KEY: response.data.enhance.api_key || '', ENHANCE_BASE_URL: response.data.enhance.base_url || '', EMOTION_MODEL: response.data.emotion?.model || '', EMOTION_API_KEY: response.data.emotion?.api_key || '', EMOTION_BASE_URL: response.data.emotion?.base_url || '', MAX_CONCURRENT_USERS: response.data.system.max_concurrent_users?.toString() || '', HISTORY_COMPRESSION_THRESHOLD: response.data.system.history_compression_threshold?.toString() || '', COMPRESSION_MODEL: response.data.system.compression_model || '', COMPRESSION_API_KEY: response.data.compression?.api_key || '', COMPRESSION_BASE_URL: response.data.compression?.base_url || '', DEFAULT_USAGE_LIMIT: response.data.system.default_usage_limit?.toString() || '', SEGMENT_SKIP_THRESHOLD: response.data.system.segment_skip_threshold?.toString() || '', MAX_UPLOAD_FILE_SIZE_MB: response.data.system.max_upload_file_size_mb?.toString() || '', THINKING_MODE_ENABLED: response.data.thinking?.enabled ?? true, THINKING_MODE_EFFORT: response.data.thinking?.effort || 'high' }); } catch (error) { toast.error('获取配置失败'); } finally { setLoading(false); } }; const handleSave = async () => { setSaving(true); try { // 只发送已修改的非空值 const updates = {}; Object.keys(formData).forEach(key => { const value = formData[key]; // 布尔值需要转换为字符串 if (typeof value === 'boolean') { updates[key] = value.toString(); } else if (typeof value === 'string' && value.trim()) { updates[key] = value.trim(); } }); const response = await axios.post('/api/admin/config', updates, { headers: { Authorization: `Bearer ${adminToken}` } }); toast.success(response.data.message); fetchConfig(); } catch (error) { toast.error(error.response?.data?.detail || '保存配置失败'); } finally { setSaving(false); } }; if (loading) { return (
); } return (
{/* 润色模型配置 */}

润色模型配置

setFormData({...formData, POLISH_MODEL: e.target.value})} placeholder="gemini-2.5-pro" className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl focus:bg-white focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500 transition-all text-sm" />
setFormData({...formData, POLISH_API_KEY: e.target.value})} placeholder="留空使用默认 OpenAI Key" className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl focus:bg-white focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500 transition-all text-sm font-mono" />
setFormData({...formData, POLISH_BASE_URL: e.target.value})} placeholder="http://localhost:8317/v1" className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl focus:bg-white focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500 transition-all text-sm" />
{/* 增强模型配置 */}

论文增强模型配置

setFormData({...formData, ENHANCE_MODEL: e.target.value})} placeholder="gemini-2.5-pro" className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl focus:bg-white focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500 transition-all text-sm" />
setFormData({...formData, ENHANCE_API_KEY: e.target.value})} placeholder="留空使用默认 OpenAI Key" className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl focus:bg-white focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500 transition-all text-sm font-mono" />
setFormData({...formData, ENHANCE_BASE_URL: e.target.value})} placeholder="http://localhost:8317/v1" className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl focus:bg-white focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500 transition-all text-sm" />
{/* 感情文章润色模型配置 */}

感情文章润色模型配置

setFormData({...formData, EMOTION_MODEL: e.target.value})} placeholder="gemini-2.5-pro" className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl focus:bg-white focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500 transition-all text-sm" />
setFormData({...formData, EMOTION_API_KEY: e.target.value})} placeholder="留空使用默认 OpenAI Key" className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl focus:bg-white focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500 transition-all text-sm font-mono" />
setFormData({...formData, EMOTION_BASE_URL: e.target.value})} placeholder="http://localhost:8317/v1" className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl focus:bg-white focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500 transition-all text-sm" />
{/* 思考模式配置 */}

思考模式配置

{/* 启用开关 */}

开启后模型会进行深度推理,可能增加响应时间和 token 消耗

{/* 思考强度选择器 */}

更高的强度会增加推理 token 消耗和响应时间,但可能获得更好的结果

{/* 系统配置 */}

系统配置

setFormData({...formData, MAX_CONCURRENT_USERS: e.target.value})} placeholder="5" className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl focus:bg-white focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500 transition-all text-sm" />
setFormData({...formData, HISTORY_COMPRESSION_THRESHOLD: e.target.value})} placeholder="5000" className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl focus:bg-white focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500 transition-all text-sm" />
setFormData({...formData, COMPRESSION_MODEL: e.target.value})} placeholder="gemini-2.5-pro" className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl focus:bg-white focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500 transition-all text-sm" />
setFormData({...formData, COMPRESSION_API_KEY: e.target.value})} placeholder="留空使用默认 OpenAI Key" className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl focus:bg-white focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500 transition-all text-sm font-mono" />
setFormData({...formData, COMPRESSION_BASE_URL: e.target.value})} placeholder="http://localhost:8317/v1" className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl focus:bg-white focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500 transition-all text-sm" />
setFormData({...formData, DEFAULT_USAGE_LIMIT: e.target.value})} placeholder="1" className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl focus:bg-white focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500 transition-all text-sm" />

新用户的默认使用次数限制

setFormData({...formData, SEGMENT_SKIP_THRESHOLD: e.target.value})} placeholder="15" className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl focus:bg-white focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500 transition-all text-sm" />

小于此字数的段落将被识别为标题并跳过

setFormData({...formData, MAX_UPLOAD_FILE_SIZE_MB: e.target.value})} placeholder="0" min="0" className="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl focus:bg-white focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500 transition-all text-sm" />

0 表示无限制

{/* 操作按钮 */}

配置修改后会立即生效,无需重启服务!

); }; export default ConfigManager;