@befly-addon/admin 1.8.7 → 1.8.8

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.
@@ -4,7 +4,9 @@
4
4
  * 功能:
5
5
  * 1. 刷新接口缓存(apis:all)
6
6
  * 2. 刷新菜单缓存(menus:all)
7
- * 3. 刷新角色权限缓存(role:info:{code})
7
+ * 3. 刷新角色缓存(role:info:{code})
8
+ * 4. 重建角色接口权限缓存(role:apis:{code},Set)
9
+ * 5. 重建角色菜单权限缓存(role:menus:{code},Set)
8
10
  *
9
11
  * 使用场景:
10
12
  * - 执行数据库同步后
@@ -22,7 +24,8 @@ const route: ApiRoute = {
22
24
  apis: { success: false, count: 0 },
23
25
  menus: { success: false, count: 0 },
24
26
  roles: { success: false, count: 0 },
25
- roleApiPermissions: { success: false }
27
+ roleApiPermissions: { success: false },
28
+ roleMenuPermissions: { success: false }
26
29
  };
27
30
 
28
31
  // 1. 刷新接口缓存
@@ -89,8 +92,17 @@ const route: ApiRoute = {
89
92
  results["roleApiPermissions"] = { success: false, error: error.message };
90
93
  }
91
94
 
95
+ // 5. 重建角色菜单权限缓存
96
+ try {
97
+ await befly.cache.rebuildRoleMenuPermissions();
98
+ results["roleMenuPermissions"] = { success: true };
99
+ } catch (error: any) {
100
+ befly.logger.error({ err: error, msg: "重建角色菜单权限缓存失败" });
101
+ results["roleMenuPermissions"] = { success: false, error: error.message };
102
+ }
103
+
92
104
  // 检查是否全部成功
93
- const allSuccess = results["apis"].success && results["menus"].success && results["roles"].success && results["roleApiPermissions"].success;
105
+ const allSuccess = results["apis"].success && results["menus"].success && results["roles"].success && results["roleApiPermissions"].success && results["roleMenuPermissions"].success;
94
106
 
95
107
  if (allSuccess) {
96
108
  return befly.tool.Yes("全部缓存刷新成功", results);
package/apis/api/all.ts CHANGED
@@ -1,28 +1,21 @@
1
- import type { DbJsonRow } from "../../utils/dbJsonRow";
2
1
  import type { ApiRoute } from "befly/types/api";
2
+ import type { JsonValue, KeyValue } from "befly/types/common";
3
+
4
+ type ApiRow = KeyValue<JsonValue>;
3
5
 
4
6
  const route: ApiRoute = {
5
7
  name: "获取所有接口",
6
8
  handler: async (befly) => {
7
9
  try {
8
10
  // 从缓存获取所有接口
9
- let allApis: unknown[] = await befly.cache.getApis();
11
+ const allApis = (await befly.cache.getApis()) as ApiRow[];
10
12
 
11
- // 如果缓存不存在,从数据库查询并缓存
13
+ // 强制缓存:不回退 DB
12
14
  if (allApis.length === 0) {
13
- const result = await befly.db.getAll<DbJsonRow>({
14
- table: "addon_admin_api",
15
- orderBy: ["id#ASC"]
16
- });
17
- allApis = result.data.lists;
18
-
19
- // 缓存到 Redis
20
- if (allApis.length > 0) {
21
- await befly.cache.cacheApis();
22
- }
15
+ return befly.tool.No("接口缓存不存在,请刷新缓存", { lists: [] });
23
16
  }
24
17
 
25
- const lists = allApis.filter((api): api is Record<string, unknown> => typeof api === "object" && api !== null).map((api) => api as DbJsonRow);
18
+ const lists = allApis.filter((api) => api && typeof api === "object");
26
19
 
27
20
  return befly.tool.Yes("操作成功", { lists: lists });
28
21
  } catch (error: unknown) {
package/apis/menu/all.ts CHANGED
@@ -1,61 +1,48 @@
1
1
  /**
2
2
  * 获取当前用户的菜单权限
3
3
  * 说明:
4
- * 1. 从 Redis 缓存读取所有菜单(如果缓存不存在则从数据库查询并缓存)
5
- * 2. 根据当前登录用户的角色过滤可访问的菜单
6
- * 3. 返回一维数组(由前端构建树形结构)
7
- * 4. 仅返回状态为启用的菜单
4
+ * 1. 从 Redis 缓存读取所有菜单(强制:不回退 DB)
5
+ * 2. 从 Redis Set 读取角色菜单权限(role:menus:{roleCode}),拿到该角色可访问的菜单 path 列表
6
+ * 3. 根据角色菜单 path 列表过滤可访问的菜单
7
+ * 4. 返回一维数组(由前端构建树形结构)
8
+ * 5. 仅返回状态为启用的菜单
8
9
  */
9
10
 
10
- import type { DbJsonRow } from "../../utils/dbJsonRow";
11
11
  import type { ApiRoute } from "befly/types/api";
12
+ import type { JsonValue, KeyValue } from "befly/types/common";
13
+
14
+ type MenuRow = KeyValue<JsonValue>;
12
15
 
13
16
  const route: ApiRoute = {
14
17
  name: "获取用户菜单",
15
18
  handler: async (befly, ctx) => {
16
19
  try {
17
- // 2. 查询角色信息获取菜单权限(使用 roleCode 而非 roleId)
18
- const role = await befly.db.getOne<{ id?: number; menus?: unknown }>({
19
- table: "addon_admin_role",
20
- where: { code: ctx.user["roleCode"] }
21
- });
22
-
23
- if (!role.data?.id) {
24
- return befly.tool.No("角色不存在", { lists: [] });
20
+ const roleCode = typeof ctx.user["roleCode"] === "string" ? ctx.user["roleCode"] : "";
21
+ if (roleCode.length === 0) {
22
+ return befly.tool.No("角色缺失", { lists: [] });
25
23
  }
26
24
 
27
- // 3. 解析菜单路径列表(menu.path 数组,array_text)
28
- const rawMenuPaths = Array.isArray(role.data.menus) ? role.data.menus : [];
29
- const menuPaths = rawMenuPaths.map((p: unknown) => (typeof p === "string" ? p.trim() : "")).filter((p: string) => p.length > 0);
25
+ // 2. Redis Set 读取角色菜单权限(由 core 的 cache 体系维护)
26
+ // 约定:key = role:menus:{roleCode}(会自动加上 Redis prefix)
27
+ const menuPaths = await befly.cache.getRoleMenuPermissions(roleCode);
30
28
 
31
29
  if (menuPaths.length === 0) {
32
30
  return befly.tool.Yes("菜单为空", { lists: [] });
33
31
  }
34
32
 
35
- // 4. 从缓存获取所有菜单
36
- let allMenus: unknown[] = await befly.cache.getMenus();
37
-
38
- // 如果缓存不存在,从数据库查询
39
- if (allMenus.length === 0) {
40
- const result = await befly.db.getAll<DbJsonRow>({
41
- table: "addon_admin_menu"
42
- });
43
- allMenus = result.data.lists;
44
- }
33
+ // 4. 从缓存获取所有菜单(强制:不回退 DB)
34
+ const allMenus = (await befly.cache.getMenus()) as MenuRow[];
45
35
 
46
36
  if (allMenus.length === 0) {
47
- return befly.tool.Yes("菜单为空", { lists: [] });
37
+ return befly.tool.No("菜单缓存不存在,请刷新缓存", { lists: [] });
48
38
  }
49
39
 
50
40
  // 5. 根据角色权限过滤菜单(按 menu.path)
51
41
  const menuPathSet = new Set<string>(menuPaths);
52
- const authorizedMenus = allMenus
53
- .filter((menu): menu is Record<string, unknown> => typeof menu === "object" && menu !== null)
54
- .filter((menu) => {
55
- const path = menu["path"];
56
- return typeof path === "string" && menuPathSet.has(path);
57
- })
58
- .map((menu) => menu as DbJsonRow);
42
+ const authorizedMenus = allMenus.filter((menu) => {
43
+ const path = menu["path"];
44
+ return typeof path === "string" && menuPathSet.has(path);
45
+ });
59
46
 
60
47
  // 6. 返回一维数组(由前端构建树形结构)
61
48
  return befly.tool.Yes("获取菜单成功", { lists: authorizedMenus });
package/apis/role/apis.ts CHANGED
@@ -8,20 +8,12 @@ const route: ApiRoute = {
8
8
  roleCode: adminRoleTable.code
9
9
  },
10
10
  handler: async (befly, ctx) => {
11
- // 查询角色信息
12
- const role = await befly.db.getOne({
13
- table: "addon_admin_role",
14
- where: { code: ctx.body.roleCode }
15
- });
16
-
17
- if (!role.data?.id) {
18
- return befly.tool.No("角色不存在");
11
+ const roleCode = typeof ctx.body.roleCode === "string" ? ctx.body.roleCode : "";
12
+ if (roleCode.length === 0) {
13
+ return befly.tool.No("参数不合法");
19
14
  }
20
15
 
21
- // 数据库自动将 array_text 转换为数组
22
- const rawApiPaths = Array.isArray(role.data.apis) ? role.data.apis : [];
23
- const apiPaths = rawApiPaths.map((p: unknown) => (typeof p === "string" ? p.trim() : "")).filter((p: string) => p.length > 0);
24
-
16
+ const apiPaths = await befly.cache.getRolePermissions(roleCode);
25
17
  return befly.tool.Yes("操作成功", { apiPaths: apiPaths });
26
18
  }
27
19
  };
@@ -10,6 +10,11 @@ const route: ApiRoute = {
10
10
  menuPaths: adminRoleTable.menus
11
11
  },
12
12
  handler: async (befly, ctx) => {
13
+ const roleCode = typeof ctx.body.roleCode === "string" ? ctx.body.roleCode : "";
14
+ if (roleCode.length === 0) {
15
+ return befly.tool.No("参数不合法");
16
+ }
17
+
13
18
  let menuPaths: string[] = [];
14
19
  try {
15
20
  menuPaths = normalizePathnameListInput(ctx.body.menuPaths, "menuPaths", false);
@@ -20,7 +25,7 @@ const route: ApiRoute = {
20
25
  // 查询角色是否存在
21
26
  const role = await befly.db.getOne({
22
27
  table: "addon_admin_role",
23
- where: { code: ctx.body.roleCode }
28
+ where: { code: roleCode }
24
29
  });
25
30
 
26
31
  if (!role.data?.id) {
@@ -30,12 +35,15 @@ const route: ApiRoute = {
30
35
  // 直接使用数组,数据库会自动处理存储
31
36
  await befly.db.updData({
32
37
  table: "addon_admin_role",
33
- where: { code: ctx.body.roleCode },
38
+ where: { code: roleCode },
34
39
  data: {
35
40
  menus: menuPaths
36
41
  }
37
42
  });
38
43
 
44
+ // 增量刷新 Redis 菜单权限缓存
45
+ await befly.cache.refreshRoleMenuPermissions(roleCode, menuPaths);
46
+
39
47
  return befly.tool.Yes("操作成功");
40
48
  }
41
49
  };
@@ -8,19 +8,12 @@ const route: ApiRoute = {
8
8
  roleCode: adminRoleTable.code
9
9
  },
10
10
  handler: async (befly, ctx) => {
11
- // 查询角色信息
12
- const role = await befly.db.getOne({
13
- table: "addon_admin_role",
14
- where: { code: ctx.body.roleCode }
15
- });
16
-
17
- if (!role.data?.id) {
18
- return befly.tool.No("角色不存在");
11
+ const roleCode = typeof ctx.body.roleCode === "string" ? ctx.body.roleCode : "";
12
+ if (roleCode.length === 0) {
13
+ return befly.tool.No("参数不合法");
19
14
  }
20
15
 
21
- // 数据库自动将 array_text 转换为数组
22
- const menuPaths = Array.isArray(role.data.menus) ? role.data.menus : [];
23
-
16
+ const menuPaths = await befly.cache.getRoleMenuPermissions(roleCode);
24
17
  return befly.tool.Yes("操作成功", menuPaths);
25
18
  }
26
19
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@befly-addon/admin",
3
- "version": "1.8.7",
4
- "gitHead": "f9f6bca0385e275961720d686bab20b2e2167f87",
3
+ "version": "1.8.8",
4
+ "gitHead": "8397629cd2bc2e37d91c3b15773af52ac8ff7681",
5
5
  "private": false,
6
6
  "description": "Befly - 管理后台功能组件",
7
7
  "keywords": [
@@ -54,7 +54,7 @@
54
54
  "ua-parser-js": "^2.0.8"
55
55
  },
56
56
  "devDependencies": {
57
- "befly": "^3.16.5"
57
+ "befly": "^3.16.6"
58
58
  },
59
59
  "peerDependencies": {
60
60
  "befly": "^3.14.0"