first commit
This commit is contained in:
107
app/blog/services/category_service.go
Normal file
107
app/blog/services/category_service.go
Normal file
@@ -0,0 +1,107 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"gobeyhan/database"
|
||||
"gobeyhan/database/models"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type CategoryService struct{}
|
||||
|
||||
func NewCategoryService() *CategoryService {
|
||||
return &CategoryService{}
|
||||
}
|
||||
|
||||
// GetAllCategories retrieves all categories, optionally filtering by active status
|
||||
func (s *CategoryService) GetAllCategories(activeOnly bool) ([]models.Category, error) {
|
||||
var categories []models.Category
|
||||
query := database.DB.Preload("Parent").Preload("Children")
|
||||
|
||||
if activeOnly {
|
||||
query = query.Where("is_active = ?", true)
|
||||
}
|
||||
|
||||
err := query.Order("`order` ASC, created_at DESC").Find(&categories).Error
|
||||
return categories, err
|
||||
}
|
||||
|
||||
// GetCategoryByID retrieves a category by ID with parent and children relationships
|
||||
func (s *CategoryService) GetCategoryByID(id uint64) (*models.Category, error) {
|
||||
var category models.Category
|
||||
err := database.DB.
|
||||
Preload("Parent").
|
||||
Preload("Children").
|
||||
First(&category, id).Error
|
||||
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &category, nil
|
||||
}
|
||||
|
||||
// GetCategoryBySlug retrieves a category by slug
|
||||
func (s *CategoryService) GetCategoryBySlug(slug string) (*models.Category, error) {
|
||||
var category models.Category
|
||||
err := database.DB.
|
||||
Preload("Parent").
|
||||
Preload("Children").
|
||||
Where("slug = ?", slug).
|
||||
First(&category).Error
|
||||
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &category, nil
|
||||
}
|
||||
|
||||
// CreateCategory creates a new category
|
||||
func (s *CategoryService) CreateCategory(category *models.Category) error {
|
||||
return database.DB.Create(category).Error
|
||||
}
|
||||
|
||||
// UpdateCategory updates an existing category
|
||||
func (s *CategoryService) UpdateCategory(id uint64, updates map[string]interface{}) error {
|
||||
result := database.DB.Model(&models.Category{}).Where("id = ?", id).Updates(updates)
|
||||
if result.Error != nil {
|
||||
return result.Error
|
||||
}
|
||||
if result.RowsAffected == 0 {
|
||||
return gorm.ErrRecordNotFound
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteCategory deletes a category by ID
|
||||
func (s *CategoryService) DeleteCategory(id uint64) error {
|
||||
result := database.DB.Delete(&models.Category{}, id)
|
||||
if result.Error != nil {
|
||||
return result.Error
|
||||
}
|
||||
if result.RowsAffected == 0 {
|
||||
return gorm.ErrRecordNotFound
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetCategoriesByParent retrieves child categories of a parent
|
||||
func (s *CategoryService) GetCategoriesByParent(parentID uint64, activeOnly bool) ([]models.Category, error) {
|
||||
var categories []models.Category
|
||||
query := database.DB.Where("parent_id = ?", parentID)
|
||||
|
||||
if activeOnly {
|
||||
query = query.Where("is_active = ?", true)
|
||||
}
|
||||
|
||||
err := query.Order("`order` ASC, created_at DESC").Find(&categories).Error
|
||||
return categories, err
|
||||
}
|
||||
67
app/blog/services/category_view_service.go
Normal file
67
app/blog/services/category_view_service.go
Normal file
@@ -0,0 +1,67 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"gobeyhan/database"
|
||||
"gobeyhan/database/models"
|
||||
)
|
||||
|
||||
type CategoryViewService struct{}
|
||||
|
||||
func NewCategoryViewService() *CategoryViewService {
|
||||
return &CategoryViewService{}
|
||||
}
|
||||
|
||||
// TrackCategoryView records a category view
|
||||
func (s *CategoryViewService) TrackCategoryView(categoryID uint64, ipAddress, userAgent string) error {
|
||||
view := &models.CategoryView{
|
||||
CategoryID: categoryID,
|
||||
IPAddress: ipAddress,
|
||||
UserAgent: userAgent,
|
||||
}
|
||||
return database.DB.Create(view).Error
|
||||
}
|
||||
|
||||
// GetCategoryViewCount gets total view count for a category
|
||||
func (s *CategoryViewService) GetCategoryViewCount(categoryID uint64) (int64, error) {
|
||||
var count int64
|
||||
err := database.DB.Model(&models.CategoryView{}).
|
||||
Where("category_id = ?", categoryID).
|
||||
Count(&count).Error
|
||||
return count, err
|
||||
}
|
||||
|
||||
// GetAllCategoryViews gets all views for a category with pagination
|
||||
func (s *CategoryViewService) GetAllCategoryViews(page, limit int) ([]models.CategoryView, int64, error) {
|
||||
var views []models.CategoryView
|
||||
var total int64
|
||||
|
||||
query := database.DB.Preload("Category")
|
||||
|
||||
query.Model(&models.CategoryView{}).Count(&total)
|
||||
|
||||
err := query.
|
||||
Offset((page - 1) * limit).
|
||||
Limit(limit).
|
||||
Order("created_at DESC").
|
||||
Find(&views).Error
|
||||
|
||||
return views, total, err
|
||||
}
|
||||
|
||||
// GetViewsByCategory gets views for a specific category
|
||||
func (s *CategoryViewService) GetViewsByCategory(categoryID uint64, page, limit int) ([]models.CategoryView, int64, error) {
|
||||
var views []models.CategoryView
|
||||
var total int64
|
||||
|
||||
query := database.DB.Where("category_id = ?", categoryID)
|
||||
|
||||
query.Model(&models.CategoryView{}).Count(&total)
|
||||
|
||||
err := query.
|
||||
Offset((page - 1) * limit).
|
||||
Limit(limit).
|
||||
Order("created_at DESC").
|
||||
Find(&views).Error
|
||||
|
||||
return views, total, err
|
||||
}
|
||||
115
app/blog/services/comment_service.go
Normal file
115
app/blog/services/comment_service.go
Normal file
@@ -0,0 +1,115 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"gobeyhan/database"
|
||||
"gobeyhan/database/models"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type CommentService struct{}
|
||||
|
||||
func NewCommentService() *CommentService {
|
||||
return &CommentService{}
|
||||
}
|
||||
|
||||
// GetCommentsByPost retrieves comments for a specific post
|
||||
func (s *CommentService) GetCommentsByPost(postID uint64, activeOnly bool) ([]models.Comment, error) {
|
||||
var comments []models.Comment
|
||||
query := database.DB.
|
||||
Where("product_id = ?", postID).
|
||||
Preload("Parent").
|
||||
Preload("Children")
|
||||
|
||||
if activeOnly {
|
||||
query = query.Where("is_active = ?", true)
|
||||
}
|
||||
|
||||
err := query.Order("created_at DESC").Find(&comments).Error
|
||||
return comments, err
|
||||
}
|
||||
|
||||
// GetAllComments retrieves all comments with pagination
|
||||
func (s *CommentService) GetAllComments(page, limit int, activeOnly bool) ([]models.Comment, int64, error) {
|
||||
var comments []models.Comment
|
||||
var total int64
|
||||
|
||||
query := database.DB.
|
||||
Preload("Product").
|
||||
Preload("Parent").
|
||||
Preload("Children")
|
||||
|
||||
if activeOnly {
|
||||
query = query.Where("is_active = ?", true)
|
||||
}
|
||||
|
||||
query.Model(&models.Comment{}).Count(&total)
|
||||
|
||||
err := query.
|
||||
Offset((page - 1) * limit).
|
||||
Limit(limit).
|
||||
Order("created_at DESC").
|
||||
Find(&comments).Error
|
||||
|
||||
return comments, total, err
|
||||
}
|
||||
|
||||
// GetCommentByID retrieves a comment by ID
|
||||
func (s *CommentService) GetCommentByID(id uint64) (*models.Comment, error) {
|
||||
var comment models.Comment
|
||||
err := database.DB.
|
||||
Preload("Product").
|
||||
Preload("Parent").
|
||||
Preload("Children").
|
||||
First(&comment, id).Error
|
||||
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &comment, nil
|
||||
}
|
||||
|
||||
// CreateComment creates a new comment
|
||||
func (s *CommentService) CreateComment(comment *models.Comment) error {
|
||||
return database.DB.Create(comment).Error
|
||||
}
|
||||
|
||||
// UpdateComment updates an existing comment
|
||||
func (s *CommentService) UpdateComment(id uint64, updates map[string]interface{}) error {
|
||||
result := database.DB.Model(&models.Comment{}).Where("id = ?", id).Updates(updates)
|
||||
if result.Error != nil {
|
||||
return result.Error
|
||||
}
|
||||
if result.RowsAffected == 0 {
|
||||
return gorm.ErrRecordNotFound
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteComment deletes a comment by ID
|
||||
func (s *CommentService) DeleteComment(id uint64) error {
|
||||
result := database.DB.Delete(&models.Comment{}, id)
|
||||
if result.Error != nil {
|
||||
return result.Error
|
||||
}
|
||||
if result.RowsAffected == 0 {
|
||||
return gorm.ErrRecordNotFound
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetCommentReplies retrieves replies to a specific comment
|
||||
func (s *CommentService) GetCommentReplies(commentID uint64) ([]models.Comment, error) {
|
||||
var replies []models.Comment
|
||||
err := database.DB.
|
||||
Where("parent_id = ? AND is_active = ?", commentID, true).
|
||||
Order("created_at ASC").
|
||||
Find(&replies).Error
|
||||
|
||||
return replies, err
|
||||
}
|
||||
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
|
||||
}
|
||||
87
app/blog/services/tag_service.go
Normal file
87
app/blog/services/tag_service.go
Normal file
@@ -0,0 +1,87 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"gobeyhan/database"
|
||||
"gobeyhan/database/models"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type TagService struct{}
|
||||
|
||||
func NewTagService() *TagService {
|
||||
return &TagService{}
|
||||
}
|
||||
|
||||
// GetAllTags retrieves all tags, optionally filtering by active status
|
||||
func (s *TagService) GetAllTags(activeOnly bool) ([]models.Tag, error) {
|
||||
var tags []models.Tag
|
||||
query := database.DB
|
||||
|
||||
if activeOnly {
|
||||
query = query.Where("is_active = ?", true)
|
||||
}
|
||||
|
||||
err := query.Order("tag ASC").Find(&tags).Error
|
||||
return tags, err
|
||||
}
|
||||
|
||||
// GetTagByID retrieves a tag by ID
|
||||
func (s *TagService) GetTagByID(id uint64) (*models.Tag, error) {
|
||||
var tag models.Tag
|
||||
err := database.DB.First(&tag, id).Error
|
||||
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &tag, nil
|
||||
}
|
||||
|
||||
// GetTagBySlug retrieves a tag by slug
|
||||
func (s *TagService) GetTagBySlug(slug string) (*models.Tag, error) {
|
||||
var tag models.Tag
|
||||
err := database.DB.Where("slug = ?", slug).First(&tag).Error
|
||||
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &tag, nil
|
||||
}
|
||||
|
||||
// CreateTag creates a new tag
|
||||
func (s *TagService) CreateTag(tag *models.Tag) error {
|
||||
return database.DB.Create(tag).Error
|
||||
}
|
||||
|
||||
// UpdateTag updates an existing tag
|
||||
func (s *TagService) UpdateTag(id uint64, updates map[string]interface{}) error {
|
||||
result := database.DB.Model(&models.Tag{}).Where("id = ?", id).Updates(updates)
|
||||
if result.Error != nil {
|
||||
return result.Error
|
||||
}
|
||||
if result.RowsAffected == 0 {
|
||||
return gorm.ErrRecordNotFound
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteTag deletes a tag by ID
|
||||
func (s *TagService) DeleteTag(id uint64) error {
|
||||
result := database.DB.Delete(&models.Tag{}, id)
|
||||
if result.Error != nil {
|
||||
return result.Error
|
||||
}
|
||||
if result.RowsAffected == 0 {
|
||||
return gorm.ErrRecordNotFound
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user