在開發過程中經常遇到多級菜單的情況,比如說導航欄、分類欄等等,甚至可以是無限級菜單。
下面是角色的權限控制,根據數據庫控制是否可以查看某個菜單
CREATE TABLE `tb_menus` (
`menu_id` int(11) NOT NULL AUTO_INCREMENT,
`menu_name` varchar(200) NOT NULL,
`menu_level` int(11) NOT NULL,
`superior_menu_id` int(11) NOT NULL,
`menu_url` varchar(200) NOT NULL,
PRIMARY KEY (`menu_id`),
UNIQUE KEY `menu_name` (`menu_name`)
) ENGINE=InnoDB AUTO_INCREMENT=41 DEFAULT CHARSET=utf8
CREATE TABLE `tb_role_menu` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`menu_id` int(11) NOT NULL,
`role_id` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=119 DEFAULT CHARSET=utf8
tb_menus表記錄的是每個菜單,關鍵信息是菜單id和上級菜單id,tb_role_menu記錄的是role_id與menu_id的對應關系,即哪個角色可以訪問哪個菜單
關鍵代碼
# 此處是Django的ORM
def get_menu_tree(role_id):
menus = RoleMenu.objects.filter(role_id=role_id).values('menu_id')
menu_list = list(Menu.objects.filter(menu_id__in=menus).order_by("menu_id").values())
return generate_tree(menu_list, 0)
def generate_tree(menu_list, superior_menu_id, temp_list=None):
if temp_list is None:
temp_list = list()
tree = list()
for menu in menu_list:
if menu["menu_id"] in temp_list:
continue
if menu["superior_menu_id"] == superior_menu_id:
temp_list.append(menu["menu_id"])
menu["under_menu"] = generate_tree(menu_list, menu["menu_id"], temp_list)
tree.append(menu)
return tree
最後得到的數據結構是
res_menu = {
'menu_id': 1, 'menu_name': '權限角色', 'menu_level': 1, 'superior_menu_id': 0, 'menu_url': '',
'under_menu': [
{
},
# 此列表是下級菜單的字典,一直循環所有
]
...
}