package repositories import ( "log" "time" "github.com/niangaodev/art-code/config" "github.com/niangaodev/art-code/models" "gorm.io/gorm" ) // GetColumns 获取所有专栏 func GetColumns() ([]models.Column, error) { var columns []models.Column err := config.DB.Model(&models.Column{}). Where("deleted_at = ?", 0). Order("sort_order ASC, created_at DESC"). Find(&columns).Error if err != nil { log.Printf("Error querying columns: %v", err) return nil, err } return columns, nil } // GetColumnByID 根据ID获取专栏 func GetColumnByID(id uint) (*models.Column, error) { var col models.Column err := config.DB.Model(&models.Column{}). Where("id = ? AND deleted_at = ?", id, 0). First(&col).Error if err != nil { if err == gorm.ErrRecordNotFound { return nil, nil } log.Printf("Error getting column by ID: %v", err) return nil, err } return &col, nil } // GetColumnStats 获取专栏统计信息(文章数量和最近更新时间) func GetColumnStats(columnID uint) (int64, int64, error) { var postCount int64 // 统计文章数量 err := config.DB.Model(&models.Post{}). Joins("JOIN column_posts cp ON posts.id = cp.post_id"). Where("cp.column_id = ? AND posts.deleted_at = ? AND posts.is_published = ?", columnID, 0, 1). Count(&postCount).Error if err != nil { log.Printf("Error counting posts for column: %v", err) return 0, 0, err } // 获取最近更新时间 var lastUpdated int64 if postCount > 0 { err = config.DB.Model(&models.Post{}). Select("COALESCE(MAX(posts.updated_at), 0)"). Joins("JOIN column_posts cp ON posts.id = cp.post_id"). Where("cp.column_id = ? AND posts.deleted_at = ? AND posts.is_published = ?", columnID, 0, 1). Scan(&lastUpdated).Error if err != nil { log.Printf("Error getting last updated time for column: %v", err) // 如果查询失败,使用专栏的更新时间 var col models.Column if err2 := config.DB.Model(&models.Column{}). Select("updated_at"). Where("id = ?", columnID). First(&col).Error; err2 == nil { lastUpdated = col.UpdatedAt } } } else { // 如果没有文章,使用专栏的更新时间 var col models.Column if err := config.DB.Model(&models.Column{}). Select("updated_at"). Where("id = ?", columnID). First(&col).Error; err == nil { lastUpdated = col.UpdatedAt } } return postCount, lastUpdated, nil } // BuildColumnResponse 构建专栏响应(包含统计信息) func BuildColumnResponse(col *models.Column) *models.ColumnResponse { postCount, lastUpdated, _ := GetColumnStats(col.ID) return &models.ColumnResponse{ ID: col.ID, Name: col.Name, Description: col.Description, Cover: col.Cover, IsActive: col.IsActive, SortOrder: col.SortOrder, CreatedAt: formatTimestamp(col.CreatedAt), UpdatedAt: formatTimestamp(col.UpdatedAt), PostCount: postCount, LastUpdated: formatTimestamp(lastUpdated), } } // BuildColumnItemResponse 构建专栏列表项响应(不含统计) func BuildColumnItemResponse(col *models.Column) *models.ColumnResponse { return &models.ColumnResponse{ ID: col.ID, Name: col.Name, Description: col.Description, Cover: col.Cover, IsActive: col.IsActive, SortOrder: col.SortOrder, CreatedAt: formatTimestamp(col.CreatedAt), UpdatedAt: formatTimestamp(col.UpdatedAt), } } // BuildColumnsResponse 构建专栏列表响应 func BuildColumnsResponse(columns []models.Column) []models.ColumnResponse { responses := make([]models.ColumnResponse, 0, len(columns)) for _, col := range columns { responses = append(responses, *BuildColumnItemResponse(&col)) } return responses } // CreateColumn 创建专栏 func CreateColumn(col *models.Column) error { err := config.DB.Create(col).Error if err != nil { log.Printf("Error creating column: %v", err) return err } return nil } // UpdateColumn 更新专栏 func UpdateColumn(col *models.Column) error { err := config.DB.Model(&models.Column{}). Where("id = ? AND deleted_at = ?", col.ID, 0). Updates(map[string]interface{}{ "name": col.Name, "description": col.Description, "cover": col.Cover, "is_active": col.IsActive, "sort_order": col.SortOrder, "updated_at": time.Now().Unix(), }).Error if err != nil { log.Printf("Error updating column: %v", err) return err } return nil } // DeleteColumn 删除专栏 func DeleteColumn(id uint) error { err := config.DB.Model(&models.Column{}). Where("id = ?", id). Update("deleted_at", time.Now().Unix()).Error if err != nil { log.Printf("Error deleting column: %v", err) return err } return nil } // GetPostsByColumnID 获取专栏下的文章(不含正文 content) func GetPostsByColumnID(columnID uint) ([]models.Post, error) { var posts []models.Post err := config.DB.Model(&models.Post{}). Select("posts.id", "posts.title", "posts.category_id", "posts.column_id", "posts.excerpt", "posts.read_count", "posts.is_published", "posts.user_id", "posts.created_at", "posts.updated_at"). Preload("Category"). Preload("Tags"). Joins("JOIN column_posts cp ON posts.id = cp.post_id"). Where("cp.column_id = ? AND posts.deleted_at = ? AND posts.is_published = ?", columnID, 0, 1). Order("cp.sort_order ASC, posts.created_at DESC"). Find(&posts).Error if err != nil { log.Printf("Error querying posts by column ID: %v", err) return nil, err } return posts, nil } // GetPostBriefsByColumnID 获取专栏文章目录(仅 id、title) func GetPostBriefsByColumnID(columnID uint) ([]models.PostBrief, error) { var briefs []models.PostBrief err := config.DB.Table("posts"). Select("posts.id, posts.title"). Joins("JOIN column_posts cp ON posts.id = cp.post_id"). Where("cp.column_id = ? AND posts.deleted_at = ? AND posts.is_published = ?", columnID, 0, 1). Order("cp.sort_order ASC, posts.created_at DESC"). Scan(&briefs).Error if err != nil { log.Printf("Error querying post briefs by column ID: %v", err) return nil, err } if briefs == nil { briefs = []models.PostBrief{} } return briefs, nil } // AddPostToColumn 添加文章到专栏 func AddPostToColumn(columnID, postID, sortOrder uint) error { columnPost := &models.ColumnPost{ ColumnID: columnID, PostID: postID, SortOrder: sortOrder, CreatedAt: time.Now().Unix(), } // 使用 Clauses 处理 ON DUPLICATE KEY UPDATE err := config.DB.Where("column_id = ? AND post_id = ?", columnID, postID). Assign(models.ColumnPost{SortOrder: sortOrder}). FirstOrCreate(columnPost).Error return err } // RemovePostFromColumn 从专栏移除文章 func RemovePostFromColumn(columnID, postID uint) error { err := config.DB.Where("column_id = ? AND post_id = ?", columnID, postID). Delete(&models.ColumnPost{}).Error return err }