Files
EasyCLIProxyAPI/src-tauri/src/app_settings.rs
T
lzt404 906f68f566 refactor: modularize backend architecture and test suite
- split Tauri business logic out of main.rs by domain
- separate agent and core configuration submodules
- organize Rust tests by feature with shared test support
- split frontend locale resources
2026-08-10 13:30:45 +08:00

233 lines
7.4 KiB
Rust

use super::*;
#[tauri::command]
pub(crate) fn health_check() -> &'static str {
"EasyCLIProxyAPI Rust backend is ready"
}
#[tauri::command]
pub(crate) fn detect_core_platform() -> Result<CorePlatform, String> {
current_core_platform()
}
#[tauri::command]
pub(crate) fn get_core_status(
process_state: tauri::State<'_, CoreProcessState>,
gui_config_state: tauri::State<'_, GuiConfigState>,
) -> Result<CoreStatus, String> {
let config = gui_config_state.snapshot()?;
current_core_status(Some(process_state.inner()), Some(config.port))
}
pub(crate) fn emit_core_status(app: &tauri::AppHandle, status: &CoreStatus) {
#[cfg(target_os = "windows")]
update_windows_tray_status(app, status);
let _ = app.emit(CORE_STATUS_EVENT, status);
}
#[tauri::command]
pub(crate) fn get_gui_settings(
gui_config_state: tauri::State<'_, GuiConfigState>,
) -> Result<GuiSettings, String> {
let config = gui_config_state.snapshot()?;
Ok(GuiSettings::from(&config))
}
#[tauri::command]
pub(crate) fn resolve_api_access_remarks(
queries: Vec<ApiAccessRemarkQuery>,
gui_config_state: tauri::State<'_, GuiConfigState>,
) -> Result<Vec<String>, String> {
let config = gui_config_state.snapshot()?;
queries
.into_iter()
.map(|query| {
validate_api_access_provider_section(&query.provider_section)?;
Ok(query
.api_keys
.iter()
.filter_map(|key| api_access_key_hash(key))
.find_map(|hash| {
config.api_access_remarks.iter().find(|entry| {
entry.provider_section == query.provider_section
&& entry.api_key_hash == hash
})
})
.map(|entry| entry.remark.clone())
.unwrap_or_default())
})
.collect()
}
#[tauri::command]
pub(crate) fn save_api_access_remark(
update: ApiAccessRemarkUpdate,
gui_config_state: tauri::State<'_, GuiConfigState>,
) -> Result<(), String> {
validate_api_access_provider_section(&update.provider_section)?;
let remark = update.remark.trim().to_string();
validate_api_key_remark(&remark)?;
let previous_hashes = update
.previous_api_keys
.iter()
.filter_map(|key| api_access_key_hash(key))
.collect::<HashSet<_>>();
let next_hashes = update
.api_keys
.iter()
.filter_map(|key| api_access_key_hash(key))
.collect::<HashSet<_>>();
let hashes_to_replace = previous_hashes
.union(&next_hashes)
.cloned()
.collect::<HashSet<_>>();
let provider_section = update.provider_section;
gui_config_state.update(|config| {
config.api_access_remarks.retain(|entry| {
entry.provider_section != provider_section
|| !hashes_to_replace.contains(&entry.api_key_hash)
});
if !remark.is_empty() {
config
.api_access_remarks
.extend(next_hashes.iter().map(|hash| GuiApiAccessRemark {
provider_section: provider_section.clone(),
api_key_hash: hash.clone(),
remark: remark.clone(),
}));
}
Ok(())
})?;
Ok(())
}
#[tauri::command]
pub(crate) fn set_app_locale(
app: tauri::AppHandle,
process_state: tauri::State<'_, CoreProcessState>,
gui_config_state: tauri::State<'_, GuiConfigState>,
locale: String,
) -> Result<String, String> {
let config = gui_config_state.set_locale(locale)?;
#[cfg(target_os = "windows")]
if let Ok(status) = current_core_status(Some(process_state.inner()), Some(config.port)) {
update_windows_tray_locale(&app, &config.locale, &status);
}
#[cfg(not(target_os = "windows"))]
let _ = (app, process_state);
Ok(config.locale)
}
#[tauri::command]
pub(crate) fn resolve_windows_close_request(
app: tauri::AppHandle,
gui_config_state: tauri::State<'_, GuiConfigState>,
action: WindowsCloseAction,
remember: Option<bool>,
) -> Result<(), String> {
if remember.unwrap_or(false) {
let close_behavior = match action {
WindowsCloseAction::Exit => WindowsCloseBehavior::Exit,
WindowsCloseAction::MinimizeToTray => WindowsCloseBehavior::MinimizeToTray,
};
gui_config_state.set_close_behavior(close_behavior)?;
}
match action {
WindowsCloseAction::Exit => app.exit(0),
WindowsCloseAction::MinimizeToTray => {
let window = app
.get_webview_window("main")
.ok_or_else(|| "主窗口不存在".to_string())?;
window
.hide()
.map_err(|error| format!("隐藏主窗口失败: {error}"))?;
}
}
Ok(())
}
pub(crate) fn app_autostart_enabled(app: &tauri::AppHandle) -> Result<bool, String> {
app.autolaunch()
.is_enabled()
.map_err(|error| format!("读取系统开机自启状态失败: {error}"))
}
pub(crate) fn set_app_autostart_enabled(
app: &tauri::AppHandle,
enabled: bool,
) -> Result<(), String> {
let manager = app.autolaunch();
if enabled {
manager
.enable()
.map_err(|error| format!("启用开机自启失败: {error}"))
} else {
manager
.disable()
.map_err(|error| format!("关闭开机自启失败: {error}"))
}
}
pub(crate) fn software_settings(
app: &tauri::AppHandle,
config: &GuiConfigFile,
) -> Result<SoftwareSettings, String> {
Ok(SoftwareSettings {
close_behavior: config.close_behavior,
autostart_enabled: app_autostart_enabled(app)?,
silent_start_enabled: config.silent_start,
})
}
#[tauri::command]
pub(crate) fn get_software_settings(
app: tauri::AppHandle,
gui_config_state: tauri::State<'_, GuiConfigState>,
) -> Result<SoftwareSettings, String> {
let config = gui_config_state.snapshot()?;
software_settings(&app, &config)
}
#[tauri::command]
pub(crate) fn save_software_settings(
app: tauri::AppHandle,
gui_config_state: tauri::State<'_, GuiConfigState>,
settings: SoftwareSettingsInput,
) -> Result<SoftwareSettings, String> {
let previous_config = gui_config_state.snapshot()?;
let previous_autostart_enabled = app_autostart_enabled(&app)?;
let autostart_changed = previous_autostart_enabled != settings.autostart_enabled;
if autostart_changed {
set_app_autostart_enabled(&app, settings.autostart_enabled)?;
}
let config = if previous_config.close_behavior == settings.close_behavior
&& previous_config.silent_start == settings.silent_start_enabled
{
previous_config
} else {
match gui_config_state
.set_software_preferences(settings.close_behavior, settings.silent_start_enabled)
{
Ok(config) => config,
Err(error) => {
let rollback_error = autostart_changed
.then(|| set_app_autostart_enabled(&app, previous_autostart_enabled).err())
.flatten();
return Err(match rollback_error {
Some(rollback_error) => {
format!("{error}; 回滚开机自启设置也失败: {rollback_error}")
}
None => error,
});
}
}
};
software_settings(&app, &config)
}