Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"date-fns": "^4.1.0",
"ipaddr.js": "^2.3.0",
"lucide-react": "^0.552.0",
"react": "^19.2.1",
"react-dom": "^19.2.1",
Expand Down
2 changes: 2 additions & 0 deletions src-tauri/src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ pub mod proxy_commands;
pub mod session_commands;
pub mod startup_commands; // 开机自启动管理命令
pub mod stats_commands;
pub mod token_commands; // 令牌资产管理命令(NEW API 集成)
pub mod tool_commands;
pub mod tool_management;
pub mod types;
Expand All @@ -29,6 +30,7 @@ pub use proxy_commands::*;
pub use session_commands::*;
pub use startup_commands::*; // 开机自启动管理命令
pub use stats_commands::*;
pub use token_commands::*; // 令牌资产管理命令(NEW API 集成)
pub use tool_commands::*;
pub use tool_management::*;
pub use update_commands::*;
Expand Down
88 changes: 88 additions & 0 deletions src-tauri/src/commands/provider_commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,73 @@ impl Default for ProviderManagerState {
}
}

/// API 地址信息
#[derive(serde::Serialize)]
pub struct ApiInfo {
pub url: String,
pub description: String,
}

/// 获取供应商的 API 地址列表
/// 从 {website_url}/api/status 获取 data.api_info 数组
/// 失败时返回空数组(降级处理)
#[tauri::command]
pub async fn fetch_provider_api_addresses(website_url: String) -> Result<Vec<ApiInfo>, String> {
use reqwest::Client;
use std::time::Duration;

// 构建 API 端点
let api_url = format!("{}/api/status", website_url.trim_end_matches('/'));

// 发送请求
let client = Client::builder()
.timeout(Duration::from_secs(10))
.build()
.map_err(|e| format!("创建 HTTP 客户端失败: {}", e))?;

let response = client.get(&api_url).send().await;

// 请求失败时返回空数组(降级)
let response = match response {
Ok(resp) => resp,
Err(_) => return Ok(vec![]),
};

// 解析 JSON
let json_result = response.json::<serde_json::Value>().await;
let json = match json_result {
Ok(j) => j,
Err(_) => return Ok(vec![]),
};

// 提取 data.api_info 数组
let api_info_array = json
.get("data")
.and_then(|data| data.get("api_info"))
.and_then(|info| info.as_array());

let api_info_array = match api_info_array {
Some(arr) => arr,
None => return Ok(vec![]),
};

// 转换为 ApiInfo 结构体
let mut result = Vec::new();
for item in api_info_array {
if let (Some(url), Some(description)) = (
item.get("url").and_then(|u| u.as_str()),
item.get("description").and_then(|d| d.as_str()),
) {
result.push(ApiInfo {
url: url.to_string(),
description: description.to_string(),
});
}
}

Ok(result)
}

/// 列出所有供应商
#[tauri::command]
pub async fn list_providers(
Expand Down Expand Up @@ -159,6 +226,27 @@ pub async fn validate_provider_config(provider: Provider) -> Result<ValidationRe
let json_result = response.json::<serde_json::Value>().await;
match json_result {
Ok(json) => {
// 检查响应体中的 success 字段
let api_success = json
.get("success")
.and_then(|s| s.as_bool())
.unwrap_or(true); // 没有 success 字段时默认为 true(兼容不同 API)

if !api_success {
// API 返回 success: false,提取错误信息
let error_msg = json
.get("message")
.and_then(|m| m.as_str())
.unwrap_or("API 验证失败")
.to_string();

return Ok(ValidationResult {
success: false,
username: None,
error: Some(error_msg),
});
}

// 尝试从响应中提取用户名 (假设在 data.username 或 username 字段)
let username = json
.get("data")
Expand Down
Loading