From 65c49a19fc3b9347ad4cb85f50bcf0d492ec704d Mon Sep 17 00:00:00 2001 From: QCU Date: Fri, 1 Aug 2025 14:32:44 +0800 Subject: [PATCH] feat: support setting http proxy --- package.json | 11 ++++++++++- src/controllers/extension.manager.ts | 2 +- src/services/api.service.ts | 20 +++++++++++++++++--- src/services/config.service.ts | 27 +++++++++++++++++++++++++++ 4 files changed, 55 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 8d7f3f6..e88af0e 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "packy-usage", "displayName": "Packy Usage", "description": "实时监控API预算使用情况,跟踪每日和每月的API消费", - "version": "1.1.0", + "version": "1.1.1", "publisher": "MashiroWang", "pricing": "Free", "author": { @@ -75,6 +75,12 @@ "default": "https://www.packycode.com/api/backend/users/info", "description": "API endpoint for budget data", "scope": "application" + }, + "packy-usage.proxy": { + "type": "string", + "default": "", + "description": "要使用的代理设置。如果未设置,则将从http_proxy和https_proxy环境变量继承", + "scope": "application" } } }, @@ -132,5 +138,8 @@ "eslint-plugin-prettier": "^5.5.1", "typescript": "^5.8.3", "typescript-eslint": "^8.36.0" + }, + "dependencies": { + "undici": "^6.19.8" } } diff --git a/src/controllers/extension.manager.ts b/src/controllers/extension.manager.ts index b70c0e8..e5198cb 100644 --- a/src/controllers/extension.manager.ts +++ b/src/controllers/extension.manager.ts @@ -119,7 +119,7 @@ export class ExtensionManager { this.dataService = new DataService() this.statusBarService = new StatusBarService() this.secretService = new SecretService(context) - this.apiService = new ApiService(this.secretService) + this.apiService = new ApiService(this.secretService, this.configService) // 初始化轮询服务(使用配置的轮询间隔) const config = this.configService.getConfig() diff --git a/src/services/api.service.ts b/src/services/api.service.ts index 1219fc0..8c4cf69 100644 --- a/src/services/api.service.ts +++ b/src/services/api.service.ts @@ -1,14 +1,19 @@ +import { fetch, ProxyAgent } from "undici" import * as vscode from "vscode" import { ApiResponse, BudgetData } from "../models/budget.model" import { ErrorHandler } from "../utils/error-handler" +import { ConfigService } from "./config.service" import { SecretService } from "./secret.service" export class ApiService { private config: vscode.WorkspaceConfiguration private readonly REQUEST_TIMEOUT = 10000 // 10 seconds - constructor(private secretService: SecretService) { + constructor( + private secretService: SecretService, + private configService: ConfigService + ) { this.config = vscode.workspace.getConfiguration("packy-usage") } @@ -27,14 +32,23 @@ export class ApiService { this.REQUEST_TIMEOUT ) - const response = await fetch(endpoint, { + // 配置代理 + const proxyUrl = this.configService.getProxyUrl() + const fetchOptions: Parameters[1] = { headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" }, method: "GET", signal: controller.signal - }) + } + + // 如果配置了代理,则使用 ProxyAgent + if (proxyUrl) { + fetchOptions.dispatcher = new ProxyAgent(proxyUrl) + } + + const response = await fetch(endpoint, fetchOptions) clearTimeout(timeoutId) diff --git a/src/services/config.service.ts b/src/services/config.service.ts index fd426c7..5e8bbb1 100644 --- a/src/services/config.service.ts +++ b/src/services/config.service.ts @@ -12,6 +12,8 @@ export interface PluginConfig { enablePolling: boolean /** 轮询间隔(毫秒) */ pollingInterval: number + /** HTTP 代理地址 */ + proxy: string /** 状态栏刷新间隔(毫秒) */ statusBarRefreshInterval: number } @@ -30,6 +32,7 @@ export class ConfigService { apiEndpoint: "https://www.packycode.com/api/backend/users/info", enablePolling: true, pollingInterval: 30000, // 30秒 + proxy: "", // 默认不使用代理 statusBarRefreshInterval: 1000 // 1秒 } @@ -73,6 +76,7 @@ export class ConfigService { "pollingInterval", ConfigService.DEFAULT_CONFIG.pollingInterval ), + proxy: config.get("proxy", ConfigService.DEFAULT_CONFIG.proxy), statusBarRefreshInterval: config.get( "statusBarRefreshInterval", ConfigService.DEFAULT_CONFIG.statusBarRefreshInterval @@ -105,6 +109,29 @@ export class ConfigService { ) } + /** + * 获取代理配置 + * 优先使用配置的代理,然后回退到环境变量 + */ + getProxyUrl(): string | undefined { + // 首先尝试获取配置的代理 + const configuredProxy = vscode.workspace + .getConfiguration(ConfigService.CONFIG_SECTION) + .get("proxy", "") + + if (configuredProxy && configuredProxy.trim()) { + return configuredProxy.trim() + } + + // 回退到环境变量 + return ( + process.env.HTTPS_PROXY || + process.env.HTTP_PROXY || + process.env.https_proxy || + process.env.http_proxy + ) + } + /** * 获取状态栏刷新间隔 */