perf(desktop): stream drag-upload and improve transfer status UX

This commit is contained in:
2026-02-18 19:50:34 +08:00
parent 09043e8059
commit d4818a78d3
4 changed files with 60 additions and 13 deletions

View File

@@ -3116,12 +3116,14 @@ dependencies = [
"sync_wrapper",
"tokio",
"tokio-rustls",
"tokio-util",
"tower",
"tower-http",
"tower-service",
"url",
"wasm-bindgen",
"wasm-bindgen-futures",
"wasm-streams 0.4.2",
"web-sys",
"webpki-roots",
]
@@ -3156,7 +3158,7 @@ dependencies = [
"url",
"wasm-bindgen",
"wasm-bindgen-futures",
"wasm-streams",
"wasm-streams 0.5.0",
"web-sys",
]
@@ -4716,6 +4718,19 @@ dependencies = [
"wasmparser",
]
[[package]]
name = "wasm-streams"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65"
dependencies = [
"futures-util",
"js-sys",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
]
[[package]]
name = "wasm-streams"
version = "0.5.0"

View File

@@ -22,5 +22,5 @@ tauri = { version = "2", features = [] }
tauri-plugin-opener = "2"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
reqwest = { version = "0.12", default-features = false, features = ["json", "cookies", "multipart", "rustls-tls"] }
reqwest = { version = "0.12", default-features = false, features = ["json", "cookies", "multipart", "stream", "rustls-tls"] }
urlencoding = "2.1"

View File

@@ -620,8 +620,6 @@ async fn api_upload_file(
.and_then(|name| name.to_str())
.map(|name| name.to_string())
.ok_or_else(|| "无法识别文件名".to_string())?;
let file_bytes = fs::read(&source_path).map_err(|err| format!("读取文件失败: {}", err))?;
let normalized_target = if target_path.trim().is_empty() {
"/".to_string()
} else {
@@ -634,9 +632,15 @@ async fn api_upload_file(
return Err("API 地址不能为空".to_string());
}
// 使用流式 multipart 上传,避免大文件整块读入内存导致占用暴涨。
let file_part = reqwest::multipart::Part::file(&source_path)
.await
.map_err(|err| format!("读取文件失败: {}", err))?
.file_name(file_name);
let multipart = reqwest::multipart::Form::new()
.text("path", normalized_target)
.part("file", reqwest::multipart::Part::bytes(file_bytes).file_name(file_name));
.part("file", file_part);
let mut request = state
.client