package models import ( "time" "gorm.io/gorm" ) // Attachment 表示附加到文章的文件。 // // 生命周期(方案 A——先上传后绑定): // - 在文章创建页面上文章尚不存在,因此 ArticleID 为 0, // 该行暂时由 SessionToken(为页面会话生成的随机值)持有。 // - 保存文章时,ArticleCreate 通过 SessionToken 绑定待处理行, // 设置它们的 ArticleID 并清除令牌。 // - 在编辑页面上,上传直接携带真实的 ArticleID。 // // 磁盘去重:StoredName 是文件内容的 SHA-256。写入前, // 处理器会检查磁盘上是否已存在同名文件;若已存在则复用(不重写)。 // 删除采用引用计数——仅当没有任何 Attachment 行引用时,才删除磁盘文件。 type Attachment struct { ID uint `gorm:"primarykey" json:"id"` ArticleID uint `gorm:"index" json:"article_id"` // 在创建页面上待绑定时为 0 SessionToken string `gorm:"size:64;index" json:"-"` // 创建页面上的临时归属令牌 UploaderID uint `gorm:"index" json:"uploader_id"` Filename string `gorm:"size:255" json:"filename"` // 原始文件名 StoredName string `gorm:"size:64;index" json:"stored_name"` // SHA-256 十六进制字符串,磁盘文件名 Ext string `gorm:"size:32" json:"ext"` MIME string `gorm:"size:128" json:"mime"` Size int64 `gorm:"default:0" json:"size"` Category string `gorm:"size:32" json:"category"` // image/document/archive/video/other CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` DeletedAt gorm.DeletedAt `gorm:"index" json:"deleted_at"` } // TableName 覆盖 GORM 默认的表名。 func (Attachment) TableName() string { return "attachments" } // IsImage 报告该附件是否为图片(用于决定 Markdown 插入形式:![]() 还是 []())。 func (a *Attachment) IsImage() bool { return a.Category == CategoryImage }