menu_controller.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. package controllers
  2. import (
  3. "ems-backend/models"
  4. "fmt"
  5. "net/http"
  6. "sort"
  7. "github.com/gin-gonic/gin"
  8. )
  9. // GetRouters 获取用户路由信息
  10. func GetRouters(c *gin.Context) {
  11. // 1. 获取当前用户(由 Auth middleware 写入 Context)
  12. username := c.GetString("username")
  13. if username == "" {
  14. c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"})
  15. return
  16. }
  17. // 2. 获取用户角色
  18. // 如果是 admin,返回所有菜单
  19. // 否则根据角色关联查询菜单
  20. var menuList []models.SysMenu
  21. if username == "admin" {
  22. models.DB.Order("order_num").Find(&menuList)
  23. // 兜底逻辑:如果 admin 用户没有任何菜单数据,或者数据明显过少(脏数据),尝试初始化
  24. if len(menuList) < 5 {
  25. // 先清空旧数据,防止 ID 冲突或重复
  26. models.DB.Exec("DELETE FROM sys_role_menus")
  27. models.DB.Exec("DELETE FROM sys_menus")
  28. models.InitSysMenuData(models.DB)
  29. models.DB.Order("order_num").Find(&menuList)
  30. }
  31. } else {
  32. // 查找用户 -> 角色 -> 菜单
  33. var user models.User
  34. if err := models.DB.Where("username = ?", username).First(&user).Error; err != nil {
  35. c.JSON(http.StatusUnauthorized, gin.H{"error": "User not found"})
  36. return
  37. }
  38. var menuIds []string
  39. models.DB.Table("sys_role_menus rm").
  40. Select("rm.menu_id").
  41. Joins("JOIN sys_user_roles ur ON ur.role_id = rm.role_id").
  42. Where("ur.user_id = ?", user.ID).
  43. Pluck("rm.menu_id", &menuIds)
  44. if len(menuIds) > 0 {
  45. models.DB.Where("id IN ? AND status = '0'", menuIds).Order("order_num").Find(&menuList)
  46. }
  47. }
  48. // 3. 构建菜单树和权限列表
  49. fmt.Printf("GetRouters: found %d menus for user %s\n", len(menuList), username)
  50. menuTree := buildMenuTree(menuList)
  51. perms := extractPerms(menuList)
  52. c.JSON(http.StatusOK, gin.H{
  53. "menus": menuTree,
  54. "permissions": perms,
  55. })
  56. }
  57. // GetMenuTree 获取所有菜单树(用于角色分配权限)
  58. func GetMenuTree(c *gin.Context) {
  59. var menuList []models.SysMenu
  60. models.DB.Order("order_num").Find(&menuList)
  61. // Convert to tree structure appropriate for frontend tree select
  62. // We can reuse buildMenuTree but ensure we return all fields needed
  63. menuTree := buildMenuTree(menuList)
  64. c.JSON(http.StatusOK, menuTree)
  65. }
  66. // GetRoleMenuIds 获取指定角色的菜单ID集合
  67. func GetRoleMenuIds(c *gin.Context) {
  68. roleId := c.Param("roleId")
  69. var menuIds []string
  70. models.DB.Model(&models.SysRoleMenu{}).
  71. Where("role_id = ?", roleId).
  72. Pluck("menu_id", &menuIds)
  73. c.JSON(http.StatusOK, menuIds)
  74. }
  75. func buildMenuTree(menus []models.SysMenu) []models.SysMenu {
  76. var tree []models.SysMenu
  77. menuMap := make(map[string]*models.SysMenu)
  78. // 1. Initialize map
  79. for i := range menus {
  80. menus[i].Children = []*models.SysMenu{}
  81. menuMap[menus[i].ID.String()] = &menus[i]
  82. }
  83. // 2. Build tree structure
  84. for i := range menus {
  85. menu := &menus[i]
  86. if menu.ParentID != nil {
  87. if parent, ok := menuMap[menu.ParentID.String()]; ok {
  88. parent.Children = append(parent.Children, menu)
  89. }
  90. }
  91. }
  92. // 3. Collect roots
  93. for i := range menus {
  94. if menus[i].ParentID == nil {
  95. tree = append(tree, menus[i])
  96. }
  97. }
  98. // 对每一层的 Children 进行排序
  99. sortChildren(tree)
  100. return tree
  101. }
  102. func sortChildren(menus []models.SysMenu) {
  103. sort.Slice(menus, func(i, j int) bool {
  104. return menus[i].OrderNum < menus[j].OrderNum
  105. })
  106. for _, menu := range menus {
  107. if len(menu.Children) > 0 {
  108. // menu.Children 是 []*SysMenu,需要转换一下才能排序,或者直接用 slice 自定义排序
  109. sortChildrenPtr(menu.Children)
  110. }
  111. }
  112. }
  113. func sortChildrenPtr(menus []*models.SysMenu) {
  114. sort.Slice(menus, func(i, j int) bool {
  115. return menus[i].OrderNum < menus[j].OrderNum
  116. })
  117. for _, menu := range menus {
  118. if len(menu.Children) > 0 {
  119. sortChildrenPtr(menu.Children)
  120. }
  121. }
  122. }
  123. func extractPerms(menus []models.SysMenu) []string {
  124. var perms []string
  125. for _, menu := range menus {
  126. if menu.Perms != "" {
  127. perms = append(perms, menu.Perms)
  128. }
  129. }
  130. return perms
  131. }