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  }