package entities import ( "time" "github.com/google/uuid" "gorm.io/gorm" ) // ArticleStatus 文章状态枚举 type ArticleStatus string const ( ArticleStatusDraft ArticleStatus = "draft" // 草稿 ArticleStatusPublished ArticleStatus = "published" // 已发布 ArticleStatusArchived ArticleStatus = "archived" // 已归档 ) // Article 文章聚合根 // 系统的核心内容实体,提供文章的完整生命周期管理 // 支持草稿、发布、归档状态,实现Entity接口便于统一管理 type Article struct { // 基础标识 ID string `gorm:"primaryKey;type:varchar(36)" json:"id" comment:"文章唯一标识"` Title string `gorm:"type:varchar(200);not null" json:"title" comment:"文章标题"` Content string `gorm:"type:text;not null" json:"content" comment:"文章内容"` Summary string `gorm:"type:varchar(500)" json:"summary" comment:"文章摘要"` CoverImage string `gorm:"type:varchar(500)" json:"cover_image" comment:"封面图片"` // 分类 CategoryID string `gorm:"type:varchar(36)" json:"category_id" comment:"分类ID"` // 状态管理 Status ArticleStatus `gorm:"type:varchar(20);not null;default:'draft'" json:"status" comment:"文章状态"` IsFeatured bool `gorm:"default:false" json:"is_featured" comment:"是否推荐"` PublishedAt *time.Time `json:"published_at" comment:"发布时间"` ScheduledAt *time.Time `json:"scheduled_at" comment:"定时发布时间"` // 统计信息 ViewCount int `gorm:"default:0" json:"view_count" comment:"阅读量"` // 时间戳字段 CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at" comment:"创建时间"` UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updated_at" comment:"更新时间"` DeletedAt gorm.DeletedAt `gorm:"index" json:"-" comment:"软删除时间"` // 关联关系 Category *Category `gorm:"foreignKey:CategoryID" json:"category,omitempty" comment:"分类信息"` Tags []Tag `gorm:"many2many:article_tag_relations;" json:"tags,omitempty" comment:"标签列表"` // 领域事件 (不持久化) domainEvents []interface{} `gorm:"-" json:"-"` } // TableName 指定表名 func (Article) TableName() string { return "articles" } // BeforeCreate GORM钩子:创建前自动生成UUID func (a *Article) BeforeCreate(tx *gorm.DB) error { if a.ID == "" { a.ID = uuid.New().String() } return nil } // 实现 Entity 接口 - 提供统一的实体管理接口 // GetID 获取实体唯一标识 func (a *Article) GetID() string { return a.ID } // GetCreatedAt 获取创建时间 func (a *Article) GetCreatedAt() time.Time { return a.CreatedAt } // GetUpdatedAt 获取更新时间 func (a *Article) GetUpdatedAt() time.Time { return a.UpdatedAt } // Validate 验证文章信息 // 检查文章必填字段是否完整,确保数据的有效性 func (a *Article) Validate() error { if a.Title == "" { return NewValidationError("文章标题不能为空") } if a.Content == "" { return NewValidationError("文章内容不能为空") } // 验证标题长度 if len(a.Title) > 200 { return NewValidationError("文章标题不能超过200个字符") } // 验证摘要长度 if a.Summary != "" && len(a.Summary) > 500 { return NewValidationError("文章摘要不能超过500个字符") } return nil } // Publish 发布文章 func (a *Article) Publish() error { if a.Status == ArticleStatusPublished { return NewValidationError("文章已经是发布状态") } a.Status = ArticleStatusPublished now := time.Now() a.PublishedAt = &now a.ScheduledAt = nil // 清除定时发布时间 return nil } // SchedulePublish 定时发布文章 func (a *Article) SchedulePublish(scheduledTime time.Time) error { if a.Status == ArticleStatusPublished { return NewValidationError("文章已经是发布状态") } if scheduledTime.Before(time.Now()) { return NewValidationError("定时发布时间不能早于当前时间") } a.Status = ArticleStatusDraft // 保持草稿状态,等待定时发布 a.ScheduledAt = &scheduledTime return nil } // IsScheduled 判断是否已设置定时发布 func (a *Article) IsScheduled() bool { return a.ScheduledAt != nil && a.Status == ArticleStatusDraft } // GetScheduledTime 获取定时发布时间 func (a *Article) GetScheduledTime() *time.Time { return a.ScheduledAt } // Archive 归档文章 func (a *Article) Archive() error { if a.Status == ArticleStatusArchived { return NewValidationError("文章已经是归档状态") } a.Status = ArticleStatusArchived return nil } // IncrementViewCount 增加阅读量 func (a *Article) IncrementViewCount() { a.ViewCount++ } // SetFeatured 设置推荐状态 func (a *Article) SetFeatured(featured bool) { a.IsFeatured = featured } // IsPublished 判断是否已发布 func (a *Article) IsPublished() bool { return a.Status == ArticleStatusPublished } // IsDraft 判断是否为草稿 func (a *Article) IsDraft() bool { return a.Status == ArticleStatusDraft } // IsArchived 判断是否已归档 func (a *Article) IsArchived() bool { return a.Status == ArticleStatusArchived } // CanEdit 判断是否可以编辑 func (a *Article) CanEdit() bool { return a.Status == ArticleStatusDraft } // CanPublish 判断是否可以发布 func (a *Article) CanPublish() bool { return a.Status == ArticleStatusDraft } // CanArchive 判断是否可以归档 func (a *Article) CanArchive() bool { return a.Status == ArticleStatusPublished }