@befly-addon/admin 1.0.12 → 1.0.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/addon.config.json +0 -1
- package/apis/admin/list.ts +1 -6
- package/apis/dashboard/environmentInfo.ts +2 -5
- package/apis/dict/list.ts +1 -4
- package/apis/menu/list.ts +1 -4
- package/package.json +3 -8
- package/tables/admin.json +7 -81
- package/tables/api.json +5 -42
- package/tables/dict.json +5 -40
- package/tables/menu.json +5 -35
- package/tables/role.json +5 -43
- package/util.ts +57 -61
- package/views/admin/components/edit.vue +1 -1
- package/views/admin/components/role.vue +2 -2
- package/views/admin/index.vue +5 -5
- package/views/dict/index.vue +2 -2
- package/views/index/components/addonList.vue +1 -2
- package/views/index/components/environmentInfo.vue +1 -1
- package/views/index/components/operationLogs.vue +2 -2
- package/views/index/components/performanceMetrics.vue +2 -2
- package/views/index/components/serviceStatus.vue +2 -2
- package/views/index/components/systemNotifications.vue +6 -6
- package/views/index/components/systemOverview.vue +2 -2
- package/views/index/components/systemResources.vue +4 -4
- package/views/index/index.vue +3 -0
- package/views/menu/index.vue +3 -3
- package/views/role/index.vue +2 -2
- package/views/user/index.vue +3 -3
- /package/views/login/{index.vue → index_1.vue} +0 -0
package/addon.config.json
CHANGED
package/apis/admin/list.ts
CHANGED
|
@@ -1,13 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
* 获取管理员列表
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { Yes } from 'befly';
|
|
1
|
+
import { Yes } from 'befly';
|
|
6
2
|
|
|
7
3
|
export default {
|
|
8
4
|
name: '获取管理员列表',
|
|
9
5
|
handler: async (befly, ctx) => {
|
|
10
|
-
// 查询所有管理员(框架自动排除password字段,自动转换字段名为小驼峰)
|
|
11
6
|
const result = await befly.db.getList({
|
|
12
7
|
table: 'addon_admin_admin',
|
|
13
8
|
page: ctx.body.page || 1,
|
|
@@ -11,11 +11,8 @@ export default {
|
|
|
11
11
|
// 获取数据库版本
|
|
12
12
|
let databaseVersion = 'Unknown';
|
|
13
13
|
try {
|
|
14
|
-
const versionResult = await befly.db.query(
|
|
15
|
-
|
|
16
|
-
type: 'one'
|
|
17
|
-
});
|
|
18
|
-
databaseVersion = versionResult.version || 'Unknown';
|
|
14
|
+
const versionResult = await befly.db.query('SELECT VERSION() as version');
|
|
15
|
+
databaseVersion = versionResult?.[0]?.version || 'Unknown';
|
|
19
16
|
} catch (error) {
|
|
20
17
|
// 忽略错误
|
|
21
18
|
}
|
package/apis/dict/list.ts
CHANGED
|
@@ -7,10 +7,7 @@ export default {
|
|
|
7
7
|
fields: ['id', 'name', 'code', 'value', 'sort', 'pid', 'description', 'state', 'created_at', 'updated_at'],
|
|
8
8
|
page: ctx.body.page,
|
|
9
9
|
limit: ctx.body.limit,
|
|
10
|
-
orderBy: [
|
|
11
|
-
{ field: 'sort', direction: 'ASC' },
|
|
12
|
-
{ field: 'id', direction: 'ASC' }
|
|
13
|
-
]
|
|
10
|
+
orderBy: ['sort#ASC', 'id#ASC']
|
|
14
11
|
});
|
|
15
12
|
|
|
16
13
|
return Yes('操作成功', result);
|
package/apis/menu/list.ts
CHANGED
|
@@ -6,10 +6,7 @@ export default {
|
|
|
6
6
|
const menus = await befly.db.getAll({
|
|
7
7
|
table: 'addon_admin_menu',
|
|
8
8
|
fields: ['id', 'name', 'path', 'icon', 'sort', 'pid', 'state', 'created_at', 'updated_at'],
|
|
9
|
-
orderBy: [
|
|
10
|
-
{ field: 'sort', direction: 'ASC' },
|
|
11
|
-
{ field: 'id', direction: 'ASC' }
|
|
12
|
-
]
|
|
9
|
+
orderBy: ['sort#ASC', 'id#ASC']
|
|
13
10
|
});
|
|
14
11
|
|
|
15
12
|
return Yes('操作成功', menus);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@befly-addon/admin",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.14",
|
|
4
4
|
"description": "Befly - 管理后台功能组件",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"private": false,
|
|
@@ -38,13 +38,8 @@
|
|
|
38
38
|
"url": "https://github.com/chenbimo/befly.git",
|
|
39
39
|
"directory": "packages/addon-admin"
|
|
40
40
|
},
|
|
41
|
-
"gitHead": "
|
|
41
|
+
"gitHead": "c3ad67d081d15ca86b8545e622ed96255524183a",
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"befly": "3.8.
|
|
44
|
-
},
|
|
45
|
-
"devDependencies": {
|
|
46
|
-
"@module-federation/vite": "^1.9.0",
|
|
47
|
-
"@vitejs/plugin-vue": "^6.0.1",
|
|
48
|
-
"rolldown-vite": "^7.2.2"
|
|
43
|
+
"befly": "3.8.5"
|
|
49
44
|
}
|
|
50
45
|
}
|
package/tables/admin.json
CHANGED
|
@@ -1,158 +1,84 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": {
|
|
3
3
|
"name": "姓名",
|
|
4
|
-
"detail": "",
|
|
5
4
|
"type": "string",
|
|
6
5
|
"min": 2,
|
|
7
|
-
"max": 50
|
|
8
|
-
"default": null,
|
|
9
|
-
"index": false,
|
|
10
|
-
"unique": false,
|
|
11
|
-
"nullable": false,
|
|
12
|
-
"unsigned": true,
|
|
13
|
-
"regexp": null
|
|
6
|
+
"max": 50
|
|
14
7
|
},
|
|
15
8
|
"nickname": {
|
|
16
9
|
"name": "昵称",
|
|
17
|
-
"detail": "",
|
|
18
10
|
"type": "string",
|
|
19
11
|
"min": 2,
|
|
20
|
-
"max": 50
|
|
21
|
-
"default": null,
|
|
22
|
-
"index": false,
|
|
23
|
-
"unique": false,
|
|
24
|
-
"nullable": false,
|
|
25
|
-
"unsigned": true,
|
|
26
|
-
"regexp": null
|
|
12
|
+
"max": 50
|
|
27
13
|
},
|
|
28
14
|
"email": {
|
|
29
15
|
"name": "邮箱",
|
|
30
|
-
"detail": "",
|
|
31
16
|
"type": "string",
|
|
32
17
|
"min": 5,
|
|
33
18
|
"max": 100,
|
|
34
|
-
"default": null,
|
|
35
19
|
"index": true,
|
|
36
|
-
"unique": false,
|
|
37
|
-
"nullable": false,
|
|
38
|
-
"unsigned": true,
|
|
39
20
|
"regexp": "^[\\w.-]+@[\\w.-]+\\.\\w+$"
|
|
40
21
|
},
|
|
41
22
|
"phone": {
|
|
42
23
|
"name": "手机号",
|
|
43
|
-
"detail": "",
|
|
44
24
|
"type": "string",
|
|
45
25
|
"min": 11,
|
|
46
26
|
"max": 11,
|
|
47
|
-
"default": null,
|
|
48
|
-
"index": false,
|
|
49
|
-
"unique": false,
|
|
50
|
-
"nullable": false,
|
|
51
|
-
"unsigned": true,
|
|
52
27
|
"regexp": "^1[3-9]\\d{9}$"
|
|
53
28
|
},
|
|
54
29
|
"username": {
|
|
55
30
|
"name": "用户名",
|
|
56
|
-
"detail": "",
|
|
57
31
|
"type": "string",
|
|
58
32
|
"min": 3,
|
|
59
33
|
"max": 30,
|
|
60
|
-
"default": null,
|
|
61
|
-
"index": false,
|
|
62
|
-
"unique": false,
|
|
63
|
-
"nullable": false,
|
|
64
|
-
"unsigned": true,
|
|
65
34
|
"regexp": "^[a-zA-Z0-9_]+$"
|
|
66
35
|
},
|
|
67
36
|
"password": {
|
|
68
37
|
"name": "密码",
|
|
69
|
-
"detail": "",
|
|
70
38
|
"type": "string",
|
|
71
39
|
"min": 6,
|
|
72
|
-
"max": 500
|
|
73
|
-
"default": null,
|
|
74
|
-
"index": false,
|
|
75
|
-
"unique": false,
|
|
76
|
-
"nullable": false,
|
|
77
|
-
"unsigned": true,
|
|
78
|
-
"regexp": null
|
|
40
|
+
"max": 500
|
|
79
41
|
},
|
|
80
42
|
"avatar": {
|
|
81
43
|
"name": "头像",
|
|
82
|
-
"detail": "",
|
|
83
44
|
"type": "string",
|
|
84
45
|
"min": 0,
|
|
85
|
-
"max": 500
|
|
86
|
-
"default": null,
|
|
87
|
-
"index": false,
|
|
88
|
-
"unique": false,
|
|
89
|
-
"nullable": false,
|
|
90
|
-
"unsigned": true,
|
|
91
|
-
"regexp": null
|
|
46
|
+
"max": 500
|
|
92
47
|
},
|
|
93
48
|
"roleId": {
|
|
94
49
|
"name": "角色ID",
|
|
95
|
-
"detail": "",
|
|
96
50
|
"type": "number",
|
|
97
51
|
"min": 1,
|
|
98
52
|
"max": 999999999999999,
|
|
99
|
-
"
|
|
100
|
-
"index": true,
|
|
101
|
-
"unique": false,
|
|
102
|
-
"nullable": false,
|
|
103
|
-
"unsigned": true,
|
|
104
|
-
"regexp": null
|
|
53
|
+
"index": true
|
|
105
54
|
},
|
|
106
55
|
"roleCode": {
|
|
107
56
|
"name": "角色编码",
|
|
108
|
-
"detail": "",
|
|
109
57
|
"type": "string",
|
|
110
58
|
"min": 2,
|
|
111
59
|
"max": 50,
|
|
112
|
-
"default": null,
|
|
113
|
-
"index": false,
|
|
114
|
-
"unique": false,
|
|
115
|
-
"nullable": false,
|
|
116
|
-
"unsigned": true,
|
|
117
60
|
"regexp": "^[a-zA-Z0-9_]+$"
|
|
118
61
|
},
|
|
119
62
|
"roleType": {
|
|
120
63
|
"name": "角色类型",
|
|
121
|
-
"detail": "",
|
|
122
64
|
"type": "string",
|
|
123
65
|
"min": 4,
|
|
124
66
|
"max": 5,
|
|
125
67
|
"default": "user",
|
|
126
68
|
"index": true,
|
|
127
|
-
"unique": false,
|
|
128
|
-
"nullable": false,
|
|
129
|
-
"unsigned": true,
|
|
130
69
|
"regexp": "^(admin|user)$"
|
|
131
70
|
},
|
|
132
71
|
"lastLoginTime": {
|
|
133
72
|
"name": "最后登录时间",
|
|
134
|
-
"detail": "",
|
|
135
73
|
"type": "number",
|
|
136
74
|
"min": 0,
|
|
137
75
|
"max": null,
|
|
138
|
-
"default": 0
|
|
139
|
-
"index": false,
|
|
140
|
-
"unique": false,
|
|
141
|
-
"nullable": false,
|
|
142
|
-
"unsigned": true,
|
|
143
|
-
"regexp": null
|
|
76
|
+
"default": 0
|
|
144
77
|
},
|
|
145
78
|
"lastLoginIp": {
|
|
146
79
|
"name": "最后登录IP",
|
|
147
|
-
"detail": "",
|
|
148
80
|
"type": "string",
|
|
149
81
|
"min": 0,
|
|
150
|
-
"max": 50
|
|
151
|
-
"default": null,
|
|
152
|
-
"index": false,
|
|
153
|
-
"unique": false,
|
|
154
|
-
"nullable": false,
|
|
155
|
-
"unsigned": true,
|
|
156
|
-
"regexp": null
|
|
82
|
+
"max": 50
|
|
157
83
|
}
|
|
158
84
|
}
|
package/tables/api.json
CHANGED
|
@@ -1,80 +1,43 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": {
|
|
3
3
|
"name": "接口名称",
|
|
4
|
-
"detail": "",
|
|
5
4
|
"type": "string",
|
|
6
5
|
"min": 2,
|
|
7
6
|
"max": 100,
|
|
8
|
-
"
|
|
9
|
-
"index": true,
|
|
10
|
-
"unique": false,
|
|
11
|
-
"nullable": false,
|
|
12
|
-
"unsigned": true,
|
|
13
|
-
"regexp": null
|
|
7
|
+
"index": true
|
|
14
8
|
},
|
|
15
9
|
"path": {
|
|
16
10
|
"name": "接口路径",
|
|
17
|
-
"detail": "",
|
|
18
11
|
"type": "string",
|
|
19
12
|
"min": 1,
|
|
20
13
|
"max": 200,
|
|
21
|
-
"
|
|
22
|
-
"index": true,
|
|
23
|
-
"unique": false,
|
|
24
|
-
"nullable": false,
|
|
25
|
-
"unsigned": true,
|
|
26
|
-
"regexp": null
|
|
14
|
+
"index": true
|
|
27
15
|
},
|
|
28
16
|
"method": {
|
|
29
17
|
"name": "请求方法",
|
|
30
|
-
"detail": "",
|
|
31
18
|
"type": "string",
|
|
32
19
|
"min": 3,
|
|
33
20
|
"max": 10,
|
|
34
21
|
"default": "POST",
|
|
35
22
|
"index": true,
|
|
36
|
-
"unique": false,
|
|
37
|
-
"nullable": false,
|
|
38
|
-
"unsigned": true,
|
|
39
23
|
"regexp": "^(GET|POST|PUT|DELETE|PATCH)$"
|
|
40
24
|
},
|
|
41
25
|
"description": {
|
|
42
26
|
"name": "接口描述",
|
|
43
|
-
"detail": "",
|
|
44
27
|
"type": "string",
|
|
45
28
|
"min": 0,
|
|
46
|
-
"max": 500
|
|
47
|
-
"default": null,
|
|
48
|
-
"index": false,
|
|
49
|
-
"unique": false,
|
|
50
|
-
"nullable": false,
|
|
51
|
-
"unsigned": true,
|
|
52
|
-
"regexp": null
|
|
29
|
+
"max": 500
|
|
53
30
|
},
|
|
54
31
|
"addonName": {
|
|
55
32
|
"name": "所属插件",
|
|
56
|
-
"detail": "",
|
|
57
33
|
"type": "string",
|
|
58
34
|
"min": 0,
|
|
59
|
-
"max": 50
|
|
60
|
-
"default": null,
|
|
61
|
-
"index": false,
|
|
62
|
-
"unique": false,
|
|
63
|
-
"nullable": false,
|
|
64
|
-
"unsigned": true,
|
|
65
|
-
"regexp": null
|
|
35
|
+
"max": 50
|
|
66
36
|
},
|
|
67
37
|
"addonTitle": {
|
|
68
38
|
"name": "插件标题",
|
|
69
|
-
"detail": "",
|
|
70
39
|
"type": "string",
|
|
71
40
|
"min": 0,
|
|
72
|
-
"max": 100
|
|
73
|
-
"default": null,
|
|
74
|
-
"index": false,
|
|
75
|
-
"unique": false,
|
|
76
|
-
"nullable": false,
|
|
77
|
-
"unsigned": true,
|
|
78
|
-
"regexp": null
|
|
41
|
+
"max": 100
|
|
79
42
|
}
|
|
80
43
|
}
|
package/tables/dict.json
CHANGED
|
@@ -1,80 +1,45 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": {
|
|
3
3
|
"name": "字典名称",
|
|
4
|
-
"detail": "",
|
|
5
4
|
"type": "string",
|
|
6
5
|
"min": 2,
|
|
7
6
|
"max": 50,
|
|
8
|
-
"
|
|
9
|
-
"index": true,
|
|
10
|
-
"unique": false,
|
|
11
|
-
"nullable": false,
|
|
12
|
-
"unsigned": true,
|
|
13
|
-
"regexp": null
|
|
7
|
+
"index": true
|
|
14
8
|
},
|
|
15
9
|
"code": {
|
|
16
10
|
"name": "字典代码",
|
|
17
|
-
"detail": "",
|
|
18
11
|
"type": "string",
|
|
19
12
|
"min": 2,
|
|
20
13
|
"max": 50,
|
|
21
|
-
"default": null,
|
|
22
14
|
"index": true,
|
|
23
|
-
"unique": false,
|
|
24
|
-
"nullable": false,
|
|
25
|
-
"unsigned": true,
|
|
26
15
|
"regexp": "^[a-zA-Z0-9_]+$"
|
|
27
16
|
},
|
|
28
17
|
"value": {
|
|
29
18
|
"name": "字典值",
|
|
30
|
-
"detail": "",
|
|
31
19
|
"type": "string",
|
|
32
20
|
"min": 0,
|
|
33
21
|
"max": 200,
|
|
34
|
-
"
|
|
35
|
-
"index": true,
|
|
36
|
-
"unique": false,
|
|
37
|
-
"nullable": false,
|
|
38
|
-
"unsigned": true,
|
|
39
|
-
"regexp": null
|
|
22
|
+
"index": true
|
|
40
23
|
},
|
|
41
24
|
"sort": {
|
|
42
25
|
"name": "排序",
|
|
43
|
-
"detail": "",
|
|
44
26
|
"type": "number",
|
|
45
27
|
"min": 0,
|
|
46
28
|
"max": 9999,
|
|
47
|
-
"default": 0
|
|
48
|
-
"index": false,
|
|
49
|
-
"unique": false,
|
|
50
|
-
"nullable": false,
|
|
51
|
-
"unsigned": true,
|
|
52
|
-
"regexp": null
|
|
29
|
+
"default": 0
|
|
53
30
|
},
|
|
54
31
|
"pid": {
|
|
55
32
|
"name": "父级ID",
|
|
56
|
-
"detail": "",
|
|
57
33
|
"type": "number",
|
|
58
34
|
"min": 0,
|
|
59
35
|
"max": 999999999999999,
|
|
60
36
|
"default": 0,
|
|
61
|
-
"index": true
|
|
62
|
-
"unique": false,
|
|
63
|
-
"nullable": false,
|
|
64
|
-
"unsigned": true,
|
|
65
|
-
"regexp": null
|
|
37
|
+
"index": true
|
|
66
38
|
},
|
|
67
39
|
"description": {
|
|
68
40
|
"name": "描述",
|
|
69
|
-
"detail": "",
|
|
70
41
|
"type": "string",
|
|
71
42
|
"min": 0,
|
|
72
|
-
"max": 200
|
|
73
|
-
"default": null,
|
|
74
|
-
"index": false,
|
|
75
|
-
"unique": false,
|
|
76
|
-
"nullable": false,
|
|
77
|
-
"unsigned": true,
|
|
78
|
-
"regexp": null
|
|
43
|
+
"max": 200
|
|
79
44
|
}
|
|
80
45
|
}
|
package/tables/menu.json
CHANGED
|
@@ -1,67 +1,37 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": {
|
|
3
3
|
"name": "菜单名称",
|
|
4
|
-
"detail": "",
|
|
5
4
|
"type": "string",
|
|
6
5
|
"min": 2,
|
|
7
6
|
"max": 50,
|
|
8
|
-
"
|
|
9
|
-
"index": true,
|
|
10
|
-
"unique": false,
|
|
11
|
-
"nullable": false,
|
|
12
|
-
"unsigned": true,
|
|
13
|
-
"regexp": null
|
|
7
|
+
"index": true
|
|
14
8
|
},
|
|
15
9
|
"path": {
|
|
16
10
|
"name": "路由路径",
|
|
17
|
-
"detail": "",
|
|
18
11
|
"type": "string",
|
|
19
12
|
"min": 1,
|
|
20
13
|
"max": 200,
|
|
21
|
-
"
|
|
22
|
-
"index": true,
|
|
23
|
-
"unique": false,
|
|
24
|
-
"nullable": false,
|
|
25
|
-
"unsigned": true,
|
|
26
|
-
"regexp": null
|
|
14
|
+
"index": true
|
|
27
15
|
},
|
|
28
16
|
"icon": {
|
|
29
17
|
"name": "图标名称",
|
|
30
|
-
"detail": "",
|
|
31
18
|
"type": "string",
|
|
32
19
|
"min": 0,
|
|
33
|
-
"max": 50
|
|
34
|
-
"default": null,
|
|
35
|
-
"index": false,
|
|
36
|
-
"unique": false,
|
|
37
|
-
"nullable": false,
|
|
38
|
-
"unsigned": true,
|
|
39
|
-
"regexp": null
|
|
20
|
+
"max": 50
|
|
40
21
|
},
|
|
41
22
|
"sort": {
|
|
42
23
|
"name": "排序",
|
|
43
|
-
"detail": "",
|
|
44
24
|
"type": "number",
|
|
45
25
|
"min": 0,
|
|
46
26
|
"max": 9999,
|
|
47
|
-
"default": 0
|
|
48
|
-
"index": false,
|
|
49
|
-
"unique": false,
|
|
50
|
-
"nullable": false,
|
|
51
|
-
"unsigned": true,
|
|
52
|
-
"regexp": null
|
|
27
|
+
"default": 0
|
|
53
28
|
},
|
|
54
29
|
"pid": {
|
|
55
30
|
"name": "父级ID",
|
|
56
|
-
"detail": "",
|
|
57
31
|
"type": "number",
|
|
58
32
|
"min": 0,
|
|
59
33
|
"max": 999999999999999,
|
|
60
34
|
"default": 0,
|
|
61
|
-
"index": true
|
|
62
|
-
"unique": false,
|
|
63
|
-
"nullable": false,
|
|
64
|
-
"unsigned": true,
|
|
65
|
-
"regexp": null
|
|
35
|
+
"index": true
|
|
66
36
|
}
|
|
67
37
|
}
|
package/tables/role.json
CHANGED
|
@@ -1,80 +1,42 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": {
|
|
3
3
|
"name": "角色名称",
|
|
4
|
-
"detail": "",
|
|
5
4
|
"type": "string",
|
|
6
5
|
"min": 2,
|
|
7
6
|
"max": 50,
|
|
8
|
-
"
|
|
9
|
-
"index": true,
|
|
10
|
-
"unique": false,
|
|
11
|
-
"nullable": false,
|
|
12
|
-
"unsigned": true,
|
|
13
|
-
"regexp": null
|
|
7
|
+
"index": true
|
|
14
8
|
},
|
|
15
9
|
"code": {
|
|
16
10
|
"name": "角色编码",
|
|
17
|
-
"detail": "",
|
|
18
11
|
"type": "string",
|
|
19
12
|
"min": 2,
|
|
20
13
|
"max": 50,
|
|
21
|
-
"default": null,
|
|
22
14
|
"index": true,
|
|
23
|
-
"unique": false,
|
|
24
|
-
"nullable": false,
|
|
25
|
-
"unsigned": true,
|
|
26
15
|
"regexp": "^[a-zA-Z0-9_]+$"
|
|
27
16
|
},
|
|
28
17
|
"description": {
|
|
29
18
|
"name": "角色描述",
|
|
30
|
-
"detail": "",
|
|
31
19
|
"type": "string",
|
|
32
20
|
"min": 0,
|
|
33
|
-
"max": 200
|
|
34
|
-
"default": null,
|
|
35
|
-
"index": false,
|
|
36
|
-
"unique": false,
|
|
37
|
-
"nullable": false,
|
|
38
|
-
"unsigned": true,
|
|
39
|
-
"regexp": null
|
|
21
|
+
"max": 200
|
|
40
22
|
},
|
|
41
23
|
"menus": {
|
|
42
24
|
"name": "菜单权限",
|
|
43
|
-
"detail": "",
|
|
44
25
|
"type": "array_text",
|
|
45
26
|
"min": null,
|
|
46
|
-
"max": null
|
|
47
|
-
"default": null,
|
|
48
|
-
"index": false,
|
|
49
|
-
"unique": false,
|
|
50
|
-
"nullable": false,
|
|
51
|
-
"unsigned": true,
|
|
52
|
-
"regexp": null
|
|
27
|
+
"max": null
|
|
53
28
|
},
|
|
54
29
|
"apis": {
|
|
55
30
|
"name": "接口权限",
|
|
56
|
-
"detail": "",
|
|
57
31
|
"type": "array_text",
|
|
58
32
|
"min": null,
|
|
59
|
-
"max": null
|
|
60
|
-
"default": null,
|
|
61
|
-
"index": false,
|
|
62
|
-
"unique": false,
|
|
63
|
-
"nullable": false,
|
|
64
|
-
"unsigned": true,
|
|
65
|
-
"regexp": null
|
|
33
|
+
"max": null
|
|
66
34
|
},
|
|
67
35
|
"sort": {
|
|
68
36
|
"name": "排序",
|
|
69
|
-
"detail": "",
|
|
70
37
|
"type": "number",
|
|
71
38
|
"min": 0,
|
|
72
39
|
"max": 9999,
|
|
73
|
-
"default": 0
|
|
74
|
-
"index": false,
|
|
75
|
-
"unique": false,
|
|
76
|
-
"nullable": false,
|
|
77
|
-
"unsigned": true,
|
|
78
|
-
"regexp": null
|
|
40
|
+
"default": 0
|
|
79
41
|
}
|
|
80
42
|
}
|
package/util.ts
CHANGED
|
@@ -1,75 +1,71 @@
|
|
|
1
|
-
|
|
2
|
-
* Admin 插件通用工具函数
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { Logger } from 'befly';
|
|
6
|
-
import type { BeflyContext } from 'befly/types/befly';
|
|
7
|
-
import { readdirSync, statSync, readFileSync } from 'node:fs';
|
|
8
|
-
import path from 'node:path';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* 输出同步统计信息
|
|
12
|
-
* @param stats - 统计对象
|
|
13
|
-
* @param deletedCount - 删除数量
|
|
14
|
-
* @param resourceName - 资源名称(如:菜单、接口)
|
|
15
|
-
*/
|
|
16
|
-
export function logSyncStats(stats: { created: number; updated: number }, deletedCount: number, resourceName: string = '记录'): void {
|
|
17
|
-
Logger.info(`\n=== ${resourceName}同步完成 ===`);
|
|
18
|
-
Logger.info(`新增${resourceName}: ${stats.created} 个`);
|
|
19
|
-
Logger.info(`更新${resourceName}: ${stats.updated} 个`);
|
|
20
|
-
Logger.info(`删除${resourceName}: ${deletedCount} 个`);
|
|
21
|
-
}
|
|
1
|
+
import type { RouteRecordRaw } from 'vue-router';
|
|
22
2
|
|
|
23
3
|
/**
|
|
24
|
-
*
|
|
25
|
-
*
|
|
4
|
+
* 自定义布局处理函数
|
|
5
|
+
* 根据文件名后缀判断使用哪个布局
|
|
6
|
+
* @param routes - 原始路由配置
|
|
7
|
+
* @param inheritLayout - 继承的布局名称(来自父级目录)
|
|
8
|
+
* @returns 处理后的路由配置
|
|
26
9
|
*/
|
|
27
|
-
export function
|
|
28
|
-
const
|
|
10
|
+
export function Layouts(routes: RouteRecordRaw[], inheritLayout = ''): RouteRecordRaw[] {
|
|
11
|
+
const result: RouteRecordRaw[] = [];
|
|
29
12
|
|
|
30
|
-
|
|
31
|
-
|
|
13
|
+
for (const route of routes) {
|
|
14
|
+
const currentPath = route.path || '';
|
|
32
15
|
|
|
33
|
-
|
|
34
|
-
const
|
|
16
|
+
// 检查当前路径是否有 _数字 格式
|
|
17
|
+
const pathMatch = currentPath.match(/_(\d+)$/);
|
|
18
|
+
const currentLayout = pathMatch ? pathMatch[1] : inheritLayout;
|
|
35
19
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
20
|
+
// 如果有子路由,递归处理(传递当前布局给子级)
|
|
21
|
+
if (route.children && route.children.length > 0) {
|
|
22
|
+
// 清理路径:如果是 xxx_数字 格式,去掉 _数字
|
|
23
|
+
const cleanPath = pathMatch ? currentPath.replace(/_\d+$/, '') : currentPath;
|
|
39
24
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
25
|
+
result.push({
|
|
26
|
+
...route,
|
|
27
|
+
path: cleanPath,
|
|
28
|
+
children: Layouts(route.children, currentLayout)
|
|
29
|
+
});
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
44
32
|
|
|
45
|
-
|
|
46
|
-
|
|
33
|
+
// 没有子路由的叶子节点,需要包裹布局
|
|
34
|
+
const lastPart = currentPath;
|
|
47
35
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
36
|
+
// 匹配 _数字 格式(如 index_1, news_2)
|
|
37
|
+
const match = lastPart.match(/_(\d+)$/);
|
|
38
|
+
// 优先使用文件自己的布局,其次使用继承的布局,最后使用 default
|
|
39
|
+
const layoutName = match ? match[1] : currentLayout || 'default';
|
|
51
40
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
title: addonName,
|
|
64
|
-
version: '1.0.0',
|
|
65
|
-
description: '',
|
|
66
|
-
enabled: true
|
|
67
|
-
});
|
|
68
|
-
}
|
|
41
|
+
// 计算清理后的路径
|
|
42
|
+
let cleanPath: string;
|
|
43
|
+
if (lastPart === 'index' || (lastPart.startsWith('index_') && match)) {
|
|
44
|
+
// index 或 index_数字 → 改为空路径(由父级路径表示)
|
|
45
|
+
cleanPath = '';
|
|
46
|
+
} else if (match) {
|
|
47
|
+
// xxx_数字 → 去掉 _数字 后缀
|
|
48
|
+
cleanPath = lastPart.replace(/_\d+$/, '');
|
|
49
|
+
} else {
|
|
50
|
+
// 其他 → 保持原样
|
|
51
|
+
cleanPath = lastPart;
|
|
69
52
|
}
|
|
70
|
-
|
|
71
|
-
|
|
53
|
+
|
|
54
|
+
// 根据布局名称加载对应组件
|
|
55
|
+
const layoutComponent = layoutName === 'default' ? () => import('@/layouts/default.vue') : () => import(`@/layouts/${layoutName}.vue`);
|
|
56
|
+
|
|
57
|
+
// 包裹布局
|
|
58
|
+
result.push({
|
|
59
|
+
path: cleanPath,
|
|
60
|
+
component: layoutComponent,
|
|
61
|
+
children: [
|
|
62
|
+
{
|
|
63
|
+
...route,
|
|
64
|
+
path: ''
|
|
65
|
+
}
|
|
66
|
+
]
|
|
67
|
+
});
|
|
72
68
|
}
|
|
73
69
|
|
|
74
|
-
return
|
|
70
|
+
return result;
|
|
75
71
|
}
|
|
@@ -124,7 +124,7 @@ const $Method = {
|
|
|
124
124
|
const valid = await date$From.form.validate();
|
|
125
125
|
if (!valid) return;
|
|
126
126
|
|
|
127
|
-
const res = await $Http($Prop.actionType === 'upd' ? '/addon/admin/
|
|
127
|
+
const res = await $Http($Prop.actionType === 'upd' ? '/addon/admin/admin/upd' : '/addon/admin/admin/ins', $Data.formData);
|
|
128
128
|
|
|
129
129
|
Modal.message({
|
|
130
130
|
message: $Prop.actionType === 'upd' ? '编辑成功' : '添加成功',
|
|
@@ -83,7 +83,7 @@ const $Method = {
|
|
|
83
83
|
if (!$Prop.rowData.id) return;
|
|
84
84
|
|
|
85
85
|
try {
|
|
86
|
-
const res = await $Http('/addon/admin/roleDetail', {
|
|
86
|
+
const res = await $Http('/addon/admin/admin/roleDetail', {
|
|
87
87
|
adminId: $Prop.rowData.id
|
|
88
88
|
});
|
|
89
89
|
$Data.checkedRoleCode = res.data.roleCode || '';
|
|
@@ -100,7 +100,7 @@ const $Method = {
|
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
try {
|
|
103
|
-
const res = await $Http('/addon/admin/roleSave', {
|
|
103
|
+
const res = await $Http('/addon/admin/admin/roleSave', {
|
|
104
104
|
adminId: $Prop.rowData.id,
|
|
105
105
|
roleCode: $Data.checkedRoleCode
|
|
106
106
|
});
|
package/views/admin/index.vue
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<div class="left">
|
|
5
5
|
<tiny-button type="primary" @click="$Method.onAction('add', {})">
|
|
6
6
|
<template #icon>
|
|
7
|
-
<i-lucide:plus
|
|
7
|
+
<i-lucide:plus />
|
|
8
8
|
</template>
|
|
9
9
|
添加管理员
|
|
10
10
|
</tiny-button>
|
|
@@ -12,14 +12,14 @@
|
|
|
12
12
|
<div class="right">
|
|
13
13
|
<tiny-button @click="$Method.handleRefresh">
|
|
14
14
|
<template #icon>
|
|
15
|
-
<i-lucide:rotate-cw
|
|
15
|
+
<i-lucide:rotate-cw />
|
|
16
16
|
</template>
|
|
17
17
|
</tiny-button>
|
|
18
18
|
</div>
|
|
19
19
|
<div class="right">
|
|
20
20
|
<tiny-button @click="$Method.handleRefresh">
|
|
21
21
|
<template #icon>
|
|
22
|
-
<i-lucide:rotate-cw
|
|
22
|
+
<i-lucide:rotate-cw />
|
|
23
23
|
</template>
|
|
24
24
|
刷新
|
|
25
25
|
</tiny-button>
|
|
@@ -109,7 +109,7 @@ const $Method = {
|
|
|
109
109
|
// 加载管理员列表
|
|
110
110
|
async apiAdminList() {
|
|
111
111
|
try {
|
|
112
|
-
const res = await $Http('/addon/admin/list', {
|
|
112
|
+
const res = await $Http('/addon/admin/admin/list', {
|
|
113
113
|
page: $Data.pagerConfig.currentPage,
|
|
114
114
|
limit: $Data.pagerConfig.pageSize
|
|
115
115
|
});
|
|
@@ -132,7 +132,7 @@ const $Method = {
|
|
|
132
132
|
status: 'warning'
|
|
133
133
|
}).then(async () => {
|
|
134
134
|
try {
|
|
135
|
-
const res = await $Http('/addon/admin/del', { id: row.id });
|
|
135
|
+
const res = await $Http('/addon/admin/admin/del', { id: row.id });
|
|
136
136
|
if (res.code === 0) {
|
|
137
137
|
Modal.message({ message: '删除成功', status: 'success' });
|
|
138
138
|
$Method.apiAdminList();
|
package/views/dict/index.vue
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<div class="left">
|
|
5
5
|
<tiny-button type="primary" @click="$Method.onAction('add', {})">
|
|
6
6
|
<template #icon>
|
|
7
|
-
<i-lucide:plus
|
|
7
|
+
<i-lucide:plus />
|
|
8
8
|
</template>
|
|
9
9
|
添加字典
|
|
10
10
|
</tiny-button>
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
<div class="right">
|
|
13
13
|
<tiny-button @click="$Method.handleRefresh">
|
|
14
14
|
<template #icon>
|
|
15
|
-
<i-lucide:rotate-cw
|
|
15
|
+
<i-lucide:rotate-cw />
|
|
16
16
|
</template>
|
|
17
17
|
刷新
|
|
18
18
|
</tiny-button>
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="section-block">
|
|
3
|
-
<div class="section-header">
|
|
3
|
+
<div class="section-header flex items-center gap-2">
|
|
4
4
|
<i-lucide:package style="width: 20px; height: 20px" />
|
|
5
5
|
<h2>已安装插件</h2>
|
|
6
6
|
</div>
|
|
7
7
|
<div class="section-content">
|
|
8
8
|
<div class="addon-list">
|
|
9
9
|
<div v-for="addon in addonList" :key="addon.name" class="addon-item">
|
|
10
|
-
<div class="addon-status-badge" :class="{ active: addon.enabled }"></div>
|
|
11
10
|
<div class="addon-icon">
|
|
12
11
|
<i-lucide:box style="width: 20px; height: 20px" />
|
|
13
12
|
</div>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="section-block">
|
|
3
|
-
<div class="section-header">
|
|
4
|
-
<i-lucide:
|
|
3
|
+
<div class="section-header flex items-center gap-2">
|
|
4
|
+
<i-lucide:file-text style="width: 20px; height: 20px" />
|
|
5
5
|
<h2>操作日志</h2>
|
|
6
6
|
</div>
|
|
7
7
|
<div class="section-content">
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="section-block">
|
|
3
|
-
<div class="section-header">
|
|
4
|
-
<i-lucide:
|
|
3
|
+
<div class="section-header flex items-center gap-2">
|
|
4
|
+
<i-lucide:activity style="width: 20px; height: 20px" />
|
|
5
5
|
<h2>性能指标</h2>
|
|
6
6
|
</div>
|
|
7
7
|
<div class="section-content">
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="section-block">
|
|
3
|
-
<div class="section-header">
|
|
4
|
-
<i-lucide:
|
|
3
|
+
<div class="section-header flex items-center gap-2">
|
|
4
|
+
<i-lucide:check-circle style="width: 20px; height: 20px" />
|
|
5
5
|
<h2>服务状态</h2>
|
|
6
6
|
</div>
|
|
7
7
|
<div class="section-content">
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="section-block">
|
|
3
|
-
<div class="section-header">
|
|
3
|
+
<div class="section-header flex items-center gap-2">
|
|
4
4
|
<i-lucide:bell style="width: 20px; height: 20px" />
|
|
5
5
|
<h2>系统通知</h2>
|
|
6
6
|
</div>
|
|
@@ -8,11 +8,11 @@
|
|
|
8
8
|
<div class="notification-compact-list">
|
|
9
9
|
<div v-for="notification in notifications" :key="notification.id" class="notification-compact-item">
|
|
10
10
|
<div class="notification-icon" :class="`type-${notification.type}`">
|
|
11
|
-
<i-lucide:info v-if="notification.type === 'info'"
|
|
12
|
-
<i-lucide:check-circle v-else-if="notification.type === 'success'"
|
|
13
|
-
<i-lucide:alert-triangle v-else-if="notification.type === 'warning'"
|
|
14
|
-
<i-lucide:x-circle v-else-if="notification.type === 'error'"
|
|
15
|
-
<i-lucide:bell v-else
|
|
11
|
+
<i-lucide:info v-if="notification.type === 'info'" />
|
|
12
|
+
<i-lucide:check-circle v-else-if="notification.type === 'success'" />
|
|
13
|
+
<i-lucide:alert-triangle v-else-if="notification.type === 'warning'" />
|
|
14
|
+
<i-lucide:x-circle v-else-if="notification.type === 'error'" />
|
|
15
|
+
<i-lucide:bell v-else />
|
|
16
16
|
</div>
|
|
17
17
|
<div class="notification-content">
|
|
18
18
|
<span class="notification-title">{{ notification.title }}</span>
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="section-block">
|
|
3
|
-
<div class="section-header">
|
|
3
|
+
<div class="section-header flex items-center gap-2">
|
|
4
4
|
<i-lucide:info style="width: 20px; height: 20px" />
|
|
5
5
|
<h2>系统概览</h2>
|
|
6
6
|
</div>
|
|
7
7
|
<div class="section-content">
|
|
8
|
-
<tiny-row :flex="true"
|
|
8
|
+
<tiny-row :flex="true">
|
|
9
9
|
<tiny-col :xs="24" :sm="12" :md="12" :lg="12">
|
|
10
10
|
<div class="info-block">
|
|
11
11
|
<div class="stats-grid">
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="section-block">
|
|
3
|
-
<div class="section-header">
|
|
3
|
+
<div class="section-header flex items-center gap-2">
|
|
4
4
|
<i-lucide:activity style="width: 20px; height: 20px" />
|
|
5
5
|
<h2>系统资源</h2>
|
|
6
6
|
</div>
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
<div class="resource-compact-list">
|
|
9
9
|
<div class="resource-compact-item">
|
|
10
10
|
<div class="resource-compact-header">
|
|
11
|
-
<i-lucide:cpu
|
|
11
|
+
<i-lucide:cpu />
|
|
12
12
|
<span class="resource-label">CPU</span>
|
|
13
13
|
<span class="resource-value">{{ systemResources.cpu.usage }}%</span>
|
|
14
14
|
<span class="resource-desc">{{ systemResources.cpu.cores }}核心</span>
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
</div>
|
|
18
18
|
<div class="resource-compact-item">
|
|
19
19
|
<div class="resource-compact-header">
|
|
20
|
-
<i-lucide:hard-drive
|
|
20
|
+
<i-lucide:hard-drive />
|
|
21
21
|
<span class="resource-label">内存</span>
|
|
22
22
|
<span class="resource-value">{{ systemResources.memory.percentage }}%</span>
|
|
23
23
|
<span class="resource-desc">{{ systemResources.memory.used }}GB / {{ systemResources.memory.total }}GB</span>
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
</div>
|
|
27
27
|
<div class="resource-compact-item">
|
|
28
28
|
<div class="resource-compact-header">
|
|
29
|
-
<i-lucide:disc
|
|
29
|
+
<i-lucide:disc />
|
|
30
30
|
<span class="resource-label">磁盘</span>
|
|
31
31
|
<span class="resource-value">{{ systemResources.disk.percentage }}%</span>
|
|
32
32
|
<span class="resource-desc">{{ systemResources.disk.used }}GB / {{ systemResources.disk.total }}GB</span>
|
package/views/index/index.vue
CHANGED
package/views/menu/index.vue
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<div class="left">
|
|
5
5
|
<tiny-button type="primary" @click="$Method.onAction('add', {})">
|
|
6
6
|
<template #icon>
|
|
7
|
-
<i-lucide:plus
|
|
7
|
+
<i-lucide:plus />
|
|
8
8
|
</template>
|
|
9
9
|
添加菜单
|
|
10
10
|
</tiny-button>
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
<div class="right">
|
|
13
13
|
<tiny-button @click="$Method.handleRefresh">
|
|
14
14
|
<template #icon>
|
|
15
|
-
<i-lucide:rotate-cw
|
|
15
|
+
<i-lucide:rotate-cw />
|
|
16
16
|
</template>
|
|
17
17
|
刷新
|
|
18
18
|
</tiny-button>
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
<tiny-grid-column field="path" title="路径" :width="200" />
|
|
26
26
|
<tiny-grid-column field="icon" title="图标" :width="100">
|
|
27
27
|
<template #default="{ row }">
|
|
28
|
-
<i-lucide:square v-if="row.icon"
|
|
28
|
+
<i-lucide:square v-if="row.icon" />
|
|
29
29
|
<span v-else>-</span>
|
|
30
30
|
</template>
|
|
31
31
|
</tiny-grid-column>
|
package/views/role/index.vue
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<div class="left">
|
|
5
5
|
<tiny-button type="primary" @click="$Method.onAction('add', {})">
|
|
6
6
|
<template #icon>
|
|
7
|
-
<i-lucide:plus
|
|
7
|
+
<i-lucide:plus />
|
|
8
8
|
</template>
|
|
9
9
|
添加角色
|
|
10
10
|
</tiny-button>
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
<div class="right">
|
|
13
13
|
<tiny-button @click="$Method.handleRefresh">
|
|
14
14
|
<template #icon>
|
|
15
|
-
<i-lucide:rotate-cw
|
|
15
|
+
<i-lucide:rotate-cw />
|
|
16
16
|
</template>
|
|
17
17
|
刷新
|
|
18
18
|
</tiny-button>
|
package/views/user/index.vue
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<div class="toolbar-left">
|
|
6
6
|
<t-button theme="primary" @click="$Method.handleAdd">
|
|
7
7
|
<template #icon>
|
|
8
|
-
<i-lucide:plus
|
|
8
|
+
<i-lucide:plus />
|
|
9
9
|
</template>
|
|
10
10
|
添加管理员
|
|
11
11
|
</t-button>
|
|
@@ -16,13 +16,13 @@
|
|
|
16
16
|
<t-select v-model="$Data.searchState" placeholder="状态" clearable style="width: 120px" :options="$Data.stateOptions" @change="$Method.handleSearch" />
|
|
17
17
|
<t-button theme="default" @click="$Method.handleSearch">
|
|
18
18
|
<template #icon>
|
|
19
|
-
<i-lucide:search
|
|
19
|
+
<i-lucide:search />
|
|
20
20
|
</template>
|
|
21
21
|
搜索
|
|
22
22
|
</t-button>
|
|
23
23
|
<t-button theme="default" @click="$Method.handleReset">
|
|
24
24
|
<template #icon>
|
|
25
|
-
<i-lucide:rotate-cw
|
|
25
|
+
<i-lucide:rotate-cw />
|
|
26
26
|
</template>
|
|
27
27
|
重置
|
|
28
28
|
</t-button>
|
|
File without changes
|