@befly-addon/admin 1.6.0 → 1.6.2

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.
@@ -30,10 +30,10 @@ export default {
30
30
  });
31
31
 
32
32
  await befly.redis.setObject("apis:all", apis.data.lists);
33
- results.apis = { success: true, count: apis.data.lists.length };
33
+ results["apis"] = { success: true, count: apis.data.lists.length };
34
34
  } catch (error: any) {
35
35
  befly.logger.error({ err: error, msg: "刷新接口缓存失败" });
36
- results.apis = { success: false, error: error.message };
36
+ results["apis"] = { success: false, error: error.message };
37
37
  }
38
38
 
39
39
  // 2. 刷新菜单缓存
@@ -47,7 +47,7 @@ export default {
47
47
  const parentCount = menus.data.lists.filter((m: any) => typeof m.parentPath !== "string" || m.parentPath.length === 0).length;
48
48
  const childCount = menus.data.lists.filter((m: any) => typeof m.parentPath === "string" && m.parentPath.length > 0).length;
49
49
 
50
- results.menus = {
50
+ results["menus"] = {
51
51
  success: true,
52
52
  count: menus.data.lists.length,
53
53
  parentCount: parentCount,
@@ -55,7 +55,7 @@ export default {
55
55
  };
56
56
  } catch (error: any) {
57
57
  befly.logger.error({ err: error, msg: "刷新菜单缓存失败" });
58
- results.menus = { success: false, error: error.message };
58
+ results["menus"] = { success: false, error: error.message };
59
59
  }
60
60
 
61
61
  // 3. 刷新角色权限缓存
@@ -72,23 +72,23 @@ export default {
72
72
  }))
73
73
  );
74
74
 
75
- results.roles = { success: true, count: count };
75
+ results["roles"] = { success: true, count: count };
76
76
  } catch (error: any) {
77
77
  befly.logger.error({ err: error, msg: "刷新角色缓存失败" });
78
- results.roles = { success: false, error: error.message };
78
+ results["roles"] = { success: false, error: error.message };
79
79
  }
80
80
 
81
81
  // 4. 重建角色接口权限缓存(版本化 + 原子切换)
82
82
  try {
83
83
  await befly.cache.rebuildRoleApiPermissions();
84
- results.roleApiPermissions = { success: true };
84
+ results["roleApiPermissions"] = { success: true };
85
85
  } catch (error: any) {
86
86
  befly.logger.error({ err: error, msg: "重建角色接口权限缓存失败" });
87
- results.roleApiPermissions = { success: false, error: error.message };
87
+ results["roleApiPermissions"] = { success: false, error: error.message };
88
88
  }
89
89
 
90
90
  // 检查是否全部成功
91
- const allSuccess = results.apis.success && results.menus.success && results.roles.success && results.roleApiPermissions.success;
91
+ const allSuccess = results["apis"].success && results["menus"].success && results["roles"].success && results["roleApiPermissions"].success;
92
92
 
93
93
  if (allSuccess) {
94
94
  return befly.tool.Yes("全部缓存刷新成功", results);
package/apis/admin/del.ts CHANGED
@@ -1,7 +1,11 @@
1
- export default {
1
+ import type { ApiRoute } from "befly/types/api";
2
+
3
+ import { fieldsScheme } from "../../utils/fieldsScheme";
4
+
5
+ const route: ApiRoute = {
2
6
  name: "删除管理员",
3
7
  fields: {
4
- id: "@id"
8
+ id: fieldsScheme.id
5
9
  },
6
10
  required: ["id"],
7
11
  handler: async (befly, ctx) => {
@@ -29,3 +33,5 @@ export default {
29
33
  return befly.tool.Yes("删除成功");
30
34
  }
31
35
  };
36
+
37
+ export default route;
@@ -1,7 +1,11 @@
1
- export default {
1
+ import type { ApiRoute } from "befly/types/api";
2
+
3
+ import { fieldsScheme } from "../../utils/fieldsScheme";
4
+
5
+ const route: ApiRoute = {
2
6
  name: "获取管理员信息",
3
7
  fields: {
4
- id: "@id"
8
+ id: fieldsScheme.id
5
9
  },
6
10
  handler: async (befly, ctx) => {
7
11
  const adminData = await befly.db.getOne({
@@ -17,3 +21,5 @@ export default {
17
21
  return befly.tool.Yes("查询成功", adminData.data);
18
22
  }
19
23
  };
24
+
25
+ export default route;
package/apis/admin/ins.ts CHANGED
@@ -1,12 +1,14 @@
1
+ import type { ApiRoute } from "befly/types/api";
2
+
1
3
  import adminTable from "../../tables/admin.json";
2
4
 
3
- export default {
5
+ const route: ApiRoute = {
4
6
  name: "添加管理员",
5
7
  fields: adminTable,
6
8
  required: ["username", "password", "roleCode"],
7
9
  handler: async (befly, ctx) => {
8
10
  // 检查用户名是否已存在
9
- const existingByUsername = await befly.db.getOne({
11
+ const existingByUsername = await befly.db.getOne<{ id?: number }>({
10
12
  table: "addon_admin_admin",
11
13
  where: { username: ctx.body.username }
12
14
  });
@@ -17,7 +19,7 @@ export default {
17
19
 
18
20
  // 检查昵称是否已存在
19
21
  if (ctx.body.nickname) {
20
- const existingByNickname = await befly.db.getOne({
22
+ const existingByNickname = await befly.db.getOne<{ id?: number }>({
21
23
  table: "addon_admin_admin",
22
24
  where: { nickname: ctx.body.nickname }
23
25
  });
@@ -28,7 +30,7 @@ export default {
28
30
  }
29
31
 
30
32
  // 查询角色信息
31
- const roleData = await befly.db.getOne({
33
+ const roleData = await befly.db.getOne<{ id?: number }>({
32
34
  table: "addon_admin_role",
33
35
  where: { code: ctx.body.roleCode }
34
36
  });
@@ -56,3 +58,5 @@ export default {
56
58
  });
57
59
  }
58
60
  };
61
+
62
+ export default route;
@@ -1,10 +1,14 @@
1
- export default {
1
+ import type { ApiRoute } from "befly/types/api";
2
+
3
+ import { fieldsScheme } from "../../utils/fieldsScheme";
4
+
5
+ const route: ApiRoute = {
2
6
  name: "查询管理员列表",
3
7
  fields: {
4
- page: "@page",
5
- limit: "@limit",
6
- keyword: "@keyword",
7
- state: "@state"
8
+ page: fieldsScheme.page,
9
+ limit: fieldsScheme.limit,
10
+ keyword: fieldsScheme.keyword,
11
+ state: fieldsScheme.state
8
12
  },
9
13
  handler: async (befly, ctx) => {
10
14
  const result = await befly.db.getList({
@@ -22,3 +26,5 @@ export default {
22
26
  return befly.tool.Yes("获取成功", result.data);
23
27
  }
24
28
  };
29
+
30
+ export default route;
package/apis/admin/upd.ts CHANGED
@@ -1,14 +1,26 @@
1
+ import type { ApiRoute } from "befly/types/api";
2
+
1
3
  import adminTable from "../../tables/admin.json";
4
+ import { fieldsScheme } from "../../utils/fieldsScheme";
5
+ import { mergeTableFields } from "../../utils/mergeTableFields";
2
6
 
3
- export default {
7
+ const route: ApiRoute = {
4
8
  name: "更新管理员",
5
- fields: { id: "@id", ...adminTable },
9
+ fields: mergeTableFields(adminTable, { id: fieldsScheme.id }),
6
10
  required: ["id"],
7
11
  handler: async (befly, ctx) => {
8
- const { id, username, nickname, roleCode, ...updateData } = ctx.body;
12
+ const id = ctx.body.id;
13
+ const username = ctx.body.username;
14
+ const nickname = ctx.body.nickname;
15
+ const roleCode = ctx.body.roleCode;
9
16
 
10
17
  // 检查管理员是否存在
11
- const admin = await befly.db.getOne({
18
+ const admin = await befly.db.getOne<{
19
+ id?: number;
20
+ username?: string;
21
+ nickname?: string;
22
+ roleCode?: string;
23
+ }>({
12
24
  table: "addon_admin_admin",
13
25
  where: { id }
14
26
  });
@@ -19,7 +31,7 @@ export default {
19
31
 
20
32
  // 检查用户名是否已被其他管理员使用
21
33
  if (username && username !== admin.data.username) {
22
- const existingUsername = await befly.db.getOne({
34
+ const existingUsername = await befly.db.getOne<{ id?: number }>({
23
35
  table: "addon_admin_admin",
24
36
  where: { username, id: { $ne: id } }
25
37
  });
@@ -30,7 +42,7 @@ export default {
30
42
 
31
43
  // 检查昵称是否已被其他管理员使用
32
44
  if (nickname && nickname !== admin.data.nickname) {
33
- const existingNickname = await befly.db.getOne({
45
+ const existingNickname = await befly.db.getOne<{ id?: number }>({
34
46
  table: "addon_admin_admin",
35
47
  where: { nickname, id: { $ne: id } }
36
48
  });
@@ -41,7 +53,7 @@ export default {
41
53
 
42
54
  // 检查角色是否存在
43
55
  if (roleCode && roleCode !== admin.data.roleCode) {
44
- const role = await befly.db.getOne({
56
+ const role = await befly.db.getOne<{ id?: number }>({
45
57
  table: "addon_admin_role",
46
58
  where: { code: roleCode }
47
59
  });
@@ -51,10 +63,19 @@ export default {
51
63
  }
52
64
 
53
65
  // 构建更新数据
54
- const dataToUpdate: Record<string, any> = { ...updateData };
55
- if (username) dataToUpdate.username = username;
56
- if (nickname) dataToUpdate.nickname = nickname;
57
- if (roleCode) dataToUpdate.roleCode = roleCode;
66
+ const dataToUpdate: Record<string, any> = {};
67
+
68
+ if (ctx.body.avatar !== undefined) dataToUpdate["avatar"] = ctx.body.avatar;
69
+ if (ctx.body.email !== undefined) dataToUpdate["email"] = ctx.body.email;
70
+ if (ctx.body.lastLoginIp !== undefined) dataToUpdate["lastLoginIp"] = ctx.body.lastLoginIp;
71
+ if (ctx.body.lastLoginTime !== undefined) dataToUpdate["lastLoginTime"] = ctx.body.lastLoginTime;
72
+ if (ctx.body.password !== undefined) dataToUpdate["password"] = ctx.body.password;
73
+ if (ctx.body.phone !== undefined) dataToUpdate["phone"] = ctx.body.phone;
74
+ if (ctx.body.roleType !== undefined) dataToUpdate["roleType"] = ctx.body.roleType;
75
+
76
+ if (username !== undefined) dataToUpdate["username"] = username;
77
+ if (nickname !== undefined) dataToUpdate["nickname"] = nickname;
78
+ if (roleCode !== undefined) dataToUpdate["roleCode"] = roleCode;
58
79
 
59
80
  // 更新管理员信息
60
81
  await befly.db.updData({
@@ -66,3 +87,5 @@ export default {
66
87
  return befly.tool.Yes("更新成功");
67
88
  }
68
89
  };
90
+
91
+ export default route;
package/apis/api/list.ts CHANGED
@@ -1,10 +1,14 @@
1
- export default {
1
+ import type { ApiRoute } from "befly/types/api";
2
+
3
+ import { fieldsScheme } from "../../utils/fieldsScheme";
4
+
5
+ const route: ApiRoute = {
2
6
  name: "获取接口列表",
3
7
  fields: {
4
- page: "@page",
5
- limit: "@limit",
6
- keyword: "@keyword",
7
- state: "@state"
8
+ page: fieldsScheme.page,
9
+ limit: fieldsScheme.limit,
10
+ keyword: fieldsScheme.keyword,
11
+ state: fieldsScheme.state
8
12
  },
9
13
  handler: async (befly, ctx) => {
10
14
  try {
@@ -25,3 +29,5 @@ export default {
25
29
  }
26
30
  }
27
31
  };
32
+
33
+ export default route;
@@ -1,8 +1,10 @@
1
+ import type { ApiRoute } from "befly/types/api";
2
+
1
3
  import { UAParser } from "ua-parser-js";
2
4
 
3
5
  import adminTable from "../../tables/admin.json";
4
6
 
5
- export default {
7
+ const route: ApiRoute = {
6
8
  name: "管理员登录",
7
9
  auth: false,
8
10
  fields: {
@@ -10,12 +12,17 @@ export default {
10
12
  name: "账号",
11
13
  type: "string",
12
14
  min: 3,
13
- max: 100
15
+ max: 100,
16
+ default: null,
17
+ regexp: null
14
18
  },
15
19
  password: adminTable.password,
16
20
  loginType: {
17
21
  name: "登录类型",
18
22
  type: "string",
23
+ min: null,
24
+ max: null,
25
+ default: null,
19
26
  regexp: "^(username|email|phone)$"
20
27
  }
21
28
  },
@@ -47,22 +54,30 @@ export default {
47
54
  };
48
55
 
49
56
  // 根据登录类型构建查询条件
50
- const whereCondition: Record<string, any> = {};
57
+ const whereCondition: Record<string, unknown> = {};
51
58
  if (ctx.body.loginType === "username") {
52
- whereCondition.username = ctx.body.account;
59
+ whereCondition["username"] = ctx.body.account;
53
60
  } else if (ctx.body.loginType === "email") {
54
- whereCondition.email = ctx.body.account;
61
+ whereCondition["email"] = ctx.body.account;
55
62
  } else if (ctx.body.loginType === "phone") {
56
- whereCondition.phone = ctx.body.account;
63
+ whereCondition["phone"] = ctx.body.account;
57
64
  }
58
65
 
59
66
  // 查询管理员
60
- const admin = await befly.db.getOne({
67
+ const admin = await befly.db.getOne<{
68
+ id?: number;
69
+ username?: string;
70
+ nickname?: string;
71
+ password?: string;
72
+ state?: number;
73
+ roleCode?: string;
74
+ roleType?: string;
75
+ }>({
61
76
  table: "addon_admin_admin",
62
77
  where: whereCondition
63
78
  });
64
79
 
65
- if (!admin.data?.id) {
80
+ if (!admin.data?.id || typeof admin.data.username !== "string" || typeof admin.data.password !== "string") {
66
81
  logData.failReason = "账号不存在";
67
82
  await befly.db.insData({ table: "addon_admin_login_log", data: logData });
68
83
  return befly.tool.No("账号或密码错误");
@@ -81,7 +96,7 @@ export default {
81
96
  await befly.db.insData({ table: "addon_admin_login_log", data: logData });
82
97
  return befly.tool.No("账号或密码错误");
83
98
  }
84
- } catch (error: any) {
99
+ } catch (error: unknown) {
85
100
  befly.logger.error({ err: error, msg: "密码验证失败" });
86
101
  logData.failReason = "密码格式错误";
87
102
  await befly.db.insData({ table: "addon_admin_login_log", data: logData });
@@ -113,11 +128,20 @@ export default {
113
128
  );
114
129
 
115
130
  // 返回用户信息(不包含密码)
116
- const { password: _, ...userWithoutPassword } = admin.data;
131
+ const userInfo = {
132
+ id: admin.data.id,
133
+ username: admin.data.username,
134
+ nickname: admin.data.nickname,
135
+ state: admin.data.state,
136
+ roleCode: admin.data.roleCode,
137
+ roleType: admin.data.roleType
138
+ };
117
139
 
118
140
  return befly.tool.Yes("登录成功", {
119
141
  token: token,
120
- userInfo: userWithoutPassword
142
+ userInfo: userInfo
121
143
  });
122
144
  }
123
145
  };
146
+
147
+ export default route;
package/apis/dict/del.ts CHANGED
@@ -1,6 +1,10 @@
1
- export default {
1
+ import type { ApiRoute } from "befly/types/api";
2
+
3
+ import { fieldsScheme } from "../../utils/fieldsScheme";
4
+
5
+ const route: ApiRoute = {
2
6
  name: "删除字典",
3
- fields: { "@id": true },
7
+ fields: { id: fieldsScheme.id },
4
8
  required: ["id"],
5
9
  handler: async (befly, ctx) => {
6
10
  await befly.db.delData({
@@ -11,3 +15,5 @@ export default {
11
15
  return befly.tool.Yes("删除成功");
12
16
  }
13
17
  };
18
+
19
+ export default route;
@@ -1,6 +1,10 @@
1
- export default {
1
+ import type { ApiRoute } from "befly/types/api";
2
+
3
+ import { fieldsScheme } from "../../utils/fieldsScheme";
4
+
5
+ const route: ApiRoute = {
2
6
  name: "获取字典详情",
3
- fields: { "@id": true },
7
+ fields: { id: fieldsScheme.id },
4
8
  required: ["id"],
5
9
  handler: async (befly, ctx) => {
6
10
  const dict = await befly.db.getOne({
@@ -34,3 +38,5 @@ export default {
34
38
  return befly.tool.Yes("获取成功", dict.data);
35
39
  }
36
40
  };
41
+
42
+ export default route;
package/apis/dict/ins.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import type { ApiRoute } from "befly/types/api";
2
+
1
3
  import adminDictTable from "../../tables/dict.json";
2
4
 
3
5
  export default {
@@ -6,7 +8,7 @@ export default {
6
8
  required: ["typeCode", "key", "label"],
7
9
  handler: async (befly, ctx) => {
8
10
  // 验证 typeCode 是否存在
9
- const dictType = await befly.db.getOne({
11
+ const dictType = await befly.db.getOne<{ id?: number }>({
10
12
  table: "addon_admin_dict_type",
11
13
  where: { code: ctx.body.typeCode }
12
14
  });
@@ -16,7 +18,7 @@ export default {
16
18
  }
17
19
 
18
20
  // 检查 typeCode+key 是否已存在
19
- const existing = await befly.db.getOne({
21
+ const existing = await befly.db.getOne<{ id?: number }>({
20
22
  table: "addon_admin_dict",
21
23
  where: {
22
24
  typeCode: ctx.body.typeCode,
@@ -41,4 +43,4 @@ export default {
41
43
 
42
44
  return befly.tool.Yes("添加成功", { id: dictId.data });
43
45
  }
44
- };
46
+ } as unknown as ApiRoute;
@@ -1,3 +1,5 @@
1
+ import type { ApiRoute } from "befly/types/api";
2
+
1
3
  export default {
2
4
  name: "获取字典项列表",
3
5
  fields: {
@@ -6,7 +8,7 @@ export default {
6
8
  required: ["typeCode"],
7
9
  handler: async (befly, ctx) => {
8
10
  // 验证 typeCode 是否存在
9
- const dictType = await befly.db.getOne({
11
+ const dictType = await befly.db.getOne<{ id?: number }>({
10
12
  table: "addon_admin_dict_type",
11
13
  where: { code: ctx.body.typeCode }
12
14
  });
@@ -24,4 +26,4 @@ export default {
24
26
 
25
27
  return befly.tool.Yes("获取成功", items.data);
26
28
  }
27
- };
29
+ } as unknown as ApiRoute;
package/apis/dict/list.ts CHANGED
@@ -1,10 +1,15 @@
1
- export default {
1
+ import type { ApiRoute } from "befly/types/api";
2
+
3
+ import dictTable from "../../tables/dict.json";
4
+ import { fieldsScheme } from "../../utils/fieldsScheme";
5
+
6
+ const route: ApiRoute = {
2
7
  name: "获取字典列表",
3
8
  fields: {
4
- page: "@page",
5
- limit: "@limit",
6
- typeCode: { type: "string", label: "类型代码" },
7
- keyword: "@keyword"
9
+ page: fieldsScheme.page,
10
+ limit: fieldsScheme.limit,
11
+ typeCode: dictTable.typeCode,
12
+ keyword: fieldsScheme.keyword
8
13
  },
9
14
  handler: async (befly, ctx) => {
10
15
  const where: any = {};
@@ -43,3 +48,5 @@ export default {
43
48
  return befly.tool.Yes("获取成功", result.data);
44
49
  }
45
50
  };
51
+
52
+ export default route;
package/apis/dict/upd.ts CHANGED
@@ -1,18 +1,19 @@
1
+ import type { ApiRoute } from "befly/types/api";
2
+
1
3
  import adminDictTable from "../../tables/dict.json";
4
+ import { fieldsScheme } from "../../utils/fieldsScheme";
5
+ import { mergeTableFields } from "../../utils/mergeTableFields";
2
6
 
3
- export default {
7
+ const route: ApiRoute = {
4
8
  name: "更新字典",
5
- fields: {
6
- ...adminDictTable,
7
- "@id": true
8
- },
9
+ fields: mergeTableFields(adminDictTable, { id: fieldsScheme.id }),
9
10
  required: ["id"],
10
11
  handler: async (befly, ctx) => {
11
12
  const { id, typeCode, key, label, sort, remark } = ctx.body;
12
13
 
13
14
  // 如果更新了 typeCode,验证其是否存在
14
15
  if (typeCode) {
15
- const dictType = await befly.db.getOne({
16
+ const dictType = await befly.db.getOne<{ id?: number }>({
16
17
  table: "addon_admin_dict_type",
17
18
  where: { code: typeCode }
18
19
  });
@@ -24,7 +25,7 @@ export default {
24
25
 
25
26
  // 如果更新了 typeCode 或 key,检查唯一性
26
27
  if (typeCode || key) {
27
- const current = await befly.db.getOne({
28
+ const current = await befly.db.getOne<{ typeCode?: string; key?: string }>({
28
29
  table: "addon_admin_dict",
29
30
  where: { id: id }
30
31
  });
@@ -32,7 +33,7 @@ export default {
32
33
  const checkTypeCode = typeCode || current.data?.typeCode;
33
34
  const checkKey = key || current.data?.key;
34
35
 
35
- const existing = await befly.db.getOne({
36
+ const existing = await befly.db.getOne<{ id?: number }>({
36
37
  table: "addon_admin_dict",
37
38
  where: {
38
39
  typeCode: checkTypeCode,
@@ -47,11 +48,11 @@ export default {
47
48
  }
48
49
 
49
50
  const updateData: Record<string, any> = {};
50
- if (typeCode !== undefined) updateData.typeCode = typeCode;
51
- if (key !== undefined) updateData.key = key;
52
- if (label !== undefined) updateData.label = label;
53
- if (sort !== undefined) updateData.sort = sort;
54
- if (remark !== undefined) updateData.remark = remark;
51
+ if (typeCode !== undefined) updateData["typeCode"] = typeCode;
52
+ if (key !== undefined) updateData["key"] = key;
53
+ if (label !== undefined) updateData["label"] = label;
54
+ if (sort !== undefined) updateData["sort"] = sort;
55
+ if (remark !== undefined) updateData["remark"] = remark;
55
56
 
56
57
  await befly.db.updData({
57
58
  table: "addon_admin_dict",
@@ -62,3 +63,5 @@ export default {
62
63
  return befly.tool.Yes("更新成功");
63
64
  }
64
65
  };
66
+
67
+ export default route;
@@ -1,11 +1,15 @@
1
- export default {
1
+ import type { ApiRoute } from "befly/types/api";
2
+
3
+ import { fieldsScheme } from "../../utils/fieldsScheme";
4
+
5
+ const route: ApiRoute = {
2
6
  name: "删除字典类型",
3
- fields: { "@id": true },
7
+ fields: { id: fieldsScheme.id },
4
8
  required: ["id"],
5
9
  handler: async (befly, ctx) => {
6
10
  const { id } = ctx.body;
7
11
 
8
- const dictType = await befly.db.getOne({
12
+ const dictType = await befly.db.getOne<{ code?: string }>({
9
13
  table: "addon_admin_dict_type",
10
14
  where: { id: id }
11
15
  });
@@ -15,7 +19,7 @@ export default {
15
19
  }
16
20
 
17
21
  // 检查是否有字典项引用此类型
18
- const dictItems = await befly.db.getOne({
22
+ const dictItems = await befly.db.getOne<{ id?: number }>({
19
23
  table: "addon_admin_dict",
20
24
  where: {
21
25
  typeCode: dictType.data.code
@@ -34,3 +38,5 @@ export default {
34
38
  return befly.tool.Yes("删除成功");
35
39
  }
36
40
  };
41
+
42
+ export default route;
@@ -1,6 +1,10 @@
1
- export default {
1
+ import type { ApiRoute } from "befly/types/api";
2
+
3
+ import { fieldsScheme } from "../../utils/fieldsScheme";
4
+
5
+ const route: ApiRoute = {
2
6
  name: "字典类型详情",
3
- fields: { "@id": true },
7
+ fields: { id: fieldsScheme.id },
4
8
  required: ["id"],
5
9
  handler: async (befly, ctx) => {
6
10
  const detail = await befly.db.getOne({
@@ -15,3 +19,5 @@ export default {
15
19
  return befly.tool.Yes("获取成功", detail.data);
16
20
  }
17
21
  };
22
+
23
+ export default route;
@@ -1,10 +1,14 @@
1
- export default {
1
+ import type { ApiRoute } from "befly/types/api";
2
+
3
+ import { fieldsScheme } from "../../utils/fieldsScheme";
4
+
5
+ const route: ApiRoute = {
2
6
  name: "获取字典类型列表",
3
7
  fields: {
4
- page: "@page",
5
- limit: "@limit",
6
- keyword: "@keyword",
7
- state: "@state"
8
+ page: fieldsScheme.page,
9
+ limit: fieldsScheme.limit,
10
+ keyword: fieldsScheme.keyword,
11
+ state: fieldsScheme.state
8
12
  },
9
13
  handler: async (befly, ctx) => {
10
14
  const result = await befly.db.getList({
@@ -20,3 +24,5 @@ export default {
20
24
  return befly.tool.Yes("操作成功", result.data);
21
25
  }
22
26
  };
27
+
28
+ export default route;
@@ -1,11 +1,12 @@
1
+ import type { ApiRoute } from "befly/types/api";
2
+
1
3
  import dictTypeTable from "../../tables/dictType.json";
4
+ import { fieldsScheme } from "../../utils/fieldsScheme";
5
+ import { mergeTableFields } from "../../utils/mergeTableFields";
2
6
 
3
- export default {
7
+ const route: ApiRoute = {
4
8
  name: "更新字典类型",
5
- fields: {
6
- ...dictTypeTable,
7
- "@id": true
8
- },
9
+ fields: mergeTableFields(dictTypeTable, { id: fieldsScheme.id }),
9
10
  required: ["id"],
10
11
  handler: async (befly, ctx) => {
11
12
  const { id, code, name, description, sort } = ctx.body;
@@ -26,10 +27,10 @@ export default {
26
27
  }
27
28
 
28
29
  const updateData: Record<string, any> = {};
29
- if (code !== undefined) updateData.code = code;
30
- if (name !== undefined) updateData.name = name;
31
- if (description !== undefined) updateData.description = description;
32
- if (sort !== undefined) updateData.sort = sort;
30
+ if (code !== undefined) updateData["code"] = code;
31
+ if (name !== undefined) updateData["name"] = name;
32
+ if (description !== undefined) updateData["description"] = description;
33
+ if (sort !== undefined) updateData["sort"] = sort;
33
34
 
34
35
  await befly.db.updData({
35
36
  table: "addon_admin_dict_type",
@@ -40,3 +41,5 @@ export default {
40
41
  return befly.tool.Yes("更新成功");
41
42
  }
42
43
  };
44
+
45
+ export default route;
@@ -14,7 +14,7 @@ export default {
14
14
  user: config.user,
15
15
  pass: config.pass,
16
16
  fromName: config.fromName,
17
- configured: !!config.user
17
+ configured: Boolean(config.user)
18
18
  });
19
19
  }
20
20
  };
@@ -1,10 +1,14 @@
1
- export default {
1
+ import type { ApiRoute } from "befly/types/api";
2
+
3
+ import { fieldsScheme } from "../../utils/fieldsScheme";
4
+
5
+ const route: ApiRoute = {
2
6
  name: "邮件发送日志列表",
3
7
  fields: {
4
- page: "@page",
5
- limit: "@limit",
6
- keyword: "@keyword",
7
- state: "@state"
8
+ page: fieldsScheme.page,
9
+ limit: fieldsScheme.limit,
10
+ keyword: fieldsScheme.keyword,
11
+ state: fieldsScheme.state
8
12
  },
9
13
  handler: async (befly, ctx) => {
10
14
  const result = await befly.db.getList({
@@ -17,3 +21,5 @@ export default {
17
21
  return befly.tool.Yes("获取成功", result.data);
18
22
  }
19
23
  };
24
+
25
+ export default route;
@@ -1,10 +1,14 @@
1
- export default {
1
+ import type { ApiRoute } from "befly/types/api";
2
+
3
+ import { fieldsScheme } from "../../utils/fieldsScheme";
4
+
5
+ const route: ApiRoute = {
2
6
  name: "获取登录日志列表",
3
7
  fields: {
4
- page: "@page",
5
- limit: "@limit",
6
- keyword: "@keyword",
7
- state: "@state"
8
+ page: fieldsScheme.page,
9
+ limit: fieldsScheme.limit,
10
+ keyword: fieldsScheme.keyword,
11
+ state: fieldsScheme.state
8
12
  },
9
13
  handler: async (befly, ctx) => {
10
14
  const result = await befly.db.getList({
@@ -17,3 +21,5 @@ export default {
17
21
  return befly.tool.Yes("获取成功", result.data);
18
22
  }
19
23
  };
24
+
25
+ export default route;
package/apis/menu/all.ts CHANGED
@@ -7,14 +7,16 @@
7
7
  * 4. 仅返回状态为启用的菜单
8
8
  */
9
9
 
10
+ import type { ApiRoute } from "befly/types/api";
11
+
10
12
  export default {
11
13
  name: "获取用户菜单",
12
14
  handler: async (befly, ctx) => {
13
15
  try {
14
16
  // 2. 查询角色信息获取菜单权限(使用 roleCode 而非 roleId)
15
- const role = await befly.db.getOne({
17
+ const role = await befly.db.getOne<{ id?: number; menus?: unknown }>({
16
18
  table: "addon_admin_role",
17
- where: { code: ctx.user.roleCode }
19
+ where: { code: ctx.user["roleCode"] }
18
20
  });
19
21
 
20
22
  if (!role.data?.id) {
@@ -23,7 +25,7 @@ export default {
23
25
 
24
26
  // 3. 解析菜单路径列表(menu.path 数组,array_text)
25
27
  const rawMenuPaths = Array.isArray(role.data.menus) ? role.data.menus : [];
26
- const menuPaths = rawMenuPaths.map((p: any) => (typeof p === "string" ? p.trim() : "")).filter((p: string) => p.length > 0);
28
+ const menuPaths = rawMenuPaths.map((p: unknown) => (typeof p === "string" ? p.trim() : "")).filter((p: string) => p.length > 0);
27
29
 
28
30
  if (menuPaths.length === 0) {
29
31
  return befly.tool.Yes("菜单为空", { lists: [] });
@@ -46,13 +48,19 @@ export default {
46
48
 
47
49
  // 5. 根据角色权限过滤菜单(按 menu.path)
48
50
  const menuPathSet = new Set<string>(menuPaths);
49
- const authorizedMenus = allMenus.filter((menu: any) => typeof menu?.path === "string" && menuPathSet.has(String(menu.path)));
51
+ const authorizedMenus = allMenus.filter((menu: unknown) => {
52
+ if (typeof menu !== "object" || menu === null) {
53
+ return false;
54
+ }
55
+ const path = (menu as { path?: unknown }).path;
56
+ return typeof path === "string" && menuPathSet.has(path);
57
+ });
50
58
 
51
59
  // 6. 返回一维数组(由前端构建树形结构)
52
60
  return befly.tool.Yes("获取菜单成功", { lists: authorizedMenus });
53
- } catch (error: any) {
61
+ } catch (error: unknown) {
54
62
  befly.logger.error({ err: error, msg: "获取用户菜单失败" });
55
63
  return befly.tool.No("获取菜单失败");
56
64
  }
57
65
  }
58
- };
66
+ } as unknown as ApiRoute;
package/apis/menu/list.ts CHANGED
@@ -1,12 +1,16 @@
1
- export default {
1
+ import type { ApiRoute } from "befly/types/api";
2
+
3
+ import { fieldsScheme } from "../../utils/fieldsScheme";
4
+
5
+ const route: ApiRoute = {
2
6
  name: "获取菜单列表",
3
7
  fields: {
4
- page: "@page",
5
- limit: "@limit",
6
- keyword: "@keyword",
7
- state: "@state"
8
+ page: fieldsScheme.page,
9
+ limit: fieldsScheme.limit,
10
+ keyword: fieldsScheme.keyword,
11
+ state: fieldsScheme.state
8
12
  },
9
- handler: async (befly) => {
13
+ handler: async (befly, _ctx) => {
10
14
  try {
11
15
  const menus = await befly.db.getAll({
12
16
  table: "addon_admin_menu"
@@ -19,3 +23,5 @@ export default {
19
23
  }
20
24
  }
21
25
  };
26
+
27
+ export default route;
@@ -1,10 +1,14 @@
1
- export default {
1
+ import type { ApiRoute } from "befly/types/api";
2
+
3
+ import { fieldsScheme } from "../../utils/fieldsScheme";
4
+
5
+ const route: ApiRoute = {
2
6
  name: "获取操作日志列表",
3
7
  fields: {
4
- page: "@page",
5
- limit: "@limit",
6
- keyword: "@keyword",
7
- state: "@state"
8
+ page: fieldsScheme.page,
9
+ limit: fieldsScheme.limit,
10
+ keyword: fieldsScheme.keyword,
11
+ state: fieldsScheme.state
8
12
  },
9
13
  handler: async (befly, ctx) => {
10
14
  const result = await befly.db.getList({
@@ -17,3 +21,5 @@ export default {
17
21
  return befly.tool.Yes("获取成功", result.data);
18
22
  }
19
23
  };
24
+
25
+ export default route;
@@ -1,3 +1,5 @@
1
+ import type { ApiRoute } from "befly/types/api";
2
+
1
3
  import adminRoleTable from "../../tables/role.json";
2
4
  import { normalizePathnameListInput } from "../../utils/normalizePathnameListInput";
3
5
 
@@ -11,12 +13,13 @@ export default {
11
13
  let apiPaths: string[] = [];
12
14
  try {
13
15
  apiPaths = normalizePathnameListInput(ctx.body.apiPaths, "apiPaths", true);
14
- } catch (error: any) {
15
- return befly.tool.No(`参数不合法:${error?.message || "未知错误"}`);
16
+ } catch (error: unknown) {
17
+ const msg = error instanceof Error ? error.message : "未知错误";
18
+ return befly.tool.No(`参数不合法:${msg}`);
16
19
  }
17
20
 
18
21
  // 查询角色是否存在
19
- const role = await befly.db.getOne({
22
+ const role = await befly.db.getOne<{ id?: number; code?: string }>({
20
23
  table: "addon_admin_role",
21
24
  where: { code: ctx.body.roleCode }
22
25
  });
@@ -25,6 +28,11 @@ export default {
25
28
  return befly.tool.No("角色不存在");
26
29
  }
27
30
 
31
+ const roleCode = role.data.code;
32
+ if (typeof roleCode !== "string" || roleCode.length === 0) {
33
+ return befly.tool.No("角色不存在");
34
+ }
35
+
28
36
  // 直接使用数组,数据库会自动处理存储
29
37
  await befly.db.updData({
30
38
  table: "addon_admin_role",
@@ -35,8 +43,8 @@ export default {
35
43
  });
36
44
 
37
45
  // 增量刷新 Redis 权限缓存
38
- await befly.cache.refreshRoleApiPermissions(role.data.code, apiPaths);
46
+ await befly.cache.refreshRoleApiPermissions(roleCode, apiPaths);
39
47
 
40
48
  return befly.tool.Yes("操作成功");
41
49
  }
42
- };
50
+ } as unknown as ApiRoute;
package/apis/role/del.ts CHANGED
@@ -1,8 +1,13 @@
1
- export default {
1
+ import type { ApiRoute } from "befly/types/api";
2
+
3
+ import { fieldsScheme } from "../../utils/fieldsScheme";
4
+
5
+ const route: ApiRoute = {
2
6
  name: "删除角色",
3
7
  fields: {
4
- id: "@id"
8
+ id: fieldsScheme.id
5
9
  },
10
+ required: ["id"],
6
11
  handler: async (befly, ctx) => {
7
12
  try {
8
13
  // 检查是否有用户使用此角色(使用 getList 代替 getAll)
@@ -47,3 +52,5 @@ export default {
47
52
  }
48
53
  }
49
54
  };
55
+
56
+ export default route;
@@ -1,7 +1,11 @@
1
- export default {
1
+ import type { ApiRoute } from "befly/types/api";
2
+
3
+ import roleTable from "../../tables/role.json";
4
+
5
+ const route: ApiRoute = {
2
6
  name: "获取用户角色",
3
7
  fields: {
4
- id: "@id"
8
+ id: roleTable.code
5
9
  },
6
10
  handler: async (befly, ctx) => {
7
11
  let roleInfo = null;
@@ -11,7 +15,10 @@ export default {
11
15
  where: { code: ctx.body.id }
12
16
  });
13
17
 
14
- roleInfo = roleInfoResult.data;
18
+ const roleId = (roleInfoResult.data as { id?: number }).id;
19
+ if (typeof roleId === "number") {
20
+ roleInfo = roleInfoResult.data;
21
+ }
15
22
  }
16
23
 
17
24
  return befly.tool.Yes("操作成功", {
@@ -20,3 +27,5 @@ export default {
20
27
  });
21
28
  }
22
29
  };
30
+
31
+ export default route;
package/apis/role/list.ts CHANGED
@@ -1,12 +1,16 @@
1
- export default {
1
+ import type { ApiRoute } from "befly/types/api";
2
+
3
+ import { fieldsScheme } from "../../utils/fieldsScheme";
4
+
5
+ const route: ApiRoute = {
2
6
  name: "获取角色列表",
3
7
  fields: {
4
- page: "@page",
5
- limit: "@limit",
6
- keyword: "@keyword",
7
- state: "@state"
8
+ page: fieldsScheme.page,
9
+ limit: fieldsScheme.limit,
10
+ keyword: fieldsScheme.keyword,
11
+ state: fieldsScheme.state
8
12
  },
9
- handler: async (befly) => {
13
+ handler: async (befly, _ctx) => {
10
14
  const roles = await befly.db.getList({
11
15
  limit: 30,
12
16
  table: "addon_admin_role",
@@ -21,3 +25,5 @@ export default {
21
25
  return befly.tool.Yes("操作成功", roles.data);
22
26
  }
23
27
  };
28
+
29
+ export default route;
@@ -1,8 +1,13 @@
1
- export default {
1
+ import type { ApiRoute } from "befly/types/api";
2
+
3
+ import { fieldsScheme } from "../../utils/fieldsScheme";
4
+
5
+ const route: ApiRoute = {
2
6
  name: "删除系统配置",
3
7
  fields: {
4
- id: "@id"
8
+ id: fieldsScheme.id
5
9
  },
10
+ required: ["id"],
6
11
  handler: async (befly, ctx) => {
7
12
  try {
8
13
  // 检查是否为系统配置
@@ -31,3 +36,5 @@ export default {
31
36
  }
32
37
  }
33
38
  };
39
+
40
+ export default route;
@@ -1,3 +1,5 @@
1
+ import type { ApiRoute } from "befly/types/api";
2
+
1
3
  export default {
2
4
  name: "根据代码获取配置值",
3
5
  auth: false,
@@ -5,7 +7,12 @@ export default {
5
7
  code: { name: "配置代码", type: "string", min: 1, max: 50 }
6
8
  },
7
9
  handler: async (befly, ctx) => {
8
- const config = await befly.db.getOne({
10
+ const config = await befly.db.getOne<{
11
+ id?: number;
12
+ code?: string;
13
+ value?: string;
14
+ valueType?: string;
15
+ }>({
9
16
  table: "addon_admin_sys_config",
10
17
  where: { code: ctx.body.code }
11
18
  });
@@ -14,20 +21,31 @@ export default {
14
21
  return befly.tool.No("配置不存在");
15
22
  }
16
23
 
24
+ const valueType = config.data.valueType;
25
+ const rawValue = config.data.value;
26
+ if (typeof valueType !== "string" || typeof rawValue !== "string") {
27
+ return befly.tool.No("配置数据不完整");
28
+ }
29
+
30
+ const code = config.data.code;
31
+ if (typeof code !== "string") {
32
+ return befly.tool.No("配置数据不完整");
33
+ }
34
+
17
35
  // 根据类型转换值
18
- let value = config.data.value;
19
- if (config.data.valueType === "number") {
20
- value = Number(config.data.value);
21
- } else if (config.data.valueType === "boolean") {
22
- value = config.data.value === "true" || config.data.value === "1";
23
- } else if (config.data.valueType === "json") {
36
+ let value: unknown = rawValue;
37
+ if (valueType === "number") {
38
+ value = Number(rawValue);
39
+ } else if (valueType === "boolean") {
40
+ value = rawValue === "true" || rawValue === "1";
41
+ } else if (valueType === "json") {
24
42
  try {
25
- value = JSON.parse(config.data.value);
43
+ value = JSON.parse(rawValue);
26
44
  } catch {
27
- value = config.data.value;
45
+ value = rawValue;
28
46
  }
29
47
  }
30
48
 
31
- return befly.tool.Yes("操作成功", { code: config.data.code, value: value });
49
+ return befly.tool.Yes("操作成功", { code: code, value: value });
32
50
  }
33
- };
51
+ } as unknown as ApiRoute;
@@ -1,3 +1,5 @@
1
+ import type { ApiRoute } from "befly/types/api";
2
+
1
3
  import sysConfigTable from "../../tables/sysConfig.json";
2
4
 
3
5
  export default {
@@ -6,12 +8,12 @@ export default {
6
8
  handler: async (befly, ctx) => {
7
9
  try {
8
10
  // 检查 code 是否已存在
9
- const existing = await befly.db.getOne({
11
+ const existing = await befly.db.getOne<{ id?: number }>({
10
12
  table: "addon_admin_sys_config",
11
13
  where: { code: ctx.body.code }
12
14
  });
13
15
 
14
- if (existing.data) {
16
+ if (existing.data?.id) {
15
17
  return befly.tool.No("配置代码已存在");
16
18
  }
17
19
 
@@ -35,4 +37,4 @@ export default {
35
37
  return befly.tool.No("操作失败");
36
38
  }
37
39
  }
38
- };
40
+ } as unknown as ApiRoute;
@@ -1,10 +1,14 @@
1
- export default {
1
+ import type { ApiRoute } from "befly/types/api";
2
+
3
+ import { fieldsScheme } from "../../utils/fieldsScheme";
4
+
5
+ const route: ApiRoute = {
2
6
  name: "获取系统配置列表",
3
7
  fields: {
4
- page: "@page",
5
- limit: "@limit",
6
- keyword: "@keyword",
7
- state: "@state"
8
+ page: fieldsScheme.page,
9
+ limit: fieldsScheme.limit,
10
+ keyword: fieldsScheme.keyword,
11
+ state: fieldsScheme.state
8
12
  },
9
13
  handler: async (befly, ctx) => {
10
14
  const result = await befly.db.getList({
@@ -18,3 +22,5 @@ export default {
18
22
  return befly.tool.Yes("操作成功", result.data);
19
23
  }
20
24
  };
25
+
26
+ export default route;
@@ -1,11 +1,13 @@
1
+ import type { ApiRoute } from "befly/types/api";
2
+
1
3
  import sysConfigTable from "../../tables/sysConfig.json";
4
+ import { fieldsScheme } from "../../utils/fieldsScheme";
5
+ import { mergeTableFields } from "../../utils/mergeTableFields";
2
6
 
3
- export default {
7
+ const route: ApiRoute = {
4
8
  name: "更新系统配置",
5
- fields: {
6
- id: "@id",
7
- ...sysConfigTable
8
- },
9
+ fields: mergeTableFields(sysConfigTable, { id: fieldsScheme.id }),
10
+ required: ["id"],
9
11
  handler: async (befly, ctx) => {
10
12
  try {
11
13
  // 检查是否为系统配置
@@ -51,3 +53,5 @@ export default {
51
53
  }
52
54
  }
53
55
  };
56
+
57
+ export default route;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@befly-addon/admin",
3
- "version": "1.6.0",
4
- "gitHead": "0d60e323a83a1fc53822147de877af19cdb972c0",
3
+ "version": "1.6.2",
4
+ "gitHead": "e30f1dd7cb51e6560832110c37708ef0a6853749",
5
5
  "private": false,
6
6
  "description": "Befly - 管理后台功能组件",
7
7
  "keywords": [
@@ -52,5 +52,11 @@
52
52
  "nodemailer": "^7.0.12",
53
53
  "ua-parser-js": "^2.0.7"
54
54
  },
55
+ "devDependencies": {
56
+ "befly": "3.14.2"
57
+ },
58
+ "peerDependencies": {
59
+ "befly": "^3.14.0"
60
+ },
55
61
  "addonName": "管理后台"
56
62
  }
package/plugins/email.ts CHANGED
@@ -3,9 +3,9 @@
3
3
  * 提供邮件发送功能,支持 SMTP 配置
4
4
  */
5
5
 
6
- import type { EmailConfig } from "../libs/emailHelper.ts";
6
+ import type { EmailConfig } from "../libs/emailHelper";
7
7
 
8
- import { EmailHelper } from "../libs/emailHelper.ts";
8
+ import { EmailHelper } from "../libs/emailHelper";
9
9
 
10
10
  /** 默认配置 */
11
11
  const defaultConfig: EmailConfig = {
package/tsconfig.json CHANGED
@@ -4,10 +4,11 @@
4
4
  "target": "ES2022",
5
5
  "types": ["bun"],
6
6
  "strict": false,
7
+ "exactOptionalPropertyTypes": false,
7
8
  "noImplicitReturns": false,
8
9
  "noFallthroughCasesInSwitch": false,
9
10
  "noImplicitOverride": false
10
11
  },
11
- "include": ["apis/**/*.ts", "libs/**/*.ts", "plugins/**/*.ts", "**/*.d.ts"],
12
+ "include": ["apis/**/*.ts", "libs/**/*.ts", "plugins/**/*.ts", "utils/**/*.ts", "**/*.d.ts"],
12
13
  "exclude": ["node_modules", "dist", "logs", "temp", "tests", "views", "adminViews", "appViews"]
13
14
  }
@@ -38,7 +38,7 @@ export function fieldClear<T = any>(data: T | T[], options: FieldClearOptions =
38
38
  const value = obj[key];
39
39
 
40
40
  // 1. keepMap 优先
41
- if (keepMap && Object.prototype.hasOwnProperty.call(keepMap, key)) {
41
+ if (keepMap && Object.hasOwn(keepMap, key)) {
42
42
  if (Object.is(keepMap[key], value)) {
43
43
  result[key] = value;
44
44
  continue;
@@ -0,0 +1,50 @@
1
+ import type { FieldDefinition } from "befly/types/validate";
2
+
3
+ export const fieldsScheme: {
4
+ id: FieldDefinition;
5
+ page: FieldDefinition;
6
+ limit: FieldDefinition;
7
+ keyword: FieldDefinition;
8
+ state: FieldDefinition;
9
+ } = {
10
+ id: {
11
+ name: "ID",
12
+ type: "number",
13
+ min: 1,
14
+ max: null,
15
+ default: null,
16
+ regexp: null
17
+ },
18
+ page: {
19
+ name: "页码",
20
+ type: "number",
21
+ min: 1,
22
+ max: 9999,
23
+ default: 1,
24
+ regexp: null
25
+ },
26
+ limit: {
27
+ name: "每页数量",
28
+ type: "number",
29
+ min: 1,
30
+ max: 100,
31
+ default: 30,
32
+ regexp: null
33
+ },
34
+ keyword: {
35
+ name: "关键词",
36
+ type: "string",
37
+ min: 0,
38
+ max: 50,
39
+ default: "",
40
+ regexp: null
41
+ },
42
+ state: {
43
+ name: "状态",
44
+ type: "number",
45
+ min: null,
46
+ max: null,
47
+ default: null,
48
+ regexp: "^[0-2]$"
49
+ }
50
+ };
@@ -0,0 +1,11 @@
1
+ import type { TableDefinition } from "befly/types/validate";
2
+
3
+ export function mergeTableFields(...tables: TableDefinition[]): TableDefinition {
4
+ const merged: TableDefinition = {};
5
+
6
+ for (const table of tables) {
7
+ Object.assign(merged, table);
8
+ }
9
+
10
+ return merged;
11
+ }