diff --git a/src-tauri/src/provider.rs b/src-tauri/src/provider.rs index 08e9cb2..5a2c0ad 100644 --- a/src-tauri/src/provider.rs +++ b/src-tauri/src/provider.rs @@ -63,6 +63,14 @@ pub struct UsageScript { pub code: String, #[serde(skip_serializing_if = "Option::is_none")] pub timeout: Option, + /// 访问令牌(用于需要登录的接口) + #[serde(skip_serializing_if = "Option::is_none")] + #[serde(rename = "accessToken")] + pub access_token: Option, + /// 用户ID(用于需要用户标识的接口) + #[serde(skip_serializing_if = "Option::is_none")] + #[serde(rename = "userId")] + pub user_id: Option, } /// 用量数据 diff --git a/src-tauri/src/services/provider.rs b/src-tauri/src/services/provider.rs index 625f9f4..492da7b 100644 --- a/src-tauri/src/services/provider.rs +++ b/src-tauri/src/services/provider.rs @@ -717,7 +717,7 @@ impl ProviderService { app_type: AppType, provider_id: &str, ) -> Result { - let (provider, script_code, timeout) = { + let (provider, script_code, timeout, access_token, user_id) = { let config = state.config.read().map_err(AppError::from)?; let manager = config .get_manager(&app_type) @@ -727,7 +727,7 @@ impl ProviderService { .get(provider_id) .cloned() .ok_or_else(|| AppError::ProviderNotFound(provider_id.to_string()))?; - let (script_code, timeout) = { + let (script_code, timeout, access_token, user_id) = { let usage_script = provider .meta .as_ref() @@ -749,15 +749,26 @@ impl ProviderService { ( usage_script.code.clone(), usage_script.timeout.unwrap_or(10), + usage_script.access_token.clone(), + usage_script.user_id.clone(), ) }; - (provider, script_code, timeout) + (provider, script_code, timeout, access_token, user_id) }; let (api_key, base_url) = Self::extract_credentials(&provider, &app_type)?; - match usage_script::execute_usage_script(&script_code, &api_key, &base_url, timeout).await { + match usage_script::execute_usage_script( + &script_code, + &api_key, + &base_url, + timeout, + access_token.as_deref(), + user_id.as_deref(), + ) + .await + { Ok(data) => { let usage_list: Vec = if data.is_array() { serde_json::from_value(data) diff --git a/src-tauri/src/usage_script.rs b/src-tauri/src/usage_script.rs index d88633c..07a9dde 100644 --- a/src-tauri/src/usage_script.rs +++ b/src-tauri/src/usage_script.rs @@ -12,12 +12,22 @@ pub async fn execute_usage_script( api_key: &str, base_url: &str, timeout_secs: u64, + access_token: Option<&str>, + user_id: Option<&str>, ) -> Result { // 1. 替换变量 - let replaced = script_code + let mut replaced = script_code .replace("{{apiKey}}", api_key) .replace("{{baseUrl}}", base_url); + // 替换 accessToken 和 userId + if let Some(token) = access_token { + replaced = replaced.replace("{{accessToken}}", token); + } + if let Some(uid) = user_id { + replaced = replaced.replace("{{userId}}", uid); + } + // 2. 在独立作用域中提取 request 配置(确保 Runtime/Context 在 await 前释放) let request_config = { let runtime = diff --git a/src/components/UsageScriptModal.tsx b/src/components/UsageScriptModal.tsx index 1f84283..fda291b 100644 --- a/src/components/UsageScriptModal.tsx +++ b/src/components/UsageScriptModal.tsx @@ -47,37 +47,28 @@ const PRESET_TEMPLATES: Record = { NewAPI: `({ request: { - url: "{{baseUrl}}/api/usage/token", + url: "{{baseUrl}}/api/user/self", method: "GET", headers: { - Authorization: "Bearer {{apiKey}}", + "Content-Type": "application/json", + "Authorization": "Bearer {{accessToken}}", + "New-Api-User": "{{userId}}" }, }, extractor: function (response) { - if (response.code) { - if (response.data.unlimited_quota) { - return { - planName: response.data.name, - total: -1, - used: response.data.total_used / 500000, - unit: "USD", - }; - } + if (response.success && response.data) { return { - isValid: true, - planName: response.data.name, - total: response.data.total_granted / 500000, - used: response.data.total_used / 500000, - remaining: response.data.total_available / 500000, + planName: response.data.group || "默认套餐", + remaining: response.data.quota / 500000, + used: response.data.used_quota / 500000, + total: (response.data.quota + response.data.used_quota) / 500000, unit: "USD", }; } - if (response.error) { - return { - isValid: false, - invalidMessage: response.error.message, - }; - } + return { + isValid: false, + invalidMessage: response.message || "查询失败" + }; }, })`, }; @@ -275,6 +266,43 @@ const UsageScriptModal: React.FC = ({ + {/* 高级配置:Access Token 和 User ID */} +
+

+ 🔑 高级配置(可选,用于需要登录的接口) +

+ + + + + +

+ 💡 在脚本中使用:{`{{accessToken}}`} 和 {`{{userId}}`} +

+
+ {/* 脚本说明 */}

diff --git a/src/types.ts b/src/types.ts index f6d020c..81d9369 100644 --- a/src/types.ts +++ b/src/types.ts @@ -43,6 +43,8 @@ export interface UsageScript { language: "javascript"; // 脚本语言 code: string; // 脚本代码(JSON 格式配置) timeout?: number; // 超时时间(秒,默认 10) + accessToken?: string; // 访问令牌(用于需要登录的接口) + userId?: string; // 用户ID(用于需要用户标识的接口) } // 单个套餐用量数据