feat(ops): 添加自动刷新配置功能

功能特性:
- 支持配置启用/禁用自动刷新
- 可配置刷新间隔(15秒/30秒/60秒)
- 实时倒计时显示,用户可见下次刷新时间
- 手动刷新自动重置倒计时
- 页面卸载时自动清理定时器

用户体验:
- 默认禁用,用户可根据需求开启
- 与现有 OpsConcurrencyCard 5秒刷新保持一致
- 倒计时带旋转动画,视觉反馈清晰
- 配置修改后立即生效,无需刷新页面

技术实现:
- ops.ts: 添加 auto_refresh_enabled 和 auto_refresh_interval_seconds 配置
- OpsSettingsDialog.vue: 添加自动刷新配置界面
- OpsDashboard.vue: 实现主刷新逻辑和双定时器设计
- OpsDashboardHeader.vue: 倒计时显示组件

配置说明:
- auto_refresh_enabled: 是否启用(默认 false)
- auto_refresh_interval_seconds: 刷新间隔(默认 30 秒,范围 15-300 秒)
This commit is contained in:
IanShaw027
2026-01-12 16:50:53 +08:00
parent 345a965fa3
commit b98fb013ae
4 changed files with 135 additions and 1 deletions

View File

@@ -20,6 +20,8 @@
:loading="loading"
:last-updated="lastUpdated"
:thresholds="metricThresholds"
:auto-refresh-enabled="autoRefreshEnabled"
:auto-refresh-countdown="autoRefreshCountdown"
@update:time-range="onTimeRangeChange"
@update:platform="onPlatformChange"
@update:group="onGroupChange"
@@ -104,7 +106,7 @@
<script setup lang="ts">
import { computed, onMounted, onUnmounted, ref, watch } from 'vue'
import { useDebounceFn } from '@vueuse/core'
import { useDebounceFn, useIntervalFn } from '@vueuse/core'
import { useI18n } from 'vue-i18n'
import { useRoute, useRouter } from 'vue-router'
import AppLayout from '@/components/layout/AppLayout.vue'
@@ -287,6 +289,45 @@ const requestDetailsPreset = ref<OpsRequestDetailsPreset>({
const showSettingsDialog = ref(false)
const showAlertRulesCard = ref(false)
// Auto refresh settings
const autoRefreshEnabled = ref(false)
const autoRefreshIntervalMs = ref(30000) // default 30 seconds
const autoRefreshCountdown = ref(0)
// Auto refresh timer
const { pause: pauseAutoRefresh, resume: resumeAutoRefresh, isActive: isAutoRefreshActive } = useIntervalFn(
() => {
if (autoRefreshEnabled.value && opsEnabled.value && !loading.value) {
fetchData()
}
},
autoRefreshIntervalMs,
{ immediate: false }
)
// Countdown timer (updates every second)
const { pause: pauseCountdown, resume: resumeCountdown } = useIntervalFn(
() => {
if (autoRefreshEnabled.value && autoRefreshCountdown.value > 0) {
autoRefreshCountdown.value--
}
},
1000,
{ immediate: false }
)
// Load auto refresh settings from backend
async function loadAutoRefreshSettings() {
try {
const settings = await opsAPI.getAdvancedSettings()
autoRefreshEnabled.value = settings.auto_refresh_enabled
autoRefreshIntervalMs.value = settings.auto_refresh_interval_seconds * 1000
autoRefreshCountdown.value = settings.auto_refresh_interval_seconds
} catch (err) {
console.error('[OpsDashboard] Failed to load auto refresh settings', err)
}
}
function handleThroughputSelectPlatform(nextPlatform: string) {
platform.value = nextPlatform || ''
groupId.value = null
@@ -510,6 +551,10 @@ async function fetchData() {
])
if (fetchSeq !== dashboardFetchSeq) return
lastUpdated.value = new Date()
// Reset auto refresh countdown after successful fetch
if (autoRefreshEnabled.value) {
autoRefreshCountdown.value = Math.floor(autoRefreshIntervalMs.value / 1000)
}
} catch (err) {
if (!isOpsDisabledError(err)) {
console.error('[ops] failed to fetch dashboard data', err)
@@ -567,9 +612,18 @@ onMounted(async () => {
// Load thresholds configuration
loadThresholds()
// Load auto refresh settings
await loadAutoRefreshSettings()
if (opsEnabled.value) {
await fetchData()
}
// Start auto refresh if enabled
if (autoRefreshEnabled.value) {
resumeAutoRefresh()
resumeCountdown()
}
})
async function loadThresholds() {
@@ -584,5 +638,27 @@ async function loadThresholds() {
onUnmounted(() => {
abortDashboardFetch()
pauseAutoRefresh()
pauseCountdown()
})
// Watch auto refresh settings changes
watch(autoRefreshEnabled, (enabled) => {
if (enabled) {
autoRefreshCountdown.value = Math.floor(autoRefreshIntervalMs.value / 1000)
resumeAutoRefresh()
resumeCountdown()
} else {
pauseAutoRefresh()
pauseCountdown()
autoRefreshCountdown.value = 0
}
})
// Reload auto refresh settings after settings dialog is closed
watch(showSettingsDialog, async (show) => {
if (!show) {
await loadAutoRefreshSettings()
}
})
</script>