性能优化

This commit is contained in:
zhongluofeng
2026-08-06 10:33:16 +08:00
parent c7578a2e6b
commit e66c53e66d
105 changed files with 7273 additions and 5002 deletions
+79 -24
View File
@@ -3,13 +3,14 @@
use base64::engine::general_purpose::STANDARD;
use base64::Engine as _;
use serde::Serialize;
use specta::Type;
use tauri::{AppHandle, State};
use super::manager::{ClipboardManager, ClipboardSettings};
use super::reader::dib_to_png;
use super::storage::{ClipboardItem, ClipboardItemDetail};
#[derive(Serialize)]
#[derive(Serialize, Type)]
#[serde(rename_all = "camelCase")]
pub struct ClipboardStatus {
pub running: bool,
@@ -21,7 +22,7 @@ fn img_to_base64(b: &[u8]) -> Option<String> {
}
/// 历史查询结果(含总数,用于分页)
#[derive(Serialize)]
#[derive(Serialize, Type)]
#[serde(rename_all = "camelCase")]
pub struct HistoryPage {
pub items: Vec<ClipboardItem>,
@@ -29,74 +30,107 @@ pub struct HistoryPage {
}
#[tauri::command]
#[specta::specta]
pub async fn clipboard_get_history(
limit: Option<i64>,
offset: Option<i64>,
kind: Option<String>,
manager: State<'_, ClipboardManager>,
) -> Result<HistoryPage, String> {
let storage = manager.storage();
let storage = manager.storage().clone();
let kind = kind.unwrap_or_else(|| "all".into());
let limit = limit.unwrap_or(50);
let offset = offset.unwrap_or(0);
let items = storage.get_history(limit, offset, &kind);
let total = storage.count_kind(&kind);
Ok(HistoryPage { items, total })
// SQLite 查询移出 async runtime 线程
tauri::async_runtime::spawn_blocking(move || {
let items = storage.get_history(limit, offset, &kind);
let total = storage.count_kind(&kind);
HistoryPage { items, total }
})
.await
.map_err(|e| format!("查询任务失败: {}", e))
}
#[tauri::command]
#[specta::specta]
pub async fn clipboard_get_pinned(
manager: State<'_, ClipboardManager>,
) -> Result<Vec<ClipboardItem>, String> {
Ok(manager.storage().get_pinned())
let storage = manager.storage().clone();
tauri::async_runtime::spawn_blocking(move || storage.get_pinned())
.await
.map_err(|e| format!("查询任务失败: {}", e))
}
#[tauri::command]
#[specta::specta]
pub async fn clipboard_search(
query: String,
limit: Option<i64>,
offset: Option<i64>,
manager: State<'_, ClipboardManager>,
) -> Result<HistoryPage, String> {
let storage = manager.storage();
let storage = manager.storage().clone();
let limit = limit.unwrap_or(50);
let offset = offset.unwrap_or(0);
let items = storage.search(&query, limit, offset);
let total = storage.count_search(&query);
Ok(HistoryPage { items, total })
tauri::async_runtime::spawn_blocking(move || {
let items = storage.search(&query, limit, offset);
let total = storage.count_search(&query);
HistoryPage { items, total }
})
.await
.map_err(|e| format!("查询任务失败: {}", e))
}
#[tauri::command]
#[specta::specta]
pub async fn clipboard_get_item(
id: i64,
manager: State<'_, ClipboardManager>,
) -> Result<Option<ClipboardItemDetail>, String> {
Ok(manager.storage().get_detail(id, img_to_base64))
let storage = manager.storage().clone();
// get_detail 内部:锁内取数 + 锁外 base64 编码,整体移出主线程
tauri::async_runtime::spawn_blocking(move || storage.get_detail(id, img_to_base64))
.await
.map_err(|e| format!("查询任务失败: {}", e))
}
#[tauri::command]
#[specta::specta]
pub async fn clipboard_set_pinned(
id: i64,
pinned: bool,
manager: State<'_, ClipboardManager>,
) -> Result<bool, String> {
Ok(manager.storage().set_pinned(id, pinned))
let storage = manager.storage().clone();
tauri::async_runtime::spawn_blocking(move || storage.set_pinned(id, pinned))
.await
.map_err(|e| format!("操作任务失败: {}", e))
}
#[tauri::command]
#[specta::specta]
pub async fn clipboard_delete(
id: i64,
manager: State<'_, ClipboardManager>,
) -> Result<bool, String> {
Ok(manager.storage().delete(id))
let storage = manager.storage().clone();
tauri::async_runtime::spawn_blocking(move || storage.delete(id))
.await
.map_err(|e| format!("删除任务失败: {}", e))
}
#[tauri::command]
#[specta::specta]
pub async fn clipboard_clear(manager: State<'_, ClipboardManager>) -> Result<bool, String> {
Ok(manager.storage().clear_non_pinned())
let storage = manager.storage().clone();
tauri::async_runtime::spawn_blocking(move || storage.clear_non_pinned())
.await
.map_err(|e| format!("清空任务失败: {}", e))
}
#[tauri::command]
#[specta::specta]
pub async fn clipboard_copy_back(
id: i64,
manager: State<'_, ClipboardManager>,
@@ -105,11 +139,16 @@ pub async fn clipboard_copy_back(
}
#[tauri::command]
#[specta::specta]
pub async fn clipboard_count(manager: State<'_, ClipboardManager>) -> Result<i64, String> {
Ok(manager.storage().count())
let storage = manager.storage().clone();
tauri::async_runtime::spawn_blocking(move || storage.count())
.await
.map_err(|e| format!("查询任务失败: {}", e))
}
#[tauri::command]
#[specta::specta]
pub async fn clipboard_get_settings(
manager: State<'_, ClipboardManager>,
) -> Result<ClipboardSettings, String> {
@@ -117,6 +156,7 @@ pub async fn clipboard_get_settings(
}
#[tauri::command]
#[specta::specta]
pub async fn clipboard_save_settings(
settings: ClipboardSettings,
app: AppHandle,
@@ -131,9 +171,11 @@ pub async fn clipboard_save_settings(
} else if !settings.enabled && prev_enabled {
manager.stop();
}
// 快捷键变化时重新注册
// 快捷键变化时重新注册(共享工具模块,原子化 + 冲突检测)
if settings.shortcut != prev_shortcut {
super::popup::register_shortcut(&app, &settings.shortcut)?;
crate::shortcut::register_shortcut(&app, "剪贴板", &settings.shortcut, |a| {
super::popup::show_popup(a)
})?;
// 新快捷键非空时确保弹窗窗口已预创建
if !settings.shortcut.trim().is_empty() {
super::popup::ensure_popup_window(&app);
@@ -143,22 +185,27 @@ pub async fn clipboard_save_settings(
}
#[tauri::command]
#[specta::specta]
pub async fn clipboard_status(
manager: State<'_, ClipboardManager>,
) -> Result<ClipboardStatus, String> {
Ok(ClipboardStatus {
running: manager.is_running(),
count: manager.storage().count(),
})
let storage = manager.storage().clone();
let running = manager.is_running();
let count = tauri::async_runtime::spawn_blocking(move || storage.count())
.await
.map_err(|e| format!("查询任务失败: {}", e))?;
Ok(ClipboardStatus { running, count })
}
#[tauri::command]
#[specta::specta]
pub async fn clipboard_start(app: AppHandle, manager: State<'_, ClipboardManager>) -> Result<(), String> {
manager.start(&app);
Ok(())
}
#[tauri::command]
#[specta::specta]
pub async fn clipboard_stop(manager: State<'_, ClipboardManager>) -> Result<(), String> {
manager.stop();
Ok(())
@@ -166,22 +213,27 @@ pub async fn clipboard_stop(manager: State<'_, ClipboardManager>) -> Result<(),
/// 注册(或切换)快捷弹窗全局快捷键
#[tauri::command]
#[specta::specta]
pub async fn clipboard_register_shortcut(
shortcut: String,
app: AppHandle,
) -> Result<(), String> {
super::popup::register_shortcut(&app, &shortcut)
crate::shortcut::register_shortcut(&app, "剪贴板", &shortcut, |a| {
super::popup::show_popup(a)
})
}
/// 注销快捷弹窗全局快捷键
#[tauri::command]
#[specta::specta]
pub async fn clipboard_unregister_shortcut(app: AppHandle) -> Result<(), String> {
super::popup::unregister_shortcut(&app);
crate::shortcut::unregister_shortcut(&app, "剪贴板");
Ok(())
}
/// 手动触发显示快捷弹窗(供 UI 按钮调用)
#[tauri::command]
#[specta::specta]
pub async fn clipboard_show_popup(app: AppHandle) -> Result<(), String> {
super::popup::show_popup(&app);
Ok(())
@@ -189,6 +241,7 @@ pub async fn clipboard_show_popup(app: AppHandle) -> Result<(), String> {
/// 隐藏快捷弹窗
#[tauri::command]
#[specta::specta]
pub async fn clipboard_hide_popup(app: AppHandle) -> Result<(), String> {
super::popup::hide_popup(&app);
Ok(())
@@ -196,6 +249,7 @@ pub async fn clipboard_hide_popup(app: AppHandle) -> Result<(), String> {
/// 显示已创建的弹窗窗口(前端 onMounted 后调用)
#[tauri::command]
#[specta::specta]
pub async fn clipboard_show_window(app: AppHandle) -> Result<(), String> {
super::popup::show_window(&app);
Ok(())
@@ -203,6 +257,7 @@ pub async fn clipboard_show_window(app: AppHandle) -> Result<(), String> {
/// 隐藏弹窗并模拟 Ctrl+V 粘贴到原窗口
#[tauri::command]
#[specta::specta]
pub async fn clipboard_paste_to_target(app: AppHandle) -> Result<(), String> {
super::popup::paste_to_target(&app);
Ok(())