mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-08-03 19:12:04 +08:00
refactor(backend): phase 4 - extract provider service layer
Architecture improvements: - Extract ProviderService with switch/backfill/write methods - Reduce command layer from 160 to 13 lines via delegation - Separate business logic (services) from state management (commands) - Introduce precise error handling with structured validation Refactoring details: - Split Codex/Claude switching into symmetric private methods - Add multi-layer validation for Codex auth field (existence + type) - Extract import_config_from_path for command and test reuse - Expose export_config_to_file and ProviderService in public API Test coverage: - Add 10+ integration tests for Claude/Codex switching flows - Cover import/export success and failure scenarios (JSON parse, missing file) - Verify state consistency on error paths (current remains unchanged) - Test snapshot backfill for both old and new providers after switching
This commit is contained in:
@@ -4,7 +4,7 @@ use crate::provider::Provider;
|
||||
use chrono::Utc;
|
||||
use serde_json::{json, Value};
|
||||
use std::fs;
|
||||
use std::path::PathBuf;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
// 默认仅保留最近 10 份备份,避免目录无限膨胀
|
||||
const MAX_BACKUPS: usize = 10;
|
||||
@@ -223,38 +223,41 @@ pub async fn import_config_from_file(
|
||||
file_path: String,
|
||||
state: tauri::State<'_, crate::store::AppState>,
|
||||
) -> Result<Value, String> {
|
||||
// 读取导入的文件
|
||||
let file_path_ref = std::path::Path::new(&file_path);
|
||||
let import_content = fs::read_to_string(file_path_ref)
|
||||
.map_err(|e| AppError::io(file_path_ref, e).to_string())?;
|
||||
import_config_from_path(Path::new(&file_path), &state)
|
||||
.map_err(|e| e.to_string())
|
||||
.map(|backup_id| {
|
||||
json!({
|
||||
"success": true,
|
||||
"message": "Configuration imported successfully",
|
||||
"backupId": backup_id
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/// 从文件导入配置的核心逻辑,供命令及测试复用。
|
||||
pub fn import_config_from_path(
|
||||
file_path: &Path,
|
||||
state: &crate::store::AppState,
|
||||
) -> Result<String, AppError> {
|
||||
let import_content =
|
||||
fs::read_to_string(file_path).map_err(|e| AppError::io(file_path, e))?;
|
||||
|
||||
// 验证并解析为配置对象
|
||||
let new_config: crate::app_config::MultiAppConfig =
|
||||
serde_json::from_str(&import_content)
|
||||
.map_err(|e| AppError::json(file_path_ref, e).to_string())?;
|
||||
.map_err(|e| AppError::json(file_path, e))?;
|
||||
|
||||
// 备份当前配置
|
||||
let config_path = crate::config::get_app_config_path();
|
||||
let backup_id = create_backup(&config_path).map_err(|e| e.to_string())?;
|
||||
let backup_id = create_backup(&config_path)?;
|
||||
|
||||
// 写入新配置到磁盘
|
||||
fs::write(&config_path, &import_content)
|
||||
.map_err(|e| AppError::io(&config_path, e).to_string())?;
|
||||
.map_err(|e| AppError::io(&config_path, e))?;
|
||||
|
||||
// 更新内存中的状态
|
||||
{
|
||||
let mut config_state = state
|
||||
.config
|
||||
.lock()
|
||||
.map_err(|e| AppError::from(e).to_string())?;
|
||||
*config_state = new_config;
|
||||
let mut guard = state.config.lock().map_err(AppError::from)?;
|
||||
*guard = new_config;
|
||||
}
|
||||
|
||||
Ok(json!({
|
||||
"success": true,
|
||||
"message": "Configuration imported successfully",
|
||||
"backupId": backup_id
|
||||
}))
|
||||
Ok(backup_id)
|
||||
}
|
||||
|
||||
/// 同步当前供应商配置到对应的 live 文件
|
||||
|
||||
Reference in New Issue
Block a user