package model import ( "time" "github.com/google/uuid" "gorm.io/gorm" ) // PostStatus 帖子状态 type PostStatus string const ( PostStatusDraft PostStatus = "draft" PostStatusPending PostStatus = "pending" // 待审核 PostStatusPublished PostStatus = "published" PostStatusRejected PostStatus = "rejected" PostStatusDeleted PostStatus = "deleted" ) // Post 帖子实体 type Post struct { ID string `json:"id" gorm:"type:varchar(36);primaryKey"` UserID string `json:"user_id" gorm:"type:varchar(36);index;index:idx_posts_user_status_created,priority:1;not null"` CommunityID string `json:"community_id" gorm:"type:varchar(36);index"` Title string `json:"title" gorm:"type:varchar(200);not null"` Content string `json:"content" gorm:"type:text;not null"` // 关联 // User 需要参与缓存序列化;否则列表命中缓存后会丢失作者信息,前端退化为“匿名用户” User *User `json:"user,omitempty" gorm:"foreignKey:UserID"` Images []PostImage `json:"images" gorm:"foreignKey:PostID"` // 审核状态 Status PostStatus `json:"status" gorm:"type:varchar(20);default:published;index:idx_posts_status_created,priority:1;index:idx_posts_user_status_created,priority:2"` ReviewedAt *time.Time `json:"reviewed_at" gorm:"type:timestamp"` ReviewedBy string `json:"reviewed_by" gorm:"type:varchar(50)"` RejectReason string `json:"reject_reason" gorm:"type:varchar(500)"` // 统计 LikesCount int `json:"likes_count" gorm:"column:likes_count;default:0"` CommentsCount int `json:"comments_count" gorm:"column:comments_count;default:0"` FavoritesCount int `json:"favorites_count" gorm:"column:favorites_count;default:0"` SharesCount int `json:"shares_count" gorm:"column:shares_count;default:0"` ViewsCount int `json:"views_count" gorm:"column:views_count;default:0"` HotScore float64 `json:"hot_score" gorm:"column:hot_score;default:0;index:idx_posts_hot_score_created,priority:1"` // 置顶/锁定 IsPinned bool `json:"is_pinned" gorm:"default:false"` IsLocked bool `json:"is_locked" gorm:"default:false"` IsDeleted bool `json:"-" gorm:"default:false"` // 投票 IsVote bool `json:"is_vote" gorm:"column:is_vote;default:false"` // 软删除 DeletedAt gorm.DeletedAt `json:"-" gorm:"index"` // 时间戳 CreatedAt time.Time `json:"created_at" gorm:"autoCreateTime;index:idx_posts_status_created,priority:2,sort:desc;index:idx_posts_user_status_created,priority:3,sort:desc;index:idx_posts_hot_score_created,priority:2,sort:desc"` UpdatedAt time.Time `json:"updated_at" gorm:"autoUpdateTime"` } // BeforeCreate 创建前生成UUID func (p *Post) BeforeCreate(tx *gorm.DB) error { if p.ID == "" { p.ID = uuid.New().String() } return nil } func (Post) TableName() string { return "posts" } // PostImage 帖子图片 type PostImage struct { ID string `json:"id" gorm:"type:varchar(36);primaryKey"` PostID string `json:"post_id" gorm:"type:varchar(36);index;not null"` URL string `json:"url" gorm:"type:text;not null"` ThumbnailURL string `json:"thumbnail_url" gorm:"type:text"` Width int `json:"width" gorm:"default:0"` Height int `json:"height" gorm:"default:0"` Size int64 `json:"size" gorm:"default:0"` // 文件大小(字节) MimeType string `json:"mime_type" gorm:"type:varchar(50)"` SortOrder int `json:"sort_order" gorm:"default:0"` CreatedAt time.Time `json:"created_at" gorm:"autoCreateTime"` } // BeforeCreate 创建前生成UUID func (pi *PostImage) BeforeCreate(tx *gorm.DB) error { if pi.ID == "" { pi.ID = uuid.New().String() } return nil } func (PostImage) TableName() string { return "post_images" }