diff --git a/backend/internal/api/auto_add.go b/backend/internal/api/auto_add.go index f6f03f8..081e59b 100644 --- a/backend/internal/api/auto_add.go +++ b/backend/internal/api/auto_add.go @@ -34,15 +34,24 @@ func StartAutoAddService() { logger.Info("自动补号检查器已启动(需在前端开启开关)", "", "auto-add") go func() { - ticker := time.NewTicker(60 * time.Second) // 每分钟检查一次 - defer ticker.Stop() + // 默认检查间隔 60 秒 + checkInterval := 60 for { + // 动态读取检查间隔配置 + if database.Instance != nil { + if val, _ := database.Instance.GetConfig("monitor_check_interval"); val != "" { + if v, err := strconv.Atoi(val); err == nil && v >= 10 { + checkInterval = v + } + } + } + select { case <-autoAddStopChan: logger.Info("自动补号检查器已停止", "", "auto-add") return - case <-ticker.C: + case <-time.After(time.Duration(checkInterval) * time.Second): checkAndAutoAdd() } } @@ -72,6 +81,7 @@ func checkAndAutoAdd() { autoAddEnabled = true } if !autoAddEnabled { + // 自动补号未开启,静默返回 return } @@ -83,7 +93,11 @@ func checkAndAutoAdd() { } } - if time.Since(lastAutoAddTime).Seconds() < float64(minInterval) { + elapsed := time.Since(lastAutoAddTime).Seconds() + if elapsed < float64(minInterval) { + // 距离上次补号时间不足,显示等待信息 + remaining := float64(minInterval) - elapsed + logger.Info(fmt.Sprintf("自动补号: 等待中 (还需 %.0f 秒)", remaining), "", "auto-add") return } @@ -110,6 +124,7 @@ func checkAndAutoAdd() { deficit := target - current if deficit <= 0 { + logger.Info(fmt.Sprintf("自动补号: 当前 %d >= 目标 %d, 无需补号", current, target), "", "auto-add") return } diff --git a/backend/internal/api/monitor.go b/backend/internal/api/monitor.go index b235438..37180bb 100644 --- a/backend/internal/api/monitor.go +++ b/backend/internal/api/monitor.go @@ -14,6 +14,7 @@ type MonitorSettings struct { Target int `json:"target"` AutoAdd bool `json:"auto_add"` MinInterval int `json:"min_interval"` + CheckInterval int `json:"check_interval"` // 自动补号检查间隔(秒) PollingEnabled bool `json:"polling_enabled"` PollingInterval int `json:"polling_interval"` } @@ -34,6 +35,7 @@ func HandleGetMonitorSettings(w http.ResponseWriter, r *http.Request) { Target: 50, AutoAdd: false, MinInterval: 300, + CheckInterval: 60, PollingEnabled: false, PollingInterval: 60, } @@ -51,6 +53,11 @@ func HandleGetMonitorSettings(w http.ResponseWriter, r *http.Request) { settings.MinInterval = v } } + if val, _ := database.Instance.GetConfig("monitor_check_interval"); val != "" { + if v, err := strconv.Atoi(val); err == nil { + settings.CheckInterval = v + } + } if val, _ := database.Instance.GetConfig("monitor_polling_enabled"); val == "true" { settings.PollingEnabled = true } @@ -85,6 +92,7 @@ func HandleSaveMonitorSettings(w http.ResponseWriter, r *http.Request) { logger.Info("收到保存监控设置请求: target="+strconv.Itoa(settings.Target)+ ", auto_add="+strconv.FormatBool(settings.AutoAdd)+ + ", check_interval="+strconv.Itoa(settings.CheckInterval)+ ", polling="+strconv.FormatBool(settings.PollingEnabled), "", "monitor") // 保存到数据库 @@ -98,6 +106,14 @@ func HandleSaveMonitorSettings(w http.ResponseWriter, r *http.Request) { if err := database.Instance.SetConfig("monitor_min_interval", strconv.Itoa(settings.MinInterval)); err != nil { saveErrors = append(saveErrors, "min_interval: "+err.Error()) } + // 检查间隔最小10秒 + checkInterval := settings.CheckInterval + if checkInterval < 10 { + checkInterval = 10 + } + if err := database.Instance.SetConfig("monitor_check_interval", strconv.Itoa(checkInterval)); err != nil { + saveErrors = append(saveErrors, "check_interval: "+err.Error()) + } if err := database.Instance.SetConfig("monitor_polling_enabled", strconv.FormatBool(settings.PollingEnabled)); err != nil { saveErrors = append(saveErrors, "polling_enabled: "+err.Error()) } @@ -115,8 +131,9 @@ func HandleSaveMonitorSettings(w http.ResponseWriter, r *http.Request) { // 输出日志 logger.Success("监控设置已保存: target="+strconv.Itoa(settings.Target)+ ", auto_add="+strconv.FormatBool(settings.AutoAdd)+ + ", check_interval="+strconv.Itoa(checkInterval)+"s"+ ", polling="+strconv.FormatBool(settings.PollingEnabled)+ - ", interval="+strconv.Itoa(settings.PollingInterval)+"s", "", "monitor") + ", polling_interval="+strconv.Itoa(settings.PollingInterval)+"s", "", "monitor") Success(w, map[string]interface{}{ "message": "设置已保存", diff --git a/frontend/src/pages/Monitor.tsx b/frontend/src/pages/Monitor.tsx index 5288398..f70058b 100644 --- a/frontend/src/pages/Monitor.tsx +++ b/frontend/src/pages/Monitor.tsx @@ -64,6 +64,7 @@ export default function Monitor() { const [targetInput, setTargetInput] = useState(50) const [autoAdd, setAutoAdd] = useState(false) const [minInterval, setMinInterval] = useState(300) + const [checkInterval, setCheckInterval] = useState(60) const [pollingEnabled, setPollingEnabled] = useState(false) const [pollingInterval, setPollingInterval] = useState(60) @@ -125,6 +126,7 @@ export default function Monitor() { target: targetInput, auto_add: autoAdd, min_interval: minInterval, + check_interval: checkInterval, polling_enabled: pollingEnabled, polling_interval: pollingInterval, }), @@ -169,6 +171,7 @@ export default function Monitor() { target: targetInput, auto_add: autoAdd, min_interval: minInterval, + check_interval: checkInterval, polling_enabled: newPollingEnabled, polling_interval: pollingInterval, }), @@ -195,6 +198,7 @@ export default function Monitor() { target: targetInput, auto_add: autoAdd, min_interval: minInterval, + check_interval: checkInterval, polling_enabled: pollingEnabled, polling_interval: pollingInterval, }), @@ -257,19 +261,21 @@ export default function Monitor() { const target = s.target || 50 const autoAddVal = s.auto_add || false const minIntervalVal = s.min_interval || 300 + const checkIntervalVal = s.check_interval || 60 const pollingEnabledVal = s.polling_enabled || false const interval = s.polling_interval || 60 setTargetInput(target) setAutoAdd(autoAddVal) setMinInterval(minIntervalVal) + setCheckInterval(checkIntervalVal) setPollingEnabled(pollingEnabledVal) setPollingInterval(interval) savedPollingIntervalRef.current = interval setCountdown(interval) // 返回加载的配置用于后续刷新 - return { target, autoAdd: autoAddVal, minInterval: minIntervalVal, pollingEnabled: pollingEnabledVal, pollingInterval: interval } + return { target, autoAdd: autoAddVal, minInterval: minIntervalVal, checkInterval: checkIntervalVal, pollingEnabled: pollingEnabledVal, pollingInterval: interval } } } } catch (e) { @@ -515,6 +521,16 @@ export default function Monitor() { hint="两次自动补号的最小间隔" disabled={!autoAdd} /> + setCheckInterval(Number(e.target.value))} + hint="自动补号检查频率 (10-300秒)" + disabled={!autoAdd} + />