refactor 6

This commit is contained in:
Julian Freeman
2026-04-18 16:15:52 -04:00
parent 73976d1367
commit 708df41063
9 changed files with 180 additions and 102 deletions

View File

@@ -5,7 +5,6 @@ use crate::domain::models::{
UpdateCandidate,
};
use crate::services::{essentials_service, settings_service, software_state_service};
use crate::winget::Software;
#[tauri::command]
pub fn get_settings(app: AppHandle) -> AppSettings {
@@ -32,16 +31,6 @@ pub async fn initialize_app(app: AppHandle) -> Result<bool, String> {
software_state_service::initialize_app(app).await
}
#[tauri::command]
pub async fn get_installed_software(app: AppHandle) -> Vec<Software> {
software_state_service::get_installed_software(app).await
}
#[tauri::command]
pub async fn get_updates(app: AppHandle) -> Vec<Software> {
software_state_service::get_updates(app).await
}
#[tauri::command]
pub async fn get_dashboard_snapshot(app: AppHandle) -> DashboardSnapshot {
software_state_service::get_dashboard_snapshot(app).await
@@ -57,11 +46,6 @@ pub async fn get_update_candidates(app: AppHandle) -> Vec<UpdateCandidate> {
software_state_service::get_update_candidates(app).await
}
#[tauri::command]
pub async fn get_software_info(app: AppHandle, id: String) -> Option<Software> {
software_state_service::get_software_info(app, id).await
}
#[tauri::command]
pub async fn get_software_icon(app: AppHandle, id: String, name: String) -> Option<String> {
software_state_service::get_software_icon(app, id, name).await

View File

@@ -51,13 +51,6 @@ pub struct SyncEssentialsResult {
pub message: String,
}
#[derive(Clone, Serialize)]
pub struct InstallProgress {
pub id: String,
pub status: String,
pub progress: f32,
}
#[derive(Clone)]
pub struct ResolvedPostInstall {
pub software: Software,

View File

@@ -22,13 +22,10 @@ pub fn run() {
commands::app_commands::save_settings,
commands::app_commands::sync_essentials,
commands::app_commands::get_essentials,
commands::app_commands::get_installed_software,
commands::app_commands::get_updates,
commands::app_commands::get_dashboard_snapshot,
commands::app_commands::get_essentials_status,
commands::app_commands::get_update_candidates,
commands::app_commands::get_software_icon,
commands::app_commands::get_software_info,
tasks::install_queue::install_software,
commands::app_commands::get_logs_history
])

View File

@@ -4,9 +4,23 @@ use tauri::AppHandle;
use crate::domain::models::{EssentialsRepo, SyncEssentialsResult};
use crate::services::log_service::emit_log;
use crate::services::settings_service;
use crate::services::task_event_service::emit_task_event;
use crate::storage::{essentials_store, paths};
pub async fn sync_essentials(app: &AppHandle) -> Result<SyncEssentialsResult, String> {
emit_task_event(
app,
"sync-essentials",
"sync-essentials",
"sync_essentials",
"running",
"starting",
0.0,
None,
Some("Starting essentials sync".to_string()),
None,
);
let settings = settings_service::get_settings(app);
let url = format!("{}/setup-essentials.json", settings.repo_url.trim_end_matches('/'));
let cache_path = paths::get_essentials_path(app);
@@ -42,6 +56,20 @@ pub async fn sync_essentials(app: &AppHandle) -> Result<SyncEssentialsResult, St
status: "updated".to_string(),
message: "清单同步成功".to_string(),
})
.inspect(|_| {
emit_task_event(
app,
"sync-essentials",
"sync-essentials",
"sync_essentials",
"completed",
"updated",
1.0,
None,
Some("Essentials list updated successfully".to_string()),
None,
);
})
} else {
emit_log(
app,
@@ -50,11 +78,35 @@ pub async fn sync_essentials(app: &AppHandle) -> Result<SyncEssentialsResult, St
"Invalid JSON format from repository. Expected { version, essentials }.",
"error",
);
emit_task_event(
app,
"sync-essentials",
"sync-essentials",
"sync_essentials",
"failed",
"invalid_json",
1.0,
None,
Some("Invalid JSON format".to_string()),
None,
);
Err("Invalid JSON format".to_string())
}
} else {
let err_msg = format!("HTTP Error: {}", response.status());
emit_log(app, "sync-essentials", "Error", &err_msg, "error");
emit_task_event(
app,
"sync-essentials",
"sync-essentials",
"sync_essentials",
"failed",
"http_error",
1.0,
None,
Some(err_msg.clone()),
None,
);
Err(err_msg)
}
}
@@ -71,9 +123,35 @@ pub async fn sync_essentials(app: &AppHandle) -> Result<SyncEssentialsResult, St
status: "cache_used".to_string(),
message: "网络不可用,已继续使用本地缓存".to_string(),
})
.inspect(|_| {
emit_task_event(
app,
"sync-essentials",
"sync-essentials",
"sync_essentials",
"completed",
"cache_used",
1.0,
None,
Some("Network unavailable, used local cache".to_string()),
None,
);
})
} else {
let err_msg = format!("Network issue: {}", e);
emit_log(app, "sync-essentials", "Error", &err_msg, "error");
emit_task_event(
app,
"sync-essentials",
"sync-essentials",
"sync_essentials",
"failed",
"network_error",
1.0,
None,
Some(err_msg.clone()),
None,
);
Err(err_msg)
}
}

View File

@@ -3,3 +3,4 @@ pub mod log_service;
pub mod reconcile_service;
pub mod settings_service;
pub mod software_state_service;
pub mod task_event_service;

View File

@@ -3,31 +3,54 @@ use tauri::AppHandle;
use crate::domain::models::{DashboardSnapshot, EssentialsStatusItem, UpdateCandidate};
use crate::providers::winget_client;
use crate::services::{essentials_service, reconcile_service};
use crate::winget::Software;
use crate::services::task_event_service::emit_task_event;
pub async fn initialize_app(app: AppHandle) -> Result<bool, String> {
emit_task_event(
&app,
"env-check",
"env-check",
"initialize_app",
"running",
"checking_environment",
0.0,
None,
Some("Checking WinGet environment".to_string()),
None,
);
let app_clone = app.clone();
tokio::task::spawn_blocking(move || winget_client::ensure_environment_ready(&app_clone).map(|_| true))
let result = tokio::task::spawn_blocking(move || winget_client::ensure_environment_ready(&app_clone).map(|_| true))
.await
.unwrap_or(Err("Initialization Task Panicked".to_string()))
}
.unwrap_or(Err("Initialization Task Panicked".to_string()));
pub async fn get_installed_software(app: AppHandle) -> Vec<Software> {
tokio::task::spawn_blocking(move || winget_client::list_installed_packages(&app))
.await
.unwrap_or_default()
}
match &result {
Ok(_) => emit_task_event(
&app,
"env-check",
"env-check",
"initialize_app",
"completed",
"ready",
1.0,
None,
Some("WinGet environment ready".to_string()),
None,
),
Err(err) => emit_task_event(
&app,
"env-check",
"env-check",
"initialize_app",
"failed",
"error",
1.0,
None,
Some(err.clone()),
None,
),
}
pub async fn get_updates(app: AppHandle) -> Vec<Software> {
tokio::task::spawn_blocking(move || winget_client::list_upgrade_candidates(&app))
.await
.unwrap_or_default()
}
pub async fn get_software_info(app: AppHandle, id: String) -> Option<Software> {
tokio::task::spawn_blocking(move || winget_client::get_package_by_id(&app, &id))
.await
.unwrap_or(None)
result
}
pub async fn get_software_icon(app: AppHandle, id: String, name: String) -> Option<String> {

View File

@@ -0,0 +1,32 @@
use tauri::{AppHandle, Emitter};
use crate::domain::models::TaskEventPayload;
use crate::winget::Software;
pub fn emit_task_event(
handle: &AppHandle,
task_id: &str,
software_id: &str,
task_type: &str,
status: &str,
stage: &str,
progress: f32,
target_version: Option<String>,
message: Option<String>,
software_info: Option<Software>,
) {
let _ = handle.emit(
"task-event",
TaskEventPayload {
task_id: task_id.to_string(),
software_id: software_id.to_string(),
task_type: task_type.to_string(),
status: status.to_string(),
stage: stage.to_string(),
progress,
target_version,
message,
software_info,
},
);
}

View File

@@ -11,10 +11,11 @@ use tokio::sync::mpsc;
use winreg::enums::*;
use winreg::RegKey;
use crate::domain::models::{InstallProgress, InstallTask, TaskEventPayload};
use crate::domain::models::{InstallTask, TaskEventPayload};
use crate::providers::winget_client;
use crate::services::essentials_service;
use crate::services::log_service::emit_log;
use crate::services::task_event_service;
use crate::winget::{PostInstallStep, Software};
pub struct AppState {
@@ -411,14 +412,6 @@ fn spawn_install_stream_reader<R: Read + Send + 'static>(
let mut is_progress = false;
if let Some(caps) = perc_re.captures(clean_line) {
if let Ok(p_val) = caps[1].parse::<f32>() {
let _ = handle.emit(
"install-status",
InstallProgress {
id: task_id.clone(),
status: "installing".to_string(),
progress: p_val / 100.0,
},
);
let _ = handle.emit(
"task-event",
TaskEventPayload {
@@ -439,14 +432,6 @@ fn spawn_install_stream_reader<R: Read + Send + 'static>(
let current = caps[1].parse::<f32>().unwrap_or(0.0);
let total = caps[2].parse::<f32>().unwrap_or(1.0);
if total > 0.0 {
let _ = handle.emit(
"install-status",
InstallProgress {
id: task_id.clone(),
status: "installing".to_string(),
progress: (current / total).min(1.0),
},
);
let _ = handle.emit(
"task-event",
TaskEventPayload {
@@ -488,35 +473,17 @@ fn emit_task_event(
message: Option<String>,
software_info: Option<Software>,
) {
let _ = handle.emit(
"task-event",
TaskEventPayload {
task_id: task_id.to_string(),
software_id: software_id.to_string(),
task_type: task_type.to_string(),
status: status.to_string(),
stage: stage.to_string(),
progress,
target_version: target_version.clone(),
message,
software_info,
},
);
let legacy_status = match status {
"queued" => "pending".to_string(),
"completed" => "success".to_string(),
"failed" => "error".to_string(),
_ => stage.to_string(),
};
let _ = handle.emit(
"install-status",
InstallProgress {
id: software_id.to_string(),
status: legacy_status,
progress,
},
task_event_service::emit_task_event(
handle,
task_id,
software_id,
task_type,
status,
stage,
progress,
target_version.clone(),
message,
software_info,
);
}