app / src-tauri /src /modules /integration.rs
AZILS's picture
Upload 323 files
a21c316 verified
use crate::modules::{process, db, device};
use crate::models::Account;
use std::fs;
pub trait SystemIntegration: Send + Sync {
/// 当切换账号时执行的系统层操作(如杀进程、写入文件、注入数据库)
async fn on_account_switch(&self, account: &crate::models::Account) -> Result<(), String>;
/// 更新系统托盘(如果适用)
fn update_tray(&self);
/// 发送系统通知
fn show_notification(&self, title: &str, body: &str);
}
/// 桌面版实现:包含完整的进程控制和 UI 同步
pub struct DesktopIntegration {
pub app_handle: tauri::AppHandle,
}
impl SystemIntegration for DesktopIntegration {
async fn on_account_switch(&self, account: &crate::models::Account) -> Result<(), String> {
crate::modules::logger::log_info(&format!("[Desktop] Executing system switch for: {}", account.email));
// 1. 获取存储路径
let storage_path = device::get_storage_path()?;
// 2. 关闭外部进程
if process::is_antigravity_running() {
process::close_antigravity(20)?;
}
// 3. 写入设备 Profile
if let Some(ref profile) = account.device_profile {
device::write_profile(&storage_path, profile)?;
}
// 4. 数据库处理与 Token 注入
let db_path = db::get_db_path()?;
if db_path.exists() {
let backup_path = db_path.with_extension("vscdb.backup");
let _ = fs::copy(&db_path, &backup_path);
}
db::inject_token(
&db_path,
&account.token.access_token,
&account.token.refresh_token,
account.token.expiry_timestamp,
&account.email,
account.token.is_gcp_tos,
account.token.project_id.as_deref(),
)?;
// 4.1 同步 Service Machine ID 到数据库 (关键修复点)
if let Some(ref profile) = account.device_profile {
let _ = db::write_service_machine_id(&db_path, &profile.mac_machine_id);
}
// 5. 重启外部进程
process::start_antigravity()?;
// 6. 更新托盘
let _ = crate::modules::tray::update_tray_menus(&self.app_handle);
Ok(())
}
fn update_tray(&self) {
let _ = crate::modules::tray::update_tray_menus(&self.app_handle);
}
fn show_notification(&self, title: &str, body: &str) {
// 使用 tauri-plugin-dialog 或原生通知(此处简化)
crate::modules::logger::log_info(&format!("[Notification] {}: {}", title, body));
}
}
/// Headless/Docker 实现:仅执行数据层操作,忽略 UI 和进程控制
pub struct HeadlessIntegration;
impl SystemIntegration for HeadlessIntegration {
async fn on_account_switch(&self, account: &crate::models::Account) -> Result<(), String> {
crate::modules::logger::log_info(&format!("[Headless] Account switched in memory: {}", account.email));
// Docker 模式下通常不直接控制宿主机的 VS Code 进程
// 如果需要同步配置到某个 volume,可以在此处添加逻辑
Ok(())
}
fn update_tray(&self) {
// No-op
}
fn show_notification(&self, title: &str, body: &str) {
crate::modules::logger::log_info(&format!("[Log Notification] {}: {}", title, body));
}
}
/// 系统集成管理器:替代 Arc<dyn SystemIntegration> 以解决 async trait 的 dyn 兼容性问题
#[derive(Clone)]
pub enum SystemManager {
Desktop(tauri::AppHandle),
Headless,
}
impl SystemManager {
pub async fn on_account_switch(&self, account: &Account) -> Result<(), String> {
match self {
SystemManager::Desktop(handle) => {
let integration = DesktopIntegration { app_handle: handle.clone() };
integration.on_account_switch(account).await
},
SystemManager::Headless => {
let integration = HeadlessIntegration;
integration.on_account_switch(account).await
}
}
}
pub fn update_tray(&self) {
if let SystemManager::Desktop(handle) = self {
let integration = DesktopIntegration { app_handle: handle.clone() };
integration.update_tray();
}
}
pub fn show_notification(&self, title: &str, body: &str) {
match self {
SystemManager::Desktop(handle) => {
let integration = DesktopIntegration { app_handle: handle.clone() };
integration.show_notification(title, body);
},
SystemManager::Headless => {
let integration = HeadlessIntegration;
integration.show_notification(title, body);
}
}
}
}
impl SystemIntegration for SystemManager {
async fn on_account_switch(&self, account: &crate::models::Account) -> Result<(), String> {
match self {
SystemManager::Desktop(handle) => {
let integration = DesktopIntegration { app_handle: handle.clone() };
integration.on_account_switch(account).await
},
SystemManager::Headless => {
let integration = HeadlessIntegration;
integration.on_account_switch(account).await
}
}
}
fn update_tray(&self) {
match self {
SystemManager::Desktop(handle) => {
let integration = DesktopIntegration { app_handle: handle.clone() };
integration.update_tray();
},
SystemManager::Headless => {
let integration = HeadlessIntegration;
integration.update_tray();
}
}
}
fn show_notification(&self, title: &str, body: &str) {
match self {
SystemManager::Desktop(handle) => {
let integration = DesktopIntegration { app_handle: handle.clone() };
integration.show_notification(title, body);
},
SystemManager::Headless => {
let integration = HeadlessIntegration;
integration.show_notification(title, body);
}
}
}
}