2026-04-22 16:01:59 +08:00
|
|
|
|
package model
|
2026-03-09 21:28:58 +08:00
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
|
"time"
|
|
|
|
|
|
|
|
|
|
|
|
"gorm.io/gorm"
|
|
|
|
|
|
|
2026-04-22 16:01:59 +08:00
|
|
|
|
"with_you/internal/pkg/utils"
|
2026-03-09 21:28:58 +08:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
// DeviceType 设备类型
|
|
|
|
|
|
type DeviceType string
|
|
|
|
|
|
|
|
|
|
|
|
const (
|
|
|
|
|
|
DeviceTypeIOS DeviceType = "ios" // iOS设备
|
|
|
|
|
|
DeviceTypeAndroid DeviceType = "android" // Android设备
|
|
|
|
|
|
DeviceTypeWeb DeviceType = "web" // Web端
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
// DeviceToken 设备Token实体
|
|
|
|
|
|
// 用于管理用户的多设备推送Token
|
|
|
|
|
|
type DeviceToken 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格式)
|
|
|
|
|
|
DeviceID string `gorm:"type:varchar(100);not null" json:"device_id"` // 设备唯一标识
|
|
|
|
|
|
DeviceType DeviceType `gorm:"type:varchar(20);not null" json:"device_type"` // 设备类型
|
|
|
|
|
|
PushToken string `gorm:"type:varchar(256);not null" json:"push_token"` // 推送Token(FCM/APNs等)
|
|
|
|
|
|
IsActive bool `gorm:"default:true" json:"is_active"` // 是否活跃
|
|
|
|
|
|
DeviceName string `gorm:"type:varchar(100)" json:"device_name,omitempty"` // 设备名称(可选)
|
|
|
|
|
|
|
|
|
|
|
|
// 时间戳
|
|
|
|
|
|
LastUsedAt *time.Time `json:"last_used_at,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 (d *DeviceToken) BeforeCreate(tx *gorm.DB) error {
|
|
|
|
|
|
if d.ID == 0 {
|
|
|
|
|
|
id, err := utils.GetSnowflake().GenerateID()
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
return err
|
|
|
|
|
|
}
|
|
|
|
|
|
d.ID = id
|
|
|
|
|
|
}
|
|
|
|
|
|
return nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (DeviceToken) TableName() string {
|
|
|
|
|
|
return "device_tokens"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// UpdateLastUsed 更新最后使用时间
|
|
|
|
|
|
func (d *DeviceToken) UpdateLastUsed() {
|
|
|
|
|
|
now := time.Now()
|
|
|
|
|
|
d.LastUsedAt = &now
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Deactivate 停用设备
|
|
|
|
|
|
func (d *DeviceToken) Deactivate() {
|
|
|
|
|
|
d.IsActive = false
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Activate 激活设备
|
|
|
|
|
|
func (d *DeviceToken) Activate() {
|
|
|
|
|
|
d.IsActive = true
|
|
|
|
|
|
now := time.Now()
|
|
|
|
|
|
d.LastUsedAt = &now
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// IsIOS 判断是否为iOS设备
|
|
|
|
|
|
func (d *DeviceToken) IsIOS() bool {
|
|
|
|
|
|
return d.DeviceType == DeviceTypeIOS
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// IsAndroid 判断是否为Android设备
|
|
|
|
|
|
func (d *DeviceToken) IsAndroid() bool {
|
|
|
|
|
|
return d.DeviceType == DeviceTypeAndroid
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// IsWeb 判断是否为Web端
|
|
|
|
|
|
func (d *DeviceToken) IsWeb() bool {
|
|
|
|
|
|
return d.DeviceType == DeviceTypeWeb
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SupportsMobilePush 判断是否支持手机推送
|
|
|
|
|
|
func (d *DeviceToken) SupportsMobilePush() bool {
|
|
|
|
|
|
return d.DeviceType == DeviceTypeIOS || d.DeviceType == DeviceTypeAndroid
|
|
|
|
|
|
}
|