first commit
This commit is contained in:
314
internal/modules/cardmaster/handler.go
Normal file
314
internal/modules/cardmaster/handler.go
Normal file
@@ -0,0 +1,314 @@
|
||||
package cardmaster
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"image"
|
||||
_ "image/gif"
|
||||
_ "image/jpeg"
|
||||
_ "image/png"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"cardverse/internal/modules/seriessetmaster"
|
||||
"cardverse/internal/pkg/response"
|
||||
"cardverse/internal/pkg/utils"
|
||||
"cardverse/internal/pkg/validator"
|
||||
|
||||
"github.com/chai2010/webp"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type Handler struct {
|
||||
service Service
|
||||
seriesSetRepo seriessetmaster.Repository
|
||||
}
|
||||
|
||||
func NewHandler(service Service, seriesSetRepo seriessetmaster.Repository) *Handler {
|
||||
return &Handler{
|
||||
service: service,
|
||||
seriesSetRepo: seriesSetRepo,
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Handler) GetAll(c *gin.Context) {
|
||||
var query ListCardMasterQuery
|
||||
if err := c.ShouldBindQuery(&query); err != nil {
|
||||
response.Error(c, http.StatusBadRequest, "query parameter tidak valid", validator.TranslateError(err))
|
||||
return
|
||||
}
|
||||
|
||||
list, total, err := h.service.GetAllPaginated(query)
|
||||
if err != nil {
|
||||
response.Error(c, http.StatusInternalServerError, "gagal mengambil data kartu", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
pagination := response.NewPagination(query.Page, query.Limit, total)
|
||||
response.SuccessWithPagination(c, http.StatusOK, "berhasil mengambil data kartu", ToCardMasterResponseList(list), pagination)
|
||||
}
|
||||
|
||||
func (h *Handler) GetElements(c *gin.Context) {
|
||||
elements := h.service.GetElements()
|
||||
response.Success(c, http.StatusOK, "berhasil mengambil data elemen", elements)
|
||||
}
|
||||
|
||||
func (h *Handler) GetByID(c *gin.Context) {
|
||||
id, err := parseID(c)
|
||||
if err != nil {
|
||||
response.Error(c, http.StatusBadRequest, "id tidak valid", []validator.FieldError{
|
||||
{Field: "id", Message: "id harus berupa angka"},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
cardData, err := h.service.GetByID(id)
|
||||
if err != nil {
|
||||
response.Error(c, http.StatusNotFound, err.Error(), nil)
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(c, http.StatusOK, "berhasil mengambil data kartu", ToCardMasterResponse(*cardData))
|
||||
}
|
||||
|
||||
func (h *Handler) Create(c *gin.Context) {
|
||||
var req CreateCardMasterRequest
|
||||
|
||||
contentType := c.GetHeader("Content-Type")
|
||||
if strings.HasPrefix(contentType, "multipart/form-data") {
|
||||
if jsonData := c.PostForm("data"); jsonData != "" {
|
||||
if err := json.Unmarshal([]byte(jsonData), &req); err != nil {
|
||||
response.Error(c, http.StatusBadRequest, "format data JSON pada multipart tidak valid", nil)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if err := c.ShouldBind(&req); err != nil {
|
||||
response.Error(c, http.StatusBadRequest, "input tidak valid", validator.TranslateError(err))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
fileHeader, err := c.FormFile("image")
|
||||
if err == nil && fileHeader != nil {
|
||||
if fileHeader.Size > 10*1024*1024 {
|
||||
response.Error(c, http.StatusBadRequest, "ukuran file gambar maksimal 10MB", nil)
|
||||
return
|
||||
}
|
||||
|
||||
if req.IDSet == 0 {
|
||||
response.Error(c, http.StatusBadRequest, "id_set wajib diisi untuk upload gambar", nil)
|
||||
return
|
||||
}
|
||||
|
||||
setInfo, err := h.seriesSetRepo.FindByID(req.IDSet)
|
||||
if err != nil || setInfo == nil {
|
||||
response.Error(c, http.StatusBadRequest, "set dengan id_set tersebut tidak ditemukan", nil)
|
||||
return
|
||||
}
|
||||
|
||||
seriesSlug := utils.Slugify(setInfo.SeriesName)
|
||||
setCode := setInfo.SetCode
|
||||
|
||||
uploadDir := filepath.Join("./public/images", seriesSlug, setCode, "images")
|
||||
if err := os.MkdirAll(uploadDir, os.ModePerm); err != nil {
|
||||
response.Error(c, http.StatusInternalServerError, "gagal membuat direktori gambar kartu", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
srcFile, err := fileHeader.Open()
|
||||
if err != nil {
|
||||
response.Error(c, http.StatusInternalServerError, "gagal membuka file gambar", err.Error())
|
||||
return
|
||||
}
|
||||
defer srcFile.Close()
|
||||
|
||||
img, _, err := image.Decode(srcFile)
|
||||
if err != nil {
|
||||
response.Error(c, http.StatusBadRequest, "file bukan merupakan gambar yang valid", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
filename := formatCardImageFilename(setCode, req.Number)
|
||||
dstPath := filepath.Join(uploadDir, filename)
|
||||
|
||||
out, err := os.Create(dstPath)
|
||||
if err != nil {
|
||||
response.Error(c, http.StatusInternalServerError, "gagal membuat file WebP kartu", err.Error())
|
||||
return
|
||||
}
|
||||
defer out.Close()
|
||||
|
||||
if err := webp.Encode(out, img, &webp.Options{Lossless: false, Quality: 90}); err != nil {
|
||||
response.Error(c, http.StatusInternalServerError, "gagal mengonversi gambar ke WebP", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
req.Image = fmt.Sprintf("/images/%s/%s/images/%s", seriesSlug, setCode, filename)
|
||||
}
|
||||
} else {
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
response.Error(c, http.StatusBadRequest, "input tidak valid", validator.TranslateError(err))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
createdCard, err := h.service.Create(req)
|
||||
if err != nil {
|
||||
response.Error(c, http.StatusBadRequest, err.Error(), nil)
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(c, http.StatusCreated, "kartu berhasil dibuat", ToCardMasterResponse(*createdCard))
|
||||
}
|
||||
|
||||
func (h *Handler) Update(c *gin.Context) {
|
||||
id, err := parseID(c)
|
||||
if err != nil {
|
||||
response.Error(c, http.StatusBadRequest, "id tidak valid", []validator.FieldError{
|
||||
{Field: "id", Message: "id harus berupa angka"},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
var req UpdateCardMasterRequest
|
||||
|
||||
contentType := c.GetHeader("Content-Type")
|
||||
if strings.HasPrefix(contentType, "multipart/form-data") {
|
||||
if jsonData := c.PostForm("data"); jsonData != "" {
|
||||
if err := json.Unmarshal([]byte(jsonData), &req); err != nil {
|
||||
response.Error(c, http.StatusBadRequest, "format data JSON pada multipart tidak valid", nil)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if err := c.ShouldBind(&req); err != nil {
|
||||
response.Error(c, http.StatusBadRequest, "input tidak valid", validator.TranslateError(err))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
fileHeader, err := c.FormFile("image")
|
||||
if err == nil && fileHeader != nil {
|
||||
if fileHeader.Size > 10*1024*1024 {
|
||||
response.Error(c, http.StatusBadRequest, "ukuran file gambar maksimal 10MB", nil)
|
||||
return
|
||||
}
|
||||
|
||||
existingCard, err := h.service.GetByID(id)
|
||||
if err != nil || existingCard == nil {
|
||||
response.Error(c, http.StatusNotFound, "kartu tidak ditemukan", nil)
|
||||
return
|
||||
}
|
||||
|
||||
targetIDSet := req.IDSet
|
||||
if targetIDSet == 0 {
|
||||
targetIDSet = existingCard.IDSet
|
||||
}
|
||||
|
||||
targetNumber := req.Number
|
||||
if targetNumber == "" {
|
||||
targetNumber = existingCard.Number
|
||||
}
|
||||
|
||||
setInfo, err := h.seriesSetRepo.FindByID(targetIDSet)
|
||||
if err != nil || setInfo == nil {
|
||||
response.Error(c, http.StatusBadRequest, "set dengan id_set tersebut tidak ditemukan", nil)
|
||||
return
|
||||
}
|
||||
|
||||
seriesSlug := utils.Slugify(setInfo.SeriesName)
|
||||
setCode := setInfo.SetCode
|
||||
|
||||
uploadDir := filepath.Join("./public/images", seriesSlug, setCode, "images")
|
||||
if err := os.MkdirAll(uploadDir, os.ModePerm); err != nil {
|
||||
response.Error(c, http.StatusInternalServerError, "gagal membuat direktori gambar kartu", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
srcFile, err := fileHeader.Open()
|
||||
if err != nil {
|
||||
response.Error(c, http.StatusInternalServerError, "gagal membuka file gambar", err.Error())
|
||||
return
|
||||
}
|
||||
defer srcFile.Close()
|
||||
|
||||
img, _, err := image.Decode(srcFile)
|
||||
if err != nil {
|
||||
response.Error(c, http.StatusBadRequest, "file bukan merupakan gambar yang valid", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
filename := formatCardImageFilename(setCode, targetNumber)
|
||||
dstPath := filepath.Join(uploadDir, filename)
|
||||
|
||||
out, err := os.Create(dstPath)
|
||||
if err != nil {
|
||||
response.Error(c, http.StatusInternalServerError, "gagal membuat file WebP kartu", err.Error())
|
||||
return
|
||||
}
|
||||
defer out.Close()
|
||||
|
||||
if err := webp.Encode(out, img, &webp.Options{Lossless: false, Quality: 90}); err != nil {
|
||||
response.Error(c, http.StatusInternalServerError, "gagal mengonversi gambar ke WebP", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
req.Image = fmt.Sprintf("/images/%s/%s/images/%s", seriesSlug, setCode, filename)
|
||||
}
|
||||
} else {
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
response.Error(c, http.StatusBadRequest, "input tidak valid", validator.TranslateError(err))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
updatedCard, err := h.service.Update(id, req)
|
||||
if err != nil {
|
||||
response.Error(c, http.StatusNotFound, err.Error(), nil)
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(c, http.StatusOK, "kartu berhasil diupdate", ToCardMasterResponse(*updatedCard))
|
||||
}
|
||||
|
||||
func (h *Handler) Delete(c *gin.Context) {
|
||||
id, err := parseID(c)
|
||||
if err != nil {
|
||||
response.Error(c, http.StatusBadRequest, "id tidak valid", []validator.FieldError{
|
||||
{Field: "id", Message: "id harus berupa angka"},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if err := h.service.Delete(id); err != nil {
|
||||
response.Error(c, http.StatusNotFound, err.Error(), nil)
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(c, http.StatusOK, "kartu berhasil dihapus", nil)
|
||||
}
|
||||
|
||||
func parseID(c *gin.Context) (uint, error) {
|
||||
idParam := c.Param("id")
|
||||
id, err := strconv.ParseUint(idParam, 10, 64)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return uint(id), nil
|
||||
}
|
||||
|
||||
func formatCardImageFilename(setCode, number string) string {
|
||||
cleanNum := strings.TrimSpace(number)
|
||||
if cleanNum != "" {
|
||||
cleanNum = strings.ReplaceAll(cleanNum, "/", "_")
|
||||
cleanNum = strings.ReplaceAll(cleanNum, "\\", "_")
|
||||
if !strings.HasSuffix(strings.ToLower(cleanNum), ".webp") {
|
||||
cleanNum = cleanNum + ".webp"
|
||||
}
|
||||
return cleanNum
|
||||
}
|
||||
return fmt.Sprintf("%s-1_%d.webp", setCode, time.Now().UnixNano())
|
||||
}
|
||||
Reference in New Issue
Block a user