topfans/backend/pkg/models/friend.go
2026-04-07 22:29:48 +08:00

151 lines
6.0 KiB
Go
Raw Permalink 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 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" // 发出的请求
)