feat: 添加应用配置管理功能,支持加载和保存配置
This commit is contained in:
@@ -24,4 +24,7 @@ serde = { version = "1", features = ["derive"] }
|
|||||||
serde_json = "1"
|
serde_json = "1"
|
||||||
tauri-plugin-fs = "2"
|
tauri-plugin-fs = "2"
|
||||||
tauri-plugin-dialog = "2"
|
tauri-plugin-dialog = "2"
|
||||||
|
blake3 = { version = "1.8.3", features = ["serde", "digest", "pure"] }
|
||||||
|
anyhow = "1.0.102"
|
||||||
|
thiserror = "2.0.18"
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
use crate::config::{AppConfig, AppConfigState};
|
||||||
|
use tauri::State;
|
||||||
use tauri::{AppHandle, WebviewWindow};
|
use tauri::{AppHandle, WebviewWindow};
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
@@ -12,3 +14,22 @@ pub fn set_window_title(
|
|||||||
.unwrap_or(app_name);
|
.unwrap_or(app_name);
|
||||||
window.set_title(&new_title).map_err(|e| e.to_string())
|
window.set_title(&new_title).map_err(|e| e.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
pub fn load_app_config(state: State<'_, AppConfigState>) -> Result<AppConfig, String> {
|
||||||
|
state.get().map_err(|e| format!("读取应用配置失败: {e}"))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
pub fn save_app_config(
|
||||||
|
app_handle: AppHandle,
|
||||||
|
state: State<'_, AppConfigState>,
|
||||||
|
config: AppConfig,
|
||||||
|
) -> Result<(), String> {
|
||||||
|
config
|
||||||
|
.save(&app_handle)
|
||||||
|
.map_err(|e| format!("保存应用配置失败: {e}"))?;
|
||||||
|
state
|
||||||
|
.set(config)
|
||||||
|
.map_err(|e| format!("更新应用配置状态失败: {e}"))
|
||||||
|
}
|
||||||
|
|||||||
101
src-tauri/src/config.rs
Normal file
101
src-tauri/src/config.rs
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::{fs, path::PathBuf, sync::RwLock};
|
||||||
|
use tauri::{path::BaseDirectory, AppHandle, Manager};
|
||||||
|
|
||||||
|
#[derive(Clone, Deserialize, Serialize)]
|
||||||
|
pub enum ProxyKind {
|
||||||
|
Http,
|
||||||
|
Socks5,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for ProxyKind {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::Http
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Deserialize, Serialize, Default)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct ProxyConfig {
|
||||||
|
pub enabled: bool,
|
||||||
|
pub kind: ProxyKind,
|
||||||
|
pub host: Option<String>,
|
||||||
|
pub port: Option<u16>,
|
||||||
|
pub username: Option<String>,
|
||||||
|
pub password: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Deserialize, Serialize, Default)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct AppConfig {
|
||||||
|
pub proxy: Option<ProxyConfig>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct AppConfigState {
|
||||||
|
inner: RwLock<AppConfig>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AppConfigState {
|
||||||
|
pub fn new(config: AppConfig) -> Self {
|
||||||
|
Self {
|
||||||
|
inner: RwLock::new(config),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get(&self) -> anyhow::Result<AppConfig> {
|
||||||
|
let guard = self
|
||||||
|
.inner
|
||||||
|
.read()
|
||||||
|
.map_err(|_| anyhow::anyhow!("读取应用配置状态失败"))?;
|
||||||
|
Ok(guard.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set(&self, config: AppConfig) -> anyhow::Result<()> {
|
||||||
|
let mut guard = self
|
||||||
|
.inner
|
||||||
|
.write()
|
||||||
|
.map_err(|_| anyhow::anyhow!("写入应用配置状态失败"))?;
|
||||||
|
*guard = config;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AppConfig {
|
||||||
|
fn config_path(app_handle: &AppHandle) -> anyhow::Result<PathBuf> {
|
||||||
|
Ok(app_handle
|
||||||
|
.path()
|
||||||
|
.resolve("config.json", BaseDirectory::AppData)?)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn save(&self, app_handle: &AppHandle) -> anyhow::Result<()> {
|
||||||
|
let config_path = Self::config_path(app_handle)?;
|
||||||
|
if let Some(parent_dir) = config_path.parent() {
|
||||||
|
fs::create_dir_all(parent_dir)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let content = serde_json::to_string_pretty(self)?;
|
||||||
|
fs::write(config_path, content)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn load(app_handle: &AppHandle) -> anyhow::Result<Self> {
|
||||||
|
let config_path = Self::config_path(app_handle)?;
|
||||||
|
if !config_path.exists() {
|
||||||
|
return Ok(Self::default());
|
||||||
|
}
|
||||||
|
|
||||||
|
let content = fs::read_to_string(config_path)?;
|
||||||
|
Ok(serde_json::from_str(&content)?)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn load_or_init(app_handle: &AppHandle) -> anyhow::Result<Self> {
|
||||||
|
let config_path = Self::config_path(app_handle)?;
|
||||||
|
if !config_path.exists() {
|
||||||
|
let default_config = Self::default();
|
||||||
|
default_config.save(app_handle)?;
|
||||||
|
return Ok(default_config);
|
||||||
|
}
|
||||||
|
|
||||||
|
Self::load(app_handle)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,12 +1,25 @@
|
|||||||
mod commands;
|
mod commands;
|
||||||
|
mod config;
|
||||||
|
|
||||||
|
use tauri::Manager;
|
||||||
|
|
||||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||||
pub fn run() {
|
pub fn run() {
|
||||||
tauri::Builder::default()
|
tauri::Builder::default()
|
||||||
|
.setup(|app| {
|
||||||
|
let app_handle = app.handle().clone();
|
||||||
|
let config = config::AppConfig::load_or_init(&app_handle)?;
|
||||||
|
app.manage(config::AppConfigState::new(config));
|
||||||
|
Ok(())
|
||||||
|
})
|
||||||
.plugin(tauri_plugin_dialog::init())
|
.plugin(tauri_plugin_dialog::init())
|
||||||
.plugin(tauri_plugin_fs::init())
|
.plugin(tauri_plugin_fs::init())
|
||||||
.plugin(tauri_plugin_opener::init())
|
.plugin(tauri_plugin_opener::init())
|
||||||
.invoke_handler(tauri::generate_handler![commands::set_window_title])
|
.invoke_handler(tauri::generate_handler![
|
||||||
|
commands::set_window_title,
|
||||||
|
commands::load_app_config,
|
||||||
|
commands::save_app_config
|
||||||
|
])
|
||||||
.run(tauri::generate_context!())
|
.run(tauri::generate_context!())
|
||||||
.expect("error while running tauri application");
|
.expect("error while running tauri application");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user