From 8521aee7f907692a14bcfbbce700fe95ce941a20 Mon Sep 17 00:00:00 2001 From: DXC Date: Tue, 15 Sep 2026 17:10:57 +0800 Subject: [PATCH] =?UTF-8?q?refactor(frontend):=20Dashboard=20=E6=B6=88?= =?UTF-8?q?=E8=B4=B9=E5=90=8E=E7=AB=AF=E6=97=B6=E6=95=88=E5=88=A4=E5=AE=9A?= =?UTF-8?q?=EF=BC=8C=E5=88=A0=E9=99=A4=E6=9C=AC=E5=9C=B0=E9=87=8D=E5=A4=8D?= =?UTF-8?q?=E8=AE=A1=E7=AE=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 删除 renderList 里自算的 diffDays / diffHours / isToday / validTime,改为 消费后端 to_dict() 的 stale_level / stale_days。这几个变量此前只在 Dashboard.vue 内部使用(已 grep 确认),移除不影响其他组件。 - 状态分级映射:severe -> 严重滞后、lagging -> 滞后、yesterday -> 昨日数据。 模板契约(statusColor / statusLabel / statusType / statusLabelColor / statusReason / sortWeight)保持不变,未改动任何模板代码。 - sortWeight 改为 stale_days * 24,与原 diffHours 同为小时量纲,排序结果与 原实现一致(同为「当天」的设备不再按小时细分,顺序退化为稳定序)。 - 离线原因文案与后端 offset 统一:拿不到可解析的数据时间就说「从未同步」, 不再另造「暂无数据」的说法。 - 时间解析保留下来仅用于显示格式化,不再参与滞后判定。 构建产物 web_dist 已重新生成并验证含新字段,但按 .gitignore 不入库。 --- .../src/views/Dashboard.vue | 41 ++++++++++--------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/zhandianxinxi/光谱数据监控/src/views/Dashboard.vue b/zhandianxinxi/光谱数据监控/src/views/Dashboard.vue index 8984720..0120ee6 100644 --- a/zhandianxinxi/光谱数据监控/src/views/Dashboard.vue +++ b/zhandianxinxi/光谱数据监控/src/views/Dashboard.vue @@ -341,8 +341,13 @@ const fetchData = async () => { const isOrphanIoT = (item.source === 'iot_card') const isWhitelist = !!item.is_whitelist - // === 1. 智能时间解析与格式化 (增强版) === - let diffDays = 0, diffHours = 0, isToday = false, validTime = false + // === 1. 时间显示格式化 === + // 滞后判定已统一由后端提供(stale_level / stale_days / offset), + // 这里只负责把 latest_time 渲染成统一格式,不再本地计算天数。 + // 判定与渲染分家的原因见 services/time_utils.py 顶部说明。 + const staleLevel = item.stale_level || 'unknown' + const staleDays = (typeof item.stale_days === 'number') ? item.stale_days : null + const validTime = staleLevel !== 'unknown' let timeStr = item.latest_time // 默认显示原始值,稍后如果解析成功则覆盖它 @@ -377,16 +382,8 @@ const fetchData = async () => { d = new Date(cleanStr); } - // C. 如果解析成功,强制重新生成统一的显示字符串 + // C. 解析成功则强制重新生成统一的显示格式 YYYY-MM-DD HH:mm:ss if (d && !isNaN(d.getTime())) { - validTime = true - isToday = d.toDateString() === now.toDateString() - - const diff = now - d - diffHours = (diff > 0 ? diff : 0) / (1000 * 3600) - diffDays = diffHours / 24 - - // 🌟 核心修改点:生成标准显示格式 YYYY-MM-DD HH:mm:ss 🌟 const y = d.getFullYear() const m = String(d.getMonth() + 1).padStart(2, '0') const dd = String(d.getDate()).padStart(2, '0') @@ -429,29 +426,33 @@ const fetchData = async () => { } } - // 4. 状态判定 + // 4. 状态判定(分级由后端给出,这里只做映射,不再本地判天数) let statusColor = '#67C23A', statusLabel = '正常', statusType = 'normal', statusLabelColor = '#fff' let statusReason = '' - let sortWeight = diffHours + // 排序权重:问题设备排前面。staleDays * 24 与原 diffHours 同为小时量纲, + // 排序结果与原实现一致(同为“当天”的设备不再按小时细分,顺序退化为稳定序) + let sortWeight = (staleDays === null) ? 80000000 : staleDays * 24 if (item.is_maintaining) { statusColor = '#409EFF'; statusLabel = '维修中'; statusType = 'maintenance'; sortWeight = Number.MAX_SAFE_INTEGER; } else if (!validTime || item.status === 'offline') { statusLabel = '离线'; statusColor = '#F56C6C'; statusType = 'error'; - statusReason = validTime ? '设备离线' : '暂无数据'; + // 文案与后端 offset 统一:拿不到可解析的数据时间就说“从未同步”, + // 不再另造一套“暂无数据”的说法 + statusReason = (item.status === 'offline') ? '设备离线' : (item.offset || '从未同步'); sortWeight = 80000000; - } else if (diffDays > 7) { + } else if (staleLevel === 'severe') { statusLabel = '严重滞后'; statusColor = '#F56C6C'; statusType = 'error'; - statusReason = `滞后 ${Math.floor(diffDays)} 天`; - } else if (diffHours > 24) { + statusReason = item.offset || `滞后 ${staleDays} 天`; + } else if (staleLevel === 'lagging') { statusLabel = '滞后'; statusColor = '#E6A23C'; statusType = 'warning'; - statusReason = `滞后 ${Math.floor(diffDays)} 天`; + statusReason = item.offset || `滞后 ${staleDays} 天`; } else if (expireWarning) { statusLabel = '即将过期'; statusColor = '#E6A23C'; statusType = 'warning'; statusReason = `即将过期`; sortWeight = 400; - } else if (!isToday) { + } else if (staleLevel === 'yesterday') { statusLabel = '昨日数据'; statusColor = '#FAC858'; statusType = 'slight-warning'; statusLabelColor = '#333'; statusReason = '非今日数据'; } else { @@ -465,7 +466,7 @@ const fetchData = async () => { isOrphanIoT, isBound, isWhitelist, - diffDays, diffHours, sortWeight, isToday, + sortWeight, staleLevel, staleDays, statusColor, statusLabel, statusType, statusLabelColor, statusReason, isEditingSite: false, tempSite: '', data_quality: item.data_quality || 'ok',