refactor(frontend): 优化布局和视图页面

- 更新 MainLayout 布局组件
- 优化 admin 视图: 用户、模型、Provider、API Keys 等管理页面
- 改进 shared 视图: Dashboard、Usage 页面
- 调整 user 视图: ModelCatalog、MyApiKeys、Settings、Announcements 页面
- 更新 public 视图: Home、CliSection、LogoColorDemo 页面
This commit is contained in:
fawney19
2025-12-12 16:15:54 +08:00
parent 06c0a47b21
commit 39ea9e8e86
20 changed files with 3062 additions and 1154 deletions

View File

@@ -6,9 +6,10 @@
:content-class="contentClasses"
>
<!-- GLOBAL TEXTURE (Paper Noise) -->
<div class="absolute inset-0 pointer-events-none z-0 opacity-[0.03] mix-blend-multiply fixed"
:style="{ backgroundImage: `url(\&quot;data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)'/%3E%3C/svg%3E\&quot;)` }">
</div>
<div
class="absolute inset-0 pointer-events-none z-0 opacity-[0.03] mix-blend-multiply fixed"
:style="{ backgroundImage: `url(\&quot;data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)'/%3E%3C/svg%3E\&quot;)` }"
/>
<template #notice>
<div class="flex w-full max-w-3xl items-center justify-between rounded-3xl bg-orange-500 px-6 py-3 text-white shadow-2xl ring-1 ring-white/30">
@@ -17,10 +18,10 @@
<span>认证已过期请重新登录</span>
</div>
<Button
@click="handleRelogin"
variant="outline"
size="sm"
class="border-white/60 text-white hover:bg-white/10"
@click="handleRelogin"
>
重新登录
</Button>
@@ -30,13 +31,21 @@
<template #sidebar>
<!-- HEADER (Brand) -->
<div class="shrink-0 flex items-center px-6 h-20">
<RouterLink to="/" class="flex items-center gap-3 group transition-opacity hover:opacity-80">
<HeaderLogo size="h-9 w-9" className="text-[#191919] dark:text-white" />
<div class="flex flex-col justify-center">
<h1 class="text-lg font-bold text-[#191919] dark:text-white leading-none">Aether</h1>
<span class="text-[10px] text-[#91918d] dark:text-muted-foreground leading-none mt-1.5 font-medium tracking-wide">Multi Private Gateway</span>
</div>
</RouterLink>
<RouterLink
to="/"
class="flex items-center gap-3 group transition-opacity hover:opacity-80"
>
<HeaderLogo
size="h-9 w-9"
class-name="text-[#191919] dark:text-white"
/>
<div class="flex flex-col justify-center">
<h1 class="text-lg font-bold text-[#191919] dark:text-white leading-none">
Aether
</h1>
<span class="text-[10px] text-[#91918d] dark:text-muted-foreground leading-none mt-1.5 font-medium tracking-wide">Multi Private Gateway</span>
</div>
</RouterLink>
</div>
<!-- NAVIGATION -->
@@ -50,28 +59,32 @@
<!-- FOOTER (Profile) -->
<div class="p-4 border-t border-[#3d3929]/5 dark:border-white/5">
<div class="flex items-center justify-between p-2 rounded-xl">
<div class="flex items-center gap-3 min-w-0">
<div class="w-8 h-8 rounded-full bg-[#f0f0eb] dark:bg-white/10 border border-black/5 flex items-center justify-center text-xs font-bold text-[#3d3929] dark:text-[#d4a27f] shrink-0">
{{ authStore.user?.username?.substring(0, 2).toUpperCase() }}
</div>
<div class="flex flex-col min-w-0">
<span class="text-xs font-semibold leading-none truncate opacity-90 text-foreground">{{ authStore.user?.username }}</span>
<span class="text-[10px] opacity-50 leading-none mt-1.5 text-muted-foreground">{{ authStore.user?.role === 'admin' ? '管理员' : '用户' }}</span>
</div>
</div>
<div class="flex items-center gap-3 min-w-0">
<div class="w-8 h-8 rounded-full bg-[#f0f0eb] dark:bg-white/10 border border-black/5 flex items-center justify-center text-xs font-bold text-[#3d3929] dark:text-[#d4a27f] shrink-0">
{{ authStore.user?.username?.substring(0, 2).toUpperCase() }}
</div>
<div class="flex flex-col min-w-0">
<span class="text-xs font-semibold leading-none truncate opacity-90 text-foreground">{{ authStore.user?.username }}</span>
<span class="text-[10px] opacity-50 leading-none mt-1.5 text-muted-foreground">{{ authStore.user?.role === 'admin' ? '管理员' : '用户' }}</span>
</div>
</div>
<div class="flex items-center gap-1">
<RouterLink
to="/dashboard/settings"
class="p-1.5 hover:bg-muted/50 rounded-md text-muted-foreground hover:text-foreground transition-colors"
title="个人设置"
>
<Settings class="w-4 h-4" />
</RouterLink>
<button @click="handleLogout" class="p-1.5 rounded-md text-muted-foreground hover:text-red-500 transition-colors" title="退出登录">
<LogOut class="w-4 h-4" />
</button>
</div>
<div class="flex items-center gap-1">
<RouterLink
to="/dashboard/settings"
class="p-1.5 hover:bg-muted/50 rounded-md text-muted-foreground hover:text-foreground transition-colors"
title="个人设置"
>
<Settings class="w-4 h-4" />
</RouterLink>
<button
class="p-1.5 rounded-md text-muted-foreground hover:text-red-500 transition-colors"
title="退出登录"
@click="handleLogout"
>
<LogOut class="w-4 h-4" />
</button>
</div>
</div>
</div>
</template>
@@ -79,46 +92,64 @@
<template #header>
<!-- Mobile Header -->
<div class="lg:hidden p-4 flex items-center justify-between border-b border-border bg-background/80 backdrop-blur-md">
<RouterLink to="/" class="flex items-center gap-2">
<HeaderLogo size="h-8 w-8" className="text-[#191919] dark:text-white" />
<span class="font-bold text-lg">Aether</span>
</RouterLink>
<MobileNav
:items="navigation"
:is-active="isNavActive"
:active-path="route.path"
:is-dark="isDark"
/>
<RouterLink
to="/"
class="flex items-center gap-2"
>
<HeaderLogo
size="h-8 w-8"
class-name="text-[#191919] dark:text-white"
/>
<span class="font-bold text-lg">Aether</span>
</RouterLink>
<MobileNav
:items="navigation"
:is-active="isNavActive"
:active-path="route.path"
:is-dark="isDark"
/>
</div>
<!-- Desktop Page Header -->
<header class="hidden lg:flex h-16 px-8 items-center justify-between shrink-0 border-b border-[#3d3929]/5 dark:border-white/5 sticky top-0 z-40 backdrop-blur-md bg-[#faf9f5]/90 dark:bg-[#191714]/90">
<div class="flex flex-col gap-0.5">
<div class="flex items-center gap-2 text-sm text-muted-foreground">
<span>{{ currentSectionName }}</span>
<ChevronRight class="w-3 h-3 opacity-50" />
<span class="text-foreground font-medium">{{ currentPageName }}</span>
</div>
<div class="flex flex-col gap-0.5">
<div class="flex items-center gap-2 text-sm text-muted-foreground">
<span>{{ currentSectionName }}</span>
<ChevronRight class="w-3 h-3 opacity-50" />
<span class="text-foreground font-medium">{{ currentPageName }}</span>
</div>
</div>
<!-- Demo Mode Badge (center) -->
<div v-if="isDemo" class="flex items-center gap-2 px-3 py-1.5 rounded-full bg-amber-100 dark:bg-amber-900/30 text-amber-700 dark:text-amber-400 text-xs font-medium">
<AlertTriangle class="w-3.5 h-3.5" />
<span>演示模式</span>
</div>
<!-- Demo Mode Badge (center) -->
<div
v-if="isDemo"
class="flex items-center gap-2 px-3 py-1.5 rounded-full bg-amber-100 dark:bg-amber-900/30 text-amber-700 dark:text-amber-400 text-xs font-medium"
>
<AlertTriangle class="w-3.5 h-3.5" />
<span>演示模式</span>
</div>
<div class="flex items-center gap-2">
<!-- Theme Toggle -->
<button
@click="toggleDarkMode"
class="flex h-9 w-9 items-center justify-center rounded-lg text-muted-foreground hover:text-foreground hover:bg-muted/50 transition"
:title="themeMode === 'system' ? '跟随系统' : themeMode === 'dark' ? '深色模式' : '浅色模式'"
>
<SunMoon v-if="themeMode === 'system'" class="h-4 w-4" />
<SunMedium v-else-if="themeMode === 'light'" class="h-4 w-4" />
<Moon v-else class="h-4 w-4" />
</button>
</div>
<div class="flex items-center gap-2">
<!-- Theme Toggle -->
<button
class="flex h-9 w-9 items-center justify-center rounded-lg text-muted-foreground hover:text-foreground hover:bg-muted/50 transition"
:title="themeMode === 'system' ? '跟随系统' : themeMode === 'dark' ? '深色模式' : '浅色模式'"
@click="toggleDarkMode"
>
<SunMoon
v-if="themeMode === 'system'"
class="h-4 w-4"
/>
<SunMedium
v-else-if="themeMode === 'light'"
class="h-4 w-4"
/>
<Moon
v-else
class="h-4 w-4"
/>
</button>
</div>
</header>
</template>