Files
order_site/apps/frontend/src/views/admin/dashboard/AdminDashboardView.vue
T
2026-05-25 23:07:19 +08:00

92 lines
2.1 KiB
Vue

<script setup lang="ts">
import { onMounted, ref } from 'vue'
import AdminPageHeader from '@/components/admin/AdminPageHeader.vue'
import { fetchAdminDashboardSummary } from '@/services/admin'
import type { AdminDashboardSummary } from '@/types/admin'
const loading = ref(true)
const summary = ref<AdminDashboardSummary | null>(null)
const errorMessage = ref('')
onMounted(async () => {
try {
const response = await fetchAdminDashboardSummary()
summary.value = response.data
} catch (error) {
errorMessage.value = error instanceof Error ? error.message : '读取概览失败'
} finally {
loading.value = false
}
})
const cards = [
{ key: 'todayOrders', label: '今日订单' },
{ key: 'paidPendingClaim', label: '待领取' },
{ key: 'claimingTasks', label: '领取中' },
{ key: 'redeemedToday', label: '今日成功' },
{ key: 'abnormalTasks', label: '异常任务' },
] as const
</script>
<template>
<div class="dashboard-page">
<AdminPageHeader title="系统概览" description="快速查看订单和交付链路的运行状态。" />
<el-alert
v-if="errorMessage"
:title="errorMessage"
type="error"
show-icon
:closable="false"
class="mt-4"
/>
<el-skeleton v-if="loading" :rows="12" animated class="mt-4" />
<div v-else class="summary-grid">
<el-card v-for="card in cards" :key="card.key" shadow="never" class="stat-card">
<span class="stat-label">{{ card.label }}</span>
<strong class="stat-value">{{ summary?.[card.key] ?? 0 }}</strong>
</el-card>
</div>
</div>
</template>
<style scoped>
.dashboard-page {
display: grid;
gap: 0;
}
.summary-grid {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: var(--space-4);
margin-top: var(--space-4);
}
.stat-card {
text-align: left;
}
.stat-label {
display: block;
color: var(--text-secondary);
font-size: var(--text-sm);
}
.stat-value {
display: block;
margin-top: 10px;
font-size: var(--text-3xl);
color: var(--text-primary);
}
@media (max-width: 900px) {
.summary-grid {
grid-template-columns: 1fr;
}
}
</style>