feat: update new modules

This commit is contained in:
hanif salafi 2025-11-16 00:43:23 +07:00
parent b3c5a0228f
commit 3c4465f900
70 changed files with 11107 additions and 14 deletions

View File

@ -2,24 +2,16 @@ stages:
- build-image
- deploy
#build-1:
# stage: build-app
# image: golang:alpine
# script:
# - go build -o main .
# artifacts:
# paths:
# - main
build-2:
build:
stage: build-image
image: docker/compose:latest
image:
name: docker:25.0.3-cli
services:
- name: docker:dind
- name: docker:25.0.3-dind
command: [ "--insecure-registry=103.82.242.92:8900" ]
script:
- docker login -u $DEPLOY_USERNAME -p $DEPLOY_TOKEN 103.82.242.92:8900
- docker-compose build
- docker compose build
- docker tag registry.gitlab.com/hanifsalafi/jaecoo-be:dev 103.82.242.92:8900/medols/jaecoo-be:dev
- docker push 103.82.242.92:8900/medols/jaecoo-be:dev
@ -30,4 +22,4 @@ deploy:
services:
- docker:dind
script:
- curl --user $JENKINS_USER:$JENKINS_PWD http://38.47.180.165:8080/job/autodeploy-campaignpool-be/build?token=autodeploycampaignpool
- curl --user $JENKINS_USER:$JENKINS_PWD http://38.47.180.165:8080/job/autodeploy-jaecoo-be/build?token=autodeployjaecoo

View File

@ -0,0 +1,18 @@
package entity
import (
"time"
)
type Banners struct {
ID uint `json:"id" gorm:"primaryKey;type:int4;autoIncrement"`
Title string `json:"title" gorm:"type:varchar"`
Description *string `json:"description" gorm:"type:text"`
ThumbnailPath *string `json:"thumbnail_path" gorm:"type:varchar"`
Position *string `json:"position" gorm:"type:varchar"`
Status *string `json:"status" gorm:"type:varchar"`
IsActive *bool `json:"is_active" gorm:"type:bool;default:true"`
CreatedAt time.Time `json:"created_at" gorm:"default:now()"`
UpdatedAt time.Time `json:"updated_at" gorm:"default:now()"`
}

View File

@ -0,0 +1,16 @@
package entity
import (
"time"
)
type Galleries struct {
ID uint `json:"id" gorm:"primaryKey;type:int4;autoIncrement"`
Title string `json:"title" gorm:"type:varchar"`
Description *string `json:"description" gorm:"type:text"`
ThumbnailPath *string `json:"thumbnail_path" gorm:"type:varchar"`
IsActive *bool `json:"is_active" gorm:"type:bool;default:true"`
CreatedAt time.Time `json:"created_at" gorm:"default:now()"`
UpdatedAt time.Time `json:"updated_at" gorm:"default:now()"`
}

View File

@ -0,0 +1,16 @@
package entity
import (
"time"
)
type GalleryFiles struct {
ID uint `json:"id" gorm:"primaryKey;type:int4;autoIncrement"`
GalleryID uint `json:"gallery_id" gorm:"type:int4"`
Title *string `json:"title" gorm:"type:varchar"`
ImagePath *string `json:"image_path" gorm:"type:varchar"`
IsActive *bool `json:"is_active" gorm:"type:bool;default:true"`
CreatedAt time.Time `json:"created_at" gorm:"default:now()"`
UpdatedAt time.Time `json:"updated_at" gorm:"default:now()"`
}

View File

@ -0,0 +1,16 @@
package entity
import (
"time"
)
type ProductSpecifications struct {
ID uint `json:"id" gorm:"primaryKey;type:int4;autoIncrement"`
ProductID uint `json:"product_id" gorm:"type:int4"`
Title string `json:"title" gorm:"type:varchar"`
ThumbnailPath *string `json:"thumbnail_path" gorm:"type:varchar"`
IsActive *bool `json:"is_active" gorm:"type:bool;default:true"`
CreatedAt time.Time `json:"created_at" gorm:"default:now()"`
UpdatedAt time.Time `json:"updated_at" gorm:"default:now()"`
}

View File

@ -0,0 +1,18 @@
package entity
import (
"time"
)
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)"`
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"`
CreatedAt time.Time `json:"created_at" gorm:"default:now()"`
UpdatedAt time.Time `json:"updated_at" gorm:"default:now()"`
}

View File

@ -0,0 +1,15 @@
package entity
import (
"time"
)
type Promotions struct {
ID uint `json:"id" gorm:"primaryKey;type:int4;autoIncrement"`
Title string `json:"title" gorm:"type:varchar"`
Description *string `json:"description" gorm:"type:text"`
ThumbnailPath *string `json:"thumbnail_path" gorm:"type:varchar"`
IsActive *bool `json:"is_active" gorm:"type:bool;default:true"`
CreatedAt time.Time `json:"created_at" gorm:"default:now()"`
UpdatedAt time.Time `json:"updated_at" gorm:"default:now()"`
}

View File

@ -0,0 +1,17 @@
package entity
import (
"time"
)
type SalesAgents struct {
ID uint `json:"id" gorm:"primaryKey;type:int4;autoIncrement"`
Name string `json:"name" gorm:"type:varchar"`
JobTitle *string `json:"job_title" gorm:"type:varchar"`
Phone *string `json:"phone" gorm:"type:varchar"`
AgentType *string `json:"agent_type" gorm:"type:text"` // JSON array stored as text
ProfilePicturePath *string `json:"profile_picture_path" gorm:"type:varchar"`
IsActive *bool `json:"is_active" gorm:"type:bool;default:true"`
CreatedAt time.Time `json:"created_at" gorm:"default:now()"`
UpdatedAt time.Time `json:"updated_at" gorm:"default:now()"`
}

View File

@ -94,15 +94,22 @@ func Models() []interface{} {
entity.ArticleFiles{},
entity.ArticleComments{},
entity.AuditTrails{},
entity.Banners{},
entity.Cities{},
entity.CsrfTokenRecords{},
entity.CustomStaticPages{},
entity.Districts{},
entity.Feedbacks{},
entity.ForgotPasswords{},
entity.Galleries{},
entity.GalleryFiles{},
entity.MasterApprovalStatuses{},
entity.ProductSpecifications{},
entity.Products{},
entity.Promotions{},
entity.Provinces{},
entity.OneTimePasswords{},
entity.SalesAgents{},
user_levels.UserLevels{},
entity.UserRoles{},
entity.UserRoleAccesses{},

View File

@ -0,0 +1,55 @@
package banners
import (
"jaecoo-be/app/module/banners/controller"
"jaecoo-be/app/module/banners/repository"
"jaecoo-be/app/module/banners/service"
"github.com/gofiber/fiber/v2"
"go.uber.org/fx"
)
// BannersRouter struct of BannersRouter
type BannersRouter struct {
App fiber.Router
Controller *controller.Controller
}
// NewBannersModule register bulky of Banners module
var NewBannersModule = fx.Options(
// register repository of Banners module
fx.Provide(repository.NewBannersRepository),
// register service of Banners module
fx.Provide(service.NewBannersService),
// register controller of Banners module
fx.Provide(controller.NewController),
// register router of Banners module
fx.Provide(NewBannersRouter),
)
// NewBannersRouter init BannersRouter
func NewBannersRouter(fiber *fiber.App, controller *controller.Controller) *BannersRouter {
return &BannersRouter{
App: fiber,
Controller: controller,
}
}
// RegisterBannersRoutes register routes of Banners module
func (_i *BannersRouter) RegisterBannersRoutes() {
// define controllers
bannersController := _i.Controller.Banners
// define routes
_i.App.Route("/banners", func(router fiber.Router) {
router.Get("/", bannersController.All)
router.Get("/:id", bannersController.Show)
router.Post("/", bannersController.Save)
router.Put("/:id", bannersController.Update)
router.Delete("/:id", bannersController.Delete)
})
}

View File

@ -0,0 +1,196 @@
package controller
import (
"jaecoo-be/app/module/banners/request"
"jaecoo-be/app/module/banners/service"
"jaecoo-be/utils/paginator"
"strconv"
"github.com/gofiber/fiber/v2"
utilRes "jaecoo-be/utils/response"
utilVal "jaecoo-be/utils/validator"
)
type bannersController struct {
bannersService service.BannersService
}
type BannersController interface {
All(c *fiber.Ctx) error
Show(c *fiber.Ctx) error
Save(c *fiber.Ctx) error
Update(c *fiber.Ctx) error
Delete(c *fiber.Ctx) error
}
func NewBannersController(bannersService service.BannersService) BannersController {
return &bannersController{
bannersService: bannersService,
}
}
// All Banners
// @Summary Get all Banners
// @Description API for getting all Banners
// @Tags Banners
// @Security Bearer
// @Param X-Client-Key header string true "Insert the X-Client-Key"
// @Param req query request.BannersQueryRequestContext false "query parameters"
// @Param req query paginator.Pagination false "pagination parameters"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
// @Failure 500 {object} response.InternalServerError
// @Router /banners [get]
func (_i *bannersController) All(c *fiber.Ctx) error {
paginate, err := paginator.Paginate(c)
if err != nil {
return err
}
reqContext := request.BannersQueryRequestContext{
Title: c.Query("title"),
Position: c.Query("position"),
Status: c.Query("status"),
}
req := reqContext.ToParamRequest()
req.Pagination = paginate
bannersData, paging, err := _i.bannersService.GetAll(req)
if err != nil {
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Banners list successfully retrieved"},
Data: bannersData,
Meta: paging,
})
}
// Show Banner
// @Summary Get Banner by ID
// @Description API for getting Banner by ID
// @Tags Banners
// @Security Bearer
// @Param X-Client-Key header string true "Insert the X-Client-Key"
// @Param id path int true "Banner ID"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
// @Failure 500 {object} response.InternalServerError
// @Router /banners/{id} [get]
func (_i *bannersController) Show(c *fiber.Ctx) error {
id, err := strconv.ParseUint(c.Params("id"), 10, 0)
if err != nil {
return err
}
bannerData, err := _i.bannersService.GetOne(uint(id))
if err != nil {
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Banner successfully retrieved"},
Data: bannerData,
})
}
// Save Banner
// @Summary Create Banner
// @Description API for creating Banner
// @Tags Banners
// @Security Bearer
// @Param X-Client-Key header string true "Insert the X-Client-Key"
// @Param payload body request.BannersCreateRequest true "Required payload"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
// @Failure 500 {object} response.InternalServerError
// @Router /banners [post]
func (_i *bannersController) Save(c *fiber.Ctx) error {
req := new(request.BannersCreateRequest)
if err := utilVal.ParseAndValidate(c, req); err != nil {
return err
}
dataResult, err := _i.bannersService.Create(*req)
if err != nil {
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Banner successfully created"},
Data: dataResult,
})
}
// Update Banner
// @Summary Update Banner
// @Description API for updating Banner
// @Tags Banners
// @Security Bearer
// @Param X-Client-Key header string true "Insert the X-Client-Key"
// @Param id path int true "Banner ID"
// @Param payload body request.BannersUpdateRequest true "Required payload"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
// @Failure 500 {object} response.InternalServerError
// @Router /banners/{id} [put]
func (_i *bannersController) Update(c *fiber.Ctx) error {
id, err := strconv.ParseUint(c.Params("id"), 10, 0)
if err != nil {
return err
}
req := new(request.BannersUpdateRequest)
if err := utilVal.ParseAndValidate(c, req); err != nil {
return err
}
dataResult, err := _i.bannersService.Update(uint(id), *req)
if err != nil {
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Banner successfully updated"},
Data: dataResult,
})
}
// Delete Banner
// @Summary Delete Banner
// @Description API for deleting Banner (soft delete)
// @Tags Banners
// @Security Bearer
// @Param X-Client-Key header string true "Insert the X-Client-Key"
// @Param id path int true "Banner ID"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
// @Failure 500 {object} response.InternalServerError
// @Router /banners/{id} [delete]
func (_i *bannersController) Delete(c *fiber.Ctx) error {
id, err := strconv.ParseUint(c.Params("id"), 10, 0)
if err != nil {
return err
}
err = _i.bannersService.Delete(uint(id))
if err != nil {
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Banner successfully deleted"},
})
}

View File

@ -0,0 +1,13 @@
package controller
import "jaecoo-be/app/module/banners/service"
type Controller struct {
Banners BannersController
}
func NewController(BannersService service.BannersService) *Controller {
return &Controller{
Banners: NewBannersController(BannersService),
}
}

View File

@ -0,0 +1,32 @@
package mapper
import (
"jaecoo-be/app/database/entity"
res "jaecoo-be/app/module/banners/response"
)
func BannersResponseMapper(banner *entity.Banners, host string) *res.BannersResponse {
if banner == nil {
return nil
}
response := &res.BannersResponse{
ID: banner.ID,
Title: banner.Title,
Description: banner.Description,
ThumbnailPath: banner.ThumbnailPath,
Position: banner.Position,
Status: banner.Status,
IsActive: banner.IsActive,
CreatedAt: banner.CreatedAt,
UpdatedAt: banner.UpdatedAt,
}
if banner.ThumbnailPath != nil && *banner.ThumbnailPath != "" {
thumbnailUrl := host + "/banners/thumbnail/viewer/" + *banner.ThumbnailPath
response.ThumbnailUrl = &thumbnailUrl
}
return response
}

View File

@ -0,0 +1,92 @@
package repository
import (
"jaecoo-be/app/database"
"jaecoo-be/app/database/entity"
"jaecoo-be/app/module/banners/request"
"jaecoo-be/utils/paginator"
"strings"
"github.com/rs/zerolog"
)
type bannersRepository struct {
DB *database.Database
Log zerolog.Logger
}
type BannersRepository interface {
GetAll(req request.BannersQueryRequest) (banners []*entity.Banners, paging paginator.Pagination, err error)
FindOne(id uint) (banner *entity.Banners, err error)
Create(banner *entity.Banners) (bannerReturn *entity.Banners, err error)
Update(id uint, banner *entity.Banners) (err error)
Delete(id uint) (err error)
}
func NewBannersRepository(db *database.Database, log zerolog.Logger) BannersRepository {
return &bannersRepository{
DB: db,
Log: log,
}
}
func (_i *bannersRepository) GetAll(req request.BannersQueryRequest) (banners []*entity.Banners, paging paginator.Pagination, err error) {
var count int64
query := _i.DB.DB.Model(&entity.Banners{})
if req.Title != nil && *req.Title != "" {
title := strings.ToLower(*req.Title)
query = query.Where("LOWER(title) LIKE ?", "%"+title+"%")
}
if req.Position != nil && *req.Position != "" {
query = query.Where("position = ?", *req.Position)
}
if req.Status != nil && *req.Status != "" {
query = query.Where("status = ?", *req.Status)
}
query = query.Where("is_active = ?", true)
query.Count(&count)
req.Pagination.Count = count
req.Pagination = paginator.Paging(req.Pagination)
query = query.Order("created_at DESC")
err = query.Offset(req.Pagination.Offset).Limit(req.Pagination.Limit).Find(&banners).Error
if err != nil {
return
}
paging = *req.Pagination
return
}
func (_i *bannersRepository) FindOne(id uint) (banner *entity.Banners, err error) {
banner = &entity.Banners{}
err = _i.DB.DB.Where("id = ? AND is_active = ?", id, true).First(banner).Error
return
}
func (_i *bannersRepository) Create(banner *entity.Banners) (bannerReturn *entity.Banners, err error) {
if err = _i.DB.DB.Create(banner).Error; err != nil {
return
}
bannerReturn = banner
return
}
func (_i *bannersRepository) Update(id uint, banner *entity.Banners) (err error) {
err = _i.DB.DB.Model(&entity.Banners{}).Where("id = ?", id).Updates(banner).Error
return
}
func (_i *bannersRepository) Delete(id uint) (err error) {
err = _i.DB.DB.Model(&entity.Banners{}).Where("id = ?", id).Update("is_active", false).Error
return
}

View File

@ -0,0 +1,81 @@
package request
import (
"jaecoo-be/app/database/entity"
"jaecoo-be/utils/paginator"
)
type BannersQueryRequest struct {
Title *string `json:"title"`
Position *string `json:"position"`
Status *string `json:"status"`
Pagination *paginator.Pagination `json:"pagination"`
}
type BannersQueryRequestContext struct {
Title string `json:"title"`
Position string `json:"position"`
Status string `json:"status"`
}
func (req BannersQueryRequestContext) ToParamRequest() BannersQueryRequest {
var request BannersQueryRequest
if title := req.Title; title != "" {
request.Title = &title
}
if position := req.Position; position != "" {
request.Position = &position
}
if status := req.Status; status != "" {
request.Status = &status
}
return request
}
type BannersCreateRequest struct {
Title string `json:"title" validate:"required"`
Description *string `json:"description"`
ThumbnailPath *string `json:"thumbnail_path"`
Position *string `json:"position"`
Status *string `json:"status"`
}
func (req BannersCreateRequest) ToEntity() *entity.Banners {
return &entity.Banners{
Title: req.Title,
Description: req.Description,
ThumbnailPath: req.ThumbnailPath,
Position: req.Position,
Status: req.Status,
}
}
type BannersUpdateRequest struct {
Title *string `json:"title"`
Description *string `json:"description"`
ThumbnailPath *string `json:"thumbnail_path"`
Position *string `json:"position"`
Status *string `json:"status"`
IsActive *bool `json:"is_active"`
}
func (req BannersUpdateRequest) ToEntity() *entity.Banners {
return &entity.Banners{
Title: getStringValue(req.Title),
Description: req.Description,
ThumbnailPath: req.ThumbnailPath,
Position: req.Position,
Status: req.Status,
IsActive: req.IsActive,
}
}
func getStringValue(s *string) string {
if s == nil {
return ""
}
return *s
}

View File

@ -0,0 +1,19 @@
package response
import (
"time"
)
type BannersResponse struct {
ID uint `json:"id"`
Title string `json:"title"`
Description *string `json:"description"`
ThumbnailPath *string `json:"thumbnail_path"`
ThumbnailUrl *string `json:"thumbnail_url"`
Position *string `json:"position"`
Status *string `json:"status"`
IsActive *bool `json:"is_active"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}

View File

@ -0,0 +1,107 @@
package service
import (
"errors"
"jaecoo-be/app/module/banners/mapper"
"jaecoo-be/app/module/banners/repository"
"jaecoo-be/app/module/banners/request"
"jaecoo-be/app/module/banners/response"
"jaecoo-be/config/config"
"jaecoo-be/utils/paginator"
"github.com/rs/zerolog"
)
type bannersService struct {
Repo repository.BannersRepository
Log zerolog.Logger
Cfg *config.Config
}
type BannersService interface {
GetAll(req request.BannersQueryRequest) (banners []*response.BannersResponse, paging paginator.Pagination, err error)
GetOne(id uint) (banner *response.BannersResponse, err error)
Create(req request.BannersCreateRequest) (banner *response.BannersResponse, err error)
Update(id uint, req request.BannersUpdateRequest) (banner *response.BannersResponse, err error)
Delete(id uint) (err error)
}
func NewBannersService(repo repository.BannersRepository, log zerolog.Logger, cfg *config.Config) BannersService {
return &bannersService{
Repo: repo,
Log: log,
Cfg: cfg,
}
}
func (_i *bannersService) GetAll(req request.BannersQueryRequest) (banners []*response.BannersResponse, paging paginator.Pagination, err error) {
bannersEntity, paging, err := _i.Repo.GetAll(req)
if err != nil {
return
}
host := _i.Cfg.App.Domain
for _, banner := range bannersEntity {
banners = append(banners, mapper.BannersResponseMapper(banner, host))
}
return
}
func (_i *bannersService) GetOne(id uint) (banner *response.BannersResponse, err error) {
bannerEntity, err := _i.Repo.FindOne(id)
if err != nil {
return
}
if bannerEntity == nil {
err = errors.New("banner not found")
return
}
host := _i.Cfg.App.Domain
banner = mapper.BannersResponseMapper(bannerEntity, host)
return
}
func (_i *bannersService) Create(req request.BannersCreateRequest) (banner *response.BannersResponse, err error) {
bannerEntity := req.ToEntity()
isActive := true
bannerEntity.IsActive = &isActive
bannerEntity, err = _i.Repo.Create(bannerEntity)
if err != nil {
return
}
host := _i.Cfg.App.Domain
banner = mapper.BannersResponseMapper(bannerEntity, host)
return
}
func (_i *bannersService) Update(id uint, req request.BannersUpdateRequest) (banner *response.BannersResponse, err error) {
bannerEntity := req.ToEntity()
err = _i.Repo.Update(id, bannerEntity)
if err != nil {
return
}
bannerEntity, err = _i.Repo.FindOne(id)
if err != nil {
return
}
host := _i.Cfg.App.Domain
banner = mapper.BannersResponseMapper(bannerEntity, host)
return
}
func (_i *bannersService) Delete(id uint) (err error) {
err = _i.Repo.Delete(id)
return
}

View File

@ -0,0 +1,13 @@
package controller
import "jaecoo-be/app/module/galleries/service"
type Controller struct {
Galleries GalleriesController
}
func NewController(GalleriesService service.GalleriesService) *Controller {
return &Controller{
Galleries: NewGalleriesController(GalleriesService),
}
}

View File

@ -0,0 +1,194 @@
package controller
import (
"jaecoo-be/app/module/galleries/request"
"jaecoo-be/app/module/galleries/service"
"jaecoo-be/utils/paginator"
"strconv"
"github.com/gofiber/fiber/v2"
utilRes "jaecoo-be/utils/response"
utilVal "jaecoo-be/utils/validator"
)
type galleriesController struct {
galleriesService service.GalleriesService
}
type GalleriesController interface {
All(c *fiber.Ctx) error
Show(c *fiber.Ctx) error
Save(c *fiber.Ctx) error
Update(c *fiber.Ctx) error
Delete(c *fiber.Ctx) error
}
func NewGalleriesController(galleriesService service.GalleriesService) GalleriesController {
return &galleriesController{
galleriesService: galleriesService,
}
}
// All Galleries
// @Summary Get all Galleries
// @Description API for getting all Galleries
// @Tags Galleries
// @Security Bearer
// @Param X-Client-Key header string true "Insert the X-Client-Key"
// @Param req query request.GalleriesQueryRequestContext false "query parameters"
// @Param req query paginator.Pagination false "pagination parameters"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
// @Failure 500 {object} response.InternalServerError
// @Router /galleries [get]
func (_i *galleriesController) All(c *fiber.Ctx) error {
paginate, err := paginator.Paginate(c)
if err != nil {
return err
}
reqContext := request.GalleriesQueryRequestContext{
Title: c.Query("title"),
}
req := reqContext.ToParamRequest()
req.Pagination = paginate
galleriesData, paging, err := _i.galleriesService.GetAll(req)
if err != nil {
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Galleries list successfully retrieved"},
Data: galleriesData,
Meta: paging,
})
}
// Show Gallery
// @Summary Get Gallery by ID
// @Description API for getting Gallery by ID
// @Tags Galleries
// @Security Bearer
// @Param X-Client-Key header string true "Insert the X-Client-Key"
// @Param id path int true "Gallery ID"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
// @Failure 500 {object} response.InternalServerError
// @Router /galleries/{id} [get]
func (_i *galleriesController) Show(c *fiber.Ctx) error {
id, err := strconv.ParseUint(c.Params("id"), 10, 0)
if err != nil {
return err
}
galleryData, err := _i.galleriesService.GetOne(uint(id))
if err != nil {
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Gallery successfully retrieved"},
Data: galleryData,
})
}
// Save Gallery
// @Summary Create Gallery
// @Description API for creating Gallery
// @Tags Galleries
// @Security Bearer
// @Param X-Client-Key header string true "Insert the X-Client-Key"
// @Param payload body request.GalleriesCreateRequest true "Required payload"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
// @Failure 500 {object} response.InternalServerError
// @Router /galleries [post]
func (_i *galleriesController) Save(c *fiber.Ctx) error {
req := new(request.GalleriesCreateRequest)
if err := utilVal.ParseAndValidate(c, req); err != nil {
return err
}
dataResult, err := _i.galleriesService.Create(*req)
if err != nil {
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Gallery successfully created"},
Data: dataResult,
})
}
// Update Gallery
// @Summary Update Gallery
// @Description API for updating Gallery
// @Tags Galleries
// @Security Bearer
// @Param X-Client-Key header string true "Insert the X-Client-Key"
// @Param id path int true "Gallery ID"
// @Param payload body request.GalleriesUpdateRequest true "Required payload"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
// @Failure 500 {object} response.InternalServerError
// @Router /galleries/{id} [put]
func (_i *galleriesController) Update(c *fiber.Ctx) error {
id, err := strconv.ParseUint(c.Params("id"), 10, 0)
if err != nil {
return err
}
req := new(request.GalleriesUpdateRequest)
if err := utilVal.ParseAndValidate(c, req); err != nil {
return err
}
dataResult, err := _i.galleriesService.Update(uint(id), *req)
if err != nil {
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Gallery successfully updated"},
Data: dataResult,
})
}
// Delete Gallery
// @Summary Delete Gallery
// @Description API for deleting Gallery (soft delete)
// @Tags Galleries
// @Security Bearer
// @Param X-Client-Key header string true "Insert the X-Client-Key"
// @Param id path int true "Gallery ID"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
// @Failure 500 {object} response.InternalServerError
// @Router /galleries/{id} [delete]
func (_i *galleriesController) Delete(c *fiber.Ctx) error {
id, err := strconv.ParseUint(c.Params("id"), 10, 0)
if err != nil {
return err
}
err = _i.galleriesService.Delete(uint(id))
if err != nil {
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Gallery successfully deleted"},
})
}

View File

@ -0,0 +1,55 @@
package galleries
import (
"jaecoo-be/app/module/galleries/controller"
"jaecoo-be/app/module/galleries/repository"
"jaecoo-be/app/module/galleries/service"
"github.com/gofiber/fiber/v2"
"go.uber.org/fx"
)
// GalleriesRouter struct of GalleriesRouter
type GalleriesRouter struct {
App fiber.Router
Controller *controller.Controller
}
// NewGalleriesModule register bulky of Galleries module
var NewGalleriesModule = fx.Options(
// register repository of Galleries module
fx.Provide(repository.NewGalleriesRepository),
// register service of Galleries module
fx.Provide(service.NewGalleriesService),
// register controller of Galleries module
fx.Provide(controller.NewController),
// register router of Galleries module
fx.Provide(NewGalleriesRouter),
)
// NewGalleriesRouter init GalleriesRouter
func NewGalleriesRouter(fiber *fiber.App, controller *controller.Controller) *GalleriesRouter {
return &GalleriesRouter{
App: fiber,
Controller: controller,
}
}
// RegisterGalleriesRoutes register routes of Galleries module
func (_i *GalleriesRouter) RegisterGalleriesRoutes() {
// define controllers
galleriesController := _i.Controller.Galleries
// define routes
_i.App.Route("/galleries", func(router fiber.Router) {
router.Get("/", galleriesController.All)
router.Get("/:id", galleriesController.Show)
router.Post("/", galleriesController.Save)
router.Put("/:id", galleriesController.Update)
router.Delete("/:id", galleriesController.Delete)
})
}

View File

@ -0,0 +1,30 @@
package mapper
import (
"jaecoo-be/app/database/entity"
res "jaecoo-be/app/module/galleries/response"
)
func GalleriesResponseMapper(gallery *entity.Galleries, host string) *res.GalleriesResponse {
if gallery == nil {
return nil
}
response := &res.GalleriesResponse{
ID: gallery.ID,
Title: gallery.Title,
Description: gallery.Description,
ThumbnailPath: gallery.ThumbnailPath,
IsActive: gallery.IsActive,
CreatedAt: gallery.CreatedAt,
UpdatedAt: gallery.UpdatedAt,
}
if gallery.ThumbnailPath != nil && *gallery.ThumbnailPath != "" {
thumbnailUrl := host + "/galleries/thumbnail/viewer/" + *gallery.ThumbnailPath
response.ThumbnailUrl = &thumbnailUrl
}
return response
}

View File

@ -0,0 +1,84 @@
package repository
import (
"jaecoo-be/app/database"
"jaecoo-be/app/database/entity"
"jaecoo-be/app/module/galleries/request"
"jaecoo-be/utils/paginator"
"strings"
"github.com/rs/zerolog"
)
type galleriesRepository struct {
DB *database.Database
Log zerolog.Logger
}
type GalleriesRepository interface {
GetAll(req request.GalleriesQueryRequest) (galleries []*entity.Galleries, paging paginator.Pagination, err error)
FindOne(id uint) (gallery *entity.Galleries, err error)
Create(gallery *entity.Galleries) (galleryReturn *entity.Galleries, err error)
Update(id uint, gallery *entity.Galleries) (err error)
Delete(id uint) (err error)
}
func NewGalleriesRepository(db *database.Database, log zerolog.Logger) GalleriesRepository {
return &galleriesRepository{
DB: db,
Log: log,
}
}
func (_i *galleriesRepository) GetAll(req request.GalleriesQueryRequest) (galleries []*entity.Galleries, paging paginator.Pagination, err error) {
var count int64
query := _i.DB.DB.Model(&entity.Galleries{})
if req.Title != nil && *req.Title != "" {
title := strings.ToLower(*req.Title)
query = query.Where("LOWER(title) LIKE ?", "%"+title+"%")
}
query = query.Where("is_active = ?", true)
query.Count(&count)
req.Pagination.Count = count
req.Pagination = paginator.Paging(req.Pagination)
query = query.Order("created_at DESC")
err = query.Offset(req.Pagination.Offset).Limit(req.Pagination.Limit).Find(&galleries).Error
if err != nil {
return
}
paging = *req.Pagination
return
}
func (_i *galleriesRepository) FindOne(id uint) (gallery *entity.Galleries, err error) {
gallery = &entity.Galleries{}
err = _i.DB.DB.Where("id = ? AND is_active = ?", id, true).First(gallery).Error
return
}
func (_i *galleriesRepository) Create(gallery *entity.Galleries) (galleryReturn *entity.Galleries, err error) {
if err = _i.DB.DB.Create(gallery).Error; err != nil {
return
}
galleryReturn = gallery
return
}
func (_i *galleriesRepository) Update(id uint, gallery *entity.Galleries) (err error) {
err = _i.DB.DB.Model(&entity.Galleries{}).Where("id = ?", id).Updates(gallery).Error
return
}
func (_i *galleriesRepository) Delete(id uint) (err error) {
err = _i.DB.DB.Model(&entity.Galleries{}).Where("id = ?", id).Update("is_active", false).Error
return
}

View File

@ -0,0 +1,63 @@
package request
import (
"jaecoo-be/app/database/entity"
"jaecoo-be/utils/paginator"
)
type GalleriesQueryRequest struct {
Title *string `json:"title"`
Pagination *paginator.Pagination `json:"pagination"`
}
type GalleriesQueryRequestContext struct {
Title string `json:"title"`
}
func (req GalleriesQueryRequestContext) ToParamRequest() GalleriesQueryRequest {
var request GalleriesQueryRequest
if title := req.Title; title != "" {
request.Title = &title
}
return request
}
type GalleriesCreateRequest struct {
Title string `json:"title" validate:"required"`
Description *string `json:"description"`
ThumbnailPath *string `json:"thumbnail_path"`
}
func (req GalleriesCreateRequest) ToEntity() *entity.Galleries {
return &entity.Galleries{
Title: req.Title,
Description: req.Description,
ThumbnailPath: req.ThumbnailPath,
}
}
type GalleriesUpdateRequest struct {
Title *string `json:"title"`
Description *string `json:"description"`
ThumbnailPath *string `json:"thumbnail_path"`
IsActive *bool `json:"is_active"`
}
func (req GalleriesUpdateRequest) ToEntity() *entity.Galleries {
return &entity.Galleries{
Title: getStringValue(req.Title),
Description: req.Description,
ThumbnailPath: req.ThumbnailPath,
IsActive: req.IsActive,
}
}
func getStringValue(s *string) string {
if s == nil {
return ""
}
return *s
}

View File

@ -0,0 +1,17 @@
package response
import (
"time"
)
type GalleriesResponse struct {
ID uint `json:"id"`
Title string `json:"title"`
Description *string `json:"description"`
ThumbnailPath *string `json:"thumbnail_path"`
ThumbnailUrl *string `json:"thumbnail_url"`
IsActive *bool `json:"is_active"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}

View File

@ -0,0 +1,107 @@
package service
import (
"errors"
"jaecoo-be/app/module/galleries/mapper"
"jaecoo-be/app/module/galleries/repository"
"jaecoo-be/app/module/galleries/request"
"jaecoo-be/app/module/galleries/response"
"jaecoo-be/config/config"
"jaecoo-be/utils/paginator"
"github.com/rs/zerolog"
)
type galleriesService struct {
Repo repository.GalleriesRepository
Log zerolog.Logger
Cfg *config.Config
}
type GalleriesService interface {
GetAll(req request.GalleriesQueryRequest) (galleries []*response.GalleriesResponse, paging paginator.Pagination, err error)
GetOne(id uint) (gallery *response.GalleriesResponse, err error)
Create(req request.GalleriesCreateRequest) (gallery *response.GalleriesResponse, err error)
Update(id uint, req request.GalleriesUpdateRequest) (gallery *response.GalleriesResponse, err error)
Delete(id uint) (err error)
}
func NewGalleriesService(repo repository.GalleriesRepository, log zerolog.Logger, cfg *config.Config) GalleriesService {
return &galleriesService{
Repo: repo,
Log: log,
Cfg: cfg,
}
}
func (_i *galleriesService) GetAll(req request.GalleriesQueryRequest) (galleries []*response.GalleriesResponse, paging paginator.Pagination, err error) {
galleriesEntity, paging, err := _i.Repo.GetAll(req)
if err != nil {
return
}
host := _i.Cfg.App.Domain
for _, gallery := range galleriesEntity {
galleries = append(galleries, mapper.GalleriesResponseMapper(gallery, host))
}
return
}
func (_i *galleriesService) GetOne(id uint) (gallery *response.GalleriesResponse, err error) {
galleryEntity, err := _i.Repo.FindOne(id)
if err != nil {
return
}
if galleryEntity == nil {
err = errors.New("gallery not found")
return
}
host := _i.Cfg.App.Domain
gallery = mapper.GalleriesResponseMapper(galleryEntity, host)
return
}
func (_i *galleriesService) Create(req request.GalleriesCreateRequest) (gallery *response.GalleriesResponse, err error) {
galleryEntity := req.ToEntity()
isActive := true
galleryEntity.IsActive = &isActive
galleryEntity, err = _i.Repo.Create(galleryEntity)
if err != nil {
return
}
host := _i.Cfg.App.Domain
gallery = mapper.GalleriesResponseMapper(galleryEntity, host)
return
}
func (_i *galleriesService) Update(id uint, req request.GalleriesUpdateRequest) (gallery *response.GalleriesResponse, err error) {
galleryEntity := req.ToEntity()
err = _i.Repo.Update(id, galleryEntity)
if err != nil {
return
}
galleryEntity, err = _i.Repo.FindOne(id)
if err != nil {
return
}
host := _i.Cfg.App.Domain
gallery = mapper.GalleriesResponseMapper(galleryEntity, host)
return
}
func (_i *galleriesService) Delete(id uint) (err error) {
err = _i.Repo.Delete(id)
return
}

View File

@ -0,0 +1,14 @@
package controller
import "jaecoo-be/app/module/gallery_files/service"
type Controller struct {
GalleryFiles GalleryFilesController
}
func NewController(GalleryFilesService service.GalleryFilesService) *Controller {
return &Controller{
GalleryFiles: NewGalleryFilesController(GalleryFilesService),
}
}

View File

@ -0,0 +1,195 @@
package controller
import (
"jaecoo-be/app/module/gallery_files/request"
"jaecoo-be/app/module/gallery_files/service"
"jaecoo-be/utils/paginator"
"strconv"
"github.com/gofiber/fiber/v2"
utilRes "jaecoo-be/utils/response"
utilVal "jaecoo-be/utils/validator"
)
type galleryFilesController struct {
galleryFilesService service.GalleryFilesService
}
type GalleryFilesController interface {
All(c *fiber.Ctx) error
Show(c *fiber.Ctx) error
Save(c *fiber.Ctx) error
Update(c *fiber.Ctx) error
Delete(c *fiber.Ctx) error
}
func NewGalleryFilesController(galleryFilesService service.GalleryFilesService) GalleryFilesController {
return &galleryFilesController{
galleryFilesService: galleryFilesService,
}
}
// All GalleryFiles
// @Summary Get all GalleryFiles
// @Description API for getting all GalleryFiles
// @Tags GalleryFiles
// @Security Bearer
// @Param X-Client-Key header string true "Insert the X-Client-Key"
// @Param req query request.GalleryFilesQueryRequestContext false "query parameters"
// @Param req query paginator.Pagination false "pagination parameters"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
// @Failure 500 {object} response.InternalServerError
// @Router /gallery-files [get]
func (_i *galleryFilesController) All(c *fiber.Ctx) error {
paginate, err := paginator.Paginate(c)
if err != nil {
return err
}
reqContext := request.GalleryFilesQueryRequestContext{
GalleryID: c.Query("gallery_id"),
Title: c.Query("title"),
}
req := reqContext.ToParamRequest()
req.Pagination = paginate
filesData, paging, err := _i.galleryFilesService.GetAll(req)
if err != nil {
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"GalleryFiles list successfully retrieved"},
Data: filesData,
Meta: paging,
})
}
// Show GalleryFile
// @Summary Get GalleryFile by ID
// @Description API for getting GalleryFile by ID
// @Tags GalleryFiles
// @Security Bearer
// @Param X-Client-Key header string true "Insert the X-Client-Key"
// @Param id path int true "GalleryFile ID"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
// @Failure 500 {object} response.InternalServerError
// @Router /gallery-files/{id} [get]
func (_i *galleryFilesController) Show(c *fiber.Ctx) error {
id, err := strconv.ParseUint(c.Params("id"), 10, 0)
if err != nil {
return err
}
fileData, err := _i.galleryFilesService.GetOne(uint(id))
if err != nil {
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"GalleryFile successfully retrieved"},
Data: fileData,
})
}
// Save GalleryFile
// @Summary Create GalleryFile
// @Description API for creating GalleryFile
// @Tags GalleryFiles
// @Security Bearer
// @Param X-Client-Key header string true "Insert the X-Client-Key"
// @Param payload body request.GalleryFilesCreateRequest true "Required payload"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
// @Failure 500 {object} response.InternalServerError
// @Router /gallery-files [post]
func (_i *galleryFilesController) Save(c *fiber.Ctx) error {
req := new(request.GalleryFilesCreateRequest)
if err := utilVal.ParseAndValidate(c, req); err != nil {
return err
}
dataResult, err := _i.galleryFilesService.Create(*req)
if err != nil {
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"GalleryFile successfully created"},
Data: dataResult,
})
}
// Update GalleryFile
// @Summary Update GalleryFile
// @Description API for updating GalleryFile
// @Tags GalleryFiles
// @Security Bearer
// @Param X-Client-Key header string true "Insert the X-Client-Key"
// @Param id path int true "GalleryFile ID"
// @Param payload body request.GalleryFilesUpdateRequest true "Required payload"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
// @Failure 500 {object} response.InternalServerError
// @Router /gallery-files/{id} [put]
func (_i *galleryFilesController) Update(c *fiber.Ctx) error {
id, err := strconv.ParseUint(c.Params("id"), 10, 0)
if err != nil {
return err
}
req := new(request.GalleryFilesUpdateRequest)
if err := utilVal.ParseAndValidate(c, req); err != nil {
return err
}
dataResult, err := _i.galleryFilesService.Update(uint(id), *req)
if err != nil {
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"GalleryFile successfully updated"},
Data: dataResult,
})
}
// Delete GalleryFile
// @Summary Delete GalleryFile
// @Description API for deleting GalleryFile (soft delete)
// @Tags GalleryFiles
// @Security Bearer
// @Param X-Client-Key header string true "Insert the X-Client-Key"
// @Param id path int true "GalleryFile ID"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
// @Failure 500 {object} response.InternalServerError
// @Router /gallery-files/{id} [delete]
func (_i *galleryFilesController) Delete(c *fiber.Ctx) error {
id, err := strconv.ParseUint(c.Params("id"), 10, 0)
if err != nil {
return err
}
err = _i.galleryFilesService.Delete(uint(id))
if err != nil {
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"GalleryFile successfully deleted"},
})
}

View File

@ -0,0 +1,55 @@
package gallery_files
import (
"jaecoo-be/app/module/gallery_files/controller"
"jaecoo-be/app/module/gallery_files/repository"
"jaecoo-be/app/module/gallery_files/service"
"github.com/gofiber/fiber/v2"
"go.uber.org/fx"
)
// GalleryFilesRouter struct of GalleryFilesRouter
type GalleryFilesRouter struct {
App fiber.Router
Controller *controller.Controller
}
// NewGalleryFilesModule register bulky of GalleryFiles module
var NewGalleryFilesModule = fx.Options(
// register repository of GalleryFiles module
fx.Provide(repository.NewGalleryFilesRepository),
// register service of GalleryFiles module
fx.Provide(service.NewGalleryFilesService),
// register controller of GalleryFiles module
fx.Provide(controller.NewController),
// register router of GalleryFiles module
fx.Provide(NewGalleryFilesRouter),
)
// NewGalleryFilesRouter init GalleryFilesRouter
func NewGalleryFilesRouter(fiber *fiber.App, controller *controller.Controller) *GalleryFilesRouter {
return &GalleryFilesRouter{
App: fiber,
Controller: controller,
}
}
// RegisterGalleryFilesRoutes register routes of GalleryFiles module
func (_i *GalleryFilesRouter) RegisterGalleryFilesRoutes() {
// define controllers
galleryFilesController := _i.Controller.GalleryFiles
// define routes
_i.App.Route("/gallery-files", func(router fiber.Router) {
router.Get("/", galleryFilesController.All)
router.Get("/:id", galleryFilesController.Show)
router.Post("/", galleryFilesController.Save)
router.Put("/:id", galleryFilesController.Update)
router.Delete("/:id", galleryFilesController.Delete)
})
}

View File

@ -0,0 +1,30 @@
package mapper
import (
"jaecoo-be/app/database/entity"
res "jaecoo-be/app/module/gallery_files/response"
)
func GalleryFilesResponseMapper(file *entity.GalleryFiles, host string) *res.GalleryFilesResponse {
if file == nil {
return nil
}
response := &res.GalleryFilesResponse{
ID: file.ID,
GalleryID: file.GalleryID,
Title: file.Title,
ImagePath: file.ImagePath,
IsActive: file.IsActive,
CreatedAt: file.CreatedAt,
UpdatedAt: file.UpdatedAt,
}
if file.ImagePath != nil && *file.ImagePath != "" {
imageUrl := host + "/gallery-files/image/viewer/" + *file.ImagePath
response.ImageUrl = &imageUrl
}
return response
}

View File

@ -0,0 +1,89 @@
package repository
import (
"jaecoo-be/app/database"
"jaecoo-be/app/database/entity"
"jaecoo-be/app/module/gallery_files/request"
"jaecoo-be/utils/paginator"
"strings"
"github.com/rs/zerolog"
)
type galleryFilesRepository struct {
DB *database.Database
Log zerolog.Logger
}
type GalleryFilesRepository interface {
GetAll(req request.GalleryFilesQueryRequest) (files []*entity.GalleryFiles, paging paginator.Pagination, err error)
FindOne(id uint) (file *entity.GalleryFiles, err error)
Create(file *entity.GalleryFiles) (fileReturn *entity.GalleryFiles, err error)
Update(id uint, file *entity.GalleryFiles) (err error)
Delete(id uint) (err error)
}
func NewGalleryFilesRepository(db *database.Database, log zerolog.Logger) GalleryFilesRepository {
return &galleryFilesRepository{
DB: db,
Log: log,
}
}
func (_i *galleryFilesRepository) GetAll(req request.GalleryFilesQueryRequest) (files []*entity.GalleryFiles, paging paginator.Pagination, err error) {
var count int64
query := _i.DB.DB.Model(&entity.GalleryFiles{})
if req.GalleryID != nil {
query = query.Where("gallery_id = ?", *req.GalleryID)
}
if req.Title != nil && *req.Title != "" {
title := strings.ToLower(*req.Title)
query = query.Where("LOWER(title) LIKE ?", "%"+title+"%")
}
query = query.Where("is_active = ?", true)
query.Count(&count)
req.Pagination.Count = count
req.Pagination = paginator.Paging(req.Pagination)
query = query.Order("created_at DESC")
err = query.Offset(req.Pagination.Offset).Limit(req.Pagination.Limit).Find(&files).Error
if err != nil {
return
}
paging = *req.Pagination
return
}
func (_i *galleryFilesRepository) FindOne(id uint) (file *entity.GalleryFiles, err error) {
file = &entity.GalleryFiles{}
err = _i.DB.DB.Where("id = ? AND is_active = ?", id, true).First(file).Error
return
}
func (_i *galleryFilesRepository) Create(file *entity.GalleryFiles) (fileReturn *entity.GalleryFiles, err error) {
if err = _i.DB.DB.Create(file).Error; err != nil {
return
}
fileReturn = file
return
}
func (_i *galleryFilesRepository) Update(id uint, file *entity.GalleryFiles) (err error) {
err = _i.DB.DB.Model(&entity.GalleryFiles{}).Where("id = ?", id).Updates(file).Error
return
}
func (_i *galleryFilesRepository) Delete(id uint) (err error) {
err = _i.DB.DB.Model(&entity.GalleryFiles{}).Where("id = ?", id).Update("is_active", false).Error
return
}

View File

@ -0,0 +1,73 @@
package request
import (
"jaecoo-be/app/database/entity"
"jaecoo-be/utils/paginator"
"strconv"
)
type GalleryFilesQueryRequest struct {
GalleryID *uint `json:"gallery_id"`
Title *string `json:"title"`
Pagination *paginator.Pagination `json:"pagination"`
}
type GalleryFilesQueryRequestContext struct {
GalleryID string `json:"gallery_id"`
Title string `json:"title"`
}
func (req GalleryFilesQueryRequestContext) ToParamRequest() GalleryFilesQueryRequest {
var request GalleryFilesQueryRequest
if galleryIDStr := req.GalleryID; galleryIDStr != "" {
galleryID, err := strconv.Atoi(galleryIDStr)
if err == nil {
galleryIDUint := uint(galleryID)
request.GalleryID = &galleryIDUint
}
}
if title := req.Title; title != "" {
request.Title = &title
}
return request
}
type GalleryFilesCreateRequest struct {
GalleryID uint `json:"gallery_id" validate:"required"`
Title *string `json:"title"`
ImagePath *string `json:"image_path"`
}
func (req GalleryFilesCreateRequest) ToEntity() *entity.GalleryFiles {
return &entity.GalleryFiles{
GalleryID: req.GalleryID,
Title: req.Title,
ImagePath: req.ImagePath,
}
}
type GalleryFilesUpdateRequest struct {
GalleryID *uint `json:"gallery_id"`
Title *string `json:"title"`
ImagePath *string `json:"image_path"`
IsActive *bool `json:"is_active"`
}
func (req GalleryFilesUpdateRequest) ToEntity() *entity.GalleryFiles {
return &entity.GalleryFiles{
GalleryID: getUintValue(req.GalleryID),
Title: req.Title,
ImagePath: req.ImagePath,
IsActive: req.IsActive,
}
}
func getUintValue(u *uint) uint {
if u == nil {
return 0
}
return *u
}

View File

@ -0,0 +1,17 @@
package response
import (
"time"
)
type GalleryFilesResponse struct {
ID uint `json:"id"`
GalleryID uint `json:"gallery_id"`
Title *string `json:"title"`
ImagePath *string `json:"image_path"`
ImageUrl *string `json:"image_url"`
IsActive *bool `json:"is_active"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}

View File

@ -0,0 +1,107 @@
package service
import (
"errors"
"jaecoo-be/app/module/gallery_files/mapper"
"jaecoo-be/app/module/gallery_files/repository"
"jaecoo-be/app/module/gallery_files/request"
"jaecoo-be/app/module/gallery_files/response"
"jaecoo-be/config/config"
"jaecoo-be/utils/paginator"
"github.com/rs/zerolog"
)
type galleryFilesService struct {
Repo repository.GalleryFilesRepository
Log zerolog.Logger
Cfg *config.Config
}
type GalleryFilesService interface {
GetAll(req request.GalleryFilesQueryRequest) (files []*response.GalleryFilesResponse, paging paginator.Pagination, err error)
GetOne(id uint) (file *response.GalleryFilesResponse, err error)
Create(req request.GalleryFilesCreateRequest) (file *response.GalleryFilesResponse, err error)
Update(id uint, req request.GalleryFilesUpdateRequest) (file *response.GalleryFilesResponse, err error)
Delete(id uint) (err error)
}
func NewGalleryFilesService(repo repository.GalleryFilesRepository, log zerolog.Logger, cfg *config.Config) GalleryFilesService {
return &galleryFilesService{
Repo: repo,
Log: log,
Cfg: cfg,
}
}
func (_i *galleryFilesService) GetAll(req request.GalleryFilesQueryRequest) (files []*response.GalleryFilesResponse, paging paginator.Pagination, err error) {
filesEntity, paging, err := _i.Repo.GetAll(req)
if err != nil {
return
}
host := _i.Cfg.App.Domain
for _, file := range filesEntity {
files = append(files, mapper.GalleryFilesResponseMapper(file, host))
}
return
}
func (_i *galleryFilesService) GetOne(id uint) (file *response.GalleryFilesResponse, err error) {
fileEntity, err := _i.Repo.FindOne(id)
if err != nil {
return
}
if fileEntity == nil {
err = errors.New("gallery file not found")
return
}
host := _i.Cfg.App.Domain
file = mapper.GalleryFilesResponseMapper(fileEntity, host)
return
}
func (_i *galleryFilesService) Create(req request.GalleryFilesCreateRequest) (file *response.GalleryFilesResponse, err error) {
fileEntity := req.ToEntity()
isActive := true
fileEntity.IsActive = &isActive
fileEntity, err = _i.Repo.Create(fileEntity)
if err != nil {
return
}
host := _i.Cfg.App.Domain
file = mapper.GalleryFilesResponseMapper(fileEntity, host)
return
}
func (_i *galleryFilesService) Update(id uint, req request.GalleryFilesUpdateRequest) (file *response.GalleryFilesResponse, err error) {
fileEntity := req.ToEntity()
err = _i.Repo.Update(id, fileEntity)
if err != nil {
return
}
fileEntity, err = _i.Repo.FindOne(id)
if err != nil {
return
}
host := _i.Cfg.App.Domain
file = mapper.GalleryFilesResponseMapper(fileEntity, host)
return
}
func (_i *galleryFilesService) Delete(id uint) (err error) {
err = _i.Repo.Delete(id)
return
}

View File

@ -0,0 +1,14 @@
package controller
import "jaecoo-be/app/module/product_specifications/service"
type Controller struct {
ProductSpecifications ProductSpecificationsController
}
func NewController(ProductSpecificationsService service.ProductSpecificationsService) *Controller {
return &Controller{
ProductSpecifications: NewProductSpecificationsController(ProductSpecificationsService),
}
}

View File

@ -0,0 +1,196 @@
package controller
import (
"jaecoo-be/app/module/product_specifications/request"
"jaecoo-be/app/module/product_specifications/service"
"jaecoo-be/utils/paginator"
"strconv"
"github.com/gofiber/fiber/v2"
utilRes "jaecoo-be/utils/response"
utilVal "jaecoo-be/utils/validator"
)
type productSpecificationsController struct {
productSpecificationsService service.ProductSpecificationsService
}
type ProductSpecificationsController interface {
All(c *fiber.Ctx) error
Show(c *fiber.Ctx) error
Save(c *fiber.Ctx) error
Update(c *fiber.Ctx) error
Delete(c *fiber.Ctx) error
}
func NewProductSpecificationsController(productSpecificationsService service.ProductSpecificationsService) ProductSpecificationsController {
return &productSpecificationsController{
productSpecificationsService: productSpecificationsService,
}
}
// All ProductSpecifications
// @Summary Get all ProductSpecifications
// @Description API for getting all ProductSpecifications
// @Tags ProductSpecifications
// @Security Bearer
// @Param X-Client-Key header string true "Insert the X-Client-Key"
// @Param req query request.ProductSpecificationsQueryRequestContext false "query parameters"
// @Param req query paginator.Pagination false "pagination parameters"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
// @Failure 500 {object} response.InternalServerError
// @Router /product-specifications [get]
func (_i *productSpecificationsController) All(c *fiber.Ctx) error {
paginate, err := paginator.Paginate(c)
if err != nil {
return err
}
reqContext := request.ProductSpecificationsQueryRequestContext{
ProductID: c.Query("product_id"),
Title: c.Query("title"),
}
req := reqContext.ToParamRequest()
req.Pagination = paginate
specsData, paging, err := _i.productSpecificationsService.GetAll(req)
if err != nil {
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"ProductSpecifications list successfully retrieved"},
Data: specsData,
Meta: paging,
})
}
// Show ProductSpecification
// @Summary Get ProductSpecification by ID
// @Description API for getting ProductSpecification by ID
// @Tags ProductSpecifications
// @Security Bearer
// @Param X-Client-Key header string true "Insert the X-Client-Key"
// @Param id path int true "ProductSpecification ID"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
// @Failure 500 {object} response.InternalServerError
// @Router /product-specifications/{id} [get]
func (_i *productSpecificationsController) Show(c *fiber.Ctx) error {
id, err := strconv.ParseUint(c.Params("id"), 10, 0)
if err != nil {
return err
}
specData, err := _i.productSpecificationsService.GetOne(uint(id))
if err != nil {
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"ProductSpecification successfully retrieved"},
Data: specData,
})
}
// Save ProductSpecification
// @Summary Create ProductSpecification
// @Description API for creating ProductSpecification
// @Tags ProductSpecifications
// @Security Bearer
// @Param X-Client-Key header string true "Insert the X-Client-Key"
// @Param payload body request.ProductSpecificationsCreateRequest true "Required payload"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
// @Failure 500 {object} response.InternalServerError
// @Router /product-specifications [post]
func (_i *productSpecificationsController) Save(c *fiber.Ctx) error {
req := new(request.ProductSpecificationsCreateRequest)
if err := utilVal.ParseAndValidate(c, req); err != nil {
return err
}
dataResult, err := _i.productSpecificationsService.Create(*req)
if err != nil {
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"ProductSpecification successfully created"},
Data: dataResult,
})
}
// Update ProductSpecification
// @Summary Update ProductSpecification
// @Description API for updating ProductSpecification
// @Tags ProductSpecifications
// @Security Bearer
// @Param X-Client-Key header string true "Insert the X-Client-Key"
// @Param id path int true "ProductSpecification ID"
// @Param payload body request.ProductSpecificationsUpdateRequest true "Required payload"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
// @Failure 500 {object} response.InternalServerError
// @Router /product-specifications/{id} [put]
func (_i *productSpecificationsController) Update(c *fiber.Ctx) error {
id, err := strconv.ParseUint(c.Params("id"), 10, 0)
if err != nil {
return err
}
req := new(request.ProductSpecificationsUpdateRequest)
if err := utilVal.ParseAndValidate(c, req); err != nil {
return err
}
dataResult, err := _i.productSpecificationsService.Update(uint(id), *req)
if err != nil {
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"ProductSpecification successfully updated"},
Data: dataResult,
})
}
// Delete ProductSpecification
// @Summary Delete ProductSpecification
// @Description API for deleting ProductSpecification (soft delete)
// @Tags ProductSpecifications
// @Security Bearer
// @Param X-Client-Key header string true "Insert the X-Client-Key"
// @Param id path int true "ProductSpecification ID"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
// @Failure 500 {object} response.InternalServerError
// @Router /product-specifications/{id} [delete]
func (_i *productSpecificationsController) Delete(c *fiber.Ctx) error {
id, err := strconv.ParseUint(c.Params("id"), 10, 0)
if err != nil {
return err
}
err = _i.productSpecificationsService.Delete(uint(id))
if err != nil {
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"ProductSpecification successfully deleted"},
})
}

View File

@ -0,0 +1,30 @@
package mapper
import (
"jaecoo-be/app/database/entity"
res "jaecoo-be/app/module/product_specifications/response"
)
func ProductSpecificationsResponseMapper(spec *entity.ProductSpecifications, host string) *res.ProductSpecificationsResponse {
if spec == nil {
return nil
}
response := &res.ProductSpecificationsResponse{
ID: spec.ID,
ProductID: spec.ProductID,
Title: spec.Title,
ThumbnailPath: spec.ThumbnailPath,
IsActive: spec.IsActive,
CreatedAt: spec.CreatedAt,
UpdatedAt: spec.UpdatedAt,
}
if spec.ThumbnailPath != nil && *spec.ThumbnailPath != "" {
thumbnailUrl := host + "/product-specifications/thumbnail/viewer/" + *spec.ThumbnailPath
response.ThumbnailUrl = &thumbnailUrl
}
return response
}

View File

@ -0,0 +1,55 @@
package product_specifications
import (
"jaecoo-be/app/module/product_specifications/controller"
"jaecoo-be/app/module/product_specifications/repository"
"jaecoo-be/app/module/product_specifications/service"
"github.com/gofiber/fiber/v2"
"go.uber.org/fx"
)
// ProductSpecificationsRouter struct of ProductSpecificationsRouter
type ProductSpecificationsRouter struct {
App fiber.Router
Controller *controller.Controller
}
// NewProductSpecificationsModule register bulky of ProductSpecifications module
var NewProductSpecificationsModule = fx.Options(
// register repository of ProductSpecifications module
fx.Provide(repository.NewProductSpecificationsRepository),
// register service of ProductSpecifications module
fx.Provide(service.NewProductSpecificationsService),
// register controller of ProductSpecifications module
fx.Provide(controller.NewController),
// register router of ProductSpecifications module
fx.Provide(NewProductSpecificationsRouter),
)
// NewProductSpecificationsRouter init ProductSpecificationsRouter
func NewProductSpecificationsRouter(fiber *fiber.App, controller *controller.Controller) *ProductSpecificationsRouter {
return &ProductSpecificationsRouter{
App: fiber,
Controller: controller,
}
}
// RegisterProductSpecificationsRoutes register routes of ProductSpecifications module
func (_i *ProductSpecificationsRouter) RegisterProductSpecificationsRoutes() {
// define controllers
productSpecificationsController := _i.Controller.ProductSpecifications
// define routes
_i.App.Route("/product-specifications", func(router fiber.Router) {
router.Get("/", productSpecificationsController.All)
router.Get("/:id", productSpecificationsController.Show)
router.Post("/", productSpecificationsController.Save)
router.Put("/:id", productSpecificationsController.Update)
router.Delete("/:id", productSpecificationsController.Delete)
})
}

View File

@ -0,0 +1,89 @@
package repository
import (
"jaecoo-be/app/database"
"jaecoo-be/app/database/entity"
"jaecoo-be/app/module/product_specifications/request"
"jaecoo-be/utils/paginator"
"strings"
"github.com/rs/zerolog"
)
type productSpecificationsRepository struct {
DB *database.Database
Log zerolog.Logger
}
type ProductSpecificationsRepository interface {
GetAll(req request.ProductSpecificationsQueryRequest) (specs []*entity.ProductSpecifications, paging paginator.Pagination, err error)
FindOne(id uint) (spec *entity.ProductSpecifications, err error)
Create(spec *entity.ProductSpecifications) (specReturn *entity.ProductSpecifications, err error)
Update(id uint, spec *entity.ProductSpecifications) (err error)
Delete(id uint) (err error)
}
func NewProductSpecificationsRepository(db *database.Database, log zerolog.Logger) ProductSpecificationsRepository {
return &productSpecificationsRepository{
DB: db,
Log: log,
}
}
func (_i *productSpecificationsRepository) GetAll(req request.ProductSpecificationsQueryRequest) (specs []*entity.ProductSpecifications, paging paginator.Pagination, err error) {
var count int64
query := _i.DB.DB.Model(&entity.ProductSpecifications{})
if req.ProductID != nil {
query = query.Where("product_id = ?", *req.ProductID)
}
if req.Title != nil && *req.Title != "" {
title := strings.ToLower(*req.Title)
query = query.Where("LOWER(title) LIKE ?", "%"+title+"%")
}
query = query.Where("is_active = ?", true)
query.Count(&count)
req.Pagination.Count = count
req.Pagination = paginator.Paging(req.Pagination)
query = query.Order("created_at DESC")
err = query.Offset(req.Pagination.Offset).Limit(req.Pagination.Limit).Find(&specs).Error
if err != nil {
return
}
paging = *req.Pagination
return
}
func (_i *productSpecificationsRepository) FindOne(id uint) (spec *entity.ProductSpecifications, err error) {
spec = &entity.ProductSpecifications{}
err = _i.DB.DB.Where("id = ? AND is_active = ?", id, true).First(spec).Error
return
}
func (_i *productSpecificationsRepository) Create(spec *entity.ProductSpecifications) (specReturn *entity.ProductSpecifications, err error) {
if err = _i.DB.DB.Create(spec).Error; err != nil {
return
}
specReturn = spec
return
}
func (_i *productSpecificationsRepository) Update(id uint, spec *entity.ProductSpecifications) (err error) {
err = _i.DB.DB.Model(&entity.ProductSpecifications{}).Where("id = ?", id).Updates(spec).Error
return
}
func (_i *productSpecificationsRepository) Delete(id uint) (err error) {
err = _i.DB.DB.Model(&entity.ProductSpecifications{}).Where("id = ?", id).Update("is_active", false).Error
return
}

View File

@ -0,0 +1,80 @@
package request
import (
"jaecoo-be/app/database/entity"
"jaecoo-be/utils/paginator"
"strconv"
)
type ProductSpecificationsQueryRequest struct {
ProductID *uint `json:"product_id"`
Title *string `json:"title"`
Pagination *paginator.Pagination `json:"pagination"`
}
type ProductSpecificationsQueryRequestContext struct {
ProductID string `json:"product_id"`
Title string `json:"title"`
}
func (req ProductSpecificationsQueryRequestContext) ToParamRequest() ProductSpecificationsQueryRequest {
var request ProductSpecificationsQueryRequest
if productIDStr := req.ProductID; productIDStr != "" {
productID, err := strconv.Atoi(productIDStr)
if err == nil {
productIDUint := uint(productID)
request.ProductID = &productIDUint
}
}
if title := req.Title; title != "" {
request.Title = &title
}
return request
}
type ProductSpecificationsCreateRequest struct {
ProductID uint `json:"product_id" validate:"required"`
Title string `json:"title" validate:"required"`
ThumbnailPath *string `json:"thumbnail_path"`
}
func (req ProductSpecificationsCreateRequest) ToEntity() *entity.ProductSpecifications {
return &entity.ProductSpecifications{
ProductID: req.ProductID,
Title: req.Title,
ThumbnailPath: req.ThumbnailPath,
}
}
type ProductSpecificationsUpdateRequest struct {
ProductID *uint `json:"product_id"`
Title *string `json:"title"`
ThumbnailPath *string `json:"thumbnail_path"`
IsActive *bool `json:"is_active"`
}
func (req ProductSpecificationsUpdateRequest) ToEntity() *entity.ProductSpecifications {
return &entity.ProductSpecifications{
ProductID: getUintValue(req.ProductID),
Title: getStringValue(req.Title),
ThumbnailPath: req.ThumbnailPath,
IsActive: req.IsActive,
}
}
func getStringValue(s *string) string {
if s == nil {
return ""
}
return *s
}
func getUintValue(u *uint) uint {
if u == nil {
return 0
}
return *u
}

View File

@ -0,0 +1,17 @@
package response
import (
"time"
)
type ProductSpecificationsResponse struct {
ID uint `json:"id"`
ProductID uint `json:"product_id"`
Title string `json:"title"`
ThumbnailPath *string `json:"thumbnail_path"`
ThumbnailUrl *string `json:"thumbnail_url"`
IsActive *bool `json:"is_active"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}

View File

@ -0,0 +1,107 @@
package service
import (
"errors"
"jaecoo-be/app/module/product_specifications/mapper"
"jaecoo-be/app/module/product_specifications/repository"
"jaecoo-be/app/module/product_specifications/request"
"jaecoo-be/app/module/product_specifications/response"
"jaecoo-be/config/config"
"jaecoo-be/utils/paginator"
"github.com/rs/zerolog"
)
type productSpecificationsService struct {
Repo repository.ProductSpecificationsRepository
Log zerolog.Logger
Cfg *config.Config
}
type ProductSpecificationsService interface {
GetAll(req request.ProductSpecificationsQueryRequest) (specs []*response.ProductSpecificationsResponse, paging paginator.Pagination, err error)
GetOne(id uint) (spec *response.ProductSpecificationsResponse, err error)
Create(req request.ProductSpecificationsCreateRequest) (spec *response.ProductSpecificationsResponse, err error)
Update(id uint, req request.ProductSpecificationsUpdateRequest) (spec *response.ProductSpecificationsResponse, err error)
Delete(id uint) (err error)
}
func NewProductSpecificationsService(repo repository.ProductSpecificationsRepository, log zerolog.Logger, cfg *config.Config) ProductSpecificationsService {
return &productSpecificationsService{
Repo: repo,
Log: log,
Cfg: cfg,
}
}
func (_i *productSpecificationsService) GetAll(req request.ProductSpecificationsQueryRequest) (specs []*response.ProductSpecificationsResponse, paging paginator.Pagination, err error) {
specsEntity, paging, err := _i.Repo.GetAll(req)
if err != nil {
return
}
host := _i.Cfg.App.Domain
for _, spec := range specsEntity {
specs = append(specs, mapper.ProductSpecificationsResponseMapper(spec, host))
}
return
}
func (_i *productSpecificationsService) GetOne(id uint) (spec *response.ProductSpecificationsResponse, err error) {
specEntity, err := _i.Repo.FindOne(id)
if err != nil {
return
}
if specEntity == nil {
err = errors.New("product specification not found")
return
}
host := _i.Cfg.App.Domain
spec = mapper.ProductSpecificationsResponseMapper(specEntity, host)
return
}
func (_i *productSpecificationsService) Create(req request.ProductSpecificationsCreateRequest) (spec *response.ProductSpecificationsResponse, err error) {
specEntity := req.ToEntity()
isActive := true
specEntity.IsActive = &isActive
specEntity, err = _i.Repo.Create(specEntity)
if err != nil {
return
}
host := _i.Cfg.App.Domain
spec = mapper.ProductSpecificationsResponseMapper(specEntity, host)
return
}
func (_i *productSpecificationsService) Update(id uint, req request.ProductSpecificationsUpdateRequest) (spec *response.ProductSpecificationsResponse, err error) {
specEntity := req.ToEntity()
err = _i.Repo.Update(id, specEntity)
if err != nil {
return
}
specEntity, err = _i.Repo.FindOne(id)
if err != nil {
return
}
host := _i.Cfg.App.Domain
spec = mapper.ProductSpecificationsResponseMapper(specEntity, host)
return
}
func (_i *productSpecificationsService) Delete(id uint) (err error) {
err = _i.Repo.Delete(id)
return
}

View File

@ -0,0 +1,14 @@
package controller
import "jaecoo-be/app/module/products/service"
type Controller struct {
Products ProductsController
}
func NewController(ProductsService service.ProductsService) *Controller {
return &Controller{
Products: NewProductsController(ProductsService),
}
}

View File

@ -0,0 +1,196 @@
package controller
import (
"jaecoo-be/app/module/products/request"
"jaecoo-be/app/module/products/service"
"jaecoo-be/utils/paginator"
"strconv"
"github.com/gofiber/fiber/v2"
utilRes "jaecoo-be/utils/response"
utilVal "jaecoo-be/utils/validator"
)
type productsController struct {
productsService service.ProductsService
}
type ProductsController interface {
All(c *fiber.Ctx) error
Show(c *fiber.Ctx) error
Save(c *fiber.Ctx) error
Update(c *fiber.Ctx) error
Delete(c *fiber.Ctx) error
}
func NewProductsController(productsService service.ProductsService) ProductsController {
return &productsController{
productsService: productsService,
}
}
// All Products
// @Summary Get all Products
// @Description API for getting all Products
// @Tags Products
// @Security Bearer
// @Param X-Client-Key header string true "Insert the X-Client-Key"
// @Param req query request.ProductsQueryRequestContext false "query parameters"
// @Param req query paginator.Pagination false "pagination parameters"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
// @Failure 500 {object} response.InternalServerError
// @Router /products [get]
func (_i *productsController) All(c *fiber.Ctx) error {
paginate, err := paginator.Paginate(c)
if err != nil {
return err
}
reqContext := request.ProductsQueryRequestContext{
Title: c.Query("title"),
Variant: c.Query("variant"),
}
req := reqContext.ToParamRequest()
req.Pagination = paginate
productsData, paging, err := _i.productsService.GetAll(req)
if err != nil {
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Products list successfully retrieved"},
Data: productsData,
Meta: paging,
})
}
// Show Product
// @Summary Get Product by ID
// @Description API for getting Product by ID
// @Tags Products
// @Security Bearer
// @Param X-Client-Key header string true "Insert the X-Client-Key"
// @Param id path int true "Product ID"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
// @Failure 500 {object} response.InternalServerError
// @Router /products/{id} [get]
func (_i *productsController) Show(c *fiber.Ctx) error {
id, err := strconv.ParseUint(c.Params("id"), 10, 0)
if err != nil {
return err
}
productData, err := _i.productsService.GetOne(uint(id))
if err != nil {
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Product successfully retrieved"},
Data: productData,
})
}
// Save Product
// @Summary Create Product
// @Description API for creating Product
// @Tags Products
// @Security Bearer
// @Param X-Client-Key header string true "Insert the X-Client-Key"
// @Param payload body request.ProductsCreateRequest true "Required payload"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
// @Failure 500 {object} response.InternalServerError
// @Router /products [post]
func (_i *productsController) Save(c *fiber.Ctx) error {
req := new(request.ProductsCreateRequest)
if err := utilVal.ParseAndValidate(c, req); err != nil {
return err
}
dataResult, err := _i.productsService.Create(*req)
if err != nil {
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Product successfully created"},
Data: dataResult,
})
}
// Update Product
// @Summary Update Product
// @Description API for updating Product
// @Tags Products
// @Security Bearer
// @Param X-Client-Key header string true "Insert the X-Client-Key"
// @Param id path int true "Product ID"
// @Param payload body request.ProductsUpdateRequest true "Required payload"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
// @Failure 500 {object} response.InternalServerError
// @Router /products/{id} [put]
func (_i *productsController) Update(c *fiber.Ctx) error {
id, err := strconv.ParseUint(c.Params("id"), 10, 0)
if err != nil {
return err
}
req := new(request.ProductsUpdateRequest)
if err := utilVal.ParseAndValidate(c, req); err != nil {
return err
}
dataResult, err := _i.productsService.Update(uint(id), *req)
if err != nil {
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Product successfully updated"},
Data: dataResult,
})
}
// Delete Product
// @Summary Delete Product
// @Description API for deleting Product (soft delete)
// @Tags Products
// @Security Bearer
// @Param X-Client-Key header string true "Insert the X-Client-Key"
// @Param id path int true "Product ID"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
// @Failure 500 {object} response.InternalServerError
// @Router /products/{id} [delete]
func (_i *productsController) Delete(c *fiber.Ctx) error {
id, err := strconv.ParseUint(c.Params("id"), 10, 0)
if err != nil {
return err
}
err = _i.productsService.Delete(uint(id))
if err != nil {
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Product successfully deleted"},
})
}

View File

@ -0,0 +1,38 @@
package mapper
import (
"encoding/json"
"jaecoo-be/app/database/entity"
res "jaecoo-be/app/module/products/response"
)
func ProductsResponseMapper(product *entity.Products, host string) *res.ProductsResponse {
if product == nil {
return nil
}
var colors []string
if product.Colors != nil && *product.Colors != "" {
json.Unmarshal([]byte(*product.Colors), &colors)
}
response := &res.ProductsResponse{
ID: product.ID,
Title: product.Title,
Variant: product.Variant,
Price: product.Price,
ThumbnailPath: product.ThumbnailPath,
Colors: colors,
IsActive: product.IsActive,
CreatedAt: product.CreatedAt,
UpdatedAt: product.UpdatedAt,
}
if product.ThumbnailPath != nil && *product.ThumbnailPath != "" {
thumbnailUrl := host + "/products/thumbnail/viewer/" + *product.ThumbnailPath
response.ThumbnailUrl = &thumbnailUrl
}
return response
}

View File

@ -0,0 +1,55 @@
package products
import (
"jaecoo-be/app/module/products/controller"
"jaecoo-be/app/module/products/repository"
"jaecoo-be/app/module/products/service"
"github.com/gofiber/fiber/v2"
"go.uber.org/fx"
)
// ProductsRouter struct of ProductsRouter
type ProductsRouter struct {
App fiber.Router
Controller *controller.Controller
}
// NewProductsModule register bulky of Products module
var NewProductsModule = fx.Options(
// register repository of Products module
fx.Provide(repository.NewProductsRepository),
// register service of Products module
fx.Provide(service.NewProductsService),
// register controller of Products module
fx.Provide(controller.NewController),
// register router of Products module
fx.Provide(NewProductsRouter),
)
// NewProductsRouter init ProductsRouter
func NewProductsRouter(fiber *fiber.App, controller *controller.Controller) *ProductsRouter {
return &ProductsRouter{
App: fiber,
Controller: controller,
}
}
// RegisterProductsRoutes register routes of Products module
func (_i *ProductsRouter) RegisterProductsRoutes() {
// define controllers
productsController := _i.Controller.Products
// define routes
_i.App.Route("/products", func(router fiber.Router) {
router.Get("/", productsController.All)
router.Get("/:id", productsController.Show)
router.Post("/", productsController.Save)
router.Put("/:id", productsController.Update)
router.Delete("/:id", productsController.Delete)
})
}

View File

@ -0,0 +1,89 @@
package repository
import (
"jaecoo-be/app/database"
"jaecoo-be/app/database/entity"
"jaecoo-be/app/module/products/request"
"jaecoo-be/utils/paginator"
"strings"
"github.com/rs/zerolog"
)
type productsRepository struct {
DB *database.Database
Log zerolog.Logger
}
type ProductsRepository interface {
GetAll(req request.ProductsQueryRequest) (products []*entity.Products, paging paginator.Pagination, err error)
FindOne(id uint) (product *entity.Products, err error)
Create(product *entity.Products) (productReturn *entity.Products, err error)
Update(id uint, product *entity.Products) (err error)
Delete(id uint) (err error)
}
func NewProductsRepository(db *database.Database, log zerolog.Logger) ProductsRepository {
return &productsRepository{
DB: db,
Log: log,
}
}
func (_i *productsRepository) GetAll(req request.ProductsQueryRequest) (products []*entity.Products, paging paginator.Pagination, err error) {
var count int64
query := _i.DB.DB.Model(&entity.Products{})
if req.Title != nil && *req.Title != "" {
title := strings.ToLower(*req.Title)
query = query.Where("LOWER(title) LIKE ?", "%"+title+"%")
}
if req.Variant != nil && *req.Variant != "" {
query = query.Where("variant = ?", *req.Variant)
}
query = query.Where("is_active = ?", true)
query.Count(&count)
req.Pagination.Count = count
req.Pagination = paginator.Paging(req.Pagination)
query = query.Order("created_at DESC")
err = query.Offset(req.Pagination.Offset).Limit(req.Pagination.Limit).Find(&products).Error
if err != nil {
return
}
paging = *req.Pagination
return
}
func (_i *productsRepository) FindOne(id uint) (product *entity.Products, err error) {
product = &entity.Products{}
err = _i.DB.DB.Where("id = ? AND is_active = ?", id, true).First(product).Error
return
}
func (_i *productsRepository) Create(product *entity.Products) (productReturn *entity.Products, err error) {
if err = _i.DB.DB.Create(product).Error; err != nil {
return
}
productReturn = product
return
}
func (_i *productsRepository) Update(id uint, product *entity.Products) (err error) {
err = _i.DB.DB.Model(&entity.Products{}).Where("id = ?", id).Updates(product).Error
return
}
func (_i *productsRepository) Delete(id uint) (err error) {
err = _i.DB.DB.Model(&entity.Products{}).Where("id = ?", id).Update("is_active", false).Error
return
}

View File

@ -0,0 +1,89 @@
package request
import (
"encoding/json"
"jaecoo-be/app/database/entity"
"jaecoo-be/utils/paginator"
)
type ProductsQueryRequest struct {
Title *string `json:"title"`
Variant *string `json:"variant"`
Pagination *paginator.Pagination `json:"pagination"`
}
type ProductsQueryRequestContext struct {
Title string `json:"title"`
Variant string `json:"variant"`
}
func (req ProductsQueryRequestContext) ToParamRequest() ProductsQueryRequest {
var request ProductsQueryRequest
if title := req.Title; title != "" {
request.Title = &title
}
if variant := req.Variant; variant != "" {
request.Variant = &variant
}
return request
}
type ProductsCreateRequest struct {
Title string `json:"title" validate:"required"`
Variant *string `json:"variant"`
Price *float64 `json:"price"`
ThumbnailPath *string `json:"thumbnail_path"`
Colors []string `json:"colors"`
}
func (req ProductsCreateRequest) ToEntity() *entity.Products {
colorsJSON, _ := json.Marshal(req.Colors)
colorsStr := string(colorsJSON)
if colorsStr == "null" {
colorsStr = ""
}
return &entity.Products{
Title: req.Title,
Variant: req.Variant,
Price: req.Price,
ThumbnailPath: req.ThumbnailPath,
Colors: &colorsStr,
}
}
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"`
}
func (req ProductsUpdateRequest) ToEntity() *entity.Products {
colorsJSON, _ := json.Marshal(req.Colors)
colorsStr := string(colorsJSON)
if colorsStr == "null" {
colorsStr = ""
}
return &entity.Products{
Title: getStringValue(req.Title),
Variant: req.Variant,
Price: req.Price,
ThumbnailPath: req.ThumbnailPath,
Colors: &colorsStr,
IsActive: req.IsActive,
}
}
func getStringValue(s *string) string {
if s == nil {
return ""
}
return *s
}

View File

@ -0,0 +1,19 @@
package response
import (
"time"
)
type ProductsResponse struct {
ID uint `json:"id"`
Title string `json:"title"`
Variant *string `json:"variant"`
Price *float64 `json:"price"`
ThumbnailPath *string `json:"thumbnail_path"`
ThumbnailUrl *string `json:"thumbnail_url"`
Colors []string `json:"colors"`
IsActive *bool `json:"is_active"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}

View File

@ -0,0 +1,107 @@
package service
import (
"errors"
"jaecoo-be/app/module/products/mapper"
"jaecoo-be/app/module/products/repository"
"jaecoo-be/app/module/products/request"
"jaecoo-be/app/module/products/response"
"jaecoo-be/config/config"
"jaecoo-be/utils/paginator"
"github.com/rs/zerolog"
)
type productsService struct {
Repo repository.ProductsRepository
Log zerolog.Logger
Cfg *config.Config
}
type ProductsService interface {
GetAll(req request.ProductsQueryRequest) (products []*response.ProductsResponse, paging paginator.Pagination, err error)
GetOne(id uint) (product *response.ProductsResponse, err error)
Create(req request.ProductsCreateRequest) (product *response.ProductsResponse, err error)
Update(id uint, req request.ProductsUpdateRequest) (product *response.ProductsResponse, err error)
Delete(id uint) (err error)
}
func NewProductsService(repo repository.ProductsRepository, log zerolog.Logger, cfg *config.Config) ProductsService {
return &productsService{
Repo: repo,
Log: log,
Cfg: cfg,
}
}
func (_i *productsService) GetAll(req request.ProductsQueryRequest) (products []*response.ProductsResponse, paging paginator.Pagination, err error) {
productsEntity, paging, err := _i.Repo.GetAll(req)
if err != nil {
return
}
host := _i.Cfg.App.Domain
for _, product := range productsEntity {
products = append(products, mapper.ProductsResponseMapper(product, host))
}
return
}
func (_i *productsService) GetOne(id uint) (product *response.ProductsResponse, err error) {
productEntity, err := _i.Repo.FindOne(id)
if err != nil {
return
}
if productEntity == nil {
err = errors.New("product not found")
return
}
host := _i.Cfg.App.Domain
product = mapper.ProductsResponseMapper(productEntity, host)
return
}
func (_i *productsService) Create(req request.ProductsCreateRequest) (product *response.ProductsResponse, err error) {
productEntity := req.ToEntity()
isActive := true
productEntity.IsActive = &isActive
productEntity, err = _i.Repo.Create(productEntity)
if err != nil {
return
}
host := _i.Cfg.App.Domain
product = mapper.ProductsResponseMapper(productEntity, host)
return
}
func (_i *productsService) Update(id uint, req request.ProductsUpdateRequest) (product *response.ProductsResponse, err error) {
productEntity := req.ToEntity()
err = _i.Repo.Update(id, productEntity)
if err != nil {
return
}
productEntity, err = _i.Repo.FindOne(id)
if err != nil {
return
}
host := _i.Cfg.App.Domain
product = mapper.ProductsResponseMapper(productEntity, host)
return
}
func (_i *productsService) Delete(id uint) (err error) {
err = _i.Repo.Delete(id)
return
}

View File

@ -0,0 +1,13 @@
package controller
import "jaecoo-be/app/module/promotions/service"
type Controller struct {
Promotions PromotionsController
}
func NewController(PromotionsService service.PromotionsService) *Controller {
return &Controller{
Promotions: NewPromotionsController(PromotionsService),
}
}

View File

@ -0,0 +1,194 @@
package controller
import (
"jaecoo-be/app/module/promotions/request"
"jaecoo-be/app/module/promotions/service"
"jaecoo-be/utils/paginator"
"strconv"
"github.com/gofiber/fiber/v2"
utilRes "jaecoo-be/utils/response"
utilVal "jaecoo-be/utils/validator"
)
type promotionsController struct {
promotionsService service.PromotionsService
}
type PromotionsController interface {
All(c *fiber.Ctx) error
Show(c *fiber.Ctx) error
Save(c *fiber.Ctx) error
Update(c *fiber.Ctx) error
Delete(c *fiber.Ctx) error
}
func NewPromotionsController(promotionsService service.PromotionsService) PromotionsController {
return &promotionsController{
promotionsService: promotionsService,
}
}
// All Promotions
// @Summary Get all Promotions
// @Description API for getting all Promotions
// @Tags Promotions
// @Security Bearer
// @Param X-Client-Key header string true "Insert the X-Client-Key"
// @Param req query request.PromotionsQueryRequestContext false "query parameters"
// @Param req query paginator.Pagination false "pagination parameters"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
// @Failure 500 {object} response.InternalServerError
// @Router /promotions [get]
func (_i *promotionsController) All(c *fiber.Ctx) error {
paginate, err := paginator.Paginate(c)
if err != nil {
return err
}
reqContext := request.PromotionsQueryRequestContext{
Title: c.Query("title"),
}
req := reqContext.ToParamRequest()
req.Pagination = paginate
promotionsData, paging, err := _i.promotionsService.GetAll(req)
if err != nil {
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Promotions list successfully retrieved"},
Data: promotionsData,
Meta: paging,
})
}
// Show Promotion
// @Summary Get Promotion by ID
// @Description API for getting Promotion by ID
// @Tags Promotions
// @Security Bearer
// @Param X-Client-Key header string true "Insert the X-Client-Key"
// @Param id path int true "Promotion ID"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
// @Failure 500 {object} response.InternalServerError
// @Router /promotions/{id} [get]
func (_i *promotionsController) Show(c *fiber.Ctx) error {
id, err := strconv.ParseUint(c.Params("id"), 10, 0)
if err != nil {
return err
}
promotionData, err := _i.promotionsService.GetOne(uint(id))
if err != nil {
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Promotion successfully retrieved"},
Data: promotionData,
})
}
// Save Promotion
// @Summary Create Promotion
// @Description API for creating Promotion
// @Tags Promotions
// @Security Bearer
// @Param X-Client-Key header string true "Insert the X-Client-Key"
// @Param payload body request.PromotionsCreateRequest true "Required payload"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
// @Failure 500 {object} response.InternalServerError
// @Router /promotions [post]
func (_i *promotionsController) Save(c *fiber.Ctx) error {
req := new(request.PromotionsCreateRequest)
if err := utilVal.ParseAndValidate(c, req); err != nil {
return err
}
dataResult, err := _i.promotionsService.Create(*req)
if err != nil {
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Promotion successfully created"},
Data: dataResult,
})
}
// Update Promotion
// @Summary Update Promotion
// @Description API for updating Promotion
// @Tags Promotions
// @Security Bearer
// @Param X-Client-Key header string true "Insert the X-Client-Key"
// @Param id path int true "Promotion ID"
// @Param payload body request.PromotionsUpdateRequest true "Required payload"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
// @Failure 500 {object} response.InternalServerError
// @Router /promotions/{id} [put]
func (_i *promotionsController) Update(c *fiber.Ctx) error {
id, err := strconv.ParseUint(c.Params("id"), 10, 0)
if err != nil {
return err
}
req := new(request.PromotionsUpdateRequest)
if err := utilVal.ParseAndValidate(c, req); err != nil {
return err
}
dataResult, err := _i.promotionsService.Update(uint(id), *req)
if err != nil {
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Promotion successfully updated"},
Data: dataResult,
})
}
// Delete Promotion
// @Summary Delete Promotion
// @Description API for deleting Promotion (soft delete)
// @Tags Promotions
// @Security Bearer
// @Param X-Client-Key header string true "Insert the X-Client-Key"
// @Param id path int true "Promotion ID"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
// @Failure 500 {object} response.InternalServerError
// @Router /promotions/{id} [delete]
func (_i *promotionsController) Delete(c *fiber.Ctx) error {
id, err := strconv.ParseUint(c.Params("id"), 10, 0)
if err != nil {
return err
}
err = _i.promotionsService.Delete(uint(id))
if err != nil {
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"Promotion successfully deleted"},
})
}

View File

@ -0,0 +1,30 @@
package mapper
import (
"jaecoo-be/app/database/entity"
res "jaecoo-be/app/module/promotions/response"
)
func PromotionsResponseMapper(promotion *entity.Promotions, host string) *res.PromotionsResponse {
if promotion == nil {
return nil
}
response := &res.PromotionsResponse{
ID: promotion.ID,
Title: promotion.Title,
Description: promotion.Description,
ThumbnailPath: promotion.ThumbnailPath,
IsActive: promotion.IsActive,
CreatedAt: promotion.CreatedAt,
UpdatedAt: promotion.UpdatedAt,
}
if promotion.ThumbnailPath != nil && *promotion.ThumbnailPath != "" {
thumbnailUrl := host + "/promotions/thumbnail/viewer/" + *promotion.ThumbnailPath
response.ThumbnailUrl = &thumbnailUrl
}
return response
}

View File

@ -0,0 +1,55 @@
package promotions
import (
"jaecoo-be/app/module/promotions/controller"
"jaecoo-be/app/module/promotions/repository"
"jaecoo-be/app/module/promotions/service"
"github.com/gofiber/fiber/v2"
"go.uber.org/fx"
)
// PromotionsRouter struct of PromotionsRouter
type PromotionsRouter struct {
App fiber.Router
Controller *controller.Controller
}
// NewPromotionsModule register bulky of Promotions module
var NewPromotionsModule = fx.Options(
// register repository of Promotions module
fx.Provide(repository.NewPromotionsRepository),
// register service of Promotions module
fx.Provide(service.NewPromotionsService),
// register controller of Promotions module
fx.Provide(controller.NewController),
// register router of Promotions module
fx.Provide(NewPromotionsRouter),
)
// NewPromotionsRouter init PromotionsRouter
func NewPromotionsRouter(fiber *fiber.App, controller *controller.Controller) *PromotionsRouter {
return &PromotionsRouter{
App: fiber,
Controller: controller,
}
}
// RegisterPromotionsRoutes register routes of Promotions module
func (_i *PromotionsRouter) RegisterPromotionsRoutes() {
// define controllers
promotionsController := _i.Controller.Promotions
// define routes
_i.App.Route("/promotions", func(router fiber.Router) {
router.Get("/", promotionsController.All)
router.Get("/:id", promotionsController.Show)
router.Post("/", promotionsController.Save)
router.Put("/:id", promotionsController.Update)
router.Delete("/:id", promotionsController.Delete)
})
}

View File

@ -0,0 +1,85 @@
package repository
import (
"jaecoo-be/app/database"
"jaecoo-be/app/database/entity"
"jaecoo-be/app/module/promotions/request"
"jaecoo-be/utils/paginator"
"strings"
"github.com/rs/zerolog"
)
type promotionsRepository struct {
DB *database.Database
Log zerolog.Logger
}
type PromotionsRepository interface {
GetAll(req request.PromotionsQueryRequest) (promotions []*entity.Promotions, paging paginator.Pagination, err error)
FindOne(id uint) (promotion *entity.Promotions, err error)
Create(promotion *entity.Promotions) (promotionReturn *entity.Promotions, err error)
Update(id uint, promotion *entity.Promotions) (err error)
Delete(id uint) (err error)
}
func NewPromotionsRepository(db *database.Database, log zerolog.Logger) PromotionsRepository {
return &promotionsRepository{
DB: db,
Log: log,
}
}
func (_i *promotionsRepository) GetAll(req request.PromotionsQueryRequest) (promotions []*entity.Promotions, paging paginator.Pagination, err error) {
var count int64
query := _i.DB.DB.Model(&entity.Promotions{})
if req.Title != nil && *req.Title != "" {
title := strings.ToLower(*req.Title)
query = query.Where("LOWER(title) LIKE ?", "%"+title+"%")
}
query = query.Where("is_active = ?", true)
query.Count(&count)
req.Pagination.Count = count
req.Pagination = paginator.Paging(req.Pagination)
query = query.Order("created_at DESC")
err = query.Offset(req.Pagination.Offset).Limit(req.Pagination.Limit).Find(&promotions).Error
if err != nil {
return
}
paging = *req.Pagination
return
}
func (_i *promotionsRepository) FindOne(id uint) (promotion *entity.Promotions, err error) {
promotion = &entity.Promotions{}
err = _i.DB.DB.Where("id = ? AND is_active = ?", id, true).First(promotion).Error
return
}
func (_i *promotionsRepository) Create(promotion *entity.Promotions) (promotionReturn *entity.Promotions, err error) {
if err = _i.DB.DB.Create(promotion).Error; err != nil {
return
}
promotionReturn = promotion
return
}
func (_i *promotionsRepository) Update(id uint, promotion *entity.Promotions) (err error) {
err = _i.DB.DB.Model(&entity.Promotions{}).Where("id = ?", id).Updates(promotion).Error
return
}
func (_i *promotionsRepository) Delete(id uint) (err error) {
err = _i.DB.DB.Model(&entity.Promotions{}).Where("id = ?", id).Update("is_active", false).Error
return
}

View File

@ -0,0 +1,62 @@
package request
import (
"jaecoo-be/app/database/entity"
"jaecoo-be/utils/paginator"
)
type PromotionsQueryRequest struct {
Title *string `json:"title"`
Pagination *paginator.Pagination `json:"pagination"`
}
type PromotionsQueryRequestContext struct {
Title string `json:"title"`
}
func (req PromotionsQueryRequestContext) ToParamRequest() PromotionsQueryRequest {
var request PromotionsQueryRequest
if title := req.Title; title != "" {
request.Title = &title
}
return request
}
type PromotionsCreateRequest struct {
Title string `json:"title" validate:"required"`
Description *string `json:"description"`
ThumbnailPath *string `json:"thumbnail_path"`
}
func (req PromotionsCreateRequest) ToEntity() *entity.Promotions {
return &entity.Promotions{
Title: req.Title,
Description: req.Description,
ThumbnailPath: req.ThumbnailPath,
}
}
type PromotionsUpdateRequest struct {
Title *string `json:"title"`
Description *string `json:"description"`
ThumbnailPath *string `json:"thumbnail_path"`
IsActive *bool `json:"is_active"`
}
func (req PromotionsUpdateRequest) ToEntity() *entity.Promotions {
return &entity.Promotions{
Title: getStringValue(req.Title),
Description: req.Description,
ThumbnailPath: req.ThumbnailPath,
IsActive: req.IsActive,
}
}
func getStringValue(s *string) string {
if s == nil {
return ""
}
return *s
}

View File

@ -0,0 +1,17 @@
package response
import (
"time"
)
type PromotionsResponse struct {
ID uint `json:"id"`
Title string `json:"title"`
Description *string `json:"description"`
ThumbnailPath *string `json:"thumbnail_path"`
ThumbnailUrl *string `json:"thumbnail_url"`
IsActive *bool `json:"is_active"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}

View File

@ -0,0 +1,107 @@
package service
import (
"errors"
"jaecoo-be/app/module/promotions/mapper"
"jaecoo-be/app/module/promotions/repository"
"jaecoo-be/app/module/promotions/request"
"jaecoo-be/app/module/promotions/response"
"jaecoo-be/config/config"
"jaecoo-be/utils/paginator"
"github.com/rs/zerolog"
)
type promotionsService struct {
Repo repository.PromotionsRepository
Log zerolog.Logger
Cfg *config.Config
}
type PromotionsService interface {
GetAll(req request.PromotionsQueryRequest) (promotions []*response.PromotionsResponse, paging paginator.Pagination, err error)
GetOne(id uint) (promotion *response.PromotionsResponse, err error)
Create(req request.PromotionsCreateRequest) (promotion *response.PromotionsResponse, err error)
Update(id uint, req request.PromotionsUpdateRequest) (promotion *response.PromotionsResponse, err error)
Delete(id uint) (err error)
}
func NewPromotionsService(repo repository.PromotionsRepository, log zerolog.Logger, cfg *config.Config) PromotionsService {
return &promotionsService{
Repo: repo,
Log: log,
Cfg: cfg,
}
}
func (_i *promotionsService) GetAll(req request.PromotionsQueryRequest) (promotions []*response.PromotionsResponse, paging paginator.Pagination, err error) {
promotionsEntity, paging, err := _i.Repo.GetAll(req)
if err != nil {
return
}
host := _i.Cfg.App.Domain
for _, promotion := range promotionsEntity {
promotions = append(promotions, mapper.PromotionsResponseMapper(promotion, host))
}
return
}
func (_i *promotionsService) GetOne(id uint) (promotion *response.PromotionsResponse, err error) {
promotionEntity, err := _i.Repo.FindOne(id)
if err != nil {
return
}
if promotionEntity == nil {
err = errors.New("promotion not found")
return
}
host := _i.Cfg.App.Domain
promotion = mapper.PromotionsResponseMapper(promotionEntity, host)
return
}
func (_i *promotionsService) Create(req request.PromotionsCreateRequest) (promotion *response.PromotionsResponse, err error) {
promotionEntity := req.ToEntity()
isActive := true
promotionEntity.IsActive = &isActive
promotionEntity, err = _i.Repo.Create(promotionEntity)
if err != nil {
return
}
host := _i.Cfg.App.Domain
promotion = mapper.PromotionsResponseMapper(promotionEntity, host)
return
}
func (_i *promotionsService) Update(id uint, req request.PromotionsUpdateRequest) (promotion *response.PromotionsResponse, err error) {
promotionEntity := req.ToEntity()
err = _i.Repo.Update(id, promotionEntity)
if err != nil {
return
}
promotionEntity, err = _i.Repo.FindOne(id)
if err != nil {
return
}
host := _i.Cfg.App.Domain
promotion = mapper.PromotionsResponseMapper(promotionEntity, host)
return
}
func (_i *promotionsService) Delete(id uint) (err error) {
err = _i.Repo.Delete(id)
return
}

View File

@ -0,0 +1,14 @@
package controller
import "jaecoo-be/app/module/sales_agents/service"
type Controller struct {
SalesAgents SalesAgentsController
}
func NewController(SalesAgentsService service.SalesAgentsService) *Controller {
return &Controller{
SalesAgents: NewSalesAgentsController(SalesAgentsService),
}
}

View File

@ -0,0 +1,197 @@
package controller
import (
"jaecoo-be/app/module/sales_agents/request"
"jaecoo-be/app/module/sales_agents/service"
"jaecoo-be/utils/paginator"
"strconv"
"github.com/gofiber/fiber/v2"
utilRes "jaecoo-be/utils/response"
utilVal "jaecoo-be/utils/validator"
)
type salesAgentsController struct {
salesAgentsService service.SalesAgentsService
}
type SalesAgentsController interface {
All(c *fiber.Ctx) error
Show(c *fiber.Ctx) error
Save(c *fiber.Ctx) error
Update(c *fiber.Ctx) error
Delete(c *fiber.Ctx) error
}
func NewSalesAgentsController(salesAgentsService service.SalesAgentsService) SalesAgentsController {
return &salesAgentsController{
salesAgentsService: salesAgentsService,
}
}
// All SalesAgents
// @Summary Get all SalesAgents
// @Description API for getting all SalesAgents
// @Tags SalesAgents
// @Security Bearer
// @Param X-Client-Key header string true "Insert the X-Client-Key"
// @Param req query request.SalesAgentsQueryRequestContext false "query parameters"
// @Param req query paginator.Pagination false "pagination parameters"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
// @Failure 500 {object} response.InternalServerError
// @Router /sales-agents [get]
func (_i *salesAgentsController) All(c *fiber.Ctx) error {
paginate, err := paginator.Paginate(c)
if err != nil {
return err
}
reqContext := request.SalesAgentsQueryRequestContext{
Name: c.Query("name"),
JobTitle: c.Query("job_title"),
AgentType: c.Query("agent_type"),
}
req := reqContext.ToParamRequest()
req.Pagination = paginate
agentsData, paging, err := _i.salesAgentsService.GetAll(req)
if err != nil {
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"SalesAgents list successfully retrieved"},
Data: agentsData,
Meta: paging,
})
}
// Show SalesAgent
// @Summary Get SalesAgent by ID
// @Description API for getting SalesAgent by ID
// @Tags SalesAgents
// @Security Bearer
// @Param X-Client-Key header string true "Insert the X-Client-Key"
// @Param id path int true "SalesAgent ID"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
// @Failure 500 {object} response.InternalServerError
// @Router /sales-agents/{id} [get]
func (_i *salesAgentsController) Show(c *fiber.Ctx) error {
id, err := strconv.ParseUint(c.Params("id"), 10, 0)
if err != nil {
return err
}
agentData, err := _i.salesAgentsService.GetOne(uint(id))
if err != nil {
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"SalesAgent successfully retrieved"},
Data: agentData,
})
}
// Save SalesAgent
// @Summary Create SalesAgent
// @Description API for creating SalesAgent
// @Tags SalesAgents
// @Security Bearer
// @Param X-Client-Key header string true "Insert the X-Client-Key"
// @Param payload body request.SalesAgentsCreateRequest true "Required payload"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
// @Failure 500 {object} response.InternalServerError
// @Router /sales-agents [post]
func (_i *salesAgentsController) Save(c *fiber.Ctx) error {
req := new(request.SalesAgentsCreateRequest)
if err := utilVal.ParseAndValidate(c, req); err != nil {
return err
}
dataResult, err := _i.salesAgentsService.Create(*req)
if err != nil {
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"SalesAgent successfully created"},
Data: dataResult,
})
}
// Update SalesAgent
// @Summary Update SalesAgent
// @Description API for updating SalesAgent
// @Tags SalesAgents
// @Security Bearer
// @Param X-Client-Key header string true "Insert the X-Client-Key"
// @Param id path int true "SalesAgent ID"
// @Param payload body request.SalesAgentsUpdateRequest true "Required payload"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
// @Failure 500 {object} response.InternalServerError
// @Router /sales-agents/{id} [put]
func (_i *salesAgentsController) Update(c *fiber.Ctx) error {
id, err := strconv.ParseUint(c.Params("id"), 10, 0)
if err != nil {
return err
}
req := new(request.SalesAgentsUpdateRequest)
if err := utilVal.ParseAndValidate(c, req); err != nil {
return err
}
dataResult, err := _i.salesAgentsService.Update(uint(id), *req)
if err != nil {
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"SalesAgent successfully updated"},
Data: dataResult,
})
}
// Delete SalesAgent
// @Summary Delete SalesAgent
// @Description API for deleting SalesAgent (soft delete)
// @Tags SalesAgents
// @Security Bearer
// @Param X-Client-Key header string true "Insert the X-Client-Key"
// @Param id path int true "SalesAgent ID"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.BadRequestError
// @Failure 401 {object} response.UnauthorizedError
// @Failure 500 {object} response.InternalServerError
// @Router /sales-agents/{id} [delete]
func (_i *salesAgentsController) Delete(c *fiber.Ctx) error {
id, err := strconv.ParseUint(c.Params("id"), 10, 0)
if err != nil {
return err
}
err = _i.salesAgentsService.Delete(uint(id))
if err != nil {
return err
}
return utilRes.Resp(c, utilRes.Response{
Success: true,
Messages: utilRes.Messages{"SalesAgent successfully deleted"},
})
}

View File

@ -0,0 +1,38 @@
package mapper
import (
"encoding/json"
"jaecoo-be/app/database/entity"
res "jaecoo-be/app/module/sales_agents/response"
)
func SalesAgentsResponseMapper(agent *entity.SalesAgents, host string) *res.SalesAgentsResponse {
if agent == nil {
return nil
}
var agentType []string
if agent.AgentType != nil && *agent.AgentType != "" {
json.Unmarshal([]byte(*agent.AgentType), &agentType)
}
response := &res.SalesAgentsResponse{
ID: agent.ID,
Name: agent.Name,
JobTitle: agent.JobTitle,
Phone: agent.Phone,
AgentType: agentType,
ProfilePicturePath: agent.ProfilePicturePath,
IsActive: agent.IsActive,
CreatedAt: agent.CreatedAt,
UpdatedAt: agent.UpdatedAt,
}
if agent.ProfilePicturePath != nil && *agent.ProfilePicturePath != "" {
profilePictureUrl := host + "/sales-agents/profile-picture/viewer/" + *agent.ProfilePicturePath
response.ProfilePictureUrl = &profilePictureUrl
}
return response
}

View File

@ -0,0 +1,93 @@
package repository
import (
"jaecoo-be/app/database"
"jaecoo-be/app/database/entity"
"jaecoo-be/app/module/sales_agents/request"
"jaecoo-be/utils/paginator"
"strings"
"github.com/rs/zerolog"
)
type salesAgentsRepository struct {
DB *database.Database
Log zerolog.Logger
}
type SalesAgentsRepository interface {
GetAll(req request.SalesAgentsQueryRequest) (agents []*entity.SalesAgents, paging paginator.Pagination, err error)
FindOne(id uint) (agent *entity.SalesAgents, err error)
Create(agent *entity.SalesAgents) (agentReturn *entity.SalesAgents, err error)
Update(id uint, agent *entity.SalesAgents) (err error)
Delete(id uint) (err error)
}
func NewSalesAgentsRepository(db *database.Database, log zerolog.Logger) SalesAgentsRepository {
return &salesAgentsRepository{
DB: db,
Log: log,
}
}
func (_i *salesAgentsRepository) GetAll(req request.SalesAgentsQueryRequest) (agents []*entity.SalesAgents, paging paginator.Pagination, err error) {
var count int64
query := _i.DB.DB.Model(&entity.SalesAgents{})
if req.Name != nil && *req.Name != "" {
name := strings.ToLower(*req.Name)
query = query.Where("LOWER(name) LIKE ?", "%"+name+"%")
}
if req.JobTitle != nil && *req.JobTitle != "" {
query = query.Where("job_title = ?", *req.JobTitle)
}
if req.AgentType != nil && *req.AgentType != "" {
query = query.Where("agent_type LIKE ?", "%"+*req.AgentType+"%")
}
query = query.Where("is_active = ?", true)
query.Count(&count)
req.Pagination.Count = count
req.Pagination = paginator.Paging(req.Pagination)
query = query.Order("created_at DESC")
err = query.Offset(req.Pagination.Offset).Limit(req.Pagination.Limit).Find(&agents).Error
if err != nil {
return
}
paging = *req.Pagination
return
}
func (_i *salesAgentsRepository) FindOne(id uint) (agent *entity.SalesAgents, err error) {
agent = &entity.SalesAgents{}
err = _i.DB.DB.Where("id = ? AND is_active = ?", id, true).First(agent).Error
return
}
func (_i *salesAgentsRepository) Create(agent *entity.SalesAgents) (agentReturn *entity.SalesAgents, err error) {
if err = _i.DB.DB.Create(agent).Error; err != nil {
return
}
agentReturn = agent
return
}
func (_i *salesAgentsRepository) Update(id uint, agent *entity.SalesAgents) (err error) {
err = _i.DB.DB.Model(&entity.SalesAgents{}).Where("id = ?", id).Updates(agent).Error
return
}
func (_i *salesAgentsRepository) Delete(id uint) (err error) {
err = _i.DB.DB.Model(&entity.SalesAgents{}).Where("id = ?", id).Update("is_active", false).Error
return
}

View File

@ -0,0 +1,94 @@
package request
import (
"encoding/json"
"jaecoo-be/app/database/entity"
"jaecoo-be/utils/paginator"
)
type SalesAgentsQueryRequest struct {
Name *string `json:"name"`
JobTitle *string `json:"job_title"`
AgentType *string `json:"agent_type"`
Pagination *paginator.Pagination `json:"pagination"`
}
type SalesAgentsQueryRequestContext struct {
Name string `json:"name"`
JobTitle string `json:"job_title"`
AgentType string `json:"agent_type"`
}
func (req SalesAgentsQueryRequestContext) ToParamRequest() SalesAgentsQueryRequest {
var request SalesAgentsQueryRequest
if name := req.Name; name != "" {
request.Name = &name
}
if jobTitle := req.JobTitle; jobTitle != "" {
request.JobTitle = &jobTitle
}
if agentType := req.AgentType; agentType != "" {
request.AgentType = &agentType
}
return request
}
type SalesAgentsCreateRequest struct {
Name string `json:"name" validate:"required"`
JobTitle *string `json:"job_title"`
Phone *string `json:"phone"`
AgentType []string `json:"agent_type"`
ProfilePicturePath *string `json:"profile_picture_path"`
}
func (req SalesAgentsCreateRequest) ToEntity() *entity.SalesAgents {
agentTypeJSON, _ := json.Marshal(req.AgentType)
agentTypeStr := string(agentTypeJSON)
if agentTypeStr == "null" {
agentTypeStr = ""
}
return &entity.SalesAgents{
Name: req.Name,
JobTitle: req.JobTitle,
Phone: req.Phone,
AgentType: &agentTypeStr,
ProfilePicturePath: req.ProfilePicturePath,
}
}
type SalesAgentsUpdateRequest struct {
Name *string `json:"name"`
JobTitle *string `json:"job_title"`
Phone *string `json:"phone"`
AgentType []string `json:"agent_type"`
ProfilePicturePath *string `json:"profile_picture_path"`
IsActive *bool `json:"is_active"`
}
func (req SalesAgentsUpdateRequest) ToEntity() *entity.SalesAgents {
agentTypeJSON, _ := json.Marshal(req.AgentType)
agentTypeStr := string(agentTypeJSON)
if agentTypeStr == "null" {
agentTypeStr = ""
}
return &entity.SalesAgents{
Name: getStringValue(req.Name),
JobTitle: req.JobTitle,
Phone: req.Phone,
AgentType: &agentTypeStr,
ProfilePicturePath: req.ProfilePicturePath,
IsActive: req.IsActive,
}
}
func getStringValue(s *string) string {
if s == nil {
return ""
}
return *s
}

View File

@ -0,0 +1,19 @@
package response
import (
"time"
)
type SalesAgentsResponse struct {
ID uint `json:"id"`
Name string `json:"name"`
JobTitle *string `json:"job_title"`
Phone *string `json:"phone"`
AgentType []string `json:"agent_type"`
ProfilePicturePath *string `json:"profile_picture_path"`
ProfilePictureUrl *string `json:"profile_picture_url"`
IsActive *bool `json:"is_active"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}

View File

@ -0,0 +1,55 @@
package sales_agents
import (
"jaecoo-be/app/module/sales_agents/controller"
"jaecoo-be/app/module/sales_agents/repository"
"jaecoo-be/app/module/sales_agents/service"
"github.com/gofiber/fiber/v2"
"go.uber.org/fx"
)
// SalesAgentsRouter struct of SalesAgentsRouter
type SalesAgentsRouter struct {
App fiber.Router
Controller *controller.Controller
}
// NewSalesAgentsModule register bulky of SalesAgents module
var NewSalesAgentsModule = fx.Options(
// register repository of SalesAgents module
fx.Provide(repository.NewSalesAgentsRepository),
// register service of SalesAgents module
fx.Provide(service.NewSalesAgentsService),
// register controller of SalesAgents module
fx.Provide(controller.NewController),
// register router of SalesAgents module
fx.Provide(NewSalesAgentsRouter),
)
// NewSalesAgentsRouter init SalesAgentsRouter
func NewSalesAgentsRouter(fiber *fiber.App, controller *controller.Controller) *SalesAgentsRouter {
return &SalesAgentsRouter{
App: fiber,
Controller: controller,
}
}
// RegisterSalesAgentsRoutes register routes of SalesAgents module
func (_i *SalesAgentsRouter) RegisterSalesAgentsRoutes() {
// define controllers
salesAgentsController := _i.Controller.SalesAgents
// define routes
_i.App.Route("/sales-agents", func(router fiber.Router) {
router.Get("/", salesAgentsController.All)
router.Get("/:id", salesAgentsController.Show)
router.Post("/", salesAgentsController.Save)
router.Put("/:id", salesAgentsController.Update)
router.Delete("/:id", salesAgentsController.Delete)
})
}

View File

@ -0,0 +1,107 @@
package service
import (
"errors"
"jaecoo-be/app/module/sales_agents/mapper"
"jaecoo-be/app/module/sales_agents/repository"
"jaecoo-be/app/module/sales_agents/request"
"jaecoo-be/app/module/sales_agents/response"
"jaecoo-be/config/config"
"jaecoo-be/utils/paginator"
"github.com/rs/zerolog"
)
type salesAgentsService struct {
Repo repository.SalesAgentsRepository
Log zerolog.Logger
Cfg *config.Config
}
type SalesAgentsService interface {
GetAll(req request.SalesAgentsQueryRequest) (agents []*response.SalesAgentsResponse, paging paginator.Pagination, err error)
GetOne(id uint) (agent *response.SalesAgentsResponse, err error)
Create(req request.SalesAgentsCreateRequest) (agent *response.SalesAgentsResponse, err error)
Update(id uint, req request.SalesAgentsUpdateRequest) (agent *response.SalesAgentsResponse, err error)
Delete(id uint) (err error)
}
func NewSalesAgentsService(repo repository.SalesAgentsRepository, log zerolog.Logger, cfg *config.Config) SalesAgentsService {
return &salesAgentsService{
Repo: repo,
Log: log,
Cfg: cfg,
}
}
func (_i *salesAgentsService) GetAll(req request.SalesAgentsQueryRequest) (agents []*response.SalesAgentsResponse, paging paginator.Pagination, err error) {
agentsEntity, paging, err := _i.Repo.GetAll(req)
if err != nil {
return
}
host := _i.Cfg.App.Domain
for _, agent := range agentsEntity {
agents = append(agents, mapper.SalesAgentsResponseMapper(agent, host))
}
return
}
func (_i *salesAgentsService) GetOne(id uint) (agent *response.SalesAgentsResponse, err error) {
agentEntity, err := _i.Repo.FindOne(id)
if err != nil {
return
}
if agentEntity == nil {
err = errors.New("sales agent not found")
return
}
host := _i.Cfg.App.Domain
agent = mapper.SalesAgentsResponseMapper(agentEntity, host)
return
}
func (_i *salesAgentsService) Create(req request.SalesAgentsCreateRequest) (agent *response.SalesAgentsResponse, err error) {
agentEntity := req.ToEntity()
isActive := true
agentEntity.IsActive = &isActive
agentEntity, err = _i.Repo.Create(agentEntity)
if err != nil {
return
}
host := _i.Cfg.App.Domain
agent = mapper.SalesAgentsResponseMapper(agentEntity, host)
return
}
func (_i *salesAgentsService) Update(id uint, req request.SalesAgentsUpdateRequest) (agent *response.SalesAgentsResponse, err error) {
agentEntity := req.ToEntity()
err = _i.Repo.Update(id, agentEntity)
if err != nil {
return
}
agentEntity, err = _i.Repo.FindOne(id)
if err != nil {
return
}
host := _i.Cfg.App.Domain
agent = mapper.SalesAgentsResponseMapper(agentEntity, host)
return
}
func (_i *salesAgentsService) Delete(id uint) (err error) {
err = _i.Repo.Delete(id)
return
}

View File

@ -8,11 +8,18 @@ import (
"jaecoo-be/app/module/article_comments"
"jaecoo-be/app/module/article_files"
"jaecoo-be/app/module/articles"
"jaecoo-be/app/module/banners"
"jaecoo-be/app/module/cities"
"jaecoo-be/app/module/custom_static_pages"
"jaecoo-be/app/module/districts"
"jaecoo-be/app/module/feedbacks"
"jaecoo-be/app/module/galleries"
"jaecoo-be/app/module/gallery_files"
"jaecoo-be/app/module/product_specifications"
"jaecoo-be/app/module/products"
"jaecoo-be/app/module/promotions"
"jaecoo-be/app/module/provinces"
"jaecoo-be/app/module/sales_agents"
"jaecoo-be/app/module/user_levels"
"jaecoo-be/app/module/user_role_accesses"
"jaecoo-be/app/module/user_roles"
@ -35,11 +42,18 @@ type Router struct {
ArticleCommentsRouter *article_comments.ArticleCommentsRouter
ArticleApprovalsRouter *article_approvals.ArticleApprovalsRouter
ArticlesRouter *articles.ArticlesRouter
BannersRouter *banners.BannersRouter
CitiesRouter *cities.CitiesRouter
CustomStaticPagesRouter *custom_static_pages.CustomStaticPagesRouter
DistrictsRouter *districts.DistrictsRouter
FeedbacksRouter *feedbacks.FeedbacksRouter
GalleriesRouter *galleries.GalleriesRouter
GalleryFilesRouter *gallery_files.GalleryFilesRouter
ProductSpecificationsRouter *product_specifications.ProductSpecificationsRouter
ProductsRouter *products.ProductsRouter
PromotionsRouter *promotions.PromotionsRouter
ProvincesRouter *provinces.ProvincesRouter
SalesAgentsRouter *sales_agents.SalesAgentsRouter
UserLevelsRouter *user_levels.UserLevelsRouter
UserRoleAccessesRouter *user_role_accesses.UserRoleAccessesRouter
UserRolesRouter *user_roles.UserRolesRouter
@ -57,11 +71,18 @@ func NewRouter(
articleCommentsRouter *article_comments.ArticleCommentsRouter,
articleApprovalsRouter *article_approvals.ArticleApprovalsRouter,
articlesRouter *articles.ArticlesRouter,
bannersRouter *banners.BannersRouter,
citiesRouter *cities.CitiesRouter,
customStaticPagesRouter *custom_static_pages.CustomStaticPagesRouter,
districtsRouter *districts.DistrictsRouter,
feedbacksRouter *feedbacks.FeedbacksRouter,
galleriesRouter *galleries.GalleriesRouter,
galleryFilesRouter *gallery_files.GalleryFilesRouter,
productSpecificationsRouter *product_specifications.ProductSpecificationsRouter,
productsRouter *products.ProductsRouter,
promotionsRouter *promotions.PromotionsRouter,
provincesRouter *provinces.ProvincesRouter,
salesAgentsRouter *sales_agents.SalesAgentsRouter,
userLevelsRouter *user_levels.UserLevelsRouter,
userRoleAccessesRouter *user_role_accesses.UserRoleAccessesRouter,
userRolesRouter *user_roles.UserRolesRouter,
@ -77,11 +98,18 @@ func NewRouter(
ArticleCommentsRouter: articleCommentsRouter,
ArticleApprovalsRouter: articleApprovalsRouter,
ArticlesRouter: articlesRouter,
BannersRouter: bannersRouter,
CitiesRouter: citiesRouter,
CustomStaticPagesRouter: customStaticPagesRouter,
DistrictsRouter: districtsRouter,
FeedbacksRouter: feedbacksRouter,
GalleriesRouter: galleriesRouter,
GalleryFilesRouter: galleryFilesRouter,
ProductSpecificationsRouter: productSpecificationsRouter,
ProductsRouter: productsRouter,
PromotionsRouter: promotionsRouter,
ProvincesRouter: provincesRouter,
SalesAgentsRouter: salesAgentsRouter,
UserLevelsRouter: userLevelsRouter,
UserRoleAccessesRouter: userRoleAccessesRouter,
UserRolesRouter: userRolesRouter,
@ -107,11 +135,18 @@ func (r *Router) Register() {
r.ArticleApprovalsRouter.RegisterArticleApprovalsRoutes()
r.ArticlesRouter.RegisterArticlesRoutes()
r.ArticleCommentsRouter.RegisterArticleCommentsRoutes()
r.BannersRouter.RegisterBannersRoutes()
r.CitiesRouter.RegisterCitiesRoutes()
r.CustomStaticPagesRouter.RegisterCustomStaticPagesRoutes()
r.DistrictsRouter.RegisterDistrictsRoutes()
r.FeedbacksRouter.RegisterFeedbacksRoutes()
r.GalleriesRouter.RegisterGalleriesRoutes()
r.GalleryFilesRouter.RegisterGalleryFilesRoutes()
r.ProductSpecificationsRouter.RegisterProductSpecificationsRoutes()
r.ProductsRouter.RegisterProductsRoutes()
r.PromotionsRouter.RegisterPromotionsRoutes()
r.ProvincesRouter.RegisterProvincesRoutes()
r.SalesAgentsRouter.RegisterSalesAgentsRoutes()
r.UserLevelsRouter.RegisterUserLevelsRoutes()
r.UserRoleAccessesRouter.RegisterUserRoleAccessesRoutes()
r.UsersRouter.RegisterUsersRoutes()

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

14
main.go
View File

@ -10,11 +10,18 @@ import (
"jaecoo-be/app/module/article_comments"
"jaecoo-be/app/module/article_files"
"jaecoo-be/app/module/articles"
"jaecoo-be/app/module/banners"
"jaecoo-be/app/module/cities"
"jaecoo-be/app/module/custom_static_pages"
"jaecoo-be/app/module/districts"
"jaecoo-be/app/module/feedbacks"
"jaecoo-be/app/module/galleries"
"jaecoo-be/app/module/gallery_files"
"jaecoo-be/app/module/product_specifications"
"jaecoo-be/app/module/products"
"jaecoo-be/app/module/promotions"
"jaecoo-be/app/module/provinces"
"jaecoo-be/app/module/sales_agents"
"jaecoo-be/app/module/user_levels"
"jaecoo-be/app/module/user_role_accesses"
"jaecoo-be/app/module/user_role_level_details"
@ -61,11 +68,18 @@ func main() {
article_approvals.NewArticleApprovalsModule,
articles.NewArticlesModule,
article_comments.NewArticleCommentsModule,
banners.NewBannersModule,
cities.NewCitiesModule,
custom_static_pages.NewCustomStaticPagesModule,
districts.NewDistrictsModule,
feedbacks.NewFeedbacksModule,
galleries.NewGalleriesModule,
gallery_files.NewGalleryFilesModule,
product_specifications.NewProductSpecificationsModule,
products.NewProductsModule,
promotions.NewPromotionsModule,
provinces.NewProvincesModule,
sales_agents.NewSalesAgentsModule,
user_levels.NewUserLevelsModule,
user_roles.NewUserRolesModule,
user_role_accesses.NewUserRoleAccessesModule,