menu.go 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. package service
  2. import (
  3. "dy-admin/internal/pcmserver/global"
  4. "dy-admin/internal/pcmserver/pkg/code"
  5. "dy-admin/internal/pcmserver/sys/model"
  6. "dy-admin/pkg/rescode"
  7. "fmt"
  8. "github.com/pkg/errors"
  9. "gorm.io/gorm"
  10. "strconv"
  11. "strings"
  12. )
  13. type MenuService struct {
  14. }
  15. // GetMenus 获取全部菜单
  16. func (ms *MenuService) GetMenus() (topMenuList []model.Menu, err error) {
  17. treeMap, err := ms.getBaseMenuTreeMap()
  18. if err != nil {
  19. return topMenuList, err
  20. }
  21. // 顶级菜单
  22. topMenuList = treeMap[0]
  23. for i := 0; i < len(topMenuList); i++ {
  24. err = ms.getBaseChildrenList(&topMenuList[i], treeMap)
  25. }
  26. return
  27. }
  28. // GetMenusByRoleIds GetMenuTree 获取角色菜单树
  29. func (ms *MenuService) GetMenusByRoleIds(roleIds []int) (topMenuList []model.Menu, err error) {
  30. treeMap, err := ms.getRoleMenuTreeMap(roleIds)
  31. // 顶级菜单
  32. topMenuList, err = ms.geTopMenus()
  33. if err != nil {
  34. return topMenuList, err
  35. }
  36. for i := 0; i < len(topMenuList); i++ {
  37. err = ms.getBaseChildrenList(&topMenuList[i], treeMap)
  38. }
  39. return
  40. }
  41. func (ms *MenuService) getRoleMenuTreeMap(roleIds []int) (treeMap map[int][]model.Menu, err error) {
  42. var roles []model.Role
  43. treeMap = make(map[int][]model.Menu)
  44. err = global.DB.Preload("SysMenu", func(db *gorm.DB) *gorm.DB {
  45. return db.Where(" menu_type in ('M','C')").Order("sort")
  46. }).Where("role_id in ?", roleIds).Find(&roles).Error
  47. if err != nil {
  48. return treeMap, rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrDatabaseCode])
  49. }
  50. for _, role := range roles {
  51. for _, menu := range role.SysMenu {
  52. treeMap[menu.ParentId] = append(treeMap[menu.ParentId], menu)
  53. }
  54. }
  55. return
  56. }
  57. func (ms *MenuService) geTopMenus() (menus []model.Menu, err error) {
  58. err = global.DB.Where(" menu_type in ('M')").Order("sort").Find(&menus).Error
  59. if err != nil {
  60. return menus, rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrDatabaseCode])
  61. }
  62. return
  63. }
  64. func (ms *MenuService) AddMenu(menu model.Menu) (err error) {
  65. err = global.DB.Where("title = ?", menu.Title).First(&model.Menu{}).Error
  66. if !errors.Is(err, gorm.ErrRecordNotFound) {
  67. msg := fmt.Sprintf("params=>%s", menu.MenuName)
  68. return rescode.RegisterErrorWithMessage(err, msg, code.ErrCodeMap[code.ErrMenuAlreadyExistCode])
  69. }
  70. if menu.Apis != nil && len(menu.Apis) > 0 {
  71. var apis []model.Api
  72. err = global.DB.Model(&model.Api{}).Where("id in ?", menu.Apis).Find(&apis).Error
  73. if err != nil {
  74. return rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrDatabaseCode])
  75. }
  76. menu.SysApi = apis
  77. }
  78. tx := global.DB.Begin()
  79. defer func() {
  80. if err != nil {
  81. tx.Rollback()
  82. } else {
  83. tx.Commit()
  84. }
  85. }()
  86. err = tx.Create(&menu).Error
  87. if err != nil {
  88. return rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrDatabaseCode])
  89. }
  90. if menu.ParentId != 0 {
  91. var parentMenu model.Menu
  92. err = tx.Where("menu_id = ?", menu.ParentId).First(&parentMenu).Error
  93. if err != nil {
  94. return rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrDatabaseCode])
  95. }
  96. if parentMenu.Paths == "" {
  97. return rescode.RegisterErrorWithCause(nil, code.ErrCodeMap[code.ErrParentMenuPathsCode])
  98. }
  99. menu.Paths = parentMenu.Paths + "/" + strconv.Itoa(menu.MenuID)
  100. } else {
  101. menu.Paths = "/0/" + strconv.Itoa(menu.MenuID)
  102. }
  103. err = tx.Model(&menu).Update("paths", menu.Paths).Error
  104. if err != nil {
  105. return rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrDatabaseCode])
  106. }
  107. return
  108. }
  109. // UpdateMenu 更新菜单
  110. func (ms *MenuService) UpdateMenu(menu model.Menu) (err error) {
  111. tx := global.DB.Begin()
  112. defer func() {
  113. if err != nil {
  114. tx.Rollback()
  115. } else {
  116. tx.Commit()
  117. }
  118. }()
  119. // 删除 旧的api关联
  120. var menuData model.Menu
  121. tx.Preload("SysApi").First(&menuData, menu.MenuID)
  122. oldPath := menuData.Paths
  123. err = tx.Model(&menuData).Association("SysApi").Delete(menuData.SysApi)
  124. if err != nil {
  125. return rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrDatabaseCode])
  126. }
  127. // 关联新的
  128. var apiList []model.Api
  129. tx.Where("id in ?", menu.Apis).Find(&apiList)
  130. menu.SysApi = apiList
  131. //更新
  132. err = tx.Model(&menu).Session(&gorm.Session{FullSaveAssociations: true}).Updates(&menu).Error
  133. if err != nil {
  134. return rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrDatabaseCode])
  135. }
  136. if menu.ParentId != 0 {
  137. var parentMenu model.Menu
  138. err = tx.Where("menu_id = ?", menu.ParentId).First(&parentMenu).Error
  139. if err != nil {
  140. return rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrDatabaseCode])
  141. }
  142. if parentMenu.Paths == "" {
  143. return rescode.RegisterErrorWithCause(nil, code.ErrCodeMap[code.ErrParentMenuPathsCode])
  144. }
  145. menu.Paths = parentMenu.Paths + "/" + strconv.Itoa(menu.MenuID)
  146. } else {
  147. menu.Paths = "/0/" + strconv.Itoa(menu.MenuID)
  148. }
  149. // 更新了paths
  150. var menuList []model.Menu
  151. tx.Where("paths like ?", oldPath+"%").Find(&menuList)
  152. for _, v := range menuList {
  153. v.Paths = strings.Replace(v.Paths, oldPath, menu.Paths, 1)
  154. err = tx.Model(&v).Update("paths", v.Paths).Error
  155. if err != nil {
  156. return rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrDatabaseCode])
  157. }
  158. }
  159. return
  160. }
  161. // DeleteMenu 删除菜单
  162. func (ms *MenuService) DeleteMenu(id int) (err error) {
  163. var count int64
  164. err = global.DB.Model(&model.Menu{}).Where("parent_id = ?", id).Count(&count).Error
  165. if count != 0 {
  166. return rescode.RegisterErrorWithCause(nil, code.ErrCodeMap[code.ErrParentHasSonCode])
  167. }
  168. var menu model.Menu
  169. err = global.DB.Preload("SysApi").Where("menu_id = ?", id).First(&menu).Error
  170. if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
  171. return rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrDatabaseCode])
  172. }
  173. // 删除关联数据
  174. var txErr error
  175. tx := global.DB.Begin()
  176. defer func() {
  177. if txErr != nil {
  178. tx.Rollback()
  179. } else {
  180. tx.Commit()
  181. }
  182. }()
  183. txErr = tx.Model(&menu).Association("SysApi").Delete(&menu.SysApi)
  184. if txErr != nil {
  185. return rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrDatabaseCode])
  186. }
  187. txErr = tx.Model(&menu).Delete(&menu, menu.MenuID).Error
  188. if txErr != nil {
  189. return rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrDatabaseCode])
  190. }
  191. return
  192. }
  193. // GetMenuByID 通过id获取菜单
  194. func (ms *MenuService) GetMenuByID(id int) (menu model.Menu, err error) {
  195. treeMap, err := ms.getBaseMenuTreeMap()
  196. if err != nil {
  197. return
  198. }
  199. err = global.DB.Preload("SysApi").Where("menu_id = ?", id).First(&menu).Error
  200. if err != nil {
  201. return menu, rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrDatabaseCode])
  202. }
  203. err = ms.getBaseChildrenList(&menu, treeMap)
  204. if err != nil {
  205. return
  206. }
  207. return
  208. }
  209. func (ms *MenuService) getBaseMenuTreeMap() (treeMap map[int][]model.Menu, err error) {
  210. var allMenus []model.Menu
  211. treeMap = make(map[int][]model.Menu)
  212. err = global.DB.Order("sort").Preload("SysApi").Find(&allMenus).Error
  213. if err != nil {
  214. return treeMap, rescode.RegisterErrorWithCause(err, code.ErrCodeMap[code.ErrDatabaseCode])
  215. }
  216. for _, v := range allMenus {
  217. treeMap[v.ParentId] = append(treeMap[v.ParentId], v)
  218. }
  219. return
  220. }
  221. func (ms *MenuService) getBaseChildrenList(menu *model.Menu, treeMap map[int][]model.Menu) (err error) {
  222. menu.Children = treeMap[menu.MenuID]
  223. for i := 0; i < len(menu.Children); i++ {
  224. err = ms.getBaseChildrenList(&menu.Children[i], treeMap)
  225. }
  226. return err
  227. }