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