(ctx context.Context, number string)
| 92 | } |
| 93 | |
| 94 | func (s *smsRepository) SendCode(ctx context.Context, number string) error { |
| 95 | // 限制:用户一分钟内只能发送一次sms请求 && 用户一天内只能发送5次SMS请求 |
| 96 | if s.cache.Count(ctx, number) > 5 { |
| 97 | s.l.Warn("用户今日发送验证码次数过多", zap.String("number", number)) |
| 98 | return fmt.Errorf("用户今日发送验证码次数过多") |
| 99 | } |
| 100 | lockResult, err := s.cache.SetNX(ctx, number, locked, time.Second*60) |
| 101 | if err != nil { |
| 102 | s.l.Warn("[smsService SendCode] s.repo.SetNX 报错: ", zap.Error(err)) |
| 103 | return fmt.Errorf("验证码发送过于频繁,请稍后再尝试") |
| 104 | } |
| 105 | if !lockResult.Val() { |
| 106 | return fmt.Errorf("验证码发送过于频繁,请稍后再尝试") |
| 107 | } |
| 108 | vCode := utils.GenRandomCode(6) |
| 109 | smsID, driver, err := mockSMSID, "mock", error(nil) |
| 110 | if viper.GetString("sms.provider") == "tencent" && s.client != nil { |
| 111 | smsID, driver, err = s.client.Send(ctx, []string{vCode}, []string{number}...) |
| 112 | } else { |
| 113 | s.l.Info("短信验证码走模拟通道", zap.String("number", number), zap.String("vCode", vCode)) |
| 114 | } |
| 115 | id, _ := strconv.ParseInt(smsID, 10, 64) |
| 116 | log := dao.VCodeSmsLog{ |
| 117 | SmsId: id, |
| 118 | SmsType: "vCode", //todo |
| 119 | Mobile: number, |
| 120 | VCode: vCode, |
| 121 | Driver: driver, |
| 122 | Status: 1, //0为失败,1为成功;其中默认为 成功 |
| 123 | StatusCode: "", //todo |
| 124 | CreateTime: time.Now().UnixNano(), |
| 125 | UpdatedTime: time.Now().UnixNano(), |
| 126 | DeletedTime: time.Now().UnixNano(), |
| 127 | } |
| 128 | |
| 129 | // SDK异常 |
| 130 | if _, ok := err.(*tencenterros.TencentCloudSDKError); ok { |
| 131 | s.l.Error("[smsService SendCode] an API error has returned: ", zap.Error(err)) |
| 132 | s.cache.ReleaseLock(ctx, number) |
| 133 | return err |
| 134 | } |
| 135 | // 非SDK异常,直接失败 |
| 136 | if err != nil { |
| 137 | s.l.Error("[smsService SendCode] an error has returned: ", zap.Error(err)) |
| 138 | s.cache.ReleaseLock(ctx, number) |
| 139 | return err |
| 140 | } |
| 141 | if err = s.StoreVCode(ctx, smsID, number, vCode); err != nil { |
| 142 | log.Status = 0 |
| 143 | log.VCode = "-1" |
| 144 | s.AddUserOperationLog(ctx, log) |
| 145 | s.cache.ReleaseLock(ctx, number) |
| 146 | s.l.Error("[smsService SendCode] s.repo.StoreVCode 报错: ", zap.Error(err)) |
| 147 | return fmt.Errorf("存储随机数失败") |
| 148 | } |
| 149 | |
| 150 | if err = s.cache.IncrCnt(ctx, number); err != nil { |
| 151 | s.l.Error("[smsService SendCode] s.rdb.IncrCnt 报错: ", zap.Error(err)) |
nothing calls this directly
no test coverage detected