- 更新 AdminView.vue 组件结构,使用新的布局和导航设计 - 集成 Element Plus 图标组件,提升界面美观度 - 添加响应式设计支持,适配移动端设备 - 重构 HomeView.vue 组件,改进 Token 查询功能 - 实现自动刷新机制,每5秒更新 Token 信息 - 优化 TokenDetailView.vue 组件,增强数据管理功能 - 添加确认对话框,防止误删操作 - 在 App.vue 中引入全局 CSS 变量和主题系统 - 创建通用组件样式类,统一页面外观 - 优化数据加载逻辑,提升页面性能和用户体验
This commit is contained in:
+204
-30
@@ -1,50 +1,224 @@
|
||||
<script setup lang="ts">
|
||||
import {ref, watch} from 'vue'
|
||||
import {useRoute, useRouter} from "vue-router";
|
||||
import {useCounterStore} from "@/stores/counter.ts";
|
||||
import {ref, watch, computed} from 'vue'
|
||||
import {useRoute, useRouter} from "vue-router"
|
||||
import {useCounterStore} from "@/stores/counter.ts"
|
||||
import {Edit, Delete, Clock, User, Document} from '@element-plus/icons-vue'
|
||||
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
const store = useCounterStore()
|
||||
|
||||
const activeIndex = ref(route.name?.toString() || "TokenList")
|
||||
const activeIndex = ref(route.name?.toString() || "TokenManage")
|
||||
|
||||
watch(route, (newRoute) => {
|
||||
activeIndex.value = newRoute.name?.toString() || "TokenList"
|
||||
activeIndex.value = newRoute.name?.toString() || "TokenManage"
|
||||
})
|
||||
|
||||
const handleSelect = (key: string) => {
|
||||
router.push({
|
||||
name: key
|
||||
})
|
||||
router.push({name: key})
|
||||
}
|
||||
|
||||
const menuItems = [
|
||||
{key: 'TokenManage', label: '管理 Token', icon: Edit},
|
||||
{key: 'TokenDetail', label: 'Token 详情', icon: Document},
|
||||
]
|
||||
|
||||
const logout = () => {
|
||||
store.isAdmin = false
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-container>
|
||||
<el-header>
|
||||
<el-menu
|
||||
:default-active="activeIndex"
|
||||
class="el-menu-demo"
|
||||
mode="horizontal"
|
||||
@select="handleSelect"
|
||||
>
|
||||
<el-menu-item index="TokenManage">管理Token</el-menu-item>
|
||||
<el-menu-item index="TokenDetail">Token详细信息</el-menu-item>
|
||||
<el-menu-item v-if="useCounterStore().isAdmin">
|
||||
<el-button type="danger" plain @click="useCounterStore().isAdmin=false">退出管理员</el-button>
|
||||
</el-menu-item>
|
||||
</el-menu>
|
||||
<div class="admin-layout">
|
||||
<header class="admin-header">
|
||||
<div class="header-left">
|
||||
<div class="logo">
|
||||
<el-icon size="24">
|
||||
<Edit/>
|
||||
</el-icon>
|
||||
<span class="logo-text">DYPID 管理后台</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</el-header>
|
||||
<nav class="header-nav">
|
||||
<div
|
||||
v-for="item in menuItems"
|
||||
:key="item.key"
|
||||
class="nav-item"
|
||||
:class="{ active: activeIndex === item.key }"
|
||||
@click="handleSelect(item.key)"
|
||||
>
|
||||
<el-icon>
|
||||
<component :is="item.icon"/>
|
||||
</el-icon>
|
||||
<span>{{ item.label }}</span>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<el-container>
|
||||
<el-main>
|
||||
<router-view></router-view>
|
||||
</el-main>
|
||||
</el-container>
|
||||
</el-container>
|
||||
<div class="header-right">
|
||||
<div v-if="store.isAdmin" class="admin-badge">
|
||||
<el-icon>
|
||||
<User/>
|
||||
</el-icon>
|
||||
<span>管理员</span>
|
||||
</div>
|
||||
<el-button
|
||||
v-if="store.isAdmin"
|
||||
type="danger"
|
||||
plain
|
||||
size="small"
|
||||
@click="logout"
|
||||
>
|
||||
<el-icon>
|
||||
<Delete/>
|
||||
</el-icon>
|
||||
退出
|
||||
</el-button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="admin-main">
|
||||
<router-view v-slot="{ Component }">
|
||||
<transition name="fade" mode="out-in">
|
||||
<component :is="Component"/>
|
||||
</transition>
|
||||
</router-view>
|
||||
</main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.admin-layout {
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: var(--bg-page);
|
||||
}
|
||||
|
||||
</style>
|
||||
.admin-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 24px;
|
||||
height: 60px;
|
||||
background: var(--bg-header);
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.header-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.logo {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
color: var(--primary-color);
|
||||
font-weight: 600;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.logo-text {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.logo-text {
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
|
||||
.header-nav {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.nav-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 8px 16px;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
color: var(--text-regular);
|
||||
font-size: 14px;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.nav-item:hover {
|
||||
background: var(--bg-page);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.nav-item.active {
|
||||
background: var(--primary-color);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.header-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.admin-badge {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 6px 12px;
|
||||
background: var(--danger-color);
|
||||
color: #fff;
|
||||
border-radius: 20px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.admin-main {
|
||||
flex: 1;
|
||||
padding: 24px 48px;
|
||||
max-width: 100%;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.fade-enter-active,
|
||||
.fade-leave-active {
|
||||
transition: opacity 0.2s ease;
|
||||
}
|
||||
|
||||
.fade-enter-from,
|
||||
.fade-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.admin-header {
|
||||
padding: 0 16px;
|
||||
flex-wrap: wrap;
|
||||
height: auto;
|
||||
padding: 12px 16px;
|
||||
}
|
||||
|
||||
.header-nav {
|
||||
order: 3;
|
||||
width: 100%;
|
||||
margin-top: 12px;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.nav-item {
|
||||
padding: 8px 12px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.nav-item span {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.admin-main {
|
||||
padding: 16px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user