|
|
|
@ -122,6 +122,17 @@ const WuyuanbiaobaContent = () => { |
|
|
|
})); |
|
|
|
}; |
|
|
|
|
|
|
|
// 归一化设备上报数据:兼容批量格式(values 为数组)与单条格式(values 为对象) |
|
|
|
const normalizeDataGroups = (values) => { |
|
|
|
if (Array.isArray(values)) { |
|
|
|
return values.filter((g) => g && Array.isArray(g.data)); |
|
|
|
} |
|
|
|
if (values && Array.isArray(values.data)) { |
|
|
|
return [values]; |
|
|
|
} |
|
|
|
return []; |
|
|
|
}; |
|
|
|
|
|
|
|
// 初始化数据 |
|
|
|
useEffect(() => { |
|
|
|
// 初始化空的实时数据表格 |
|
|
|
@ -172,46 +183,54 @@ const WuyuanbiaobaContent = () => { |
|
|
|
realtimeDataSubscription.latest && |
|
|
|
realtimeDataSubscription.latest.values |
|
|
|
) { |
|
|
|
const newRealtimeData = processRealtimeData( |
|
|
|
// 兼容批量上报(values 为数组)与单条上报(values 为对象) |
|
|
|
const dataGroups = normalizeDataGroups( |
|
|
|
realtimeDataSubscription.latest.values |
|
|
|
); |
|
|
|
|
|
|
|
if (newRealtimeData.length > 0) { |
|
|
|
const currentTime = Date.now(); |
|
|
|
const currentSecond = Math.floor(currentTime / 1000); |
|
|
|
|
|
|
|
// 每秒采样一次数据用于图表和表格显示 |
|
|
|
if (currentSecond > lastSampleTime) { |
|
|
|
setLastSampleTime(currentSecond); |
|
|
|
if (dataGroups.length > 0) { |
|
|
|
// 维护两分钟的缓冲区(批量模式下保留批量内全部数据点,保证导出全分辨率) |
|
|
|
dataGroups.forEach((group) => pushToRealtimeBuffer(group)); |
|
|
|
setLastUpdateTime(new Date()); |
|
|
|
|
|
|
|
// 更新采样后的历史数据(用于图表显示) |
|
|
|
setTableData((prevData) => { |
|
|
|
const updatedData = [ |
|
|
|
...prevData, |
|
|
|
...newRealtimeData.map((point) => ({ |
|
|
|
// 展示采样:取最新一条数据(批量模式下取批量内最后一条) |
|
|
|
const latestGroup = dataGroups[dataGroups.length - 1]; |
|
|
|
const newRealtimeData = processRealtimeData(latestGroup); |
|
|
|
|
|
|
|
if (newRealtimeData.length > 0) { |
|
|
|
const currentTime = Date.now(); |
|
|
|
const currentSecond = Math.floor(currentTime / 1000); |
|
|
|
|
|
|
|
// 每秒采样一次数据用于图表和表格显示 |
|
|
|
if (currentSecond > lastSampleTime) { |
|
|
|
setLastSampleTime(currentSecond); |
|
|
|
|
|
|
|
// 更新采样后的历史数据(用于图表显示) |
|
|
|
setTableData((prevData) => { |
|
|
|
const updatedData = [ |
|
|
|
...prevData, |
|
|
|
...newRealtimeData.map((point) => ({ |
|
|
|
...point, |
|
|
|
key: `${currentTime}_${point.key}`, |
|
|
|
timestamp: currentTime, |
|
|
|
updateTime: new Date(currentTime).toLocaleString(), |
|
|
|
})), |
|
|
|
]; |
|
|
|
|
|
|
|
// 只保留最近25个数据点 |
|
|
|
return updatedData.slice(-75); // 3个设备 * 25个时间点 |
|
|
|
}); |
|
|
|
|
|
|
|
// 更新实时数据表格(使用最新的采样数据) |
|
|
|
setRealtimeData( |
|
|
|
newRealtimeData.map((point) => ({ |
|
|
|
...point, |
|
|
|
key: `${currentTime}_${point.key}`, |
|
|
|
timestamp: currentTime, |
|
|
|
key: `realtime_${point.key}`, |
|
|
|
updateTime: new Date(currentTime).toLocaleString(), |
|
|
|
})), |
|
|
|
]; |
|
|
|
|
|
|
|
// 只保留最近25个数据点 |
|
|
|
return updatedData.slice(-75); // 3个设备 * 25个时间点 |
|
|
|
}); |
|
|
|
|
|
|
|
// 更新实时数据表格(使用最新的采样数据) |
|
|
|
setRealtimeData( |
|
|
|
newRealtimeData.map((point) => ({ |
|
|
|
...point, |
|
|
|
key: `realtime_${point.key}`, |
|
|
|
updateTime: new Date(currentTime).toLocaleString(), |
|
|
|
})) |
|
|
|
); |
|
|
|
})) |
|
|
|
); |
|
|
|
} |
|
|
|
} |
|
|
|
//维护两分钟的缓冲区 |
|
|
|
pushToRealtimeBuffer(realtimeDataSubscription.latest.values); |
|
|
|
setLastUpdateTime(new Date()); |
|
|
|
} |
|
|
|
} |
|
|
|
}, [realtimeDataSubscription.latest]); |
|
|
|
|