[feature/backend] add categories param in posts

This commit is contained in:
CDN 2025-02-22 02:42:55 +08:00
parent 958e3c2886
commit be8bf22017
Signed by: CDN
GPG key ID: 0C656827F9F80080
21 changed files with 448 additions and 281 deletions

View file

@ -186,10 +186,12 @@ func (h *Handler) ListPosts(c *gin.Context) {
langCode = "en" // Default to English
}
var categoryID *int
if catIDStr := c.Query("category_id"); catIDStr != "" {
if id, err := strconv.Atoi(catIDStr); err == nil {
categoryID = &id
var categoryIDs []int
if catIDsStr := c.QueryArray("category_ids"); len(catIDsStr) > 0 {
for _, idStr := range catIDsStr {
if id, err := strconv.Atoi(idStr); err == nil {
categoryIDs = append(categoryIDs, id)
}
}
}
@ -207,7 +209,7 @@ func (h *Handler) ListPosts(c *gin.Context) {
}
}
posts, err := h.service.ListPosts(c.Request.Context(), langCode, categoryID, limit, offset)
posts, err := h.service.ListPosts(c.Request.Context(), langCode, categoryIDs, limit, offset)
if err != nil {
log.Error().Err(err).Msg("Failed to list posts")
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to list posts"})
@ -256,7 +258,22 @@ func (h *Handler) GetPost(c *gin.Context) {
}
func (h *Handler) CreatePost(c *gin.Context) {
post, err := h.service.CreatePost(c.Request.Context(), "draft") // Default to draft status
var req struct {
Status string `json:"status" binding:"omitempty,oneof=draft published archived"`
CategoryIDs []int `json:"category_ids" binding:"required,min=1"`
}
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
status := req.Status
if status == "" {
status = "draft" // Default to draft status
}
post, err := h.service.CreatePost(c.Request.Context(), status, req.CategoryIDs)
if err != nil {
log.Error().Err(err).Msg("Failed to create post")
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create post"})
@ -268,7 +285,8 @@ func (h *Handler) CreatePost(c *gin.Context) {
"id": post.ID,
"status": post.Status,
"edges": gin.H{
"contents": []interface{}{},
"contents": []interface{}{},
"categories": []interface{}{},
},
}

View file

@ -476,7 +476,7 @@ func (s *serviceImpl) DeleteMedia(ctx context.Context, id int, userID int) error
}
// Post operations
func (s *serviceImpl) CreatePost(ctx context.Context, status string) (*ent.Post, error) {
func (s *serviceImpl) CreatePost(ctx context.Context, status string, categoryIDs []int) (*ent.Post, error) {
var postStatus post.Status
switch status {
case "draft":
@ -492,10 +492,25 @@ func (s *serviceImpl) CreatePost(ctx context.Context, status string) (*ent.Post,
// Generate a random slug
slug := fmt.Sprintf("post-%s", uuid.New().String()[:8])
return s.client.Post.Create().
// Create post with categories
postCreate := s.client.Post.Create().
SetStatus(postStatus).
SetSlug(slug).
Save(ctx)
SetSlug(slug)
// Add categories if provided
if len(categoryIDs) > 0 {
categories := make([]*ent.Category, 0, len(categoryIDs))
for _, id := range categoryIDs {
category, err := s.client.Category.Get(ctx, id)
if err != nil {
return nil, fmt.Errorf("failed to get category %d: %w", id, err)
}
categories = append(categories, category)
}
postCreate.AddCategories(categories...)
}
return postCreate.Save(ctx)
}
func (s *serviceImpl) AddPostContent(ctx context.Context, postID int, langCode, title, content, summary string, metaKeywords, metaDescription string) (*ent.PostContent, error) {
@ -574,7 +589,7 @@ func (s *serviceImpl) GetPostBySlug(ctx context.Context, langCode, slug string)
WithContents(func(q *ent.PostContentQuery) {
q.Where(postcontent.LanguageCodeEQ(languageCode))
}).
WithCategory().
WithCategories().
All(ctx)
if err != nil {
return nil, fmt.Errorf("failed to get posts: %w", err)
@ -590,7 +605,7 @@ func (s *serviceImpl) GetPostBySlug(ctx context.Context, langCode, slug string)
return posts[0], nil
}
func (s *serviceImpl) ListPosts(ctx context.Context, langCode string, categoryID *int, limit, offset int) ([]*ent.Post, error) {
func (s *serviceImpl) ListPosts(ctx context.Context, langCode string, categoryIDs []int, limit, offset int) ([]*ent.Post, error) {
var languageCode postcontent.LanguageCode
switch langCode {
case "en":
@ -610,8 +625,8 @@ func (s *serviceImpl) ListPosts(ctx context.Context, langCode string, categoryID
Where(post.StatusEQ(post.StatusPublished))
// Add category filter if provided
if categoryID != nil {
query = query.Where(post.HasCategoryWith(category.ID(*categoryID)))
if len(categoryIDs) > 0 {
query = query.Where(post.HasCategoriesWith(category.IDIn(categoryIDs...)))
}
// Get unique post IDs
@ -638,7 +653,7 @@ func (s *serviceImpl) ListPosts(ctx context.Context, langCode string, categoryID
}
// If no category filter is applied, only take the latest 5 posts
if categoryID == nil && len(postIDs) > 5 {
if len(categoryIDs) == 0 && len(postIDs) > 5 {
postIDs = postIDs[:5]
}
@ -666,7 +681,7 @@ func (s *serviceImpl) ListPosts(ctx context.Context, langCode string, categoryID
WithContents(func(q *ent.PostContentQuery) {
q.Where(postcontent.LanguageCodeEQ(languageCode))
}).
WithCategory().
WithCategories().
Order(ent.Desc(post.FieldCreatedAt)).
All(ctx)
if err != nil {

View file

@ -34,10 +34,10 @@ type Service interface {
GetCategories(ctx context.Context, langCode string) ([]*ent.Category, error)
// Post operations
CreatePost(ctx context.Context, status string) (*ent.Post, error)
CreatePost(ctx context.Context, status string, categoryIDs []int) (*ent.Post, error)
AddPostContent(ctx context.Context, postID int, langCode, title, content, summary string, metaKeywords, metaDescription string) (*ent.PostContent, error)
GetPostBySlug(ctx context.Context, langCode, slug string) (*ent.Post, error)
ListPosts(ctx context.Context, langCode string, categoryID *int, limit, offset int) ([]*ent.Post, error)
ListPosts(ctx context.Context, langCode string, categoryIDs []int, limit, offset int) ([]*ent.Post, error)
// Media operations
ListMedia(ctx context.Context, limit, offset int) ([]*ent.Media, error)