Files
yunzerwebsiteallinone/uniapp/pages/dashboard/dashboard.vue
T
2026-07-15 09:08:52 +08:00

383 lines
7.9 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="dashboard-container">
<!-- 顶部欢迎区域 -->
<view class="header">
<view class="user-info">
<view class="avatar">
<text class="avatar-text"></text>
</view>
<view class="info">
<text class="greeting">{{ greeting }}{{ userName }}</text>
<text class="date">{{ currentDate }}</text>
</view>
</view>
<view class="notice-icon" @click="goToNotice">
<text class="iconfont">🔔</text>
<view class="badge" v-if="unreadCount > 0">
<text>{{ unreadCount > 99 ? '99+' : unreadCount }}</text>
</view>
</view>
</view>
<!-- 数据概览卡片 -->
<view class="section">
<view class="section-title">
<text>数据概览</text>
</view>
<view class="stats-grid">
<view class="stat-card" v-for="(item, index) in statsData" :key="index">
<text class="stat-value" :style="{ color: item.color }">{{ item.value }}</text>
<text class="stat-label">{{ item.label }}</text>
<view class="trend" :class="item.trend > 0 ? 'up' : 'down'">
<text>{{ item.trend > 0 ? '↑' : '↓' }} {{ Math.abs(item.trend) }}%</text>
</view>
</view>
</view>
</view>
<!-- 快捷操作 -->
<view class="section">
<view class="section-title">
<text>快捷操作</text>
</view>
<view class="quick-actions">
<view class="action-item" v-for="(action, index) in quickActions" :key="index" @click="handleAction(action)">
<view class="action-icon" :style="{ backgroundColor: action.bgColor }">
<text>{{ action.icon }}</text>
</view>
<text class="action-name">{{ action.name }}</text>
</view>
</view>
</view>
<!-- 最近动态 -->
<view class="section">
<view class="section-title-row">
<text class="section-title">最近动态</text>
<text class="more" @click="viewMore">查看更多 ></text>
</view>
<view class="activity-list">
<view class="activity-item" v-for="(item, index) in recentActivities" :key="index">
<view class="activity-dot" :style="{ backgroundColor: item.color }"></view>
<view class="activity-content">
<text class="activity-title">{{ item.title }}</text>
<text class="activity-time">{{ item.time }}</text>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
userName: '用户',
unreadCount: 3,
statsData: [
{ label: '今日访问', value: '1,234', color: '#1989fa', trend: 12.5 },
{ label: '总用户数', value: '5,678', color: '#07c160', trend: 8.3 },
{ label: '订单数量', value: '892', color: '#fa9d3b', trend: -2.1 },
{ label: '收入金额', value: '¥12.5w', color: '#ff6b6b', trend: 15.7 }
],
quickActions: [
{ name: '数据报表', icon: '📊', bgColor: '#e8f4fd', path: '' },
{ name: '内容管理', icon: '📝', bgColor: '#e8faef', path: '' },
{ name: '用户管理', icon: '👥', bgColor: '#fef3e8', path: '' },
{ name: '系统设置', icon: '⚙️', bgColor: '#fce8ec', path: '' }
],
recentActivities: [
{ title: '新用户 张三 完成注册', time: '10分钟前', color: '#1989fa' },
{ title: '订单 #20240115001 已完成', time: '30分钟前', color: '#07c160' },
{ title: '系统已完成自动备份', time: '1小时前', color: '#fa9d3b' },
{ title: '内容《新手指南》已发布', time: '2小时前', color: '#ff6b6b' }
]
}
},
computed: {
greeting() {
const hour = new Date().getHours()
if (hour < 6) return '凌晨好'
if (hour < 9) return '早上好'
if (hour < 12) return '上午好'
if (hour < 14) return '中午好'
if (hour < 17) return '下午好'
if (hour < 19) return '傍晚好'
return '晚上好'
},
currentDate() {
const now = new Date()
const weekDays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']
const month = now.getMonth() + 1
const day = now.getDate()
const weekDay = weekDays[now.getDay()]
return `${month}${day}${weekDay}`
}
},
onShow() {
this.checkLoginStatus()
},
methods: {
checkLoginStatus() {
const isLoggedIn = uni.getStorageSync('isLoggedIn')
if (!isLoggedIn) {
uni.reLaunch({
url: '/pages/login/login'
})
} else {
const userInfo = uni.getStorageSync('userInfo')
if (userInfo && userInfo.phone) {
this.userName = userInfo.phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2')
}
}
},
goToNotice() {
uni.showToast({ title: '消息中心开发中', icon: 'none' })
},
handleAction(action) {
uni.showToast({ title: action.name + ' 功能开发中', icon: 'none' })
},
viewMore() {
uni.showToast({ title: '查看更多动态', icon: 'none' })
}
}
}
</script>
<style scoped>
.dashboard-container {
min-height: 100vh;
background-color: #f5f5f5;
padding-bottom: 32rpx;
}
.header {
background: linear-gradient(135deg, #1989fa 0%, #0d7ed9 100%);
padding: 32rpx 32rpx 48rpx;
display: flex;
justify-content: space-between;
align-items: center;
}
.user-info {
display: flex;
align-items: center;
}
.avatar {
width: 96rpx;
height: 96rpx;
border-radius: 50%;
background-color: rgba(255, 255, 255, 0.25);
display: flex;
align-items: center;
justify-content: center;
margin-right: 24rpx;
}
.avatar-text {
font-size: 36rpx;
color: #fff;
font-weight: bold;
}
.info {
display: flex;
flex-direction: column;
}
.greeting {
font-size: 34rpx;
color: #fff;
font-weight: 500;
margin-bottom: 6rpx;
}
.date {
font-size: 24rpx;
color: rgba(255, 255, 255, 0.8);
}
.notice-icon {
position: relative;
width: 64rpx;
height: 64rpx;
display: flex;
align-items: center;
justify-content: center;
}
.iconfont {
font-size: 40rpx;
}
.badge {
position: absolute;
top: 0;
right: 0;
min-width: 32rpx;
height: 32rpx;
background-color: #ff4d4f;
border-radius: 16rpx;
display: flex;
align-items: center;
justify-content: center;
padding: 0 8rpx;
}
.badge text {
font-size: 20rpx;
color: #fff;
}
.section {
margin: 24rpx 24rpx 0;
background-color: #fff;
border-radius: 20rpx;
padding: 32rpx;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.04);
}
.section-title {
font-size: 32rpx;
font-weight: 600;
color: #333;
margin-bottom: 28rpx;
}
.section-title-row {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 28rpx;
}
.section-title-row .section-title {
margin-bottom: 0;
}
.more {
font-size: 26rpx;
color: #999;
}
.stats-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 24rpx;
}
.stat-card {
background-color: #fafafa;
border-radius: 16rpx;
padding: 28rpx 24rpx;
}
.stat-value {
font-size: 44rpx;
font-weight: bold;
display: block;
margin-bottom: 8rpx;
}
.stat-label {
font-size: 26rpx;
color: #666;
display: block;
margin-bottom: 12rpx;
}
.trend {
display: inline-block;
font-size: 22rpx;
padding: 4rpx 12rpx;
border-radius: 6rpx;
}
.trend.up {
color: #07c160;
background-color: rgba(7, 193, 96, 0.1);
}
.trend.down {
color: #ff4d4f;
background-color: rgba(255, 77, 79, 0.1);
}
.quick-actions {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 24rpx;
}
.action-item {
display: flex;
flex-direction: column;
align-items: center;
}
.action-icon {
width: 100rpx;
height: 100rpx;
border-radius: 24rpx;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 12rpx;
}
.action-icon text {
font-size: 44rpx;
}
.action-name {
font-size: 24rpx;
color: #666;
}
.activity-list {
display: flex;
flex-direction: column;
}
.activity-item {
display: flex;
align-items: flex-start;
padding: 20rpx 0;
border-bottom: 1rpx solid #f5f5f5;
}
.activity-item:last-child {
border-bottom: none;
}
.activity-dot {
width: 16rpx;
height: 16rpx;
border-radius: 50%;
margin-top: 12rpx;
margin-right: 20rpx;
flex-shrink: 0;
}
.activity-content {
flex: 1;
display: flex;
justify-content: space-between;
align-items: center;
}
.activity-title {
font-size: 28rpx;
color: #333;
}
.activity-time {
font-size: 24rpx;
color: #999;
flex-shrink: 0;
margin-left: 24rpx;
}
</style>