Files
backend/internal/model/push_record.go
lan 4d8f2ec997 Initial backend repository commit.
Set up project files and add .gitignore to exclude local build/runtime artifacts.

Made-with: Cursor
2026-03-09 21:28:58 +08:00

130 lines
4.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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++
}