app / src-tauri /src /modules /account_service.rs
AZILS's picture
Upload 323 files
a21c316 verified
use crate::models::{Account, TokenData};
use crate::modules;
/// 账号服务层 - 彻底解除对 Tauri 运行时的依赖
pub struct AccountService {
pub integration: crate::modules::integration::SystemManager,
}
impl AccountService {
pub fn new(integration: crate::modules::integration::SystemManager) -> Self {
Self { integration }
}
/// 添加账号逻辑
pub async fn add_account(&self, refresh_token: &str) -> Result<Account, String> {
// [FIX #1583] 生成临时 UUID 作为账号上下文,避免传递 None 导致代理选择异常
let temp_account_id = uuid::Uuid::new_v4().to_string();
// 1. 获取 Token (使用临时 ID 确保代理选择有明确上下文)
let token_res = modules::oauth::refresh_access_token(refresh_token, Some(&temp_account_id)).await?;
// 2. 获取用户信息
let user_info = modules::oauth::get_user_info(&token_res.access_token, Some(&temp_account_id)).await?;
// 3. 获取项目 ID (尝试)
let project_id = crate::proxy::project_resolver::fetch_project_id(&token_res.access_token)
.await
.ok();
// 4. 构造 TokenData
let token = TokenData::new(
token_res.access_token.clone(),
refresh_token.to_string(),
token_res.expires_in,
Some(user_info.email.clone()),
project_id,
None,
true,
)
.with_oauth_client_key(token_res.oauth_client_key.clone());
// 5. 持久化
let mut account =
modules::upsert_account(user_info.email.clone(), user_info.get_display_name(), token)?;
// 6. [NEW] 自动获取配额信息(用于刷新时间排序)
let email_for_log = account.email.clone();
let access_token = token_res.access_token.clone();
match modules::quota::fetch_quota(&access_token, &email_for_log, Some(&account.id)).await {
Ok((quota_data, new_project_id)) => {
account.quota = Some(quota_data);
if let Some(pid) = new_project_id {
account.token.project_id = Some(pid);
}
// 保存更新后的账号信息
if let Err(e) = modules::account::save_account(&account) {
modules::logger::log_warn(&format!(
"[Service] Failed to save quota for {}: {}",
email_for_log, e
));
} else {
modules::logger::log_info(&format!(
"[Service] Fetched quota for new account: {}",
email_for_log
));
}
}
Err(e) => {
modules::logger::log_warn(&format!(
"[Service] Failed to fetch quota for {}: {}",
email_for_log, e
));
}
}
modules::logger::log_info(&format!(
"[Service] Added/Updated account: {}",
account.email
));
Ok(account)
}
/// 删除账号逻辑
pub fn delete_account(&self, account_id: &str) -> Result<(), String> {
modules::delete_account(account_id)?;
self.integration.update_tray();
Ok(())
}
/// 切换账号逻辑
pub async fn switch_account(&self, account_id: &str) -> Result<(), String> {
modules::account::switch_account(account_id, &self.integration).await
}
/// 列表获取
pub fn list_accounts(&self) -> Result<Vec<Account>, String> {
modules::list_accounts()
}
/// 获取当前 ID
pub fn get_current_id(&self) -> Result<Option<String>, String> {
modules::get_current_account_id()
}
// --- OAuth 逻辑 ---
pub async fn prepare_oauth_url(&self, oauth_client_key: Option<String>) -> Result<String, String> {
let handle = match &self.integration {
modules::integration::SystemManager::Desktop(h) => Some(h.clone()),
modules::integration::SystemManager::Headless => None,
};
modules::oauth_server::prepare_oauth_url(handle, oauth_client_key).await
}
pub async fn start_oauth_login(&self, oauth_client_key: Option<String>) -> Result<Account, String> {
let handle = match &self.integration {
modules::integration::SystemManager::Desktop(h) => Some(h.clone()),
modules::integration::SystemManager::Headless => None,
};
let token_res = modules::oauth_server::start_oauth_flow(handle, oauth_client_key).await?;
self.process_oauth_token(token_res).await
}
pub async fn complete_oauth_login(&self) -> Result<Account, String> {
let handle = match &self.integration {
modules::integration::SystemManager::Desktop(h) => Some(h.clone()),
modules::integration::SystemManager::Headless => None,
};
let token_res = modules::oauth_server::complete_oauth_flow(handle).await?;
self.process_oauth_token(token_res).await
}
pub fn cancel_oauth_login(&self) {
modules::oauth_server::cancel_oauth_flow();
}
pub async fn submit_oauth_code(
&self,
code: String,
state: Option<String>,
) -> Result<(), String> {
modules::oauth_server::submit_oauth_code(code, state).await
}
async fn process_oauth_token(
&self,
token_res: modules::oauth::TokenResponse,
) -> Result<Account, String> {
let refresh_token = token_res
.refresh_token
.ok_or_else(|| "未获取到 Refresh Token。请撤销权限后重试。".to_string())?;
// [FIX #1583] 生成临时 UUID 作为账号上下文
let temp_account_id = uuid::Uuid::new_v4().to_string();
let user_info = modules::oauth::get_user_info(&token_res.access_token, Some(&temp_account_id)).await?;
let project_id = crate::proxy::project_resolver::fetch_project_id(&token_res.access_token)
.await
.ok();
let token_data = crate::models::TokenData::new(
token_res.access_token,
refresh_token,
token_res.expires_in,
Some(user_info.email.clone()),
project_id,
None,
true,
)
.with_oauth_client_key(token_res.oauth_client_key.clone());
let account = modules::upsert_account(
user_info.email.clone(),
user_info.get_display_name(),
token_data,
)?;
// 发送 UI 更新通知 (通过 integration)
self.integration.update_tray();
Ok(account)
}
}