Files
akmon/pages/mall/admin/index.uvue
2026-01-20 08:04:15 +08:00

848 lines
19 KiB
Plaintext

<!-- 后台管理端首页 - UTS Android 兼容 -->
<template>
<view class="admin-container">
<!-- 头部导航 -->
<view class="header">
<view class="header-left">
<text class="app-title">商城管理后台</text>
<text class="welcome-text">欢迎回来,{{ adminInfo.nickname }}</text>
</view>
<view class="header-right">
<text class="notification-btn" @click="goToNotifications">🔔</text>
<text class="profile-btn" @click="goToProfile">👤</text>
</view>
</view>
<!-- 核心指标概览 -->
<view class="metrics-section">
<text class="section-title">核心指标</text>
<view class="metrics-grid">
<view class="metric-card">
<text class="metric-value">¥{{ platformStats.total_gmv }}</text>
<text class="metric-label">总GMV</text>
<text class="metric-change positive">+{{ platformStats.gmv_growth }}%</text>
</view>
<view class="metric-card">
<text class="metric-value">{{ platformStats.total_orders }}</text>
<text class="metric-label">总订单数</text>
<text class="metric-change positive">+{{ platformStats.order_growth }}%</text>
</view>
<view class="metric-card">
<text class="metric-value">{{ platformStats.total_users }}</text>
<text class="metric-label">注册用户</text>
<text class="metric-change positive">+{{ platformStats.user_growth }}%</text>
</view>
<view class="metric-card">
<text class="metric-value">{{ platformStats.total_merchants }}</text>
<text class="metric-label">入驻商家</text>
<text class="metric-change positive">+{{ platformStats.merchant_growth }}%</text>
</view>
</view>
</view>
<!-- 今日数据 -->
<view class="today-section">
<text class="section-title">今日数据</text>
<view class="today-grid">
<view class="today-item">
<text class="today-value">¥{{ todayStats.sales }}</text>
<text class="today-label">销售额</text>
</view>
<view class="today-item">
<text class="today-value">{{ todayStats.orders }}</text>
<text class="today-label">订单数</text>
</view>
<view class="today-item">
<text class="today-value">{{ todayStats.new_users }}</text>
<text class="today-label">新增用户</text>
</view>
<view class="today-item">
<text class="today-value">{{ todayStats.active_users }}</text>
<text class="today-label">活跃用户</text>
</view>
</view>
</view>
<!-- 待处理事项 -->
<view class="pending-section">
<text class="section-title">待处理事项</text>
<view class="pending-list">
<view class="pending-item urgent" @click="goToMerchantReview">
<text class="pending-icon">🏪</text>
<view class="pending-content">
<text class="pending-title">商家入驻审核</text>
<text class="pending-subtitle">{{ pendingCounts.merchant_review }}个商家待审核</text>
</view>
<text class="pending-count">{{ pendingCounts.merchant_review }}</text>
</view>
<view class="pending-item" @click="goToProductReview">
<text class="pending-icon">📦</text>
<view class="pending-content">
<text class="pending-title">商品审核</text>
<text class="pending-subtitle">{{ pendingCounts.product_review }}个商品待审核</text>
</view>
<text class="pending-count">{{ pendingCounts.product_review }}</text>
</view>
<view class="pending-item" @click="goToRefundReview">
<text class="pending-icon">💰</text>
<view class="pending-content">
<text class="pending-title">退款处理</text>
<text class="pending-subtitle">{{ pendingCounts.refund_review }}个退款申请</text>
</view>
<text class="pending-count">{{ pendingCounts.refund_review }}</text>
</view>
<view class="pending-item" @click="goToComplaints">
<text class="pending-icon">⚠️</text>
<view class="pending-content">
<text class="pending-title">投诉处理</text>
<text class="pending-subtitle">{{ pendingCounts.complaints }}个投诉待处理</text>
</view>
<text class="pending-count">{{ pendingCounts.complaints }}</text>
</view>
</view>
</view>
<!-- 实时监控 -->
<view class="monitor-section">
<text class="section-title">实时监控</text>
<view class="monitor-grid">
<view class="monitor-card">
<text class="monitor-title">在线用户</text>
<text class="monitor-value">{{ realTimeStats.online_users }}</text>
<text class="monitor-unit">人</text>
</view>
<view class="monitor-card">
<text class="monitor-title">活跃配送员</text>
<text class="monitor-value">{{ realTimeStats.active_drivers }}</text>
<text class="monitor-unit">人</text>
</view>
<view class="monitor-card">
<text class="monitor-title">配送中订单</text>
<text class="monitor-value">{{ realTimeStats.delivering_orders }}</text>
<text class="monitor-unit">单</text>
</view>
<view class="monitor-card">
<text class="monitor-title">系统负载</text>
<text class="monitor-value">{{ realTimeStats.system_load }}</text>
<text class="monitor-unit">%</text>
</view>
</view>
</view>
<!-- 快捷管理功能 -->
<view class="shortcuts-section">
<text class="section-title">快捷管理</text>
<view class="shortcuts-grid">
<view class="shortcut-item" @click="goToUserManagement">
<text class="shortcut-icon">👥</text>
<text class="shortcut-text">用户管理</text>
</view>
<view class="shortcut-item" @click="goToMerchantManagement">
<text class="shortcut-icon">🏪</text>
<text class="shortcut-text">商家管理</text>
</view>
<view class="shortcut-item" @click="goToProductManagement">
<text class="shortcut-icon">📦</text>
<text class="shortcut-text">商品管理</text>
</view>
<view class="shortcut-item" @click="goToOrderManagement">
<text class="shortcut-icon">📋</text>
<text class="shortcut-text">订单管理</text>
</view>
<view class="shortcut-item" @click="goToCouponManagement">
<text class="shortcut-icon">🎫</text>
<text class="shortcut-text">优惠券管理</text>
</view>
<view class="shortcut-item" @click="goToDeliveryManagement">
<text class="shortcut-icon">🚚</text>
<text class="shortcut-text">配送管理</text>
</view>
<view class="shortcut-item" @click="goToFinanceManagement">
<text class="shortcut-icon">💳</text>
<text class="shortcut-text">财务管理</text>
</view>
<view class="shortcut-item" @click="goToSystemSettings">
<text class="shortcut-icon">⚙️</text>
<text class="shortcut-text">系统设置</text>
</view>
<view class="shortcut-item" @click="goToAdminUserSubscriptions">
<text class="shortcut-icon">📑</text>
<text class="shortcut-text">用户订阅</text>
</view>
<view class="shortcut-item" @click="goToSubscriptionPlans">
<text class="shortcut-icon">🧾</text>
<text class="shortcut-text">订阅方案</text>
</view>
</view>
</view>
<!-- 最新动态 -->
<view class="activities-section">
<view class="section-header">
<text class="section-title">最新动态</text>
<text class="section-more" @click="goToActivityLog">查看全部</text>
</view>
<view class="activities-list">
<view v-for="activity in recentActivities" :key="activity.id" class="activity-item">
<text class="activity-icon">{{ getActivityIcon(activity.type) }}</text>
<view class="activity-content">
<text class="activity-text">{{ activity.description }}</text>
<text class="activity-time">{{ formatTime(activity.created_at) }}</text>
</view>
</view>
</view>
</view>
</view>
</template>
<script lang="uts">
type AdminInfoType = {
id: string
nickname: string
role: string
}
type PlatformStatsType = {
total_gmv: string
gmv_growth: number
total_orders: number
order_growth: number
total_users: number
user_growth: number
total_merchants: number
merchant_growth: number
}
type TodayStatsType = {
sales: string
orders: number
new_users: number
active_users: number
}
type PendingCountsType = {
merchant_review: number
product_review: number
refund_review: number
complaints: number
}
type RealTimeStatsType = {
online_users: number
active_drivers: number
delivering_orders: number
system_load: number
}
type ActivityType = {
id: string
type: string
description: string
created_at: string
}
export default {
data() {
return {
adminInfo: {
id: '',
nickname: '管理员',
role: 'admin'
} as AdminInfoType,
platformStats: {
total_gmv: '0.00',
gmv_growth: 0,
total_orders: 0,
order_growth: 0,
total_users: 0,
user_growth: 0,
total_merchants: 0,
merchant_growth: 0
} as PlatformStatsType,
todayStats: {
sales: '0.00',
orders: 0,
new_users: 0,
active_users: 0
} as TodayStatsType,
pendingCounts: {
merchant_review: 0,
product_review: 0,
refund_review: 0,
complaints: 0
} as PendingCountsType,
realTimeStats: {
online_users: 0,
active_drivers: 0,
delivering_orders: 0,
system_load: 0
} as RealTimeStatsType,
recentActivities: [] as Array<ActivityType>
}
},
onLoad() {
this.loadAdminInfo()
this.loadPlatformStats()
this.loadTodayStats()
this.loadPendingCounts()
this.loadRealTimeStats()
this.loadRecentActivities()
},
onShow() {
// 页面显示时刷新实时数据
this.refreshRealTimeData()
},
methods: {
// 加载管理员信息
loadAdminInfo() {
// TODO: 调用API获取管理员信息
this.adminInfo.nickname = '系统管理员'
},
// 加载平台统计
loadPlatformStats() {
// TODO: 调用API获取平台统计数据
this.platformStats = {
total_gmv: '12,580,000.00',
gmv_growth: 15.6,
total_orders: 125800,
order_growth: 12.3,
total_users: 45600,
user_growth: 8.9,
total_merchants: 2560,
merchant_growth: 5.2
}
},
// 加载今日统计
loadTodayStats() {
// TODO: 调用API获取今日数据
this.todayStats = {
sales: '156,800.00',
orders: 1568,
new_users: 89,
active_users: 3456
}
},
// 加载待处理数量
loadPendingCounts() {
// TODO: 调用API获取待处理数量
this.pendingCounts = {
merchant_review: 12,
product_review: 45,
refund_review: 8,
complaints: 3
}
},
// 加载实时统计
loadRealTimeStats() {
// TODO: 调用API获取实时数据
this.realTimeStats = {
online_users: 2345,
active_drivers: 156,
delivering_orders: 234,
system_load: 68
}
},
// 加载最新动态
loadRecentActivities() {
// TODO: 调用API获取最新动态
this.recentActivities = [
{
id: '1',
type: 'user_register',
description: '新用户注册:张三',
created_at: '2025-01-08T15:30:00Z'
},
{
id: '2',
type: 'merchant_apply',
description: '商家申请入驻:华强北电子商城',
created_at: '2025-01-08T15:25:00Z'
},
{
id: '3',
type: 'order_created',
description: '新订单创建:订单号 M202501081567',
created_at: '2025-01-08T15:20:00Z'
}
]
},
// 刷新实时数据
refreshRealTimeData() {
this.loadRealTimeStats()
this.loadPendingCounts()
this.loadRecentActivities()
},
// 获取活动图标
getActivityIcon(type: string): string {
switch (type) {
case 'user_register': return '👤'
case 'merchant_apply': return '🏪'
case 'order_created': return '📋'
case 'product_review': return '📦'
case 'refund_request': return '💰'
case 'complaint': return '⚠️'
default: return '📝'
}
},
// 格式化时间
formatTime(timeStr: string): string {
const date = new Date(timeStr)
const now = new Date()
const diff = now.getTime() - date.getTime()
const minutes = Math.floor(diff / (1000 * 60))
if (minutes < 60) {
return `${minutes}分钟前`
} else if (minutes < 1440) {
return `${Math.floor(minutes / 60)}小时前`
} else {
return `${Math.floor(minutes / 1440)}天前`
}
},
// 导航方法
goToNotifications() {
uni.navigateTo({
url: '/pages/mall/admin/notifications'
})
},
goToProfile() {
uni.navigateTo({
url: '/pages/mall/admin/profile'
})
},
goToMerchantReview() {
uni.navigateTo({
url: '/pages/mall/admin/merchant-review'
})
},
goToProductReview() {
uni.navigateTo({
url: '/pages/mall/admin/product-review'
})
},
goToRefundReview() {
uni.navigateTo({
url: '/pages/mall/admin/refund-review'
})
},
goToComplaints() {
uni.navigateTo({
url: '/pages/mall/admin/complaints'
})
},
goToUserManagement() {
uni.navigateTo({
url: '/pages/mall/admin/user-management'
})
},
goToMerchantManagement() {
uni.navigateTo({
url: '/pages/mall/admin/merchant-management'
})
},
goToProductManagement() {
uni.navigateTo({
url: '/pages/mall/admin/product-management'
})
},
goToOrderManagement() {
uni.navigateTo({
url: '/pages/mall/admin/order-management'
})
},
goToCouponManagement() {
uni.navigateTo({
url: '/pages/mall/admin/coupon-management'
})
},
goToDeliveryManagement() {
uni.navigateTo({
url: '/pages/mall/admin/delivery-management'
})
},
goToFinanceManagement() {
uni.navigateTo({
url: '/pages/mall/admin/finance-management'
})
},
goToSystemSettings() {
uni.navigateTo({
url: '/pages/mall/admin/system-settings'
})
},
goToActivityLog() {
uni.navigateTo({
url: '/pages/mall/admin/activity-log'
})
},
goToSubscriptionPlans() {
uni.navigateTo({
url: '/pages/mall/admin/subscription/plan-management'
})
},
goToAdminUserSubscriptions() {
uni.navigateTo({
url: '/pages/mall/admin/subscription/user-subscriptions'
})
}
}
}
</script>
<style>
.admin-container {
background-color: #f5f5f5;
min-height: 100vh;
padding-bottom: 40rpx;
}
.header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
padding: 40rpx 30rpx 30rpx;
display: flex;
justify-content: space-between;
align-items: center;
}
.header-left {
display: flex;
flex-direction: column;
}
.app-title {
font-size: 36rpx;
font-weight: bold;
color: #fff;
margin-bottom: 8rpx;
}
.welcome-text {
font-size: 24rpx;
color: rgba(255, 255, 255, 0.8);
}
.header-right {
display: flex;
align-items: center;
}
.notification-btn,
.profile-btn {
font-size: 32rpx;
color: #fff;
margin-left: 30rpx;
}
.metrics-section {
background-color: #fff;
margin: 20rpx;
padding: 30rpx;
border-radius: 16rpx;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
}
.section-title {
font-size: 32rpx;
font-weight: bold;
color: #333;
margin-bottom: 30rpx;
}
.metrics-grid {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.metric-card {
width: 48%;
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
padding: 30rpx 20rpx;
border-radius: 12rpx;
margin-bottom: 20rpx;
position: relative;
}
.metric-value {
font-size: 32rpx;
font-weight: bold;
color: #fff;
margin-bottom: 8rpx;
}
.metric-label {
font-size: 24rpx;
color: rgba(255, 255, 255, 0.9);
margin-bottom: 10rpx;
}
.metric-change {
font-size: 20rpx;
position: absolute;
top: 20rpx;
right: 20rpx;
}
.positive {
color: #4CAF50;
background-color: rgba(255, 255, 255, 0.2);
padding: 4rpx 8rpx;
border-radius: 8rpx;
}
.today-section {
background-color: #fff;
margin: 20rpx;
padding: 30rpx;
border-radius: 16rpx;
}
.today-grid {
display: flex;
justify-content: space-between;
}
.today-item {
display: flex;
flex-direction: column;
align-items: center;
flex: 1;
}
.today-value {
font-size: 36rpx;
font-weight: bold;
color: #2196F3;
margin-bottom: 10rpx;
}
.today-label {
font-size: 24rpx;
color: #666;
}
.pending-section {
background-color: #fff;
margin: 20rpx;
padding: 30rpx;
border-radius: 16rpx;
}
.pending-list {
display: flex;
flex-direction: column;
}
.pending-item {
display: flex;
align-items: center;
padding: 20rpx;
border-radius: 12rpx;
margin-bottom: 15rpx;
border: 1rpx solid #f0f0f0;
}
.pending-item.urgent {
border-color: #FF5722;
background-color: #FFF3E0;
}
.pending-icon {
font-size: 32rpx;
margin-right: 20rpx;
width: 40rpx;
}
.pending-content {
display: flex;
flex-direction: column;
flex: 1;
}
.pending-title {
font-size: 28rpx;
color: #333;
margin-bottom: 6rpx;
}
.pending-subtitle {
font-size: 22rpx;
color: #666;
}
.pending-count {
font-size: 28rpx;
color: #FF5722;
font-weight: bold;
background-color: #FFEBEE;
padding: 8rpx 16rpx;
border-radius: 20rpx;
}
.monitor-section {
background-color: #fff;
margin: 20rpx;
padding: 30rpx;
border-radius: 16rpx;
}
.monitor-grid {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.monitor-card {
width: 48%;
background: linear-gradient(135deg, #84fab0 0%, #8fd3f4 100%);
padding: 30rpx 20rpx;
border-radius: 12rpx;
margin-bottom: 20rpx;
text-align: center;
}
.monitor-title {
font-size: 24rpx;
color: #333;
margin-bottom: 15rpx;
}
.monitor-value {
font-size: 48rpx;
font-weight: bold;
color: #2E7D32;
margin-bottom: 5rpx;
}
.monitor-unit {
font-size: 20rpx;
color: #666;
}
.shortcuts-section {
background-color: #fff;
margin: 20rpx;
padding: 30rpx;
border-radius: 16rpx;
}
.shortcuts-grid {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.shortcut-item {
width: 22%;
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 30rpx;
}
.shortcut-icon {
font-size: 48rpx;
margin-bottom: 15rpx;
}
.shortcut-text {
font-size: 22rpx;
color: #333;
text-align: center;
}
.activities-section {
background-color: #fff;
margin: 20rpx;
padding: 30rpx;
border-radius: 16rpx;
}
.section-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 30rpx;
}
.section-more {
font-size: 24rpx;
color: #2196F3;
}
.activities-list {
display: flex;
flex-direction: column;
}
.activity-item {
display: flex;
align-items: center;
padding: 15rpx 0;
border-bottom: 1rpx solid #f0f0f0;
}
.activity-item:last-child {
border-bottom: none;
}
.activity-icon {
font-size: 28rpx;
margin-right: 20rpx;
width: 40rpx;
}
.activity-content {
display: flex;
flex-direction: column;
flex: 1;
}
.activity-text {
font-size: 26rpx;
color: #333;
margin-bottom: 5rpx;
}
.activity-time {
font-size: 22rpx;
color: #999;
}
</style>