Files
backend/internal/model/push_record.go

130 lines
4.0 KiB
Go
Raw Normal View History

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++
}