947 lines
20 KiB
Vue
947 lines
20 KiB
Vue
<template>
|
|
<div class="modern-home">
|
|
<!-- 欢迎区域 -->
|
|
<section class="welcome-section">
|
|
<div class="welcome-content">
|
|
<div class="welcome-left">
|
|
<div class="welcome-logo">
|
|
<img src="@/assets/logo.webp" alt="Logo" class="welcome-logo-image" />
|
|
<div class="logo-glow"></div>
|
|
</div>
|
|
<h1 class="welcome-title">
|
|
<span class="greeting" v-if="isLoggedIn">{{ t('home.welcome.title', { name: userName }) }}</span>
|
|
<span class="greeting" v-else>{{ t('home.welcome.title', { name: t('home.welcome.defaultName') }) }}</span>
|
|
</h1>
|
|
<p class="welcome-subtitle">
|
|
{{ t('home.welcome.greetingMessage') }}
|
|
</p>
|
|
<div class="welcome-actions">
|
|
<el-button
|
|
v-if="isLoggedIn"
|
|
type="primary"
|
|
size="large"
|
|
class="action-btn primary-btn create-btn-large"
|
|
@click="navigateToFeature({ path: `/project/new/Done` })">
|
|
{{ t('home.welcome.startCreating') }}
|
|
</el-button>
|
|
<div v-else class="guest-actions">
|
|
<el-button
|
|
type="primary"
|
|
size="large"
|
|
class="action-btn primary-btn create-btn-large"
|
|
@click="navigateToFeature({ path: '/login' })">
|
|
{{ t('home.welcome.loginToStart') }}
|
|
</el-button>
|
|
<el-button
|
|
size="large"
|
|
class="action-btn secondary-btn"
|
|
@click="navigateToFeature({ path: '/register' })">
|
|
{{ t('home.welcome.register') }}
|
|
</el-button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="welcome-right">
|
|
<div class="welcome-visual">
|
|
<div class="animated-bg">
|
|
<div class="bg-circle circle-1"></div>
|
|
<div class="bg-circle circle-2"></div>
|
|
<div class="bg-circle circle-3"></div>
|
|
<div class="bg-circle circle-4"></div>
|
|
<div class="bg-circle circle-5"></div>
|
|
</div>
|
|
<div class="floating-cards">
|
|
<div class="floating-card card-1" @click="navigateToFeature({ path: '/order-management' })">
|
|
<el-icon><Tickets /></el-icon>
|
|
<span>{{ t('home.floatingCards.orders') }}</span>
|
|
</div>
|
|
<div class="floating-card card-2" @click="navigateToFeature({ path: '/agent-management' })">
|
|
<el-icon><Cpu /></el-icon>
|
|
<span>{{ t('home.floatingCards.settings') }}</span>
|
|
</div>
|
|
<div class="floating-card card-3" @click="navigateToFeature({ path: '/creation-workspace' })">
|
|
<el-icon><Picture /></el-icon>
|
|
<span>{{ t('sidebar.projects') }}</span>
|
|
</div>
|
|
</div>
|
|
<div class="welcome-avatar">
|
|
<el-avatar :size="100" :src="userAvatar" v-if="isLoggedIn">
|
|
<el-icon size="50"><User /></el-icon>
|
|
</el-avatar>
|
|
<div v-else class="guest-avatar" @click="navigateToFeature({ path: '/login' })">
|
|
<el-icon size="50"><User /></el-icon>
|
|
<div class="guest-login-tip">{{ t('home.welcome.clickToLogin') }}</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
<!-- 统计卡片区 -->
|
|
<section class="stats-section">
|
|
<div class="stats-container">
|
|
<div
|
|
v-for="(stat, index) in statsData"
|
|
:key="stat.id"
|
|
class="stat-card"
|
|
:style="{ '--delay': index * 0.1 + 's' }"
|
|
>
|
|
<div class="stat-icon" :style="{ '--icon-color': stat.color }">
|
|
<component :is="iconComponents[stat.icon]" />
|
|
</div>
|
|
<div class="stat-content">
|
|
<div class="stat-value">
|
|
<count-up :end-val="stat.value" :duration="2" />
|
|
<span class="stat-unit">{{ stat.unit }}</span>
|
|
</div>
|
|
<div class="stat-label">{{ stat.label }}</div>
|
|
</div>
|
|
<!-- <div class="stat-trend" :class="stat.trend">
|
|
<component :is="iconComponents[stat.trendIcon]" />
|
|
<span>{{ stat.trendValue }}</span>
|
|
</div> -->
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { computed, onMounted } from 'vue'
|
|
import { useRouter } from 'vue-router'
|
|
import { useI18n } from 'vue-i18n'
|
|
import { useAuthStore } from '@/stores/auth'
|
|
import CountUp from 'vue-countup-v3'
|
|
import { ModernHome } from './index.js'
|
|
import { dateUtils } from '@deotaland/utils';
|
|
const modernHome = new ModernHome();
|
|
// 图标组件
|
|
import {
|
|
User,
|
|
Star,
|
|
Clock,
|
|
Document,
|
|
MagicStick,
|
|
ArrowUp,
|
|
ArrowDown,
|
|
Minus,
|
|
VideoPlay,
|
|
ChatDotRound,
|
|
Tickets,
|
|
Setting,
|
|
Picture,
|
|
Cpu
|
|
} from '@element-plus/icons-vue'
|
|
|
|
const { t } = useI18n()
|
|
const router = useRouter()
|
|
const authStore = useAuthStore()
|
|
|
|
// 创建图标组件映射
|
|
const iconComponents = {
|
|
MagicStick,
|
|
Star,
|
|
Clock,
|
|
Document,
|
|
ArrowUp,
|
|
ArrowDown,
|
|
Minus,
|
|
VideoPlay,
|
|
ChatDotRound,
|
|
Tickets,
|
|
Setting,
|
|
Picture,
|
|
Cpu
|
|
}
|
|
|
|
// 响应式数据 - 使用计算属性来支持国际化
|
|
const statsData = computed(() => [
|
|
// {
|
|
// id: 'creations',
|
|
// value: homeData.value.agent_count,
|
|
// unit: '',
|
|
// label: t('home.stats.creations'),
|
|
// icon: 'MagicStick',
|
|
// color: '#6B46C1',
|
|
// trend: 'up',
|
|
// trendIcon: 'ArrowUp',
|
|
// trendValue: '12%'
|
|
// },
|
|
// {
|
|
// id: 'credits',
|
|
// value: 2840,
|
|
// unit: '',
|
|
// label: t('home.stats.credits'),
|
|
// icon: 'Star',
|
|
// color: '#F59E0B',
|
|
// trend: 'up',
|
|
// trendIcon: 'ArrowUp',
|
|
// trendValue: '5%'
|
|
// },
|
|
{
|
|
id: 'hours',
|
|
value: dateUtils.secondsToTime(homeData.value.total_duration_seconds),
|
|
unit: 'm',
|
|
label: t('home.stats.hours'),
|
|
icon: 'Clock',
|
|
color: '#10B981',
|
|
trend: 'down',
|
|
trendIcon: 'ArrowDown',
|
|
trendValue: '8%'
|
|
},
|
|
{
|
|
id: 'projects',
|
|
value: homeData.value.project_count,
|
|
unit: '',
|
|
label: t('home.stats.projects'),
|
|
icon: 'Document',
|
|
color: '#3B82F6',
|
|
trend: 'stable',
|
|
trendIcon: 'Minus',
|
|
trendValue: '0%'
|
|
}
|
|
])
|
|
|
|
|
|
// 计算属性
|
|
const currentUser = computed(() => authStore.user)
|
|
const userName = computed(() => currentUser.value?.nickname || '')
|
|
const userAvatar = computed(() => currentUser.value?.avatarUrl || '')
|
|
const isLoggedIn = computed(() => authStore.token)
|
|
|
|
// 方法
|
|
const navigateToFeature = (feature) => {
|
|
router.push(feature.path)
|
|
}
|
|
const homeData = ref({
|
|
total_duration_seconds: 0,
|
|
project_count: 0,
|
|
agent_count: 0,
|
|
});
|
|
const init = () => {
|
|
modernHome.getUserStatistics().then(res => {
|
|
if (res.code === 0) {
|
|
homeData.value = res.data;
|
|
|
|
}
|
|
});
|
|
// orderManagement.orderStatistics().then(res => {
|
|
// if (res.code === 0) {
|
|
|
|
// }
|
|
// });
|
|
}
|
|
onMounted(() => {
|
|
let token = window.localStorage.getItem('token');
|
|
token&&init();
|
|
})
|
|
</script>
|
|
|
|
<style scoped>
|
|
.modern-home {
|
|
padding: 24px;
|
|
background: var(--bg-color, #f9fafb);
|
|
/* min-height: 100vh; */
|
|
}
|
|
|
|
/* 欢迎区域 */
|
|
.welcome-section {
|
|
position: relative;
|
|
padding: 80px 24px;
|
|
background: linear-gradient(135deg,
|
|
#6B46C1 0%,
|
|
#8B5CF6 25%,
|
|
#A78BFA 50%);
|
|
background-size: 100% 100%;
|
|
overflow: hidden;
|
|
border-radius: 24px;
|
|
box-shadow:
|
|
0 20px 60px rgba(107, 70, 193, 0.3),
|
|
0 8px 24px rgba(107, 70, 193, 0.2),
|
|
0 4px 12px rgba(107, 70, 193, 0.1),
|
|
inset 0 1px 0 rgba(255, 255, 255, 0.2);
|
|
border: 1px solid rgba(255, 255, 255, 0.1);
|
|
backdrop-filter: blur(12px);
|
|
transition: all 0.4s cubic-bezier(0.25, 0.8, 0.25, 1);
|
|
}
|
|
|
|
.welcome-section:hover {
|
|
transform: translateY(-4px);
|
|
box-shadow:
|
|
0 32px 80px rgba(107, 70, 193, 0.4),
|
|
0 12px 32px rgba(107, 70, 193, 0.25),
|
|
0 6px 16px rgba(107, 70, 193, 0.15),
|
|
inset 0 1px 0 rgba(255, 255, 255, 0.3);
|
|
}
|
|
|
|
.welcome-section::before {
|
|
content: '';
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
background:
|
|
radial-gradient(circle at 25% 25%, rgba(255, 255, 255, 0.1) 0%, transparent 50%),
|
|
radial-gradient(circle at 75% 75%, rgba(255, 255, 255, 0.05) 0%, transparent 50%),
|
|
radial-gradient(circle at 40% 60%, rgba(255, 255, 255, 0.05) 0%, transparent 50%);
|
|
}
|
|
|
|
/* 暗色主题支持 */
|
|
.dark .welcome-section {
|
|
background: linear-gradient(135deg,
|
|
#1a1625 0%,
|
|
#2d1b3d 25%,
|
|
#3730a3 50%,
|
|
#3730a3 75%,
|
|
#1e1b4b 100%);
|
|
box-shadow:
|
|
0 20px 60px rgba(0, 0, 0, 0.6),
|
|
0 8px 24px rgba(0, 0, 0, 0.4),
|
|
0 4px 12px rgba(0, 0, 0, 0.3),
|
|
inset 0 1px 0 rgba(255, 255, 255, 0.05);
|
|
border-color: rgba(255, 255, 255, 0.05);
|
|
}
|
|
|
|
.dark .welcome-section:hover {
|
|
box-shadow:
|
|
0 32px 80px rgba(0, 0, 0, 0.7),
|
|
0 12px 32px rgba(0, 0, 0, 0.5),
|
|
0 6px 16px rgba(0, 0, 0, 0.4),
|
|
inset 0 1px 0 rgba(255, 255, 255, 0.08);
|
|
}
|
|
|
|
.welcome-content {
|
|
max-width: 1200px;
|
|
margin: 0 auto;
|
|
display: grid;
|
|
grid-template-columns: 1fr 1fr;
|
|
gap: 60px;
|
|
align-items: center;
|
|
position: relative;
|
|
z-index: 1;
|
|
}
|
|
|
|
.welcome-left {
|
|
max-width: 500px;
|
|
}
|
|
|
|
.welcome-logo {
|
|
position: relative;
|
|
width: 120px;
|
|
height: 120px;
|
|
margin-bottom: 32px;
|
|
animation: logoFloat 6s ease-in-out infinite;
|
|
}
|
|
|
|
.welcome-logo-image {
|
|
width: 100%;
|
|
height: 100%;
|
|
object-fit: contain;
|
|
border-radius:50%;
|
|
position: relative;
|
|
z-index: 2;
|
|
}
|
|
|
|
.logo-glow {
|
|
position: absolute;
|
|
top: -20px;
|
|
left: -20px;
|
|
right: -20px;
|
|
bottom: -20px;
|
|
background: rgba(255, 255, 255, 0.2);
|
|
border-radius: 50%;
|
|
animation: glowPulse 3s ease-in-out infinite;
|
|
z-index: 1;
|
|
}
|
|
|
|
.welcome-title {
|
|
font-size: 2.5rem;
|
|
font-weight: 700;
|
|
margin: 0 0 16px 0;
|
|
line-height: 1.2;
|
|
/* 初始隐藏状态 */
|
|
opacity: 0;
|
|
transform: translateY(30px);
|
|
animation: fadeInUp 0.8s ease-out both;
|
|
color: #ffffff;
|
|
}
|
|
|
|
.greeting {
|
|
background: linear-gradient(45deg, #ffffff, #F3F4F6);
|
|
-webkit-background-clip: text;
|
|
-webkit-text-fill-color: transparent;
|
|
background-clip: text;
|
|
}
|
|
|
|
.welcome-subtitle {
|
|
font-size: 1.125rem;
|
|
opacity: 0.9;
|
|
margin: 0 0 32px 0;
|
|
line-height: 1.6;
|
|
/* 初始隐藏状态 */
|
|
opacity: 0;
|
|
transform: translateY(30px);
|
|
animation: fadeInUp 0.8s ease-out 0.2s both;
|
|
color: rgba(255, 255, 255, 0.9);
|
|
}
|
|
|
|
.welcome-actions {
|
|
display: flex;
|
|
gap: 16px;
|
|
flex-wrap: wrap;
|
|
/* 初始隐藏状态 */
|
|
opacity: 0;
|
|
transform: translateY(30px);
|
|
animation: fadeInUp 0.8s ease-out 0.4s both;
|
|
}
|
|
|
|
.action-btn {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
padding: 12px 24px;
|
|
border-radius: 12px;
|
|
font-weight: 600;
|
|
transition: all 0.3s ease;
|
|
position: relative;
|
|
overflow: hidden;
|
|
/* 拆件动画 */
|
|
opacity: 0;
|
|
transform: translateY(40px);
|
|
animation: buttonFloatIn 0.6s ease-out 0.2s forwards;
|
|
}
|
|
|
|
.action-btn::before {
|
|
content: '';
|
|
position: absolute;
|
|
top: 0;
|
|
left: -100%;
|
|
width: 100%;
|
|
height: 100%;
|
|
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
|
|
transition: left 0.5s;
|
|
}
|
|
|
|
.action-btn:hover::before {
|
|
left: 100%;
|
|
}
|
|
|
|
.primary-btn {
|
|
background: rgba(255, 255, 255, 0.2);
|
|
border: 2px solid rgba(255, 255, 255, 0.3);
|
|
color: #ffffff;
|
|
backdrop-filter: blur(10px);
|
|
}
|
|
|
|
.primary-btn:hover {
|
|
background: rgba(255, 255, 255, 0.3);
|
|
border-color: rgba(255, 255, 255, 0.5);
|
|
transform: translateY(-2px);
|
|
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
|
|
}
|
|
|
|
.create-btn-large {
|
|
font-size: 18px !important;
|
|
padding: 16px 32px !important;
|
|
min-width: 200px !important;
|
|
height: 56px !important;
|
|
}
|
|
|
|
.create-btn-large:hover {
|
|
transform: translateY(-3px) scale(1.02) !important;
|
|
box-shadow: 0 15px 40px rgba(0, 0, 0, 0.25) !important;
|
|
}
|
|
|
|
.secondary-btn {
|
|
background: transparent;
|
|
border: 2px solid rgba(255, 255, 255, 0.3);
|
|
color: #ffffff;
|
|
}
|
|
|
|
.secondary-btn:hover {
|
|
background: rgba(255, 255, 255, 0.1);
|
|
border-color: rgba(255, 255, 255, 0.5);
|
|
transform: translateY(-2px);
|
|
}
|
|
|
|
.welcome-right {
|
|
position: relative;
|
|
}
|
|
|
|
.welcome-visual {
|
|
position: relative;
|
|
width: 100%;
|
|
height: 400px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.animated-bg {
|
|
position: absolute;
|
|
width: 100%;
|
|
height: 100%;
|
|
top: 0;
|
|
left: 0;
|
|
}
|
|
|
|
.bg-circle {
|
|
position: absolute;
|
|
border-radius: 50%;
|
|
background: rgba(255, 255, 255, 0.1);
|
|
backdrop-filter: blur(10px);
|
|
border: 1px solid rgba(255, 255, 255, 0.2);
|
|
/* 拆件动画 */
|
|
opacity: 0;
|
|
transform: translateY(30px) scale(0.8);
|
|
animation: circleFloatIn 0.8s ease-out forwards;
|
|
}
|
|
|
|
.circle-1 {
|
|
width: 120px;
|
|
height: 120px;
|
|
top: 10%;
|
|
left: 20%;
|
|
animation: circleFloatIn 0.8s ease-out 0.1s forwards, circleFloat1 8s ease-in-out infinite 0.8s;
|
|
}
|
|
|
|
.circle-2 {
|
|
width: 80px;
|
|
height: 80px;
|
|
top: 60%;
|
|
left: 70%;
|
|
animation: circleFloatIn 0.8s ease-out 0.3s forwards, circleFloat2 10s ease-in-out infinite 1.0s;
|
|
}
|
|
|
|
.circle-3 {
|
|
width: 60px;
|
|
height: 60px;
|
|
top: 30%;
|
|
left: 10%;
|
|
animation: circleFloatIn 0.8s ease-out 0.5s forwards, circleFloat3 12s ease-in-out infinite 1.2s;
|
|
}
|
|
|
|
.circle-4 {
|
|
width: 100px;
|
|
height: 100px;
|
|
top: 70%;
|
|
left: 20%;
|
|
animation: circleFloatIn 0.8s ease-out 0.7s forwards, circleFloat4 9s ease-in-out infinite 1.4s;
|
|
}
|
|
|
|
.circle-5 {
|
|
width: 40px;
|
|
height: 40px;
|
|
top: 50%;
|
|
left: 60%;
|
|
animation: circleFloatIn 0.8s ease-out 0.9s forwards, circleFloat5 7s ease-in-out infinite 1.6s;
|
|
}
|
|
|
|
.floating-cards {
|
|
position: relative;
|
|
z-index: 3;
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
|
|
.floating-card {
|
|
position: absolute;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
padding: 12px 16px;
|
|
background: rgba(255, 255, 255, 0.15);
|
|
backdrop-filter: blur(20px);
|
|
border: 1px solid rgba(255, 255, 255, 0.2);
|
|
border-radius: 12px;
|
|
color: white;
|
|
font-size: 14px;
|
|
font-weight: 500;
|
|
animation: cardFloat 6s ease-in-out infinite;
|
|
cursor: pointer;
|
|
transition: all 0.3s ease;
|
|
/* 初始隐藏状态 */
|
|
opacity: 0;
|
|
transform: translateY(30px);
|
|
}
|
|
|
|
.floating-card:hover {
|
|
background: rgba(255, 255, 255, 0.25);
|
|
border-color: rgba(255, 255, 255, 0.4);
|
|
transform: translateY(-8px) scale(1.05);
|
|
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.2);
|
|
}
|
|
|
|
.floating-card:active {
|
|
transform: translateY(-4px) scale(1.02);
|
|
transition: all 0.15s ease;
|
|
}
|
|
|
|
.card-1 {
|
|
top: 20%;
|
|
left: 10%;
|
|
animation: cardFloatIn 0.6s ease-out 0.4s forwards, cardFloat 6s ease-in-out infinite 1.0s;
|
|
}
|
|
|
|
.card-2 {
|
|
top: 60%;
|
|
right: 15%;
|
|
animation: cardFloatIn 0.6s ease-out 0.6s forwards, cardFloat 6s ease-in-out infinite 1.2s;
|
|
}
|
|
|
|
.card-3 {
|
|
bottom: 30%;
|
|
left: 20%;
|
|
animation: cardFloatIn 0.6s ease-out 0.8s forwards, cardFloat 6s ease-in-out infinite 1.4s;
|
|
}
|
|
|
|
.welcome-avatar {
|
|
position: relative;
|
|
z-index: 4;
|
|
/* 初始隐藏状态 */
|
|
opacity: 0;
|
|
transform: translateY(30px);
|
|
animation: fadeInUp 0.8s ease-out 1.0s both;
|
|
}
|
|
|
|
.guest-avatar {
|
|
width: 100px;
|
|
height: 100px;
|
|
border-radius: 50%;
|
|
background: rgba(255, 255, 255, 0.2);
|
|
backdrop-filter: blur(10px);
|
|
border: 2px solid rgba(255, 255, 255, 0.3);
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
cursor: pointer;
|
|
transition: all 0.3s ease;
|
|
position: relative;
|
|
color: rgba(255, 255, 255, 0.8);
|
|
}
|
|
|
|
.guest-avatar:hover {
|
|
background: rgba(255, 255, 255, 0.3);
|
|
border-color: rgba(255, 255, 255, 0.5);
|
|
transform: scale(1.05);
|
|
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
|
|
}
|
|
|
|
.guest-login-tip {
|
|
font-size: 10px;
|
|
color: rgba(255, 255, 255, 0.8);
|
|
margin-top: 4px;
|
|
text-align: center;
|
|
line-height: 1.2;
|
|
}
|
|
|
|
.guest-actions {
|
|
display: flex;
|
|
gap: 16px;
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
/* 响应式设计 */
|
|
@media (max-width: 768px) {
|
|
.welcome-content {
|
|
grid-template-columns: 1fr;
|
|
gap: 40px;
|
|
text-align: center;
|
|
}
|
|
|
|
.welcome-title {
|
|
font-size: 2rem;
|
|
}
|
|
|
|
.welcome-actions {
|
|
justify-content: center;
|
|
}
|
|
|
|
.action-btn {
|
|
flex: 1;
|
|
min-width: 120px;
|
|
}
|
|
|
|
.welcome-visual {
|
|
height: 300px;
|
|
}
|
|
}
|
|
|
|
/* 统计卡片区 */
|
|
.stats-section {
|
|
padding: 40px 0px;
|
|
width: 100%;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
.stats-container {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
|
gap: 24px;
|
|
}
|
|
|
|
.stat-card {
|
|
background: white;
|
|
border-radius: 16px;
|
|
padding: 24px;
|
|
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.05);
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 16px;
|
|
position: relative;
|
|
overflow: hidden;
|
|
transition: all 0.3s ease;
|
|
animation: fadeInUp 0.6s ease-out both;
|
|
animation-delay: var(--delay);
|
|
}
|
|
|
|
.stat-card:hover {
|
|
transform: translateY(-5px);
|
|
box-shadow: 0 12px 30px rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
.stat-card::before {
|
|
content: '';
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
height: 4px;
|
|
background: var(--icon-color);
|
|
}
|
|
|
|
.stat-icon {
|
|
width: 60px;
|
|
height: 60px;
|
|
border-radius: 12px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
background: rgba(var(--icon-color), 0.1);
|
|
color: var(--icon-color);
|
|
font-size: 24px;
|
|
}
|
|
|
|
.stat-content {
|
|
flex: 1;
|
|
}
|
|
|
|
.stat-value {
|
|
font-size: 2rem;
|
|
font-weight: 700;
|
|
color: var(--text-primary, #1f2937);
|
|
margin-bottom: 4px;
|
|
display: flex;
|
|
align-items: baseline;
|
|
gap: 4px;
|
|
}
|
|
|
|
.stat-unit {
|
|
font-size: 1rem;
|
|
font-weight: 400;
|
|
color: var(--text-secondary, #6b7280);
|
|
}
|
|
|
|
.stat-label {
|
|
font-size: 0.875rem;
|
|
color: var(--text-secondary, #6b7280);
|
|
}
|
|
|
|
.stat-trend {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: flex-end;
|
|
gap: 4px;
|
|
font-size: 0.875rem;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.stat-trend.up {
|
|
color: #10B981;
|
|
}
|
|
|
|
.stat-trend.down {
|
|
color: #EF4444;
|
|
}
|
|
|
|
.stat-trend.stable {
|
|
color: #6B7280;
|
|
}
|
|
|
|
|
|
|
|
/* 动画 */
|
|
@keyframes fadeInUp {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(30px);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
|
|
@keyframes circleFloatIn {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(30px) scale(0.8);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateY(0) scale(1);
|
|
}
|
|
}
|
|
|
|
@keyframes buttonFloatIn {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(40px);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
|
|
@keyframes cardFloatIn {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(30px);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
|
|
@keyframes float {
|
|
0%, 100% {
|
|
transform: translateY(0);
|
|
}
|
|
50% {
|
|
transform: translateY(-15px);
|
|
}
|
|
}
|
|
|
|
@keyframes gradientShift {
|
|
0% {
|
|
background-position: 0% 50%;
|
|
}
|
|
25% {
|
|
background-position: 100% 25%;
|
|
}
|
|
50% {
|
|
background-position: 100% 100%;
|
|
}
|
|
75% {
|
|
background-position: 0% 75%;
|
|
}
|
|
100% {
|
|
background-position: 0% 50%;
|
|
}
|
|
}
|
|
|
|
@keyframes backgroundFloat {
|
|
0%, 100% {
|
|
transform: translate(0, 0) rotate(0deg);
|
|
opacity: 0.8;
|
|
}
|
|
25% {
|
|
transform: translate(10px, -15px) rotate(2deg);
|
|
opacity: 1;
|
|
}
|
|
50% {
|
|
transform: translate(-5px, 10px) rotate(-1deg);
|
|
opacity: 0.9;
|
|
}
|
|
75% {
|
|
transform: translate(15px, 5px) rotate(1deg);
|
|
opacity: 0.95;
|
|
}
|
|
}
|
|
|
|
@keyframes backgroundPulse {
|
|
0%, 100% {
|
|
transform: scale(1) rotate(0deg);
|
|
opacity: 0.6;
|
|
}
|
|
33% {
|
|
transform: scale(1.05) rotate(1deg);
|
|
opacity: 0.8;
|
|
}
|
|
66% {
|
|
transform: scale(0.95) rotate(-1deg);
|
|
opacity: 0.7;
|
|
}
|
|
}
|
|
|
|
@keyframes logoFloat {
|
|
0%, 100% {
|
|
transform: translateY(0px);
|
|
}
|
|
50% {
|
|
transform: translateY(-8px);
|
|
}
|
|
}
|
|
|
|
@keyframes glowPulse {
|
|
0%, 100% {
|
|
transform: scale(1);
|
|
opacity: 0.3;
|
|
}
|
|
50% {
|
|
transform: scale(1.1);
|
|
opacity: 0.6;
|
|
}
|
|
}
|
|
|
|
/* 深色主题 */
|
|
.dark .modern-home {
|
|
--bg-color: #111827;
|
|
--text-primary: #f9fafb;
|
|
--text-secondary: #d1d5db;
|
|
--border-color: #374151;
|
|
}
|
|
|
|
.dark .stat-card {
|
|
background: #1f2937;
|
|
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);
|
|
}
|
|
|
|
.dark .stat-card:hover {
|
|
box-shadow: 0 12px 30px rgba(0, 0, 0, 0.3);
|
|
}
|
|
|
|
/* 响应式设计 */
|
|
@media (max-width: 768px) {
|
|
.welcome-content {
|
|
grid-template-columns: 1fr;
|
|
gap: 40px;
|
|
text-align: center;
|
|
}
|
|
|
|
.welcome-title {
|
|
font-size: 2rem;
|
|
}
|
|
|
|
.welcome-actions {
|
|
justify-content: center;
|
|
}
|
|
|
|
.action-btn {
|
|
flex: 1;
|
|
min-width: 120px;
|
|
}
|
|
|
|
.welcome-visual {
|
|
height: 300px;
|
|
}
|
|
|
|
.stats-container {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
}
|
|
</style> |