Set up project files and add .gitignore to exclude local build/runtime artifacts. Made-with: Cursor
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++
|
||
}
|