// // utils.go // Copyright (C) 2025 veypi // // Distributed under terms of the MIT license. // package sms import ( "fmt" "time" "github.com/veypi/OneAuth/cfg" "github.com/veypi/OneAuth/models" "gorm.io/gorm" ) // checkDailyLimit 检查每日发送次数限制 func CheckDailyLimit(phone, region string) error { today := time.Now().Truncate(24 * time.Hour) tomorrow := today.Add(24 * time.Hour) var count int64 err := cfg.DB().Model(&models.SMSCode{}). Where("phone = ? AND region = ? AND created_at >= ? AND created_at < ?", phone, region, today, tomorrow). Count(&count).Error if err != nil { return fmt.Errorf("failed to check daily limit: %w", err) } if count >= int64(cfg.Config.SMS.Global.MaxDailyCount) { return fmt.Errorf("daily sms limit exceeded") } return nil } // checkSendInterval 检查发送间隔 func CheckSendInterval(phone, region, purpose string) error { var lastCode models.SMSCode err := cfg.DB().Where("phone = ? AND region = ? AND purpose = ?", phone, region, purpose). Order("created_at DESC"). First(&lastCode).Error if err != nil && err != gorm.ErrRecordNotFound { return fmt.Errorf("failed to check send interval: %w", err) } if err == nil { timeSinceLastSend := time.Since(lastCode.CreatedAt) if timeSinceLastSend < cfg.Config.SMS.Global.SendInterval { remaining := cfg.Config.SMS.Global.SendInterval - timeSinceLastSend return fmt.Errorf("please wait %d seconds before sending again", int(remaining.Seconds())) } } return nil } // logSMS 记录短信发送日志 func LogSMS(phone, region, provider, messageID string, err error) { log := &models.SMSLog{ Phone: phone, Region: region, Provider: provider, MessageID: messageID, Status: "ok", } if err != nil { log.Status = "failed" log.Error = err.Error() } cfg.DB().Create(log) } // CleanupExpiredCodes 清理过期的验证码 func CleanupExpiredCodes() error { result := cfg.DB().Model(&models.SMSCode{}). Where("status = ? AND expires_at < ?", models.CodeStatusPending, time.Now()). Update("status", models.CodeStatusExpired) if result.Error != nil { return fmt.Errorf("failed to cleanup expired codes: %w", result.Error) } return nil }