feat: 基础架构重构
This commit is contained in:
315
apps/desktop/src-tauri/src/business/services/config_manager.rs
Normal file
315
apps/desktop/src-tauri/src/business/services/config_manager.rs
Normal file
@@ -0,0 +1,315 @@
|
||||
//! 配置管理服务
|
||||
//! 统一管理应用配置,支持配置验证和环境适配
|
||||
|
||||
use anyhow::{Result, anyhow};
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::RwLock;
|
||||
use tracing::{info, warn, error, debug};
|
||||
|
||||
use crate::config::{AppConfig, ComfyUISettings};
|
||||
use crate::data::models::comfyui::{ComfyUIConfig, ValidationResult};
|
||||
|
||||
/// 环境类型
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum Environment {
|
||||
/// 开发环境
|
||||
Development,
|
||||
/// 测试环境
|
||||
Testing,
|
||||
/// 生产环境
|
||||
Production,
|
||||
}
|
||||
|
||||
impl Environment {
|
||||
/// 从环境变量获取环境类型
|
||||
pub fn from_env() -> Self {
|
||||
match std::env::var("MIXVIDEO_ENV").as_deref() {
|
||||
Ok("production") | Ok("prod") => Environment::Production,
|
||||
Ok("testing") | Ok("test") => Environment::Testing,
|
||||
_ => Environment::Development,
|
||||
}
|
||||
}
|
||||
|
||||
/// 获取环境名称
|
||||
pub fn name(&self) -> &'static str {
|
||||
match self {
|
||||
Environment::Development => "development",
|
||||
Environment::Testing => "testing",
|
||||
Environment::Production => "production",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 配置管理器
|
||||
pub struct ConfigManager {
|
||||
/// 应用配置
|
||||
app_config: Arc<RwLock<AppConfig>>,
|
||||
/// 当前环境
|
||||
environment: Environment,
|
||||
/// 配置文件路径
|
||||
config_path: Option<String>,
|
||||
}
|
||||
|
||||
impl ConfigManager {
|
||||
/// 创建新的配置管理器
|
||||
pub fn new(app_config: AppConfig, config_path: Option<String>) -> Self {
|
||||
let environment = Environment::from_env();
|
||||
info!("配置管理器初始化,环境: {}", environment.name());
|
||||
|
||||
Self {
|
||||
app_config: Arc::new(RwLock::new(app_config)),
|
||||
environment,
|
||||
config_path,
|
||||
}
|
||||
}
|
||||
|
||||
/// 获取当前环境
|
||||
pub fn get_environment(&self) -> &Environment {
|
||||
&self.environment
|
||||
}
|
||||
|
||||
/// 获取应用配置
|
||||
pub async fn get_app_config(&self) -> AppConfig {
|
||||
self.app_config.read().await.clone()
|
||||
}
|
||||
|
||||
/// 更新应用配置
|
||||
pub async fn update_app_config(&self, config: AppConfig) -> Result<()> {
|
||||
// 验证配置
|
||||
let validation = self.validate_app_config(&config).await?;
|
||||
if !validation.valid {
|
||||
return Err(anyhow!("配置验证失败: {:?}", validation.errors));
|
||||
}
|
||||
|
||||
// 更新配置
|
||||
*self.app_config.write().await = config;
|
||||
|
||||
// 保存到文件
|
||||
self.save_config().await?;
|
||||
|
||||
info!("应用配置已更新");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// 获取 ComfyUI 配置
|
||||
pub async fn get_comfyui_config(&self) -> ComfyUIConfig {
|
||||
let app_config = self.app_config.read().await;
|
||||
let mut config = app_config.comfyui_settings.to_comfyui_config();
|
||||
|
||||
// 根据环境调整配置
|
||||
self.apply_environment_config(&mut config);
|
||||
|
||||
config
|
||||
}
|
||||
|
||||
/// 更新 ComfyUI 配置
|
||||
pub async fn update_comfyui_config(&self, config: ComfyUIConfig) -> Result<()> {
|
||||
// 验证配置
|
||||
let validation = config.validate();
|
||||
if !validation.valid {
|
||||
return Err(anyhow!("ComfyUI 配置验证失败: {:?}", validation.errors));
|
||||
}
|
||||
|
||||
// 更新应用配置中的 ComfyUI 设置
|
||||
{
|
||||
let mut app_config = self.app_config.write().await;
|
||||
app_config.comfyui_settings.update_from_comfyui_config(&config);
|
||||
}
|
||||
|
||||
// 保存到文件
|
||||
self.save_config().await?;
|
||||
|
||||
info!("ComfyUI 配置已更新");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// 获取 ComfyUI 设置
|
||||
pub async fn get_comfyui_settings(&self) -> ComfyUISettings {
|
||||
let app_config = self.app_config.read().await;
|
||||
app_config.comfyui_settings.clone()
|
||||
}
|
||||
|
||||
/// 更新 ComfyUI 设置
|
||||
pub async fn update_comfyui_settings(&self, settings: ComfyUISettings) -> Result<()> {
|
||||
// 验证设置
|
||||
let validation = settings.validate();
|
||||
if !validation.valid {
|
||||
return Err(anyhow!("ComfyUI 设置验证失败: {:?}", validation.errors));
|
||||
}
|
||||
|
||||
// 更新配置
|
||||
{
|
||||
let mut app_config = self.app_config.write().await;
|
||||
app_config.comfyui_settings = settings;
|
||||
}
|
||||
|
||||
// 保存到文件
|
||||
self.save_config().await?;
|
||||
|
||||
info!("ComfyUI 设置已更新");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// 重置 ComfyUI 配置为默认值
|
||||
pub async fn reset_comfyui_config(&self) -> Result<()> {
|
||||
let default_settings = ComfyUISettings::default();
|
||||
self.update_comfyui_settings(default_settings).await
|
||||
}
|
||||
|
||||
/// 验证应用配置
|
||||
async fn validate_app_config(&self, config: &AppConfig) -> Result<ValidationResult> {
|
||||
use crate::data::models::comfyui::{ValidationResult, ValidationError};
|
||||
|
||||
let mut result = ValidationResult::success();
|
||||
|
||||
// 验证主题
|
||||
if !["light", "dark", "auto"].contains(&config.theme.as_str()) {
|
||||
result.add_error(ValidationError::new("theme", "无效的主题设置"));
|
||||
}
|
||||
|
||||
// 验证语言
|
||||
if !["zh-CN", "en-US"].contains(&config.language.as_str()) {
|
||||
result.add_error(ValidationError::new("language", "无效的语言设置"));
|
||||
}
|
||||
|
||||
// 验证窗口大小
|
||||
if config.window_size.width <= 0.0 || config.window_size.height <= 0.0 {
|
||||
result.add_error(ValidationError::new("window_size", "窗口大小必须大于 0"));
|
||||
}
|
||||
|
||||
// 验证 ComfyUI 设置
|
||||
let comfyui_validation = config.comfyui_settings.validate();
|
||||
for error in comfyui_validation.errors {
|
||||
result.add_error(error);
|
||||
}
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
/// 根据环境调整配置
|
||||
fn apply_environment_config(&self, config: &mut ComfyUIConfig) {
|
||||
match self.environment {
|
||||
Environment::Development => {
|
||||
// 开发环境:启用详细日志,较短超时
|
||||
config.timeout_seconds = std::cmp::min(config.timeout_seconds, 120);
|
||||
config.retry_attempts = std::cmp::min(config.retry_attempts, 2);
|
||||
debug!("应用开发环境配置");
|
||||
}
|
||||
Environment::Testing => {
|
||||
// 测试环境:中等超时,适中重试
|
||||
config.timeout_seconds = std::cmp::min(config.timeout_seconds, 180);
|
||||
config.retry_attempts = std::cmp::min(config.retry_attempts, 3);
|
||||
debug!("应用测试环境配置");
|
||||
}
|
||||
Environment::Production => {
|
||||
// 生产环境:较长超时,更多重试
|
||||
config.timeout_seconds = std::cmp::max(config.timeout_seconds, 300);
|
||||
config.retry_attempts = std::cmp::max(config.retry_attempts, 3);
|
||||
debug!("应用生产环境配置");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 保存配置到文件
|
||||
async fn save_config(&self) -> Result<()> {
|
||||
if let Some(config_path) = &self.config_path {
|
||||
let app_config = self.app_config.read().await;
|
||||
let config_json = serde_json::to_string_pretty(&*app_config)?;
|
||||
|
||||
tokio::fs::write(config_path, config_json).await
|
||||
.map_err(|e| anyhow!("保存配置文件失败: {}", e))?;
|
||||
|
||||
debug!("配置已保存到: {}", config_path);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// 从文件加载配置
|
||||
pub async fn load_config(config_path: &str) -> Result<AppConfig> {
|
||||
match tokio::fs::read_to_string(config_path).await {
|
||||
Ok(content) => {
|
||||
let config: AppConfig = serde_json::from_str(&content)
|
||||
.map_err(|e| anyhow!("解析配置文件失败: {}", e))?;
|
||||
|
||||
info!("从文件加载配置: {}", config_path);
|
||||
Ok(config)
|
||||
}
|
||||
Err(_) => {
|
||||
warn!("配置文件不存在,使用默认配置: {}", config_path);
|
||||
Ok(AppConfig::default())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 导出配置
|
||||
pub async fn export_config(&self) -> Result<String> {
|
||||
let app_config = self.app_config.read().await;
|
||||
serde_json::to_string_pretty(&*app_config)
|
||||
.map_err(|e| anyhow!("导出配置失败: {}", e))
|
||||
}
|
||||
|
||||
/// 导入配置
|
||||
pub async fn import_config(&self, config_json: &str) -> Result<()> {
|
||||
let config: AppConfig = serde_json::from_str(config_json)
|
||||
.map_err(|e| anyhow!("解析配置失败: {}", e))?;
|
||||
|
||||
self.update_app_config(config).await
|
||||
}
|
||||
|
||||
/// 获取配置统计信息
|
||||
pub async fn get_config_stats(&self) -> ConfigStats {
|
||||
let app_config = self.app_config.read().await;
|
||||
|
||||
ConfigStats {
|
||||
environment: self.environment.clone(),
|
||||
config_path: self.config_path.clone(),
|
||||
comfyui_enabled: app_config.comfyui_settings.enabled,
|
||||
sdk_enabled: app_config.comfyui_settings.is_sdk_enabled(),
|
||||
recent_projects_count: app_config.recent_projects.len(),
|
||||
}
|
||||
}
|
||||
|
||||
/// 检查配置健康状态
|
||||
pub async fn health_check(&self) -> Result<ConfigHealthStatus> {
|
||||
let app_config = self.app_config.read().await;
|
||||
let validation = self.validate_app_config(&*app_config).await?;
|
||||
|
||||
let status = if validation.valid {
|
||||
ConfigHealthStatus::Healthy
|
||||
} else {
|
||||
ConfigHealthStatus::Unhealthy(validation.errors)
|
||||
};
|
||||
|
||||
Ok(status)
|
||||
}
|
||||
}
|
||||
|
||||
/// 配置统计信息
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ConfigStats {
|
||||
pub environment: Environment,
|
||||
pub config_path: Option<String>,
|
||||
pub comfyui_enabled: bool,
|
||||
pub sdk_enabled: bool,
|
||||
pub recent_projects_count: usize,
|
||||
}
|
||||
|
||||
/// 配置健康状态
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum ConfigHealthStatus {
|
||||
/// 健康
|
||||
Healthy,
|
||||
/// 不健康
|
||||
Unhealthy(Vec<crate::data::models::comfyui::ValidationError>),
|
||||
}
|
||||
|
||||
impl std::fmt::Display for ConfigHealthStatus {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
ConfigHealthStatus::Healthy => write!(f, "健康"),
|
||||
ConfigHealthStatus::Unhealthy(errors) => {
|
||||
write!(f, "不健康 ({} 个错误)", errors.len())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user