feat: Tauri commands — encode/export/history CRUD

This commit is contained in:
2026-06-17 00:19:39 +08:00
parent 4d3147a1e9
commit a952ebcb5f
+112 -3
View File
@@ -1,6 +1,106 @@
use qr_core::qr::{QrCode, QrConfig, VersionMode};
use qr_core::version::EcLevel;
use serde::{Deserialize, Serialize};
use std::sync::Mutex;
/// QR 编码响应
#[derive(Debug, Serialize, Clone)]
struct QrResponse {
svg: String,
version: u8,
size: u8,
mask: u8,
}
/// 历史记录条目
#[derive(Debug, Serialize, Deserialize, Clone)]
struct HistoryEntry {
id: String,
mode: String,
content: String,
timestamp: u64,
}
/// 应用状态
struct AppState {
history: Mutex<Vec<HistoryEntry>>,
}
/// 编码 QR 码,返回 SVG + 元信息
#[tauri::command] #[tauri::command]
fn greet(name: &str) -> String { fn encode_qr(text: String, level: String, margin: u8) -> Result<QrResponse, String> {
format!("你好, {}! QRGen GUI 已就绪。", name) let ec_level = match level.to_uppercase().as_str() {
"L" => EcLevel::L,
"M" => EcLevel::M,
"Q" => EcLevel::Q,
"H" => EcLevel::H,
_ => return Err(format!("无效纠错级别: {}", level)),
};
let config = QrConfig {
level: ec_level,
version: VersionMode::Auto,
margin,
};
let qr = QrCode::encode(&text, config).map_err(|e| format!("编码失败: {}", e))?;
let svg = qr.to_svg();
Ok(QrResponse {
svg,
version: qr.version.0,
size: qr.size(),
mask: qr.mask,
})
}
/// 导出 PNG bytes
#[tauri::command]
fn export_png(text: String, level: String, margin: u8, module_size: u8) -> Result<Vec<u8>, String> {
let ec_level = match level.to_uppercase().as_str() {
"L" => EcLevel::L,
"M" => EcLevel::M,
"Q" => EcLevel::Q,
"H" => EcLevel::H,
_ => return Err(format!("无效纠错级别: {}", level)),
};
let config = QrConfig {
level: ec_level,
version: VersionMode::Auto,
margin,
};
let qr = QrCode::encode(&text, config).map_err(|e| format!("编码失败: {}", e))?;
Ok(qr.to_png_bytes(module_size))
}
/// 保存历史记录条目
#[tauri::command]
fn save_history(state: tauri::State<AppState>, entry: HistoryEntry) -> Result<(), String> {
let mut history = state.history.lock().map_err(|e| e.to_string())?;
history.push(entry);
if history.len() > 50 {
history.remove(0);
}
Ok(())
}
/// 加载全部历史记录
#[tauri::command]
fn load_history(state: tauri::State<AppState>) -> Result<Vec<HistoryEntry>, String> {
let history = state.history.lock().map_err(|e| e.to_string())?;
Ok(history.clone())
}
/// 清空历史记录
#[tauri::command]
fn clear_history(state: tauri::State<AppState>) -> Result<(), String> {
let mut history = state.history.lock().map_err(|e| e.to_string())?;
history.clear();
Ok(())
} }
#[cfg_attr(mobile, tauri::mobile_entry_point)] #[cfg_attr(mobile, tauri::mobile_entry_point)]
@@ -9,7 +109,16 @@ pub fn run() {
.plugin(tauri_plugin_store::Builder::new().build()) .plugin(tauri_plugin_store::Builder::new().build())
.plugin(tauri_plugin_dialog::init()) .plugin(tauri_plugin_dialog::init())
.plugin(tauri_plugin_clipboard_manager::init()) .plugin(tauri_plugin_clipboard_manager::init())
.invoke_handler(tauri::generate_handler![greet]) .manage(AppState {
history: Mutex::new(Vec::new()),
})
.invoke_handler(tauri::generate_handler![
encode_qr,
export_png,
save_history,
load_history,
clear_history,
])
.run(tauri::generate_context!()) .run(tauri::generate_context!())
.expect("启动 QRGen GUI 失败"); .expect("启动 QRGen GUI 失败");
} }