From e92fbb04431a98708b673321db39314305ab02bb Mon Sep 17 00:00:00 2001 From: Soulter <37870767+Soulter@users.noreply.github.com> Date: Mon, 21 Jul 2025 15:05:49 +0800 Subject: [PATCH] feat: add ProxySelector component for GitHub proxy configuration and connection testing (#2185) --- astrbot/dashboard/routes/stat.py | 45 +++++- .../src/components/shared/ProxySelector.vue | 152 ++++++++++++++++++ dashboard/src/views/ExtensionPage.vue | 4 + dashboard/src/views/Settings.vue | 34 +--- 4 files changed, 200 insertions(+), 35 deletions(-) create mode 100644 dashboard/src/components/shared/ProxySelector.vue diff --git a/astrbot/dashboard/routes/stat.py b/astrbot/dashboard/routes/stat.py index 79397290e..2a8389396 100644 --- a/astrbot/dashboard/routes/stat.py +++ b/astrbot/dashboard/routes/stat.py @@ -2,6 +2,7 @@ import traceback import psutil import time import threading +import aiohttp from .route import Route, Response, RouteContext from astrbot.core import logger from quart import request @@ -25,6 +26,7 @@ class StatRoute(Route): "/stat/version": ("GET", self.get_version), "/stat/start-time": ("GET", self.get_start_time), "/stat/restart-core": ("POST", self.restart_core), + "/stat/test-ghproxy-connection": ("POST", self.test_ghproxy_connection), } self.db_helper = db_helper self.register_routes() @@ -45,11 +47,7 @@ class StatRoute(Route): """将总秒数转换为时分秒组件""" minutes, seconds = divmod(total_seconds, 60) hours, minutes = divmod(minutes, 60) - return { - "hours": hours, - "minutes": minutes, - "seconds": seconds - } + return {"hours": hours, "minutes": minutes, "seconds": seconds} def is_default_cred(self): username = self.config["dashboard"]["username"] @@ -144,3 +142,40 @@ class StatRoute(Route): except Exception as e: logger.error(traceback.format_exc()) return Response().error(e.__str__()).__dict__ + + async def test_ghproxy_connection(self): + """ + 测试 GitHub 代理连接是否可用。 + """ + try: + data = await request.get_json() + proxy_url: str = data.get("proxy_url") + + if not proxy_url: + return Response().error("proxy_url is required").__dict__ + + proxy_url = proxy_url.rstrip("/") + + test_url = f"{proxy_url}/https://github.com/AstrBotDevs/AstrBot/raw/refs/heads/master/.python-version" + start_time = time.time() + + async with aiohttp.ClientSession() as session: + async with session.get( + test_url, timeout=aiohttp.ClientTimeout(total=10) + ) as response: + if response.status == 200: + end_time = time.time() + _ = await response.text() + ret = { + "latency": round((end_time - start_time) * 1000, 2), + } + return Response().ok(data=ret).__dict__ + else: + return ( + Response() + .error(f"Failed. Status code: {response.status}") + .__dict__ + ) + except Exception as e: + logger.error(traceback.format_exc()) + return Response().error(f"Error: {str(e)}").__dict__ diff --git a/dashboard/src/components/shared/ProxySelector.vue b/dashboard/src/components/shared/ProxySelector.vue new file mode 100644 index 000000000..d45a0f520 --- /dev/null +++ b/dashboard/src/components/shared/ProxySelector.vue @@ -0,0 +1,152 @@ + + + + + + \ No newline at end of file diff --git a/dashboard/src/views/ExtensionPage.vue b/dashboard/src/views/ExtensionPage.vue index 892034add..c8fb62452 100644 --- a/dashboard/src/views/ExtensionPage.vue +++ b/dashboard/src/views/ExtensionPage.vue @@ -3,6 +3,7 @@ import ExtensionCard from '@/components/shared/ExtensionCard.vue'; import AstrBotConfig from '@/components/shared/AstrBotConfig.vue'; import ConsoleDisplayer from '@/components/shared/ConsoleDisplayer.vue'; import ReadmeDialog from '@/components/shared/ReadmeDialog.vue'; +import ProxySelector from '@/components/shared/ProxySelector.vue'; import axios from 'axios'; import { useCommonStore } from '@/stores/common'; import { useI18n, useModuleI18n } from '@/i18n/composables'; @@ -1190,6 +1191,9 @@ onMounted(async () => { hide-details placeholder="https://github.com/username/repo" > +
+ +
diff --git a/dashboard/src/views/Settings.vue b/dashboard/src/views/Settings.vue index 0b68ab7d7..77ad4ea1f 100644 --- a/dashboard/src/views/Settings.vue +++ b/dashboard/src/views/Settings.vue @@ -5,11 +5,8 @@ {{ tm('network.title') }} - - - - + + {{ tm('system.title') }} @@ -17,41 +14,29 @@ {{ tm('system.restart.button') }} - - - - - \ No newline at end of file