feat: 按安装目录隔离存储应用数据,实现多实例独立运行
新增 StoragePaths 模块,将数据库、设置、frp 版本等业务数据统一保存在应用实际安装位置,避免不同实例或版本间数据混淆。新增 Preferences 模块管理安装目录内的持久化设置,重构数据库初始化逻辑,修改 Frpc 运行目录、frp 版本存储路径,新增数据目录锁机制防止多进程冲突,同时更新文档说明数据目录规则与平台差异。
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
use std::collections::BTreeMap;
|
||||
use std::sync::Mutex;
|
||||
|
||||
use tauri::State;
|
||||
use tauri_helper::auto_collect_command;
|
||||
|
||||
use crate::services::storage::{StoragePaths, write_json};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct PreferencesLock(pub Mutex<()>);
|
||||
|
||||
#[tauri::command]
|
||||
#[auto_collect_command]
|
||||
pub fn get_preferences(
|
||||
paths: State<'_, StoragePaths>,
|
||||
lock: State<'_, PreferencesLock>,
|
||||
) -> Result<Option<BTreeMap<String, String>>, String> {
|
||||
let _guard = lock.0.lock().map_err(|e| e.to_string())?;
|
||||
let path = paths.data().join("preferences.json");
|
||||
match std::fs::read(path) {
|
||||
Ok(bytes) => serde_json::from_slice(&bytes)
|
||||
.map(Some)
|
||||
.map_err(|e| e.to_string()),
|
||||
Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok(None),
|
||||
Err(e) => Err(e.to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
#[auto_collect_command]
|
||||
pub fn set_preferences(
|
||||
paths: State<'_, StoragePaths>,
|
||||
lock: State<'_, PreferencesLock>,
|
||||
preferences: BTreeMap<String, String>,
|
||||
) -> Result<(), String> {
|
||||
if preferences
|
||||
.iter()
|
||||
.any(|(key, value)| !key.starts_with("frpcpilot:") || key.len() + value.len() > 65536)
|
||||
|| preferences.len() > 100
|
||||
{
|
||||
return Err("设置数据无效或过大".into());
|
||||
}
|
||||
let _guard = lock.0.lock().map_err(|e| e.to_string())?;
|
||||
write_json(&paths.data().join("preferences.json"), &preferences)
|
||||
}
|
||||
Reference in New Issue
Block a user