From 26d751b07137bd29451ff297f01e984a1302f381 Mon Sep 17 00:00:00 2001 From: xxm Date: Sat, 22 Aug 2026 09:56:43 +0800 Subject: [PATCH] =?UTF-8?q?feat(alert):=20=E5=BC=82=E5=B8=B8=E6=B5=AE?= =?UTF-8?q?=E5=8A=A8=E6=96=B0=E8=A1=8C=E4=B8=BA=E2=80=94=E2=80=9424h?= =?UTF-8?q?=E8=BF=87=E6=BB=A4+=E6=96=B0=E5=BC=82=E5=B8=B83=E7=A7=92?= =?UTF-8?q?=E5=B1=95=E5=BC=80=E6=8A=98=E5=8F=A0+=E5=B7=B2=E5=B1=95?= =?UTF-8?q?=E5=BC=80=E4=B8=8D=E9=87=8D=E5=A4=8D+=E9=A6=96=E6=AC=A1?= =?UTF-8?q?=E5=8A=A0=E8=BD=BD=E4=B8=8D=E5=BC=B9=E6=97=A7=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- static/index.html | 61 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 45 insertions(+), 16 deletions(-) diff --git a/static/index.html b/static/index.html index db7ce3fa..b0bb4a83 100644 --- a/static/index.html +++ b/static/index.html @@ -3077,16 +3077,40 @@ function toggleAlertFloat(ev) { } function renderAlerts(alerts) { + // 首次加载初始化:把当前已有异常标记为"已展开",避免打开页面就弹旧异常 + if (!localStorage.getItem('alertsInitialized')) { + try { + const initKeys = (Array.isArray(alerts)?alerts:[]).map(a => (a.ts||0)+'_'+(a.source||'')+'_'+(a.code||'')); + localStorage.setItem('expandedAlertKeys', JSON.stringify(initKeys)); + localStorage.setItem('alertsInitialized', '1'); + } catch(e) {} + } const el = document.getElementById('alertFloat'); const body = document.getElementById('alertBody'); const countEl = document.getElementById('alertCount'); const list = Array.isArray(alerts) ? alerts : []; // 只显示 error/critical/warning(info 不打扰) const shown = list.filter(a => a.level !== 'info'); - const keys = shown.map(a => a.ts + '_' + a.source + '_' + a.code).join('|'); - if (!shown.length) { - // 无异常 → 整个浮窗隐藏(2026-08-13 老莫反馈:无异常不应显示红底感叹号) + // ── 24小时过滤:只有24小时内的异常才算"最新异常",有资格右上角显示 ── + const nowSec = Date.now() / 1000; + const fresh = shown.filter(a => (a.ts || 0) > nowSec - 86400); + + // 已展开过的异常 keys(localStorage 持久化,跨会话记住,旧异常不再触发展开) + let expandedKeys = new Set(); + try { expandedKeys = new Set(JSON.parse(localStorage.getItem('expandedAlertKeys') || '[]')); } catch(e) {} + // 清理过期的已展开记录(24小时前的清掉,避免无限增长) + const expandedArr = [...expandedKeys]; + + const freshKeys = fresh.map(a => (a.ts||0) + '_' + (a.source||'') + '_' + (a.code||'')); + const freshKeySet = new Set(freshKeys); + + // 找出"新异常":在24小时内,且从未被展开过 + const newKeys = freshKeys.filter(k => !expandedKeys.has(k)); + const hasNew = newKeys.length > 0; + + if (!fresh.length) { + // 无最新异常 → 隐藏浮窗 el.style.display = 'none'; el.classList.add('collapsed'); body.style.display = 'none'; @@ -3096,29 +3120,27 @@ function renderAlerts(alerts) { return; } - // 有异常 → 显示浮窗 + // 有最新异常 → 显示浮窗 el.style.display = ''; - - // 新异常 → 自动展开几秒后折叠 - const isNew = keys !== lastAlertKeys; - lastAlertKeys = keys; - countEl.style.display = 'inline-block'; - countEl.textContent = shown.length; + countEl.textContent = fresh.length; const levelIcon = { critical: '🔴', error: '🟠', warning: '🟡' }; - body.innerHTML = shown.map(a => + body.innerHTML = fresh.map(a => `
${levelIcon[a.level]||'🟠'} ${a.source||''} ${a.code ? `${a.code}` : ''}
-
${a.title || ''}
- ${a.detail ? `
${a.detail}
` : ''} +
${esc(a.title || '')}
+ ${a.detail ? `
${esc(a.detail)}
` : ''}
${a.ts_str || ''}
` ).join(''); - // 折叠态且新消息 → 展开 5 秒自动收起 - if (isNew && el.classList.contains('collapsed')) { + // ── 展开逻辑:只有"新异常"(未展开过)才触发自动展开 ── + const isCurrentlyCollapsed = el.classList.contains('collapsed'); + + if (hasNew && isCurrentlyCollapsed) { + // 展开 3 秒后自动折叠 el.classList.remove('collapsed'); body.style.display = 'block'; el.querySelector('.alert-toggle').textContent = '▴'; @@ -3128,8 +3150,15 @@ function renderAlerts(alerts) { body.style.display = 'none'; el.querySelector('.alert-toggle').textContent = '▾'; alertAutoHideTimer = null; - }, 5000); + }, 3000); + + // 把这些新异常标记为"已展开过"(持久化,之后不再触发) + newKeys.forEach(k => expandedKeys.add(k)); + try { localStorage.setItem('expandedAlertKeys', JSON.stringify([...expandedKeys])); } catch(e) {} } + + lastAlertKeys = freshKeys.join('|'); +} } // refreshAll 内联渲染:把 alerts 交给 renderAlerts