// Copyright 2019 GoAdmin Core Team. All rights reserved. // Use of this source code is governed by a Apache-2.0 style // license that can be found in the LICENSE file. package menu import ( "html/template" "regexp" "strconv" "strings" "github.com/GoAdminGroup/go-admin/modules/db/dialect" "github.com/GoAdminGroup/go-admin/modules/db" "github.com/GoAdminGroup/go-admin/modules/language" "github.com/GoAdminGroup/go-admin/plugins/admin/models" ) // Item is an menu item. type Item struct { Name string `json:"name"` ID string `json:"id"` Url string `json:"url"` IsLinkUrl bool `json:"isLinkUrl"` Icon string `json:"icon"` Header string `json:"header"` Active string `json:"active"` ChildrenList []Item `json:"childrenList"` } // Menu contains list of menu items and other info. type Menu struct { List []Item `json:"list"` Options []map[string]string `json:"options"` MaxOrder int64 `json:"maxOrder"` PluginName string `json:"pluginName"` ForceUpdate bool `json:"forceUpdate"` } func (menu *Menu) GetUpdateJS(updateFlag bool) template.JS { if !updateFlag { return "" } forceUpdate := "false" if menu.ForceUpdate { forceUpdate = "true" } return template.JS(`$(function () { let curMenuPlug = $(".main-sidebar section.sidebar ul.sidebar-menu").attr("data-plug"); if (curMenuPlug !== '` + menu.PluginName + `' || ` + forceUpdate + `) { $(".main-sidebar section.sidebar").html($("#sidebar-menu-tmpl").html()) } });`) } // SetMaxOrder set the max order of menu. func (menu *Menu) SetMaxOrder(order int64) { menu.MaxOrder = order } // AddMaxOrder add the max order of menu. func (menu *Menu) AddMaxOrder() { menu.MaxOrder++ } // SetActiveClass set the active class of menu. func (menu *Menu) SetActiveClass(path string) *Menu { reg, _ := regexp.Compile(`\?(.*)`) path = reg.ReplaceAllString(path, "") for i := 0; i < len(menu.List); i++ { menu.List[i].Active = "" } for i := 0; i < len(menu.List); i++ { if menu.List[i].Url == path && len(menu.List[i].ChildrenList) == 0 { menu.List[i].Active = "active" return menu } for j := 0; j < len(menu.List[i].ChildrenList); j++ { if menu.List[i].ChildrenList[j].Url == path { menu.List[i].Active = "active" menu.List[i].ChildrenList[j].Active = "active" return menu } menu.List[i].Active = "" menu.List[i].ChildrenList[j].Active = "" } } return menu } // FormatPath get template.HTML for front-end. func (menu Menu) FormatPath() template.HTML { res := template.HTML(``) for i := 0; i < len(menu.List); i++ { if menu.List[i].Active != "" { if menu.List[i].Url != "#" && menu.List[i].Url != "" && len(menu.List[i].ChildrenList) > 0 { res += template.HTML(`
  • ` + menu.List[i].Name + `
  • `) } else { res += template.HTML(`
  • ` + menu.List[i].Name + `
  • `) if len(menu.List[i].ChildrenList) == 0 { return res } } for j := 0; j < len(menu.List[i].ChildrenList); j++ { if menu.List[i].ChildrenList[j].Active != "" { return res + template.HTML(`
  • `+menu.List[i].ChildrenList[j].Name+`
  • `) } } } } return res } // GetEditMenuList return menu items list. func (menu *Menu) GetEditMenuList() []Item { return menu.List } type NewMenuData struct { ParentId int64 `json:"parent_id"` Type int64 `json:"type"` Order int64 `json:"order"` Title string `json:"title"` Icon string `json:"icon"` PluginName string `json:"plugin_name"` Uri string `json:"uri"` Header string `json:"header"` Uuid string `json:"uuid"` } func NewMenu(conn db.Connection, data NewMenuData) (int64, error) { maxOrder := data.Order checkOrder, _ := db.WithDriver(conn).Table("goadmin_menu"). Where("plugin_name", "=", data.PluginName). OrderBy("order", "desc"). First() if checkOrder != nil { maxOrder = checkOrder["order"].(int64) } id, err := db.WithDriver(conn).Table("goadmin_menu"). Insert(dialect.H{ "parent_id": data.ParentId, "type": data.Type, "order": maxOrder, "title": data.Title, "uuid": data.Uuid, "icon": data.Icon, "plugin_name": data.PluginName, "uri": data.Uri, "header": data.Header, }) if !db.CheckError(err, db.INSERT) { return id, nil } return id, err } // GetGlobalMenu return Menu of given user model. func GetGlobalMenu(user models.UserModel, conn db.Connection, lang string, pluginNames ...string) *Menu { var ( menus []map[string]interface{} menuOption = make([]map[string]string, 0) plugName = "" ) if len(pluginNames) > 0 { plugName = pluginNames[0] } user.WithRoles().WithMenus() if user.IsSuperAdmin() { menus, _ = db.WithDriver(conn).Table("goadmin_menu"). Where("id", ">", 0). Where("plugin_name", "=", plugName). OrderBy("order", "asc"). All() } else { var ids []interface{} for i := 0; i < len(user.MenuIds); i++ { ids = append(ids, user.MenuIds[i]) } menus, _ = db.WithDriver(conn).Table("goadmin_menu"). WhereIn("id", ids). Where("plugin_name", "=", plugName). OrderBy("order", "asc"). All() } var title string for i := 0; i < len(menus); i++ { title = language.GetWithLang(menus[i]["title"].(string), lang) menuOption = append(menuOption, map[string]string{ "id": strconv.FormatInt(menus[i]["id"].(int64), 10), "title": title, }) } menuList := constructMenuTree(menus, 0, lang) maxOrder := int64(0) if len(menus) > 0 { maxOrder = menus[len(menus)-1]["parent_id"].(int64) } return &Menu{ List: menuList, Options: menuOption, MaxOrder: maxOrder, PluginName: plugName, } } func constructMenuTree(menus []map[string]interface{}, parentID int64, lang string) []Item { branch := make([]Item, 0) var title string for j := 0; j < len(menus); j++ { if parentID == menus[j]["parent_id"].(int64) { if menus[j]["type"].(int64) == 1 { title = language.Get(menus[j]["title"].(string)) } else { title = menus[j]["title"].(string) } header, _ := menus[j]["header"].(string) uri := menus[j]["uri"].(string) if lang != "" { if strings.Contains(uri, "?") { uri += "&__ga_lang=" + lang } else { uri += "?__ga_lang=" + lang } } child := Item{ Name: title, ID: strconv.FormatInt(menus[j]["id"].(int64), 10), Url: uri, Icon: menus[j]["icon"].(string), Header: header, Active: "", ChildrenList: constructMenuTree(menus, menus[j]["id"].(int64), lang), } branch = append(branch, child) } } return branch }