Files
nl-blogs/server/repositories/column_repository.go
2026-06-26 17:00:02 +08:00

230 lines
6.7 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 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
}