286 lines
7.2 KiB
Go
286 lines
7.2 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"
|
|
staticDto "github.com/Caknoooo/go-gin-clean-starter/pkg/dto"
|
|
"github.com/google/uuid"
|
|
"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
|
|
}
|
|
|
|
// 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 {
|
|
res := dto.MenuResponse{
|
|
ID: entity.ID.String(),
|
|
Name: entity.Name,
|
|
IconUrl: entity.IconUrl,
|
|
Url: entity.Url,
|
|
Sequence: entity.Sequence,
|
|
Mode: entity.Mode,
|
|
Status: entity.Status,
|
|
}
|
|
|
|
if entity.Parent != nil {
|
|
res.Parent = &dto.MenuParentResponse{
|
|
ID: entity.Parent.ID.String(),
|
|
Name: entity.Parent.Name,
|
|
}
|
|
} else if entity.ParentID != nil {
|
|
res.Parent = &dto.MenuParentResponse{ID: entity.ParentID.String()}
|
|
}
|
|
|
|
if len(entity.Permissions) > 0 {
|
|
res.Permissions = make([]staticDto.PermissionResponse, 0, len(entity.Permissions))
|
|
for _, perm := range entity.Permissions {
|
|
res.Permissions = append(res.Permissions, staticDto.PermissionResponse{
|
|
ID: perm.ID.String(),
|
|
Name: perm.Name,
|
|
})
|
|
}
|
|
}
|
|
|
|
responses = append(responses, res)
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
// map back to DTO
|
|
res := dto.MenuResponse{
|
|
ID: created.ID.String(),
|
|
Name: created.Name,
|
|
IconUrl: created.IconUrl,
|
|
Url: created.Url,
|
|
Sequence: created.Sequence,
|
|
Mode: created.Mode,
|
|
Status: created.Status,
|
|
}
|
|
|
|
if created.Parent != nil {
|
|
res.Parent = &dto.MenuParentResponse{
|
|
ID: created.Parent.ID.String(),
|
|
Name: created.Parent.Name,
|
|
}
|
|
} else if created.ParentID != nil {
|
|
res.Parent = &dto.MenuParentResponse{ID: created.ParentID.String()}
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
res := dto.MenuResponse{
|
|
ID: entity.ID.String(),
|
|
Name: entity.Name,
|
|
IconUrl: entity.IconUrl,
|
|
Url: entity.Url,
|
|
Sequence: entity.Sequence,
|
|
Mode: entity.Mode,
|
|
Status: entity.Status,
|
|
}
|
|
|
|
if entity.Parent != nil {
|
|
res.Parent = &dto.MenuParentResponse{
|
|
ID: entity.Parent.ID.String(),
|
|
Name: entity.Parent.Name,
|
|
}
|
|
} else if entity.ParentID != nil {
|
|
res.Parent = &dto.MenuParentResponse{ID: entity.ParentID.String()}
|
|
}
|
|
|
|
if len(entity.Permissions) > 0 {
|
|
res.Permissions = make([]staticDto.PermissionResponse, 0, len(entity.Permissions))
|
|
for _, perm := range entity.Permissions {
|
|
res.Permissions = append(res.Permissions, staticDto.PermissionResponse{
|
|
ID: perm.ID.String(),
|
|
Name: perm.Name,
|
|
// Description: perm.Description,
|
|
// Code: perm.Code,
|
|
})
|
|
}
|
|
}
|
|
return res, 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.MenuResponse{
|
|
ID: entity.ID.String(),
|
|
Name: entity.Name,
|
|
IconUrl: entity.IconUrl,
|
|
Url: entity.Url,
|
|
Sequence: entity.Sequence,
|
|
Mode: entity.Mode,
|
|
Status: entity.Status,
|
|
}
|
|
|
|
if entity.Parent != nil {
|
|
res.Parent = &dto.MenuParentResponse{
|
|
ID: entity.Parent.ID.String(),
|
|
Name: entity.Parent.Name,
|
|
}
|
|
} else if entity.ParentID != nil {
|
|
res.Parent = &dto.MenuParentResponse{ID: entity.ParentID.String()}
|
|
}
|
|
|
|
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.MenuResponse{
|
|
ID: updated.ID.String(),
|
|
Name: updated.Name,
|
|
IconUrl: updated.IconUrl,
|
|
Url: updated.Url,
|
|
Sequence: updated.Sequence,
|
|
Mode: updated.Mode,
|
|
Status: updated.Status,
|
|
}
|
|
|
|
if updated.Parent != nil {
|
|
res.Parent = &dto.MenuParentResponse{
|
|
ID: updated.Parent.ID.String(),
|
|
Name: updated.Parent.Name,
|
|
}
|
|
} else if updated.ParentID != nil {
|
|
res.Parent = &dto.MenuParentResponse{ID: updated.ParentID.String()}
|
|
}
|
|
|
|
return res, nil
|
|
}
|
|
|
|
func NewMenuService(
|
|
menuRepo repository.MenuRepository,
|
|
jwtService service.JWTService,
|
|
db *gorm.DB,
|
|
) MenuService {
|
|
return &menuService{
|
|
menuRepository: menuRepo,
|
|
jwtService: jwtService,
|
|
db: db,
|
|
}
|
|
}
|