refactor:【antd】【iot】优化消息趋势卡片组件,调整图表渲染逻辑

This commit is contained in:
haohao
2025-11-23 15:44:24 +08:00
parent a1e6982a28
commit 7d8c57711f

View File

@@ -6,7 +6,6 @@ import { computed, nextTick, onMounted, reactive, ref } from 'vue';
import { DICT_TYPE } from '@vben/constants'; import { DICT_TYPE } from '@vben/constants';
import { getDictOptions } from '@vben/hooks'; import { getDictOptions } from '@vben/hooks';
import { EchartsUI, useEcharts } from '@vben/plugins/echarts'; import { EchartsUI, useEcharts } from '@vben/plugins/echarts';
import { beginOfDay, endOfDay, formatDateTime } from '@vben/utils';
import { Card, DatePicker, Empty, Select } from 'ant-design-vue'; import { Card, DatePicker, Empty, Select } from 'ant-design-vue';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
@@ -89,8 +88,6 @@ async function fetchMessageData() {
loading.value = true; loading.value = true;
try { try {
messageData.value = await getDeviceMessageSummaryByDate(queryParams); messageData.value = await getDeviceMessageSummaryByDate(queryParams);
await nextTick();
initChart();
} catch (error) { } catch (error) {
// 开发环境:记录错误信息,便于调试 // 开发环境:记录错误信息,便于调试
console.error('获取消息统计数据失败:', error); console.error('获取消息统计数据失败:', error);
@@ -98,11 +95,13 @@ async function fetchMessageData() {
messageData.value = []; messageData.value = [];
} finally { } finally {
loading.value = false; loading.value = false;
await renderChartWhenReady();
} }
} }
/** 初始化图表 */ /** 初始化图表 */
function initChart() { function initChart() {
// 检查数据是否存在
if (!hasData.value) return; if (!hasData.value) return;
const times = messageData.value.map((item) => item.time); const times = messageData.value.map((item) => item.time);
@@ -114,6 +113,15 @@ function initChart() {
); );
} }
/** 确保图表容器已经可见后再渲染 */
async function renderChartWhenReady() {
if (!hasData.value) return;
// 等待 Card loading 状态、v-show 等 DOM 更新完成
await nextTick();
await nextTick();
initChart();
}
/** 组件挂载时查询数据 */ /** 组件挂载时查询数据 */
onMounted(() => { onMounted(() => {
fetchMessageData(); fetchMessageData();
@@ -121,7 +129,7 @@ onMounted(() => {
</script> </script>
<template> <template>
<Card class="h-full" :loading="loading"> <Card class="h-full">
<template #title> <template #title>
<div class="flex flex-wrap items-center justify-between gap-4"> <div class="flex flex-wrap items-center justify-between gap-4">
<span class="text-base font-medium text-gray-600">消息量统计</span> <span class="text-base font-medium text-gray-600">消息量统计</span>
@@ -143,7 +151,7 @@ onMounted(() => {
v-model:value="queryParams.interval" v-model:value="queryParams.interval"
:options="intervalOptions" :options="intervalOptions"
placeholder="间隔类型" placeholder="间隔类型"
class="!w-160px" :style="{ width: '80px' }"
@change="handleIntervalChange" @change="handleIntervalChange"
/> />
</div> </div>
@@ -151,30 +159,27 @@ onMounted(() => {
</div> </div>
</template> </template>
<!-- 加载中状态 -->
<div <div
v-if="loading && !hasData" v-show="loading && !hasData"
class="flex h-[300px] items-center justify-center" class="flex h-[300px] items-center justify-center"
> >
<Empty description="加载中..." /> <Empty description="加载中..." />
</div> </div>
<!-- 无数据状态 -->
<div <div
v-else-if="!hasData" v-show="!loading && !hasData"
class="flex h-[300px] items-center justify-center" class="flex h-[300px] items-center justify-center"
> >
<Empty description="暂无数据" /> <Empty description="暂无数据" />
</div> </div>
<div v-else> <!-- 图表容器 - 使用 v-show 而非 v-if确保组件始终挂载 -->
<div v-show="hasData">
<EchartsUI ref="messageChartRef" class="h-[300px] w-full" /> <EchartsUI ref="messageChartRef" class="h-[300px] w-full" />
</div> </div>
</Card> </Card>
</template> </template>
<style scoped> <style scoped>
:deep(.ant-card-body) {
padding: 20px;
}
:deep(.ant-card-head) {
border-bottom: 1px solid #f0f0f0;
}
</style> </style>