151 lines
6.0 KiB
Go
151 lines
6.0 KiB
Go
package models
|
||
|
||
import (
|
||
"time"
|
||
|
||
"gorm.io/gorm"
|
||
)
|
||
|
||
// Friendship 好友关系表模型
|
||
// 存储已确认的好友关系(双向存储:A→B 和 B→A 各存一条记录)
|
||
type Friendship struct {
|
||
ID int64 `gorm:"primaryKey;autoIncrement;column:id"`
|
||
UserID int64 `gorm:"not null;uniqueIndex:uk_friendships_user_friend_star;index:idx_friendships_user_star_status;index:idx_friendships_user_star_created;index:idx_friendships_list_query;column:user_id"`
|
||
FriendID int64 `gorm:"not null;uniqueIndex:uk_friendships_user_friend_star;index:idx_friendships_friend_star;index:idx_friendships_list_query;column:friend_id"`
|
||
StarID int64 `gorm:"not null;uniqueIndex:uk_friendships_user_friend_star;index:idx_friendships_user_star_status;index:idx_friendships_user_star_created;index:idx_friendships_list_query;column:star_id"`
|
||
Status string `gorm:"type:varchar(20);not null;default:'accepted';index:idx_friendships_user_star_status;index:idx_friendships_list_query;column:status"` // accepted, blocked
|
||
Remark *string `gorm:"type:varchar(50);index:idx_friendships_list_query;column:remark"` // 备注名(好友昵称)
|
||
Intimacy int32 `gorm:"default:0;not null;column:intimacy"` // 亲密度(预留字段)
|
||
CreatedAt int64 `gorm:"not null;index:idx_friendships_user_star_created,sort:desc;index:idx_friendships_list_query;column:created_at"`
|
||
UpdatedAt int64 `gorm:"not null;column:updated_at"`
|
||
|
||
// 关联关系
|
||
User User `gorm:"foreignKey:UserID;references:ID;constraint:OnDelete:CASCADE"`
|
||
Friend User `gorm:"foreignKey:FriendID;references:ID;constraint:OnDelete:CASCADE"`
|
||
Star Star `gorm:"foreignKey:StarID;references:StarID;constraint:OnDelete:CASCADE"`
|
||
}
|
||
|
||
// TableName 指定表名
|
||
func (Friendship) TableName() string {
|
||
return "friendships"
|
||
}
|
||
|
||
// BeforeCreate 创建前钩子
|
||
func (f *Friendship) BeforeCreate(tx *gorm.DB) error {
|
||
now := time.Now().UnixMilli()
|
||
f.CreatedAt = now
|
||
f.UpdatedAt = now
|
||
|
||
// 验证不能添加自己为好友
|
||
if f.UserID == f.FriendID {
|
||
return gorm.ErrCheckConstraintViolated
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
// BeforeUpdate 更新前钩子
|
||
func (f *Friendship) BeforeUpdate(tx *gorm.DB) error {
|
||
f.UpdatedAt = time.Now().UnixMilli()
|
||
return nil
|
||
}
|
||
|
||
// FriendRequest 好友请求表模型
|
||
// 存储好友请求的历史记录(保留所有状态的记录)
|
||
type FriendRequest struct {
|
||
ID int64 `gorm:"primaryKey;autoIncrement;column:id"`
|
||
FromUserID int64 `gorm:"not null;index:idx_friend_requests_from_status;index:idx_friend_requests_users_star;column:from_user_id"`
|
||
ToUserID int64 `gorm:"not null;index:idx_friend_requests_to_status;index:idx_friend_requests_users_star;column:to_user_id"`
|
||
StarID int64 `gorm:"not null;index:idx_friend_requests_star;index:idx_friend_requests_users_star;column:star_id"`
|
||
Message *string `gorm:"type:varchar(200);column:message"` // 请求附带消息
|
||
Status string `gorm:"type:varchar(20);not null;default:'pending';index:idx_friend_requests_to_status;index:idx_friend_requests_from_status;column:status"` // pending, accepted, rejected, expired
|
||
CreatedAt int64 `gorm:"not null;index:idx_friend_requests_to_status,sort:desc;index:idx_friend_requests_from_status,sort:desc;index:idx_friend_requests_users_star,sort:desc;column:created_at"`
|
||
UpdatedAt int64 `gorm:"not null;column:updated_at"`
|
||
ExpiresAt *int64 `gorm:"index:idx_friend_requests_expires;column:expires_at"` // 过期时间(毫秒时间戳)
|
||
ProcessedAt *int64 `gorm:"column:processed_at"` // 处理时间(毫秒时间戳)
|
||
|
||
// 关联关系
|
||
FromUser User `gorm:"foreignKey:FromUserID;references:ID;constraint:OnDelete:CASCADE"`
|
||
ToUser User `gorm:"foreignKey:ToUserID;references:ID;constraint:OnDelete:CASCADE"`
|
||
Star Star `gorm:"foreignKey:StarID;references:StarID;constraint:OnDelete:CASCADE"`
|
||
}
|
||
|
||
// TableName 指定表名
|
||
func (FriendRequest) TableName() string {
|
||
return "friend_requests"
|
||
}
|
||
|
||
// BeforeCreate 创建前钩子
|
||
func (fr *FriendRequest) BeforeCreate(tx *gorm.DB) error {
|
||
now := time.Now().UnixMilli()
|
||
fr.CreatedAt = now
|
||
fr.UpdatedAt = now
|
||
|
||
// 验证不能请求自己为好友
|
||
if fr.FromUserID == fr.ToUserID {
|
||
return gorm.ErrCheckConstraintViolated
|
||
}
|
||
|
||
// 设置默认状态
|
||
if fr.Status == "" {
|
||
fr.Status = FriendRequestStatusPending
|
||
}
|
||
|
||
// 注意:过期时间应该在 Service 层创建 FriendRequest 之前设置
|
||
// Service 层会根据 friend_config.go 中的配置计算过期时间
|
||
// 这里不再设置过期时间,避免硬编码和配置不一致
|
||
|
||
return nil
|
||
}
|
||
|
||
// BeforeUpdate 更新前钩子
|
||
func (fr *FriendRequest) BeforeUpdate(tx *gorm.DB) error {
|
||
fr.UpdatedAt = time.Now().UnixMilli()
|
||
return nil
|
||
}
|
||
|
||
// IsExpired 检查请求是否已过期
|
||
func (fr *FriendRequest) IsExpired() bool {
|
||
if fr.ExpiresAt == nil {
|
||
return false
|
||
}
|
||
return time.Now().UnixMilli() > *fr.ExpiresAt
|
||
}
|
||
|
||
// IsPending 检查请求是否为待处理状态
|
||
func (fr *FriendRequest) IsPending() bool {
|
||
return fr.Status == FriendRequestStatusPending
|
||
}
|
||
|
||
// IsAccepted 检查请求是否已接受
|
||
func (fr *FriendRequest) IsAccepted() bool {
|
||
return fr.Status == FriendRequestStatusAccepted
|
||
}
|
||
|
||
// IsRejected 检查请求是否已拒绝
|
||
func (fr *FriendRequest) IsRejected() bool {
|
||
return fr.Status == FriendRequestStatusRejected
|
||
}
|
||
|
||
// 常量定义
|
||
|
||
// 好友关系状态
|
||
const (
|
||
FriendshipStatusAccepted = "accepted" // 已接受
|
||
FriendshipStatusBlocked = "blocked" // 已屏蔽(预留)
|
||
)
|
||
|
||
// 好友请求状态
|
||
const (
|
||
FriendRequestStatusPending = "pending" // 待处理
|
||
FriendRequestStatusAccepted = "accepted" // 已接受
|
||
FriendRequestStatusRejected = "rejected" // 已拒绝
|
||
FriendRequestStatusExpired = "expired" // 已过期
|
||
)
|
||
|
||
// 好友请求类型(用于查询)
|
||
const (
|
||
FriendRequestTypeReceived = "received" // 收到的请求
|
||
FriendRequestTypeSent = "sent" // 发出的请求
|
||
)
|