Commit cbbb9911 authored by xinzhedeai's avatar xinzhedeai

左侧三模块增加10s轮询处理

parent 92a5d294
......@@ -22,15 +22,14 @@
</template>
<script setup lang="ts">
import {
import {
useMessage
} from 'naive-ui';
import { ref, onMounted } from "vue";
import { ref, onMounted, onUnmounted } from "vue";
import { getDeviceStatusInfo } from '@/api/index-dp';
const message = useMessage();
// 定义设备状态数据接口
interface DeviceStatus {
id: string;
......@@ -39,73 +38,65 @@ interface DeviceStatus {
color: string;
onlineCount: number;
offlineCount: number;
online: number;
unline: number;
onlinePercent: number;
}
// // 定义组件属性
// const props = defineProps<{
// // 如果需要从父组件传递数据,可以添加props
// // deviceStatusList?: DeviceStatus[];
// }>();
// 设备状态数据列表
const deviceStatusList = ref<DeviceStatus[]>([]);
// 模拟接口请求函数
// 轮询定时器引用
let pollingTimer: number | null = null;
// 获取设备状态数据函数
const fetchDeviceStatus = async () => {
try {
// 这里应该是实际的API请求
const response = await getDeviceStatusInfo();
if (response.data.code == 200) {
deviceStatusList.value = response.data.data
deviceStatusList.value = response.data.data;
} else {
message.error(response.data.msg)
}
// // 模拟接口返回数据
// deviceStatusList.value = [
// {
// id: "1",
// name: "在线监测",
// percent: 100,
// color: "cyan",
// onlineCount: 56,
// offlineCount: 0,
// },
// {
// id: "2",
// name: "视频监测",
// percent: 82,
// color: "yellow",
// onlineCount: 87,
// offlineCount: 2,
// },
// {
// id: "3",
// name: "人员定位",
// percent: 88,
// color: "blue",
// onlineCount: 16,
// offlineCount: 2,
// },
// {
// id: "4",
// name: "车辆定位",
// percent: 100,
// color: "green",
// onlineCount: 7,
// offlineCount: 2,
// },
// ];
message.error(response.data.msg);
}
} catch (error) {
console.error("获取设备状态数据失败:", error);
message.error("获取设备状态数据失败");
}
};
// 开始轮询
const startPolling = () => {
// 先清除已存在的定时器
if (pollingTimer) {
clearInterval(pollingTimer);
}
// 每10秒轮询一次
pollingTimer = window.setInterval(() => {
fetchDeviceStatus();
}, 10000);
};
// 停止轮询
const stopPolling = () => {
if (pollingTimer) {
clearInterval(pollingTimer);
pollingTimer = null;
}
};
// 组件挂载时获取数据
// 组件挂载时获取数据并开始轮询
onMounted(() => {
// 立即获取一次数据
fetchDeviceStatus();
// 开始轮询
startPolling();
});
// 组件卸载时停止轮询,防止内存泄漏
onUnmounted(() => {
stopPolling();
});
</script>
......@@ -118,7 +109,8 @@ onMounted(() => {
padding-top: 0.45rem;
// background: var(--n-bg-color-secondary);
background-image: url("@/assets/jinrun/module-bg.png");
background-size: cover;
background-size: cover;
.card-title {
position: absolute;
left: 0.25rem;
......@@ -128,6 +120,7 @@ background-size: cover;
color: #ffffff;
text-shadow: 0rem 0rem 0rem rgba(5, 38, 68, 0.5);
}
.card-header {
position: relative;
width: 4.48rem;
......@@ -164,15 +157,19 @@ background-size: cover;
background-size: cover;
// padding: 0.05rem 0.1rem;
// border-radius: 0.05rem;
&.blue {
background-image: url("@/assets/jinrun/blue.png");
}
&.yellow {
background-image: url("@/assets/jinrun/yellow.png");
}
&.cyan {
background-image: url("@/assets/jinrun/cyan.png");
}
&.green {
background-image: url("@/assets/jinrun/green.png");
}
......
......@@ -56,6 +56,12 @@ const vehicleScrollWrapper = ref(null)
// 滚动定时器
let scrollTimer = null
// 轮询定时器
let pollingTimer = null
// 轮询间隔时间(毫秒)
const POLLING_INTERVAL = 10000; // 10秒
// 根据status获取对应的class
const getItemClass = (item) => {
if (item.state == 1) {
......@@ -136,7 +142,9 @@ const initScroll = () => {
}, 50)
}
// 获取数据函数
const fetchData = async () => {
try {
const response = await getOnlineData();
if (response.data.code == 200) {
tableData.value = response.data.data
......@@ -148,18 +156,50 @@ const fetchData = async () => {
} else {
message.error(response.data.msg)
}
} catch (error) {
console.error('获取在线监测数据失败:', error)
message.error('获取数据失败')
}
}
// 组件挂载时获取数据
onMounted(() => {
// 启动轮询
const startPolling = () => {
// 先清除已存在的定时器
if (pollingTimer) {
clearInterval(pollingTimer);
}
// 立即获取一次数据
fetchData();
// 设置新的轮询定时器
pollingTimer = setInterval(() => {
fetchData();
}, POLLING_INTERVAL);
};
// 停止轮询
const stopPolling = () => {
if (pollingTimer) {
clearInterval(pollingTimer);
pollingTimer = null;
}
};
// 组件挂载时启动轮询
onMounted(() => {
startPolling();
});
// 组件卸载前清除定时器
// 组件卸载前清除所有定时器
onBeforeUnmount(() => {
// 清除滚动定时器
if (scrollTimer) {
clearInterval(scrollTimer)
}
// 清除轮询定时器
stopPolling();
});
</script>
......
......@@ -3,6 +3,9 @@
<h2 class="card-title">近24小时降雨量变化趋势图</h2>
<div class="chart-wrapper">
<div class="chart-container" ref="chartRef"></div>
<div v-show="showNoData" class="no-data-overlay">
<div class="no-data-text">暂无数据</div>
</div>
</div>
</div>
</template>
......@@ -13,16 +16,27 @@ import * as echarts from "echarts";
import { debounce } from "lodash-es"; // 防抖函数,避免频繁触发resize
import { getRainCurve } from '@/api/index-dp';
import {
import {
useMessage
} from 'naive-ui';
const message = useMessage();
// 轮询定时器
let pollingTimer: number | null = null;
// 轮询间隔时间(毫秒)
const POLLING_INTERVAL = 10000; // 10秒
// 设备状态数据列表
var warningLines = ref([]);
var xAxisData = ref([]);
var yAxisData = ref([]);
// 控制是否显示"暂无数据"提示
const showNoData = ref(false);
// 默认坐标轴配置
const DEFAULT_X_AXIS_DATA = Array.from({ length: 24 }, (_, i) => `${i}:00`);
const DEFAULT_Y_AXIS_MAX = 250; // Y轴最大值
const DEFAULT_Y_AXIS_MIN = 0; // Y轴最小值
// 模拟接口请求函数
const fetchRainCurve = async () => {
......@@ -30,15 +44,82 @@ const fetchRainCurve = async () => {
console.log('降雨量',response.data)
const result = response.data
if (result.code == 200) {
// 处理空数据情况
if (!result.data || !result.data.ydata || result.data.ydata.length === 0) {
// 如果没有数据,设置默认空数组
yAxisData.value = new Array(24).fill(null);
xAxisData.value = DEFAULT_X_AXIS_DATA;
warningLines.value = result.data?.alarm || [];
// 显示"暂无数据"提示
showNoData.value = true;
} else {
yAxisData.value = result.data.ydata
xAxisData.value = result.data.xdata
warningLines.value = result.data.alarm
// 隐藏"暂无数据"提示
showNoData.value = false;
}
// 更新图表数据
updateChartData();
} else {
message.error(result.msg)
}
};
// 启动轮询
const startPolling = () => {
// 先清除已存在的定时器
if (pollingTimer) {
clearInterval(pollingTimer);
}
// 设置新的轮询定时器
pollingTimer = window.setInterval(() => {
fetchRainCurve();
}, POLLING_INTERVAL);
};
// 停止轮询
const stopPolling = () => {
if (pollingTimer) {
clearInterval(pollingTimer);
pollingTimer = null;
}
};
// 更新图表数据
const updateChartData = () => {
if (chartInstance) {
chartInstance.setOption({
xAxis: {
data: xAxisData.value
},
yAxis: {
min: DEFAULT_Y_AXIS_MIN,
max: DEFAULT_Y_AXIS_MAX
},
series: [{
data: yAxisData.value,
markLine: {
symbol: 'none',
data: warningLines.value.map(line => ({
label: {
show: false
},
name: line.name,
yAxis: line.value,
lineStyle: {
color: line.color,
width: 1,
type: 'dashed',
}
}))
}
}]
});
}
};
const chartRef = ref<HTMLDivElement | null>(null);
let chartInstance: echarts.ECharts | null = null;
......@@ -47,17 +128,6 @@ let chartInstance: echarts.ECharts | null = null;
const initChart = () => {
if (!chartRef.value) return;
chartInstance = echarts.init(chartRef.value);
const hours = Array.from({ length: 24 }, (_, i) => `${i}:00`);
const data = hours.map(() => Math.floor(Math.random() * 150) + 20);
console.log(hours, data)
// 定义警戒线值
// const warningLines = [
// { value: 50, name: '蓝色警戒线', color: '#409EFF' },
// { value: 100, name: '黄色警戒线', color: '#FFD700' },
// { value: 150, name: '橙色警戒线', color: '#FF8C00' },
// { value: 200, name: '红色警戒线', color: '#FF0000' }
// ];
chartInstance.setOption({
grid: { left: "3%", right: "4%", bottom: "3%", containLabel: true },
......@@ -66,7 +136,7 @@ const initChart = () => {
},
xAxis: {
type: "category",
data: xAxisData.value,
data: DEFAULT_X_AXIS_DATA, // 使用默认X轴数据
axisLine: { lineStyle: { color: "#4f6b95" } },
axisLabel: { color: "#fff", interval: 2 },
},
......@@ -77,7 +147,8 @@ const initChart = () => {
padding: [0, 38, 0, 0],
},
type: "value",
// max: 300,
min: DEFAULT_Y_AXIS_MIN, // 设置Y轴最小值
max: DEFAULT_Y_AXIS_MAX, // 设置Y轴最大值
axisLine: { lineStyle: { color: "#4f6b95" } },
axisLabel: { color: "white"},
splitLine: { lineStyle: { color: "rgba(79, 107, 149, 0.2)" } },
......@@ -85,7 +156,7 @@ const initChart = () => {
series: [
{
data: yAxisData.value,
data: new Array(24).fill(null), // 初始为空数据
type: "line",
smooth: true,
showSymbol: false,
......@@ -98,18 +169,7 @@ const initChart = () => {
lineStyle: { color: "rgba(54, 162, 235, 1)", width: 2 },
markLine: {
symbol: 'none',
data: warningLines.value.map(line => ({
label: {
show: false
},
name: line.name,
yAxis: line.value,
lineStyle: {
color: line.color,
width: 1,
type: 'dashed',
}
}))
data: [] // 初始无警戒线
}
},
],
......@@ -152,11 +212,17 @@ onMounted(() => {
window.addEventListener("resize", resizeChart);
// 添加容器尺寸观察器
cleanupObserver = observeContainerResize();
// 启动轮询
startPolling();
});
});
});
onUnmounted(() => {
// 清理轮询定时器
stopPolling();
window.removeEventListener("resize", resizeChart);
if (cleanupObserver) {
cleanupObserver();
......@@ -164,7 +230,6 @@ onUnmounted(() => {
chartInstance?.dispose();
});
</script>
<style scoped lang="scss">
.wrapper {
overflow: visible;
......@@ -194,11 +259,31 @@ onUnmounted(() => {
justify-content: space-between;
width: 100%;
height: 100%;
position: relative;
}
.chart-container {
width: 100%;
height: 100%;
}
.no-data-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
// background-color: rgba(0, 0, 0, 0.3);
z-index: 10;
.no-data-text {
font-size: 0.18rem;
color: #ffffff;
text-shadow: 0 0 5px rgba(0, 0, 0, 0.5);
}
}
}
</style>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment