feat: 支持系统设置中自定义全站名称和副标题

新增 site_name 和 site_subtitle 两个系统配置项,允许管理员在后台自定义
站点品牌名称(默认 Aether)和副标题(默认 AI Gateway)。

- 后端:DEFAULT_CONFIGS 新增配置项,公开 /api/public/site-info 端点
- 后端:邮件发送 app_name 回退链增加 site_name
- 前端:新增 useSiteInfo composable 全局缓存站点信息
- 前端:首页、后台布局、登录页、指南页面全部改为动态读取
- 前端:系统设置页新增「站点信息」配置区块
- 前端:配置导出文件名跟随站点名称
- 优化:请求失败允许重试,保存后即时生效无需刷新页面
- 优化:document.title 随站点名称动态更新

Closes #176

Co-authored-by: LewisPen <[email protected]>
This commit is contained in:
fawney19
2026-02-13 21:50:05 +08:00
co-authored by LewisPen
parent c171d65d3f
commit f464f32e48
14 changed files with 223 additions and 34 deletions
@@ -2,6 +2,9 @@
import { RouterLink } from 'vue-router'
import { ArrowRight, Shuffle, FileCode, Globe, Shield, Check, Info, AlertTriangle, Settings } from 'lucide-vue-next'
import { panelClasses } from './guide-config'
import { useSiteInfo } from '@/composables/useSiteInfo'
const { siteName } = useSiteInfo()
withDefaults(
defineProps<{
@@ -162,7 +165,7 @@ const systemSettings = [
高级功能
</h1>
<p class="text-lg text-[#666663] dark:text-[#a3a094]">
Aether 提供了一些高级功能,帮助你实现更灵活的 API 管理。
{{ siteName }} 提供了一些高级功能,帮助你实现更灵活的 API 管理。
</p>
</div>
+4 -1
View File
@@ -2,6 +2,9 @@
import { ref, computed } from 'vue'
import { Search, ChevronDown, ExternalLink, HelpCircle } from 'lucide-vue-next'
import { faqItems, panelClasses } from './guide-config'
import { useSiteInfo } from '@/composables/useSiteInfo'
const { siteName } = useSiteInfo()
withDefaults(
defineProps<{
@@ -70,7 +73,7 @@ function toggleAll() {
常见问题
</h1>
<p class="text-lg text-[#666663] dark:text-[#a3a094]">
关于 Aether 使用和配置的常见问题解答。
关于 {{ siteName }} 使用和配置的常见问题解答。
</p>
</div>
@@ -14,9 +14,9 @@
/>
<div class="flex flex-col justify-center">
<h1 class="text-base sm:text-lg font-bold text-[#191919] dark:text-white leading-none">
Aether
{{ siteName }}
</h1>
<span class="text-[9px] sm:text-[10px] text-[#91918d] dark:text-muted-foreground leading-none mt-1 sm:mt-1.5 font-medium tracking-wide">AI Gateway</span>
<span class="text-[9px] sm:text-[10px] text-[#91918d] dark:text-muted-foreground leading-none mt-1 sm:mt-1.5 font-medium tracking-wide">{{ siteSubtitle }}</span>
</div>
</RouterLink>
@@ -157,7 +157,7 @@
<!-- Base URL Input -->
<div class="p-4 border-t border-[#e5e4df] dark:border-[rgba(227,224,211,0.12)]">
<label class="block text-xs font-medium text-[#666663] dark:text-muted-foreground mb-2">
Aether Base URL
{{ siteName }} Base URL
</label>
<input
v-model="baseUrl"
@@ -200,10 +200,12 @@ import {
import GithubIcon from '@/components/icons/GithubIcon.vue'
import HeaderLogo from '@/components/HeaderLogo.vue'
import { useDarkMode } from '@/composables/useDarkMode'
import { useSiteInfo } from '@/composables/useSiteInfo'
import { guideNavItems } from './guide-config'
const route = useRoute()
const { themeMode, toggleDarkMode } = useDarkMode()
const { siteName, siteSubtitle } = useSiteInfo()
const showMobileNav = ref(false)
const baseUrl = ref(typeof window !== 'undefined' ? window.location.origin : 'https://your-aether.com')
+7 -4
View File
@@ -2,6 +2,9 @@
import { RouterLink } from 'vue-router'
import { ArrowRight, Server, Layers, Key, Box, ChevronRight } from 'lucide-vue-next'
import { coreConcepts, apiFormats, configSteps, panelClasses } from './guide-config'
import { useSiteInfo } from '@/composables/useSiteInfo'
const { siteName } = useSiteInfo()
withDefaults(
defineProps<{
@@ -41,10 +44,10 @@ const conceptIconColors = {
<!-- 标题区域 -->
<div class="space-y-4">
<h1 class="text-3xl font-bold text-[#262624] dark:text-[#f1ead8]">
欢迎使用 Aether
欢迎使用 {{ siteName }}
</h1>
<p class="text-lg text-[#666663] dark:text-[#a3a094]">
Aether 是一个 AI API 网关,帮助你统一管理多个 AI 服务供应商,实现负载均衡、访问控制和用量统计。
{{ siteName }} 是一个 AI API 网关,帮助你统一管理多个 AI 服务供应商,实现负载均衡、访问控制和用量统计。
</p>
</div>
@@ -54,7 +57,7 @@ const conceptIconColors = {
核心概念
</h2>
<p class="text-[#666663] dark:text-[#a3a094]">
理解这四个核心概念,是配置 Aether 的基础:
理解这四个核心概念,是配置 {{ siteName }} 的基础:
</p>
<div class="grid gap-4 sm:grid-cols-2">
@@ -161,7 +164,7 @@ const conceptIconColors = {
支持的 API 格式
</h2>
<p class="text-[#666663] dark:text-[#a3a094]">
Aether 支持多种 API 格式,可以作为不同客户端的统一入口:
{{ siteName }} 支持多种 API 格式,可以作为不同客户端的统一入口:
</p>
<div
@@ -2,6 +2,9 @@
import { RouterLink } from 'vue-router'
import { ArrowRight, Server, Settings, Check, AlertTriangle, Info } from 'lucide-vue-next'
import { apiFormats, panelClasses } from './guide-config'
import { useSiteInfo } from '@/composables/useSiteInfo'
const { siteName } = useSiteInfo()
withDefaults(
defineProps<{
@@ -73,7 +76,7 @@ const providerExamples = [
供应商管理
</h1>
<p class="text-lg text-[#666663] dark:text-[#a3a094]">
供应商和端点是 Aether 的基础配置,决定了系统可以调用哪些 AI 服务。
供应商和端点是 {{ siteName }} 的基础配置,决定了系统可以调用哪些 AI 服务。
</p>
</div>
@@ -2,6 +2,9 @@
import { RouterLink } from 'vue-router'
import { ArrowRight, Users, Key, Shield, Check, Info, AlertTriangle, Clock } from 'lucide-vue-next'
import { panelClasses } from './guide-config'
import { useSiteInfo } from '@/composables/useSiteInfo'
const { siteName } = useSiteInfo()
withDefaults(
defineProps<{
@@ -46,7 +49,7 @@ const roleComparison = [
用户与密钥
</h1>
<p class="text-lg text-[#666663] dark:text-[#a3a094]">
用户和 API Key 是 Aether 的访问控制核心。通过用户管理分配角色权限,通过 Key 管理控制 API 访问。
用户和 API Key 是 {{ siteName }} 的访问控制核心。通过用户管理分配角色权限,通过 Key 管理控制 API 访问。
</p>
</div>
@@ -192,7 +195,7 @@ const roleComparison = [
<ul class="space-y-3 text-sm text-[#666663] dark:text-[#a3a094]">
<li class="flex items-start gap-2">
<Check class="h-4 w-4 text-green-500 mt-0.5 flex-shrink-0" />
<span>API Key 是用户调用 Aether API 的凭证</span>
<span>API Key 是用户调用 {{ siteName }} API 的凭证</span>
</li>
<li class="flex items-start gap-2">
<Check class="h-4 w-4 text-green-500 mt-0.5 flex-shrink-0" />