befly 3.19.6 → 3.19.7
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/tongJi/onlineReport.js +45 -1
- package/apis/tongJi/onlineStats.js +109 -1
- package/package.json +2 -2
|
@@ -35,6 +35,24 @@ function getPeriodKeys(periodType, periodValue) {
|
|
|
35
35
|
};
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
function getOnlineStatsProductKey(productName) {
|
|
39
|
+
return encodeURIComponent(String(productName || ""));
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function getOnlineStatsProductPeriodKeys(periodType, periodValue, productName) {
|
|
43
|
+
const productKey = getOnlineStatsProductKey(productName);
|
|
44
|
+
|
|
45
|
+
return {
|
|
46
|
+
pv: `online:${periodType}:${periodValue}:product:${productKey}:pv`,
|
|
47
|
+
members: `online:${periodType}:${periodValue}:product:${productKey}:members`,
|
|
48
|
+
reportTime: `online:${periodType}:${periodValue}:product:${productKey}:reportTime`
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function getOnlineStatsProductsKey(periodType, periodValue) {
|
|
53
|
+
return `online:${periodType}:${periodValue}:products`;
|
|
54
|
+
}
|
|
55
|
+
|
|
38
56
|
async function touchRedisKeys(befly, keys, ttl) {
|
|
39
57
|
for (const key of keys) {
|
|
40
58
|
await befly.redis.expire(key, ttl);
|
|
@@ -76,12 +94,34 @@ async function updateOnlineStatsPeriod(befly, periodType, periodValue, member) {
|
|
|
76
94
|
await touchRedisKeys(befly, Object.values(keys), ONLINE_STATS_TEMP_TTL_SECONDS);
|
|
77
95
|
}
|
|
78
96
|
|
|
97
|
+
async function updateOnlineStatsProductPeriod(befly, periodType, periodValue, member, productName) {
|
|
98
|
+
if (!productName) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const keys = getOnlineStatsProductPeriodKeys(periodType, periodValue, productName);
|
|
103
|
+
const productsKey = getOnlineStatsProductsKey(periodType, periodValue);
|
|
104
|
+
|
|
105
|
+
await befly.redis.incr(keys.pv);
|
|
106
|
+
await befly.redis.sadd(keys.members, [member]);
|
|
107
|
+
await befly.redis.setString(keys.reportTime, String(Date.now()), ONLINE_STATS_TEMP_TTL_SECONDS);
|
|
108
|
+
await befly.redis.sadd(productsKey, [productName]);
|
|
109
|
+
await touchRedisKeys(befly, [...Object.values(keys), productsKey], ONLINE_STATS_TEMP_TTL_SECONDS);
|
|
110
|
+
}
|
|
111
|
+
|
|
79
112
|
export default {
|
|
80
113
|
name: "上报在线统计",
|
|
81
114
|
method: "POST",
|
|
82
115
|
body: "none",
|
|
83
116
|
auth: false,
|
|
84
|
-
fields: {
|
|
117
|
+
fields: {
|
|
118
|
+
pagePath: { name: "页面路径", input: "string", min: 0, max: 200 },
|
|
119
|
+
pageName: { name: "页面名称", input: "string", min: 0, max: 100 },
|
|
120
|
+
source: { name: "来源", input: "string", min: 0, max: 50 },
|
|
121
|
+
productName: { name: "产品名称", input: "string", min: 0, max: 100 },
|
|
122
|
+
productCode: { name: "产品代号", input: "string", min: 0, max: 100 },
|
|
123
|
+
productVersion: { name: "产品版本", input: "string", min: 0, max: 50 }
|
|
124
|
+
},
|
|
85
125
|
required: [],
|
|
86
126
|
handler: async (befly, ctx) => {
|
|
87
127
|
const now = Date.now();
|
|
@@ -89,6 +129,7 @@ export default {
|
|
|
89
129
|
const weekStartDate = getOnlineStatsWeekStartDate(now);
|
|
90
130
|
const monthStartDate = getOnlineStatsMonthStartDate(now);
|
|
91
131
|
const member = getOnlineStatsMember(ctx);
|
|
132
|
+
const productName = ctx.body?.productName || "";
|
|
92
133
|
|
|
93
134
|
await befly.redis.setString(`online:visitor:${member}`, "1", ONLINE_STATS_ONLINE_TTL_SECONDS);
|
|
94
135
|
await befly.redis.sadd("online:visitors", [member]);
|
|
@@ -99,6 +140,9 @@ export default {
|
|
|
99
140
|
await updateOnlineStatsPeriod(befly, "day", reportDate, member);
|
|
100
141
|
await updateOnlineStatsPeriod(befly, "week", weekStartDate, member);
|
|
101
142
|
await updateOnlineStatsPeriod(befly, "month", monthStartDate, member);
|
|
143
|
+
await updateOnlineStatsProductPeriod(befly, "day", reportDate, member, productName);
|
|
144
|
+
await updateOnlineStatsProductPeriod(befly, "week", weekStartDate, member, productName);
|
|
145
|
+
await updateOnlineStatsProductPeriod(befly, "month", monthStartDate, member, productName);
|
|
102
146
|
|
|
103
147
|
return befly.tool.Yes("上报成功", {
|
|
104
148
|
reportTime: now,
|
|
@@ -44,6 +44,24 @@ function getPeriodKeys(periodType, periodValue) {
|
|
|
44
44
|
};
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
function getOnlineStatsProductKey(productName) {
|
|
48
|
+
return encodeURIComponent(String(productName || ""));
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function getOnlineStatsProductPeriodKeys(periodType, periodValue, productName) {
|
|
52
|
+
const productKey = getOnlineStatsProductKey(productName);
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
pv: `online:${periodType}:${periodValue}:product:${productKey}:pv`,
|
|
56
|
+
members: `online:${periodType}:${periodValue}:product:${productKey}:members`,
|
|
57
|
+
reportTime: `online:${periodType}:${periodValue}:product:${productKey}:reportTime`
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function getOnlineStatsProductsKey(periodType, periodValue) {
|
|
62
|
+
return `online:${periodType}:${periodValue}:products`;
|
|
63
|
+
}
|
|
64
|
+
|
|
47
65
|
async function getRedisNumber(befly, key) {
|
|
48
66
|
return toOnlineStatsNumber(await befly.redis.getString(key));
|
|
49
67
|
}
|
|
@@ -57,6 +75,32 @@ async function getOnlineStatsPeriodData(befly, periodType, periodValue) {
|
|
|
57
75
|
};
|
|
58
76
|
}
|
|
59
77
|
|
|
78
|
+
async function getOnlineStatsProductPeriodData(befly, periodType, periodValue, productName) {
|
|
79
|
+
const keys = getOnlineStatsProductPeriodKeys(periodType, periodValue, productName);
|
|
80
|
+
|
|
81
|
+
return {
|
|
82
|
+
reportTime: await getRedisNumber(befly, keys.reportTime),
|
|
83
|
+
pv: await getRedisNumber(befly, keys.pv),
|
|
84
|
+
uv: toOnlineStatsNumber(await befly.redis.scard(keys.members))
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
async function getOnlineStatsProductNames(befly, recentDateList) {
|
|
89
|
+
const productSet = new Set();
|
|
90
|
+
|
|
91
|
+
for (const item of recentDateList) {
|
|
92
|
+
for (const productName of await befly.redis.smembers(getOnlineStatsProductsKey("day", item))) {
|
|
93
|
+
if (!productName) {
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
productSet.add(String(productName));
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return Array.from(productSet.values());
|
|
102
|
+
}
|
|
103
|
+
|
|
60
104
|
async function getOnlineStatsOnlineCount(befly) {
|
|
61
105
|
const members = await befly.redis.smembers("online:visitors");
|
|
62
106
|
if (members.length === 0) {
|
|
@@ -83,6 +127,16 @@ async function getOnlineStatsOnlineCount(befly) {
|
|
|
83
127
|
return onlineCount;
|
|
84
128
|
}
|
|
85
129
|
|
|
130
|
+
function sumProductTrendField(list, field) {
|
|
131
|
+
let total = 0;
|
|
132
|
+
|
|
133
|
+
for (const item of list) {
|
|
134
|
+
total += toOnlineStatsNumber(item?.[field]);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return total;
|
|
138
|
+
}
|
|
139
|
+
|
|
86
140
|
export default {
|
|
87
141
|
name: "获取在线统计",
|
|
88
142
|
method: "POST",
|
|
@@ -97,6 +151,7 @@ export default {
|
|
|
97
151
|
const monthStartDate = getOnlineStatsMonthStartDate(now);
|
|
98
152
|
const recentDateList = getOnlineStatsRecentDateList(now, ONLINE_STATS_DAY_LIMIT);
|
|
99
153
|
const days = [];
|
|
154
|
+
const products = [];
|
|
100
155
|
|
|
101
156
|
for (const item of recentDateList) {
|
|
102
157
|
const dayData = await getOnlineStatsPeriodData(befly, "day", item);
|
|
@@ -117,6 +172,58 @@ export default {
|
|
|
117
172
|
const weekCurrent = await getOnlineStatsPeriodData(befly, "week", weekStartDate);
|
|
118
173
|
const monthCurrent = await getOnlineStatsPeriodData(befly, "month", monthStartDate);
|
|
119
174
|
const onlineCount = await getOnlineStatsOnlineCount(befly);
|
|
175
|
+
const productNames = await getOnlineStatsProductNames(befly, recentDateList);
|
|
176
|
+
|
|
177
|
+
for (const productName of productNames) {
|
|
178
|
+
const productDays = [];
|
|
179
|
+
|
|
180
|
+
for (const item of recentDateList) {
|
|
181
|
+
const dayData = await getOnlineStatsProductPeriodData(befly, "day", item, productName);
|
|
182
|
+
|
|
183
|
+
if (dayData.reportTime <= 0) {
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
productDays.push({
|
|
188
|
+
reportDate: item,
|
|
189
|
+
reportTime: dayData.reportTime,
|
|
190
|
+
pv: dayData.pv,
|
|
191
|
+
uv: dayData.uv
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
const productToday = await getOnlineStatsProductPeriodData(befly, "day", reportDate, productName);
|
|
196
|
+
const productWeek = await getOnlineStatsProductPeriodData(befly, "week", weekStartDate, productName);
|
|
197
|
+
const productMonth = await getOnlineStatsProductPeriodData(befly, "month", monthStartDate, productName);
|
|
198
|
+
|
|
199
|
+
products.push({
|
|
200
|
+
key: productName,
|
|
201
|
+
productName: productName,
|
|
202
|
+
today: {
|
|
203
|
+
pv: productToday.pv,
|
|
204
|
+
uv: productToday.uv
|
|
205
|
+
},
|
|
206
|
+
week: {
|
|
207
|
+
pv: productWeek.pv,
|
|
208
|
+
uv: productWeek.uv
|
|
209
|
+
},
|
|
210
|
+
month: {
|
|
211
|
+
pv: productMonth.pv,
|
|
212
|
+
uv: productMonth.uv
|
|
213
|
+
},
|
|
214
|
+
days: productDays,
|
|
215
|
+
totalPv: sumProductTrendField(productDays, "pv"),
|
|
216
|
+
totalUv: sumProductTrendField(productDays, "uv")
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
products.sort((a, b) => {
|
|
221
|
+
if (b.totalPv !== a.totalPv) {
|
|
222
|
+
return b.totalPv - a.totalPv;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
return String(a.productName).localeCompare(String(b.productName), "zh-CN");
|
|
226
|
+
});
|
|
120
227
|
|
|
121
228
|
return befly.tool.Yes("获取成功", {
|
|
122
229
|
queryTime: now,
|
|
@@ -141,7 +248,8 @@ export default {
|
|
|
141
248
|
pv: monthCurrent.pv,
|
|
142
249
|
uv: monthCurrent.uv
|
|
143
250
|
},
|
|
144
|
-
days: days
|
|
251
|
+
days: days,
|
|
252
|
+
products: products
|
|
145
253
|
});
|
|
146
254
|
}
|
|
147
255
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "befly",
|
|
3
|
-
"version": "3.19.
|
|
4
|
-
"gitHead": "
|
|
3
|
+
"version": "3.19.7",
|
|
4
|
+
"gitHead": "c47d1e515dabe142531e0a8415979cccb2729259",
|
|
5
5
|
"private": false,
|
|
6
6
|
"description": "Befly - 为 Bun 专属打造的 JavaScript API 接口框架核心引擎",
|
|
7
7
|
"keywords": [
|