Initial commit
This commit is contained in:
94
license-system-frontend/src/pages/admin/DashboardView.vue
Normal file
94
license-system-frontend/src/pages/admin/DashboardView.vue
Normal file
@@ -0,0 +1,94 @@
|
||||
<template>
|
||||
<div class="page-shell">
|
||||
<div class="toolbar">
|
||||
<div>
|
||||
<h2 class="section-title">{{ '\u4eea\u8868\u76d8' }}</h2>
|
||||
<div class="tag">{{ '\u5b9e\u65f6\u6982\u89c8' }}</div>
|
||||
</div>
|
||||
<el-button type="primary" plain @click="loadData">{{ '\u5237\u65b0' }}</el-button>
|
||||
</div>
|
||||
|
||||
<div class="stat-grid">
|
||||
<div class="stat-card" v-for="item in overviewCards" :key="item.label">
|
||||
<div class="stat-label">{{ item.label }}</div>
|
||||
<div class="stat-value">{{ item.value }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid-two">
|
||||
<div class="glass-card panel">
|
||||
<div class="chart-header">
|
||||
<h3 class="section-title">{{ '\u6d3b\u8dc3\u8d8b\u52bf' }}</h3>
|
||||
<span class="tag">{{ '\u6700\u8fd130\u5929' }}</span>
|
||||
</div>
|
||||
<TrendChart :trend="trend" />
|
||||
</div>
|
||||
<div class="glass-card panel">
|
||||
<div class="chart-header">
|
||||
<h3 class="section-title">{{ '\u9879\u76ee\u5206\u5e03' }}</h3>
|
||||
<span class="tag">{{ '\u6d3b\u8dc3\u5361\u5bc6' }}</span>
|
||||
</div>
|
||||
<el-table :data="projectDistribution" height="320">
|
||||
<el-table-column prop="project" :label="'\u9879\u76ee'" min-width="120" />
|
||||
<el-table-column prop="count" :label="'\u5361\u5bc6'" width="120" />
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, onMounted, ref } from 'vue';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import TrendChart from '@/components/TrendChart.vue';
|
||||
import { statsDashboard } from '@/api/admin';
|
||||
|
||||
const data = ref({ overview: {}, trend: {}, projectDistribution: [] });
|
||||
|
||||
const overviewCards = computed(() => {
|
||||
const overview = data.value.overview || {};
|
||||
return [
|
||||
{ label: '\u9879\u76ee\u603b\u6570', value: overview.totalProjects ?? 0 },
|
||||
{ label: '\u5361\u5bc6\u603b\u6570', value: overview.totalCards ?? 0 },
|
||||
{ label: '\u6d3b\u8dc3\u5361\u5bc6', value: overview.activeCards ?? 0 },
|
||||
{ label: '\u5728\u7ebf\u8bbe\u5907', value: overview.activeDevices ?? 0 },
|
||||
{ label: '\u4eca\u65e5\u6536\u5165', value: overview.todayRevenue ?? 0 },
|
||||
{ label: '\u672c\u6708\u6536\u5165', value: overview.monthRevenue ?? 0 }
|
||||
];
|
||||
});
|
||||
|
||||
const trend = computed(() => data.value.trend || {});
|
||||
const projectDistribution = computed(() => data.value.projectDistribution || []);
|
||||
|
||||
const loadData = async () => {
|
||||
try {
|
||||
data.value = await statsDashboard();
|
||||
} catch (err) {
|
||||
ElMessage.error(err?.message || '\u52a0\u8f7d\u4eea\u8868\u76d8\u5931\u8d25');
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(loadData);
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.grid-two {
|
||||
display: grid;
|
||||
grid-template-columns: 2fr 1fr;
|
||||
gap: 16px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.chart-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
.grid-two {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user