/modules/menu/menu.go

https://github.com/GoAdminGroup/go-admin · Go · 261 lines · 234 code · 18 blank · 9 comment · 11 complexity · 535db9a5238474db036a8d17fa89ee15 MD5 · raw file

  1. // Copyright 2019 GoAdmin Core Team. All rights reserved.
  2. // Use of this source code is governed by a Apache-2.0 style
  3. // license that can be found in the LICENSE file.
  4. package menu
  5. import (
  6. "html/template"
  7. "regexp"
  8. "strconv"
  9. "github.com/GoAdminGroup/go-admin/modules/db/dialect"
  10. "github.com/GoAdminGroup/go-admin/modules/db"
  11. "github.com/GoAdminGroup/go-admin/modules/language"
  12. "github.com/GoAdminGroup/go-admin/plugins/admin/models"
  13. )
  14. // Item is an menu item.
  15. type Item struct {
  16. Name string `json:"name"`
  17. ID string `json:"id"`
  18. Url string `json:"url"`
  19. IsLinkUrl bool `json:"isLinkUrl"`
  20. Icon string `json:"icon"`
  21. Header string `json:"header"`
  22. Active string `json:"active"`
  23. ChildrenList []Item `json:"childrenList"`
  24. }
  25. // Menu contains list of menu items and other info.
  26. type Menu struct {
  27. List []Item `json:"list"`
  28. Options []map[string]string `json:"options"`
  29. MaxOrder int64 `json:"maxOrder"`
  30. PluginName string `json:"pluginName"`
  31. ForceUpdate bool `json:"forceUpdate"`
  32. }
  33. func (menu *Menu) GetUpdateJS(updateFlag bool) template.JS {
  34. if !updateFlag {
  35. return ""
  36. }
  37. forceUpdate := "false"
  38. if menu.ForceUpdate {
  39. forceUpdate = "true"
  40. }
  41. return template.JS(`$(function () {
  42. let curMenuPlug = $(".main-sidebar section.sidebar ul.sidebar-menu").attr("data-plug");
  43. if (curMenuPlug !== '` + menu.PluginName + `' || ` + forceUpdate + `) {
  44. $(".main-sidebar section.sidebar").html($("#sidebar-menu-tmpl").html())
  45. }
  46. });`)
  47. }
  48. // SetMaxOrder set the max order of menu.
  49. func (menu *Menu) SetMaxOrder(order int64) {
  50. menu.MaxOrder = order
  51. }
  52. // AddMaxOrder add the max order of menu.
  53. func (menu *Menu) AddMaxOrder() {
  54. menu.MaxOrder++
  55. }
  56. // SetActiveClass set the active class of menu.
  57. func (menu *Menu) SetActiveClass(path string) *Menu {
  58. reg, _ := regexp.Compile(`\?(.*)`)
  59. path = reg.ReplaceAllString(path, "")
  60. for i := 0; i < len(menu.List); i++ {
  61. menu.List[i].Active = ""
  62. }
  63. for i := 0; i < len(menu.List); i++ {
  64. if menu.List[i].Url == path && len(menu.List[i].ChildrenList) == 0 {
  65. menu.List[i].Active = "active"
  66. return menu
  67. }
  68. for j := 0; j < len(menu.List[i].ChildrenList); j++ {
  69. if menu.List[i].ChildrenList[j].Url == path {
  70. menu.List[i].Active = "active"
  71. menu.List[i].ChildrenList[j].Active = "active"
  72. return menu
  73. }
  74. menu.List[i].Active = ""
  75. menu.List[i].ChildrenList[j].Active = ""
  76. }
  77. }
  78. return menu
  79. }
  80. // FormatPath get template.HTML for front-end.
  81. func (menu Menu) FormatPath() template.HTML {
  82. res := template.HTML(``)
  83. for i := 0; i < len(menu.List); i++ {
  84. if menu.List[i].Active != "" {
  85. if menu.List[i].Url != "#" && menu.List[i].Url != "" && len(menu.List[i].ChildrenList) > 0 {
  86. res += template.HTML(`<li><a href="` + menu.List[i].Url + `">` + menu.List[i].Name + `</a></li>`)
  87. } else {
  88. res += template.HTML(`<li>` + menu.List[i].Name + `</li>`)
  89. if len(menu.List[i].ChildrenList) == 0 {
  90. return res
  91. }
  92. }
  93. for j := 0; j < len(menu.List[i].ChildrenList); j++ {
  94. if menu.List[i].ChildrenList[j].Active != "" {
  95. return res + template.HTML(`<li>`+menu.List[i].ChildrenList[j].Name+`</li>`)
  96. }
  97. }
  98. }
  99. }
  100. return res
  101. }
  102. // GetEditMenuList return menu items list.
  103. func (menu *Menu) GetEditMenuList() []Item {
  104. return menu.List
  105. }
  106. type NewMenuData struct {
  107. ParentId int64 `json:"parent_id"`
  108. Type int64 `json:"type"`
  109. Order int64 `json:"order"`
  110. Title string `json:"title"`
  111. Icon string `json:"icon"`
  112. PluginName string `json:"plugin_name"`
  113. Uri string `json:"uri"`
  114. Header string `json:"header"`
  115. Uuid string `json:"uuid"`
  116. }
  117. func NewMenu(conn db.Connection, data NewMenuData) (int64, error) {
  118. maxOrder := data.Order
  119. checkOrder, _ := db.WithDriver(conn).Table("goadmin_menu").
  120. Where("plugin_name", "=", data.PluginName).
  121. OrderBy("order", "desc").
  122. First()
  123. if checkOrder != nil {
  124. maxOrder = checkOrder["order"].(int64)
  125. }
  126. id, err := db.WithDriver(conn).Table("goadmin_menu").
  127. Insert(dialect.H{
  128. "parent_id": data.ParentId,
  129. "type": data.Type,
  130. "order": maxOrder,
  131. "title": data.Title,
  132. "uuid": data.Uuid,
  133. "icon": data.Icon,
  134. "plugin_name": data.PluginName,
  135. "uri": data.Uri,
  136. "header": data.Header,
  137. })
  138. if !db.CheckError(err, db.INSERT) {
  139. return id, nil
  140. }
  141. return id, err
  142. }
  143. // GetGlobalMenu return Menu of given user model.
  144. func GetGlobalMenu(user models.UserModel, conn db.Connection, pluginNames ...string) *Menu {
  145. var (
  146. menus []map[string]interface{}
  147. menuOption = make([]map[string]string, 0)
  148. plugName = ""
  149. )
  150. if len(pluginNames) > 0 {
  151. plugName = pluginNames[0]
  152. }
  153. user.WithRoles().WithMenus()
  154. if user.IsSuperAdmin() {
  155. menus, _ = db.WithDriver(conn).Table("goadmin_menu").
  156. Where("id", ">", 0).
  157. Where("plugin_name", "=", plugName).
  158. OrderBy("order", "asc").
  159. All()
  160. } else {
  161. var ids []interface{}
  162. for i := 0; i < len(user.MenuIds); i++ {
  163. ids = append(ids, user.MenuIds[i])
  164. }
  165. menus, _ = db.WithDriver(conn).Table("goadmin_menu").
  166. WhereIn("id", ids).
  167. Where("plugin_name", "=", plugName).
  168. OrderBy("order", "asc").
  169. All()
  170. }
  171. var title string
  172. for i := 0; i < len(menus); i++ {
  173. if menus[i]["type"].(int64) == 1 {
  174. title = language.Get(menus[i]["title"].(string))
  175. } else {
  176. title = menus[i]["title"].(string)
  177. }
  178. menuOption = append(menuOption, map[string]string{
  179. "id": strconv.FormatInt(menus[i]["id"].(int64), 10),
  180. "title": title,
  181. })
  182. }
  183. menuList := constructMenuTree(menus, 0)
  184. maxOrder := int64(0)
  185. if len(menus) > 0 {
  186. maxOrder = menus[len(menus)-1]["parent_id"].(int64)
  187. }
  188. return &Menu{
  189. List: menuList,
  190. Options: menuOption,
  191. MaxOrder: maxOrder,
  192. PluginName: plugName,
  193. }
  194. }
  195. func constructMenuTree(menus []map[string]interface{}, parentID int64) []Item {
  196. branch := make([]Item, 0)
  197. var title string
  198. for j := 0; j < len(menus); j++ {
  199. if parentID == menus[j]["parent_id"].(int64) {
  200. if menus[j]["type"].(int64) == 1 {
  201. title = language.Get(menus[j]["title"].(string))
  202. } else {
  203. title = menus[j]["title"].(string)
  204. }
  205. header, _ := menus[j]["header"].(string)
  206. child := Item{
  207. Name: title,
  208. ID: strconv.FormatInt(menus[j]["id"].(int64), 10),
  209. Url: menus[j]["uri"].(string),
  210. Icon: menus[j]["icon"].(string),
  211. Header: header,
  212. Active: "",
  213. ChildrenList: constructMenuTree(menus, menus[j]["id"].(int64)),
  214. }
  215. branch = append(branch, child)
  216. }
  217. }
  218. return branch
  219. }