性能优化
This commit is contained in:
@@ -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(())
|
||||
|
||||
Reference in New Issue
Block a user