feat: add feature upload file coverimage in article
This commit is contained in:
parent
76bd158b55
commit
fc1298e894
|
@ -27,4 +27,5 @@ go.work.sum
|
|||
.env.dev
|
||||
|
||||
# Ignore avatar images
|
||||
/public/uploads/avatars/
|
||||
/public/uploads/avatars/
|
||||
/public/uploads/articles/
|
|
@ -29,9 +29,7 @@ func (r *RequestArticleDTO) Validate() (map[string][]string, bool) {
|
|||
if strings.TrimSpace(r.Title) == "" {
|
||||
errors["title"] = append(errors["title"], "Title is required")
|
||||
}
|
||||
if strings.TrimSpace(r.CoverImage) == "" {
|
||||
errors["coverImage"] = append(errors["coverImage"], "Cover image is required")
|
||||
}
|
||||
|
||||
if strings.TrimSpace(r.Author) == "" {
|
||||
errors["author"] = append(errors["author"], "Author is required")
|
||||
}
|
||||
|
|
|
@ -18,22 +18,28 @@ func NewArticleHandler(articleService services.ArticleService) *ArticleHandler {
|
|||
}
|
||||
|
||||
func (h *ArticleHandler) CreateArticle(c *fiber.Ctx) error {
|
||||
var requestArticleDTO dto.RequestArticleDTO
|
||||
if err := c.BodyParser(&requestArticleDTO); err != nil {
|
||||
|
||||
var request dto.RequestArticleDTO
|
||||
if err := c.BodyParser(&request); err != nil {
|
||||
return utils.ValidationErrorResponse(c, map[string][]string{"body": {"Invalid body"}})
|
||||
}
|
||||
|
||||
errors, valid := requestArticleDTO.Validate()
|
||||
errors, valid := request.Validate()
|
||||
if !valid {
|
||||
return utils.ValidationErrorResponse(c, errors)
|
||||
}
|
||||
|
||||
articleResponse, err := h.ArticleService.CreateArticle(requestArticleDTO)
|
||||
coverImage, err := c.FormFile("coverImage")
|
||||
if err != nil {
|
||||
return utils.GenericErrorResponse(c, fiber.StatusBadRequest, err.Error())
|
||||
return utils.GenericErrorResponse(c, fiber.StatusBadRequest, "Cover image is required")
|
||||
}
|
||||
|
||||
return utils.CreateResponse(c, articleResponse, "Article created successfully")
|
||||
articleResponse, err := h.ArticleService.CreateArticle(request, coverImage)
|
||||
if err != nil {
|
||||
return utils.GenericErrorResponse(c, fiber.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return utils.SuccessResponse(c, articleResponse, "Article created successfully")
|
||||
}
|
||||
|
||||
func (h *ArticleHandler) GetAllArticles(c *fiber.Ctx) error {
|
||||
|
|
|
@ -2,8 +2,12 @@ package services
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"mime/multipart"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/pahmiudahgede/senggoldong/dto"
|
||||
"github.com/pahmiudahgede/senggoldong/internal/repositories"
|
||||
"github.com/pahmiudahgede/senggoldong/model"
|
||||
|
@ -11,7 +15,7 @@ import (
|
|||
)
|
||||
|
||||
type ArticleService interface {
|
||||
CreateArticle(articleDTO dto.RequestArticleDTO) (*dto.ArticleResponseDTO, error)
|
||||
CreateArticle(request dto.RequestArticleDTO, coverImage *multipart.FileHeader) (*dto.ArticleResponseDTO, error)
|
||||
GetAllArticles(page, limit int) ([]dto.ArticleResponseDTO, int, error)
|
||||
GetArticleByID(id string) (*dto.ArticleResponseDTO, error)
|
||||
}
|
||||
|
@ -24,22 +28,55 @@ func NewArticleService(articleRepo repositories.ArticleRepository) ArticleServic
|
|||
return &articleService{ArticleRepo: articleRepo}
|
||||
}
|
||||
|
||||
func (s *articleService) CreateArticle(articleDTO dto.RequestArticleDTO) (*dto.ArticleResponseDTO, error) {
|
||||
func (s *articleService) CreateArticle(request dto.RequestArticleDTO, coverImage *multipart.FileHeader) (*dto.ArticleResponseDTO, error) {
|
||||
|
||||
article := &model.Article{
|
||||
Title: articleDTO.Title,
|
||||
CoverImage: articleDTO.CoverImage,
|
||||
Author: articleDTO.Author,
|
||||
Heading: articleDTO.Heading,
|
||||
Content: articleDTO.Content,
|
||||
coverImageDir := "./public/uploads/articles"
|
||||
if _, err := os.Stat(coverImageDir); os.IsNotExist(err) {
|
||||
err := os.MkdirAll(coverImageDir, os.ModePerm)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create directory for cover image: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
err := s.ArticleRepo.CreateArticle(article)
|
||||
extension := filepath.Ext(coverImage.Filename)
|
||||
if extension != ".jpg" && extension != ".jpeg" && extension != ".png" {
|
||||
return nil, fmt.Errorf("invalid file type, only .jpg, .jpeg, and .png are allowed")
|
||||
}
|
||||
|
||||
coverImageFileName := fmt.Sprintf("%s_cover%s", uuid.New().String(), extension)
|
||||
coverImagePath := filepath.Join(coverImageDir, coverImageFileName)
|
||||
|
||||
src, err := coverImage.Open()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to open uploaded file: %v", err)
|
||||
}
|
||||
defer src.Close()
|
||||
|
||||
dst, err := os.Create(coverImagePath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create cover image file: %v", err)
|
||||
}
|
||||
defer dst.Close()
|
||||
|
||||
_, err = dst.ReadFrom(src)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to save cover image: %v", err)
|
||||
}
|
||||
|
||||
article := model.Article{
|
||||
Title: request.Title,
|
||||
CoverImage: coverImagePath,
|
||||
Author: request.Author,
|
||||
Heading: request.Heading,
|
||||
Content: request.Content,
|
||||
}
|
||||
|
||||
err = s.ArticleRepo.CreateArticle(&article)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create article: %v", err)
|
||||
}
|
||||
|
||||
publishedAt, _ := utils.FormatDateToIndonesianFormat(article.PublishedAt)
|
||||
createdAt, _ := utils.FormatDateToIndonesianFormat(article.PublishedAt)
|
||||
updatedAt, _ := utils.FormatDateToIndonesianFormat(article.UpdatedAt)
|
||||
|
||||
articleResponseDTO := &dto.ArticleResponseDTO{
|
||||
|
@ -49,7 +86,7 @@ func (s *articleService) CreateArticle(articleDTO dto.RequestArticleDTO) (*dto.A
|
|||
Author: article.Author,
|
||||
Heading: article.Heading,
|
||||
Content: article.Content,
|
||||
PublishedAt: publishedAt,
|
||||
PublishedAt: createdAt,
|
||||
UpdatedAt: updatedAt,
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue