feat: Tauri commands — encode/export/history CRUD
This commit is contained in:
+112
-3
@@ -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]
|
||||
fn greet(name: &str) -> String {
|
||||
format!("你好, {}! QRGen GUI 已就绪。", name)
|
||||
fn encode_qr(text: String, level: String, margin: u8) -> Result<QrResponse, 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))?;
|
||||
|
||||
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)]
|
||||
@@ -9,7 +109,16 @@ pub fn run() {
|
||||
.plugin(tauri_plugin_store::Builder::new().build())
|
||||
.plugin(tauri_plugin_dialog::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!())
|
||||
.expect("启动 QRGen GUI 失败");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user