You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
OneAuth/models/sms.go

66 lines
2.7 KiB
Go

package models
import (
"gorm.io/gorm"
"time"
)
// SMSCode 短信验证码记录
type SMSCode struct {
ID uint `gorm:"primarykey" json:"id"`
Phone string `gorm:"index;not null" json:"phone"` // 手机号
Code string `gorm:"not null" json:"code"` // 验证码
Region string `gorm:"index;not null" json:"region"` // 区域
Purpose string `gorm:"index;not null" json:"purpose"` // 用途(注册、登录、重置密码等)
Status CodeStatus `gorm:"default:0" json:"status"` // 状态
ExpiresAt time.Time `gorm:"index;not null" json:"expires_at"` // 过期时间
UsedAt *time.Time `gorm:"index" json:"used_at"` // 使用时间
Attempts int `gorm:"default:0" json:"attempts"` // 验证尝试次数
SendCount int `gorm:"default:1" json:"send_count"` // 发送次数
RemoteIP string `gorm:"index" json:"remote_ip"` // 远程IP地址
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"deleted_at"`
}
// CodeStatus 验证码状态
type CodeStatus int
const (
CodeStatusPending CodeStatus = iota // 待验证
CodeStatusUsed // 已使用
CodeStatusExpired // 已过期
CodeStatusFailed // 验证失败(超过最大尝试次数)
)
// SMSLog 短信发送日志
type SMSLog struct {
ID uint `gorm:"primarykey" json:"id"`
Phone string `gorm:"index;not null" json:"phone"`
Region string `gorm:"index;not null" json:"region"`
Provider string `gorm:"not null" json:"provider"`
MessageID string `gorm:"index" json:"message_id"` // 服务商返回的消息ID
Content string `json:"content"` // 短信内容
Status string `gorm:"not null" json:"status"` // 发送状态
Error string `json:"error"` // 错误信息
Cost float64 `json:"cost"` // 费用
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"deleted_at"`
}
// IsExpired 检查验证码是否过期
func (s *SMSCode) IsExpired() bool {
return time.Now().After(s.ExpiresAt)
}
// IsUsed 检查验证码是否已使用
func (s *SMSCode) IsUsed() bool {
return s.Status == CodeStatusUsed && s.UsedAt != nil
}
// CanRetry 检查是否可以重试验证
func (s *SMSCode) CanRetry(maxAttempts int) bool {
return s.Status == CodeStatusPending && s.Attempts < maxAttempts && !s.IsExpired()
}