fix: 修复轮询停机连坐、实名逆转防抖及carrier_stopped原因写入缺失三个逻辑缺陷
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 9m37s

This commit is contained in:
2026-04-20 11:24:56 +08:00
parent fd795d8742
commit 868f5a8ef3
11 changed files with 514 additions and 10 deletions

View File

@@ -97,6 +97,10 @@ func (h *PollingCardStatusHandler) Handle(ctx context.Context, t *asynq.Task) er
fields := map[string]any{"last_card_status_check_at": now}
if statusChanged {
fields["network_status"] = newNetworkStatus
// 网关侧停机事件:补写 stop_reason便于状态追踪和区分手动停机
if newNetworkStatus == constants.NetworkStatusOffline && card.StopReason == "" {
fields["stop_reason"] = constants.StopReasonCarrierStopped
}
}
if updateErr := h.iotCardStore.UpdateFields(ctx, cardID, fields); updateErr != nil {
h.base.logger.Warn("更新卡状态信息失败", zap.Uint("card_id", cardID), zap.Error(updateErr))

View File

@@ -139,6 +139,8 @@ func (h *PollingRealnameHandler) Handle(ctx context.Context, t *asynq.Task) erro
zap.Int("new_status", newStatus))
if isFirstRealname {
// 0→1 时清除逆转计数器
h.base.redis.Del(ctx, constants.RedisPollingRealnameReversalCountKey(cardID))
// 0→1首次实名触发套餐激活并立即复机评估不等待下一个 carddata/package 周期)
h.triggerFirstRealnameActivation(ctx, cardID)
h.triggerDeviceRealnameActivation(ctx, cardID)
@@ -152,15 +154,26 @@ func (h *PollingRealnameHandler) Handle(ctx context.Context, t *asynq.Task) erro
}
}
} else if newStatus == constants.RealNameStatusNotVerified {
// 1→0实名逆转立即触发停机评估不等待下一个 carddata/package 周期,否则最长延迟 1 小时)
h.base.logger.Warn("检测到实名逆转,立即触发停机评估",
zap.Uint("card_id", cardID))
if h.stopResumeSvc != nil {
freshCard, loadErr := h.iotCardStore.GetByID(ctx, cardID)
if loadErr == nil {
if evalErr := h.stopResumeSvc.EvaluateAndAct(ctx, freshCard); evalErr != nil {
h.base.logger.Warn("实名逆转后触发停机评估失败",
zap.Uint("card_id", cardID), zap.Error(evalErr))
reversalKey := constants.RedisPollingRealnameReversalCountKey(cardID)
count, incrErr := h.base.redis.Incr(ctx, reversalKey).Result()
if incrErr == nil {
h.base.redis.Expire(ctx, reversalKey, 10*time.Minute)
}
h.base.logger.Warn("检测到实名逆转",
zap.Uint("card_id", cardID),
zap.Int64("reversal_count", count),
zap.Int("threshold", constants.PollingRealnameReversalThreshold))
if count >= int64(constants.PollingRealnameReversalThreshold) {
h.base.redis.Del(ctx, reversalKey)
h.base.logger.Warn("实名逆转达到阈值,触发停机评估",
zap.Uint("card_id", cardID))
if h.stopResumeSvc != nil {
freshCard, loadErr := h.iotCardStore.GetByID(ctx, cardID)
if loadErr == nil {
if evalErr := h.stopResumeSvc.EvaluateAndAct(ctx, freshCard); evalErr != nil {
h.base.logger.Warn("实名逆转后触发停机评估失败",
zap.Uint("card_id", cardID), zap.Error(evalErr))
}
}
}
}