feat: add official balance query for DeepSeek, StepFun, SiliconFlow, OpenRouter, Novita AI

Add a new "Official" (官方) template type in the usage query panel that
queries account balance via each provider's native API endpoint.
Follows the same zero-script pattern as Token Plan — Rust handles the
HTTP call, frontend auto-detects the provider from base URL.

Supported providers and endpoints:
- DeepSeek: GET /user/balance
- StepFun: GET /v1/accounts
- SiliconFlow: GET /v1/user/info (cn + com)
- OpenRouter: GET /api/v1/credits
- Novita AI: GET /v3/user/balance
This commit is contained in:
Jason
2026-04-05 16:54:51 +08:00
parent 24555275bb
commit f1fb3351c1
12 changed files with 561 additions and 2 deletions
+6
View File
@@ -0,0 +1,6 @@
use crate::provider::UsageResult;
#[tauri::command]
pub async fn get_balance(base_url: String, api_key: String) -> Result<UsageResult, String> {
crate::services::balance::get_balance(&base_url, &api_key).await
}
+2
View File
@@ -1,6 +1,7 @@
#![allow(non_snake_case)]
mod auth;
mod balance;
mod coding_plan;
mod config;
mod copilot;
@@ -31,6 +32,7 @@ mod webdav_sync;
mod workspace;
pub use auth::*;
pub use balance::*;
pub use coding_plan::*;
pub use config::*;
pub use copilot::*;
+25
View File
@@ -14,6 +14,7 @@ use std::str::FromStr;
// 常量定义
const TEMPLATE_TYPE_GITHUB_COPILOT: &str = "github_copilot";
const TEMPLATE_TYPE_TOKEN_PLAN: &str = "token_plan";
const TEMPLATE_TYPE_BALANCE: &str = "balance";
const COPILOT_UNIT_PREMIUM: &str = "requests";
/// 获取所有供应商
@@ -268,6 +269,30 @@ pub async fn queryProviderUsage(
});
}
// ── 官方余额查询路径 ──
if template_type == TEMPLATE_TYPE_BALANCE {
let settings_config = provider
.map(|p| &p.settings_config)
.cloned()
.unwrap_or_default();
let env = settings_config.get("env");
let base_url = env
.and_then(|e| e.get("ANTHROPIC_BASE_URL"))
.and_then(|v| v.as_str())
.unwrap_or("");
let api_key = env
.and_then(|e| {
e.get("ANTHROPIC_AUTH_TOKEN")
.or_else(|| e.get("ANTHROPIC_API_KEY"))
})
.and_then(|v| v.as_str())
.unwrap_or("");
return crate::services::balance::get_balance(base_url, api_key)
.await
.map_err(|e| format!("Failed to query balance: {e}"));
}
// ── 通用 JS 脚本路径 ──
ProviderService::query_usage(state.inner(), app_type, &providerId)
.await