367 lines
10 KiB
Go
367 lines
10 KiB
Go
package services
|
|
|
|
import (
|
|
"fmt"
|
|
"mime/multipart"
|
|
"os"
|
|
"path/filepath"
|
|
"time"
|
|
|
|
"rijig/dto"
|
|
"rijig/internal/repositories"
|
|
"rijig/model"
|
|
"rijig/utils"
|
|
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
type BannerService interface {
|
|
CreateBanner(request dto.RequestBannerDTO, bannerImage *multipart.FileHeader) (*dto.ResponseBannerDTO, error)
|
|
GetAllBanners() ([]dto.ResponseBannerDTO, error)
|
|
GetBannerByID(id string) (*dto.ResponseBannerDTO, error)
|
|
UpdateBanner(id string, request dto.RequestBannerDTO, bannerImage *multipart.FileHeader) (*dto.ResponseBannerDTO, error)
|
|
DeleteBanner(id string) error
|
|
}
|
|
|
|
type bannerService struct {
|
|
BannerRepo repositories.BannerRepository
|
|
}
|
|
|
|
func NewBannerService(bannerRepo repositories.BannerRepository) BannerService {
|
|
return &bannerService{BannerRepo: bannerRepo}
|
|
}
|
|
|
|
func (s *bannerService) saveBannerImage(bannerImage *multipart.FileHeader) (string, error) {
|
|
bannerImageDir := "./public" + os.Getenv("BASE_URL") + "/uploads/banners"
|
|
if _, err := os.Stat(bannerImageDir); os.IsNotExist(err) {
|
|
if err := os.MkdirAll(bannerImageDir, os.ModePerm); err != nil {
|
|
return "", fmt.Errorf("failed to create directory for banner image: %v", err)
|
|
}
|
|
}
|
|
|
|
allowedExtensions := map[string]bool{".jpg": true, ".jpeg": true, ".png": true}
|
|
extension := filepath.Ext(bannerImage.Filename)
|
|
if !allowedExtensions[extension] {
|
|
return "", fmt.Errorf("invalid file type, only .jpg, .jpeg, and .png are allowed")
|
|
}
|
|
|
|
bannerImageFileName := fmt.Sprintf("%s_banner%s", uuid.New().String(), extension)
|
|
bannerImagePath := filepath.Join(bannerImageDir, bannerImageFileName)
|
|
|
|
src, err := bannerImage.Open()
|
|
if err != nil {
|
|
return "", fmt.Errorf("failed to open uploaded file: %v", err)
|
|
}
|
|
defer src.Close()
|
|
|
|
dst, err := os.Create(bannerImagePath)
|
|
if err != nil {
|
|
return "", fmt.Errorf("failed to create banner image file: %v", err)
|
|
}
|
|
defer dst.Close()
|
|
|
|
if _, err := dst.ReadFrom(src); err != nil {
|
|
return "", fmt.Errorf("failed to save banner image: %v", err)
|
|
}
|
|
|
|
return bannerImagePath, nil
|
|
}
|
|
|
|
func (s *bannerService) CreateBanner(request dto.RequestBannerDTO, bannerImage *multipart.FileHeader) (*dto.ResponseBannerDTO, error) {
|
|
|
|
errors, valid := request.ValidateBannerInput()
|
|
if !valid {
|
|
return nil, fmt.Errorf("validation error: %v", errors)
|
|
}
|
|
|
|
bannerImagePath, err := s.saveBannerImage(bannerImage)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to save banner image: %v", err)
|
|
}
|
|
|
|
banner := model.Banner{
|
|
BannerName: request.BannerName,
|
|
BannerImage: bannerImagePath,
|
|
}
|
|
|
|
if err := s.BannerRepo.CreateBanner(&banner); err != nil {
|
|
return nil, fmt.Errorf("failed to create banner: %v", err)
|
|
}
|
|
|
|
createdAt, _ := utils.FormatDateToIndonesianFormat(banner.CreatedAt)
|
|
updatedAt, _ := utils.FormatDateToIndonesianFormat(banner.UpdatedAt)
|
|
|
|
bannerResponseDTO := &dto.ResponseBannerDTO{
|
|
ID: banner.ID,
|
|
BannerName: banner.BannerName,
|
|
BannerImage: banner.BannerImage,
|
|
CreatedAt: createdAt,
|
|
UpdatedAt: updatedAt,
|
|
}
|
|
|
|
articlesCacheKey := "banners:all"
|
|
err = utils.DeleteData(articlesCacheKey)
|
|
if err != nil {
|
|
fmt.Printf("Error deleting cache for all banners: %v\n", err)
|
|
}
|
|
|
|
cacheKey := fmt.Sprintf("banner:%s", banner.ID)
|
|
cacheData := map[string]interface{}{
|
|
"data": bannerResponseDTO,
|
|
}
|
|
if err := utils.SetJSONData(cacheKey, cacheData, time.Hour*24); err != nil {
|
|
fmt.Printf("Error caching banner: %v\n", err)
|
|
}
|
|
|
|
banners, err := s.BannerRepo.FindAllBanners()
|
|
if err == nil {
|
|
var bannersDTO []dto.ResponseBannerDTO
|
|
for _, b := range banners {
|
|
createdAt, _ := utils.FormatDateToIndonesianFormat(b.CreatedAt)
|
|
updatedAt, _ := utils.FormatDateToIndonesianFormat(b.UpdatedAt)
|
|
|
|
bannersDTO = append(bannersDTO, dto.ResponseBannerDTO{
|
|
ID: b.ID,
|
|
BannerName: b.BannerName,
|
|
BannerImage: b.BannerImage,
|
|
CreatedAt: createdAt,
|
|
UpdatedAt: updatedAt,
|
|
})
|
|
}
|
|
|
|
cacheData = map[string]interface{}{
|
|
"data": bannersDTO,
|
|
}
|
|
if err := utils.SetJSONData(articlesCacheKey, cacheData, time.Hour*24); err != nil {
|
|
fmt.Printf("Error caching updated banners to Redis: %v\n", err)
|
|
}
|
|
} else {
|
|
fmt.Printf("Error fetching all banners: %v\n", err)
|
|
}
|
|
|
|
return bannerResponseDTO, nil
|
|
}
|
|
|
|
func (s *bannerService) GetAllBanners() ([]dto.ResponseBannerDTO, error) {
|
|
var banners []dto.ResponseBannerDTO
|
|
|
|
cacheKey := "banners:all"
|
|
cachedData, err := utils.GetJSONData(cacheKey)
|
|
if err == nil && cachedData != nil {
|
|
|
|
if data, ok := cachedData["data"].([]interface{}); ok {
|
|
for _, item := range data {
|
|
if bannerData, ok := item.(map[string]interface{}); ok {
|
|
banners = append(banners, dto.ResponseBannerDTO{
|
|
ID: bannerData["id"].(string),
|
|
BannerName: bannerData["bannername"].(string),
|
|
BannerImage: bannerData["bannerimage"].(string),
|
|
CreatedAt: bannerData["createdAt"].(string),
|
|
UpdatedAt: bannerData["updatedAt"].(string),
|
|
})
|
|
}
|
|
}
|
|
return banners, nil
|
|
}
|
|
}
|
|
|
|
records, err := s.BannerRepo.FindAllBanners()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to fetch banners: %v", err)
|
|
}
|
|
|
|
for _, record := range records {
|
|
createdAt, _ := utils.FormatDateToIndonesianFormat(record.CreatedAt)
|
|
updatedAt, _ := utils.FormatDateToIndonesianFormat(record.UpdatedAt)
|
|
|
|
banners = append(banners, dto.ResponseBannerDTO{
|
|
ID: record.ID,
|
|
BannerName: record.BannerName,
|
|
BannerImage: record.BannerImage,
|
|
CreatedAt: createdAt,
|
|
UpdatedAt: updatedAt,
|
|
})
|
|
}
|
|
|
|
cacheData := map[string]interface{}{
|
|
"data": banners,
|
|
}
|
|
if err := utils.SetJSONData(cacheKey, cacheData, time.Hour*24); err != nil {
|
|
fmt.Printf("Error caching banners: %v\n", err)
|
|
}
|
|
|
|
return banners, nil
|
|
}
|
|
|
|
func (s *bannerService) GetBannerByID(id string) (*dto.ResponseBannerDTO, error) {
|
|
|
|
cacheKey := fmt.Sprintf("banner:%s", id)
|
|
cachedData, err := utils.GetJSONData(cacheKey)
|
|
if err == nil && cachedData != nil {
|
|
if data, ok := cachedData["data"].(map[string]interface{}); ok {
|
|
return &dto.ResponseBannerDTO{
|
|
ID: data["id"].(string),
|
|
BannerName: data["bannername"].(string),
|
|
BannerImage: data["bannerimage"].(string),
|
|
CreatedAt: data["createdAt"].(string),
|
|
UpdatedAt: data["updatedAt"].(string),
|
|
}, nil
|
|
}
|
|
}
|
|
|
|
banner, err := s.BannerRepo.FindBannerByID(id)
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("banner with ID %s not found", id)
|
|
}
|
|
|
|
createdAt, _ := utils.FormatDateToIndonesianFormat(banner.CreatedAt)
|
|
updatedAt, _ := utils.FormatDateToIndonesianFormat(banner.UpdatedAt)
|
|
|
|
bannerResponseDTO := &dto.ResponseBannerDTO{
|
|
ID: banner.ID,
|
|
BannerName: banner.BannerName,
|
|
BannerImage: banner.BannerImage,
|
|
CreatedAt: createdAt,
|
|
UpdatedAt: updatedAt,
|
|
}
|
|
|
|
cacheData := map[string]interface{}{
|
|
"data": bannerResponseDTO,
|
|
}
|
|
if err := utils.SetJSONData(cacheKey, cacheData, time.Hour*24); err != nil {
|
|
fmt.Printf("Error caching banner: %v\n", err)
|
|
}
|
|
|
|
return bannerResponseDTO, nil
|
|
}
|
|
|
|
func (s *bannerService) UpdateBanner(id string, request dto.RequestBannerDTO, bannerImage *multipart.FileHeader) (*dto.ResponseBannerDTO, error) {
|
|
|
|
banner, err := s.BannerRepo.FindBannerByID(id)
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("banner with ID %s not found", id)
|
|
}
|
|
|
|
var oldImagePath string
|
|
if bannerImage != nil {
|
|
|
|
bannerImagePath, err := s.saveBannerImage(bannerImage)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to save banner image: %v", err)
|
|
}
|
|
|
|
oldImagePath = banner.BannerImage
|
|
banner.BannerImage = bannerImagePath
|
|
}
|
|
|
|
banner.BannerName = request.BannerName
|
|
|
|
if err := s.BannerRepo.UpdateBanner(id, banner); err != nil {
|
|
return nil, fmt.Errorf("failed to update banner: %v", err)
|
|
}
|
|
|
|
if oldImagePath != "" {
|
|
err := os.Remove(oldImagePath)
|
|
if err != nil {
|
|
fmt.Printf("Failed to delete old banner image: %v\n", err)
|
|
}
|
|
}
|
|
|
|
createdAt, _ := utils.FormatDateToIndonesianFormat(banner.CreatedAt)
|
|
updatedAt, _ := utils.FormatDateToIndonesianFormat(banner.UpdatedAt)
|
|
|
|
bannerResponseDTO := &dto.ResponseBannerDTO{
|
|
ID: banner.ID,
|
|
BannerName: banner.BannerName,
|
|
BannerImage: banner.BannerImage,
|
|
CreatedAt: createdAt,
|
|
UpdatedAt: updatedAt,
|
|
}
|
|
|
|
cacheKey := fmt.Sprintf("banner:%s", id)
|
|
err = utils.DeleteData(cacheKey)
|
|
if err != nil {
|
|
fmt.Printf("Error deleting cache for banner: %v\n", err)
|
|
}
|
|
|
|
cacheData := map[string]interface{}{
|
|
"data": bannerResponseDTO,
|
|
}
|
|
if err := utils.SetJSONData(cacheKey, cacheData, time.Hour*24); err != nil {
|
|
fmt.Printf("Error caching updated banner: %v\n", err)
|
|
}
|
|
|
|
articlesCacheKey := "banners:all"
|
|
err = utils.DeleteData(articlesCacheKey)
|
|
if err != nil {
|
|
fmt.Printf("Error deleting cache for all banners: %v\n", err)
|
|
}
|
|
|
|
banners, err := s.BannerRepo.FindAllBanners()
|
|
if err == nil {
|
|
var bannersDTO []dto.ResponseBannerDTO
|
|
for _, b := range banners {
|
|
createdAt, _ := utils.FormatDateToIndonesianFormat(b.CreatedAt)
|
|
updatedAt, _ := utils.FormatDateToIndonesianFormat(b.UpdatedAt)
|
|
|
|
bannersDTO = append(bannersDTO, dto.ResponseBannerDTO{
|
|
ID: b.ID,
|
|
BannerName: b.BannerName,
|
|
BannerImage: b.BannerImage,
|
|
CreatedAt: createdAt,
|
|
UpdatedAt: updatedAt,
|
|
})
|
|
}
|
|
|
|
cacheData = map[string]interface{}{
|
|
"data": bannersDTO,
|
|
}
|
|
if err := utils.SetJSONData(articlesCacheKey, cacheData, time.Hour*24); err != nil {
|
|
fmt.Printf("Error caching updated banners to Redis: %v\n", err)
|
|
}
|
|
} else {
|
|
fmt.Printf("Error fetching all banners: %v\n", err)
|
|
}
|
|
|
|
return bannerResponseDTO, nil
|
|
}
|
|
|
|
func (s *bannerService) DeleteBanner(id string) error {
|
|
|
|
banner, err := s.BannerRepo.FindBannerByID(id)
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("banner with ID %s not found", id)
|
|
}
|
|
|
|
if banner.BannerImage != "" {
|
|
err := os.Remove(banner.BannerImage)
|
|
if err != nil {
|
|
|
|
fmt.Printf("Failed to delete banner image: %v\n", err)
|
|
} else {
|
|
fmt.Printf("Successfully deleted banner image: %s\n", banner.BannerImage)
|
|
}
|
|
}
|
|
|
|
if err := s.BannerRepo.DeleteBanner(id); err != nil {
|
|
return fmt.Errorf("failed to delete banner from database: %v", err)
|
|
}
|
|
|
|
cacheKey := fmt.Sprintf("banner:%s", banner.ID)
|
|
err = utils.DeleteData(cacheKey)
|
|
if err != nil {
|
|
fmt.Printf("Error deleting cache for banner: %v\n", err)
|
|
}
|
|
|
|
articlesCacheKey := "banners:all"
|
|
err = utils.DeleteData(articlesCacheKey)
|
|
if err != nil {
|
|
fmt.Printf("Error deleting cache for all banners: %v\n", err)
|
|
}
|
|
|
|
return nil
|
|
}
|