refactor(ops): 简化自动刷新定时器逻辑
- 合并双定时器为单一倒计时定时器 - 倒计时归零时触发数据刷新 - 添加自定义时间范围的安全回退
This commit is contained in:
@@ -2048,6 +2048,7 @@ export default {
|
||||
lastRun: '最近运行',
|
||||
lastSuccess: '最近成功',
|
||||
lastError: '最近错误',
|
||||
result: '结果',
|
||||
noData: '暂无数据',
|
||||
loadingText: '加载中...',
|
||||
ready: '就绪',
|
||||
|
||||
@@ -414,7 +414,17 @@ const handleScroll = () => {
|
||||
menu.show = false
|
||||
}
|
||||
|
||||
onMounted(async () => { load(); try { const [p, g] = await Promise.all([adminAPI.proxies.getAll(), adminAPI.groups.getAll()]); proxies.value = p; groups.value = g } catch (error) { console.error('Failed to load proxies/groups:', error) } window.addEventListener('scroll', handleScroll, true) })
|
||||
onMounted(async () => {
|
||||
load()
|
||||
try {
|
||||
const [p, g] = await Promise.all([adminAPI.proxies.getAll(), adminAPI.groups.getAll()])
|
||||
proxies.value = p
|
||||
groups.value = g
|
||||
} catch (error) {
|
||||
console.error('Failed to load proxies/groups:', error)
|
||||
}
|
||||
window.addEventListener('scroll', handleScroll, true)
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener('scroll', handleScroll, true)
|
||||
|
||||
@@ -355,23 +355,21 @@ const autoRefreshCountdown = ref(0)
|
||||
// Used to trigger child component refreshes in a single shared cadence.
|
||||
const dashboardRefreshToken = ref(0)
|
||||
|
||||
// Auto refresh timer
|
||||
const { pause: pauseAutoRefresh, resume: resumeAutoRefresh } = useIntervalFn(
|
||||
() => {
|
||||
if (autoRefreshEnabled.value && opsEnabled.value && !loading.value) {
|
||||
fetchData()
|
||||
}
|
||||
},
|
||||
autoRefreshIntervalMs,
|
||||
{ immediate: false }
|
||||
)
|
||||
|
||||
// Countdown timer (updates every second)
|
||||
// Countdown timer (drives auto refresh; updates every second)
|
||||
const { pause: pauseCountdown, resume: resumeCountdown } = useIntervalFn(
|
||||
() => {
|
||||
if (autoRefreshEnabled.value && autoRefreshCountdown.value > 0) {
|
||||
autoRefreshCountdown.value--
|
||||
if (!autoRefreshEnabled.value) return
|
||||
if (!opsEnabled.value) return
|
||||
if (loading.value) return
|
||||
|
||||
if (autoRefreshCountdown.value <= 0) {
|
||||
// Fetch immediately when the countdown reaches 0.
|
||||
// fetchData() will reset the countdown to the full interval.
|
||||
fetchData()
|
||||
return
|
||||
}
|
||||
|
||||
autoRefreshCountdown.value -= 1
|
||||
},
|
||||
1000,
|
||||
{ immediate: false }
|
||||
@@ -477,12 +475,19 @@ function buildApiParams() {
|
||||
group_id: groupId.value ?? undefined,
|
||||
mode: queryMode.value
|
||||
}
|
||||
if (timeRange.value === 'custom' && customStartTime.value && customEndTime.value) {
|
||||
params.start_time = customStartTime.value
|
||||
params.end_time = customEndTime.value
|
||||
|
||||
if (timeRange.value === 'custom') {
|
||||
if (customStartTime.value && customEndTime.value) {
|
||||
params.start_time = customStartTime.value
|
||||
params.end_time = customEndTime.value
|
||||
} else {
|
||||
// Safety fallback: avoid sending time_range=custom (backend may not support it)
|
||||
params.time_range = '1h'
|
||||
}
|
||||
} else {
|
||||
params.time_range = timeRange.value
|
||||
}
|
||||
|
||||
return params
|
||||
}
|
||||
|
||||
@@ -679,7 +684,6 @@ onMounted(async () => {
|
||||
|
||||
// Start auto refresh if enabled
|
||||
if (autoRefreshEnabled.value) {
|
||||
resumeAutoRefresh()
|
||||
resumeCountdown()
|
||||
}
|
||||
})
|
||||
@@ -697,7 +701,6 @@ async function loadThresholds() {
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener('keydown', handleKeydown)
|
||||
abortDashboardFetch()
|
||||
pauseAutoRefresh()
|
||||
pauseCountdown()
|
||||
})
|
||||
|
||||
@@ -705,10 +708,8 @@ onUnmounted(() => {
|
||||
watch(autoRefreshEnabled, (enabled) => {
|
||||
if (enabled) {
|
||||
autoRefreshCountdown.value = Math.floor(autoRefreshIntervalMs.value / 1000)
|
||||
resumeAutoRefresh()
|
||||
resumeCountdown()
|
||||
} else {
|
||||
pauseAutoRefresh()
|
||||
pauseCountdown()
|
||||
autoRefreshCountdown.value = 0
|
||||
}
|
||||
|
||||
@@ -191,8 +191,10 @@ function handleCustomTimeRangeConfirm() {
|
||||
if (!customStartTimeInput.value || !customEndTimeInput.value) return
|
||||
const startTime = new Date(customStartTimeInput.value).toISOString()
|
||||
const endTime = new Date(customEndTimeInput.value).toISOString()
|
||||
emit('update:timeRange', 'custom')
|
||||
// Emit custom time range first so the parent can build correct API params
|
||||
// when it reacts to timeRange switching to "custom".
|
||||
emit('update:customTimeRange', startTime, endTime)
|
||||
emit('update:timeRange', 'custom')
|
||||
showCustomTimeRangeDialog.value = false
|
||||
}
|
||||
|
||||
@@ -221,8 +223,14 @@ function getSLAThresholdLevel(slaPercent: number | null): ThresholdLevel {
|
||||
if (slaPercent == null) return 'normal'
|
||||
const threshold = props.thresholds?.sla_percent_min
|
||||
if (threshold == null) return 'normal'
|
||||
|
||||
// SLA is "higher is better":
|
||||
// - below threshold => critical
|
||||
// - within +0.1% buffer => warning
|
||||
const warningBuffer = 0.1
|
||||
|
||||
if (slaPercent < threshold) return 'critical'
|
||||
if (slaPercent < threshold / 0.8) return 'warning'
|
||||
if (slaPercent < threshold + warningBuffer) return 'warning'
|
||||
return 'normal'
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user