wms-be/modules/menu/service/menu_service.go

177 lines
4.4 KiB
Go

package service
import (
"context"
"errors"
"github.com/Caknoooo/go-gin-clean-starter/database/entities"
"github.com/Caknoooo/go-gin-clean-starter/modules/auth/service"
"github.com/Caknoooo/go-gin-clean-starter/modules/menu/dto"
"github.com/Caknoooo/go-gin-clean-starter/modules/menu/repository"
"github.com/google/uuid"
"github.com/sirupsen/logrus"
"gorm.io/gorm"
)
type MenuService interface {
Create(ctx context.Context, menu dto.MenuResponse) (dto.MenuResponse, error)
GetById(ctx context.Context, menuId string) (dto.MenuResponse, error)
GetByName(ctx context.Context, name string) (dto.MenuResponse, error)
Update(ctx context.Context, menuId string, menu dto.MenuUpdateRequest) (dto.MenuResponse, error)
GetAll(ctx context.Context) ([]dto.MenuResponse, error)
Delete(ctx context.Context, menuId string) error
}
type menuService struct {
menuRepository repository.MenuRepository
jwtService service.JWTService
db *gorm.DB
log *logrus.Logger
}
// GetAll implements MenuService.
func (m *menuService) GetAll(ctx context.Context) ([]dto.MenuResponse, error) {
entities, err := m.menuRepository.GetAll(ctx, m.db)
if err != nil {
return nil, err
}
responses := make([]dto.MenuResponse, 0, len(entities))
for _, entity := range entities {
responses = append(responses, dto.ToMenuResponse(entity))
}
return responses, nil
}
// Create implements MenuService.
func (m *menuService) Create(ctx context.Context, menu dto.MenuResponse) (dto.MenuResponse, error) {
var entity entities.M_Menu
// ID: use provided or generate new
if menu.ID != "" {
id, err := uuid.Parse(menu.ID)
if err != nil {
return dto.MenuResponse{}, err
}
entity.ID = id
} else {
entity.ID = uuid.New()
}
// map simple fields
entity.Name = menu.Name
entity.IconUrl = menu.IconUrl
entity.Url = menu.Url
entity.Sequence = menu.Sequence
entity.Mode = menu.Mode
entity.Status = menu.Status
// ParentID if provided
if menu.Parent != nil && menu.Parent.ID != "" {
pid, err := uuid.Parse(menu.Parent.ID)
if err != nil {
return dto.MenuResponse{}, err
}
entity.ParentID = &pid
} else {
entity.ParentID = nil
}
created, err := m.menuRepository.Create(ctx, m.db, entity)
if err != nil {
return dto.MenuResponse{}, err
}
res := dto.ToMenuResponse(created)
return res, nil
}
// Delete implements MenuService.
func (m *menuService) Delete(ctx context.Context, menuId string) error {
return m.menuRepository.Delete(ctx, m.db, menuId)
}
// GetById implements MenuService.
func (m *menuService) GetById(ctx context.Context, menuId string) (dto.MenuResponse, error) {
entity, err := m.menuRepository.GetById(ctx, m.db, menuId)
if err != nil {
return dto.MenuResponse{}, err
}
return dto.ToMenuResponse(entity), nil
}
// GetByName implements MenuService.
func (m *menuService) GetByName(ctx context.Context, name string) (dto.MenuResponse, error) {
entity, err := m.menuRepository.GetByName(ctx, m.db, name)
if err != nil {
return dto.MenuResponse{}, err
}
res := dto.ToMenuResponse(entity)
return res, nil
}
// Update implements MenuService.
func (m *menuService) Update(ctx context.Context, menuId string, menu dto.MenuUpdateRequest) (dto.MenuResponse, error) {
existing, err := m.menuRepository.GetById(ctx, m.db, menuId)
if err != nil {
return dto.MenuResponse{}, dto.ErrMenuNotFound
}
if menu.Name != "" {
menuByName, err := m.menuRepository.GetByName(ctx, m.db, menu.Name)
if err == nil && menuByName.ID != existing.ID {
return dto.MenuResponse{}, errors.New("menu name already exists")
}
existing.Name = menu.Name
}
if menu.IconUrl != "" {
existing.IconUrl = menu.IconUrl
}
if menu.Url != "" {
existing.Url = menu.Url
}
if menu.Mode != "" {
existing.Mode = menu.Mode
}
if menu.Status != "" {
existing.Status = menu.Status
}
if menu.Sequence != 0 {
existing.Sequence = menu.Sequence
}
if menu.ParentID != nil {
pid := *menu.ParentID
existing.ParentID = &pid
} else {
existing.ParentID = nil
}
updated, err := m.menuRepository.Update(ctx, m.db, existing)
if err != nil {
return dto.MenuResponse{}, err
}
res := dto.ToMenuResponse(updated)
return res, nil
}
func NewMenuService(
menuRepo repository.MenuRepository,
jwtService service.JWTService,
db *gorm.DB,
log *logrus.Logger,
) MenuService {
return &menuService{
menuRepository: menuRepo,
jwtService: jwtService,
db: db,
log: log,
}
}