first commit
This commit is contained in:
202
app/blog/services/post_service.go
Normal file
202
app/blog/services/post_service.go
Normal file
@@ -0,0 +1,202 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"gobeyhan/database"
|
||||
"gobeyhan/database/models"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type PostService struct{}
|
||||
|
||||
func NewPostService() *PostService {
|
||||
return &PostService{}
|
||||
}
|
||||
|
||||
// GetAllPosts retrieves all posts with pagination, optionally filtering by active status
|
||||
func (s *PostService) GetAllPosts(page, limit int, activeOnly bool) ([]models.Post, int64, error) {
|
||||
var posts []models.Post
|
||||
var total int64
|
||||
|
||||
query := database.DB.
|
||||
Preload("User").
|
||||
Preload("Categories").
|
||||
Preload("Tags").
|
||||
Preload("Parent").
|
||||
Preload("Children")
|
||||
|
||||
if activeOnly {
|
||||
query = query.Where("is_active = ?", true)
|
||||
}
|
||||
|
||||
// Count total
|
||||
query.Model(&models.Post{}).Count(&total)
|
||||
|
||||
// Get paginated results
|
||||
err := query.
|
||||
Offset((page - 1) * limit).
|
||||
Limit(limit).
|
||||
Order("created_at DESC").
|
||||
Find(&posts).Error
|
||||
|
||||
return posts, total, err
|
||||
}
|
||||
|
||||
// GetPostByID retrieves a post by ID with all relationships
|
||||
func (s *PostService) GetPostByID(id uint64) (*models.Post, error) {
|
||||
var post models.Post
|
||||
err := database.DB.
|
||||
Preload("User").
|
||||
Preload("Categories").
|
||||
Preload("Tags").
|
||||
Preload("Parent").
|
||||
Preload("Children").
|
||||
First(&post, id).Error
|
||||
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &post, nil
|
||||
}
|
||||
|
||||
// GetPostBySlug retrieves a post by slug
|
||||
func (s *PostService) GetPostBySlug(slug string) (*models.Post, error) {
|
||||
var post models.Post
|
||||
err := database.DB.
|
||||
Preload("User").
|
||||
Preload("Categories").
|
||||
Preload("Tags").
|
||||
Preload("Parent").
|
||||
Preload("Children").
|
||||
Where("slug = ? AND is_active = ?", slug, true).
|
||||
First(&post).Error
|
||||
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &post, nil
|
||||
}
|
||||
|
||||
// CreatePost creates a new post
|
||||
func (s *PostService) CreatePost(post *models.Post) error {
|
||||
return database.DB.Create(post).Error
|
||||
}
|
||||
|
||||
// UpdatePost updates an existing post
|
||||
func (s *PostService) UpdatePost(id uint64, updates map[string]interface{}) error {
|
||||
// Handle many-to-many relationships separately if they're in updates
|
||||
var categoryIDs []*models.Category
|
||||
var tagIDs []*models.Tag
|
||||
|
||||
if categories, ok := updates["categories"]; ok {
|
||||
if catSlice, ok := categories.([]*models.Category); ok {
|
||||
categoryIDs = catSlice
|
||||
delete(updates, "categories")
|
||||
}
|
||||
}
|
||||
|
||||
if tags, ok := updates["tags"]; ok {
|
||||
if tagSlice, ok := tags.([]*models.Tag); ok {
|
||||
tagIDs = tagSlice
|
||||
delete(updates, "tags")
|
||||
}
|
||||
}
|
||||
|
||||
// Update basic fields
|
||||
result := database.DB.Model(&models.Post{}).Where("id = ?", id).Updates(updates)
|
||||
if result.Error != nil {
|
||||
return result.Error
|
||||
}
|
||||
if result.RowsAffected == 0 {
|
||||
return gorm.ErrRecordNotFound
|
||||
}
|
||||
|
||||
// Update relationships if provided
|
||||
if len(categoryIDs) > 0 || len(tagIDs) > 0 {
|
||||
var post models.Post
|
||||
if err := database.DB.First(&post, id).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(categoryIDs) > 0 {
|
||||
if err := database.DB.Model(&post).Association("Categories").Replace(categoryIDs); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if len(tagIDs) > 0 {
|
||||
if err := database.DB.Model(&post).Association("Tags").Replace(tagIDs); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeletePost deletes a post by ID
|
||||
func (s *PostService) DeletePost(id uint64) error {
|
||||
result := database.DB.Delete(&models.Post{}, id)
|
||||
if result.Error != nil {
|
||||
return result.Error
|
||||
}
|
||||
if result.RowsAffected == 0 {
|
||||
return gorm.ErrRecordNotFound
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetPostsByCategory retrieves posts by category ID
|
||||
func (s *PostService) GetPostsByCategory(categoryID uint64, page, limit int) ([]models.Post, int64, error) {
|
||||
var posts []models.Post
|
||||
var total int64
|
||||
|
||||
query := database.DB.
|
||||
Joins("JOIN post_categories ON post_categories.post_id = posts.id").
|
||||
Where("post_categories.category_id = ? AND posts.is_active = ?", categoryID, true).
|
||||
Preload("User").
|
||||
Preload("Categories").
|
||||
Preload("Tags")
|
||||
|
||||
query.Model(&models.Post{}).Count(&total)
|
||||
|
||||
err := query.
|
||||
Offset((page - 1) * limit).
|
||||
Limit(limit).
|
||||
Order("posts.created_at DESC").
|
||||
Find(&posts).Error
|
||||
|
||||
return posts, total, err
|
||||
}
|
||||
|
||||
// GetPostsByTag retrieves posts by tag ID
|
||||
func (s *PostService) GetPostsByTag(tagID uint64, page, limit int) ([]models.Post, int64, error) {
|
||||
var posts []models.Post
|
||||
var total int64
|
||||
|
||||
query := database.DB.
|
||||
Joins("JOIN post_tags ON post_tags.post_id = posts.id").
|
||||
Where("post_tags.tag_id = ? AND posts.is_active = ?", tagID, true).
|
||||
Preload("User").
|
||||
Preload("Categories").
|
||||
Preload("Tags")
|
||||
|
||||
query.Model(&models.Post{}).Count(&total)
|
||||
|
||||
err := query.
|
||||
Offset((page - 1) * limit).
|
||||
Limit(limit).
|
||||
Order("posts.created_at DESC").
|
||||
Find(&posts).Error
|
||||
|
||||
return posts, total, err
|
||||
}
|
||||
Reference in New Issue
Block a user