diff --git a/src/components/Dashboard.vue b/src/components/Dashboard.vue index b4bbbea..db64c2a 100644 --- a/src/components/Dashboard.vue +++ b/src/components/Dashboard.vue @@ -92,15 +92,82 @@ - -
-
-
-

实时数据对比分析

-
+
+ +
+
+
+

小区实时监控数据

+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
小区名称实时用户数总订单量今日订单量状态
+
+
+ {{ community.name }} +
+
+
+ {{ community.userCount }} + + + {{ formatTrend(community.userTrend) }} + +
+
+
+ {{ community.totalOrders }} + + + {{ formatTrend(community.totalOrdersTrend) }} + +
+
+
+ {{ community.todayOrders }} + + + {{ formatTrend(community.todayOrdersTrend) }} + +
+
+ + {{ community.status }} + +
+
-
-
+ + +
+
+
+

实时数据对比分析

+
+
+
+
+
@@ -130,11 +197,13 @@ export default { today_community_count: 0, yesterday_community_count: 0 }, + communityData: [], loading: false, lastUpdateTime: null, comparisonChart: null, currentTime: '', timeInterval: null, + scrollInterval: null, shouldBeautifyData: true // 默认美化数据 }; }, @@ -167,12 +236,17 @@ export default { } catch (error) { console.error('解析查询参数出错:', error); } + + // 生成模拟的小区数据 + this.generateMockCommunityData(); }, mounted() { this.fetchDashboardData(); // 每1分钟自动刷新一次数据 this.autoRefreshInterval = setInterval(() => { this.fetchDashboardData(); + // 更新小区数据 + this.updateCommunityData(); }, 60 * 1000); // 更新当前时间 @@ -180,6 +254,9 @@ export default { this.timeInterval = setInterval(() => { this.updateCurrentTime(); }, 1000); + + // 启动小区数据表格自动滚动 + this.startTableScroll(); }, beforeDestroy() { if (this.autoRefreshInterval) { @@ -188,11 +265,30 @@ export default { if (this.timeInterval) { clearInterval(this.timeInterval); } + if (this.scrollInterval) { + clearInterval(this.scrollInterval); + } if (this.comparisonChart) { this.comparisonChart.dispose(); } }, methods: { + // 修改表格自动滚动方法 + startTableScroll() { + this.scrollInterval = setInterval(() => { + const tbody = this.$refs.communityTableBody; + if (tbody) { + const scrollAmount = 1; // 每次滚动的像素数 + + // 直接使用 tbody 元素进行滚动,而不是其父元素 + if (tbody.scrollTop + tbody.clientHeight >= tbody.scrollHeight) { + tbody.scrollTop = 0; + } else { + tbody.scrollTop += scrollAmount; + } + } + }, 50); // 滚动速度,数值越小滚动越快 + }, updateCurrentTime() { const now = new Date(); this.currentTime = now.toLocaleTimeString(); @@ -315,28 +411,28 @@ export default { return 'el-icon-minus'; }, initComparisonChart() { - if (!this.$refs.comparisonChart) return; - if (this.comparisonChart) { this.comparisonChart.dispose(); } - this.comparisonChart = echarts.init(this.$refs.comparisonChart); + const chartDom = this.$refs.comparisonChart; + this.comparisonChart = echarts.init(chartDom); const option = { - backgroundColor: 'transparent', + grid: { + top: '10%', + left: '3%', + right: '4%', + bottom: '10%', + containLabel: true + }, tooltip: { trigger: 'axis', axisPointer: { - type: 'shadow', - shadowStyle: { - color: 'rgba(0, 180, 220, 0.1)' - } + type: 'shadow' }, - backgroundColor: 'rgba(0, 20, 40, 0.8)', - borderColor: 'rgba(0, 180, 220, 0.8)', textStyle: { - color: '#fff' + fontSize: 12 } }, legend: { @@ -344,26 +440,19 @@ export default { textStyle: { color: '#00b4dc' }, - itemStyle: { - borderColor: '#00b4dc' - } - }, - grid: { - left: '3%', - right: '4%', - bottom: '3%', - containLabel: true + top: 0 }, xAxis: { type: 'category', - data: ['用户', '订单', '社区'], + data: ['用户数', '订单数', '社区数'], axisLine: { lineStyle: { color: '#00b4dc' } }, axisLabel: { - color: '#00b4dc' + color: '#00b4dc', + fontSize: 12 } }, yAxis: { @@ -376,11 +465,12 @@ export default { }, splitLine: { lineStyle: { - color: 'rgba(0, 180, 220, 0.2)' + color: 'rgba(0, 180, 220, 0.1)' } }, axisLabel: { - color: '#00b4dc' + color: '#00b4dc', + fontSize: 12 } }, series: [ @@ -388,9 +478,9 @@ export default { name: '今日', type: 'bar', data: [ - this.dashboardData.today_user_count || 0, - this.dashboardData.today_order_count || 0, - this.dashboardData.today_community_count || 0 + this.dashboardData.today_user_count, + this.dashboardData.today_order_count, + this.dashboardData.today_community_count ], itemStyle: { color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ @@ -398,21 +488,20 @@ export default { { offset: 1, color: '#0066ff' } ]) }, - barWidth: '20%', - barGap: '10%' + barWidth: '20%' }, { name: '昨日', type: 'bar', data: [ - this.dashboardData.yesterday_user_count || 0, - this.dashboardData.yesterday_order_count || 0, - this.dashboardData.yesterday_community_count || 0 + this.dashboardData.yesterday_user_count, + this.dashboardData.yesterday_order_count, + this.dashboardData.yesterday_community_count ], itemStyle: { color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ - { offset: 0, color: '#ff9a00' }, - { offset: 1, color: '#ff0000' } + { offset: 0, color: '#ff9a9e' }, + { offset: 1, color: '#ff6b6b' } ]) }, barWidth: '20%' @@ -426,21 +515,126 @@ export default { window.addEventListener('resize', () => { this.comparisonChart.resize(); }); - } + }, + // 新增方法:生成模拟的小区数据 + generateMockCommunityData() { + const communityNames = [ + '阳光花园小区', '蓝天公寓', '绿地国际城', '和平家园', + '金色家园', '紫荆花园', '龙湖小区', '万科城市花园', + '恒大名都', '碧桂园' + ]; + + this.communityData = communityNames.map((name, index) => { + // 生成随机数据 + const userCount = Math.floor(Math.random() * 500) + 100; + const totalOrders = Math.floor(Math.random() * 2000) + 500; + const todayOrders = Math.floor(Math.random() * 100) + 10; + + // 生成随机趋势 + const userTrend = (Math.random() - 0.3) * 10; // 偏向正增长 + const totalOrdersTrend = (Math.random() - 0.3) * 15; // 偏向正增长 + const todayOrdersTrend = (Math.random() - 0.4) * 8; // 更偏向正增长 + + // 随机状态 + const statuses = ['正常', '活跃', '火爆', '平稳']; + const status = statuses[Math.floor(Math.random() * statuses.length)]; + + return { + name, + userCount, + totalOrders, + todayOrders, + userTrend, + totalOrdersTrend, + todayOrdersTrend, + status + }; + }); + + // 按总订单量排序 + this.communityData.sort((a, b) => b.totalOrders - a.totalOrders); + }, + + // 更新小区数据(模拟数据变化) + updateCommunityData() { + this.communityData = this.communityData.map(community => { + // 小幅度更新数据 + const userChange = Math.floor(Math.random() * 10) - 3; // -3 到 6 的变化 + const totalOrdersChange = Math.floor(Math.random() * 15); // 0 到 14 的变化 + const todayOrdersChange = Math.floor(Math.random() * 5); // 0 到 4 的变化 + + // 更新趋势 + const userTrend = (Math.random() - 0.3) * 10; + const totalOrdersTrend = (Math.random() - 0.3) * 15; + const todayOrdersTrend = (Math.random() - 0.4) * 8; + + // 随机状态变化 + const statuses = ['正常', '活跃', '火爆', '平稳']; + const status = Math.random() > 0.8 + ? statuses[Math.floor(Math.random() * statuses.length)] + : community.status; + + return { + ...community, + userCount: Math.max(0, community.userCount + userChange), + totalOrders: community.totalOrders + totalOrdersChange, + todayOrders: Math.max(0, community.todayOrders + todayOrdersChange), + userTrend, + totalOrdersTrend, + todayOrdersTrend, + status + }; + }); + + // 重新排序 + this.communityData.sort((a, b) => b.totalOrders - a.totalOrders); + }, + + // 根据趋势值获取样式类 + getTrendClass(trendValue) { + if (trendValue > 0) return 'trend-up'; + if (trendValue < 0) return 'trend-down'; + return 'trend-flat'; + }, + + // 根据趋势值获取图标 + getTrendIconByValue(trendValue) { + if (trendValue > 0) return 'el-icon-top'; + if (trendValue < 0) return 'el-icon-bottom'; + return 'el-icon-minus'; + }, + + // 格式化趋势显示 + formatTrend(trendValue) { + const absValue = Math.abs(trendValue).toFixed(1); + if (trendValue > 0) return `+${absValue}%`; + if (trendValue < 0) return `-${absValue}%`; + return '0%'; + }, + + // 获取状态样式类 + getStatusClass(status) { + switch (status) { + case '火爆': return 'status-hot'; + case '活跃': return 'status-active'; + case '平稳': return 'status-stable'; + default: return 'status-normal'; + } + }, } };