diff --git a/astrbot/cli/commands/cmd_conf.py b/astrbot/cli/commands/cmd_conf.py index 3e087e61c..06cf58811 100644 --- a/astrbot/cli/commands/cmd_conf.py +++ b/astrbot/cli/commands/cmd_conf.py @@ -54,7 +54,7 @@ def _validate_dashboard_port(value: str) -> int: try: port = int(value) except ValueError: - raise click.ClickException(t("config_port_must_be_number")) + raise click.ClickException(t("config_port_must_be_number")) from None if port < 1 or port > 65535: raise click.ClickException(t("config_port_range_invalid")) return port diff --git a/dashboard/package.json b/dashboard/package.json index ef08023c0..612834468 100644 --- a/dashboard/package.json +++ b/dashboard/package.json @@ -28,16 +28,16 @@ "event-source-polyfill": "^1.0.31", "highlight.js": "^11.11.1", "js-md5": "^0.8.3", - "katex": "^0.16.43", + "katex": "^0.16.44", "lodash": "4.18.1", "markdown-it": "^14.1.1", "markstream-vue": "^0.0.9", - "mermaid": "^11.13.0", + "mermaid": "^11.14.0", "monaco-editor": "^0.55.1", "pinia": "3.0.0", "pinyin-pro": "^3.28.0", "qrcode": "^1.5.4", - "shiki": "^3.13.0", + "shiki": "^3.23.0", "stream-markdown": "^0.0.14", "vee-validate": "4.15.1", "vite-plugin-vuetify": "2.1.3", @@ -54,7 +54,7 @@ "@rushstack/eslint-patch": "1.16.1", "@types/chance": "1.1.7", "@types/markdown-it": "^14.1.2", - "@types/node": "^25.5.0", + "@types/node": "^25.5.2", "@vitejs/plugin-vue": "6.0.5", "@vue/eslint-config-prettier": "10.2.0", "@vue/eslint-config-typescript": "14.7.0", @@ -64,11 +64,11 @@ "prettier": "3.8.1", "sass": "1.98.0", "sass-loader": "16.0.7", - "subset-font": "^2.4.0", - "typescript": "~6.0.0", + "subset-font": "^2.5.0", + "typescript": "~6.0.2", "vite": "8.0.3", "vite-plugin-webfont-dl": "^3.12.0", - "vue-tsc": "^3.0.0" + "vue-tsc": "^3.2.6" }, "overrides": { "flatted": "3.4.2", diff --git a/dashboard/src/i18n/locales/en-US/features/auth.json b/dashboard/src/i18n/locales/en-US/features/auth.json index e3bbb600b..d07f952c6 100644 --- a/dashboard/src/i18n/locales/en-US/features/auth.json +++ b/dashboard/src/i18n/locales/en-US/features/auth.json @@ -10,5 +10,16 @@ "theme": { "switchToDark": "Switch to Dark Theme", "switchToLight": "Switch to Light Theme" + }, + "serverConfig": { + "title": "Server Configuration", + "description": "If the backend is not on the same origin (host/port), please specify the full URL here.", + "label": "API Base URL", + "placeholder": "e.g. http://localhost:6185", + "hint": "Empty for default (relative path)", + "presetLabel": "Quick Select Preset", + "save": "Save & Reload", + "cancel": "Cancel", + "tooltip": "Server Configuration" } -} +} diff --git a/dashboard/src/i18n/locales/ru-RU/features/auth.json b/dashboard/src/i18n/locales/ru-RU/features/auth.json index 6f7ab79cf..e7dc9cca7 100644 --- a/dashboard/src/i18n/locales/ru-RU/features/auth.json +++ b/dashboard/src/i18n/locales/ru-RU/features/auth.json @@ -1,14 +1,25 @@ -{ - "login": "Вход", - "username": "Имя пользователя", - "password": "Пароль", - "defaultHint": "Учетные данные по умолчанию: astrbot / astrbot", - "logo": { - "title": "Панель управления AstrBot", - "subtitle": "Добро пожаловать" - }, - "theme": { - "switchToDark": "Перейти на темную тему", - "switchToLight": "Перейти на светлую тему" - } -} +{ + "login": "Вход", + "username": "Имя пользователя", + "password": "Пароль", + "defaultHint": "Учетные данные по умолчанию: astrbot / astrbot", + "logo": { + "title": "Панель управления AstrBot", + "subtitle": "Добро пожаловать" + }, + "theme": { + "switchToDark": "Перейти на темную тему", + "switchToLight": "Перейти на светлую тему" + }, + "serverConfig": { + "title": "Настройки сервера", + "description": "Если бэкенд не на том же домене, укажите полный URL здесь.", + "label": "Базовый URL API", + "placeholder": "Например: http://localhost:6185", + "hint": "Оставьте пустым для настроек по умолчанию (относительный путь)", + "presetLabel": "Быстрый выбор", + "save": "Сохранить и обновить", + "cancel": "Отмена", + "tooltip": "Настройки сервера" + } +} \ No newline at end of file diff --git a/dashboard/src/i18n/locales/zh-CN/features/auth.json b/dashboard/src/i18n/locales/zh-CN/features/auth.json index b927d9a0d..84df8ca9b 100644 --- a/dashboard/src/i18n/locales/zh-CN/features/auth.json +++ b/dashboard/src/i18n/locales/zh-CN/features/auth.json @@ -10,5 +10,16 @@ "theme": { "switchToDark": "切换到深色主题", "switchToLight": "切换到浅色主题" + }, + "serverConfig": { + "title": "服务器配置", + "description": "如果后端服务不在同源(主机/端口不同),请在此指定完整 URL。", + "label": "API 基础地址", + "placeholder": "例如:http://localhost:6185", + "hint": "留空以使用默认设置(相对路径)", + "presetLabel": "快速选择预设", + "save": "保存并刷新", + "cancel": "取消", + "tooltip": "服务器配置" } -} +} diff --git a/dashboard/src/views/authentication/auth/LoginPage.vue b/dashboard/src/views/authentication/auth/LoginPage.vue index 8b8e95626..b659eae27 100644 --- a/dashboard/src/views/authentication/auth/LoginPage.vue +++ b/dashboard/src/views/authentication/auth/LoginPage.vue @@ -3,6 +3,7 @@ import AuthLogin from "../authForms/AuthLogin.vue"; import LanguageSwitcher from "@/components/shared/LanguageSwitcher.vue"; import { onMounted, ref } from "vue"; import { useAuthStore } from "@/stores/auth"; +import { useApiStore } from "@/stores/api"; import { useRouter } from "vue-router"; import { useCustomizerStore } from "@/stores/customizer"; import { useModuleI18n } from "@/i18n/composables"; @@ -11,10 +12,39 @@ import { useTheme } from "vuetify"; const cardVisible = ref(false); const router = useRouter(); const authStore = useAuthStore(); +const apiStore = useApiStore(); const customizer = useCustomizerStore(); const { tm: t } = useModuleI18n("features/auth"); 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 = @@ -25,15 +55,10 @@ function toggleTheme() { theme.global.name.value = newTheme; } -onMounted(async () => { +onMounted(() => { // 检查用户是否已登录,如果已登录则重定向 if (authStore.has_token()) { - const onboardingCompleted = await authStore.checkOnboardingCompleted(); - if (onboardingCompleted) { - router.push("/dashboard/default"); - } else { - router.push("/welcome"); - } + router.push(authStore.returnUrl || "/"); return; } @@ -63,9 +88,31 @@ onMounted(async () => { height: 24px !important; opacity: 0.9 !important; align-self: center !important; - border-color: rgba(var(--v-theme-primary), 0.45) !important; + border-color: rgba(180, 148, 246, 0.8) !important; " > + + + + mdi-server + + + {{ t("serverConfig.tooltip") }} + + + { variant="text" size="small" > - + mdi-white-balance-sunny @@ -91,6 +145,107 @@ onMounted(async () => { + + + + {{ t("serverConfig.title") }} + + + {{ t("serverConfig.description") }} + + + + + + {{ t("serverConfig.presetLabel") }} + + + mdi-plus + + + + + + + + Add Preset + + + + + + {{ preset.name }} + + + + + + + + + {{ + t("serverConfig.cancel") + }} + {{ + t("serverConfig.save") + }} + + +