package model import ( "time" "gorm.io/gorm" "carrot_bbs/internal/pkg/utils" ) // PushChannel 推送通道类型 type PushChannel string const ( PushChannelWebSocket PushChannel = "websocket" // WebSocket推送 PushChannelFCM PushChannel = "fcm" // Firebase Cloud Messaging PushChannelAPNs PushChannel = "apns" // Apple Push Notification service PushChannelHuawei PushChannel = "huawei" // 华为推送 ) // PushStatus 推送状态 type PushStatus string const ( PushStatusPending PushStatus = "pending" // 待推送 PushStatusPushing PushStatus = "pushing" // 推送中 PushStatusPushed PushStatus = "pushed" // 已推送(成功发送到推送服务) PushStatusDelivered PushStatus = "delivered" // 已送达(客户端确认) PushStatusFailed PushStatus = "failed" // 推送失败 PushStatusExpired PushStatus = "expired" // 消息过期 ) // PushRecord 推送记录实体 // 用于跟踪消息的推送状态,支持多设备推送和重试机制 type PushRecord struct { ID int64 `gorm:"primaryKey;autoIncrement:false" json:"id"` // 雪花算法ID UserID string `gorm:"column:user_id;type:varchar(50);index;not null" json:"user_id"` // 目标用户ID (UUID格式) MessageID string `gorm:"index;not null;size:20" json:"message_id"` // 关联的消息ID (string类型) PushChannel PushChannel `gorm:"type:varchar(20);not null" json:"push_channel"` // 推送通道 PushStatus PushStatus `gorm:"type:varchar(20);not null;default:'pending'" json:"push_status"` // 推送状态 // 设备信息 DeviceToken string `gorm:"type:varchar(256)" json:"device_token,omitempty"` // 设备Token(用于手机推送) DeviceType string `gorm:"type:varchar(20)" json:"device_type,omitempty"` // 设备类型 (ios/android/web) // 重试机制 RetryCount int `gorm:"default:0" json:"retry_count"` // 重试次数 MaxRetry int `gorm:"default:3" json:"max_retry"` // 最大重试次数 // 时间戳 PushedAt *time.Time `json:"pushed_at,omitempty"` // 推送时间 DeliveredAt *time.Time `json:"delivered_at,omitempty"` // 送达时间 ExpiredAt *time.Time `gorm:"index" json:"expired_at,omitempty"` // 过期时间 // 错误信息 ErrorMessage string `gorm:"type:varchar(500)" json:"error_message,omitempty"` // 错误信息 // 软删除 DeletedAt gorm.DeletedAt `json:"-" gorm:"index"` // 时间戳 CreatedAt time.Time `json:"created_at" gorm:"autoCreateTime"` UpdatedAt time.Time `json:"updated_at" gorm:"autoUpdateTime"` } // BeforeCreate 创建前生成雪花算法ID func (r *PushRecord) BeforeCreate(tx *gorm.DB) error { if r.ID == 0 { id, err := utils.GetSnowflake().GenerateID() if err != nil { return err } r.ID = id } return nil } func (PushRecord) TableName() string { return "push_records" } // CanRetry 判断是否可以重试 func (r *PushRecord) CanRetry() bool { return r.RetryCount < r.MaxRetry && r.PushStatus != PushStatusDelivered && r.PushStatus != PushStatusExpired } // IsExpired 判断是否已过期 func (r *PushRecord) IsExpired() bool { if r.ExpiredAt == nil { return false } return time.Now().After(*r.ExpiredAt) } // MarkPushing 标记为推送中 func (r *PushRecord) MarkPushing() { r.PushStatus = PushStatusPushing } // MarkPushed 标记为已推送 func (r *PushRecord) MarkPushed() { now := time.Now() r.PushStatus = PushStatusPushed r.PushedAt = &now } // MarkDelivered 标记为已送达 func (r *PushRecord) MarkDelivered() { now := time.Now() r.PushStatus = PushStatusDelivered r.DeliveredAt = &now } // MarkFailed 标记为推送失败 func (r *PushRecord) MarkFailed(errMsg string) { r.PushStatus = PushStatusFailed r.ErrorMessage = errMsg r.RetryCount++ } // MarkExpired 标记为已过期 func (r *PushRecord) MarkExpired() { r.PushStatus = PushStatusExpired } // IncrementRetry 增加重试次数 func (r *PushRecord) IncrementRetry() { r.RetryCount++ }