Files
server/app/services/tree_service.go
T
2026-01-16 15:49:34 +08:00

115 lines
3.1 KiB
Go

package services
import (
"github.com/goravel/framework/facades"
"goravel/app/models"
)
type TreeService interface {
// BuildMenuTree 构建菜单树形结构
BuildMenuTree(parentID uint) ([]models.Menu, error)
// BuildDepartmentTree 构建部门树形结构
BuildDepartmentTree(parentID uint) ([]models.Department, error)
// HasMenuChildren 检查菜单是否有子节点
HasMenuChildren(menuID uint) (bool, error)
// HasDepartmentChildren 检查部门是否有子节点
HasDepartmentChildren(departmentID uint) (bool, error)
// GetMenuChildrenIDs 获取菜单及其所有子菜单的ID列表
GetMenuChildrenIDs(menuID uint) ([]uint, error)
}
type TreeServiceImpl struct {
}
func NewTreeServiceImpl() *TreeServiceImpl {
return &TreeServiceImpl{}
}
// BuildMenuTree 构建菜单树形结构
func (s *TreeServiceImpl) BuildMenuTree(parentID uint) ([]models.Menu, error) {
var menus []models.Menu
if err := facades.Orm().Query().Where("parent_id", parentID).Order("sort asc, id asc").Get(&menus); err != nil {
return nil, err
}
// 递归加载子菜单
for i := range menus {
children, err := s.BuildMenuTree(menus[i].ID)
if err != nil {
return nil, err
}
menus[i].Children = children
}
return menus, nil
}
// BuildDepartmentTree 构建部门树形结构
func (s *TreeServiceImpl) BuildDepartmentTree(parentID uint) ([]models.Department, error) {
var departments []models.Department
if err := facades.Orm().Query().Where("parent_id", parentID).Order("sort asc, id asc").Get(&departments); err != nil {
return nil, err
}
// 递归加载子部门
for i := range departments {
children, err := s.BuildDepartmentTree(departments[i].ID)
if err != nil {
return nil, err
}
departments[i].Children = children
}
return departments, nil
}
// HasMenuChildren 检查菜单是否有子节点
func (s *TreeServiceImpl) HasMenuChildren(menuID uint) (bool, error) {
count, err := facades.Orm().Query().Model(&models.Menu{}).Where("parent_id", menuID).Count()
if err != nil {
return false, err
}
return count > 0, nil
}
// HasDepartmentChildren 检查部门是否有子节点
func (s *TreeServiceImpl) HasDepartmentChildren(departmentID uint) (bool, error) {
count, err := facades.Orm().Query().Model(&models.Department{}).Where("parent_id", departmentID).Count()
if err != nil {
return false, err
}
return count > 0, nil
}
// GetMenuChildrenIDs 获取菜单及其所有子菜单的ID列表(递归)
func (s *TreeServiceImpl) GetMenuChildrenIDs(menuID uint) ([]uint, error) {
var menuIDs []uint
menuIDs = append(menuIDs, menuID)
// 递归获取所有子菜单ID
var getChildren func(parentID uint) error
getChildren = func(parentID uint) error {
var children []models.Menu
if err := facades.Orm().Query().Model(&models.Menu{}).Where("parent_id", parentID).Select("id").Get(&children); err != nil {
return err
}
for _, child := range children {
menuIDs = append(menuIDs, child.ID)
// 递归获取子菜单的子菜单
if err := getChildren(child.ID); err != nil {
return err
}
}
return nil
}
if err := getChildren(menuID); err != nil {
return nil, err
}
return menuIDs, nil
}