import React, { useState, useEffect } from 'react'; import { AiModel, AiRole, ApiChannel, ModelConfigManager } from '../constants'; import { Settings, Plus, Edit3, Trash2, Save, X, Download, Upload, RefreshCw, Bot, Brain, Image, Zap, AlertCircle, Check, HardDrive, Globe, Key, Eye, EyeOff, Star, StarOff, Shield, Lock } from 'lucide-react'; interface ModelConfigManagerProps { isOpen: boolean; onClose: () => void; onConfigChange: () => void; } interface EditingChannel extends Partial { isNew?: boolean; } interface EditingModel extends Partial { isNew?: boolean; } interface EditingRole extends Partial { isNew?: boolean; } const ModelConfigManagerComponent: React.FC = ({ isOpen, onClose, onConfigChange }) => { const [activeTab, setActiveTab] = useState<'channels' | 'models' | 'roles' | 'storage'>('channels'); const [channels, setChannels] = useState([]); const [models, setModels] = useState([]); const [roles, setRoles] = useState([]); const [editingChannel, setEditingChannel] = useState(null); const [editingModel, setEditingModel] = useState(null); const [editingRole, setEditingRole] = useState(null); const [validationErrors, setValidationErrors] = useState([]); const [importText, setImportText] = useState(''); const [showImport, setShowImport] = useState(false); const [message, setMessage] = useState<{ type: 'success' | 'error'; text: string } | null>(null); const [storageInfo, setStorageInfo] = useState<{ used: number; available: number; channels: number; models: number; roles: number }>({ used: 0, available: 0, channels: 0, models: 0, roles: 0 }); const [showApiKeys, setShowApiKeys] = useState>({}); useEffect(() => { if (isOpen) { loadConfig(); updateStorageInfo(); } }, [isOpen]); const loadConfig = () => { try { setChannels(ModelConfigManager.getChannels()); setModels(ModelConfigManager.getModels()); setRoles(ModelConfigManager.getRoles()); } catch (error) { console.error('加载配置失败:', error); showMessage('error', '加载配置失败,请检查浏览器存储设置'); } }; const updateStorageInfo = () => { try { setStorageInfo(ModelConfigManager.getStorageInfo()); } catch (error) { console.error('获取存储信息失败:', error); } }; const showMessage = (type: 'success' | 'error', text: string) => { setMessage({ type, text }); setTimeout(() => setMessage(null), 3000); }; const toggleApiKeyVisibility = (channelId: string) => { setShowApiKeys(prev => ({ ...prev, [channelId]: !prev[channelId] })); }; // 获取渠道显示的API密钥内容 const getDisplayApiKey = (channel: ApiChannel): string => { if (channel.isProtected) { return '●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●● (受保护)'; } return channel.apiKey || '未设置'; }; // 检查用户是否可以修改此渠道 const canEditChannel = (channel: ApiChannel): boolean => { return channel.isCustom || !channel.isProtected; }; // ============ 渠道管理 ============ const handleSaveChannel = () => { if (!editingChannel) return; const errors = ModelConfigManager.validateChannel(editingChannel); if (errors.length > 0) { setValidationErrors(errors); return; } try { if (editingChannel.isNew) { const { id, createdAt, isCustom, isNew, ...channelData } = editingChannel; ModelConfigManager.addChannel(channelData as Omit); showMessage('success', '渠道添加成功'); } else { ModelConfigManager.updateChannel(editingChannel.id!, editingChannel); showMessage('success', '渠道更新成功'); } loadConfig(); updateStorageInfo(); setEditingChannel(null); setValidationErrors([]); onConfigChange(); } catch (error) { showMessage('error', '保存渠道失败: ' + (error instanceof Error ? error.message : '未知错误')); } }; const handleDeleteChannel = (id: string) => { // 检查是否有模型使用此渠道 const modelsUsingChannel = models.filter(model => model.channelId === id); if (modelsUsingChannel.length > 0) { showMessage('error', `无法删除渠道:有 ${modelsUsingChannel.length} 个模型正在使用此渠道`); return; } if (window.confirm('确定要删除这个渠道吗?此操作不可撤销。')) { try { ModelConfigManager.deleteChannel(id); loadConfig(); updateStorageInfo(); showMessage('success', '渠道删除成功'); onConfigChange(); } catch (error) { showMessage('error', '删除渠道失败: ' + (error instanceof Error ? error.message : '未知错误')); } } }; const handleSetDefaultChannel = (id: string) => { try { ModelConfigManager.updateChannel(id, { isDefault: true }); loadConfig(); showMessage('success', '默认渠道设置成功'); } catch (error) { showMessage('error', '设置默认渠道失败'); } }; const handleEditChannel = (channel: ApiChannel) => { if (channel.isProtected && !channel.isCustom) { // 对于受保护的预置渠道,创建一个编辑副本,但不显示真实的API密钥 setEditingChannel({ ...channel, apiKey: '' // 不显示受保护的密钥 }); } else { setEditingChannel(channel); } }; // ============ 模型管理 ============ const handleSaveModel = () => { if (!editingModel) return; const errors = ModelConfigManager.validateModel(editingModel); if (errors.length > 0) { setValidationErrors(errors); return; } try { if (editingModel.isNew) { const { id, createdAt, isCustom, isNew, ...modelData } = editingModel; ModelConfigManager.addModel(modelData as Omit); showMessage('success', '模型添加成功'); } else { ModelConfigManager.updateModel(editingModel.id!, editingModel); showMessage('success', '模型更新成功'); } loadConfig(); updateStorageInfo(); setEditingModel(null); setValidationErrors([]); onConfigChange(); } catch (error) { showMessage('error', '保存模型失败: ' + (error instanceof Error ? error.message : '未知错误')); } }; const handleDeleteModel = (id: string) => { // 检查是否有角色使用此模型 const rolesUsingModel = roles.filter(role => role.modelId === id); if (rolesUsingModel.length > 0) { showMessage('error', `无法删除模型:有 ${rolesUsingModel.length} 个角色正在使用此模型`); return; } if (window.confirm('确定要删除这个模型吗?此操作不可撤销。')) { try { ModelConfigManager.deleteModel(id); loadConfig(); updateStorageInfo(); showMessage('success', '模型删除成功'); onConfigChange(); } catch (error) { showMessage('error', '删除模型失败: ' + (error instanceof Error ? error.message : '未知错误')); } } }; // ============ 角色管理 ============ const handleSaveRole = () => { if (!editingRole) return; if (!editingRole.name?.trim() || !editingRole.systemPrompt?.trim() || !editingRole.modelId) { setValidationErrors(['角色名称、系统提示词和关联模型都不能为空']); return; } try { if (editingRole.isNew) { const { id, isNew, ...roleData } = editingRole; ModelConfigManager.addRole(roleData as Omit); showMessage('success', '角色添加成功'); } else { ModelConfigManager.updateRole(editingRole.id!, editingRole); showMessage('success', '角色更新成功'); } loadConfig(); updateStorageInfo(); setEditingRole(null); setValidationErrors([]); onConfigChange(); } catch (error) { showMessage('error', '保存角色失败: ' + (error instanceof Error ? error.message : '未知错误')); } }; const handleDeleteRole = (id: string) => { if (window.confirm('确定要删除这个角色吗?此操作不可撤销。')) { try { ModelConfigManager.deleteRole(id); loadConfig(); updateStorageInfo(); showMessage('success', '角色删除成功'); onConfigChange(); } catch (error) { showMessage('error', '删除角色失败: ' + (error instanceof Error ? error.message : '未知错误')); } } }; // ============ 通用操作 ============ const handleExport = () => { try { const config = ModelConfigManager.exportConfig(); const blob = new Blob([config], { type: 'application/json' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = `multi-mind-chat-config-${new Date().toISOString().split('T')[0]}.json`; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); showMessage('success', '配置导出成功'); } catch (error) { showMessage('error', '导出配置失败: ' + (error instanceof Error ? error.message : '未知错误')); } }; const handleImport = () => { if (!importText.trim()) { showMessage('error', '请输入配置内容'); return; } try { const result = ModelConfigManager.importConfig(importText); if (result.success) { loadConfig(); updateStorageInfo(); setImportText(''); setShowImport(false); showMessage('success', result.message); onConfigChange(); } else { showMessage('error', result.message); } } catch (error) { showMessage('error', '导入配置时发生错误: ' + (error instanceof Error ? error.message : '未知错误')); } }; const handleReset = () => { if (window.confirm('确定要重置为默认配置吗?这将删除所有自定义配置。')) { try { ModelConfigManager.resetToDefaults(); loadConfig(); updateStorageInfo(); showMessage('success', '已重置为默认配置'); onConfigChange(); } catch (error) { showMessage('error', '重置配置失败: ' + (error instanceof Error ? error.message : '未知错误')); } } }; const handleClearAllData = () => { if (window.confirm('警告:这将清空所有配置数据,包括渠道、模型和角色!此操作不可撤销,确定继续吗?')) { try { ModelConfigManager.clearAllData(); loadConfig(); updateStorageInfo(); showMessage('success', '所有数据已清空'); onConfigChange(); } catch (error) { showMessage('error', '清空数据失败: ' + (error instanceof Error ? error.message : '未知错误')); } } }; if (!isOpen) return null; return (
{/* Header */}

Multi-Mind Chat 配置管理

{/* Message */} {message && (
{message.type === 'success' ? : } {message.text}
)} {/* Import Section */} {showImport && (

导入配置