package system import ( "context" "time" ) type MenuButton struct { CreatedAt time.Time UpdatedAt time.Time DeletedAt *time.Time ID uint Name string Description string MenuID uint AuthorityID uint } type MenuParameter struct { CreatedAt time.Time UpdatedAt time.Time DeletedAt *time.Time ID uint MenuID uint Type string Key string Value string } type Menu struct { CreatedAt time.Time UpdatedAt time.Time DeletedAt *time.Time ID uint MenuID uint ParentID uint Path string Name string Hidden bool Component string Sort int ActiveName string KeepAlive bool DefaultMenu bool Title string Icon string CloseTab bool TransitionType string Children []*Menu Buttons []*MenuButton Parameters []*MenuParameter } type MenuRepo interface { Create(context.Context, *Menu) error Update(context.Context, *Menu) error Delete(context.Context, uint) error Find(context.Context, uint) (*Menu, error) List(context.Context) ([]*Menu, error) SetAuthorityMenus(context.Context, uint, []uint) error AuthorityMenuIDs(context.Context, uint) ([]uint, error) // ListAuthorityMenus returns the base menus assigned to the target // authority. Unlike List, it must not apply the current actor's strict // menu filter: the administration endpoint is explicitly querying another // role's assignments. ListAuthorityMenus(context.Context, uint) ([]*Menu, error) MenuRoleIDs(context.Context, uint) ([]uint, error) DefaultRouterRoleIDs(context.Context, uint) ([]uint, error) SetMenuRoles(context.Context, uint, []uint) error } type MenuUsecase struct{ repo MenuRepo } func NewMenuUsecase(repo MenuRepo) *MenuUsecase { return &MenuUsecase{repo: repo} } func (uc *MenuUsecase) List(ctx context.Context) ([]*Menu, error) { return uc.repo.List(ctx) } func (uc *MenuUsecase) Tree(ctx context.Context) ([]*Menu, error) { items, err := uc.repo.List(ctx) if err != nil { return nil, err } byID := make(map[uint]*Menu, len(items)) for _, item := range items { item.Children = nil byID[item.ID] = item } var roots []*Menu for _, item := range items { if parent := byID[item.ParentID]; parent != nil { parent.Children = append(parent.Children, item) } else if item.ParentID == 0 { roots = append(roots, item) } } return roots, nil } func (uc *MenuUsecase) Create(ctx context.Context, menu *Menu) error { return uc.repo.Create(ctx, menu) } func (uc *MenuUsecase) Update(ctx context.Context, menu *Menu) error { return uc.repo.Update(ctx, menu) } func (uc *MenuUsecase) Delete(ctx context.Context, id uint) error { return uc.repo.Delete(ctx, id) } func (uc *MenuUsecase) Find(ctx context.Context, id uint) (*Menu, error) { return uc.repo.Find(ctx, id) } func (uc *MenuUsecase) SetAuthorityMenus(ctx context.Context, authorityID uint, ids []uint) error { return uc.repo.SetAuthorityMenus(ctx, authorityID, ids) } func (uc *MenuUsecase) AuthorityMenus(ctx context.Context, authorityID uint) ([]*Menu, error) { items, err := uc.repo.ListAuthorityMenus(ctx, authorityID) if err != nil { return nil, err } return items, nil } func (uc *MenuUsecase) RoleIDs(ctx context.Context, menuID uint) ([]uint, error) { return uc.repo.MenuRoleIDs(ctx, menuID) } func (uc *MenuUsecase) DefaultRouterRoleIDs(ctx context.Context, menuID uint) ([]uint, error) { return uc.repo.DefaultRouterRoleIDs(ctx, menuID) } func (uc *MenuUsecase) SetRoles(ctx context.Context, menuID uint, ids []uint) error { return uc.repo.SetMenuRoles(ctx, menuID, ids) }