MIF_E31222379_BE/internal/services/article_service.go

178 lines
5.3 KiB
Go

package services
import (
"fmt"
"time"
"github.com/pahmiudahgede/senggoldong/dto"
"github.com/pahmiudahgede/senggoldong/internal/repositories"
"github.com/pahmiudahgede/senggoldong/model"
"github.com/pahmiudahgede/senggoldong/utils"
)
type ArticleService interface {
CreateArticle(articleDTO dto.RequestArticleDTO) (*dto.ArticleResponseDTO, error)
GetAllArticles(page, limit int) ([]dto.ArticleResponseDTO, int, error)
GetArticleByID(id string) (*dto.ArticleResponseDTO, error)
}
type articleService struct {
ArticleRepo repositories.ArticleRepository
}
func NewArticleService(articleRepo repositories.ArticleRepository) ArticleService {
return &articleService{ArticleRepo: articleRepo}
}
func (s *articleService) CreateArticle(articleDTO dto.RequestArticleDTO) (*dto.ArticleResponseDTO, error) {
article := &model.Article{
Title: articleDTO.Title,
CoverImage: articleDTO.CoverImage,
Author: articleDTO.Author,
Heading: articleDTO.Heading,
Content: articleDTO.Content,
}
err := s.ArticleRepo.CreateArticle(article)
if err != nil {
return nil, fmt.Errorf("failed to create article: %v", err)
}
publishedAt, _ := utils.FormatDateToIndonesianFormat(article.PublishedAt)
updatedAt, _ := utils.FormatDateToIndonesianFormat(article.UpdatedAt)
articleResponseDTO := &dto.ArticleResponseDTO{
ID: article.ID,
Title: article.Title,
CoverImage: article.CoverImage,
Author: article.Author,
Heading: article.Heading,
Content: article.Content,
PublishedAt: publishedAt,
UpdatedAt: updatedAt,
}
cacheKey := fmt.Sprintf("article:%s", article.ID)
cacheData := map[string]interface{}{
"data": articleResponseDTO,
}
err = utils.SetJSONData(cacheKey, cacheData, time.Hour*24)
if err != nil {
fmt.Printf("Error caching article to Redis: %v\n", err)
}
return articleResponseDTO, nil
}
func (s *articleService) GetAllArticles(page, limit int) ([]dto.ArticleResponseDTO, int, error) {
cacheKey := fmt.Sprintf("articles_page:%d_limit:%d", page, limit)
cachedData, err := utils.GetJSONData(cacheKey)
if err == nil && cachedData != nil {
var articles []dto.ArticleResponseDTO
if data, ok := cachedData["data"].([]interface{}); ok {
for _, item := range data {
articleData, ok := item.(map[string]interface{})
if ok {
articles = append(articles, dto.ArticleResponseDTO{
ID: articleData["article_id"].(string),
Title: articleData["title"].(string),
CoverImage: articleData["coverImage"].(string),
Author: articleData["author"].(string),
Heading: articleData["heading"].(string),
Content: articleData["content"].(string),
PublishedAt: articleData["publishedAt"].(string),
UpdatedAt: articleData["updatedAt"].(string),
})
}
}
return articles, len(articles), nil
}
}
articles, total, err := s.ArticleRepo.FindAllArticles(page, limit)
if err != nil {
return nil, 0, fmt.Errorf("failed to fetch articles: %v", err)
}
var articleDTOs []dto.ArticleResponseDTO
for _, article := range articles {
publishedAt, _ := utils.FormatDateToIndonesianFormat(article.PublishedAt)
updatedAt, _ := utils.FormatDateToIndonesianFormat(article.UpdatedAt)
articleDTOs = append(articleDTOs, dto.ArticleResponseDTO{
ID: article.ID,
Title: article.Title,
CoverImage: article.CoverImage,
Author: article.Author,
Heading: article.Heading,
Content: article.Content,
PublishedAt: publishedAt,
UpdatedAt: updatedAt,
})
}
cacheData := map[string]interface{}{
"data": articleDTOs,
}
err = utils.SetJSONData(cacheKey, cacheData, time.Hour*24)
if err != nil {
fmt.Printf("Error caching articles to Redis: %v\n", err)
}
return articleDTOs, total, nil
}
func (s *articleService) GetArticleByID(id string) (*dto.ArticleResponseDTO, error) {
cacheKey := fmt.Sprintf("article:%s", id)
cachedData, err := utils.GetJSONData(cacheKey)
if err == nil && cachedData != nil {
articleData, ok := cachedData["data"].(map[string]interface{})
if ok {
article := dto.ArticleResponseDTO{
ID: articleData["article_id"].(string),
Title: articleData["title"].(string),
CoverImage: articleData["coverImage"].(string),
Author: articleData["author"].(string),
Heading: articleData["heading"].(string),
Content: articleData["content"].(string),
PublishedAt: articleData["publishedAt"].(string),
UpdatedAt: articleData["updatedAt"].(string),
}
return &article, nil
}
}
article, err := s.ArticleRepo.FindArticleByID(id)
if err != nil {
return nil, fmt.Errorf("failed to fetch article by ID: %v", err)
}
createdAt, _ := utils.FormatDateToIndonesianFormat(article.PublishedAt)
updatedAt, _ := utils.FormatDateToIndonesianFormat(article.UpdatedAt)
articleResponseDTO := &dto.ArticleResponseDTO{
ID: article.ID,
Title: article.Title,
CoverImage: article.CoverImage,
Author: article.Author,
Heading: article.Heading,
Content: article.Content,
PublishedAt: createdAt,
UpdatedAt: updatedAt,
}
cacheData := map[string]interface{}{
"data": articleResponseDTO,
}
err = utils.SetJSONData(cacheKey, cacheData, time.Hour*24)
if err != nil {
fmt.Printf("Error caching article to Redis: %v\n", err)
}
return articleResponseDTO, nil
}