130 lines
4.0 KiB
Go
130 lines
4.0 KiB
Go
|
|
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++
|
|||
|
|
}
|