befly 3.24.19 → 3.25.0
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/apis/_apis.js +20 -0
- package/apis/admin/delete.js +3 -1
- package/apis/admin/detail.js +1 -3
- package/apis/admin/select.js +9 -7
- package/apis/admin/update.js +2 -2
- package/apis/api/all.js +6 -11
- package/apis/api/select.js +18 -19
- package/apis/dict/_dict.js +24 -0
- package/apis/dict/all.js +6 -4
- package/apis/dict/detail.js +9 -5
- package/apis/dict/insert.js +4 -11
- package/apis/dict/items.js +5 -6
- package/apis/dict/select.js +13 -9
- package/apis/dict/update.js +9 -13
- package/apis/dictType/select.js +4 -4
- package/apis/email/config.js +9 -11
- package/apis/email/logList.js +14 -4
- package/apis/email/send.js +10 -3
- package/apis/email/verify.js +9 -7
- package/apis/loginLog/select.js +11 -4
- package/apis/menu/all.js +13 -19
- package/apis/menu/select.js +19 -14
- package/apis/operateLog/select.js +13 -4
- package/apis/role/_role.js +21 -0
- package/apis/role/all.js +1 -3
- package/apis/role/apiSave.js +8 -15
- package/apis/role/apis.js +4 -10
- package/apis/role/delete.js +28 -36
- package/apis/role/detail.js +4 -10
- package/apis/role/insert.js +12 -10
- package/apis/role/menuSave.js +9 -15
- package/apis/role/menus.js +4 -10
- package/apis/role/save.js +19 -23
- package/apis/role/select.js +12 -9
- package/apis/role/update.js +14 -15
- package/apis/source/imageList.js +3 -3
- package/apis/sysConfig/get.js +11 -23
- package/apis/sysConfig/insert.js +22 -27
- package/apis/sysConfig/select.js +11 -5
- package/apis/sysConfig/update.js +33 -38
- package/apis/tongJi/_tongJi.js +41 -0
- package/apis/tongJi/cacheHealth.js +8 -30
- package/apis/tongJi/errorList.js +26 -27
- package/apis/tongJi/errorReport.js +26 -43
- package/apis/tongJi/errorStats.js +17 -48
- package/apis/tongJi/fallbackReset.js +7 -15
- package/apis/tongJi/infoReport.js +20 -32
- package/apis/tongJi/infoStats.js +5 -17
- package/apis/tongJi/onlineReport.js +50 -56
- package/apis/tongJi/onlineStats.js +97 -111
- package/checks/config.js +44 -1
- package/configs/beflyConfig.json +10 -1
- package/index.js +25 -0
- package/lib/dbHelper.js +1 -1
- package/lib/dbParse.js +61 -99
- package/lib/dbUtil.js +101 -21
- package/lib/redisHelper.js +25 -0
- package/lib/sqlBuilder.js +6 -0
- package/package.json +1 -1
- package/plugins/email.js +3 -6
- package/router/api.js +0 -7
- package/utils/email.js +3 -0
- package/apis/admin/cacheRefresh.js +0 -122
- package/apis/dashboard/configStatus.js +0 -39
- package/apis/dashboard/performanceMetrics.js +0 -23
- package/apis/dashboard/permissionStats.js +0 -27
- package/apis/dashboard/systemInfo.js +0 -19
- package/lib/requestMetrics.js +0 -203
package/apis/_apis.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export const queryFields = {
|
|
2
|
+
page: {
|
|
3
|
+
name: "页码",
|
|
4
|
+
input: "integer",
|
|
5
|
+
min: 1,
|
|
6
|
+
max: 10000
|
|
7
|
+
},
|
|
8
|
+
limit: {
|
|
9
|
+
name: "每页数量",
|
|
10
|
+
input: "integer",
|
|
11
|
+
min: 1,
|
|
12
|
+
max: 100
|
|
13
|
+
},
|
|
14
|
+
keyword: {
|
|
15
|
+
name: "关键字",
|
|
16
|
+
input: "string",
|
|
17
|
+
min: 0,
|
|
18
|
+
max: 100
|
|
19
|
+
}
|
|
20
|
+
};
|
package/apis/admin/delete.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
import adminTable from "#root/tables/admin.json";
|
|
2
|
+
|
|
1
3
|
export default {
|
|
2
4
|
name: "删除管理员",
|
|
3
5
|
method: "POST",
|
|
4
6
|
body: "none",
|
|
5
7
|
auth: true,
|
|
6
8
|
fields: {
|
|
7
|
-
id:
|
|
9
|
+
id: adminTable.id
|
|
8
10
|
},
|
|
9
11
|
required: ["id"],
|
|
10
12
|
handler: async (befly, ctx) => {
|
package/apis/admin/detail.js
CHANGED
package/apis/admin/select.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
|
+
import { queryFields } from "#root/apis/_apis.js";
|
|
2
|
+
import adminTable from "#root/tables/admin.json";
|
|
3
|
+
|
|
1
4
|
export default {
|
|
2
5
|
name: "查询管理员列表",
|
|
3
6
|
method: "POST",
|
|
4
7
|
body: "none",
|
|
5
8
|
auth: true,
|
|
6
9
|
fields: {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
keyword: { name: "关键词", input: "string", min: 0, max: 50 },
|
|
10
|
-
state: { name: "状态", input: "integer", min: 0, max: 2 }
|
|
10
|
+
...queryFields,
|
|
11
|
+
state: adminTable.state
|
|
11
12
|
},
|
|
12
13
|
required: [],
|
|
13
14
|
handler: async (befly, ctx) => {
|
|
@@ -16,9 +17,10 @@ export default {
|
|
|
16
17
|
page: ctx.body.page,
|
|
17
18
|
limit: ctx.body.limit,
|
|
18
19
|
where: {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
username$like$or: ctx.body.keyword,
|
|
21
|
+
nickname$like$or: ctx.body.keyword,
|
|
22
|
+
state: ctx.body.state,
|
|
23
|
+
roleCode$not: "dev"
|
|
22
24
|
},
|
|
23
25
|
orderBy: ["createdAt#DESC"]
|
|
24
26
|
});
|
package/apis/admin/update.js
CHANGED
|
@@ -34,7 +34,7 @@ export default {
|
|
|
34
34
|
table: "beflyAdmin",
|
|
35
35
|
where: {
|
|
36
36
|
username: ctx.body.username,
|
|
37
|
-
id
|
|
37
|
+
id$not: ctx.body.id
|
|
38
38
|
}
|
|
39
39
|
});
|
|
40
40
|
|
|
@@ -48,7 +48,7 @@ export default {
|
|
|
48
48
|
table: "beflyAdmin",
|
|
49
49
|
where: {
|
|
50
50
|
nickname: ctx.body.nickname,
|
|
51
|
-
id
|
|
51
|
+
id$not: ctx.body.id
|
|
52
52
|
}
|
|
53
53
|
});
|
|
54
54
|
|
package/apis/api/all.js
CHANGED
|
@@ -6,19 +6,14 @@ export default {
|
|
|
6
6
|
fields: {},
|
|
7
7
|
required: [],
|
|
8
8
|
handler: async (befly) => {
|
|
9
|
-
|
|
10
|
-
const allApis = await befly.cache.getApis();
|
|
9
|
+
const allApis = await befly.cache.getApis();
|
|
11
10
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
if (allApis.length === 0) {
|
|
12
|
+
return befly.tool.No("接口缓存不存在,请刷新缓存", { lists: [] });
|
|
13
|
+
}
|
|
15
14
|
|
|
16
|
-
|
|
15
|
+
const lists = allApis.filter((api) => api && typeof api === "object");
|
|
17
16
|
|
|
18
|
-
|
|
19
|
-
} catch (error) {
|
|
20
|
-
befly.logger.error("获取接口列表失败", error);
|
|
21
|
-
return befly.tool.No("获取接口列表失败");
|
|
22
|
-
}
|
|
17
|
+
return befly.tool.Yes("操作成功", { lists: lists });
|
|
23
18
|
}
|
|
24
19
|
};
|
package/apis/api/select.js
CHANGED
|
@@ -1,31 +1,30 @@
|
|
|
1
|
+
import { queryFields } from "#root/apis/_apis.js";
|
|
2
|
+
import apiTable from "#root/tables/api.json";
|
|
3
|
+
|
|
1
4
|
export default {
|
|
2
5
|
name: "获取接口列表",
|
|
3
6
|
method: "POST",
|
|
4
7
|
body: "none",
|
|
5
8
|
auth: true,
|
|
6
9
|
fields: {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
keyword: { name: "关键词", input: "string", min: 0, max: 50 },
|
|
10
|
-
state: { name: "状态", input: "integer", min: 0, max: 2 }
|
|
10
|
+
...queryFields,
|
|
11
|
+
state: apiTable.state
|
|
11
12
|
},
|
|
12
13
|
required: [],
|
|
13
14
|
handler: async (befly, ctx) => {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
15
|
+
const result = await befly.mysql.getList({
|
|
16
|
+
table: "beflyApi",
|
|
17
|
+
where: {
|
|
18
|
+
name$like$or: ctx.body.keyword,
|
|
19
|
+
path$like$or: ctx.body.keyword,
|
|
20
|
+
parentPath$like$or: ctx.body.keyword,
|
|
21
|
+
state: ctx.body.state
|
|
22
|
+
},
|
|
23
|
+
orderBy: ["id#ASC"],
|
|
24
|
+
page: ctx.body.page,
|
|
25
|
+
limit: ctx.body.limit
|
|
26
|
+
});
|
|
24
27
|
|
|
25
|
-
|
|
26
|
-
} catch (error) {
|
|
27
|
-
befly.logger.error("获取接口列表失败", error);
|
|
28
|
-
return befly.tool.No("获取接口列表失败");
|
|
29
|
-
}
|
|
28
|
+
return befly.tool.Yes("操作成功", result.data);
|
|
30
29
|
}
|
|
31
30
|
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export const dictReadTable = ["beflyDict", "beflyDictType"];
|
|
2
|
+
export const dictReadLeftJoin = ["beflyDict.typeCode beflyDictType.code"];
|
|
3
|
+
export const dictReadFields = ["beflyDict.id", "beflyDict.typeCode", "beflyDict.key", "beflyDict.label", "beflyDict.sort", "beflyDict.remark", "beflyDict.createdAt", "beflyDict.updatedAt", "beflyDictType.name typeName"];
|
|
4
|
+
export const dictReadOrderBy = ["beflyDict.sort#ASC", "beflyDict.id#ASC"];
|
|
5
|
+
|
|
6
|
+
export async function getDictTypeByCode(befly, typeCode) {
|
|
7
|
+
return await befly.mysql.getOne({
|
|
8
|
+
table: "beflyDictType",
|
|
9
|
+
where: {
|
|
10
|
+
code: typeCode
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export async function getDictByTypeCodeAndKey(befly, typeCode, key, dictId = undefined) {
|
|
16
|
+
return await befly.mysql.getOne({
|
|
17
|
+
table: "beflyDict",
|
|
18
|
+
where: {
|
|
19
|
+
typeCode: typeCode,
|
|
20
|
+
key: key,
|
|
21
|
+
id$not: dictId
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
}
|
package/apis/dict/all.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import dictTable from "#root/tables/dict.json";
|
|
2
|
+
|
|
3
|
+
import { dictReadFields, dictReadLeftJoin, dictReadOrderBy, dictReadTable } from "./_dict.js";
|
|
2
4
|
export default {
|
|
3
5
|
name: "获取所有字典",
|
|
4
6
|
method: "POST",
|
|
@@ -10,10 +12,10 @@ export default {
|
|
|
10
12
|
required: [],
|
|
11
13
|
handler: async (befly) => {
|
|
12
14
|
const result = await befly.mysql.getAll({
|
|
13
|
-
table:
|
|
14
|
-
leftJoin:
|
|
15
|
-
fields:
|
|
16
|
-
orderBy:
|
|
15
|
+
table: dictReadTable,
|
|
16
|
+
leftJoin: dictReadLeftJoin,
|
|
17
|
+
fields: dictReadFields,
|
|
18
|
+
orderBy: dictReadOrderBy
|
|
17
19
|
});
|
|
18
20
|
|
|
19
21
|
return befly.tool.Yes("获取成功", result.data);
|
package/apis/dict/detail.js
CHANGED
|
@@ -1,21 +1,25 @@
|
|
|
1
|
+
import dictTable from "#root/tables/dict.json";
|
|
2
|
+
|
|
3
|
+
import { dictReadFields, dictReadLeftJoin, dictReadTable } from "./_dict.js";
|
|
4
|
+
|
|
1
5
|
export default {
|
|
2
6
|
name: "获取字典详情",
|
|
3
7
|
method: "POST",
|
|
4
8
|
body: "none",
|
|
5
9
|
auth: false,
|
|
6
10
|
fields: {
|
|
7
|
-
id:
|
|
11
|
+
id: dictTable.id
|
|
8
12
|
},
|
|
9
13
|
required: ["id"],
|
|
10
14
|
handler: async (befly, ctx) => {
|
|
11
15
|
const dict = await befly.mysql.getOne({
|
|
12
|
-
table:
|
|
13
|
-
leftJoin:
|
|
14
|
-
fields:
|
|
16
|
+
table: dictReadTable,
|
|
17
|
+
leftJoin: dictReadLeftJoin,
|
|
18
|
+
fields: dictReadFields,
|
|
15
19
|
where: { "beflyDict.id": ctx.body.id }
|
|
16
20
|
});
|
|
17
21
|
|
|
18
|
-
if (!dict.data
|
|
22
|
+
if (!dict.data?.id) {
|
|
19
23
|
return befly.tool.No("字典项不存在");
|
|
20
24
|
}
|
|
21
25
|
|
package/apis/dict/insert.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import dictTable from "#root/tables/dict.json";
|
|
2
2
|
|
|
3
|
+
import { getDictByTypeCodeAndKey, getDictTypeByCode } from "./_dict.js";
|
|
4
|
+
|
|
3
5
|
export default {
|
|
4
6
|
name: "添加字典",
|
|
5
7
|
method: "POST",
|
|
@@ -14,22 +16,13 @@ export default {
|
|
|
14
16
|
},
|
|
15
17
|
required: ["typeCode", "key", "label"],
|
|
16
18
|
handler: async (befly, ctx) => {
|
|
17
|
-
const dictType = await befly.
|
|
18
|
-
table: "beflyDictType",
|
|
19
|
-
where: { code: ctx.body.typeCode }
|
|
20
|
-
});
|
|
19
|
+
const dictType = await getDictTypeByCode(befly, ctx.body.typeCode);
|
|
21
20
|
|
|
22
21
|
if (!dictType.data?.id) {
|
|
23
22
|
return befly.tool.No("字典类型不存在");
|
|
24
23
|
}
|
|
25
24
|
|
|
26
|
-
const existing = await befly.
|
|
27
|
-
table: "beflyDict",
|
|
28
|
-
where: {
|
|
29
|
-
typeCode: ctx.body.typeCode,
|
|
30
|
-
key: ctx.body.key
|
|
31
|
-
}
|
|
32
|
-
});
|
|
25
|
+
const existing = await getDictByTypeCodeAndKey(befly, ctx.body.typeCode, ctx.body.key);
|
|
33
26
|
|
|
34
27
|
if (existing.data?.id) {
|
|
35
28
|
return befly.tool.No("该类型下已存在相同的键名");
|
package/apis/dict/items.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import dictTable from "#root/tables/dict.json";
|
|
2
2
|
|
|
3
|
+
import { dictReadOrderBy, getDictTypeByCode } from "./_dict.js";
|
|
4
|
+
|
|
3
5
|
export default {
|
|
4
6
|
name: "获取字典项列表",
|
|
5
7
|
method: "POST",
|
|
@@ -10,19 +12,16 @@ export default {
|
|
|
10
12
|
},
|
|
11
13
|
required: ["typeCode"],
|
|
12
14
|
handler: async (befly, ctx) => {
|
|
13
|
-
const dictType = await befly.
|
|
14
|
-
table: "beflyDictType",
|
|
15
|
-
where: { code: ctx.body.typeCode }
|
|
16
|
-
});
|
|
15
|
+
const dictType = await getDictTypeByCode(befly, ctx.body.typeCode);
|
|
17
16
|
|
|
18
|
-
if (!dictType.data
|
|
17
|
+
if (!dictType.data?.id) {
|
|
19
18
|
return befly.tool.No("字典类型不存在");
|
|
20
19
|
}
|
|
21
20
|
|
|
22
21
|
const items = await befly.mysql.getAll({
|
|
23
22
|
table: "beflyDict",
|
|
24
23
|
where: { typeCode: ctx.body.typeCode },
|
|
25
|
-
orderBy:
|
|
24
|
+
orderBy: dictReadOrderBy
|
|
26
25
|
});
|
|
27
26
|
|
|
28
27
|
return befly.tool.Yes("获取成功", items.data);
|
package/apis/dict/select.js
CHANGED
|
@@ -1,28 +1,32 @@
|
|
|
1
|
+
import { queryFields } from "#root/apis/_apis.js";
|
|
1
2
|
import dictTable from "#root/tables/dict.json";
|
|
2
3
|
|
|
4
|
+
import { dictReadFields, dictReadLeftJoin, dictReadOrderBy, dictReadTable } from "./_dict.js";
|
|
5
|
+
|
|
3
6
|
export default {
|
|
4
7
|
name: "获取字典列表",
|
|
5
8
|
method: "POST",
|
|
6
9
|
body: "none",
|
|
7
10
|
auth: false,
|
|
8
11
|
fields: {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
typeCode: dictTable.typeCode,
|
|
12
|
-
keyword: { name: "关键词", input: "string", min: 0, max: 50 }
|
|
12
|
+
...queryFields,
|
|
13
|
+
typeCode: dictTable.typeCode
|
|
13
14
|
},
|
|
14
15
|
required: [],
|
|
15
16
|
handler: async (befly, ctx) => {
|
|
16
17
|
const result = await befly.mysql.getList({
|
|
17
|
-
table:
|
|
18
|
-
leftJoin:
|
|
19
|
-
fields:
|
|
18
|
+
table: dictReadTable,
|
|
19
|
+
leftJoin: dictReadLeftJoin,
|
|
20
|
+
fields: dictReadFields,
|
|
20
21
|
where: {
|
|
21
|
-
"beflyDict.typeCode": ctx.body.typeCode
|
|
22
|
+
"beflyDict.typeCode": ctx.body.typeCode,
|
|
23
|
+
"beflyDict.key$like$or": ctx.body.keyword,
|
|
24
|
+
"beflyDict.label$like$or": ctx.body.keyword,
|
|
25
|
+
"beflyDict.remark$like$or": ctx.body.keyword
|
|
22
26
|
},
|
|
23
27
|
page: ctx.body.page,
|
|
24
28
|
limit: ctx.body.limit,
|
|
25
|
-
orderBy:
|
|
29
|
+
orderBy: dictReadOrderBy
|
|
26
30
|
});
|
|
27
31
|
|
|
28
32
|
return befly.tool.Yes("获取成功", result.data);
|
package/apis/dict/update.js
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import dictTable from "#root/tables/dict.json";
|
|
2
2
|
|
|
3
|
+
import { getDictByTypeCodeAndKey, getDictTypeByCode } from "./_dict.js";
|
|
4
|
+
|
|
3
5
|
export default {
|
|
4
6
|
name: "更新字典",
|
|
5
7
|
method: "POST",
|
|
6
8
|
body: "none",
|
|
7
9
|
auth: true,
|
|
8
10
|
fields: {
|
|
9
|
-
id:
|
|
11
|
+
id: dictTable.id,
|
|
10
12
|
typeCode: dictTable.typeCode,
|
|
11
13
|
key: dictTable.key,
|
|
12
14
|
label: dictTable.label,
|
|
@@ -16,10 +18,7 @@ export default {
|
|
|
16
18
|
required: ["id"],
|
|
17
19
|
handler: async (befly, ctx) => {
|
|
18
20
|
if (ctx.body.typeCode !== undefined) {
|
|
19
|
-
const dictType = await befly.
|
|
20
|
-
table: "beflyDictType",
|
|
21
|
-
where: { code: ctx.body.typeCode }
|
|
22
|
-
});
|
|
21
|
+
const dictType = await getDictTypeByCode(befly, ctx.body.typeCode);
|
|
23
22
|
|
|
24
23
|
if (!dictType.data?.id) {
|
|
25
24
|
return befly.tool.No("字典类型不存在");
|
|
@@ -32,14 +31,11 @@ export default {
|
|
|
32
31
|
where: { id: ctx.body.id }
|
|
33
32
|
});
|
|
34
33
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
id$not: ctx.body.id
|
|
41
|
-
}
|
|
42
|
-
});
|
|
34
|
+
if (!current.data?.id) {
|
|
35
|
+
return befly.tool.No("字典项不存在");
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const existing = await getDictByTypeCodeAndKey(befly, ctx.body.typeCode !== undefined ? ctx.body.typeCode : current.data.typeCode, ctx.body.key !== undefined ? ctx.body.key : current.data.key, ctx.body.id);
|
|
43
39
|
|
|
44
40
|
if (existing.data?.id) {
|
|
45
41
|
return befly.tool.No("该类型下已存在相同的键名");
|
package/apis/dictType/select.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { queryFields } from "#root/apis/_apis.js";
|
|
1
2
|
import dictTypeTable from "#root/tables/dictType.json";
|
|
2
3
|
|
|
3
4
|
export default {
|
|
@@ -6,9 +7,7 @@ export default {
|
|
|
6
7
|
body: "none",
|
|
7
8
|
auth: true,
|
|
8
9
|
fields: {
|
|
9
|
-
|
|
10
|
-
limit: { name: "每页数量", input: "integer", min: 1, max: 100 },
|
|
11
|
-
keyword: { name: "关键词", input: "string", min: 0, max: 50 },
|
|
10
|
+
...queryFields,
|
|
12
11
|
state: dictTypeTable.state
|
|
13
12
|
},
|
|
14
13
|
required: [],
|
|
@@ -16,7 +15,8 @@ export default {
|
|
|
16
15
|
const result = await befly.mysql.getList({
|
|
17
16
|
table: "beflyDictType",
|
|
18
17
|
where: {
|
|
19
|
-
|
|
18
|
+
name$like$or: ctx.body.keyword,
|
|
19
|
+
code$like$or: ctx.body.keyword,
|
|
20
20
|
state: ctx.body.state
|
|
21
21
|
},
|
|
22
22
|
orderBy: ["sort#ASC", "id#ASC"],
|
package/apis/email/config.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { hasEmailConfig } from "#root/utils/email.js";
|
|
2
|
+
|
|
1
3
|
export default {
|
|
2
4
|
name: "获取邮件配置",
|
|
3
5
|
method: "POST",
|
|
@@ -6,20 +8,16 @@ export default {
|
|
|
6
8
|
fields: {},
|
|
7
9
|
required: [],
|
|
8
10
|
handler: async (befly) => {
|
|
9
|
-
|
|
10
|
-
return befly.tool.No("邮件插件未加载,请检查配置");
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
const config = befly.email.getConfig();
|
|
11
|
+
const config = befly?.config?.email || {};
|
|
14
12
|
|
|
15
13
|
return befly.tool.Yes("获取成功", {
|
|
16
|
-
host: config.host,
|
|
17
|
-
port: config.port,
|
|
14
|
+
host: config.host || "",
|
|
15
|
+
port: config.port || 0,
|
|
18
16
|
secure: config.secure,
|
|
19
|
-
user: config.user,
|
|
20
|
-
pass: config.pass,
|
|
21
|
-
|
|
22
|
-
configured:
|
|
17
|
+
user: config.user || "",
|
|
18
|
+
pass: config.pass || "",
|
|
19
|
+
label: config.label || "",
|
|
20
|
+
configured: hasEmailConfig(config)
|
|
23
21
|
});
|
|
24
22
|
}
|
|
25
23
|
};
|
package/apis/email/logList.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
|
+
import { queryFields } from "#root/apis/_apis.js";
|
|
2
|
+
import emailLogTable from "#root/tables/emailLog.json";
|
|
3
|
+
|
|
1
4
|
export default {
|
|
2
5
|
name: "邮件发送日志列表",
|
|
3
6
|
method: "POST",
|
|
4
7
|
body: "none",
|
|
5
8
|
auth: true,
|
|
6
9
|
fields: {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
keyword: { name: "关键词", input: "string", min: 0, max: 50 },
|
|
10
|
-
state: { name: "状态", input: "integer", min: 0, max: 2 }
|
|
10
|
+
...queryFields,
|
|
11
|
+
state: emailLogTable.state
|
|
11
12
|
},
|
|
12
13
|
required: [],
|
|
13
14
|
handler: async (befly, ctx) => {
|
|
@@ -15,6 +16,15 @@ export default {
|
|
|
15
16
|
table: "beflyEmailLog",
|
|
16
17
|
page: ctx.body.page,
|
|
17
18
|
limit: ctx.body.limit,
|
|
19
|
+
where: {
|
|
20
|
+
username$like$or: ctx.body.keyword,
|
|
21
|
+
nickname$like$or: ctx.body.keyword,
|
|
22
|
+
toEmail$like$or: ctx.body.keyword,
|
|
23
|
+
subject$like$or: ctx.body.keyword,
|
|
24
|
+
failReason$like$or: ctx.body.keyword,
|
|
25
|
+
messageId$like$or: ctx.body.keyword,
|
|
26
|
+
state: ctx.body.state
|
|
27
|
+
},
|
|
18
28
|
orderBy: ["sendTime#DESC"]
|
|
19
29
|
});
|
|
20
30
|
|
package/apis/email/send.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import emailLogTable from "#root/tables/emailLog.json";
|
|
2
|
+
import { hasEmailConfig } from "#root/utils/email.js";
|
|
2
3
|
|
|
3
4
|
export default {
|
|
4
5
|
name: "发送邮件",
|
|
@@ -20,6 +21,12 @@ export default {
|
|
|
20
21
|
},
|
|
21
22
|
required: ["to", "subject", "content"],
|
|
22
23
|
handler: async (befly, ctx) => {
|
|
24
|
+
const emailConfig = befly.config.email || {};
|
|
25
|
+
|
|
26
|
+
if (!hasEmailConfig(emailConfig)) {
|
|
27
|
+
return befly.tool.No("邮件未配置,请检查 SMTP 配置");
|
|
28
|
+
}
|
|
29
|
+
|
|
23
30
|
if (!befly.email) {
|
|
24
31
|
return befly.tool.No("邮件插件未加载,请检查配置");
|
|
25
32
|
}
|
|
@@ -31,15 +38,15 @@ export default {
|
|
|
31
38
|
subject: ctx.body.subject,
|
|
32
39
|
html: ctx.body.isHtml ? ctx.body.content : undefined,
|
|
33
40
|
text: ctx.body.isHtml ? undefined : ctx.body.content,
|
|
34
|
-
cc: ctx.body.cc
|
|
35
|
-
bcc: ctx.body.bcc
|
|
41
|
+
cc: ctx.body.cc,
|
|
42
|
+
bcc: ctx.body.bcc
|
|
36
43
|
});
|
|
37
44
|
|
|
38
45
|
try {
|
|
39
46
|
await befly.mysql.insData({
|
|
40
47
|
table: "beflyEmailLog",
|
|
41
48
|
data: {
|
|
42
|
-
adminId: ctx.userId
|
|
49
|
+
adminId: ctx.userId,
|
|
43
50
|
username: "",
|
|
44
51
|
nickname: ctx.nickname || "",
|
|
45
52
|
toEmail: ctx.body.to,
|
package/apis/email/verify.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { hasEmailConfig } from "#root/utils/email.js";
|
|
2
|
+
|
|
1
3
|
export default {
|
|
2
4
|
name: "验证邮件配置",
|
|
3
5
|
method: "POST",
|
|
@@ -6,16 +8,16 @@ export default {
|
|
|
6
8
|
fields: {},
|
|
7
9
|
required: [],
|
|
8
10
|
handler: async (befly) => {
|
|
9
|
-
|
|
10
|
-
return befly.tool.No("邮件插件未加载,请检查配置");
|
|
11
|
-
}
|
|
11
|
+
const emailConfig = befly?.config?.email || {};
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
if (!hasEmailConfig(emailConfig)) {
|
|
14
|
+
return befly.tool.No("邮件未配置,请检查 SMTP 配置");
|
|
15
|
+
}
|
|
14
16
|
|
|
15
|
-
if (
|
|
16
|
-
return befly.tool.
|
|
17
|
+
if (!befly.email) {
|
|
18
|
+
return befly.tool.No("邮件插件未加载,请检查配置");
|
|
17
19
|
}
|
|
18
20
|
|
|
19
|
-
return befly.tool.
|
|
21
|
+
return befly.tool.Yes("邮件配置已启用");
|
|
20
22
|
}
|
|
21
23
|
};
|
package/apis/loginLog/select.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
|
+
import { queryFields } from "#root/apis/_apis.js";
|
|
2
|
+
import loginLogTable from "#root/tables/loginLog.json";
|
|
3
|
+
|
|
1
4
|
export default {
|
|
2
5
|
name: "获取登录日志列表",
|
|
3
6
|
method: "POST",
|
|
4
7
|
body: "none",
|
|
5
8
|
auth: true,
|
|
6
9
|
fields: {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
keyword: { name: "关键词", input: "string", min: 0, max: 50 },
|
|
10
|
-
state: { name: "状态", input: "integer", min: 0, max: 2 }
|
|
10
|
+
...queryFields,
|
|
11
|
+
state: loginLogTable.state
|
|
11
12
|
},
|
|
12
13
|
required: [],
|
|
13
14
|
handler: async (befly, ctx) => {
|
|
@@ -15,6 +16,12 @@ export default {
|
|
|
15
16
|
table: "beflyLoginLog",
|
|
16
17
|
page: ctx.body.page,
|
|
17
18
|
limit: ctx.body.limit,
|
|
19
|
+
where: {
|
|
20
|
+
username$like$or: ctx.body.keyword,
|
|
21
|
+
nickname$like$or: ctx.body.keyword,
|
|
22
|
+
ip$like$or: ctx.body.keyword,
|
|
23
|
+
state: ctx.body.state
|
|
24
|
+
},
|
|
18
25
|
orderBy: ["loginTime#DESC"]
|
|
19
26
|
});
|
|
20
27
|
|
package/apis/menu/all.js
CHANGED
|
@@ -6,29 +6,23 @@ export default {
|
|
|
6
6
|
fields: {},
|
|
7
7
|
required: [],
|
|
8
8
|
handler: async (befly, ctx) => {
|
|
9
|
-
|
|
10
|
-
const menuPaths = await befly.cache.getRoleMenus(ctx.roleCode);
|
|
9
|
+
const menuPaths = await befly.cache.getRoleMenus(ctx.roleCode);
|
|
11
10
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
if (menuPaths.length === 0) {
|
|
12
|
+
return befly.tool.Yes("菜单为空", { lists: [] });
|
|
13
|
+
}
|
|
15
14
|
|
|
16
|
-
|
|
15
|
+
const allMenus = await befly.cache.getMenus();
|
|
17
16
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
if (allMenus.length === 0) {
|
|
18
|
+
return befly.tool.No("菜单缓存不存在,请刷新缓存", { lists: [] });
|
|
19
|
+
}
|
|
21
20
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
});
|
|
21
|
+
const menuPathSet = new Set(menuPaths);
|
|
22
|
+
const authorizedMenus = allMenus.filter((menu) => {
|
|
23
|
+
return menuPathSet.has(menu.path);
|
|
24
|
+
});
|
|
27
25
|
|
|
28
|
-
|
|
29
|
-
} catch (error) {
|
|
30
|
-
befly.logger.error("获取用户菜单失败", error);
|
|
31
|
-
return befly.tool.No("获取菜单失败");
|
|
32
|
-
}
|
|
26
|
+
return befly.tool.Yes("获取菜单成功", { lists: authorizedMenus });
|
|
33
27
|
}
|
|
34
28
|
};
|