package service import ( "dy-admin/internal/pcmserver/global" "dy-admin/internal/pcmserver/pkg/code" "dy-admin/internal/pcmserver/sys/model" "dy-admin/pkg/rescode" "fmt" "github.com/pkg/errors" "gorm.io/gorm" "strconv" "strings" ) type MenuService struct { } // GetMenus 获取全部菜单 func (ms *MenuService) GetMenus() (topMenuList []model.Menu, err error) { treeMap, err := ms.getBaseMenuTreeMap() if err != nil { return topMenuList, err } // 顶级菜单 topMenuList = treeMap[0] for i := 0; i < len(topMenuList); i++ { err = ms.getBaseChildrenList(&topMenuList[i], treeMap) } return } // GetMenusByRoleIds GetMenuTree 获取角色菜单树 func (ms *MenuService) GetMenusByRoleIds(roleIds []int) (topMenuList []model.Menu, err error) { treeMap, err := ms.getRoleMenuTreeMap(roleIds) // 顶级菜单 topMenuList, err = ms.geTopMenus() if err != nil { return topMenuList, err } for i := 0; i < len(topMenuList); i++ { err = ms.getBaseChildrenList(&topMenuList[i], treeMap) } return } func (ms *MenuService) getRoleMenuTreeMap(roleIds []int) (treeMap map[int][]model.Menu, err error) { var roles []model.Role treeMap = make(map[int][]model.Menu) err = global.DB.Preload("SysMenu", func(db *gorm.DB) *gorm.DB { return db.Where(" menu_type in ('M','C')").Order("sort") }).Where("role_id in ?", roleIds).Find(&roles).Error if err != nil { return treeMap, rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrDatabaseCode]) } for _, role := range roles { for _, menu := range role.SysMenu { treeMap[menu.ParentId] = append(treeMap[menu.ParentId], menu) } } return } func (ms *MenuService) geTopMenus() (menus []model.Menu, err error) { err = global.DB.Where(" menu_type in ('M')").Order("sort").Find(&menus).Error if err != nil { return menus, rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrDatabaseCode]) } return } func (ms *MenuService) AddMenu(menu model.Menu) (err error) { err = global.DB.Where("title = ?", menu.Title).First(&model.Menu{}).Error if !errors.Is(err, gorm.ErrRecordNotFound) { msg := fmt.Sprintf("params=>%s", menu.MenuName) return rescode.RegisterErrorWithMessage(err, msg, code.ErrCodeMap[code.ErrMenuAlreadyExistCode]) } if menu.Apis != nil && len(menu.Apis) > 0 { var apis []model.Api err = global.DB.Model(&model.Api{}).Where("id in ?", menu.Apis).Find(&apis).Error if err != nil { return rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrDatabaseCode]) } menu.SysApi = apis } tx := global.DB.Begin() defer func() { if err != nil { tx.Rollback() } else { tx.Commit() } }() err = tx.Create(&menu).Error if err != nil { return rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrDatabaseCode]) } if menu.ParentId != 0 { var parentMenu model.Menu err = tx.Where("menu_id = ?", menu.ParentId).First(&parentMenu).Error if err != nil { return rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrDatabaseCode]) } if parentMenu.Paths == "" { return rescode.RegisterErrorWithCause(nil, code.ErrCodeMap[code.ErrParentMenuPathsCode]) } menu.Paths = parentMenu.Paths + "/" + strconv.Itoa(menu.MenuID) } else { menu.Paths = "/0/" + strconv.Itoa(menu.MenuID) } err = tx.Model(&menu).Update("paths", menu.Paths).Error if err != nil { return rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrDatabaseCode]) } return } // UpdateMenu 更新菜单 func (ms *MenuService) UpdateMenu(menu model.Menu) (err error) { tx := global.DB.Begin() defer func() { if err != nil { tx.Rollback() } else { tx.Commit() } }() // 删除 旧的api关联 var menuData model.Menu tx.Preload("SysApi").First(&menuData, menu.MenuID) oldPath := menuData.Paths err = tx.Model(&menuData).Association("SysApi").Delete(menuData.SysApi) if err != nil { return rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrDatabaseCode]) } // 关联新的 var apiList []model.Api tx.Where("id in ?", menu.Apis).Find(&apiList) menu.SysApi = apiList //更新 err = tx.Model(&menu).Session(&gorm.Session{FullSaveAssociations: true}).Updates(&menu).Error if err != nil { return rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrDatabaseCode]) } if menu.ParentId != 0 { var parentMenu model.Menu err = tx.Where("menu_id = ?", menu.ParentId).First(&parentMenu).Error if err != nil { return rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrDatabaseCode]) } if parentMenu.Paths == "" { return rescode.RegisterErrorWithCause(nil, code.ErrCodeMap[code.ErrParentMenuPathsCode]) } menu.Paths = parentMenu.Paths + "/" + strconv.Itoa(menu.MenuID) } else { menu.Paths = "/0/" + strconv.Itoa(menu.MenuID) } // 更新了paths var menuList []model.Menu tx.Where("paths like ?", oldPath+"%").Find(&menuList) for _, v := range menuList { v.Paths = strings.Replace(v.Paths, oldPath, menu.Paths, 1) err = tx.Model(&v).Update("paths", v.Paths).Error if err != nil { return rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrDatabaseCode]) } } return } // DeleteMenu 删除菜单 func (ms *MenuService) DeleteMenu(id int) (err error) { var count int64 err = global.DB.Model(&model.Menu{}).Where("parent_id = ?", id).Count(&count).Error if count != 0 { return rescode.RegisterErrorWithCause(nil, code.ErrCodeMap[code.ErrParentHasSonCode]) } var menu model.Menu err = global.DB.Preload("SysApi").Where("menu_id = ?", id).First(&menu).Error if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { return rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrDatabaseCode]) } // 删除关联数据 var txErr error tx := global.DB.Begin() defer func() { if txErr != nil { tx.Rollback() } else { tx.Commit() } }() txErr = tx.Model(&menu).Association("SysApi").Delete(&menu.SysApi) if txErr != nil { return rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrDatabaseCode]) } txErr = tx.Model(&menu).Delete(&menu, menu.MenuID).Error if txErr != nil { return rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrDatabaseCode]) } return } // GetMenuByID 通过id获取菜单 func (ms *MenuService) GetMenuByID(id int) (menu model.Menu, err error) { treeMap, err := ms.getBaseMenuTreeMap() if err != nil { return } err = global.DB.Preload("SysApi").Where("menu_id = ?", id).First(&menu).Error if err != nil { return menu, rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrDatabaseCode]) } err = ms.getBaseChildrenList(&menu, treeMap) if err != nil { return } return } func (ms *MenuService) getBaseMenuTreeMap() (treeMap map[int][]model.Menu, err error) { var allMenus []model.Menu treeMap = make(map[int][]model.Menu) err = global.DB.Order("sort").Preload("SysApi").Find(&allMenus).Error if err != nil { return treeMap, rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrDatabaseCode]) } for _, v := range allMenus { treeMap[v.ParentId] = append(treeMap[v.ParentId], v) } return } func (ms *MenuService) getBaseChildrenList(menu *model.Menu, treeMap map[int][]model.Menu) (err error) { menu.Children = treeMap[menu.MenuID] for i := 0; i < len(menu.Children); i++ { err = ms.getBaseChildrenList(&menu.Children[i], treeMap) } return err }