动态生成菜单
首先修改 static/config/pear.config.json
文件里面引用的地址
json
"menu": {
"data": "/static/admin/data/menu.json",
"data": "/api/v1/menu",
"method": "GET",
"accordion": true,
"collapse": false,
"control": false,
"controlWidth": 500,
"select": "10",
"select": "126",
"async": true
},
"tab": {
"enable": true,
"keepState": true,
"session": true,
"preload": true,
"max": "30",
"index": {
"id": "10",
"id": "126",
"href": "view/analysis/index.html",
"title": "首页"
}
},
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
编写动态生成菜单的接口。
python
@passport_api.get("/menu")
@jwt_required()
def menus_api():
rights_orm_list = set()
current_user: UserORM = get_current_user()
for role in current_user.role_list:
for rights_orm in role.rights_list:
if rights_orm.type != "auth":
rights_orm_list.add(rights_orm)
rights_list = [rights_orm.menu_json() for rights_orm in rights_orm_list]
rights_list.sort(key=lambda x: (x["pid"], x["id"]), reverse=True)
menu_dict_list = OrderedDict()
for menu_dict in rights_list:
if menu_dict["id"] in menu_dict_list.keys(): # 如果当前节点已经存在与字典中
# 当前节点添加子节点
menu_dict["children"] = deepcopy(menu_dict_list[menu_dict["id"]])
menu_dict["children"].sort(key=lambda item: item["sort"])
# 删除子节点
del menu_dict_list[menu_dict["id"]]
if menu_dict["pid"] not in menu_dict_list:
menu_dict_list[menu_dict["pid"]] = [menu_dict]
else:
menu_dict_list[menu_dict["pid"]].append(menu_dict)
return sorted(menu_dict_list.get(0), key=lambda item: item["sort"])
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
配置文件修改与说明
在说配置文件之前,有三个小优化点需要提前讲一下
可以在 index.html 中给 html 标签添加
lang='zh-CN'
,每次刷新时就不会弹出翻译提示了。对初始化的数据做了一些调整,不影响使用。
flask-jwt-extended 默认过期时间只有十五分钟,应该放到 BaseConfig 当中
pythonclass BaseConfig: SECRET_KEY = os.getenv("SECRET_KEY", "pear-admin-flask") SQLALCHEMY_DATABASE_URI = "" ROOT_PATH = os.path.dirname(os.path.abspath(__file__)) JWT_TOKEN_LOCATION = ["headers"] JWT_ACCESS_TOKEN_EXPIRES = timedelta(days=7)
1
2
3
4
5
6
7
8
9
然后再来看前端的配置文件
json
{
"logo": {
"title": "Pear Admin Flask", // 项目标题
"image": "/static/admin/images/logo.png" // 菜单栏收起时展示的图片
},
"menu": {
"data": "/api/v1/menu", // 菜单的数据接口
"method": "GET",
"accordion": true,
"collapse": false,
"control": false,
"controlWidth": 500,
"select": "10",
"select": "126", // 默认选中的菜单 ID
"async": true
},
"tab": { // tab 标签导航栏
"enable": true,
"keepState": true,
"session": true,
"preload": false,
"max": "30",
"index": { // 默认选中的菜单信息
"id": "126",
"href": "view/analysis/index.html",
"title": "首页"
}
},
"theme": {
"defaultColor": "2", // 默认选中的系统主题色
"defaultColor": "1",
"defaultMenu": "dark-theme",
"defaultHeader": "light-theme",
"allowCustom": true,
"banner": false
},
"colors": [
{
"id": "1",
"color": "#2d8cf0", // 主配色,可以自行调整
"color": "#16baaa",
"second": "#ecf5ff"
},
{
"id": "2",
"color": "#36b368",
"second": "#f0f9eb"
},
{
"id": "3",
"color": "#f6ad55",
"second": "#fdf6ec"
},
{
"id": "4",
"color": "#f56c6c",
"second": "#fef0f0"
},
{
"id": "5",
"color": "#3963bc",
"second": "#ecf5ff"
}
],
"other": {
"keepLoad": "1200",
"autoHead": false,
"footer": false
},
"header": {
"message": "/static/admin/data/message.json"
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73