befly 3.19.5 → 3.19.6

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.
@@ -65,30 +65,25 @@
65
65
  "path": "/log",
66
66
  "sort": 9003,
67
67
  "children": [
68
- {
69
- "name": "访问统计",
70
- "path": "/visit",
71
- "sort": 1
72
- },
73
68
  {
74
69
  "name": "登录日志",
75
70
  "path": "/login",
76
- "sort": 2
71
+ "sort": 1
77
72
  },
78
73
  {
79
74
  "name": "邮件日志",
80
75
  "path": "/email",
81
- "sort": 3
76
+ "sort": 2
82
77
  },
83
78
  {
84
79
  "name": "操作日志",
85
80
  "path": "/operate",
86
- "sort": 4
81
+ "sort": 3
87
82
  },
88
83
  {
89
84
  "name": "错误报告",
90
85
  "path": "/error",
91
- "sort": 5
86
+ "sort": 4
92
87
  }
93
88
  ]
94
89
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "befly",
3
- "version": "3.19.5",
4
- "gitHead": "ba7fa7cc0534c48de2df4970d69a14853cf6b2a6",
3
+ "version": "3.19.6",
4
+ "gitHead": "84b6e4e0adde7f566cfc890887b024ccf10b0516",
5
5
  "private": false,
6
6
  "description": "Befly - 为 Bun 专属打造的 JavaScript API 接口框架核心引擎",
7
7
  "keywords": [
@@ -52,7 +52,7 @@
52
52
  "test": "bun test"
53
53
  },
54
54
  "dependencies": {
55
- "fast-xml-parser": "^5.5.4",
55
+ "fast-xml-parser": "^5.5.5",
56
56
  "nodemailer": "^8.0.2",
57
57
  "pathe": "^2.0.3",
58
58
  "ua-parser-js": "^2.0.9",
package/sql/befly.sql CHANGED
@@ -15,7 +15,7 @@ CREATE TABLE IF NOT EXISTS `befly_admin` (
15
15
  `updated_at` BIGINT NOT NULL DEFAULT 0,
16
16
  `deleted_at` BIGINT NULL DEFAULT NULL,
17
17
  PRIMARY KEY (`id`)
18
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
18
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
19
19
 
20
20
  CREATE TABLE IF NOT EXISTS `befly_api` (
21
21
  `id` BIGINT NOT NULL,
@@ -29,7 +29,7 @@ CREATE TABLE IF NOT EXISTS `befly_api` (
29
29
  `updated_at` BIGINT NOT NULL DEFAULT 0,
30
30
  `deleted_at` BIGINT NULL DEFAULT NULL,
31
31
  PRIMARY KEY (`id`)
32
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
32
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
33
33
 
34
34
  CREATE TABLE IF NOT EXISTS `befly_dict` (
35
35
  `id` BIGINT NOT NULL,
@@ -43,7 +43,7 @@ CREATE TABLE IF NOT EXISTS `befly_dict` (
43
43
  `updated_at` BIGINT NOT NULL DEFAULT 0,
44
44
  `deleted_at` BIGINT NULL DEFAULT NULL,
45
45
  PRIMARY KEY (`id`)
46
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
46
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
47
47
 
48
48
  CREATE TABLE IF NOT EXISTS `befly_dict_type` (
49
49
  `id` BIGINT NOT NULL,
@@ -56,7 +56,7 @@ CREATE TABLE IF NOT EXISTS `befly_dict_type` (
56
56
  `updated_at` BIGINT NOT NULL DEFAULT 0,
57
57
  `deleted_at` BIGINT NULL DEFAULT NULL,
58
58
  PRIMARY KEY (`id`)
59
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
59
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
60
60
 
61
61
  CREATE TABLE IF NOT EXISTS `befly_email_log` (
62
62
  `id` BIGINT NOT NULL,
@@ -77,7 +77,7 @@ CREATE TABLE IF NOT EXISTS `befly_email_log` (
77
77
  `updated_at` BIGINT NOT NULL DEFAULT 0,
78
78
  `deleted_at` BIGINT NULL DEFAULT NULL,
79
79
  PRIMARY KEY (`id`)
80
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
80
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
81
81
 
82
82
  CREATE TABLE IF NOT EXISTS `befly_login_log` (
83
83
  `id` BIGINT NOT NULL,
@@ -103,7 +103,7 @@ CREATE TABLE IF NOT EXISTS `befly_login_log` (
103
103
  `updated_at` BIGINT NOT NULL DEFAULT 0,
104
104
  `deleted_at` BIGINT NULL DEFAULT NULL,
105
105
  PRIMARY KEY (`id`)
106
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
106
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
107
107
 
108
108
  CREATE TABLE IF NOT EXISTS `befly_menu` (
109
109
  `id` BIGINT NOT NULL,
@@ -116,7 +116,7 @@ CREATE TABLE IF NOT EXISTS `befly_menu` (
116
116
  `updated_at` BIGINT NOT NULL DEFAULT 0,
117
117
  `deleted_at` BIGINT NULL DEFAULT NULL,
118
118
  PRIMARY KEY (`id`)
119
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
119
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
120
120
 
121
121
  CREATE TABLE IF NOT EXISTS `befly_operate_log` (
122
122
  `id` BIGINT NOT NULL,
@@ -139,7 +139,7 @@ CREATE TABLE IF NOT EXISTS `befly_operate_log` (
139
139
  `updated_at` BIGINT NOT NULL DEFAULT 0,
140
140
  `deleted_at` BIGINT NULL DEFAULT NULL,
141
141
  PRIMARY KEY (`id`)
142
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
142
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
143
143
 
144
144
  CREATE TABLE IF NOT EXISTS `befly_role` (
145
145
  `id` BIGINT NOT NULL,
@@ -154,7 +154,7 @@ CREATE TABLE IF NOT EXISTS `befly_role` (
154
154
  `updated_at` BIGINT NOT NULL DEFAULT 0,
155
155
  `deleted_at` BIGINT NULL DEFAULT NULL,
156
156
  PRIMARY KEY (`id`)
157
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
157
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
158
158
 
159
159
  CREATE TABLE IF NOT EXISTS `befly_sys_config` (
160
160
  `id` BIGINT NOT NULL,
@@ -171,26 +171,7 @@ CREATE TABLE IF NOT EXISTS `befly_sys_config` (
171
171
  `updated_at` BIGINT NOT NULL DEFAULT 0,
172
172
  `deleted_at` BIGINT NULL DEFAULT NULL,
173
173
  PRIMARY KEY (`id`)
174
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
175
-
176
- CREATE TABLE IF NOT EXISTS `befly_visit_stats` (
177
- `id` BIGINT NOT NULL,
178
- `bucket_time` BIGINT NOT NULL DEFAULT 0,
179
- `bucket_date` INT NOT NULL DEFAULT 0,
180
- `pv` BIGINT NOT NULL DEFAULT 0,
181
- `uv` BIGINT NOT NULL DEFAULT 0,
182
- `error_count` BIGINT NOT NULL DEFAULT 0,
183
- `duration_sum` BIGINT NOT NULL DEFAULT 0,
184
- `duration_count` BIGINT NOT NULL DEFAULT 0,
185
- `avg_duration` BIGINT NOT NULL DEFAULT 0,
186
- `state` TINYINT NOT NULL DEFAULT 1,
187
- `created_at` BIGINT NOT NULL DEFAULT 0,
188
- `updated_at` BIGINT NOT NULL DEFAULT 0,
189
- `deleted_at` BIGINT NULL DEFAULT NULL,
190
- PRIMARY KEY (`id`),
191
- UNIQUE KEY `uk_befly_visit_stats_bucket_time` (`bucket_time`),
192
- KEY `idx_befly_visit_stats_bucket_date` (`bucket_date`)
193
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
174
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
194
175
 
195
176
  CREATE TABLE IF NOT EXISTS `befly_error_report` (
196
177
  `id` BIGINT NOT NULL,
@@ -225,4 +206,36 @@ CREATE TABLE IF NOT EXISTS `befly_error_report` (
225
206
  PRIMARY KEY (`id`),
226
207
  KEY `idx_befly_error_report_time` (`report_time`),
227
208
  KEY `idx_befly_error_report_bucket_date` (`bucket_date`)
228
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
209
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
210
+
211
+ CREATE TABLE IF NOT EXISTS `befly_info_report` (
212
+ `id` BIGINT NOT NULL,
213
+ `report_time` BIGINT NOT NULL DEFAULT 0,
214
+ `report_date` INT NOT NULL DEFAULT 0,
215
+ `member_key` VARCHAR(100) NOT NULL DEFAULT '',
216
+ `source` VARCHAR(50) NOT NULL DEFAULT '',
217
+ `product_name` VARCHAR(100) NOT NULL DEFAULT '',
218
+ `product_code` VARCHAR(100) NOT NULL DEFAULT '',
219
+ `product_version` VARCHAR(100) NOT NULL DEFAULT '',
220
+ `page_path` VARCHAR(200) NOT NULL DEFAULT '',
221
+ `page_name` VARCHAR(100) NOT NULL DEFAULT '',
222
+ `detail` TEXT NULL,
223
+ `user_agent` VARCHAR(500) NOT NULL DEFAULT '',
224
+ `browser_name` VARCHAR(100) NOT NULL DEFAULT '',
225
+ `browser_version` VARCHAR(100) NOT NULL DEFAULT '',
226
+ `os_name` VARCHAR(100) NOT NULL DEFAULT '',
227
+ `os_version` VARCHAR(100) NOT NULL DEFAULT '',
228
+ `device_type` VARCHAR(50) NOT NULL DEFAULT '',
229
+ `device_vendor` VARCHAR(100) NOT NULL DEFAULT '',
230
+ `device_model` VARCHAR(100) NOT NULL DEFAULT '',
231
+ `engine_name` VARCHAR(100) NOT NULL DEFAULT '',
232
+ `cpu_architecture` VARCHAR(100) NOT NULL DEFAULT '',
233
+ `state` TINYINT NOT NULL DEFAULT 1,
234
+ `created_at` BIGINT NOT NULL DEFAULT 0,
235
+ `updated_at` BIGINT NOT NULL DEFAULT 0,
236
+ `deleted_at` BIGINT NULL DEFAULT NULL,
237
+ PRIMARY KEY (`id`),
238
+ UNIQUE KEY `uk_befly_info_report_date_member` (`report_date`, `member_key`),
239
+ KEY `idx_befly_info_report_time` (`report_time`),
240
+ KEY `idx_befly_info_report_date` (`report_date`)
241
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
@@ -1,241 +0,0 @@
1
- import { UAParser } from "ua-parser-js";
2
-
3
- import { isValidPositiveInt } from "../../utils/is.js";
4
- import { getDateYmdNumber, getTimeBucketStart } from "../../utils/datetime.js";
5
- import { VISIT_STATS_BUCKET_MS, VISIT_STATS_ONLINE_TTL_SECONDS, VISIT_STATS_PRODUCT_FIELDS, VISIT_STATS_REDIS_TTL_SECONDS, VISIT_STATS_UA_FIELDS, getVisitStatsBucketKey, getVisitStatsBucketProductPvKey, getVisitStatsBucketProductUvKey, getVisitStatsDayKey, getVisitStatsDayProductCountKey, getVisitStatsDayProductKeysKey, getVisitStatsDayProductPvKey, getVisitStatsDayProductUvKey, getVisitStatsDayProductValuesKey, getVisitStatsDayUaCountKey, getVisitStatsDayUaValuesKey, getVisitStatsProductKey, getVisitStatsProductMeta, getVisitStatsProductMetaKey, normalizeVisitStatsProductValue, normalizeVisitStatsUaValue, toVisitStatsNumber } from "../../utils/visitStats.js";
6
-
7
- function getVisitStatsMember(ctx) {
8
- if (isValidPositiveInt(ctx.userId)) {
9
- return `user:${ctx.userId}`;
10
- }
11
-
12
- return `ip:${ctx.ip || "unknown"}`;
13
- }
14
-
15
- function getVisitStatsUaData(ctx) {
16
- let userAgent = "";
17
-
18
- if (typeof ctx.req?.headers?.get === "function") {
19
- userAgent = String(ctx.req.headers.get("user-agent") || "");
20
- } else if (typeof ctx.headers?.get === "function") {
21
- userAgent = String(ctx.headers.get("user-agent") || "");
22
- }
23
-
24
- const uaResult = UAParser(userAgent);
25
-
26
- return {
27
- deviceType: normalizeVisitStatsUaValue(uaResult.device.type, "desktop"),
28
- browserName: normalizeVisitStatsUaValue(uaResult.browser.name),
29
- browserVersion: normalizeVisitStatsUaValue(uaResult.browser.version),
30
- osName: normalizeVisitStatsUaValue(uaResult.os.name),
31
- osVersion: normalizeVisitStatsUaValue(uaResult.os.version),
32
- deviceVendor: normalizeVisitStatsUaValue(uaResult.device.vendor),
33
- deviceModel: normalizeVisitStatsUaValue(uaResult.device.model),
34
- engineName: normalizeVisitStatsUaValue(uaResult.engine.name),
35
- cpuArchitecture: normalizeVisitStatsUaValue(uaResult.cpu.architecture)
36
- };
37
- }
38
-
39
- function getVisitStatsProductData(ctx) {
40
- return getVisitStatsProductMeta({
41
- productName: ctx.body?.productName,
42
- productCode: ctx.body?.productCode,
43
- productVersion: ctx.body?.productVersion
44
- });
45
- }
46
-
47
- async function saveVisitStatsUaData(befly, bucketDate, uaData) {
48
- const saddItems = [];
49
- const expireItems = [];
50
- const countTasks = [];
51
-
52
- for (const item of VISIT_STATS_UA_FIELDS) {
53
- const field = item.field;
54
- const defaultValue = item.defaultValue;
55
- const value = normalizeVisitStatsUaValue(uaData[field], defaultValue);
56
- const valuesKey = getVisitStatsDayUaValuesKey(bucketDate, field);
57
- const countKey = getVisitStatsDayUaCountKey(bucketDate, field, value);
58
-
59
- saddItems.push({ key: valuesKey, members: [value] });
60
- expireItems.push({ key: valuesKey, seconds: VISIT_STATS_REDIS_TTL_SECONDS });
61
- countTasks.push(befly.redis.incrWithExpire(countKey, VISIT_STATS_REDIS_TTL_SECONDS));
62
- }
63
-
64
- await befly.redis.saddBatch(saddItems);
65
- await befly.redis.expireBatch(expireItems);
66
- await Promise.all(countTasks);
67
- }
68
-
69
- async function saveVisitStatsProductData(befly, bucketDate, productData) {
70
- const saddItems = [];
71
- const expireItems = [];
72
- const countTasks = [];
73
-
74
- for (const item of VISIT_STATS_PRODUCT_FIELDS) {
75
- const field = item.field;
76
- const defaultValue = item.defaultValue;
77
- const value = normalizeVisitStatsProductValue(productData[field], defaultValue);
78
- const valuesKey = getVisitStatsDayProductValuesKey(bucketDate, field);
79
- const countKey = getVisitStatsDayProductCountKey(bucketDate, field, value);
80
-
81
- saddItems.push({ key: valuesKey, members: [value] });
82
- expireItems.push({ key: valuesKey, seconds: VISIT_STATS_REDIS_TTL_SECONDS });
83
- countTasks.push(befly.redis.incrWithExpire(countKey, VISIT_STATS_REDIS_TTL_SECONDS));
84
- }
85
-
86
- await befly.redis.saddBatch(saddItems);
87
- await befly.redis.expireBatch(expireItems);
88
- await Promise.all(countTasks);
89
- }
90
-
91
- async function saveVisitStatsProductSummary(befly, bucketTime, bucketDate, member, productData) {
92
- const productKey = getVisitStatsProductKey(productData);
93
- const metaKey = getVisitStatsProductMetaKey(productKey);
94
- const dayKeysKey = getVisitStatsDayProductKeysKey(bucketDate);
95
- const bucketPvKey = getVisitStatsBucketProductPvKey(bucketTime, productKey);
96
- const bucketUvKey = getVisitStatsBucketProductUvKey(bucketTime, productKey);
97
- const dayPvKey = getVisitStatsDayProductPvKey(bucketDate, productKey);
98
- const dayUvKey = getVisitStatsDayProductUvKey(bucketDate, productKey);
99
-
100
- await befly.redis.setString(metaKey, JSON.stringify(productData), VISIT_STATS_REDIS_TTL_SECONDS);
101
- await befly.redis.sadd(dayKeysKey, [productKey]);
102
- await befly.redis.expire(dayKeysKey, VISIT_STATS_REDIS_TTL_SECONDS);
103
- await befly.redis.incrWithExpire(bucketPvKey, VISIT_STATS_REDIS_TTL_SECONDS);
104
- await befly.redis.sadd(bucketUvKey, [member]);
105
- await befly.redis.expire(bucketUvKey, VISIT_STATS_REDIS_TTL_SECONDS);
106
- await befly.redis.incrWithExpire(dayPvKey, VISIT_STATS_REDIS_TTL_SECONDS);
107
- await befly.redis.sadd(dayUvKey, [member]);
108
- await befly.redis.expire(dayUvKey, VISIT_STATS_REDIS_TTL_SECONDS);
109
- }
110
-
111
- async function ensureVisitStatsTableReady(befly) {
112
- if (befly.visitStatsTableReady !== undefined) {
113
- return befly.visitStatsTableReady;
114
- }
115
-
116
- const tableExistsResult = await befly.mysql.tableExists("beflyVisitStats");
117
- befly.visitStatsTableReady = tableExistsResult.data === true;
118
- return befly.visitStatsTableReady;
119
- }
120
-
121
- async function flushVisitStatsBucket(befly, bucketTime) {
122
- if (bucketTime <= 0) {
123
- return;
124
- }
125
-
126
- const currentBucketTime = getTimeBucketStart(Date.now(), VISIT_STATS_BUCKET_MS);
127
- if (bucketTime >= currentBucketTime) {
128
- return;
129
- }
130
-
131
- const tableReady = await ensureVisitStatsTableReady(befly);
132
- if (!tableReady) {
133
- return;
134
- }
135
-
136
- const flushedKey = `visitStats:flushed:${bucketTime}`;
137
- const flushed = await befly.redis.exists(flushedKey);
138
- if (flushed) {
139
- return;
140
- }
141
-
142
- const bucketDate = getDateYmdNumber(bucketTime);
143
- const bucketKey = getVisitStatsBucketKey(bucketTime);
144
- const pv = toVisitStatsNumber(await befly.redis.getString(`${bucketKey}:pv`));
145
- const uv = await befly.redis.scard(`${bucketKey}:uv`);
146
- const errorCount = toVisitStatsNumber(await befly.redis.getString(`${bucketKey}:errorCount`));
147
- const durationSum = toVisitStatsNumber(await befly.redis.getString(`${bucketKey}:durationSum`));
148
- const durationCount = toVisitStatsNumber(await befly.redis.getString(`${bucketKey}:durationCount`));
149
- const avgDuration = durationCount > 0 ? Math.round(durationSum / durationCount) : 0;
150
-
151
- if (pv <= 0 && uv <= 0 && errorCount <= 0 && durationCount <= 0) {
152
- await befly.redis.setString(flushedKey, "1", VISIT_STATS_REDIS_TTL_SECONDS);
153
- return;
154
- }
155
-
156
- const data = {
157
- bucketTime: bucketTime,
158
- bucketDate: bucketDate,
159
- pv: pv,
160
- uv: uv,
161
- errorCount: errorCount,
162
- durationSum: durationSum,
163
- durationCount: durationCount,
164
- avgDuration: avgDuration
165
- };
166
-
167
- const detail = await befly.mysql.getOne({
168
- table: "beflyVisitStats",
169
- where: { bucketTime: bucketTime }
170
- });
171
-
172
- if (detail.data?.id) {
173
- await befly.mysql.updData({
174
- table: "beflyVisitStats",
175
- data: data,
176
- where: { bucketTime: bucketTime }
177
- });
178
- } else {
179
- await befly.mysql.insData({
180
- table: "beflyVisitStats",
181
- data: data
182
- });
183
- }
184
-
185
- await befly.redis.setString(flushedKey, "1", VISIT_STATS_REDIS_TTL_SECONDS);
186
- }
187
-
188
- async function flushVisitStatsPreviousBucket(befly, now = Date.now()) {
189
- const currentBucketTime = getTimeBucketStart(now, VISIT_STATS_BUCKET_MS);
190
- await flushVisitStatsBucket(befly, currentBucketTime - 30 * 60 * 1000);
191
- }
192
-
193
- export default {
194
- name: "上报访问统计",
195
- method: "POST",
196
- body: "none",
197
- auth: false,
198
- fields: {
199
- pagePath: { name: "页面路径", input: "string", min: 0, max: 200 },
200
- pageName: { name: "页面名称", input: "string", min: 0, max: 100 },
201
- source: { name: "来源", input: "string", min: 0, max: 50 },
202
- productName: { name: "产品名称", input: "string", min: 0, max: 100 },
203
- productCode: { name: "产品代号", input: "string", min: 0, max: 100 },
204
- productVersion: { name: "产品版本", input: "string", min: 0, max: 100 }
205
- },
206
- required: [],
207
- handler: async (befly, ctx) => {
208
- const now = Date.now();
209
- const bucketTime = getTimeBucketStart(now, VISIT_STATS_BUCKET_MS);
210
- const bucketDate = getDateYmdNumber(now);
211
- const bucketKey = getVisitStatsBucketKey(bucketTime);
212
- const dayKey = getVisitStatsDayKey(bucketDate);
213
- const member = getVisitStatsMember(ctx);
214
- const uaData = getVisitStatsUaData(ctx);
215
- const productData = getVisitStatsProductData(ctx);
216
-
217
- await flushVisitStatsPreviousBucket(befly, now);
218
-
219
- await befly.redis.incrWithExpire(`${bucketKey}:pv`, VISIT_STATS_REDIS_TTL_SECONDS);
220
- await befly.redis.incrWithExpire(`${dayKey}:pv`, VISIT_STATS_REDIS_TTL_SECONDS);
221
-
222
- await befly.redis.sadd(`${bucketKey}:uv`, [member]);
223
- await befly.redis.expire(`${bucketKey}:uv`, VISIT_STATS_REDIS_TTL_SECONDS);
224
- await befly.redis.sadd(`${dayKey}:uv`, [member]);
225
- await befly.redis.expire(`${dayKey}:uv`, VISIT_STATS_REDIS_TTL_SECONDS);
226
-
227
- await befly.redis.setString(`visitStats:online:visitor:${member}`, "1", VISIT_STATS_ONLINE_TTL_SECONDS);
228
- await befly.redis.sadd("visitStats:online:visitors", [member]);
229
- await befly.redis.expire("visitStats:online:visitors", VISIT_STATS_REDIS_TTL_SECONDS);
230
- await saveVisitStatsUaData(befly, bucketDate, uaData);
231
- await saveVisitStatsProductData(befly, bucketDate, productData);
232
- await saveVisitStatsProductSummary(befly, bucketTime, bucketDate, member, productData);
233
-
234
- const result = {
235
- bucketTime: bucketTime,
236
- bucketDate: bucketDate
237
- };
238
-
239
- return befly.tool.Yes("上报成功", result);
240
- }
241
- };