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