212 lines
6.0 KiB
Go
212 lines
6.0 KiB
Go
package controller
|
|
|
|
import (
|
|
"errors"
|
|
"net/http"
|
|
|
|
"github.com/Caknoooo/go-gin-clean-starter/modules/menu/dto"
|
|
"github.com/Caknoooo/go-gin-clean-starter/modules/menu/query"
|
|
"github.com/Caknoooo/go-gin-clean-starter/modules/menu/service"
|
|
"github.com/Caknoooo/go-gin-clean-starter/pkg/constants"
|
|
"github.com/Caknoooo/go-gin-clean-starter/pkg/utils"
|
|
"github.com/Caknoooo/go-pagination"
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/samber/do"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type (
|
|
MenuController interface {
|
|
CreateMenu(ctx *gin.Context)
|
|
GetMenuByID(ctx *gin.Context)
|
|
GetMenuByName(ctx *gin.Context)
|
|
GetMenus(ctx *gin.Context)
|
|
UpdateMenu(ctx *gin.Context)
|
|
DeleteMenu(ctx *gin.Context)
|
|
}
|
|
|
|
menuController struct {
|
|
menuService service.MenuService
|
|
db *gorm.DB
|
|
}
|
|
)
|
|
|
|
// CreateMenu implements MenuController.
|
|
func (m *menuController) CreateMenu(ctx *gin.Context) {
|
|
var req dto.MenuCreateRequest
|
|
if err := ctx.ShouldBind(&req); err != nil {
|
|
res := utils.BuildResponseFailed(dto.MESSAGE_FAILED_GET_DATA_FROM_BODY, err.Error(), nil)
|
|
ctx.AbortWithStatusJSON(http.StatusBadRequest, res)
|
|
return
|
|
}
|
|
|
|
in := dto.MenuResponse{
|
|
Name: req.Name,
|
|
IconUrl: req.IconUrl,
|
|
Url: req.Url,
|
|
Sequence: req.Sequence,
|
|
Mode: req.Mode,
|
|
Status: req.Status,
|
|
}
|
|
if req.ParentID != nil {
|
|
in.Parent = &dto.MenuParentResponse{ID: req.ParentID.String()}
|
|
}
|
|
|
|
res, err := m.menuService.Create(ctx.Request.Context(), in)
|
|
if err != nil {
|
|
resp := utils.BuildResponseFailed(dto.MESSAGE_FAILED_CREATE_MENU, err.Error(), nil)
|
|
ctx.JSON(http.StatusBadRequest, resp)
|
|
return
|
|
}
|
|
|
|
resp := utils.BuildResponseSuccess(dto.MESSAGE_SUCCESS_CREATE_MENU, res)
|
|
ctx.JSON(http.StatusOK, resp)
|
|
}
|
|
|
|
// GetMenus implements MenuController.
|
|
func (m *menuController) GetMenus(ctx *gin.Context) {
|
|
_ = ctx.MustGet("client_id").(string)
|
|
var filter = &query.MenuFilter{
|
|
// ClientID: clientId,
|
|
Name: ctx.Query("name"),
|
|
ParentID: ctx.Query("parent_id"),
|
|
Includes: ctx.QueryArray("includes"),
|
|
}
|
|
filter.BindPagination(ctx)
|
|
ctx.ShouldBindQuery(filter)
|
|
menus, total, err := pagination.PaginatedQueryWithIncludable[query.M_Menu](m.db, filter)
|
|
if err != nil {
|
|
res := utils.BuildResponseFailed(dto.MESSAGE_FAILED_GET_LIST_MENU, err.Error(), nil)
|
|
ctx.JSON(http.StatusBadRequest, res)
|
|
return
|
|
}
|
|
|
|
menuResponses := ToMenuResponses(menus)
|
|
paginationResponse := pagination.CalculatePagination(filter.Pagination, total)
|
|
response := pagination.NewPaginatedResponse(http.StatusOK, dto.MESSAGE_SUCCESS_GET_LIST_MENU, menuResponses, paginationResponse)
|
|
ctx.JSON(http.StatusOK, response)
|
|
}
|
|
|
|
// GetMenuByID implements MenuController.
|
|
func (m *menuController) GetMenuByID(ctx *gin.Context) {
|
|
id := ctx.Param("id")
|
|
if id == "" {
|
|
res := utils.BuildResponseFailed(dto.MESSAGE_FAILED_GET_MENU, "id is required", nil)
|
|
ctx.JSON(http.StatusBadRequest, res)
|
|
return
|
|
}
|
|
|
|
res, err := m.menuService.GetById(ctx.Request.Context(), id)
|
|
if err != nil {
|
|
resErr := utils.BuildResponseFailed(dto.MESSAGE_FAILED_GET_MENU, err.Error(), nil)
|
|
ctx.JSON(http.StatusBadRequest, resErr)
|
|
return
|
|
}
|
|
|
|
resp := utils.BuildResponseSuccess(dto.MESSAGE_SUCCESS_GET_MENU, res)
|
|
ctx.JSON(http.StatusOK, resp)
|
|
}
|
|
|
|
// GetMenuByName implements MenuController.
|
|
func (m *menuController) GetMenuByName(ctx *gin.Context) {
|
|
name := ctx.Query("name")
|
|
if name == "" {
|
|
res := utils.BuildResponseFailed(dto.MESSAGE_FAILED_GET_MENU, "name query is required", nil)
|
|
ctx.JSON(http.StatusBadRequest, res)
|
|
return
|
|
}
|
|
|
|
res, err := m.menuService.GetByName(ctx.Request.Context(), name)
|
|
if err != nil {
|
|
resErr := utils.BuildResponseFailed(dto.MESSAGE_FAILED_GET_MENU, err.Error(), nil)
|
|
ctx.JSON(http.StatusBadRequest, resErr)
|
|
return
|
|
}
|
|
|
|
resp := utils.BuildResponseSuccess(dto.MESSAGE_SUCCESS_GET_MENU, res)
|
|
ctx.JSON(http.StatusOK, resp)
|
|
}
|
|
|
|
// UpdateMenu implements MenuController.
|
|
func (m *menuController) UpdateMenu(ctx *gin.Context) {
|
|
var req dto.MenuUpdateRequest
|
|
if err := ctx.ShouldBind(&req); err != nil {
|
|
res := utils.BuildResponseFailed(dto.MESSAGE_FAILED_GET_DATA_FROM_BODY, err.Error(), nil)
|
|
ctx.AbortWithStatusJSON(http.StatusBadRequest, res)
|
|
return
|
|
}
|
|
|
|
menuId := ctx.Param("id")
|
|
result, err := m.menuService.Update(ctx.Request.Context(), menuId, req)
|
|
if err != nil {
|
|
res := utils.BuildResponseFailed(dto.MESSAGE_FAILED_UPDATE_MENU, err.Error(), nil)
|
|
ctx.JSON(http.StatusBadRequest, res)
|
|
return
|
|
}
|
|
|
|
resp := utils.BuildResponseSuccess(dto.MESSAGE_SUCCESS_UPDATE_MENU, result)
|
|
ctx.JSON(http.StatusOK, resp)
|
|
}
|
|
|
|
// DeleteMenu implements MenuController.
|
|
func (m *menuController) DeleteMenu(ctx *gin.Context) {
|
|
id := ctx.Param("id")
|
|
if id == "" {
|
|
res := utils.BuildResponseFailed(dto.MESSAGE_FAILED_DELETE_MENU, "id is required", nil)
|
|
ctx.JSON(http.StatusBadRequest, res)
|
|
return
|
|
}
|
|
|
|
if err := m.menuService.Delete(ctx.Request.Context(), id); err != nil {
|
|
// if record not found, return 404
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
ctx.JSON(http.StatusNotFound, gin.H{"error": "menu not found"})
|
|
return
|
|
}
|
|
res := utils.BuildResponseFailed(dto.MESSAGE_FAILED_DELETE_MENU, err.Error(), nil)
|
|
ctx.JSON(http.StatusBadRequest, res)
|
|
return
|
|
}
|
|
|
|
resp := utils.BuildResponseSuccess(dto.MESSAGE_SUCCESS_DELETE_MENU, nil)
|
|
ctx.JSON(http.StatusOK, resp)
|
|
}
|
|
|
|
func NewMenuController(i *do.Injector, ms service.MenuService) MenuController {
|
|
db := do.MustInvokeNamed[*gorm.DB](i, constants.DB)
|
|
return &menuController{
|
|
menuService: ms,
|
|
db: db,
|
|
}
|
|
}
|
|
|
|
// Fungsi transform dari entities ke DTO
|
|
func ToMenuResponse(menu query.M_Menu) dto.MenuResponse {
|
|
response := dto.MenuResponse{
|
|
ID: menu.ID.String(),
|
|
Name: menu.Name,
|
|
IconUrl: menu.IconUrl,
|
|
Url: menu.Url,
|
|
Sequence: menu.Sequence,
|
|
Mode: menu.Mode,
|
|
Status: menu.Status,
|
|
}
|
|
// Handle parent jika ada
|
|
if menu.Parent != nil {
|
|
response.Parent = &dto.MenuParentResponse{
|
|
ID: menu.Parent.ID.String(),
|
|
Name: menu.Parent.Name,
|
|
}
|
|
}
|
|
|
|
return response
|
|
}
|
|
|
|
func ToMenuResponses(menus []query.M_Menu) []dto.MenuResponse {
|
|
responses := make([]dto.MenuResponse, len(menus))
|
|
for i, menu := range menus {
|
|
responses[i] = ToMenuResponse(menu)
|
|
}
|
|
return responses
|
|
}
|