From 6fa90252dfdad3891feb7009ccbda666ae653f6b Mon Sep 17 00:00:00 2001 From: dushixiang Date: Sat, 17 Jan 2026 14:06:30 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=20ddns=20=E7=BC=93=E5=AD=98?= =?UTF-8?q?=E6=B8=85=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/repo/ddns_config_repo.go | 10 +++++ internal/service/ddns_service.go | 69 +++++++++++++++++++++++++++++-- 2 files changed, 75 insertions(+), 4 deletions(-) diff --git a/internal/repo/ddns_config_repo.go b/internal/repo/ddns_config_repo.go index 21554fe..d8c3f3e 100644 --- a/internal/repo/ddns_config_repo.go +++ b/internal/repo/ddns_config_repo.go @@ -62,3 +62,13 @@ func (r *DDNSConfigRepo) FindAllEnabled(ctx context.Context) ([]models.DDNSConfi Find(&configs).Error return configs, err } + +// ListAgentIDs 返回所有配置关联的探针ID(去重) +func (r *DDNSConfigRepo) ListAgentIDs(ctx context.Context) ([]string, error) { + var agentIDs []string + err := r.db.WithContext(ctx). + Model(&models.DDNSConfig{}). + Distinct(). + Pluck("agent_id", &agentIDs).Error + return agentIDs, err +} diff --git a/internal/service/ddns_service.go b/internal/service/ddns_service.go index 9208f54..9c96acd 100644 --- a/internal/service/ddns_service.go +++ b/internal/service/ddns_service.go @@ -132,6 +132,14 @@ func (s *DDNSService) initIPCache() { s.logger.Info("IP 缓存初始化完成") } +func (s *DDNSService) clearIPCache(agentID string, reason string) { + if agentID == "" { + return + } + s.ipCache.Delete(agentID) + s.logger.Debug("清理 IP 缓存", zap.String("agentId", agentID), zap.String("reason", reason)) +} + // HandleIPReport 处理客户端上报的 IP 地址 func (s *DDNSService) HandleIPReport(ctx context.Context, agentID string, ipData *protocol.DDNSIPReportData) error { // 获取该探针的 DDNS 配置 @@ -327,13 +335,33 @@ func (s *DDNSService) CreateConfig(ctx context.Context, config *models.DDNSConfi // UpdateConfig 更新 DDNS 配置 func (s *DDNSService) UpdateConfig(ctx context.Context, config *models.DDNSConfig) error { - return s.ConfigRepo.Save(ctx, config) + if err := s.ConfigRepo.Save(ctx, config); err != nil { + return err + } + s.clearIPCache(config.AgentID, "config_updated") + return nil } func (s *DDNSService) UpdateEnabled(ctx context.Context, id string, enabled bool) error { - return s.ConfigRepo.UpdateColumnsById(ctx, id, map[string]interface{}{ + config, err := s.GetConfig(ctx, id) + if err != nil { + return err + } + if err := s.ConfigRepo.UpdateColumnsById(ctx, id, map[string]interface{}{ "enabled": enabled, - }) + }); err != nil { + return err + } + config.Enabled = enabled + s.clearIPCache(config.AgentID, "enabled_updated") + if enabled { + if err := s.sendDDNSConfigToAgent(config); err != nil { + s.logger.Debug("启用后发送 DDNS 配置失败", + zap.String("agentID", config.AgentID), + zap.Error(err)) + } + } + return nil } // GetConfig 获取 DDNS 配置 @@ -347,12 +375,22 @@ func (s *DDNSService) GetConfig(ctx context.Context, id string) (*models.DDNSCon // DeleteConfig 删除 DDNS 配置 func (s *DDNSService) DeleteConfig(ctx context.Context, id string) error { + config, err := s.GetConfig(ctx, id) + if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { + return err + } // 先删除相关记录 if err := s.recordRepo.DeleteByConfigID(ctx, id); err != nil { return err } // 删除配置 - return s.ConfigRepo.DeleteById(ctx, id) + if err := s.ConfigRepo.DeleteById(ctx, id); err != nil { + return err + } + if err == nil { + s.clearIPCache(config.AgentID, "config_deleted") + } + return nil } // Run 启动 DDNS 定时任务 @@ -385,6 +423,27 @@ func (s *DDNSService) checkDDNS() { return } + enabledAgents := make(map[string]struct{}, len(configs)) + for _, config := range configs { + if config.AgentID != "" { + enabledAgents[config.AgentID] = struct{}{} + } + } + + allAgents, err := s.ConfigRepo.ListAgentIDs(ctx) + if err != nil { + s.logger.Error("查询 DDNS 探针列表失败", zap.Error(err)) + } else { + for _, agentID := range allAgents { + if agentID == "" { + continue + } + if _, ok := enabledAgents[agentID]; !ok { + s.clearIPCache(agentID, "disabled_or_missing") + } + } + } + // 并发向每个配置对应的在线探针发送 DDNS 配置 for _, config := range configs { agentID := config.AgentID @@ -431,6 +490,8 @@ func (s *DDNSService) TriggerUpdate(ctx context.Context, configID string) error return fmt.Errorf("DDNS 配置未启用") } + s.clearIPCache(config.AgentID, "manual_trigger") + // 向探针发送配置,触发探针立即上报 IP if err := s.sendDDNSConfigToAgent(config); err != nil { return fmt.Errorf("向探针发送配置失败: %w", err)