From d68ccfcc963a8c2ea44e9e04fdeeba1f950f8507 Mon Sep 17 00:00:00 2001 From: LIghtJUNction Date: Fri, 6 Feb 2026 03:47:53 +0800 Subject: [PATCH] =?UTF-8?q?1.=E5=89=8D=E7=AB=AF=E7=9A=84=E5=90=8E=E7=AB=AF?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E9=A1=B5=E9=9D=A2=E6=96=B0=E5=A2=9E=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E6=8C=89=E9=92=AE=EF=BC=8C=E5=85=81=E8=AE=B8=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E5=90=8E=E7=AB=AF=EF=BC=8C=E8=87=AA=E7=94=B1=E5=88=87?= =?UTF-8?q?=E6=8D=A2=E5=90=8E=E7=AB=AF=E3=80=822.=E4=B8=80=E4=BA=9B?= =?UTF-8?q?=E5=BF=85=E8=A6=81=E7=9A=84=E6=94=B9=E8=BF=9B=EF=BC=8C=E6=AF=94?= =?UTF-8?q?=E5=A6=82astrbot=20init=E5=88=9D=E5=A7=8B=E5=8C=96=E6=97=B6?= =?UTF-8?q?=E5=80=99=E8=AF=A2=E9=97=AE=E6=98=AF=E5=90=A6=E4=B8=8B=E8=BD=BD?= =?UTF-8?q?=E5=89=8D=E7=AB=AF=EF=BC=8C=E5=8F=AF=E9=80=89=E6=8B=A9=E4=B8=8D?= =?UTF-8?q?=E4=B8=8B=E8=BD=BD=EF=BC=8C=E4=BD=BF=E7=94=A8--backend-only?= =?UTF-8?q?=E9=80=89=E9=A1=B9=E6=97=B6=E5=80=99=EF=BC=8C=E4=B8=8D=E5=86=8D?= =?UTF-8?q?=E6=8F=90=E7=A4=BA=E8=A6=81=E4=B8=8B=E8=BD=BD=E5=89=8D=E7=AB=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- astrbot/cli/commands/cmd_init.py | 9 ++- astrbot/cli/commands/cmd_run.py | 3 +- astrbot/dashboard/routes/static_file.py | 3 + dashboard/src/stores/api.ts | 23 +++++- dashboard/src/views/Settings.vue | 74 +++++++++++++++++- .../views/authentication/auth/LoginPage.vue | 75 ++++++++++++++++++- 6 files changed, 178 insertions(+), 9 deletions(-) diff --git a/astrbot/cli/commands/cmd_init.py b/astrbot/cli/commands/cmd_init.py index 6c0c34b99..0adbf3288 100644 --- a/astrbot/cli/commands/cmd_init.py +++ b/astrbot/cli/commands/cmd_init.py @@ -34,8 +34,13 @@ async def initialize_astrbot(astrbot_root: Path) -> None: for name, path in paths.items(): path.mkdir(parents=True, exist_ok=True) click.echo(f"{'Created' if not path.exists() else 'Directory exists'}: {path}") - - await check_dashboard(astrbot_root / "data") + if click.confirm( + "是否需要集成式 WebUI?(个人电脑推荐,服务器不推荐)", + default=True, + ): + await check_dashboard(astrbot_root / "data") + else: + click.echo("你可以使用在线面版(v4.14.4+),填写后端地址的方式来控制。") @click.command() diff --git a/astrbot/cli/commands/cmd_run.py b/astrbot/cli/commands/cmd_run.py index 6952ba323..6039d2eff 100644 --- a/astrbot/cli/commands/cmd_run.py +++ b/astrbot/cli/commands/cmd_run.py @@ -15,7 +15,8 @@ async def run_astrbot(astrbot_root: Path): from astrbot.core import LogBroker, LogManager, db_helper, logger from astrbot.core.initial_loader import InitialLoader - await check_dashboard(astrbot_root / "data") + if os.environ.get("DASHBOARD_ENABLE") == "True": + await check_dashboard(astrbot_root / "data") log_broker = LogBroker() LogManager.set_queue_handler(logger, log_broker) diff --git a/astrbot/dashboard/routes/static_file.py b/astrbot/dashboard/routes/static_file.py index 3d3d0ca51..7e7592e9b 100644 --- a/astrbot/dashboard/routes/static_file.py +++ b/astrbot/dashboard/routes/static_file.py @@ -5,6 +5,9 @@ class StaticFileRoute(Route): def __init__(self, context: RouteContext) -> None: super().__init__(context) + if "index" in self.app.view_functions: + return + index_ = [ "/", "/auth/login", diff --git a/dashboard/src/stores/api.ts b/dashboard/src/stores/api.ts index 57ab3c495..b664c1d95 100644 --- a/dashboard/src/stores/api.ts +++ b/dashboard/src/stores/api.ts @@ -11,11 +11,30 @@ export const useApiStore = defineStore({ state: () => ({ // 优先从 localStorage 读取用户手动设置的地址 apiBaseUrl: localStorage.getItem("apiBaseUrl") || "", - presets: [] as ApiPreset[], + configPresets: [] as ApiPreset[], + customPresets: JSON.parse( + localStorage.getItem("customPresets") || "[]", + ) as ApiPreset[], }), + getters: { + presets: (state): ApiPreset[] => [ + ...state.configPresets, + ...state.customPresets, + ], + }, actions: { setPresets(presets: ApiPreset[]) { - this.presets = presets; + this.configPresets = presets; + }, + + addPreset(preset: ApiPreset) { + this.customPresets.push(preset); + localStorage.setItem("customPresets", JSON.stringify(this.customPresets)); + }, + + removePreset(name: string) { + this.customPresets = this.customPresets.filter((p) => p.name !== name); + localStorage.setItem("customPresets", JSON.stringify(this.customPresets)); }, /** diff --git a/dashboard/src/views/Settings.vue b/dashboard/src/views/Settings.vue index ff6ff1b28..20a5c1e8e 100644 --- a/dashboard/src/views/Settings.vue +++ b/dashboard/src/views/Settings.vue @@ -22,9 +22,60 @@
+
+
+ Quick Select Preset +
+ + mdi-plus + +
+ + +
+ + + Add Preset +
+
+ {{ preset.name }} @@ -178,6 +231,25 @@ const apiStore = useApiStore(); const apiBaseUrl = ref(apiStore.apiBaseUrl); +const showAddPreset = ref(false); +const newPresetName = ref(""); +const newPresetUrl = ref(""); + +const savePreset = () => { + if (!newPresetName.value || !newPresetUrl.value) return; + apiStore.addPreset({ + name: newPresetName.value, + url: newPresetUrl.value, + }); + showAddPreset.value = false; + newPresetName.value = ""; + newPresetUrl.value = ""; +}; + +const isCustomPreset = (name) => { + return apiStore.customPresets.some((p) => p.name === name); +}; + const saveApiUrl = () => { apiStore.setApiBaseUrl(apiBaseUrl.value); window.location.reload(); diff --git a/dashboard/src/views/authentication/auth/LoginPage.vue b/dashboard/src/views/authentication/auth/LoginPage.vue index ac6f512fd..b659eae27 100644 --- a/dashboard/src/views/authentication/auth/LoginPage.vue +++ b/dashboard/src/views/authentication/auth/LoginPage.vue @@ -20,12 +20,31 @@ const theme = useTheme(); const serverConfigDialog = ref(false); const apiUrl = ref(apiStore.apiBaseUrl); +const showAddPreset = ref(false); +const newPresetName = ref(""); +const newPresetUrl = ref(""); + function saveApiUrl() { apiStore.setApiBaseUrl(apiUrl.value); serverConfigDialog.value = false; window.location.reload(); } +function savePreset() { + if (!newPresetName.value || !newPresetUrl.value) return; + apiStore.addPreset({ + name: newPresetName.value, + url: newPresetUrl.value, + }); + showAddPreset.value = false; + newPresetName.value = ""; + newPresetUrl.value = ""; +} + +function isCustomPreset(name: string) { + return apiStore.customPresets.some((p) => p.name === name); +} + // 主题切换函数 function toggleTheme() { const newTheme = @@ -136,12 +155,60 @@ onMounted(() => {
-
- {{ t("serverConfig.presetLabel") }} +
+
+ {{ t("serverConfig.presetLabel") }} +
+ + mdi-plus +
+ + +
+ + + Add Preset +
+
+ { @click="apiUrl = preset.url" :variant="apiUrl === preset.url ? 'flat' : 'tonal'" :color="apiUrl === preset.url ? 'primary' : undefined" + :closable="isCustomPreset(preset.name)" + @click:close="apiStore.removePreset(preset.name)" > {{ preset.name }}