package redisdao import ( "context" "fmt" "time" "git.lzcwy.cn/zhengchiliu/zt-closet-backend/global" "git.lzcwy.cn/zhengchiliu/zt-closet-backend/internal/redismodel" ) // VirtualPayUnpaidSet 标记某虚拟支付订单「最近一次查单确认未支付」,TTL 内不再重复查询。 func VirtualPayUnpaidSet(ctx context.Context, orderNo string, ttl time.Duration) error { ctx, span := global.Tracer.Start(ctx, "redisdao.VirtualPayUnpaidSet") defer span.End() key := fmt.Sprintf(redismodel.KeyVirtualPayUnpaid, orderNo) if err := global.RedisEngine.Set(ctx, key, 1, ttl).Err(); err != nil { span.RecordError(err) return err } return nil } // VirtualPayUnpaidDel 清除负缓存(订单已支付/已处理后调用,让后续流程不再跳过它)。 func VirtualPayUnpaidDel(ctx context.Context, orderNo string) error { ctx, span := global.Tracer.Start(ctx, "redisdao.VirtualPayUnpaidDel") defer span.End() key := fmt.Sprintf(redismodel.KeyVirtualPayUnpaid, orderNo) if err := global.RedisEngine.Del(ctx, key).Err(); err != nil { span.RecordError(err) return err } return nil } // VirtualRefundCheckedSetNX 标记某订单的退款结果本轮已完成反查(TTL 内不重复查询),返回是否为首次标记。 func VirtualRefundCheckedSetNX(ctx context.Context, orderNo string, ttl time.Duration) (bool, error) { ctx, span := global.Tracer.Start(ctx, "redisdao.VirtualRefundCheckedSetNX") defer span.End() key := fmt.Sprintf(redismodel.KeyVirtualRefundChecked, orderNo) ok, err := global.RedisEngine.SetNX(ctx, key, 1, ttl).Result() if err != nil { span.RecordError(err) return false, err } return ok, nil } // VirtualRefundCheckedDel 撤销「已核对」标记:查单失败时调用,让下一轮立即重试而非等待 TTL 过期。 func VirtualRefundCheckedDel(ctx context.Context, orderNo string) error { ctx, span := global.Tracer.Start(ctx, "redisdao.VirtualRefundCheckedDel") defer span.End() key := fmt.Sprintf(redismodel.KeyVirtualRefundChecked, orderNo) if err := global.RedisEngine.Del(ctx, key).Err(); err != nil { span.RecordError(err) return err } return nil } // VirtualRefundStuckAlertSetNX 标记某订单的「退款长期未完成」告警已发出(TTL 内不重复告警),返回是否为首次。 func VirtualRefundStuckAlertSetNX(ctx context.Context, orderNo string, ttl time.Duration) (bool, error) { ctx, span := global.Tracer.Start(ctx, "redisdao.VirtualRefundStuckAlertSetNX") defer span.End() key := fmt.Sprintf(redismodel.KeyVirtualRefundStuckAlert, orderNo) ok, err := global.RedisEngine.SetNX(ctx, key, 1, ttl).Result() if err != nil { span.RecordError(err) return false, err } return ok, nil } // VirtualPayUnpaidBatchGet 批量判断哪些订单命中负缓存。 // 用一次 MGET 代替 N 次 GET,避免逐单往返 Redis 放大单轮耗时。 func VirtualPayUnpaidBatchGet(ctx context.Context, orderNos []string) (map[string]bool, error) { ctx, span := global.Tracer.Start(ctx, "redisdao.VirtualPayUnpaidBatchGet") defer span.End() result := make(map[string]bool, len(orderNos)) if len(orderNos) == 0 { return result, nil } keys := make([]string, 0, len(orderNos)) for _, no := range orderNos { keys = append(keys, fmt.Sprintf(redismodel.KeyVirtualPayUnpaid, no)) } vals, err := global.RedisEngine.MGet(ctx, keys...).Result() if err != nil { span.RecordError(err) return nil, err } for i, v := range vals { if i >= len(orderNos) { break } if v != nil { result[orderNos[i]] = true } } return result, nil }