@befly-addon/admin 1.0.9 → 1.0.11

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.
Files changed (40) hide show
  1. package/apis/api/all.ts +5 -12
  2. package/apis/menu/all.ts +8 -14
  3. package/package.json +17 -3
  4. package/tables/admin.json +157 -13
  5. package/tables/api.json +79 -7
  6. package/tables/dict.json +79 -7
  7. package/tables/menu.json +79 -7
  8. package/tables/role.json +79 -7
  9. package/util.ts +1 -150
  10. package/views/403/index.vue +68 -0
  11. package/views/admin/components/edit.vue +150 -0
  12. package/views/admin/components/role.vue +138 -0
  13. package/views/admin/index.vue +179 -0
  14. package/views/dict/components/edit.vue +159 -0
  15. package/views/dict/index.vue +162 -0
  16. package/views/index/components/addonList.vue +127 -0
  17. package/views/index/components/environmentInfo.vue +99 -0
  18. package/views/index/components/operationLogs.vue +114 -0
  19. package/views/index/components/performanceMetrics.vue +150 -0
  20. package/views/index/components/quickActions.vue +27 -0
  21. package/views/index/components/serviceStatus.vue +183 -0
  22. package/views/index/components/systemNotifications.vue +132 -0
  23. package/views/index/components/systemOverview.vue +190 -0
  24. package/views/index/components/systemResources.vue +106 -0
  25. package/views/index/components/userInfo.vue +206 -0
  26. package/views/index/index.vue +29 -0
  27. package/views/login/components/emailLoginForm.vue +167 -0
  28. package/views/login/components/registerForm.vue +170 -0
  29. package/views/login/components/welcomePanel.vue +61 -0
  30. package/views/login/index.vue +191 -0
  31. package/views/menu/components/edit.vue +153 -0
  32. package/views/menu/index.vue +177 -0
  33. package/views/news/detail/index.vue +26 -0
  34. package/views/news/index.vue +26 -0
  35. package/views/role/components/api.vue +283 -0
  36. package/views/role/components/edit.vue +132 -0
  37. package/views/role/components/menu.vue +146 -0
  38. package/views/role/index.vue +179 -0
  39. package/views/user/index.vue +322 -0
  40. package/apis/dashboard/addonList.ts +0 -47
package/apis/api/all.ts CHANGED
@@ -9,26 +9,19 @@ export default {
9
9
  name: '获取所有接口',
10
10
  handler: async (befly, ctx) => {
11
11
  try {
12
- // 从 Redis 缓存读取所有接口
13
- let allApis = await befly.redis.getObject<any[]>('apis:all');
12
+ // 从缓存获取所有接口
13
+ let allApis = await befly.cache.getApis();
14
14
 
15
15
  // 如果缓存不存在,从数据库查询
16
- if (!allApis || allApis.length === 0) {
17
- befly.logger.info('接口缓存未命中,从数据库查询');
16
+ if (allApis.length === 0) {
18
17
  allApis = await befly.db.getAll({
19
18
  table: 'addon_admin_api',
20
19
  fields: ['id', 'name', 'path', 'method', 'description', 'addonName', 'addonTitle'],
21
20
  orderBy: ['addonName#ASC', 'path#ASC']
22
21
  });
23
-
24
- // 回写缓存
25
- if (allApis.length > 0) {
26
- await befly.redis.setObject('apis:all', allApis);
27
- }
28
- return Yes('操作成功', { lists: allApis, from: '来自数据库' });
29
- } else {
30
- return Yes('操作成功', { lists: allApis, from: '来自缓存' });
31
22
  }
23
+
24
+ return Yes('操作成功', { lists: allApis });
32
25
  } catch (error: any) {
33
26
  befly.logger.error('获取接口列表失败:', error);
34
27
  return No('获取接口列表失败');
package/apis/menu/all.ts CHANGED
@@ -33,26 +33,20 @@ export default {
33
33
  return Yes('菜单为空', []);
34
34
  }
35
35
 
36
- // 4. 从 Redis 缓存读取所有菜单
37
- let allMenus = await befly.redis.getObject<any[]>('menus:all');
38
- let fromMenus = 'cache';
36
+ // 4. 从缓存获取所有菜单
37
+ let allMenus = await befly.cache.getMenus();
39
38
 
40
- // 如果缓存不存在,从数据库查询并缓存
41
- if (!allMenus || allMenus.length === 0) {
42
- fromMenus = 'database';
39
+ // 如果缓存不存在,从数据库查询
40
+ if (allMenus.length === 0) {
43
41
  allMenus = await befly.db.getAll({
44
42
  table: 'addon_admin_menu',
45
43
  fields: ['id', 'pid', 'name', 'path', 'icon', 'type', 'sort'],
46
44
  orderBy: ['sort#ASC', 'id#ASC']
47
45
  });
46
+ }
48
47
 
49
- // 回写缓存
50
- if (allMenus.length > 0) {
51
- await befly.redis.setObject('menus:all', allMenus);
52
- befly.logger.info(`已缓存 ${allMenus.length} 个菜单到 Redis`);
53
- }
54
- } else {
55
- befly.logger.debug(`从 Redis 缓存读取 ${allMenus.length} 个菜单`);
48
+ if (allMenus.length === 0) {
49
+ return Yes('菜单为空', []);
56
50
  }
57
51
 
58
52
  // 5. 根据角色权限过滤菜单
@@ -60,7 +54,7 @@ export default {
60
54
  const authorizedMenus = allMenus.filter((menu: any) => menuIdSet.has(String(menu.id)));
61
55
 
62
56
  // 6. 返回一维数组(由前端构建树形结构)
63
- return Yes('获取菜单成功', authorizedMenus, { from: fromMenus });
57
+ return Yes('获取菜单成功', authorizedMenus);
64
58
  } catch (error) {
65
59
  befly.logger.error('获取用户菜单失败:', error);
66
60
  return No('获取菜单失败');
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@befly-addon/admin",
3
- "version": "1.0.9",
4
- "description": "Befly Admin Addon - 管理后台功能组件",
3
+ "version": "1.0.11",
4
+ "description": "Befly - 管理后台功能组件",
5
5
  "type": "module",
6
6
  "private": false,
7
7
  "publishConfig": {
@@ -9,9 +9,15 @@
9
9
  "registry": "https://registry.npmjs.org"
10
10
  },
11
11
  "main": "addon.config.json",
12
+ "scripts": {
13
+ "dev": "vite",
14
+ "build": "vite build",
15
+ "preview": "vite preview"
16
+ },
12
17
  "files": [
13
18
  "apis/",
14
19
  "tables/",
20
+ "views/",
15
21
  "addon.config.json",
16
22
  "util.ts",
17
23
  "README.md",
@@ -32,5 +38,13 @@
32
38
  "url": "https://github.com/chenbimo/befly.git",
33
39
  "directory": "packages/addon-admin"
34
40
  },
35
- "gitHead": "f3bbd3446f51f0cec30311133b1a07a9decf104d"
41
+ "gitHead": "51d86162e5f0b94ecc44a833a98ebf97c27f7bd6",
42
+ "dependencies": {
43
+ "befly": "3.8.3"
44
+ },
45
+ "devDependencies": {
46
+ "@module-federation/vite": "^1.9.0",
47
+ "@vitejs/plugin-vue": "^6.0.1",
48
+ "rolldown-vite": "^7.2.2"
49
+ }
36
50
  }
package/tables/admin.json CHANGED
@@ -1,14 +1,158 @@
1
- {
2
- "name": "姓名|string|2|50|null|0|null",
3
- "nickname": "昵称|string|2|50|null|0|null",
4
- "email": "邮箱|string|5|100|null|1|^[\\w.-]+@[\\w.-]+\\.\\w+$",
5
- "phone": "手机号|string|11|11|null|0|^1[3-9]\\d{9}$",
6
- "username": "用户名|string|3|30|null|0|^[a-zA-Z0-9_]+$",
7
- "password": "密码|string|6|500|null|0|null",
8
- "avatar": "头像|string|0|500|null|0|null",
9
- "roleId": "角色ID|number|1|999999999999999|null|1|null",
10
- "roleCode": "角色编码|string|2|50|null|0|^[a-zA-Z0-9_]+$",
11
- "roleType": "角色类型|string|4|5|user|1|^(admin|user)$",
12
- "lastLoginTime": "最后登录时间|number|0|null|0|0|null",
13
- "lastLoginIp": "最后登录IP|string|0|50|null|0|null"
1
+ {
2
+ "name": {
3
+ "name": "姓名",
4
+ "detail": "",
5
+ "type": "string",
6
+ "min": 2,
7
+ "max": 50,
8
+ "default": null,
9
+ "index": false,
10
+ "unique": false,
11
+ "nullable": false,
12
+ "unsigned": true,
13
+ "regexp": null
14
+ },
15
+ "nickname": {
16
+ "name": "昵称",
17
+ "detail": "",
18
+ "type": "string",
19
+ "min": 2,
20
+ "max": 50,
21
+ "default": null,
22
+ "index": false,
23
+ "unique": false,
24
+ "nullable": false,
25
+ "unsigned": true,
26
+ "regexp": null
27
+ },
28
+ "email": {
29
+ "name": "邮箱",
30
+ "detail": "",
31
+ "type": "string",
32
+ "min": 5,
33
+ "max": 100,
34
+ "default": null,
35
+ "index": true,
36
+ "unique": false,
37
+ "nullable": false,
38
+ "unsigned": true,
39
+ "regexp": "^[\\w.-]+@[\\w.-]+\\.\\w+$"
40
+ },
41
+ "phone": {
42
+ "name": "手机号",
43
+ "detail": "",
44
+ "type": "string",
45
+ "min": 11,
46
+ "max": 11,
47
+ "default": null,
48
+ "index": false,
49
+ "unique": false,
50
+ "nullable": false,
51
+ "unsigned": true,
52
+ "regexp": "^1[3-9]\\d{9}$"
53
+ },
54
+ "username": {
55
+ "name": "用户名",
56
+ "detail": "",
57
+ "type": "string",
58
+ "min": 3,
59
+ "max": 30,
60
+ "default": null,
61
+ "index": false,
62
+ "unique": false,
63
+ "nullable": false,
64
+ "unsigned": true,
65
+ "regexp": "^[a-zA-Z0-9_]+$"
66
+ },
67
+ "password": {
68
+ "name": "密码",
69
+ "detail": "",
70
+ "type": "string",
71
+ "min": 6,
72
+ "max": 500,
73
+ "default": null,
74
+ "index": false,
75
+ "unique": false,
76
+ "nullable": false,
77
+ "unsigned": true,
78
+ "regexp": null
79
+ },
80
+ "avatar": {
81
+ "name": "头像",
82
+ "detail": "",
83
+ "type": "string",
84
+ "min": 0,
85
+ "max": 500,
86
+ "default": null,
87
+ "index": false,
88
+ "unique": false,
89
+ "nullable": false,
90
+ "unsigned": true,
91
+ "regexp": null
92
+ },
93
+ "roleId": {
94
+ "name": "角色ID",
95
+ "detail": "",
96
+ "type": "number",
97
+ "min": 1,
98
+ "max": 999999999999999,
99
+ "default": null,
100
+ "index": true,
101
+ "unique": false,
102
+ "nullable": false,
103
+ "unsigned": true,
104
+ "regexp": null
105
+ },
106
+ "roleCode": {
107
+ "name": "角色编码",
108
+ "detail": "",
109
+ "type": "string",
110
+ "min": 2,
111
+ "max": 50,
112
+ "default": null,
113
+ "index": false,
114
+ "unique": false,
115
+ "nullable": false,
116
+ "unsigned": true,
117
+ "regexp": "^[a-zA-Z0-9_]+$"
118
+ },
119
+ "roleType": {
120
+ "name": "角色类型",
121
+ "detail": "",
122
+ "type": "string",
123
+ "min": 4,
124
+ "max": 5,
125
+ "default": "user",
126
+ "index": true,
127
+ "unique": false,
128
+ "nullable": false,
129
+ "unsigned": true,
130
+ "regexp": "^(admin|user)$"
131
+ },
132
+ "lastLoginTime": {
133
+ "name": "最后登录时间",
134
+ "detail": "",
135
+ "type": "number",
136
+ "min": 0,
137
+ "max": null,
138
+ "default": 0,
139
+ "index": false,
140
+ "unique": false,
141
+ "nullable": false,
142
+ "unsigned": true,
143
+ "regexp": null
144
+ },
145
+ "lastLoginIp": {
146
+ "name": "最后登录IP",
147
+ "detail": "",
148
+ "type": "string",
149
+ "min": 0,
150
+ "max": 50,
151
+ "default": null,
152
+ "index": false,
153
+ "unique": false,
154
+ "nullable": false,
155
+ "unsigned": true,
156
+ "regexp": null
157
+ }
14
158
  }
package/tables/api.json CHANGED
@@ -1,8 +1,80 @@
1
- {
2
- "name": "接口名称|string|2|100|null|1|null",
3
- "path": "接口路径|string|1|200|null|1|null",
4
- "method": "请求方法|string|3|10|POST|1|^(GET|POST|PUT|DELETE|PATCH)$",
5
- "description": "接口描述|string|0|500|null|0|null",
6
- "addonName": "所属插件|string|0|50|null|0|null",
7
- "addonTitle": "插件标题|string|0|100|null|0|null"
1
+ {
2
+ "name": {
3
+ "name": "接口名称",
4
+ "detail": "",
5
+ "type": "string",
6
+ "min": 2,
7
+ "max": 100,
8
+ "default": null,
9
+ "index": true,
10
+ "unique": false,
11
+ "nullable": false,
12
+ "unsigned": true,
13
+ "regexp": null
14
+ },
15
+ "path": {
16
+ "name": "接口路径",
17
+ "detail": "",
18
+ "type": "string",
19
+ "min": 1,
20
+ "max": 200,
21
+ "default": null,
22
+ "index": true,
23
+ "unique": false,
24
+ "nullable": false,
25
+ "unsigned": true,
26
+ "regexp": null
27
+ },
28
+ "method": {
29
+ "name": "请求方法",
30
+ "detail": "",
31
+ "type": "string",
32
+ "min": 3,
33
+ "max": 10,
34
+ "default": "POST",
35
+ "index": true,
36
+ "unique": false,
37
+ "nullable": false,
38
+ "unsigned": true,
39
+ "regexp": "^(GET|POST|PUT|DELETE|PATCH)$"
40
+ },
41
+ "description": {
42
+ "name": "接口描述",
43
+ "detail": "",
44
+ "type": "string",
45
+ "min": 0,
46
+ "max": 500,
47
+ "default": null,
48
+ "index": false,
49
+ "unique": false,
50
+ "nullable": false,
51
+ "unsigned": true,
52
+ "regexp": null
53
+ },
54
+ "addonName": {
55
+ "name": "所属插件",
56
+ "detail": "",
57
+ "type": "string",
58
+ "min": 0,
59
+ "max": 50,
60
+ "default": null,
61
+ "index": false,
62
+ "unique": false,
63
+ "nullable": false,
64
+ "unsigned": true,
65
+ "regexp": null
66
+ },
67
+ "addonTitle": {
68
+ "name": "插件标题",
69
+ "detail": "",
70
+ "type": "string",
71
+ "min": 0,
72
+ "max": 100,
73
+ "default": null,
74
+ "index": false,
75
+ "unique": false,
76
+ "nullable": false,
77
+ "unsigned": true,
78
+ "regexp": null
79
+ }
8
80
  }
package/tables/dict.json CHANGED
@@ -1,8 +1,80 @@
1
- {
2
- "name": "字典名称|string|2|50|null|1|null",
3
- "code": "字典代码|string|2|50|null|1|^[a-zA-Z0-9_]+$",
4
- "value": "字典值|string|0|200|null|1|null",
5
- "sort": "排序|number|0|9999|0|0|null",
6
- "pid": "父级ID|number|0|999999999999999|0|1|null",
7
- "description": "描述|string|0|200|null|0|null"
1
+ {
2
+ "name": {
3
+ "name": "字典名称",
4
+ "detail": "",
5
+ "type": "string",
6
+ "min": 2,
7
+ "max": 50,
8
+ "default": null,
9
+ "index": true,
10
+ "unique": false,
11
+ "nullable": false,
12
+ "unsigned": true,
13
+ "regexp": null
14
+ },
15
+ "code": {
16
+ "name": "字典代码",
17
+ "detail": "",
18
+ "type": "string",
19
+ "min": 2,
20
+ "max": 50,
21
+ "default": null,
22
+ "index": true,
23
+ "unique": false,
24
+ "nullable": false,
25
+ "unsigned": true,
26
+ "regexp": "^[a-zA-Z0-9_]+$"
27
+ },
28
+ "value": {
29
+ "name": "字典值",
30
+ "detail": "",
31
+ "type": "string",
32
+ "min": 0,
33
+ "max": 200,
34
+ "default": null,
35
+ "index": true,
36
+ "unique": false,
37
+ "nullable": false,
38
+ "unsigned": true,
39
+ "regexp": null
40
+ },
41
+ "sort": {
42
+ "name": "排序",
43
+ "detail": "",
44
+ "type": "number",
45
+ "min": 0,
46
+ "max": 9999,
47
+ "default": 0,
48
+ "index": false,
49
+ "unique": false,
50
+ "nullable": false,
51
+ "unsigned": true,
52
+ "regexp": null
53
+ },
54
+ "pid": {
55
+ "name": "父级ID",
56
+ "detail": "",
57
+ "type": "number",
58
+ "min": 0,
59
+ "max": 999999999999999,
60
+ "default": 0,
61
+ "index": true,
62
+ "unique": false,
63
+ "nullable": false,
64
+ "unsigned": true,
65
+ "regexp": null
66
+ },
67
+ "description": {
68
+ "name": "描述",
69
+ "detail": "",
70
+ "type": "string",
71
+ "min": 0,
72
+ "max": 200,
73
+ "default": null,
74
+ "index": false,
75
+ "unique": false,
76
+ "nullable": false,
77
+ "unsigned": true,
78
+ "regexp": null
79
+ }
8
80
  }
package/tables/menu.json CHANGED
@@ -1,8 +1,80 @@
1
- {
2
- "name": "菜单名称|string|2|50|null|1|null",
3
- "path": "路由路径|string|1|200|null|1|null",
4
- "icon": "图标名称|string|0|50|null|0|null",
5
- "sort": "排序|number|0|9999|0|0|null",
6
- "pid": "父级ID|number|0|999999999999999|0|1|null",
7
- "type": "菜单类型|number|1|2|1|1|^(1|2)$"
1
+ {
2
+ "name": {
3
+ "name": "菜单名称",
4
+ "detail": "",
5
+ "type": "string",
6
+ "min": 2,
7
+ "max": 50,
8
+ "default": null,
9
+ "index": true,
10
+ "unique": false,
11
+ "nullable": false,
12
+ "unsigned": true,
13
+ "regexp": null
14
+ },
15
+ "path": {
16
+ "name": "路由路径",
17
+ "detail": "",
18
+ "type": "string",
19
+ "min": 1,
20
+ "max": 200,
21
+ "default": null,
22
+ "index": true,
23
+ "unique": false,
24
+ "nullable": false,
25
+ "unsigned": true,
26
+ "regexp": null
27
+ },
28
+ "icon": {
29
+ "name": "图标名称",
30
+ "detail": "",
31
+ "type": "string",
32
+ "min": 0,
33
+ "max": 50,
34
+ "default": null,
35
+ "index": false,
36
+ "unique": false,
37
+ "nullable": false,
38
+ "unsigned": true,
39
+ "regexp": null
40
+ },
41
+ "sort": {
42
+ "name": "排序",
43
+ "detail": "",
44
+ "type": "number",
45
+ "min": 0,
46
+ "max": 9999,
47
+ "default": 0,
48
+ "index": false,
49
+ "unique": false,
50
+ "nullable": false,
51
+ "unsigned": true,
52
+ "regexp": null
53
+ },
54
+ "pid": {
55
+ "name": "父级ID",
56
+ "detail": "",
57
+ "type": "number",
58
+ "min": 0,
59
+ "max": 999999999999999,
60
+ "default": 0,
61
+ "index": true,
62
+ "unique": false,
63
+ "nullable": false,
64
+ "unsigned": true,
65
+ "regexp": null
66
+ },
67
+ "type": {
68
+ "name": "菜单类型",
69
+ "detail": "",
70
+ "type": "number",
71
+ "min": 1,
72
+ "max": 2,
73
+ "default": 1,
74
+ "index": true,
75
+ "unique": false,
76
+ "nullable": false,
77
+ "unsigned": true,
78
+ "regexp": "^(1|2)$"
79
+ }
8
80
  }
package/tables/role.json CHANGED
@@ -1,8 +1,80 @@
1
- {
2
- "name": "角色名称|string|2|50|null|1|null",
3
- "code": "角色编码|string|2|50|null|1|^[a-zA-Z0-9_]+$",
4
- "description": "角色描述|string|0|200|null|0|null",
5
- "menus": "菜单权限|array_text|null|null|null|0|null",
6
- "apis": "接口权限|array_text|null|null|null|0|null",
7
- "sort": "排序|number|0|9999|0|0|null"
1
+ {
2
+ "name": {
3
+ "name": "角色名称",
4
+ "detail": "",
5
+ "type": "string",
6
+ "min": 2,
7
+ "max": 50,
8
+ "default": null,
9
+ "index": true,
10
+ "unique": false,
11
+ "nullable": false,
12
+ "unsigned": true,
13
+ "regexp": null
14
+ },
15
+ "code": {
16
+ "name": "角色编码",
17
+ "detail": "",
18
+ "type": "string",
19
+ "min": 2,
20
+ "max": 50,
21
+ "default": null,
22
+ "index": true,
23
+ "unique": false,
24
+ "nullable": false,
25
+ "unsigned": true,
26
+ "regexp": "^[a-zA-Z0-9_]+$"
27
+ },
28
+ "description": {
29
+ "name": "角色描述",
30
+ "detail": "",
31
+ "type": "string",
32
+ "min": 0,
33
+ "max": 200,
34
+ "default": null,
35
+ "index": false,
36
+ "unique": false,
37
+ "nullable": false,
38
+ "unsigned": true,
39
+ "regexp": null
40
+ },
41
+ "menus": {
42
+ "name": "菜单权限",
43
+ "detail": "",
44
+ "type": "array_text",
45
+ "min": null,
46
+ "max": null,
47
+ "default": null,
48
+ "index": false,
49
+ "unique": false,
50
+ "nullable": false,
51
+ "unsigned": true,
52
+ "regexp": null
53
+ },
54
+ "apis": {
55
+ "name": "接口权限",
56
+ "detail": "",
57
+ "type": "array_text",
58
+ "min": null,
59
+ "max": null,
60
+ "default": null,
61
+ "index": false,
62
+ "unique": false,
63
+ "nullable": false,
64
+ "unsigned": true,
65
+ "regexp": null
66
+ },
67
+ "sort": {
68
+ "name": "排序",
69
+ "detail": "",
70
+ "type": "number",
71
+ "min": 0,
72
+ "max": 9999,
73
+ "default": 0,
74
+ "index": false,
75
+ "unique": false,
76
+ "nullable": false,
77
+ "unsigned": true,
78
+ "regexp": null
79
+ }
8
80
  }