From 1c6f8ed07b31f1853c14408e47be013d1a16a519 Mon Sep 17 00:00:00 2001 From: huang Date: Tue, 31 Mar 2026 19:59:35 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=81=9C=E5=A4=8D?= =?UTF-8?q?=E6=9C=BA=E6=93=8D=E4=BD=9C=E6=9C=AA=E5=90=8C=E6=AD=A5=E8=BD=AE?= =?UTF-8?q?=E8=AF=A2=E5=8D=A1=E7=BC=93=E5=AD=98=E5=AF=BC=E8=87=B4=E5=8D=A1?= =?UTF-8?q?=E6=97=A0=E6=B3=95=E5=AE=9E=E9=99=85=E5=81=9C=E6=9C=BA=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 多处修改 network_status 的代码只更新了 DB 而未失效轮询缓存(polling:card:{id}), 导致轮询系统持续读取旧缓存值,跳过 Gateway 停机调用。 修复方式:DB 更新后立即 Del 轮询缓存 key,下次轮询自动从 DB 重建。 涉及文件: - StopResumeService: CheckAndStopCard/resumeSingleCard/ManualStopCard/ManualStartCard - iot_card/Service: RefreshCardDataFromGateway(通过 OnCardStatusChanged 回调) - device/Service: StopDevice/StartDevice --- internal/service/device/service.go | 9 ++++++++ internal/service/iot_card/service.go | 5 +++++ .../service/iot_card/stop_resume_service.go | 22 +++++++++++++++++++ 3 files changed, 36 insertions(+) diff --git a/internal/service/device/service.go b/internal/service/device/service.go index 48ba070..35728e9 100644 --- a/internal/service/device/service.go +++ b/internal/service/device/service.go @@ -872,6 +872,7 @@ func (s *Service) StopDevice(ctx context.Context, deviceID uint) (*dto.DeviceSus continue } + s.invalidatePollingCardCache(card.ID) successCount++ } @@ -973,6 +974,7 @@ func (s *Service) StartDevice(ctx context.Context, deviceID uint) error { continue } + s.invalidatePollingCardCache(card.ID) successCount++ } @@ -989,3 +991,10 @@ func (s *Service) StartDevice(ctx context.Context, deviceID uint) error { return nil } + +func (s *Service) invalidatePollingCardCache(cardID uint) { + if s.redis == nil { + return + } + _ = s.redis.Del(context.Background(), constants.RedisPollingCardInfoKey(cardID)).Err() +} diff --git a/internal/service/iot_card/service.go b/internal/service/iot_card/service.go index ebb66fd..a01bf14 100644 --- a/internal/service/iot_card/service.go +++ b/internal/service/iot_card/service.go @@ -876,6 +876,11 @@ func (s *Service) RefreshCardDataFromGateway(ctx context.Context, iccid string) } } + // 失效轮询缓存,确保轮询系统读到最新的 network_status/real_name_status/流量 + if s.pollingCallback != nil { + s.pollingCallback.OnCardStatusChanged(ctx, card.ID) + } + s.logger.Info("刷新卡数据成功", zap.String("iccid", iccid), zap.Uint("card_id", card.ID), diff --git a/internal/service/iot_card/stop_resume_service.go b/internal/service/iot_card/stop_resume_service.go index 0405171..58b1100 100644 --- a/internal/service/iot_card/stop_resume_service.go +++ b/internal/service/iot_card/stop_resume_service.go @@ -98,6 +98,9 @@ func (s *StopResumeService) CheckAndStopCard(ctx context.Context, cardID uint) e return err } + // 失效轮询缓存,确保下次轮询从 DB 读取最新状态 + s.invalidatePollingCache(cardID) + s.logger.Info("卡因流量耗尽已停机", zap.Uint("card_id", cardID), zap.String("iccid", card.ICCID)) @@ -183,6 +186,8 @@ func (s *StopResumeService) resumeSingleCard(ctx context.Context, cardID uint) e return nil } + s.invalidatePollingCache(cardID) + s.logger.Info("卡已自动复机", zap.Uint("card_id", cardID), zap.String("iccid", card.ICCID)) @@ -345,6 +350,9 @@ func (s *StopResumeService) ManualStopCard(ctx context.Context, iccid string) er }).Error; err != nil { return errors.Wrap(errors.CodeDatabaseError, err, "更新卡状态失败") } + + s.invalidatePollingCache(card.ID) + return nil } @@ -384,5 +392,19 @@ func (s *StopResumeService) ManualStartCard(ctx context.Context, iccid string) e }).Error; err != nil { return errors.Wrap(errors.CodeDatabaseError, err, "更新卡状态失败") } + + s.invalidatePollingCache(card.ID) + return nil } + +// invalidatePollingCache 删除轮询卡缓存,下次轮询自动从 DB 重建 +func (s *StopResumeService) invalidatePollingCache(cardID uint) { + if s.redis == nil { + return + } + key := constants.RedisPollingCardInfoKey(cardID) + if err := s.redis.Del(context.Background(), key).Err(); err != nil { + s.logger.Warn("删除轮询卡缓存失败", zap.Uint("card_id", cardID), zap.Error(err)) + } +}