diff --git a/app.py b/app.py index 8141e37..27daa89 100644 --- a/app.py +++ b/app.py @@ -1103,7 +1103,7 @@ HTML_TEMPLATE = ''' - 项目服务管理面板 v3.0 + 项目服务管理面板 v3.1 @@ -1751,6 +1751,18 @@ HTML_TEMPLATE = ''' +
+ +

在此时间段内不发送邮件通知(如夜间休息时段)

+
+ + + + + +
+
+
@@ -2396,20 +2408,24 @@ HTML_TEMPLATE = ''' const resourceNames = { 'cpu': 'CPU', 'memory': '内存', 'disk': '磁盘' }; - list.innerHTML = rules.map(rule => ` + list.innerHTML = rules.map(rule => { + const silentInfo = rule.silentEnabled ? `静默:${rule.silentStart}-${rule.silentEnd}` : ''; + return `
-
+
${rule.enabled ? '启用' : '禁用'} ${rule.name} ${resourceNames[rule.resource]} ≥ ${rule.threshold}% → ${rule.email} + ${silentInfo ? ` ${silentInfo}` : ''}
- `).join(''); + `; + }).join(''); } function showAddEmailRuleModal() { @@ -2420,6 +2436,9 @@ HTML_TEMPLATE = ''' document.getElementById('emailRuleThreshold').value = 80; document.getElementById('emailRuleAddress').value = ''; document.getElementById('emailRuleInterval').value = 300; + document.getElementById('emailRuleSilentStart').value = '23:00'; + document.getElementById('emailRuleSilentEnd').value = '08:00'; + document.getElementById('emailRuleSilentEnabled').checked = false; document.getElementById('emailRuleEnabled').checked = true; document.getElementById('emailRuleModal').classList.remove('hidden'); } @@ -2440,6 +2459,9 @@ HTML_TEMPLATE = ''' document.getElementById('emailRuleThreshold').value = rule.threshold; document.getElementById('emailRuleAddress').value = rule.email; document.getElementById('emailRuleInterval').value = rule.interval; + document.getElementById('emailRuleSilentStart').value = rule.silentStart || '23:00'; + document.getElementById('emailRuleSilentEnd').value = rule.silentEnd || '08:00'; + document.getElementById('emailRuleSilentEnabled').checked = rule.silentEnabled || false; document.getElementById('emailRuleEnabled').checked = rule.enabled; document.getElementById('emailRuleModal').classList.remove('hidden'); } @@ -2453,6 +2475,9 @@ HTML_TEMPLATE = ''' const threshold = parseInt(document.getElementById('emailRuleThreshold').value); const email = document.getElementById('emailRuleAddress').value.trim(); const interval = parseInt(document.getElementById('emailRuleInterval').value) || 300; + const silentStart = document.getElementById('emailRuleSilentStart').value; + const silentEnd = document.getElementById('emailRuleSilentEnd').value; + const silentEnabled = document.getElementById('emailRuleSilentEnabled').checked; const enabled = document.getElementById('emailRuleEnabled').checked; if (!name || !email) { @@ -2466,13 +2491,13 @@ HTML_TEMPLATE = ''' // 编辑 const idx = rules.findIndex(r => r.id === ruleId); if (idx >= 0) { - rules[idx] = { ...rules[idx], name, resource, threshold, email, interval, enabled }; + rules[idx] = { ...rules[idx], name, resource, threshold, email, interval, silentStart, silentEnd, silentEnabled, enabled }; } } else { // 新增 rules.push({ id: 'rule_' + Date.now(), - name, resource, threshold, email, interval, enabled, + name, resource, threshold, email, interval, silentStart, silentEnd, silentEnabled, enabled, lastSent: 0 }); } @@ -2493,11 +2518,36 @@ HTML_TEMPLATE = ''' async function checkEmailRules(data) { const rules = getEmailRules().filter(r => r.enabled); const now = Date.now(); + const nowTime = new Date(); + const currentHour = nowTime.getHours(); + const currentMin = nowTime.getMinutes(); + const currentTimeStr = `${currentHour.toString().padStart(2, '0')}:${currentMin.toString().padStart(2, '0')}`; for (const rule of rules) { // 检查间隔 if (now - rule.lastSent < rule.interval * 1000) continue; + // 检查静默时间 + if (rule.silentEnabled && rule.silentStart && rule.silentEnd) { + const start = rule.silentStart; + const end = rule.silentEnd; + + // 处理跨越午夜的情况(如23:00到08:00) + let inSilentPeriod = false; + if (start > end) { + // 跨越午夜:如23:00-08:00,则currentTime >= start 或 currentTime < end 都在静默区间 + inSilentPeriod = (currentTimeStr >= start || currentTimeStr < end); + } else { + // 同一天内:如01:00-06:00 + inSilentPeriod = (currentTimeStr >= start && currentTimeStr < end); + } + + if (inSilentPeriod) { + console.log(`规则 ${rule.name} 当前在静默时间段 ${start}-${end},跳过发送`); + continue; + } + } + // 检查阈值 const value = data[rule.resource]?.percent; if (value === undefined || value < rule.threshold) continue; diff --git a/logs/app.log b/logs/app.log index 6c1531a..8f1e1de 100644 Binary files a/logs/app.log and b/logs/app.log differ