mirror of
https://github.com/Dvorinka/MyClubServer.git
synced 2026-06-04 02:32:57 +00:00
298 lines
8.3 KiB
Go
298 lines
8.3 KiB
Go
package controllers
|
|
|
|
import (
|
|
"fotbal-club/internal/models"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// ExampleUsageController demonstrates how to use the new utility controllers
|
|
type ExampleUsageController struct {
|
|
DB *gorm.DB
|
|
}
|
|
|
|
// NewExampleUsageController creates a new ExampleUsageController instance
|
|
func NewExampleUsageController(db *gorm.DB) *ExampleUsageController {
|
|
return &ExampleUsageController{DB: db}
|
|
}
|
|
|
|
// ===== EXAMPLE 1: Simple List with Pagination =====
|
|
// GET /api/v1/articles?page=1&page_size=20
|
|
func (euc *ExampleUsageController) ListArticlesWithPagination(c *gin.Context) {
|
|
query := euc.DB.Model(&models.Article{}).Where("published = ?", true)
|
|
|
|
var articles []models.Article
|
|
meta, err := Paginator.Paginate(c, query, &articles)
|
|
if err != nil {
|
|
Respond.InternalError(c, "Failed to retrieve articles")
|
|
return
|
|
}
|
|
|
|
Respond.SuccessWithMeta(c, articles, meta, "Articles retrieved successfully")
|
|
}
|
|
|
|
// ===== EXAMPLE 2: List with Search, Sort, and Pagination =====
|
|
// GET /api/v1/articles?search=football&sort=created_at:desc&page=1&page_size=20
|
|
func (euc *ExampleUsageController) ListArticlesWithFilters(c *gin.Context) {
|
|
query := QueryParser.BuildQueryChain(c, euc.DB.Model(&models.Article{})).
|
|
WithSearch("title", "content").
|
|
WithSort("created_at", "desc").
|
|
Build()
|
|
|
|
var articles []models.Article
|
|
meta, err := Paginator.PaginateWithPreload(c, query, &articles, "Author", "Category")
|
|
if err != nil {
|
|
Respond.InternalError(c, "Failed to retrieve articles")
|
|
return
|
|
}
|
|
|
|
Respond.SuccessWithMeta(c, articles, meta, "Articles retrieved successfully")
|
|
}
|
|
|
|
// ===== EXAMPLE 3: Create with Validation =====
|
|
func (euc *ExampleUsageController) CreateArticleWithValidation(c *gin.Context) {
|
|
var req struct {
|
|
Title string `json:"title" validate:"required,min=3,max=200"`
|
|
Content string `json:"content" validate:"required,min=10"`
|
|
Slug string `json:"slug" validate:"omitempty,slug"`
|
|
}
|
|
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
Respond.BadRequest(c, "Invalid JSON: "+err.Error())
|
|
return
|
|
}
|
|
|
|
// Validate using our helper
|
|
if !Validator.ValidateAndRespond(c, req) {
|
|
return // Response already sent
|
|
}
|
|
|
|
// Sanitize inputs
|
|
req.Title = Validator.SanitizeString(req.Title)
|
|
req.Slug = Validator.SanitizeSlug(req.Slug)
|
|
|
|
article := models.Article{
|
|
Title: req.Title,
|
|
Content: req.Content,
|
|
Slug: req.Slug,
|
|
}
|
|
|
|
if err := euc.DB.Create(&article).Error; err != nil {
|
|
Respond.InternalError(c, "Failed to create article")
|
|
return
|
|
}
|
|
|
|
// Log the creation
|
|
if AuditLogger != nil {
|
|
_ = AuditLogger.LogCreate(c, "Article", article.ID, "Article created: "+article.Title)
|
|
}
|
|
|
|
Respond.Created(c, article, "Article created successfully")
|
|
}
|
|
|
|
// ===== EXAMPLE 4: Update with Audit Logging =====
|
|
func (euc *ExampleUsageController) UpdateArticleWithAudit(c *gin.Context) {
|
|
id := c.Param("id")
|
|
|
|
var article models.Article
|
|
if err := euc.DB.First(&article, id).Error; err != nil {
|
|
if err == gorm.ErrRecordNotFound {
|
|
Respond.NotFound(c, "Article not found")
|
|
return
|
|
}
|
|
Respond.InternalError(c, "Failed to retrieve article")
|
|
return
|
|
}
|
|
|
|
// Store old values for audit
|
|
oldTitle := article.Title
|
|
oldPublished := article.Published
|
|
|
|
var req struct {
|
|
Title string `json:"title" validate:"omitempty,min=3,max=200"`
|
|
Published *bool `json:"published"`
|
|
}
|
|
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
Respond.BadRequest(c, "Invalid JSON: "+err.Error())
|
|
return
|
|
}
|
|
|
|
if !Validator.ValidateAndRespond(c, req) {
|
|
return
|
|
}
|
|
|
|
// Apply updates
|
|
if req.Title != "" {
|
|
article.Title = Validator.SanitizeString(req.Title)
|
|
}
|
|
if req.Published != nil {
|
|
article.Published = *req.Published
|
|
}
|
|
|
|
if err := euc.DB.Save(&article).Error; err != nil {
|
|
Respond.InternalError(c, "Failed to update article")
|
|
return
|
|
}
|
|
|
|
// Log the update with changes
|
|
if AuditLogger != nil {
|
|
before := map[string]interface{}{
|
|
"title": oldTitle,
|
|
"published": oldPublished,
|
|
}
|
|
after := map[string]interface{}{
|
|
"title": article.Title,
|
|
"published": article.Published,
|
|
}
|
|
_ = AuditLogger.LogUpdate(c, "Article", article.ID, "Article updated", before, after)
|
|
}
|
|
|
|
Respond.Success(c, article, "Article updated successfully")
|
|
}
|
|
|
|
// ===== EXAMPLE 5: Batch Delete =====
|
|
// POST /api/v1/articles/batch-delete
|
|
// Body: {"ids": [1, 2, 3]}
|
|
func (euc *ExampleUsageController) BatchDeleteArticles(c *gin.Context) {
|
|
if BatchOps == nil {
|
|
BatchOps = NewBatchOperationsController(euc.DB)
|
|
}
|
|
BatchOps.BatchDelete(c, &models.Article{}, "articles")
|
|
}
|
|
|
|
// ===== EXAMPLE 6: Advanced Filtering =====
|
|
// GET /api/v1/articles?published=true&category_ids=1,2,3&from=2024-01-01&to=2024-12-31
|
|
func (euc *ExampleUsageController) ListArticlesAdvanced(c *gin.Context) {
|
|
query := QueryParser.BuildQueryChain(c, euc.DB.Model(&models.Article{})).
|
|
WithSearch("title", "content").
|
|
WithSort("created_at", "desc").
|
|
WithBoolFilter("published", "published").
|
|
WithBoolFilter("featured", "featured").
|
|
WithIDsFilter("category_ids", "category_id").
|
|
WithDateRange("created_at").
|
|
Build()
|
|
|
|
var articles []models.Article
|
|
meta, err := Paginator.PaginateWithPreload(c, query, &articles, "Author", "Category")
|
|
if err != nil {
|
|
Respond.InternalError(c, "Failed to retrieve articles")
|
|
return
|
|
}
|
|
|
|
Respond.SuccessWithMeta(c, articles, meta, "Articles retrieved successfully")
|
|
}
|
|
|
|
// ===== EXAMPLE 7: Batch Publish/Unpublish =====
|
|
// POST /api/v1/articles/batch-publish
|
|
// Body: {"ids": [1, 2, 3]}
|
|
func (euc *ExampleUsageController) BatchPublishArticles(c *gin.Context) {
|
|
if BatchOps == nil {
|
|
BatchOps = NewBatchOperationsController(euc.DB)
|
|
}
|
|
BatchOps.BatchPublish(c, &models.Article{}, "articles", true)
|
|
}
|
|
|
|
func (euc *ExampleUsageController) BatchUnpublishArticles(c *gin.Context) {
|
|
if BatchOps == nil {
|
|
BatchOps = NewBatchOperationsController(euc.DB)
|
|
}
|
|
BatchOps.BatchPublish(c, &models.Article{}, "articles", false)
|
|
}
|
|
|
|
// ===== EXAMPLE 8: Get Entity with Standard Response =====
|
|
func (euc *ExampleUsageController) GetArticle(c *gin.Context) {
|
|
id := c.Param("id")
|
|
|
|
var article models.Article
|
|
if err := euc.DB.Preload("Author").Preload("Category").First(&article, id).Error; err != nil {
|
|
if err == gorm.ErrRecordNotFound {
|
|
Respond.NotFound(c, "Article not found")
|
|
return
|
|
}
|
|
Respond.InternalError(c, "Failed to retrieve article")
|
|
return
|
|
}
|
|
|
|
Respond.Success(c, article, "Article retrieved successfully")
|
|
}
|
|
|
|
// ===== EXAMPLE 9: Delete with Audit =====
|
|
func (euc *ExampleUsageController) DeleteArticleWithAudit(c *gin.Context) {
|
|
id := c.Param("id")
|
|
|
|
var article models.Article
|
|
if err := euc.DB.First(&article, id).Error; err != nil {
|
|
if err == gorm.ErrRecordNotFound {
|
|
Respond.NotFound(c, "Article not found")
|
|
return
|
|
}
|
|
Respond.InternalError(c, "Failed to retrieve article")
|
|
return
|
|
}
|
|
|
|
title := article.Title
|
|
articleID := article.ID
|
|
|
|
if err := euc.DB.Delete(&article).Error; err != nil {
|
|
Respond.InternalError(c, "Failed to delete article")
|
|
return
|
|
}
|
|
|
|
// Log the deletion
|
|
if AuditLogger != nil {
|
|
_ = AuditLogger.LogDelete(c, "Article", articleID, "Article deleted: "+title)
|
|
}
|
|
|
|
Respond.NoContent(c)
|
|
}
|
|
|
|
// ===== EXAMPLE 10: Complex Query with Multiple Filters =====
|
|
func (euc *ExampleUsageController) SearchArticlesComplex(c *gin.Context) {
|
|
// Start with base query
|
|
query := euc.DB.Model(&models.Article{})
|
|
|
|
// Get search term
|
|
searchTerm := QueryParser.GetSearchQuery(c)
|
|
if searchTerm != "" {
|
|
query = QueryParser.ApplySearch(query, searchTerm, "title", "content", "seo_description")
|
|
}
|
|
|
|
// Apply boolean filters
|
|
if published := QueryParser.GetBoolQuery(c, "published"); published != nil {
|
|
query = query.Where("published = ?", *published)
|
|
}
|
|
|
|
if featured := QueryParser.GetBoolQuery(c, "featured"); featured != nil {
|
|
query = query.Where("featured = ?", *featured)
|
|
}
|
|
|
|
// Apply category filter
|
|
if categoryID := c.Query("category_id"); categoryID != "" {
|
|
query = query.Where("category_id = ?", categoryID)
|
|
}
|
|
|
|
// Apply date range
|
|
from, to := QueryParser.GetDateRange(c)
|
|
if from != "" {
|
|
query = query.Where("created_at >= ?", from)
|
|
}
|
|
if to != "" {
|
|
query = query.Where("created_at <= ?", to)
|
|
}
|
|
|
|
// Apply sorting
|
|
query = QueryParser.ApplySortFromContext(c, query, "created_at", "desc")
|
|
|
|
// Execute with pagination
|
|
var articles []models.Article
|
|
meta, err := Paginator.PaginateWithPreload(c, query, &articles, "Author", "Category")
|
|
if err != nil {
|
|
Respond.InternalError(c, "Failed to search articles")
|
|
return
|
|
}
|
|
|
|
Respond.SuccessWithMeta(c, articles, meta, "Search completed successfully")
|
|
}
|