diff --git a/dashboard/README.md b/dashboard/README.md index 52df63351..0cdcae80c 100644 --- a/dashboard/README.md +++ b/dashboard/README.md @@ -1,3 +1,10 @@ # AstrBot 管理面板 -基于 CodedThemes/Berry 模板开发。 \ No newline at end of file +基于 CodedThemes/Berry 模板开发。 + +## 环境变量 + +- `VITE_ASTRBOT_RELEASE_BASE_URL`(可选) + - 默认值:`https://github.com/AstrBotDevs/AstrBot/releases` + - 用途:管理面板内“更新到最新版本”外部跳转所使用的 release 基地址。集成方可按需覆盖(例如 Desktop 指向其自身发布页)。 + - 建议传入仓库的 `.../releases` 基地址(不带 `/latest`)。 diff --git a/dashboard/env.d.ts b/dashboard/env.d.ts index 11f02fe2a..b4b350830 100644 --- a/dashboard/env.d.ts +++ b/dashboard/env.d.ts @@ -1 +1,9 @@ /// + +interface ImportMetaEnv { + readonly VITE_ASTRBOT_RELEASE_BASE_URL?: string; +} + +interface ImportMeta { + readonly env: ImportMetaEnv; +} diff --git a/dashboard/src/layouts/full/vertical-header/VerticalHeader.vue b/dashboard/src/layouts/full/vertical-header/VerticalHeader.vue index 7b5c87ba3..543aef12c 100644 --- a/dashboard/src/layouts/full/vertical-header/VerticalHeader.vue +++ b/dashboard/src/layouts/full/vertical-header/VerticalHeader.vue @@ -53,8 +53,22 @@ const isDesktopReleaseMode = ref( const redirectConfirmDialog = ref(false); const pendingRedirectUrl = ref(''); const resolvingReleaseTarget = ref(false); -const desktopReleaseBaseUrl = 'https://github.com/AstrBotDevs/AstrBot-desktop/releases'; -const fallbackReleaseUrl = desktopReleaseBaseUrl; +const DEFAULT_ASTRBOT_RELEASE_BASE_URL = 'https://github.com/AstrBotDevs/AstrBot/releases'; +const resolveReleaseBaseUrl = () => { + const raw = import.meta.env.VITE_ASTRBOT_RELEASE_BASE_URL; + // Keep upstream default on AstrBot releases; desktop distributors can override via env injection. + const normalized = raw?.trim()?.replace(/\/+$/, '') || ''; + const withoutLatestSuffix = normalized.replace(/\/latest$/i, ''); + return withoutLatestSuffix || DEFAULT_ASTRBOT_RELEASE_BASE_URL; +}; +const releaseBaseUrl = resolveReleaseBaseUrl(); +const getReleaseUrlByTag = (tag: string | null | undefined) => { + const normalizedTag = (tag || '').trim(); + if (!normalizedTag || normalizedTag.toLowerCase() === 'latest') { + return `${releaseBaseUrl}/latest`; + } + return `${releaseBaseUrl}/tag/${normalizedTag}`; +}; const getSelectedGitHubProxy = () => { if (typeof window === "undefined" || !window.localStorage) return ""; @@ -137,14 +151,11 @@ function confirmExternalRedirect() { const getReleaseUrlForDesktop = () => { const firstRelease = (releases.value as any[])?.[0]; if (firstRelease?.tag_name) { - const tag = firstRelease.tag_name as string; - return `${desktopReleaseBaseUrl}/tag/${tag}`; + return getReleaseUrlByTag(firstRelease.tag_name as string); } - if (hasNewVersion.value) return fallbackReleaseUrl; + if (hasNewVersion.value) return getReleaseUrlByTag('latest'); const tag = botCurrVersion.value?.startsWith('v') ? botCurrVersion.value : 'latest'; - return tag === 'latest' - ? fallbackReleaseUrl - : `${desktopReleaseBaseUrl}/tag/${tag}`; + return getReleaseUrlByTag(tag); }; function handleUpdateClick() { @@ -153,7 +164,7 @@ function handleUpdateClick() { resolvingReleaseTarget.value = true; checkUpdate(); void getReleases().finally(() => { - pendingRedirectUrl.value = getReleaseUrlForDesktop() || fallbackReleaseUrl; + pendingRedirectUrl.value = getReleaseUrlForDesktop() || getReleaseUrlByTag('latest'); resolvingReleaseTarget.value = false; }); return;