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>, } /// 编码 QR 码,返回 SVG + 元信息 #[tauri::command] fn encode_qr(text: String, level: String, margin: u8) -> Result { 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, 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, 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) -> Result, String> { let history = state.history.lock().map_err(|e| e.to_string())?; Ok(history.clone()) } /// 清空历史记录 #[tauri::command] fn clear_history(state: tauri::State) -> Result<(), String> { let mut history = state.history.lock().map_err(|e| e.to_string())?; history.clear(); Ok(()) } #[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() .plugin(tauri_plugin_store::Builder::new().build()) .plugin(tauri_plugin_dialog::init()) .plugin(tauri_plugin_clipboard_manager::init()) .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 失败"); }