页面样式,svg

This commit is contained in:
2025-11-14 15:29:02 +08:00
parent 46003a646e
commit 6be3cc6abd
27 changed files with 585 additions and 180 deletions

View File

@@ -68,6 +68,7 @@
import { ref, onMounted, onUnmounted } from 'vue';
import { ElRow, ElCol, ElCard, ElDatePicker } from 'element-plus';
import * as echarts from 'echarts';
import { systemOverviewApi } from '@/apis/system/overview';
const dateRange = ref<[Date, Date] | null>(null);
const activityChart = ref<HTMLElement | null>(null);
@@ -75,51 +76,20 @@ const resourcePieChart = ref<HTMLElement | null>(null);
let activityChartInstance: echarts.ECharts | null = null;
let pieChartInstance: echarts.ECharts | null = null;
const statistics = ref([
{
icon: '👥',
label: '总用户数',
value: '1,234',
change: '+12%',
trend: 'up',
color: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)'
},
{
icon: '📚',
label: '总资源数',
value: '5,678',
change: '+8%',
trend: 'up',
color: 'linear-gradient(135deg, #f093fb 0%, #f5576c 100%)'
},
{
icon: '👁',
label: '今日访问量',
value: '892',
change: '+15%',
trend: 'up',
color: 'linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)'
},
{
icon: '✅',
label: '活跃用户',
value: '456',
change: '+5%',
trend: 'up',
color: 'linear-gradient(135deg, #43e97b 0%, #38f9d7 100%)'
}
]);
const statistics = ref<{
icon: string;
label: string;
value: string | number;
change: string;
trend: 'up' | 'down';
color: string;
}[]>([]);
const visitStats = ref([
{ label: 'UV(独立访客)', value: '892' },
{ label: 'PV(页面浏览量)', value: '3,456' },
{ label: '平均访问时长', value: '5分32秒' },
{ label: '跳出率', value: '35.6%' }
]);
const visitStats = ref<{ label: string; value: string | number }[]>([]);
onMounted(() => {
onMounted(async () => {
initCharts();
// TODO: 加载实际数据
await loadOverviewData();
});
onUnmounted(() => {
@@ -131,54 +101,129 @@ onUnmounted(() => {
}
});
async function loadOverviewData() {
try {
const [statRes, activeRes, pieRes, todayRes] = await Promise.all([
systemOverviewApi.getStatistics(),
systemOverviewApi.getActiveUsersChart('2025-10-15', '2025-10-21'),
systemOverviewApi.getResourceCategoryStats(),
systemOverviewApi.getTodayVisits()
]);
if (statRes.success && statRes.data) {
const d = statRes.data;
statistics.value = [
{
icon: '👥',
label: '总用户数',
value: d.totalUsers,
change: d.totalUsersChange,
trend: d.totalUsersChange.startsWith('-') ? 'down' : 'up',
color: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)'
},
{
icon: '📚',
label: '总资源数',
value: d.totalResources,
change: d.totalResourcesChange,
trend: d.totalResourcesChange.startsWith('-') ? 'down' : 'up',
color: 'linear-gradient(135deg, #f093fb 0%, #f5576c 100%)'
},
{
icon: '👁',
label: '今日访问量',
value: d.todayVisits,
change: d.todayVisitsChange,
trend: d.todayVisitsChange.startsWith('-') ? 'down' : 'up',
color: 'linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)'
},
{
icon: '✅',
label: '活跃用户',
value: d.activeUsers,
change: d.activeUsersChange,
trend: d.activeUsersChange.startsWith('-') ? 'down' : 'up',
color: 'linear-gradient(135deg, #43e97b 0%, #38f9d7 100%)'
}
];
}
if (todayRes.success && todayRes.data) {
const t = todayRes.data;
visitStats.value = [
{ label: 'UV(独立访客)', value: t.uv },
{ label: 'PV(页面浏览量)', value: t.pv },
{ label: '平均访问时长', value: t.avgVisitDuration },
{ label: '跳出率', value: t.bounceRate }
];
}
if (activeRes.success && activeRes.data) {
updateActivityChart(activeRes.data.labels, activeRes.data.values);
}
if (pieRes.success && pieRes.data) {
updatePieChart(pieRes.data.items);
}
} catch (error) {
console.error('加载系统总览数据失败:', error);
}
}
function initCharts() {
if (activityChart.value) {
activityChartInstance = echarts.init(activityChart.value);
const activityOption = {
tooltip: {
trigger: 'axis'
},
xAxis: {
type: 'category',
data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
},
yAxis: {
type: 'value'
},
series: [{
data: [120, 200, 150, 80, 70, 110, 130],
type: 'line',
smooth: true,
areaStyle: {}
}]
};
activityChartInstance.setOption(activityOption);
}
if (resourcePieChart.value) {
pieChartInstance = echarts.init(resourcePieChart.value);
const pieOption = {
tooltip: {
trigger: 'item'
},
legend: {
orient: 'vertical',
left: 'left'
},
series: [{
}
}
function updateActivityChart(labels: string[], values: number[]) {
if (!activityChartInstance) return;
const option = {
tooltip: {
trigger: 'axis'
},
xAxis: {
type: 'category',
data: labels
},
yAxis: {
type: 'value'
},
series: [
{
data: values,
type: 'line',
smooth: true,
areaStyle: {}
}
]
};
activityChartInstance.setOption(option);
}
function updatePieChart(items: { name: string; value: number }[]) {
if (!pieChartInstance) return;
const option = {
tooltip: {
trigger: 'item'
},
legend: {
orient: 'vertical',
left: 'left'
},
series: [
{
type: 'pie',
radius: '50%',
data: [
{ value: 1048, name: '文章' },
{ value: 735, name: '视频' },
{ value: 580, name: '音频' },
{ value: 484, name: '课程' },
{ value: 300, name: '其他' }
]
}]
};
pieChartInstance.setOption(pieOption);
}
data: items
}
]
};
pieChartInstance.setOption(option);
}
</script>