fix:fixing image upload

This commit is contained in:
pahmiudahgede 2025-05-17 22:30:30 +07:00
parent 3f911ae321
commit 043a2fe78e
2 changed files with 94 additions and 77 deletions

View File

@ -3,6 +3,7 @@ package services
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"log"
"mime/multipart" "mime/multipart"
"os" "os"
"path/filepath" "path/filepath"
@ -32,41 +33,77 @@ func NewArticleService(articleRepo repositories.ArticleRepository) ArticleServic
return &articleService{ArticleRepo: articleRepo} return &articleService{ArticleRepo: articleRepo}
} }
func (s *articleService) CreateArticle(request dto.RequestArticleDTO, coverImage *multipart.FileHeader) (*dto.ArticleResponseDTO, error) { func (s *articleService) saveCoverArticle(coverArticle *multipart.FileHeader) (string, error) {
pathImage := "/uploads/articles/"
coverArticleDir := "./public" + os.Getenv("BASE_URL") + pathImage
if _, err := os.Stat(coverArticleDir); os.IsNotExist(err) {
coverImageDir := "./public" + os.Getenv("BASE_URL") + "/uploads/articles" if err := os.MkdirAll(coverArticleDir, os.ModePerm); err != nil {
if err := os.MkdirAll(coverImageDir, os.ModePerm); err != nil { return "", fmt.Errorf("failed to create directory for cover article: %v", err)
return nil, fmt.Errorf("failed to create directory for cover image: %v", err) }
} }
allowedExtensions := map[string]bool{".jpg": true, ".jpeg": true, ".png": true} allowedExtensions := map[string]bool{".jpg": true, ".jpeg": true, ".png": true, ".svg": true}
extension := filepath.Ext(coverImage.Filename) extension := filepath.Ext(coverArticle.Filename)
if !allowedExtensions[extension] { if !allowedExtensions[extension] {
return nil, fmt.Errorf("invalid file type, only .jpg, .jpeg, and .png are allowed") return "", fmt.Errorf("invalid file type, only .jpg, .jpeg, and .png are allowed")
} }
coverImageFileName := fmt.Sprintf("%s_cover%s", uuid.New().String(), extension) coverArticleFileName := fmt.Sprintf("%s_coverarticle%s", uuid.New().String(), extension)
coverImagePath := filepath.Join(coverImageDir, coverImageFileName) coverArticlePath := filepath.Join(coverArticleDir, coverArticleFileName)
src, err := coverImage.Open() src, err := coverArticle.Open()
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to open uploaded file: %v", err) return "", fmt.Errorf("failed to open uploaded file: %v", err)
} }
defer src.Close() defer src.Close()
dst, err := os.Create(coverImagePath) dst, err := os.Create(coverArticlePath)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to create cover image file: %v", err) return "", fmt.Errorf("failed to create cover article file: %v", err)
} }
defer dst.Close() defer dst.Close()
if _, err := dst.ReadFrom(src); err != nil { if _, err := dst.ReadFrom(src); err != nil {
return nil, fmt.Errorf("failed to save cover image: %v", err) return "", fmt.Errorf("failed to save cover article: %v", err)
}
iconTrashUrl := fmt.Sprintf("%s%s", pathImage, coverArticleFileName)
return iconTrashUrl, nil
}
func deleteCoverArticle(imagePath string) error {
if imagePath == "" {
return nil
}
baseDir := "./public/" + os.Getenv("BASE_URL")
absolutePath := baseDir + imagePath
if _, err := os.Stat(absolutePath); os.IsNotExist(err) {
return fmt.Errorf("image file not found: %v", err)
}
err := os.Remove(absolutePath)
if err != nil {
return fmt.Errorf("failed to delete image: %v", err)
}
log.Printf("Image deleted successfully: %s", absolutePath)
return nil
}
func (s *articleService) CreateArticle(request dto.RequestArticleDTO, coverImage *multipart.FileHeader) (*dto.ArticleResponseDTO, error) {
coverArticlePath, err := s.saveCoverArticle(coverImage)
if err != nil {
return nil, fmt.Errorf("gagal menyimpan ikon sampah: %v", err)
} }
article := model.Article{ article := model.Article{
Title: request.Title, Title: request.Title,
CoverImage: coverImagePath, CoverImage: coverArticlePath,
Author: request.Author, Author: request.Author,
Heading: request.Heading, Heading: request.Heading,
Content: request.Content, Content: request.Content,
@ -254,21 +291,30 @@ func (s *articleService) UpdateArticle(id string, request dto.RequestArticleDTO,
return nil, fmt.Errorf("article not found: %v", id) return nil, fmt.Errorf("article not found: %v", id)
} }
if article.CoverImage != "" {
err := deleteCoverArticle(article.CoverImage)
if err != nil {
return nil, fmt.Errorf("failed to delete old image: %v", err)
}
}
var coverArticlePath string
if coverImage != nil {
coverArticlePath, err = s.saveCoverArticle(coverImage)
if err != nil {
return nil, fmt.Errorf("failed to save card photo: %v", err)
}
}
if coverArticlePath != "" {
article.CoverImage = coverArticlePath
}
article.Title = request.Title article.Title = request.Title
article.Heading = request.Heading article.Heading = request.Heading
article.Content = request.Content article.Content = request.Content
article.Author = request.Author article.Author = request.Author
var coverImagePath string
if coverImage != nil {
coverImagePath, err = s.saveCoverImage(coverImage, article.CoverImage)
if err != nil {
return nil, fmt.Errorf("failed to save cover image: %v", err)
}
article.CoverImage = coverImagePath
}
err = s.ArticleRepo.UpdateArticle(id, article) err = s.ArticleRepo.UpdateArticle(id, article)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to update article: %v", err) return nil, fmt.Errorf("failed to update article: %v", err)
@ -338,64 +384,14 @@ func (s *articleService) UpdateArticle(id string, request dto.RequestArticleDTO,
return articleResponseDTO, nil return articleResponseDTO, nil
} }
func (s *articleService) saveCoverImage(coverImage *multipart.FileHeader, oldImagePath string) (string, error) {
coverImageDir := "/uploads/articles"
if _, err := os.Stat(coverImageDir); os.IsNotExist(err) {
if err := os.MkdirAll(coverImageDir, os.ModePerm); err != nil {
return "", fmt.Errorf("failed to create directory for cover image: %v", err)
}
}
extension := filepath.Ext(coverImage.Filename)
if extension != ".jpg" && extension != ".jpeg" && extension != ".png" {
return "", 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)
if oldImagePath != "" {
err := os.Remove(oldImagePath)
if err != nil {
fmt.Printf("Failed to delete old cover image: %v\n", err)
} else {
fmt.Printf("Successfully deleted old cover image: %s\n", oldImagePath)
}
}
src, err := coverImage.Open()
if err != nil {
return "", fmt.Errorf("failed to open uploaded file: %v", err)
}
defer src.Close()
dst, err := os.Create(coverImagePath)
if err != nil {
return "", fmt.Errorf("failed to create cover image file: %v", err)
}
defer dst.Close()
_, err = dst.ReadFrom(src)
if err != nil {
return "", fmt.Errorf("failed to save cover image: %v", err)
}
return coverImagePath, nil
}
func (s *articleService) DeleteArticle(id string) error { func (s *articleService) DeleteArticle(id string) error {
article, err := s.ArticleRepo.FindArticleByID(id) article, err := s.ArticleRepo.FindArticleByID(id)
if err != nil { if err != nil {
return fmt.Errorf("failed to find article: %v", id) return fmt.Errorf("failed to find article: %v", id)
} }
if article.CoverImage != "" { if err := deleteCoverArticle(article.CoverImage); err != nil {
err := os.Remove(article.CoverImage) return fmt.Errorf("error waktu menghapus cover image article %s: %v", id, err)
if err != nil {
fmt.Printf("Failed to delete cover image: %v\n", err)
} else {
fmt.Printf("Successfully deleted cover image: %s\n", article.CoverImage)
}
} }
err = s.ArticleRepo.DeleteArticle(id) err = s.ArticleRepo.DeleteArticle(id)

21
model/trashcart_model.go Normal file
View File

@ -0,0 +1,21 @@
package model
import "time"
type Cart struct {
ID string `gorm:"primaryKey;type:uuid;default:uuid_generate_v4()" json:"id"`
UserId string `gorm:"not null" json:"userid"`
User User `gorm:"foreignKey:UserId;constraint:OnDelete:CASCADE;" json:"user"`
CartItem []CartItems `gorm:"foreignKey:CategoryID;constraint:OnDelete:CASCADE;" json:"cartitems"`
TotalAmount float32 `json:"totalamount"`
EstimatedTotalPrice float32 `json:"estimated_totalprice"`
}
type CartItems struct {
ID string `gorm:"primaryKey;type:uuid;default:uuid_generate_v4()" json:"id"`
TrashId string `json:"trashid"`
TrashCategory TrashCategory `gorm:"foreignKey:TrashId;constraint:OnDelete:CASCADE;" json:"trash"`
Amount float32 `json:"amount"`
CreaatedAt time.Time `gorm:"default:current_timestamp" json:"createdAt"`
UpdatedAt time.Time `gorm:"default:current_timestamp" json:"updatedAt"`
}