Files
backend/internal/model/post.go
lan ebd9cb8b04 feat: 添加日志管理和敏感词过滤功能
- 新增日志管理模块:操作日志、登录日志、数据变更日志
- 新增敏感词过滤器 (sanitizer)
- 新增日志异步写入管理器
- 新增日志定时清理服务
- 优化帖子相关服务和上传服务
2026-03-15 02:25:10 +08:00

104 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"
"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"`
IsFeatured bool `json:"is_featured" 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:false"`
}
// 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"`
PreviewURL string `json:"preview_url" gorm:"type:text"` // 列表/网格预览图最大300px
PreviewURLLarge string `json:"preview_url_large" gorm:"type:text"` // 详情页预览图最大800px
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"
}