befly 3.63.0 → 3.65.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/auth/login.js +19 -64
- package/apis/tongJi/dailyReportSelect.js +36 -0
- package/apis/tongJi/dailyStats.js +18 -3
- package/apis/tongJi/errorReport.js +1 -1
- package/apis/tongJi/projectDelete.js +20 -0
- package/apis/tongJi/projectInsert.js +35 -0
- package/apis/tongJi/projectSelect.js +31 -0
- package/apis/tongJi/projectUpdate.js +52 -0
- package/configs/beflyMenus.json +20 -3
- package/package.json +1 -1
- package/sql/befly.sql +14 -0
- package/tables/project.json +42 -0
package/apis/auth/login.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import adminTable from "#befly/tables/admin.json";
|
|
2
|
+
import loginLogTable from "#befly/tables/loginLog.json";
|
|
2
3
|
import { toSessionTtlSeconds } from "#befly/utils/util.js";
|
|
3
4
|
|
|
4
5
|
export default {
|
|
@@ -21,61 +22,15 @@ export default {
|
|
|
21
22
|
min: null,
|
|
22
23
|
max: null
|
|
23
24
|
},
|
|
24
|
-
clientType:
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
input: "string",
|
|
34
|
-
min: 0,
|
|
35
|
-
max: 100
|
|
36
|
-
},
|
|
37
|
-
productCode: {
|
|
38
|
-
name: "产品代号",
|
|
39
|
-
input: "string",
|
|
40
|
-
min: 0,
|
|
41
|
-
max: 100
|
|
42
|
-
},
|
|
43
|
-
productVersion: {
|
|
44
|
-
name: "产品版本",
|
|
45
|
-
input: "string",
|
|
46
|
-
min: 0,
|
|
47
|
-
max: 50
|
|
48
|
-
},
|
|
49
|
-
clientVersion: {
|
|
50
|
-
name: "客户端版本",
|
|
51
|
-
input: "string",
|
|
52
|
-
min: 0,
|
|
53
|
-
max: 100
|
|
54
|
-
},
|
|
55
|
-
os: {
|
|
56
|
-
name: "操作系统",
|
|
57
|
-
input: "string",
|
|
58
|
-
min: 0,
|
|
59
|
-
max: 100
|
|
60
|
-
},
|
|
61
|
-
system: {
|
|
62
|
-
name: "系统",
|
|
63
|
-
input: "string",
|
|
64
|
-
min: 0,
|
|
65
|
-
max: 100
|
|
66
|
-
},
|
|
67
|
-
brand: {
|
|
68
|
-
name: "设备品牌",
|
|
69
|
-
input: "string",
|
|
70
|
-
min: 0,
|
|
71
|
-
max: 100
|
|
72
|
-
},
|
|
73
|
-
model: {
|
|
74
|
-
name: "设备型号",
|
|
75
|
-
input: "string",
|
|
76
|
-
min: 0,
|
|
77
|
-
max: 100
|
|
78
|
-
}
|
|
25
|
+
clientType: loginLogTable.clientType,
|
|
26
|
+
productName: loginLogTable.productName,
|
|
27
|
+
productCode: loginLogTable.productCode,
|
|
28
|
+
productVersion: loginLogTable.productVersion,
|
|
29
|
+
clientVersion: loginLogTable.clientVersion,
|
|
30
|
+
os: loginLogTable.os,
|
|
31
|
+
system: loginLogTable.system,
|
|
32
|
+
brand: loginLogTable.brand,
|
|
33
|
+
model: loginLogTable.model
|
|
79
34
|
},
|
|
80
35
|
required: ["account", "password", "loginType"],
|
|
81
36
|
handler: async (befly, ctx) => {
|
|
@@ -86,15 +41,15 @@ export default {
|
|
|
86
41
|
username: ctx.body.account,
|
|
87
42
|
nickname: "",
|
|
88
43
|
ip: ctx.ip || "",
|
|
89
|
-
clientType: body.clientType,
|
|
90
|
-
productName: body.productName ||
|
|
91
|
-
productCode: body.productCode ||
|
|
92
|
-
productVersion: body.productVersion ||
|
|
93
|
-
clientVersion: body.clientVersion ||
|
|
94
|
-
os: body.os ||
|
|
95
|
-
system: body.system ||
|
|
96
|
-
brand: body.brand ||
|
|
97
|
-
model: body.model ||
|
|
44
|
+
clientType: body.clientType || "",
|
|
45
|
+
productName: body.productName || "",
|
|
46
|
+
productCode: body.productCode || "",
|
|
47
|
+
productVersion: body.productVersion || "",
|
|
48
|
+
clientVersion: body.clientVersion || "",
|
|
49
|
+
os: body.os || "",
|
|
50
|
+
system: body.system || "",
|
|
51
|
+
brand: body.brand || "",
|
|
52
|
+
model: body.model || "",
|
|
98
53
|
loginTime: Date.now(),
|
|
99
54
|
loginResult: 0,
|
|
100
55
|
failReason: ""
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { queryFields } from "#befly/apis/_apis.js";
|
|
2
|
+
import dailyReportTable from "#befly/tables/dailyReport.json";
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
name: "获取日报记录列表",
|
|
6
|
+
method: "POST",
|
|
7
|
+
body: "none",
|
|
8
|
+
auth: true,
|
|
9
|
+
fields: {
|
|
10
|
+
...queryFields,
|
|
11
|
+
productCode: dailyReportTable.productCode,
|
|
12
|
+
clientType: dailyReportTable.clientType,
|
|
13
|
+
reportDate: dailyReportTable.reportDate,
|
|
14
|
+
memberType: dailyReportTable.memberType
|
|
15
|
+
},
|
|
16
|
+
required: [],
|
|
17
|
+
handler: async (befly, ctx) => {
|
|
18
|
+
const result = await befly.mysql.getList({
|
|
19
|
+
table: "beflyDailyReport",
|
|
20
|
+
where: {
|
|
21
|
+
productCode$like$or: ctx.body.productCode,
|
|
22
|
+
clientType: ctx.body.clientType,
|
|
23
|
+
memberType: ctx.body.memberType,
|
|
24
|
+
reportDate: ctx.body.reportDate,
|
|
25
|
+
productName$like$or: ctx.body.keyword,
|
|
26
|
+
member$like$or: ctx.body.keyword,
|
|
27
|
+
clientId$like$or: ctx.body.keyword
|
|
28
|
+
},
|
|
29
|
+
page: ctx.body.page,
|
|
30
|
+
limit: ctx.body.limit,
|
|
31
|
+
orderBy: ["id#desc"]
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
return befly.tool.Yes("获取成功", result.data);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
@@ -86,7 +86,23 @@ function buildProductSummary(item, stats, todayCount) {
|
|
|
86
86
|
};
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
-
async function
|
|
89
|
+
async function loadProjectLists(befly) {
|
|
90
|
+
if (!befly.mysql) {
|
|
91
|
+
return [];
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const result = await befly.mysql.getAll({
|
|
95
|
+
table: "beflyProject",
|
|
96
|
+
fields: ["code", "name"],
|
|
97
|
+
where: { state: 1 },
|
|
98
|
+
orderBy: ["sort#asc"]
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
return result.data?.lists || [];
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
async function buildDailyStatsProducts(befly, history, dateStats) {
|
|
105
|
+
const projectLists = await loadProjectLists(befly);
|
|
90
106
|
const products = await Promise.all(
|
|
91
107
|
projectLists.map(async (item) => {
|
|
92
108
|
const stats = history[item.code] || { yesterday: 0, dayBeforeYesterday: 0, month: 0, lastMonth: 0 };
|
|
@@ -131,7 +147,6 @@ export default {
|
|
|
131
147
|
const [previousMonthStartDate, previousMonthEndDate] = getPreviousMonthDateRange(reportDate);
|
|
132
148
|
const recentDateList = getTongJiRecentDateList(now, DAILY_STATS_DAY_LIMIT, befly.config?.tz);
|
|
133
149
|
const productCode = ctx.body?.productCode ?? "";
|
|
134
|
-
const projectLists = productCode ? [] : befly.config?.projectLists || [];
|
|
135
150
|
const dateStats = {
|
|
136
151
|
reportDate: reportDate,
|
|
137
152
|
yesterdayDate: recentDateList[recentDateList.length - 2],
|
|
@@ -144,7 +159,7 @@ export default {
|
|
|
144
159
|
const history = await loadHistory(befly, reportDate, dateStats);
|
|
145
160
|
const todayCount = productCode ? await getTodayCount(befly, reportDate, productCode) : 0;
|
|
146
161
|
const summary = productCode ? buildFullSummary(history[productCode] || { yesterday: 0, dayBeforeYesterday: 0, month: 0, lastMonth: 0 }, dateStats, todayCount) : null;
|
|
147
|
-
const products = await buildDailyStatsProducts(befly,
|
|
162
|
+
const products = productCode ? [] : await buildDailyStatsProducts(befly, history, dateStats);
|
|
148
163
|
|
|
149
164
|
return befly.tool.Yes("获取成功", {
|
|
150
165
|
queryTime: now,
|
|
@@ -108,7 +108,7 @@ export default {
|
|
|
108
108
|
};
|
|
109
109
|
|
|
110
110
|
try {
|
|
111
|
-
await befly.mysql.insData({ table: "
|
|
111
|
+
await befly.mysql.insData({ table: "beflyErrorReport", data: data });
|
|
112
112
|
stored = true;
|
|
113
113
|
} catch (error) {
|
|
114
114
|
Logger.error("errorReport 插入失败", error);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import projectTable from "#befly/tables/project.json";
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
name: "删除产品",
|
|
5
|
+
method: "POST",
|
|
6
|
+
body: "none",
|
|
7
|
+
auth: true,
|
|
8
|
+
fields: {
|
|
9
|
+
id: projectTable.id
|
|
10
|
+
},
|
|
11
|
+
required: ["id"],
|
|
12
|
+
handler: async (befly, ctx) => {
|
|
13
|
+
await befly.mysql.delData({
|
|
14
|
+
table: "beflyProject",
|
|
15
|
+
where: { id: ctx.body.id }
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
return befly.tool.Yes("删除成功");
|
|
19
|
+
}
|
|
20
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import projectTable from "#befly/tables/project.json";
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
name: "添加产品",
|
|
5
|
+
method: "POST",
|
|
6
|
+
body: "none",
|
|
7
|
+
auth: true,
|
|
8
|
+
fields: {
|
|
9
|
+
code: projectTable.code,
|
|
10
|
+
name: projectTable.name,
|
|
11
|
+
sort: projectTable.sort
|
|
12
|
+
},
|
|
13
|
+
required: ["code", "name"],
|
|
14
|
+
handler: async (befly, ctx) => {
|
|
15
|
+
const existing = await befly.mysql.getOne({
|
|
16
|
+
table: "beflyProject",
|
|
17
|
+
where: { code: ctx.body.code }
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
if (existing.data?.id) {
|
|
21
|
+
return befly.tool.No("产品代号已存在");
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const projectId = await befly.mysql.insData({
|
|
25
|
+
table: "beflyProject",
|
|
26
|
+
data: {
|
|
27
|
+
code: ctx.body.code,
|
|
28
|
+
name: ctx.body.name,
|
|
29
|
+
sort: ctx.body.sort
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
return befly.tool.Yes("添加成功", { id: projectId.data });
|
|
34
|
+
}
|
|
35
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { queryFields } from "#befly/apis/_apis.js";
|
|
2
|
+
import projectTable from "#befly/tables/project.json";
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
name: "获取产品列表",
|
|
6
|
+
method: "POST",
|
|
7
|
+
body: "none",
|
|
8
|
+
auth: true,
|
|
9
|
+
fields: {
|
|
10
|
+
...queryFields,
|
|
11
|
+
code: projectTable.code,
|
|
12
|
+
state: projectTable.state
|
|
13
|
+
},
|
|
14
|
+
required: [],
|
|
15
|
+
handler: async (befly, ctx) => {
|
|
16
|
+
const result = await befly.mysql.getList({
|
|
17
|
+
table: "beflyProject",
|
|
18
|
+
fields: ["id", "code", "name", "sort", "state", "createdAt", "updatedAt"],
|
|
19
|
+
where: {
|
|
20
|
+
code$like$or: ctx.body.code,
|
|
21
|
+
name$like$or: ctx.body.keyword,
|
|
22
|
+
state: ctx.body.state
|
|
23
|
+
},
|
|
24
|
+
page: ctx.body.page,
|
|
25
|
+
limit: ctx.body.limit,
|
|
26
|
+
orderBy: ["sort#asc"]
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
return befly.tool.Yes("获取成功", result.data);
|
|
30
|
+
}
|
|
31
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import projectTable from "#befly/tables/project.json";
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
name: "更新产品",
|
|
5
|
+
method: "POST",
|
|
6
|
+
body: "none",
|
|
7
|
+
auth: true,
|
|
8
|
+
fields: {
|
|
9
|
+
id: projectTable.id,
|
|
10
|
+
code: projectTable.code,
|
|
11
|
+
name: projectTable.name,
|
|
12
|
+
sort: projectTable.sort,
|
|
13
|
+
state: projectTable.state
|
|
14
|
+
},
|
|
15
|
+
required: ["id"],
|
|
16
|
+
handler: async (befly, ctx) => {
|
|
17
|
+
const current = await befly.mysql.getOne({
|
|
18
|
+
table: "beflyProject",
|
|
19
|
+
where: { id: ctx.body.id }
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
if (!current.data?.id) {
|
|
23
|
+
return befly.tool.No("产品不存在");
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (ctx.body.code !== undefined && ctx.body.code !== current.data.code) {
|
|
27
|
+
const existing = await befly.mysql.getOne({
|
|
28
|
+
table: "beflyProject",
|
|
29
|
+
where: { code: ctx.body.code }
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
if (existing.data?.id) {
|
|
33
|
+
return befly.tool.No("产品代号已存在");
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const updateData = {};
|
|
38
|
+
|
|
39
|
+
if (ctx.body.code !== undefined) updateData.code = ctx.body.code;
|
|
40
|
+
if (ctx.body.name !== undefined) updateData.name = ctx.body.name;
|
|
41
|
+
if (ctx.body.sort !== undefined) updateData.sort = ctx.body.sort;
|
|
42
|
+
if (ctx.body.state !== undefined) updateData.state = ctx.body.state;
|
|
43
|
+
|
|
44
|
+
await befly.mysql.updData({
|
|
45
|
+
table: "beflyProject",
|
|
46
|
+
data: updateData,
|
|
47
|
+
where: { id: ctx.body.id }
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
return befly.tool.Yes("更新成功");
|
|
51
|
+
}
|
|
52
|
+
};
|
package/configs/beflyMenus.json
CHANGED
|
@@ -5,9 +5,26 @@
|
|
|
5
5
|
"sort": 0
|
|
6
6
|
},
|
|
7
7
|
{
|
|
8
|
-
"name": "
|
|
9
|
-
"path": "/
|
|
10
|
-
"sort":
|
|
8
|
+
"name": "统计管理",
|
|
9
|
+
"path": "/tong-ji",
|
|
10
|
+
"sort": 2,
|
|
11
|
+
"children": [
|
|
12
|
+
{
|
|
13
|
+
"name": "统计数据",
|
|
14
|
+
"path": "/statistics-data",
|
|
15
|
+
"sort": 1
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"name": "项目管理",
|
|
19
|
+
"path": "/project-manage",
|
|
20
|
+
"sort": 2
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"name": "统计记录",
|
|
24
|
+
"path": "/statistics-record",
|
|
25
|
+
"sort": 3
|
|
26
|
+
}
|
|
27
|
+
]
|
|
11
28
|
},
|
|
12
29
|
{
|
|
13
30
|
"name": "人员管理",
|
package/package.json
CHANGED
package/sql/befly.sql
CHANGED
|
@@ -255,3 +255,17 @@ CREATE TABLE IF NOT EXISTS `befly_error_report` (
|
|
|
255
255
|
KEY `idx_befly_error_report_product_code_report_time` (`product_code`, `report_time`),
|
|
256
256
|
KEY `idx_befly_error_report_error_type_report_time` (`error_type`, `report_time`)
|
|
257
257
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
|
258
|
+
|
|
259
|
+
CREATE TABLE IF NOT EXISTS `befly_project` (
|
|
260
|
+
`id` BIGINT NOT NULL AUTO_INCREMENT,
|
|
261
|
+
`code` VARCHAR(100) NOT NULL DEFAULT '',
|
|
262
|
+
`name` VARCHAR(100) NOT NULL DEFAULT '',
|
|
263
|
+
`sort` INT NOT NULL DEFAULT 0,
|
|
264
|
+
`state` TINYINT NOT NULL DEFAULT 1,
|
|
265
|
+
`created_at` BIGINT NOT NULL DEFAULT 0,
|
|
266
|
+
`updated_at` BIGINT NOT NULL DEFAULT 0,
|
|
267
|
+
`deleted_at` BIGINT NULL DEFAULT NULL,
|
|
268
|
+
PRIMARY KEY (`id`),
|
|
269
|
+
UNIQUE KEY `uk_befly_project_code` (`code`),
|
|
270
|
+
KEY `idx_befly_project_state` (`state`)
|
|
271
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": {
|
|
3
|
+
"name": "ID",
|
|
4
|
+
"input": "integer",
|
|
5
|
+
"min": 1,
|
|
6
|
+
"max": null
|
|
7
|
+
},
|
|
8
|
+
"code": {
|
|
9
|
+
"name": "产品代号",
|
|
10
|
+
"input": "string",
|
|
11
|
+
"min": 1,
|
|
12
|
+
"max": 100
|
|
13
|
+
},
|
|
14
|
+
"name": {
|
|
15
|
+
"name": "产品名称",
|
|
16
|
+
"input": "string",
|
|
17
|
+
"min": 1,
|
|
18
|
+
"max": 100
|
|
19
|
+
},
|
|
20
|
+
"sort": {
|
|
21
|
+
"name": "排序",
|
|
22
|
+
"input": "number",
|
|
23
|
+
"max": 9999
|
|
24
|
+
},
|
|
25
|
+
"state": {
|
|
26
|
+
"name": "状态(0=已删除,1=正常,2=禁用)",
|
|
27
|
+
"input": "enumInteger",
|
|
28
|
+
"check": "0|1|2"
|
|
29
|
+
},
|
|
30
|
+
"createdAt": {
|
|
31
|
+
"name": "创建时间",
|
|
32
|
+
"input": "number"
|
|
33
|
+
},
|
|
34
|
+
"updatedAt": {
|
|
35
|
+
"name": "更新时间",
|
|
36
|
+
"input": "number"
|
|
37
|
+
},
|
|
38
|
+
"deletedAt": {
|
|
39
|
+
"name": "删除时间",
|
|
40
|
+
"input": "number"
|
|
41
|
+
}
|
|
42
|
+
}
|