From 817d70c8e10536b5274f04c86ac4c7b2a5033b45 Mon Sep 17 00:00:00 2001 From: xianrenge <34586161+xianrenge@users.noreply.github.com> Date: Mon, 17 Aug 2026 23:39:16 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=9F=A5=E8=AF=86=E5=BA=93=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E7=9B=AE=E5=BD=95=E5=BC=B9=E7=AA=97=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E6=B5=8F=E8=A7=88=E9=80=89=E6=8B=A9=E2=80=94=E2=80=94=E6=8E=A5?= =?UTF-8?q?=E5=85=A5=20tauri-plugin-dialog=20=E5=8E=9F=E7=94=9F=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E5=A4=B9=E9=80=89=E6=8B=A9=E5=99=A8=EF=BC=8C=E7=9B=AE?= =?UTF-8?q?=E5=BD=95=E8=B7=AF=E5=BE=84=E5=8F=AF=E6=89=8B=E8=BE=93=E6=88=96?= =?UTF-8?q?=E7=82=B9=E9=80=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 144 ++++++++++++++++++++++++++++- apps/desktop/Cargo.toml | 1 + apps/desktop/src/lib.rs | 1 + docs/ARCHITECTURE.md | 2 +- docs/FEATURES.md | 2 + ui/package-lock.json | 10 ++ ui/package.json | 2 +- ui/src/pages/KnowledgeBasePage.tsx | 37 ++++++-- 8 files changed, 190 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4f86ef0..cfd1d20 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2699,6 +2699,7 @@ checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" dependencies = [ "bitflags 2.13.1", "block2", + "libc", "objc2", "objc2-core-foundation", ] @@ -3403,6 +3404,30 @@ dependencies = [ "web-sys", ] +[[package]] +name = "rfd" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a15ad77d9e70a92437d8f74c35d99b4e4691128df018833e99f90bcd36152672" +dependencies = [ + "block2", + "dispatch2", + "glib-sys", + "gobject-sys", + "gtk-sys", + "js-sys", + "log", + "objc2", + "objc2-app-kit", + "objc2-core-foundation", + "objc2-foundation", + "raw-window-handle", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "windows-sys 0.60.2", +] + [[package]] name = "ring" version = "0.17.14" @@ -4226,6 +4251,48 @@ dependencies = [ "thiserror 2.0.20", ] +[[package]] +name = "tauri-plugin-dialog" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2d3c1dbe38037e7f590cdf2492594d5ceebe031e7bc7e827509b22a999d2940" +dependencies = [ + "log", + "raw-window-handle", + "rfd", + "serde", + "serde_json", + "tauri", + "tauri-plugin", + "tauri-plugin-fs", + "thiserror 2.0.20", + "url", +] + +[[package]] +name = "tauri-plugin-fs" +version = "2.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7ecc274121aca0c036a2b42d1cbe83d368d348f54e0bb8a735c2b1548e8f371" +dependencies = [ + "anyhow", + "dunce", + "glob", + "log", + "objc2-foundation", + "percent-encoding", + "schemars 0.8.22", + "serde", + "serde_json", + "serde_repr", + "tauri", + "tauri-plugin", + "tauri-utils", + "thiserror 2.0.20", + "toml 1.1.4+spec-1.1.0", + "url", +] + [[package]] name = "tauri-plugin-opener" version = "2.5.4" @@ -5444,6 +5511,15 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.5", +] + [[package]] name = "windows-sys" version = "0.61.2" @@ -5492,13 +5568,30 @@ dependencies = [ "windows_aarch64_gnullvm 0.52.6", "windows_aarch64_msvc 0.52.6", "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm", + "windows_i686_gnullvm 0.52.6", "windows_i686_msvc 0.52.6", "windows_x86_64_gnu 0.52.6", "windows_x86_64_gnullvm 0.52.6", "windows_x86_64_msvc 0.52.6", ] +[[package]] +name = "windows-targets" +version = "0.53.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" +dependencies = [ + "windows-link 0.2.1", + "windows_aarch64_gnullvm 0.53.1", + "windows_aarch64_msvc 0.53.1", + "windows_i686_gnu 0.53.1", + "windows_i686_gnullvm 0.53.1", + "windows_i686_msvc 0.53.1", + "windows_x86_64_gnu 0.53.1", + "windows_x86_64_gnullvm 0.53.1", + "windows_x86_64_msvc 0.53.1", +] + [[package]] name = "windows-threading" version = "0.1.0" @@ -5535,6 +5628,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" + [[package]] name = "windows_aarch64_msvc" version = "0.42.2" @@ -5553,6 +5652,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" + [[package]] name = "windows_i686_gnu" version = "0.42.2" @@ -5571,12 +5676,24 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" +[[package]] +name = "windows_i686_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" + [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" + [[package]] name = "windows_i686_msvc" version = "0.42.2" @@ -5595,6 +5712,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +[[package]] +name = "windows_i686_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" + [[package]] name = "windows_x86_64_gnu" version = "0.42.2" @@ -5613,6 +5736,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" + [[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" @@ -5631,6 +5760,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" + [[package]] name = "windows_x86_64_msvc" version = "0.42.2" @@ -5649,6 +5784,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" + [[package]] name = "winnow" version = "0.5.40" @@ -5812,6 +5953,7 @@ dependencies = [ "tauri", "tauri-build", "tauri-plugin-autostart", + "tauri-plugin-dialog", "tauri-plugin-opener", "tokio", "tracing", diff --git a/apps/desktop/Cargo.toml b/apps/desktop/Cargo.toml index effce44..502f6e3 100644 --- a/apps/desktop/Cargo.toml +++ b/apps/desktop/Cargo.toml @@ -20,6 +20,7 @@ tauri-build = { version = "2", features = [] } tauri = { version = "2", features = [] } tauri-plugin-opener = "2" tauri-plugin-autostart = "2" +tauri-plugin-dialog = "2" tracing-subscriber.workspace = true tracing.workspace = true tracing-appender.workspace = true diff --git a/apps/desktop/src/lib.rs b/apps/desktop/src/lib.rs index 7e88681..4603d9c 100644 --- a/apps/desktop/src/lib.rs +++ b/apps/desktop/src/lib.rs @@ -69,6 +69,7 @@ pub fn run() { MacosLauncher::LaunchAgent, None, )) + .plugin(tauri_plugin_dialog::init()) .setup(|app| { let core = CoreApp::init(None) .map_err(|e| -> Box { e.to_string().into() })?; diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index 4c7c941..a150bf3 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -97,7 +97,7 @@ ui/src/ ### 4.1 `lib.rs` - `run()`:初始化数据目录(`%APPDATA%\XianrenStudio`)、日志、panic 钩子;构建 Tauri 应用并注册 `invoke_handler`。 -- 注册插件:`tauri-plugin-opener`、`tauri-plugin-autostart`(开机启动,Windows 写注册表启动项)。 +- 注册插件:`tauri-plugin-opener`、`tauri-plugin-autostart`(开机启动,Windows 写注册表启动项)、`tauri-plugin-dialog`(原生文件/文件夹选择对话框,知识库目录来源「浏览…」使用)。 - `setup` 末尾启动**自动加载模型**任务(`auto_load_models`:按设置列表顺序逐个部署,最后一个保持运行)。 - `setup` 末尾启动**定时计划后台调度循环**(tokio interval 每 30 秒调用 `run_due_scheduled_tasks`)。 - 数据目录:`logs/`、`models/`、`engines/`、`recommendations/`。 diff --git a/docs/FEATURES.md b/docs/FEATURES.md index 06c89dd..ffc28fa 100644 --- a/docs/FEATURES.md +++ b/docs/FEATURES.md @@ -134,6 +134,7 @@ - **知识库管理**:新建 / 编辑 / 删除知识库,字段含名称、描述、**分块大小**(100–10000 字,默认 500)与**块间重叠**(默认 50);删除知识库会级联删除其文档与分块。 - **文档导入**:支持多文件上传,格式覆盖文本类文件(txt / md / json / csv / 代码 / HTML 等)与 **PDF**(后端提取文本);导入后按知识库分块设置自动切块并写入全文索引。 - **目录来源(批量导入)**:可为知识库添加多个本地目录,扫描目录批量导入文档: + - **目录选择**:目录路径支持手动输入,或点击「浏览…」调起系统原生文件夹选择器; - **后缀过滤**:可指定只导入的后缀列表(如 `.txt,.md,.pdf`),留空默认全部; - **递归子目录**:可开关是否递归扫描所有子目录; - **类型过滤**:只收录**可读文本**(提取内容并分块检索)、**图片 / 视频**、**音频**三类文件(图片视频音频以文件名为内容登记,可按文件名检索),检测到其他类型自动忽略; @@ -229,6 +230,7 @@ ### 2026-08-17 +- 知识库「添加目录」弹窗支持两种方式选择目录:手动输入路径,或点击「浏览…」调起系统原生文件夹选择器(接入 tauri-plugin-dialog)。 - 知识库新增「目录来源」:支持添加多个本地目录批量导入(后缀过滤默认全部、可开关递归子目录),只收录文本 / 图片视频 / 音频三类文件其余忽略,支持重新扫描增量导入与按来源删除。 - 新增「知识库」选项卡与完整操作界面:知识库管理(新建/编辑/删除)、多格式文档上传(文本类 + PDF)、自动分块与全文检索(FTS5 trigram + BM25)、文档预览 / 重新切分 / 删除、检索结果一键复制。 - 计划任务支持发送邮件:任务设置中可开启邮件并填写收件人,内容支持固定内容与大模型生成两种模式;设置页新增「邮件」SMTP 配置与测试发送。 diff --git a/ui/package-lock.json b/ui/package-lock.json index 93d7dba..78ba69b 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -9,6 +9,7 @@ "version": "0.1.0", "dependencies": { "@tauri-apps/api": "^2.1.1", + "@tauri-apps/plugin-dialog": "^2.0.0", "react": "^18.3.1", "react-dom": "^18.3.1", "react-markdown": "^9.0.1", @@ -1414,6 +1415,15 @@ "url": "https://opencollective.com/tauri" } }, + "node_modules/@tauri-apps/plugin-dialog": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-dialog/-/plugin-dialog-2.7.2.tgz", + "integrity": "sha512-pX0IGm1I3I6wc+zeKYcq1GSqogK6okCNX5fOdaNU5ab1AjGS6l1E5wFNjEb7meg7ZFSp0JUs+0jQGQNyOvLrsg==", + "license": "MIT OR Apache-2.0", + "dependencies": { + "@tauri-apps/api": "^2.11.0" + } + }, "node_modules/@types/babel__core": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", diff --git a/ui/package.json b/ui/package.json index 2392a3c..856ee28 100644 --- a/ui/package.json +++ b/ui/package.json @@ -9,6 +9,7 @@ "preview": "vite preview" }, "dependencies": { + "@tauri-apps/plugin-dialog": "^2.0.0", "@tauri-apps/api": "^2.1.1", "react": "^18.3.1", "react-dom": "^18.3.1", @@ -27,4 +28,3 @@ "vite": "^5.4.8" } } - diff --git a/ui/src/pages/KnowledgeBasePage.tsx b/ui/src/pages/KnowledgeBasePage.tsx index 854c683..42c9ba1 100644 --- a/ui/src/pages/KnowledgeBasePage.tsx +++ b/ui/src/pages/KnowledgeBasePage.tsx @@ -1,4 +1,5 @@ import { useEffect, useMemo, useRef, useState } from "react"; +import { open as openDialog } from "@tauri-apps/plugin-dialog"; import { api, KbDocument, @@ -778,6 +779,21 @@ function SourceModal({ const [recursive, setRecursive] = useState(true); const valid = path.trim().length > 0; + async function handleBrowse() { + try { + const dir = await openDialog({ + directory: true, + multiple: false, + title: "选择目录", + }); + if (typeof dir === "string" && dir) { + setPath(dir); + } + } catch { + // 取消或选择器异常时不改变当前输入 + } + } + return (
- setPath(e.target.value)} - /> +
+ setPath(e.target.value)} + /> + +