修复 i18n
This commit is contained in:
@@ -8,7 +8,7 @@ use std::time::Duration;
|
||||
use tauri::{command, State};
|
||||
|
||||
use crate::commands::agents::AgentDb;
|
||||
use crate::commands::relay_stations::{RelayStationAdapter, RelayStation};
|
||||
use crate::commands::relay_stations::{RelayStation, RelayStationAdapter};
|
||||
use crate::i18n;
|
||||
|
||||
// 创建HTTP客户端的辅助函数
|
||||
@@ -89,25 +89,47 @@ pub struct TokenPaginationResponse {
|
||||
pub trait StationAdapter: Send + Sync {
|
||||
/// 获取中转站信息
|
||||
async fn get_station_info(&self, station: &RelayStation) -> Result<StationInfo>;
|
||||
|
||||
|
||||
/// 获取用户信息
|
||||
async fn get_user_info(&self, station: &RelayStation, user_id: &str) -> Result<UserInfo>;
|
||||
|
||||
|
||||
/// 测试连接
|
||||
async fn test_connection(&self, station: &RelayStation) -> Result<ConnectionTestResult>;
|
||||
|
||||
|
||||
/// 获取使用日志
|
||||
async fn get_usage_logs(&self, station: &RelayStation, user_id: &str, page: Option<usize>, size: Option<usize>) -> Result<Value>;
|
||||
|
||||
async fn get_usage_logs(
|
||||
&self,
|
||||
station: &RelayStation,
|
||||
user_id: &str,
|
||||
page: Option<usize>,
|
||||
size: Option<usize>,
|
||||
) -> Result<Value>;
|
||||
|
||||
/// 列出 Tokens
|
||||
async fn list_tokens(&self, station: &RelayStation, page: Option<usize>, size: Option<usize>) -> Result<TokenPaginationResponse>;
|
||||
|
||||
async fn list_tokens(
|
||||
&self,
|
||||
station: &RelayStation,
|
||||
page: Option<usize>,
|
||||
size: Option<usize>,
|
||||
) -> Result<TokenPaginationResponse>;
|
||||
|
||||
/// 创建 Token
|
||||
async fn create_token(&self, station: &RelayStation, name: &str, quota: Option<i64>) -> Result<TokenInfo>;
|
||||
|
||||
async fn create_token(
|
||||
&self,
|
||||
station: &RelayStation,
|
||||
name: &str,
|
||||
quota: Option<i64>,
|
||||
) -> Result<TokenInfo>;
|
||||
|
||||
/// 更新 Token
|
||||
async fn update_token(&self, station: &RelayStation, token_id: &str, name: Option<&str>, quota: Option<i64>) -> Result<TokenInfo>;
|
||||
|
||||
async fn update_token(
|
||||
&self,
|
||||
station: &RelayStation,
|
||||
token_id: &str,
|
||||
name: Option<&str>,
|
||||
quota: Option<i64>,
|
||||
) -> Result<TokenInfo>;
|
||||
|
||||
/// 删除 Token
|
||||
async fn delete_token(&self, station: &RelayStation, token_id: &str) -> Result<String>;
|
||||
}
|
||||
@@ -120,7 +142,7 @@ impl StationAdapter for PackycodeAdapter {
|
||||
async fn get_station_info(&self, station: &RelayStation) -> Result<StationInfo> {
|
||||
// PackyCode 使用简单的健康检查端点
|
||||
let url = format!("{}/health", station.api_url.trim_end_matches('/'));
|
||||
|
||||
|
||||
let client = create_http_client();
|
||||
let response = client
|
||||
.get(&url)
|
||||
@@ -137,7 +159,10 @@ impl StationAdapter for PackycodeAdapter {
|
||||
metadata: Some({
|
||||
let mut map = HashMap::new();
|
||||
map.insert("adapter_type".to_string(), json!("packycode"));
|
||||
map.insert("support_features".to_string(), json!(["quota_query", "usage_stats"]));
|
||||
map.insert(
|
||||
"support_features".to_string(),
|
||||
json!(["quota_query", "usage_stats"]),
|
||||
);
|
||||
map
|
||||
}),
|
||||
quota_per_unit: Some(1),
|
||||
@@ -150,7 +175,7 @@ impl StationAdapter for PackycodeAdapter {
|
||||
async fn get_user_info(&self, station: &RelayStation, _user_id: &str) -> Result<UserInfo> {
|
||||
// PackyCode 用户信息获取
|
||||
let url = format!("{}/user/info", station.api_url.trim_end_matches('/'));
|
||||
|
||||
|
||||
let client = create_http_client();
|
||||
let response = client
|
||||
.get(&url)
|
||||
@@ -159,24 +184,23 @@ impl StationAdapter for PackycodeAdapter {
|
||||
.await?;
|
||||
|
||||
let data: Value = response.json().await?;
|
||||
|
||||
|
||||
Ok(UserInfo {
|
||||
id: "packycode_user".to_string(),
|
||||
username: data.get("username")
|
||||
username: data
|
||||
.get("username")
|
||||
.and_then(|v| v.as_str())
|
||||
.unwrap_or("PackyCode用户")
|
||||
.to_string(),
|
||||
display_name: Some("PackyCode用户".to_string()),
|
||||
email: data.get("email")
|
||||
email: data
|
||||
.get("email")
|
||||
.and_then(|v| v.as_str())
|
||||
.map(|s| s.to_string()),
|
||||
quota: data.get("quota")
|
||||
.and_then(|v| v.as_i64())
|
||||
.unwrap_or(0),
|
||||
used_quota: data.get("used_quota")
|
||||
.and_then(|v| v.as_i64())
|
||||
.unwrap_or(0),
|
||||
request_count: data.get("request_count")
|
||||
quota: data.get("quota").and_then(|v| v.as_i64()).unwrap_or(0),
|
||||
used_quota: data.get("used_quota").and_then(|v| v.as_i64()).unwrap_or(0),
|
||||
request_count: data
|
||||
.get("request_count")
|
||||
.and_then(|v| v.as_i64())
|
||||
.unwrap_or(0),
|
||||
group: "default".to_string(),
|
||||
@@ -186,7 +210,7 @@ impl StationAdapter for PackycodeAdapter {
|
||||
|
||||
async fn test_connection(&self, station: &RelayStation) -> Result<ConnectionTestResult> {
|
||||
let start_time = std::time::Instant::now();
|
||||
|
||||
|
||||
match self.get_station_info(station).await {
|
||||
Ok(info) => {
|
||||
let response_time = start_time.elapsed().as_millis() as u64;
|
||||
@@ -194,8 +218,10 @@ impl StationAdapter for PackycodeAdapter {
|
||||
success: true,
|
||||
response_time,
|
||||
message: format!("{} - 连接成功", info.name),
|
||||
details: Some(format!("服务版本: {}",
|
||||
info.version.unwrap_or_else(|| "Unknown".to_string()))),
|
||||
details: Some(format!(
|
||||
"服务版本: {}",
|
||||
info.version.unwrap_or_else(|| "Unknown".to_string())
|
||||
)),
|
||||
})
|
||||
}
|
||||
Err(e) => {
|
||||
@@ -210,7 +236,13 @@ impl StationAdapter for PackycodeAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
async fn get_usage_logs(&self, _station: &RelayStation, _user_id: &str, _page: Option<usize>, _size: Option<usize>) -> Result<Value> {
|
||||
async fn get_usage_logs(
|
||||
&self,
|
||||
_station: &RelayStation,
|
||||
_user_id: &str,
|
||||
_page: Option<usize>,
|
||||
_size: Option<usize>,
|
||||
) -> Result<Value> {
|
||||
// PackyCode 暂不支持详细使用日志
|
||||
Ok(json!({
|
||||
"logs": [],
|
||||
@@ -218,21 +250,45 @@ impl StationAdapter for PackycodeAdapter {
|
||||
}))
|
||||
}
|
||||
|
||||
async fn list_tokens(&self, _station: &RelayStation, _page: Option<usize>, _size: Option<usize>) -> Result<TokenPaginationResponse> {
|
||||
async fn list_tokens(
|
||||
&self,
|
||||
_station: &RelayStation,
|
||||
_page: Option<usize>,
|
||||
_size: Option<usize>,
|
||||
) -> Result<TokenPaginationResponse> {
|
||||
// PackyCode 使用单一 Token,不支持多 Token 管理
|
||||
Err(anyhow::anyhow!(i18n::t("relay_adapter.packycode_single_token")))
|
||||
Err(anyhow::anyhow!(i18n::t(
|
||||
"relay_adapter.packycode_single_token"
|
||||
)))
|
||||
}
|
||||
|
||||
async fn create_token(&self, _station: &RelayStation, _name: &str, _quota: Option<i64>) -> Result<TokenInfo> {
|
||||
Err(anyhow::anyhow!(i18n::t("relay_adapter.packycode_single_token")))
|
||||
async fn create_token(
|
||||
&self,
|
||||
_station: &RelayStation,
|
||||
_name: &str,
|
||||
_quota: Option<i64>,
|
||||
) -> Result<TokenInfo> {
|
||||
Err(anyhow::anyhow!(i18n::t(
|
||||
"relay_adapter.packycode_single_token"
|
||||
)))
|
||||
}
|
||||
|
||||
async fn update_token(&self, _station: &RelayStation, _token_id: &str, _name: Option<&str>, _quota: Option<i64>) -> Result<TokenInfo> {
|
||||
Err(anyhow::anyhow!(i18n::t("relay_adapter.packycode_single_token")))
|
||||
async fn update_token(
|
||||
&self,
|
||||
_station: &RelayStation,
|
||||
_token_id: &str,
|
||||
_name: Option<&str>,
|
||||
_quota: Option<i64>,
|
||||
) -> Result<TokenInfo> {
|
||||
Err(anyhow::anyhow!(i18n::t(
|
||||
"relay_adapter.packycode_single_token"
|
||||
)))
|
||||
}
|
||||
|
||||
async fn delete_token(&self, _station: &RelayStation, _token_id: &str) -> Result<String> {
|
||||
Err(anyhow::anyhow!(i18n::t("relay_adapter.packycode_single_token")))
|
||||
Err(anyhow::anyhow!(i18n::t(
|
||||
"relay_adapter.packycode_single_token"
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -272,7 +328,7 @@ impl StationAdapter for CustomAdapter {
|
||||
|
||||
async fn test_connection(&self, station: &RelayStation) -> Result<ConnectionTestResult> {
|
||||
let start_time = std::time::Instant::now();
|
||||
|
||||
|
||||
// 尝试简单的 GET 请求测试连接
|
||||
let client = create_http_client();
|
||||
let response = client
|
||||
@@ -285,50 +341,76 @@ impl StationAdapter for CustomAdapter {
|
||||
let response_time = start_time.elapsed().as_millis() as u64;
|
||||
|
||||
match response {
|
||||
Ok(resp) => {
|
||||
Ok(ConnectionTestResult {
|
||||
success: resp.status().is_success(),
|
||||
response_time,
|
||||
message: if resp.status().is_success() {
|
||||
format!("{} - 连接成功", station.name)
|
||||
} else {
|
||||
format!("HTTP {}: 服务器响应错误", resp.status())
|
||||
},
|
||||
details: Some(format!("响应状态: {}", resp.status())),
|
||||
})
|
||||
}
|
||||
Err(e) => {
|
||||
Ok(ConnectionTestResult {
|
||||
success: false,
|
||||
response_time,
|
||||
message: format!("连接失败: {}", e),
|
||||
details: None,
|
||||
})
|
||||
}
|
||||
Ok(resp) => Ok(ConnectionTestResult {
|
||||
success: resp.status().is_success(),
|
||||
response_time,
|
||||
message: if resp.status().is_success() {
|
||||
format!("{} - 连接成功", station.name)
|
||||
} else {
|
||||
format!("HTTP {}: 服务器响应错误", resp.status())
|
||||
},
|
||||
details: Some(format!("响应状态: {}", resp.status())),
|
||||
}),
|
||||
Err(e) => Ok(ConnectionTestResult {
|
||||
success: false,
|
||||
response_time,
|
||||
message: format!("连接失败: {}", e),
|
||||
details: None,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
async fn get_usage_logs(&self, _station: &RelayStation, _user_id: &str, _page: Option<usize>, _size: Option<usize>) -> Result<Value> {
|
||||
async fn get_usage_logs(
|
||||
&self,
|
||||
_station: &RelayStation,
|
||||
_user_id: &str,
|
||||
_page: Option<usize>,
|
||||
_size: Option<usize>,
|
||||
) -> Result<Value> {
|
||||
Ok(json!({
|
||||
"logs": [],
|
||||
"message": "自定义适配器暂不支持使用日志查询"
|
||||
}))
|
||||
}
|
||||
|
||||
async fn list_tokens(&self, _station: &RelayStation, _page: Option<usize>, _size: Option<usize>) -> Result<TokenPaginationResponse> {
|
||||
Err(anyhow::anyhow!(i18n::t("relay_adapter.token_management_not_available")))
|
||||
async fn list_tokens(
|
||||
&self,
|
||||
_station: &RelayStation,
|
||||
_page: Option<usize>,
|
||||
_size: Option<usize>,
|
||||
) -> Result<TokenPaginationResponse> {
|
||||
Err(anyhow::anyhow!(i18n::t(
|
||||
"relay_adapter.token_management_not_available"
|
||||
)))
|
||||
}
|
||||
|
||||
async fn create_token(&self, _station: &RelayStation, _name: &str, _quota: Option<i64>) -> Result<TokenInfo> {
|
||||
Err(anyhow::anyhow!(i18n::t("relay_adapter.token_management_not_available")))
|
||||
async fn create_token(
|
||||
&self,
|
||||
_station: &RelayStation,
|
||||
_name: &str,
|
||||
_quota: Option<i64>,
|
||||
) -> Result<TokenInfo> {
|
||||
Err(anyhow::anyhow!(i18n::t(
|
||||
"relay_adapter.token_management_not_available"
|
||||
)))
|
||||
}
|
||||
|
||||
async fn update_token(&self, _station: &RelayStation, _token_id: &str, _name: Option<&str>, _quota: Option<i64>) -> Result<TokenInfo> {
|
||||
Err(anyhow::anyhow!(i18n::t("relay_adapter.token_management_not_available")))
|
||||
async fn update_token(
|
||||
&self,
|
||||
_station: &RelayStation,
|
||||
_token_id: &str,
|
||||
_name: Option<&str>,
|
||||
_quota: Option<i64>,
|
||||
) -> Result<TokenInfo> {
|
||||
Err(anyhow::anyhow!(i18n::t(
|
||||
"relay_adapter.token_management_not_available"
|
||||
)))
|
||||
}
|
||||
|
||||
async fn delete_token(&self, _station: &RelayStation, _token_id: &str) -> Result<String> {
|
||||
Err(anyhow::anyhow!(i18n::t("relay_adapter.token_management_not_available")))
|
||||
Err(anyhow::anyhow!(i18n::t(
|
||||
"relay_adapter.token_management_not_available"
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -349,20 +431,19 @@ pub fn create_adapter(adapter_type: &RelayStationAdapter) -> Box<dyn StationAdap
|
||||
#[command]
|
||||
pub async fn relay_station_get_info(
|
||||
station_id: String,
|
||||
db: State<'_, AgentDb>
|
||||
db: State<'_, AgentDb>,
|
||||
) -> Result<StationInfo, String> {
|
||||
// 获取中转站配置
|
||||
let station = crate::commands::relay_stations::relay_station_get(station_id, db).await?;
|
||||
|
||||
|
||||
// 创建适配器
|
||||
let adapter = create_adapter(&station.adapter);
|
||||
|
||||
|
||||
// 获取站点信息
|
||||
adapter.get_station_info(&station).await
|
||||
.map_err(|e| {
|
||||
log::error!("Failed to get station info: {}", e);
|
||||
i18n::t("relay_adapter.get_info_failed")
|
||||
})
|
||||
adapter.get_station_info(&station).await.map_err(|e| {
|
||||
log::error!("Failed to get station info: {}", e);
|
||||
i18n::t("relay_adapter.get_info_failed")
|
||||
})
|
||||
}
|
||||
|
||||
/// 获取用户信息
|
||||
@@ -370,12 +451,14 @@ pub async fn relay_station_get_info(
|
||||
pub async fn relay_station_get_user_info(
|
||||
station_id: String,
|
||||
user_id: String,
|
||||
db: State<'_, AgentDb>
|
||||
db: State<'_, AgentDb>,
|
||||
) -> Result<UserInfo, String> {
|
||||
let station = crate::commands::relay_stations::relay_station_get(station_id, db).await?;
|
||||
let adapter = create_adapter(&station.adapter);
|
||||
|
||||
adapter.get_user_info(&station, &user_id).await
|
||||
|
||||
adapter
|
||||
.get_user_info(&station, &user_id)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
log::error!("Failed to get user info: {}", e);
|
||||
i18n::t("relay_adapter.get_user_info_failed")
|
||||
@@ -386,16 +469,15 @@ pub async fn relay_station_get_user_info(
|
||||
#[command]
|
||||
pub async fn relay_station_test_connection(
|
||||
station_id: String,
|
||||
db: State<'_, AgentDb>
|
||||
db: State<'_, AgentDb>,
|
||||
) -> Result<ConnectionTestResult, String> {
|
||||
let station = crate::commands::relay_stations::relay_station_get(station_id, db).await?;
|
||||
let adapter = create_adapter(&station.adapter);
|
||||
|
||||
adapter.test_connection(&station).await
|
||||
.map_err(|e| {
|
||||
log::error!("Connection test failed: {}", e);
|
||||
i18n::t("relay_adapter.connection_test_failed")
|
||||
})
|
||||
|
||||
adapter.test_connection(&station).await.map_err(|e| {
|
||||
log::error!("Connection test failed: {}", e);
|
||||
i18n::t("relay_adapter.connection_test_failed")
|
||||
})
|
||||
}
|
||||
|
||||
/// 获取使用日志
|
||||
@@ -405,12 +487,14 @@ pub async fn relay_station_get_usage_logs(
|
||||
user_id: String,
|
||||
page: Option<usize>,
|
||||
size: Option<usize>,
|
||||
db: State<'_, AgentDb>
|
||||
db: State<'_, AgentDb>,
|
||||
) -> Result<Value, String> {
|
||||
let station = crate::commands::relay_stations::relay_station_get(station_id, db).await?;
|
||||
let adapter = create_adapter(&station.adapter);
|
||||
|
||||
adapter.get_usage_logs(&station, &user_id, page, size).await
|
||||
|
||||
adapter
|
||||
.get_usage_logs(&station, &user_id, page, size)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
log::error!("Failed to get usage logs: {}", e);
|
||||
i18n::t("relay_adapter.get_usage_logs_failed")
|
||||
@@ -423,12 +507,14 @@ pub async fn relay_station_list_tokens(
|
||||
station_id: String,
|
||||
page: Option<usize>,
|
||||
size: Option<usize>,
|
||||
db: State<'_, AgentDb>
|
||||
db: State<'_, AgentDb>,
|
||||
) -> Result<TokenPaginationResponse, String> {
|
||||
let station = crate::commands::relay_stations::relay_station_get(station_id, db).await?;
|
||||
let adapter = create_adapter(&station.adapter);
|
||||
|
||||
adapter.list_tokens(&station, page, size).await
|
||||
|
||||
adapter
|
||||
.list_tokens(&station, page, size)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
log::error!("Failed to list tokens: {}", e);
|
||||
i18n::t("relay_adapter.list_tokens_failed")
|
||||
@@ -441,12 +527,14 @@ pub async fn relay_station_create_token(
|
||||
station_id: String,
|
||||
name: String,
|
||||
quota: Option<i64>,
|
||||
db: State<'_, AgentDb>
|
||||
db: State<'_, AgentDb>,
|
||||
) -> Result<TokenInfo, String> {
|
||||
let station = crate::commands::relay_stations::relay_station_get(station_id, db).await?;
|
||||
let adapter = create_adapter(&station.adapter);
|
||||
|
||||
adapter.create_token(&station, &name, quota).await
|
||||
|
||||
adapter
|
||||
.create_token(&station, &name, quota)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
log::error!("Failed to create token: {}", e);
|
||||
i18n::t("relay_adapter.create_token_failed")
|
||||
@@ -460,12 +548,14 @@ pub async fn relay_station_update_token(
|
||||
token_id: String,
|
||||
name: Option<String>,
|
||||
quota: Option<i64>,
|
||||
db: State<'_, AgentDb>
|
||||
db: State<'_, AgentDb>,
|
||||
) -> Result<TokenInfo, String> {
|
||||
let station = crate::commands::relay_stations::relay_station_get(station_id, db).await?;
|
||||
let adapter = create_adapter(&station.adapter);
|
||||
|
||||
adapter.update_token(&station, &token_id, name.as_deref(), quota).await
|
||||
|
||||
adapter
|
||||
.update_token(&station, &token_id, name.as_deref(), quota)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
log::error!("Failed to update token: {}", e);
|
||||
i18n::t("relay_adapter.update_token_failed")
|
||||
@@ -477,12 +567,14 @@ pub async fn relay_station_update_token(
|
||||
pub async fn relay_station_delete_token(
|
||||
station_id: String,
|
||||
token_id: String,
|
||||
db: State<'_, AgentDb>
|
||||
db: State<'_, AgentDb>,
|
||||
) -> Result<String, String> {
|
||||
let station = crate::commands::relay_stations::relay_station_get(station_id, db).await?;
|
||||
let adapter = create_adapter(&station.adapter);
|
||||
|
||||
adapter.delete_token(&station, &token_id).await
|
||||
|
||||
adapter
|
||||
.delete_token(&station, &token_id)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
log::error!("Failed to delete token: {}", e);
|
||||
i18n::t("relay_adapter.delete_token_failed")
|
||||
@@ -493,7 +585,7 @@ pub async fn relay_station_delete_token(
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct PackycodeUserQuota {
|
||||
pub daily_budget_usd: f64, // 日预算(美元)
|
||||
pub daily_spent_usd: f64, // 日已使用(美元)
|
||||
pub daily_spent_usd: f64, // 日已使用(美元)
|
||||
pub monthly_budget_usd: f64, // 月预算(美元)
|
||||
pub monthly_spent_usd: f64, // 月已使用(美元)
|
||||
pub balance_usd: f64, // 账户余额(美元)
|
||||
@@ -509,32 +601,34 @@ pub struct PackycodeUserQuota {
|
||||
#[command]
|
||||
pub async fn packycode_get_user_quota(
|
||||
station_id: String,
|
||||
db: State<'_, AgentDb>
|
||||
db: State<'_, AgentDb>,
|
||||
) -> Result<PackycodeUserQuota, String> {
|
||||
let station = crate::commands::relay_stations::relay_station_get(station_id, db).await
|
||||
let station = crate::commands::relay_stations::relay_station_get(station_id, db)
|
||||
.await
|
||||
.map_err(|e| format!("Failed to get station: {}", e))?;
|
||||
|
||||
|
||||
if station.adapter.as_str() != "packycode" {
|
||||
return Err("此功能仅支持 PackyCode 中转站".to_string());
|
||||
}
|
||||
|
||||
|
||||
// 根据服务类型构建不同的 URL
|
||||
let url = if station.api_url.contains("share-api") || station.api_url.contains("share.packycode") {
|
||||
// 滴滴车服务
|
||||
"https://share.packycode.com/api/backend/users/info"
|
||||
} else {
|
||||
// 公交车服务
|
||||
"https://www.packycode.com/api/backend/users/info"
|
||||
};
|
||||
|
||||
let url =
|
||||
if station.api_url.contains("share-api") || station.api_url.contains("share.packycode") {
|
||||
// 滴滴车服务
|
||||
"https://share.packycode.com/api/backend/users/info"
|
||||
} else {
|
||||
// 公交车服务
|
||||
"https://www.packycode.com/api/backend/users/info"
|
||||
};
|
||||
|
||||
let client = Client::builder()
|
||||
.timeout(Duration::from_secs(30))
|
||||
.no_proxy() // 禁用所有代理
|
||||
.no_proxy() // 禁用所有代理
|
||||
.build()
|
||||
.map_err(|e| format!("创建 HTTP 客户端失败: {}", e))?;
|
||||
|
||||
|
||||
log::info!("正在请求 PackyCode 用户信息: {}", url);
|
||||
|
||||
|
||||
let response = client
|
||||
.get(url)
|
||||
.header("Authorization", format!("Bearer {}", station.system_token))
|
||||
@@ -564,15 +658,19 @@ pub async fn packycode_get_user_quota(
|
||||
});
|
||||
}
|
||||
|
||||
let data: Value = response.json().await
|
||||
let data: Value = response
|
||||
.json()
|
||||
.await
|
||||
.map_err(|e| format!("解析响应失败: {}", e))?;
|
||||
|
||||
|
||||
// 辅助函数:将值转换为 f64
|
||||
let to_f64 = |v: &Value| -> f64 {
|
||||
if v.is_null() {
|
||||
0.0
|
||||
} else if v.is_string() {
|
||||
v.as_str().and_then(|s| s.parse::<f64>().ok()).unwrap_or(0.0)
|
||||
v.as_str()
|
||||
.and_then(|s| s.parse::<f64>().ok())
|
||||
.unwrap_or(0.0)
|
||||
} else if v.is_f64() {
|
||||
v.as_f64().unwrap_or(0.0)
|
||||
} else if v.is_i64() {
|
||||
@@ -581,7 +679,7 @@ pub async fn packycode_get_user_quota(
|
||||
0.0
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Ok(PackycodeUserQuota {
|
||||
daily_budget_usd: to_f64(data.get("daily_budget_usd").unwrap_or(&Value::Null)),
|
||||
daily_spent_usd: to_f64(data.get("daily_spent_usd").unwrap_or(&Value::Null)),
|
||||
@@ -589,20 +687,23 @@ pub async fn packycode_get_user_quota(
|
||||
monthly_spent_usd: to_f64(data.get("monthly_spent_usd").unwrap_or(&Value::Null)),
|
||||
balance_usd: to_f64(data.get("balance_usd").unwrap_or(&Value::Null)),
|
||||
total_spent_usd: to_f64(data.get("total_spent_usd").unwrap_or(&Value::Null)),
|
||||
plan_type: data.get("plan_type")
|
||||
plan_type: data
|
||||
.get("plan_type")
|
||||
.and_then(|v| v.as_str())
|
||||
.unwrap_or("basic")
|
||||
.to_string(),
|
||||
plan_expires_at: data.get("plan_expires_at")
|
||||
plan_expires_at: data
|
||||
.get("plan_expires_at")
|
||||
.and_then(|v| v.as_str())
|
||||
.map(|s| s.to_string()),
|
||||
username: data.get("username")
|
||||
username: data
|
||||
.get("username")
|
||||
.and_then(|v| v.as_str())
|
||||
.map(|s| s.to_string()),
|
||||
email: data.get("email")
|
||||
email: data
|
||||
.get("email")
|
||||
.and_then(|v| v.as_str())
|
||||
.map(|s| s.to_string()),
|
||||
opus_enabled: data.get("opus_enabled")
|
||||
.and_then(|v| v.as_bool()),
|
||||
opus_enabled: data.get("opus_enabled").and_then(|v| v.as_bool()),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user