From a4d6353f1acaac937929b9cc179ddbe8d24eb19d Mon Sep 17 00:00:00 2001 From: impressionyang Date: Thu, 21 May 2026 18:45:08 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E8=87=AA=E5=AE=9A?= =?UTF-8?q?=E4=B9=89=E6=A8=A1=E5=9E=8B=E8=B7=AF=E5=BE=84=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 后端变更: - src/app/commands.rs: 新增 select_model_file 命令,使用 Tauri dialog 打开文件选择器 - src/app/mod.rs: 注册 select_model_file 命令到 invoke_handler 前端变更: - web/src/pages/SettingsPage.tsx: - 添加 modelPath 字段到 Settings 接口 - 添加 handleSelectModel 函数处理文件选择 - 添加模型路径配置 UI(输入框 + 选择按钮) - web/src/App.css: 添加.model-path-selector 样式 功能说明: - 用户可通过托盘菜单或设置页面选择自定义 ONNX 模型文件 - 支持 .onnx 扩展名过滤 - 模型路径保存在配置中,可选功能,留空时使用内置模型 - 设置保存后应用到 ASR 引擎 --- src/app/commands.rs | 23 ++++++++++++++++++ src/app/mod.rs | 1 + web/src/App.css | 13 ++++++++++ web/src/pages/SettingsPage.tsx | 43 +++++++++++++++++++++++++++++++++- 4 files changed, 79 insertions(+), 1 deletion(-) diff --git a/src/app/commands.rs b/src/app/commands.rs index 7095ce5..5b492eb 100644 --- a/src/app/commands.rs +++ b/src/app/commands.rs @@ -160,3 +160,26 @@ pub fn set_theme(theme: String, state: State<'_, AppState>) { let app_theme = AppTheme::from_str(&theme); state.set_theme(app_theme); } + +/// 选择模型文件 +#[tauri::command] +pub async fn select_model_file(app: tauri::AppHandle) -> Result { + use tauri_plugin_dialog::DialogExt; + + let (tx, rx) = std::sync::mpsc::channel(); + + app.dialog() + .file() + .add_filter("ONNX Model", &["onnx"]) + .pick_file(move |file_path| { + let result = match file_path { + Some(path) => Ok(path.to_string_lossy().to_string()), + None => Err("用户取消选择".to_string()), + }; + let _ = tx.send(result); + }); + + rx.recv() + .map_err(|e| e.to_string()) + .and_then(|r| r) +} diff --git a/src/app/mod.rs b/src/app/mod.rs index f1e77f3..29c287a 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -45,6 +45,7 @@ pub fn run() -> Result<()> { commands::clear_history, commands::get_theme, commands::set_theme, + commands::select_model_file, ]) .setup(|app| { info!("[设置] 初始化应用插件..."); diff --git a/web/src/App.css b/web/src/App.css index cff30b6..73a8a7b 100644 --- a/web/src/App.css +++ b/web/src/App.css @@ -299,3 +299,16 @@ body { background: var(--accent); color: var(--text-primary); } + +/* 模型路径选择器 */ +.model-path-selector { + display: flex; + align-items: center; + gap: 8px; + width: 100%; +} + +.model-path-selector .input { + flex: 1; + min-width: 200px; +} diff --git a/web/src/pages/SettingsPage.tsx b/web/src/pages/SettingsPage.tsx index 8adb04e..664f74c 100644 --- a/web/src/pages/SettingsPage.tsx +++ b/web/src/pages/SettingsPage.tsx @@ -13,6 +13,7 @@ interface Settings { hotkeyRecord: string hotkeyCopy: string hotkeyToggle: string + modelPath?: string } interface SettingsPageProps { @@ -20,6 +21,12 @@ interface SettingsPageProps { onThemeChange: (theme: 'light' | 'dark' | 'system') => void } +declare const window: Window & { + __TAURI__: { + invoke: (cmd: string, args?: Record) => Promise + } +} + export default function SettingsPage({ theme, onThemeChange }: SettingsPageProps) { const [settings, setSettings] = useState({ model: 'sensevoice-small', @@ -63,11 +70,24 @@ export default function SettingsPage({ theme, onThemeChange }: SettingsPageProps historyKeepDays: 30, hotkeyRecord: 'Ctrl+Shift+R', hotkeyCopy: 'Ctrl+Shift+C', - hotkeyToggle: 'Ctrl+Shift+H' + hotkeyToggle: 'Ctrl+Shift+H', + modelPath: undefined }) setModified(true) } + const handleSelectModel = async () => { + try { + const modelPath = await window.__TAURI__.invoke('select_model_file') + if (modelPath) { + setSettings(prev => ({ ...prev, modelPath })) + setModified(true) + } + } catch (e) { + console.error('选择模型文件失败:', e) + } + } + return (

设置

@@ -94,6 +114,27 @@ export default function SettingsPage({ theme, onThemeChange }: SettingsPageProps
+
+
+
模型路径
+
自定义模型文件路径(可选,留空使用内置模型)
+
+
+ handleChange('modelPath', e.target.value)} + placeholder="选择自定义模型文件..." + readOnly + /> + +
+
+
识别语言