From a4dfa542d11ae330950be7d62f7c8d02e928c242 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=94=B5=E6=91=87=E5=B0=8F=E5=AD=90?= Date: Mon, 1 Jun 2026 10:11:25 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=E5=A4=9A=E6=A8=A1?= =?UTF-8?q?=E5=9E=8B=E6=9C=8D=E5=8A=A1=E9=85=8D=E7=BD=AE=20(Key/Base=20URL?= =?UTF-8?q?/=E6=A8=A1=E5=9E=8B=E5=90=8D)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 后端 ai:chat 支持 baseURL 参数,可配置任意 OpenAI 兼容 API - 前端 UI 增加 Base URL 输入框和模型选择下拉 (DeepSeek/GPT-4o/Claude/Moonshot) - 配置通过 localStorage 持久化,支持从 .env 文件读取默认値 - 统一错误提示,移除 DeepSeek 硬编码引用 Co-Authored-By: Claude Opus 4.7 --- .env.example | 4 ++- src/main/index.ts | 14 ++++++---- src/renderer/src/components/ChatWindow.tsx | 32 ++++++++++++++++++---- 3 files changed, 37 insertions(+), 13 deletions(-) diff --git a/.env.example b/.env.example index 980b2d0..9f8be6d 100644 --- a/.env.example +++ b/.env.example @@ -1,8 +1,10 @@ # WeChat Database Key (Optional, can be entered in UI) VITE_DB_KEY= -# DeepSeek API Key (Optional, can be entered in UI) +# AI API Configuration (Optional, can be entered in UI) VITE_DEEPSEEK_API_KEY= +VITE_AI_BASE_URL=https://api.deepseek.com +VITE_AI_MODEL=deepseek-chat # Message types to filter out (comma separated) VITE_FILTER_MSG_TYPES=分享消息,图片,表情包,视频 diff --git a/src/main/index.ts b/src/main/index.ts index adfb143..47584b3 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -181,22 +181,24 @@ app.whenReady().then(() => { async ( _, messages: { role: string; content: string }[], - options?: { apiKey?: string; model?: string } + options?: { apiKey?: string; model?: string; baseURL?: string } ) => { // @ts-ignore: vite env const apiKey = options?.apiKey || import.meta.env.VITE_DEEPSEEK_API_KEY - const model = options?.model || 'deepseek-chat' + const model = options?.model || import.meta.env.VITE_AI_MODEL || 'deepseek-chat' + const baseURL = + options?.baseURL || import.meta.env.VITE_AI_BASE_URL || 'https://api.deepseek.com' if (!apiKey) { - return { success: false, error: '未配置 DeepSeek API Key' } + return { success: false, error: '未配置 API Key' } } // 动态导入以避免如果未安装或初始类型缺失的问题 const { OpenAI } = await import('openai') const openai = new OpenAI({ - baseURL: 'https://api.deepseek.com', - apiKey: apiKey + baseURL, + apiKey }) try { const completion = await openai.chat.completions.create({ @@ -206,7 +208,7 @@ app.whenReady().then(() => { }) return { success: true, data: completion.choices[0].message.content } } catch (error: unknown) { - console.error('DeepSeek API Error:', error) + console.error('AI API Error:', error) const errorMessage = error instanceof Error ? error.message : 'Unknown error' return { success: false, error: errorMessage } } diff --git a/src/renderer/src/components/ChatWindow.tsx b/src/renderer/src/components/ChatWindow.tsx index e605bc9..0d91ffe 100644 --- a/src/renderer/src/components/ChatWindow.tsx +++ b/src/renderer/src/components/ChatWindow.tsx @@ -52,11 +52,16 @@ const ChatWindow: React.FC = ({ // AI Settings const [showSettingsModal, setShowSettingsModal] = useState(false) - const [apiKey, setApiKey] = useState(() => localStorage.getItem('deepseek_api_key') || '') - const [model, setModel] = useState('deepseek-chat') + const [apiKey, setApiKey] = useState(() => localStorage.getItem('ai_api_key') || '') + const [baseURL, setBaseURL] = useState( + () => localStorage.getItem('ai_base_url') || 'https://api.deepseek.com' + ) + const [model, setModel] = useState(() => localStorage.getItem('ai_model') || 'deepseek-chat') const handleSaveSettings = (): void => { - localStorage.setItem('deepseek_api_key', apiKey) + localStorage.setItem('ai_api_key', apiKey) + localStorage.setItem('ai_base_url', baseURL) + localStorage.setItem('ai_model', model) setShowSettingsModal(false) AIChat() } @@ -186,7 +191,7 @@ const ChatWindow: React.FC = ({ { role: 'system', content: systemPrompt }, { role: 'user', content: prompt } ], - { apiKey, model } + { apiKey, model, baseURL } ) if (result.success && result.data) { @@ -482,22 +487,37 @@ const ChatWindow: React.FC = ({
e.stopPropagation()}>

AI 设置

- +
+
+ + setBaseURL(e.target.value)} + placeholder="https://api.deepseek.com" + style={{ width: '95%', padding: '8px' }} + /> +
setApiKey(e.target.value)} - placeholder="Enter your DeepSeek API Key" + placeholder="Enter your API Key" style={{ width: '95%', padding: '8px' }} />