first commit

This commit is contained in:
Beyhan Oğur
2026-04-26 21:43:40 +03:00
commit f34e54c5a5
100 changed files with 27342 additions and 0 deletions

View 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
}

View 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
}

View 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
}

View 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
}

View 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
}