fix: update product, banners, gallery_files, product spec, promotions

This commit is contained in:
hanif salafi 2025-11-17 22:44:55 +07:00
parent d6aa8b6c2c
commit 1bef2a45e5
21 changed files with 63 additions and 53 deletions

View File

@ -8,7 +8,7 @@ type Products struct {
ID uint `json:"id" gorm:"primaryKey;type:int4;autoIncrement"`
Title string `json:"title" gorm:"type:varchar"`
Variant *string `json:"variant" gorm:"type:varchar"`
Price *float64 `json:"price" gorm:"type:decimal(10,2)"`
Price *string `json:"price" gorm:"type:varchar"`
ThumbnailPath *string `json:"thumbnail_path" gorm:"type:varchar"`
Colors *string `json:"colors" gorm:"type:text"` // JSON array stored as text
IsActive *bool `json:"is_active" gorm:"type:bool;default:true"`

View File

@ -240,7 +240,7 @@ func (_i *bannersController) Delete(c *fiber.Ctx) error {
// @Tags Banners
// @Security Bearer
// @Param X-Client-Key header string true "Insert the X-Client-Key"
// @Param filename path string true "Banner File Path"
// @Param filename path string true "Banner File Name (e.g., user_277788.png)"
// @Success 200 {file} file
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError

View File

@ -3,6 +3,7 @@ package mapper
import (
"jaecoo-be/app/database/entity"
res "jaecoo-be/app/module/banners/response"
"path/filepath"
)
func BannersResponseMapper(banner *entity.Banners, host string) *res.BannersResponse {
@ -23,10 +24,11 @@ func BannersResponseMapper(banner *entity.Banners, host string) *res.BannersResp
}
if banner.ThumbnailPath != nil && *banner.ThumbnailPath != "" {
thumbnailUrl := host + "/banners/thumbnail/viewer/" + *banner.ThumbnailPath
// Extract filename from path
filename := filepath.Base(*banner.ThumbnailPath)
thumbnailUrl := host + "/banners/viewer/" + filename
response.ThumbnailUrl = &thumbnailUrl
}
return response
}

View File

@ -195,7 +195,7 @@ func (_i *bannersService) Delete(id uint) (err error) {
func (_i *bannersService) Viewer(c *fiber.Ctx) (err error) {
filename := c.Params("filename")
// Find banner by thumbnail path
// Find banner by filename (repository will search using LIKE pattern)
result, err := _i.Repo.FindByThumbnailPath(filename)
if err != nil {
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{

View File

@ -230,7 +230,7 @@ func (_i *galleryFilesController) Delete(c *fiber.Ctx) error {
// @Tags GalleryFiles
// @Security Bearer
// @Param X-Client-Key header string true "Insert the X-Client-Key"
// @Param filename path string true "Gallery File Path"
// @Param filename path string true "Gallery File Name (e.g., user_277788.png)"
// @Success 200 {file} file
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError

View File

@ -3,6 +3,7 @@ package mapper
import (
"jaecoo-be/app/database/entity"
res "jaecoo-be/app/module/gallery_files/response"
"path/filepath"
)
func GalleryFilesResponseMapper(file *entity.GalleryFiles, host string) *res.GalleryFilesResponse {
@ -21,7 +22,9 @@ func GalleryFilesResponseMapper(file *entity.GalleryFiles, host string) *res.Gal
}
if file.ImagePath != nil && *file.ImagePath != "" {
imageUrl := host + "/gallery-files/image/viewer/" + *file.ImagePath
// Extract filename from path
filename := filepath.Base(*file.ImagePath)
imageUrl := host + "/gallery-files/viewer/" + filename
response.ImageUrl = &imageUrl
}

View File

@ -195,7 +195,7 @@ func (_i *galleryFilesService) Delete(id uint) (err error) {
func (_i *galleryFilesService) Viewer(c *fiber.Ctx) (err error) {
filename := c.Params("filename")
// Find gallery file by image path
// Find gallery file by filename (repository will search using LIKE pattern)
result, err := _i.Repo.FindByImagePath(filename)
if err != nil {
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{

View File

@ -235,7 +235,7 @@ func (_i *productSpecificationsController) Delete(c *fiber.Ctx) error {
// @Tags ProductSpecifications
// @Security Bearer
// @Param X-Client-Key header string true "Insert the X-Client-Key"
// @Param filename path string true "Product Specification File Path"
// @Param filename path string true "Product Specification File Name (e.g., user_277788.png)"
// @Success 200 {file} file
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError

View File

@ -3,6 +3,7 @@ package mapper
import (
"jaecoo-be/app/database/entity"
res "jaecoo-be/app/module/product_specifications/response"
"path/filepath"
)
func ProductSpecificationsResponseMapper(spec *entity.ProductSpecifications, host string) *res.ProductSpecificationsResponse {
@ -21,7 +22,9 @@ func ProductSpecificationsResponseMapper(spec *entity.ProductSpecifications, hos
}
if spec.ThumbnailPath != nil && *spec.ThumbnailPath != "" {
thumbnailUrl := host + "/product-specifications/thumbnail/viewer/" + *spec.ThumbnailPath
// Extract filename from path
filename := filepath.Base(*spec.ThumbnailPath)
thumbnailUrl := host + "/product-specifications/viewer/" + filename
response.ThumbnailUrl = &thumbnailUrl
}

View File

@ -195,7 +195,7 @@ func (_i *productSpecificationsService) Delete(id uint) (err error) {
func (_i *productSpecificationsService) Viewer(c *fiber.Ctx) (err error) {
filename := c.Params("filename")
// Find product specification by thumbnail path
// Find product specification by filename (repository will search using LIKE pattern)
result, err := _i.Repo.FindByThumbnailPath(filename)
if err != nil {
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{

View File

@ -110,7 +110,7 @@ func (_i *productsController) Show(c *fiber.Ctx) error {
// @Param file formData file false "Upload file"
// @Param title formData string true "Product title"
// @Param variant formData string false "Product variant"
// @Param price formData number false "Product price"
// @Param price formData string false "Product price"
// @Param colors formData string false "Product colors (JSON array)"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
@ -136,10 +136,8 @@ func (_i *productsController) Save(c *fiber.Ctx) error {
req.Variant = &variant
}
if priceStr := c.FormValue("price"); priceStr != "" {
if price, err := strconv.ParseFloat(priceStr, 64); err == nil {
req.Price = &price
}
if price := c.FormValue("price"); price != "" {
req.Price = &price
}
// Handle colors (JSON array string)
@ -246,7 +244,7 @@ func (_i *productsController) Delete(c *fiber.Ctx) error {
// @Tags Products
// @Security Bearer
// @Param X-Client-Key header string true "Insert the X-Client-Key"
// @Param filename path string true "Product File Path"
// @Param filename path string true "Product File Name (e.g., user_277788.png)"
// @Success 200 {file} file
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
@ -255,4 +253,3 @@ func (_i *productsController) Delete(c *fiber.Ctx) error {
func (_i *productsController) Viewer(c *fiber.Ctx) error {
return _i.productsService.Viewer(c)
}

View File

@ -4,6 +4,7 @@ import (
"encoding/json"
"jaecoo-be/app/database/entity"
res "jaecoo-be/app/module/products/response"
"path/filepath"
)
func ProductsResponseMapper(product *entity.Products, host string) *res.ProductsResponse {
@ -29,7 +30,9 @@ func ProductsResponseMapper(product *entity.Products, host string) *res.Products
}
if product.ThumbnailPath != nil && *product.ThumbnailPath != "" {
thumbnailUrl := host + "/products/thumbnail/viewer/" + *product.ThumbnailPath
// Extract filename from path
filename := filepath.Base(*product.ThumbnailPath)
thumbnailUrl := host + "/products/viewer/" + filename
response.ThumbnailUrl = &thumbnailUrl
}

View File

@ -33,7 +33,7 @@ func (req ProductsQueryRequestContext) ToParamRequest() ProductsQueryRequest {
type ProductsCreateRequest struct {
Title string `json:"title" validate:"required"`
Variant *string `json:"variant"`
Price *float64 `json:"price"`
Price *string `json:"price"`
ThumbnailPath *string `json:"thumbnail_path"`
Colors []string `json:"colors"`
}
@ -55,12 +55,12 @@ func (req ProductsCreateRequest) ToEntity() *entity.Products {
}
type ProductsUpdateRequest struct {
Title *string `json:"title"`
Variant *string `json:"variant"`
Price *float64 `json:"price"`
ThumbnailPath *string `json:"thumbnail_path"`
Colors []string `json:"colors"`
IsActive *bool `json:"is_active"`
Title *string `json:"title"`
Variant *string `json:"variant"`
Price *string `json:"price"`
ThumbnailPath *string `json:"thumbnail_path"`
Colors []string `json:"colors"`
IsActive *bool `json:"is_active"`
}
func (req ProductsUpdateRequest) ToEntity() *entity.Products {
@ -86,4 +86,3 @@ func getStringValue(s *string) string {
}
return *s
}

View File

@ -8,7 +8,7 @@ type ProductsResponse struct {
ID uint `json:"id"`
Title string `json:"title"`
Variant *string `json:"variant"`
Price *float64 `json:"price"`
Price *string `json:"price"`
ThumbnailPath *string `json:"thumbnail_path"`
ThumbnailUrl *string `json:"thumbnail_url"`
Colors []string `json:"colors"`

View File

@ -195,7 +195,7 @@ func (_i *productsService) Delete(id uint) (err error) {
func (_i *productsService) Viewer(c *fiber.Ctx) (err error) {
filename := c.Params("filename")
// Find product by thumbnail path
// Find product by filename (repository will search using LIKE pattern)
result, err := _i.Repo.FindByThumbnailPath(filename)
if err != nil {
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{

View File

@ -228,7 +228,7 @@ func (_i *promotionsController) Delete(c *fiber.Ctx) error {
// @Tags Promotions
// @Security Bearer
// @Param X-Client-Key header string true "Insert the X-Client-Key"
// @Param filename path string true "Promotion File Path"
// @Param filename path string true "Promotion File Name (e.g., user_277788.png)"
// @Success 200 {file} file
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError

View File

@ -3,6 +3,7 @@ package mapper
import (
"jaecoo-be/app/database/entity"
res "jaecoo-be/app/module/promotions/response"
"path/filepath"
)
func PromotionsResponseMapper(promotion *entity.Promotions, host string) *res.PromotionsResponse {
@ -21,7 +22,9 @@ func PromotionsResponseMapper(promotion *entity.Promotions, host string) *res.Pr
}
if promotion.ThumbnailPath != nil && *promotion.ThumbnailPath != "" {
thumbnailUrl := host + "/promotions/thumbnail/viewer/" + *promotion.ThumbnailPath
// Extract filename from path
filename := filepath.Base(*promotion.ThumbnailPath)
thumbnailUrl := host + "/promotions/viewer/" + filename
response.ThumbnailUrl = &thumbnailUrl
}

View File

@ -195,7 +195,7 @@ func (_i *promotionsService) Delete(id uint) (err error) {
func (_i *promotionsService) Viewer(c *fiber.Ctx) (err error) {
filename := c.Params("filename")
// Find promotion by thumbnail path
// Find promotion by filename (repository will search using LIKE pattern)
result, err := _i.Repo.FindByThumbnailPath(filename)
if err != nil {
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{

View File

@ -3426,7 +3426,7 @@ const docTemplate = `{
},
{
"type": "string",
"description": "Banner File Path",
"description": "Banner File Name (e.g., user_277788.png)",
"name": "filename",
"in": "path",
"required": true
@ -5440,7 +5440,7 @@ const docTemplate = `{
},
{
"type": "string",
"description": "Gallery File Path",
"description": "Gallery File Name (e.g., user_277788.png)",
"name": "filename",
"in": "path",
"required": true
@ -5835,7 +5835,7 @@ const docTemplate = `{
},
{
"type": "string",
"description": "Product Specification File Path",
"description": "Product Specification File Name (e.g., user_277788.png)",
"name": "filename",
"in": "path",
"required": true
@ -6179,7 +6179,7 @@ const docTemplate = `{
"in": "formData"
},
{
"type": "number",
"type": "string",
"description": "Product price",
"name": "price",
"in": "formData"
@ -6241,7 +6241,7 @@ const docTemplate = `{
},
{
"type": "string",
"description": "Product File Path",
"description": "Product File Name (e.g., user_277788.png)",
"name": "filename",
"in": "path",
"required": true
@ -6630,7 +6630,7 @@ const docTemplate = `{
},
{
"type": "string",
"description": "Promotion File Path",
"description": "Promotion File Name (e.g., user_277788.png)",
"name": "filename",
"in": "path",
"required": true
@ -10406,7 +10406,7 @@ const docTemplate = `{
"type": "boolean"
},
"price": {
"type": "number"
"type": "string"
},
"thumbnail_path": {
"type": "string"

View File

@ -3415,7 +3415,7 @@
},
{
"type": "string",
"description": "Banner File Path",
"description": "Banner File Name (e.g., user_277788.png)",
"name": "filename",
"in": "path",
"required": true
@ -5429,7 +5429,7 @@
},
{
"type": "string",
"description": "Gallery File Path",
"description": "Gallery File Name (e.g., user_277788.png)",
"name": "filename",
"in": "path",
"required": true
@ -5824,7 +5824,7 @@
},
{
"type": "string",
"description": "Product Specification File Path",
"description": "Product Specification File Name (e.g., user_277788.png)",
"name": "filename",
"in": "path",
"required": true
@ -6168,7 +6168,7 @@
"in": "formData"
},
{
"type": "number",
"type": "string",
"description": "Product price",
"name": "price",
"in": "formData"
@ -6230,7 +6230,7 @@
},
{
"type": "string",
"description": "Product File Path",
"description": "Product File Name (e.g., user_277788.png)",
"name": "filename",
"in": "path",
"required": true
@ -6619,7 +6619,7 @@
},
{
"type": "string",
"description": "Promotion File Path",
"description": "Promotion File Name (e.g., user_277788.png)",
"name": "filename",
"in": "path",
"required": true
@ -10395,7 +10395,7 @@
"type": "boolean"
},
"price": {
"type": "number"
"type": "string"
},
"thumbnail_path": {
"type": "string"

View File

@ -436,7 +436,7 @@ definitions:
is_active:
type: boolean
price:
type: number
type: string
thumbnail_path:
type: string
title:
@ -3133,7 +3133,7 @@ paths:
name: X-Client-Key
required: true
type: string
- description: Banner File Path
- description: Banner File Name (e.g., user_277788.png)
in: path
name: filename
required: true
@ -4415,7 +4415,7 @@ paths:
name: X-Client-Key
required: true
type: string
- description: Gallery File Path
- description: Gallery File Name (e.g., user_277788.png)
in: path
name: filename
required: true
@ -4668,7 +4668,7 @@ paths:
name: X-Client-Key
required: true
type: string
- description: Product Specification File Path
- description: Product Specification File Name (e.g., user_277788.png)
in: path
name: filename
required: true
@ -4780,7 +4780,7 @@ paths:
- description: Product price
in: formData
name: price
type: number
type: string
- description: Product colors (JSON array)
in: formData
name: colors
@ -4928,7 +4928,7 @@ paths:
name: X-Client-Key
required: true
type: string
- description: Product File Path
- description: Product File Name (e.g., user_277788.png)
in: path
name: filename
required: true
@ -5177,7 +5177,7 @@ paths:
name: X-Client-Key
required: true
type: string
- description: Promotion File Path
- description: Promotion File Name (e.g., user_277788.png)
in: path
name: filename
required: true