mirror of
https://github.com/AstrBotDevs/AstrBot
synced 2026-07-16 17:47:06 +08:00
fix(dashboard): resolve JSON syntax errors and BOM in auth.json
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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": "Настройки сервера"
|
||||
}
|
||||
}
|
||||
@@ -10,5 +10,16 @@
|
||||
"theme": {
|
||||
"switchToDark": "切换到深色主题",
|
||||
"switchToLight": "切换到浅色主题"
|
||||
},
|
||||
"serverConfig": {
|
||||
"title": "服务器配置",
|
||||
"description": "如果后端服务不在同源(主机/端口不同),请在此指定完整 URL。",
|
||||
"label": "API 基础地址",
|
||||
"placeholder": "例如:http://localhost:6185",
|
||||
"hint": "留空以使用默认设置(相对路径)",
|
||||
"presetLabel": "快速选择预设",
|
||||
"save": "保存并刷新",
|
||||
"cancel": "取消",
|
||||
"tooltip": "服务器配置"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
"
|
||||
></v-divider>
|
||||
|
||||
<v-btn
|
||||
@click="serverConfigDialog = true"
|
||||
icon
|
||||
variant="text"
|
||||
size="small"
|
||||
>
|
||||
<v-icon
|
||||
size="18"
|
||||
:color="
|
||||
useCustomizerStore().uiTheme === 'PurpleTheme'
|
||||
? '#5e35b1'
|
||||
: '#d7c5fa'
|
||||
"
|
||||
>
|
||||
mdi-server
|
||||
</v-icon>
|
||||
<v-tooltip activator="parent" location="top">
|
||||
{{ t("serverConfig.tooltip") }}
|
||||
</v-tooltip>
|
||||
</v-btn>
|
||||
|
||||
<v-btn
|
||||
@click="toggleTheme"
|
||||
class="theme-toggle-btn"
|
||||
@@ -73,7 +120,14 @@ onMounted(async () => {
|
||||
variant="text"
|
||||
size="small"
|
||||
>
|
||||
<v-icon size="18" :color="'rgb(var(--v-theme-primary))'">
|
||||
<v-icon
|
||||
size="18"
|
||||
:color="
|
||||
useCustomizerStore().uiTheme === 'PurpleTheme'
|
||||
? '#5e35b1'
|
||||
: '#d7c5fa'
|
||||
"
|
||||
>
|
||||
mdi-white-balance-sunny
|
||||
</v-icon>
|
||||
<v-tooltip activator="parent" location="top">
|
||||
@@ -91,6 +145,107 @@ onMounted(async () => {
|
||||
<AuthLogin />
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
|
||||
<v-dialog v-model="serverConfigDialog" max-width="450">
|
||||
<v-card>
|
||||
<v-card-title>{{ t("serverConfig.title") }}</v-card-title>
|
||||
<v-card-text>
|
||||
<div class="text-body-2 text-medium-emphasis mb-4">
|
||||
{{ t("serverConfig.description") }}
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="
|
||||
(apiStore.presets && apiStore.presets.length > 0) ||
|
||||
apiStore.customPresets
|
||||
"
|
||||
class="mb-4"
|
||||
>
|
||||
<div class="d-flex justify-space-between align-center mb-2">
|
||||
<div class="text-caption text-medium-emphasis">
|
||||
{{ t("serverConfig.presetLabel") }}
|
||||
</div>
|
||||
<v-btn
|
||||
size="x-small"
|
||||
variant="text"
|
||||
icon
|
||||
@click="showAddPreset = !showAddPreset"
|
||||
>
|
||||
<v-icon>mdi-plus</v-icon>
|
||||
</v-btn>
|
||||
</div>
|
||||
|
||||
<v-expand-transition>
|
||||
<div
|
||||
v-if="showAddPreset"
|
||||
class="mb-2 pa-2 bg-grey-lighten-4 rounded border"
|
||||
>
|
||||
<v-text-field
|
||||
v-model="newPresetName"
|
||||
label="Name"
|
||||
density="compact"
|
||||
hide-details
|
||||
class="mb-2"
|
||||
variant="outlined"
|
||||
bg-color="white"
|
||||
></v-text-field>
|
||||
<v-text-field
|
||||
v-model="newPresetUrl"
|
||||
label="URL"
|
||||
density="compact"
|
||||
hide-details
|
||||
class="mb-2"
|
||||
variant="outlined"
|
||||
bg-color="white"
|
||||
></v-text-field>
|
||||
<v-btn
|
||||
size="small"
|
||||
block
|
||||
color="primary"
|
||||
variant="flat"
|
||||
@click="savePreset"
|
||||
>Add Preset</v-btn
|
||||
>
|
||||
</div>
|
||||
</v-expand-transition>
|
||||
|
||||
<v-chip-group column>
|
||||
<v-chip
|
||||
v-for="preset in apiStore.presets"
|
||||
:key="preset.name"
|
||||
size="small"
|
||||
@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 }}
|
||||
</v-chip>
|
||||
</v-chip-group>
|
||||
</div>
|
||||
|
||||
<v-text-field
|
||||
v-model="apiUrl"
|
||||
:label="t('serverConfig.label')"
|
||||
:placeholder="t('serverConfig.placeholder')"
|
||||
:hint="t('serverConfig.hint')"
|
||||
persistent-hint
|
||||
variant="outlined"
|
||||
density="compact"
|
||||
></v-text-field>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn variant="text" @click="serverConfigDialog = false">{{
|
||||
t("serverConfig.cancel")
|
||||
}}</v-btn>
|
||||
<v-btn color="primary" variant="flat" @click="saveApiUrl">{{
|
||||
t("serverConfig.save")
|
||||
}}</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user