- 移除 App.vue 中的内联样式,将 CSS 变量定义移到 main.css - 在 HomeView.vue 中使用 Element Plus Card 组件替代自定义卡片样式 - 更新 HomeView.vue 中的统计卡片布局,使用 Space 和 Card 组件 - 添加 fade-in 动画到全局主题配置 - 在 components.d.ts 中注册 ElCard 和 ElContainer 组件 - 移除 SettingsView.vue 中的空样式标签 - 使用 Tailwind CSS 类替代原有的自定义样式类
This commit is contained in:
Vendored
+2
@@ -13,8 +13,10 @@ declare module 'vue' {
|
||||
export interface GlobalComponents {
|
||||
AddDataDialog: typeof import('./src/components/AddDataDialog.vue')['default']
|
||||
ElButton: typeof import('element-plus/es')['ElButton']
|
||||
ElCard: typeof import('element-plus/es')['ElCard']
|
||||
ElCollapse: typeof import('element-plus/es')['ElCollapse']
|
||||
ElCollapseItem: typeof import('element-plus/es')['ElCollapseItem']
|
||||
ElContainer: typeof import('element-plus/es')['ElContainer']
|
||||
ElDialog: typeof import('element-plus/es')['ElDialog']
|
||||
ElDivider: typeof import('element-plus/es')['ElDivider']
|
||||
ElDropdown: typeof import('element-plus/es')['ElDropdown']
|
||||
|
||||
+1
-52
@@ -3,58 +3,7 @@ const themeMode = ref('light')
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div :class="themeMode" class="app-container">
|
||||
<div :class="themeMode" class="min-h-screen bg-(--bg-page) max-w-full">
|
||||
<router-view></router-view>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
:root {
|
||||
--bg-page: #f5f7fa;
|
||||
--bg-card: #ffffff;
|
||||
--bg-header: #ffffff;
|
||||
}
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html, body {
|
||||
height: 100%;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
||||
}
|
||||
|
||||
.app-container {
|
||||
min-height: 100vh;
|
||||
background: var(--bg-page);
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
/* 卡片通用样式 */
|
||||
.content-card {
|
||||
background: var(--bg-card);
|
||||
border-radius: 8px;
|
||||
padding: 24px;
|
||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
/* 页面标题样式 */
|
||||
.page-title {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
color: var(--el-text-color-primary);
|
||||
margin-bottom: 20px;
|
||||
padding-bottom: 12px;
|
||||
border-bottom: 1px solid var(--el-border-color);
|
||||
}
|
||||
|
||||
/* Section 标题 */
|
||||
.section-title {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: var(--el-text-color-primary);
|
||||
margin: 20px 0 16px;
|
||||
}
|
||||
</style>
|
||||
@@ -1 +1,23 @@
|
||||
@import "tailwindcss" important;
|
||||
|
||||
@theme {
|
||||
--animate-fade-in: fade-in 0.3s ease;
|
||||
--bg-page: #f5f7fa;
|
||||
--bg-card: #ffffff;
|
||||
--bg-header: #ffffff;
|
||||
}
|
||||
|
||||
@keyframes fade-in {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
:root {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
||||
}
|
||||
|
||||
+27
-146
@@ -45,18 +45,26 @@ const checkPassword = () => {
|
||||
ElMessage.error('密码错误')
|
||||
}
|
||||
}
|
||||
|
||||
const navItemClass = (name: string) => {
|
||||
return activeIndex.value === name
|
||||
? 'bg-[var(--el-color-primary)] text-white'
|
||||
: 'text-[var(--el-text-color-regular)] hover:bg-[var(--bg-page)] hover:text-[var(--el-text-color-primary)]'
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="admin-layout">
|
||||
<el-header class="admin-header">
|
||||
<div class="header-left">
|
||||
<div class="logo">DYPID 管理后台</div>
|
||||
<div class="min-h-screen flex flex-col bg-(--bg-page)">
|
||||
<el-header
|
||||
class="flex items-center justify-between bg-(--bg-header) border-b border-(--el-border-color) sticky top-0 z-50 max-md:flex-wrap max-md:h-auto max-md:px-4 max-md:py-3">
|
||||
<div class="flex items-center">
|
||||
<div class="flex items-center gap-2.5 text-(--el-color-primary) font-semibold text-lg">DYPID 管理后台</div>
|
||||
</div>
|
||||
|
||||
<nav class="header-nav">
|
||||
<div class="nav-item"
|
||||
:class="{active:activeIndex=='TokenManage'}"
|
||||
<nav class="flex gap-2 max-md:order-3 max-md:w-full max-md:mt-3 max-md:overflow-x-auto max-md:pb-1">
|
||||
<div
|
||||
class="flex items-center gap-1.5 px-4 py-2 rounded-lg cursor-pointer text-sm transition-all duration-200 max-md:px-3 max-md:py-2 max-md:text-xs"
|
||||
:class="navItemClass('TokenManage')"
|
||||
@click="handleSelect('TokenManage')"
|
||||
>
|
||||
<el-icon>
|
||||
@@ -65,8 +73,9 @@ const checkPassword = () => {
|
||||
<span>管理 Token</span>
|
||||
</div>
|
||||
|
||||
<div class="nav-item"
|
||||
:class="{active:activeIndex=='TokenDetail'}"
|
||||
<div
|
||||
class="flex items-center gap-1.5 px-4 py-2 rounded-lg cursor-pointer text-sm transition-all duration-200 max-md:px-3 max-md:py-2 max-md:text-xs"
|
||||
:class="navItemClass('TokenDetail')"
|
||||
@click="handleSelect('TokenDetail')"
|
||||
>
|
||||
<el-icon>
|
||||
@@ -76,7 +85,7 @@ const checkPassword = () => {
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="header-right">
|
||||
<div class="flex items-center">
|
||||
<el-button v-if="_isAdmin" circle link
|
||||
@click="handleSelect('AdminSettings')"
|
||||
>
|
||||
@@ -106,15 +115,16 @@ const checkPassword = () => {
|
||||
|
||||
<el-main>
|
||||
<!-- 登录页面 -->
|
||||
<div v-if="!_isAdmin" class="login-page">
|
||||
<div class="login-card">
|
||||
<div class="login-icon">
|
||||
<div v-if="!_isAdmin" class="flex justify-center items-center min-h-[60vh]">
|
||||
<div
|
||||
class="w-full max-w-100 text-center py-12 px-10 bg-(--bg-card) rounded-2xl shadow-[0_4px_24px_rgba(0,0,0,0.08)]">
|
||||
<div class="mb-6">
|
||||
<el-icon size="48" color="#409eff">
|
||||
<Lock/>
|
||||
</el-icon>
|
||||
</div>
|
||||
<div class="login-title">管理员登录</div>
|
||||
<div class="login-subtitle">请输入管理员密码访问管理后台</div>
|
||||
<div class="text-2xl font-semibold text-(--el-text-color-primary) mb-2">管理员登录</div>
|
||||
<div class="text-sm text-(--el-text-color-secondary) mb-8">请输入管理员密码访问管理后台</div>
|
||||
|
||||
<el-input
|
||||
v-model="inputPassWord"
|
||||
@@ -122,6 +132,7 @@ const checkPassword = () => {
|
||||
placeholder="请输入管理员密码"
|
||||
size="large"
|
||||
show-password
|
||||
class="mb-4"
|
||||
@keyup.enter="checkPassword"
|
||||
>
|
||||
<template #prefix>
|
||||
@@ -131,7 +142,7 @@ const checkPassword = () => {
|
||||
</template>
|
||||
</el-input>
|
||||
|
||||
<el-button type="primary" size="large" class="login-btn" @click="checkPassword">
|
||||
<el-button type="primary" size="large" class="w-full mt-2" @click="checkPassword">
|
||||
登录
|
||||
</el-button>
|
||||
</div>
|
||||
@@ -143,133 +154,3 @@ const checkPassword = () => {
|
||||
</el-main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.admin-layout {
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: var(--bg-page);
|
||||
}
|
||||
|
||||
.admin-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
background: var(--bg-header);
|
||||
border-bottom: 1px solid var(--el-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(--el-color-primary);
|
||||
font-weight: 600;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.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(--el-text-color-regular);
|
||||
font-size: 14px;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.nav-item:hover {
|
||||
background: var(--bg-page);
|
||||
color: var(--el-text-color-primary);
|
||||
}
|
||||
|
||||
.nav-item.active {
|
||||
background: var(--el-color-primary);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.header-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* 登录页面 */
|
||||
.login-page {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: 60vh;
|
||||
}
|
||||
|
||||
.login-card {
|
||||
width: 100%;
|
||||
max-width: 400px;
|
||||
text-align: center;
|
||||
padding: 48px 40px;
|
||||
background: var(--bg-card);
|
||||
border-radius: 16px;
|
||||
box-shadow: 0 4px 24px rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
.login-icon {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.login-title {
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
color: var(--el-text-color-primary);
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.login-subtitle {
|
||||
font-size: 14px;
|
||||
color: var(--el-text-color-secondary);
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
|
||||
.login-card :deep(.el-input) {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.login-btn {
|
||||
width: 100%;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.admin-header {
|
||||
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;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
+125
-104
@@ -56,21 +56,16 @@ onMounted(() => {
|
||||
onUnmounted(() => {
|
||||
clearInterval(timer)
|
||||
})
|
||||
|
||||
const statCards = [
|
||||
{label: '去重对象', key: 'dedup_object', icon: DataAnalysis, color: '#409eff'},
|
||||
{label: '上传数据格式', key: 'data_format', icon: Document, color: '#67c23a'},
|
||||
{label: '去重记录值', key: 'dedup_items_number', icon: Key, color: '#e6a23c'},
|
||||
{label: 'Redis中数据条数', key: 'cache_list_number', icon: Warning, color: '#909399'},
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="p-6 h-dvh">
|
||||
<div class="content-card h-full">
|
||||
<div class="text-center mb-8">
|
||||
<div class="page-title">Token 信息查询</div>
|
||||
<div class="header-subtitle">输入 Token 以查看去重和缓存信息</div>
|
||||
<div class="bg-white rounded-lg p-6 shadow-[0_2px_12px_rgba(0,0,0,0.08)] h-full">
|
||||
<div class="text-center mb-4">
|
||||
<div class="text-xl font-semibold text-(--el-text-color-primary) mb-5 pb-3 border-b border-(--el-border-color)">
|
||||
Token 信息查询
|
||||
</div>
|
||||
<div class="text-(--el-text-color-secondary) mt-2">输入 Token 以查看去重和缓存信息</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center mb-8">
|
||||
@@ -91,40 +86,138 @@ const statCards = [
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<AddDataDialog v-model="showAddDataDialog" :token="inputToken"/>
|
||||
|
||||
<div v-if="result" class="result-section">
|
||||
<el-button type="primary" size=""
|
||||
class=""
|
||||
@click="showAddDataDialog = true" :icon="Plus"
|
||||
<el-space direction="vertical"
|
||||
class="w-full animate-fade-in"
|
||||
v-if="result"
|
||||
>
|
||||
增加数据
|
||||
</el-button>
|
||||
<el-card class="p-6">
|
||||
<template #header>
|
||||
<el-text>Token 信息</el-text>
|
||||
<el-divider direction="vertical"/>
|
||||
<el-tag type="primary" effect="plain">{{ inputToken }}</el-tag>
|
||||
</template>
|
||||
|
||||
<div class="flex ">
|
||||
<span class="section-title">Token 信息</span>
|
||||
</div>
|
||||
|
||||
<div class="stat-cards">
|
||||
<div v-for="card in statCards" :key="card.key" class="stat-card">
|
||||
<div class="stat-icon" :style="{ background: card.color + '20', color: card.color }">
|
||||
<el-space direction="vertical">
|
||||
<el-space>
|
||||
<div
|
||||
class="flex items-center gap-4 p-5 bg-(--bg-page) rounded-xl transition-all duration-200
|
||||
hover:-translate-y-0.5 hover:shadow-[0_4px_16px_rgba(0,0,0,0.1)]
|
||||
min-w-100"
|
||||
>
|
||||
<div
|
||||
class="w-14 h-14 rounded-xl flex items-center justify-center shrink-0"
|
||||
style="background: #409eff20; color: #409eff"
|
||||
>
|
||||
<el-icon size="24">
|
||||
<component :is="card.icon"/>
|
||||
<DataAnalysis/>
|
||||
</el-icon>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<div class="stat-label">{{ card.label }}</div>
|
||||
<div class="stat-value">{{ result[card.key] || '-' }}</div>
|
||||
<div class="text-xs text-(--el-text-color-secondary) mb-1">
|
||||
去重对象
|
||||
</div>
|
||||
<div
|
||||
class="text-lg font-semibold text-(--el-text-color-primary) overflow-hidden text-ellipsis whitespace-nowrap"
|
||||
>
|
||||
{{ result['dedup_object'] || '-' }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="flex items-center gap-4 p-5 bg-(--bg-page) rounded-xl transition-all duration-200
|
||||
hover:-translate-y-0.5 hover:shadow-[0_4px_16px_rgba(0,0,0,0.1)]
|
||||
min-w-100"
|
||||
>
|
||||
<div
|
||||
class="w-14 h-14 rounded-xl flex items-center justify-center shrink-0"
|
||||
style="background: #67c23a20; color: #67c23a"
|
||||
>
|
||||
<el-icon size="24">
|
||||
<Document/>
|
||||
</el-icon>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<div class="text-xs text-(--el-text-color-secondary) mb-1">
|
||||
上传数据格式
|
||||
</div>
|
||||
<div
|
||||
class="text-lg font-semibold text-(--el-text-color-primary) overflow-hidden text-ellipsis whitespace-nowrap"
|
||||
>
|
||||
{{ result['data_format'] || '-' }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-space>
|
||||
<el-space>
|
||||
<div
|
||||
class="flex items-center gap-4 p-5 bg-(--bg-page) rounded-xl transition-all duration-200
|
||||
hover:-translate-y-0.5 hover:shadow-[0_4px_16px_rgba(0,0,0,0.1)]
|
||||
min-w-100"
|
||||
>
|
||||
<div
|
||||
class="w-14 h-14 rounded-xl flex items-center justify-center shrink-0"
|
||||
style="background: #e6a23c20; color: #e6a23c"
|
||||
>
|
||||
<el-icon size="24">
|
||||
<Key/>
|
||||
</el-icon>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<div class="text-xs text-(--el-text-color-secondary) mb-1">
|
||||
去重记录值
|
||||
</div>
|
||||
<div
|
||||
class="text-lg font-semibold text-(--el-text-color-primary) overflow-hidden text-ellipsis whitespace-nowrap"
|
||||
>
|
||||
{{ result['dedup_items_number'] || '-' }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="flex items-center gap-4 p-5 bg-(--bg-page) rounded-xl transition-all duration-200
|
||||
hover:-translate-y-0.5 hover:shadow-[0_4px_16px_rgba(0,0,0,0.1)]
|
||||
min-w-100"
|
||||
>
|
||||
<div
|
||||
class="w-14 h-14 rounded-xl flex items-center justify-center shrink-0"
|
||||
style="background: #90939920; color: #909399"
|
||||
>
|
||||
<el-icon size="24">
|
||||
<Warning/>
|
||||
</el-icon>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<div class="text-xs text-(--el-text-color-secondary) mb-1">
|
||||
Redis中数据条数
|
||||
</div>
|
||||
<div
|
||||
class="text-lg font-semibold text-(--el-text-color-primary) overflow-hidden text-ellipsis whitespace-nowrap"
|
||||
>
|
||||
{{ result['cache_list_number'] || '-' }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-space>
|
||||
</el-space>
|
||||
|
||||
<el-text v-if="lastUpdate" type="info"
|
||||
class="block w-full mt-5 text-center"
|
||||
>
|
||||
每5秒更新一次数据 最后更新: {{ lastUpdate }}
|
||||
</el-text>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<el-text>操作</el-text>
|
||||
<el-divider direction="vertical"/>
|
||||
<el-button type="primary" size=""
|
||||
class=""
|
||||
@click="showAddDataDialog = true" :icon="Plus"
|
||||
>
|
||||
添加数据
|
||||
</el-button>
|
||||
</template>
|
||||
</el-card>
|
||||
</el-space>
|
||||
|
||||
<el-space v-else direction="vertical"
|
||||
class="flex p-16"
|
||||
@@ -136,78 +229,6 @@ const statCards = [
|
||||
</el-space>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<AddDataDialog v-model="showAddDataDialog" :token="inputToken"/>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.header-subtitle {
|
||||
color: var(--el-text-color-secondary);
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.result-section {
|
||||
animation: fadeIn 0.3s ease;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
.result-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.stat-cards {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.stat-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
padding: 20px;
|
||||
background: var(--bg-page);
|
||||
border-radius: 12px;
|
||||
transition: transform 0.2s, box-shadow 0.2s;
|
||||
}
|
||||
|
||||
.stat-card:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.stat-icon {
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
border-radius: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-size: 13px;
|
||||
color: var(--el-text-color-secondary);
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.stat-value {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: var(--el-text-color-primary);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
</style>
|
||||
@@ -5,7 +5,3 @@
|
||||
<template>
|
||||
TODO
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
Reference in New Issue
Block a user