befly 3.69.0 → 3.70.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.
@@ -0,0 +1,47 @@
1
+ import { getTongJiDateYmdNumber } from "./_tongJi.js";
2
+
3
+ async function getTodayCount(befly, reportDate, productCode) {
4
+ if (!befly.redis) {
5
+ return 0;
6
+ }
7
+
8
+ return Number(await befly.redis.scard(`daily:day:${reportDate}:members:${productCode}`)) || 0;
9
+ }
10
+
11
+ async function loadProjects(befly) {
12
+ if (!befly.mysql) {
13
+ return [];
14
+ }
15
+
16
+ const result = await befly.mysql.getAll({
17
+ table: "beflyProject",
18
+ fields: ["code"],
19
+ where: { state: 1 }
20
+ });
21
+
22
+ return result.data?.lists || [];
23
+ }
24
+
25
+ export default {
26
+ name: "获取今日在线总数",
27
+ method: "POST",
28
+ body: "none",
29
+ auth: true,
30
+ fields: {},
31
+ required: [],
32
+ handler: async (befly, _ctx) => {
33
+ const reportDate = getTongJiDateYmdNumber(Date.now(), befly.config?.tz);
34
+ const projects = await loadProjects(befly);
35
+ let total = 0;
36
+
37
+ for (const item of projects) {
38
+ total += await getTodayCount(befly, reportDate, item.code);
39
+ }
40
+
41
+ return befly.tool.Yes("获取成功", {
42
+ today: {
43
+ count: total
44
+ }
45
+ });
46
+ }
47
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "befly",
3
- "version": "3.69.0",
3
+ "version": "3.70.0",
4
4
  "gitHead": "49c39d36695036e85fc64083cc43c1652fff96cb",
5
5
  "private": false,
6
6
  "description": "Befly - 为 Bun 专属打造的 JavaScript API 接口框架核心引擎",
@@ -1,297 +0,0 @@
1
- const WINDOWS_VERSION_MAP = {
2
- "10.0": "10",
3
- 6.3: "8.1",
4
- 6.2: "8",
5
- 6.1: "7"
6
- };
7
-
8
- function firstMatch(text, regexp) {
9
- const matched = regexp.exec(text);
10
-
11
- if (!matched) {
12
- return null;
13
- }
14
-
15
- for (let index = 1; index < matched.length; index++) {
16
- if (matched[index]) {
17
- return matched[index];
18
- }
19
- }
20
-
21
- return null;
22
- }
23
-
24
- function firstNonEmptyMatch(text, regexp) {
25
- const matched = regexp.exec(text);
26
-
27
- if (!matched) {
28
- return null;
29
- }
30
-
31
- for (let index = 1; index < matched.length; index++) {
32
- if (matched[index]) {
33
- return matched[index];
34
- }
35
- }
36
-
37
- return null;
38
- }
39
-
40
- function hasMatch(text, regexp) {
41
- return regexp.test(text) ? "" : null;
42
- }
43
-
44
- function normalizeVersion(version) {
45
- return String(version || "").replace(/_/g, ".");
46
- }
47
-
48
- function majorVersion(version) {
49
- const parts = String(version || "").split(".");
50
- return parts[0] || "";
51
- }
52
-
53
- function matchBrowser(text) {
54
- const rules = [
55
- { name: "wxwork", regexp: /wxwork\/([\d.]+)/ },
56
- { name: "WeChat", regexp: /MicroMessenger\/([\d.]+)/ },
57
- { name: "DingTalk", regexp: /DingTalk\/([\d.]+)/ },
58
- { name: "Alipay", regexp: /AlipayClient\/([\d.]+)/ },
59
- { name: "Taobao", regexp: /(?:TaoBao|AliApp\(TB|WindVane)/, match: hasMatch },
60
- { name: "Jingdong", regexp: /jdapp/i, match: hasMatch },
61
- { name: "Weibo", regexp: /Weibo|__weibo__/, match: hasMatch },
62
- { name: "Douyin", regexp: /(?:aweme|Trill|Douyin)/i, match: hasMatch },
63
- { name: "Lark", regexp: /(?:Lark|Feishu)\S*?\/([\d.]+)/ },
64
- { name: "QQ Browser", regexp: /(?:MQQBrowser|QQBrowser)\/([\d.]+)/ },
65
- { name: "UC Browser", regexp: /UCBrowser\/([\d.]+)/ },
66
- { name: "Quark", regexp: /Quark\/([\d.]+)/ },
67
- { name: "Baidu", regexp: /(?:baiduboxapp|baiduapp|BaiduBrowser|FlyFlow)\S*?\/([\d.]+)/i },
68
- { name: "Sogou", regexp: /(?:SogouMobileBrowser|SogouMSE|MetaSr)\S*?\/([\d.]+)/i },
69
- { name: "360", regexp: /(?:360SE|360EE|QHBrowser|QihooBrowser)\S*?(?:\s|v|\/)([\d.]+)/i },
70
- { name: "Huawei Browser", regexp: /HuaweiBrowser\/([\d.]+)/ },
71
- { name: "MiuiBrowser", regexp: /MiuiBrowser\/([\d.]+)/ },
72
- { name: "HeyTapBrowser", regexp: /HeyTapBrowser\/([\d.]+)/ },
73
- { name: "VivoBrowser", regexp: /VivoBrowser\/([\d.]+)/ },
74
- { name: "Samsung Browser", regexp: /SamsungBrowser\/([\d.]+)/ },
75
- { name: "Maxthon", regexp: /Maxthon\/([\d.]+)/ },
76
- { name: "Edge", regexp: /Edg(?:e|A|iOS)?\/([\d.]+)/ },
77
- { name: "Opera", regexp: /(?:OPR|Opera)\/([\d.]+)/ },
78
- { name: "Firefox", regexp: /(?:FxiOS|Firefox)\/([\d.]+)/ },
79
- { name: "Chrome", regexp: /(?:CriOS|Chrome)\/([\d.]+)/ },
80
- { name: "Safari", regexp: /Version\/([\d.]+).*Safari/ },
81
- { name: "IE", regexp: /(?:MSIE\s([\d.]+)|Trident\/.*rv:([\d.]+))/, match: firstNonEmptyMatch }
82
- ];
83
-
84
- for (const rule of rules) {
85
- const matcher = rule.match || firstMatch;
86
- const version = matcher(text, rule.regexp);
87
-
88
- if (version !== null) {
89
- const name = rule.name === "Safari" && /iPhone|iPad|iPod/i.test(text) ? "Mobile Safari" : rule.name;
90
-
91
- return { name: name, version: version };
92
- }
93
- }
94
-
95
- return { name: "", version: "" };
96
- }
97
-
98
- function matchEngine(text) {
99
- if (/AppleWebKit/i.test(text) && /iPhone|iPad|iPod/i.test(text)) {
100
- return { name: "WebKit", version: firstMatch(text, /AppleWebKit\/([\d.]+)/) };
101
- }
102
-
103
- const rules = [
104
- { name: "Blink", regexp: /Chrome\/([\d.]+)/ },
105
- { name: "Blink", regexp: /CriOS\/([\d.]+)/ },
106
- { name: "Blink", regexp: /Edg(?:e|A|iOS)?\/([\d.]+)/ },
107
- { name: "Blink", regexp: /OPR\/([\d.]+)/ },
108
- { name: "Gecko", regexp: /Firefox\/([\d.]+)/ },
109
- { name: "Gecko", regexp: /FxiOS\/([\d.]+)/ },
110
- { name: "WebKit", regexp: /AppleWebKit\/([\d.]+)/ },
111
- { name: "Trident", regexp: /Trident\/([\d.]+)/ },
112
- { name: "Trident", regexp: /MSIE\s([\d.]+)/ }
113
- ];
114
-
115
- for (const rule of rules) {
116
- const version = firstMatch(text, rule.regexp);
117
-
118
- if (version) {
119
- return { name: rule.name, version: version };
120
- }
121
- }
122
-
123
- return { name: "", version: "" };
124
- }
125
-
126
- function matchOs(text) {
127
- const androidVersion = firstMatch(text, /Android\s([\d.]+)/);
128
-
129
- if (androidVersion) {
130
- return { name: "Android", version: androidVersion };
131
- }
132
-
133
- const iosVersion = firstMatch(text, /(?:iPhone|iPad|iPod).*OS\s([\d_]+)/);
134
-
135
- if (iosVersion) {
136
- return { name: "iOS", version: normalizeVersion(iosVersion) };
137
- }
138
-
139
- const windowsVersion = firstMatch(text, /Windows NT\s([\d.]+)/);
140
-
141
- if (windowsVersion) {
142
- return { name: "Windows", version: WINDOWS_VERSION_MAP[windowsVersion] || windowsVersion };
143
- }
144
-
145
- const macVersion = firstMatch(text, /Mac OS X\s([\d_]+)/);
146
-
147
- if (macVersion) {
148
- return { name: "macOS", version: normalizeVersion(macVersion) };
149
- }
150
-
151
- if (/HarmonyOS/i.test(text)) {
152
- return { name: "HarmonyOS", version: "" };
153
- }
154
-
155
- if (/Linux/i.test(text)) {
156
- return { name: "Linux", version: "" };
157
- }
158
-
159
- if (/CrOS/i.test(text)) {
160
- return { name: "Chrome OS", version: "" };
161
- }
162
-
163
- return { name: "", version: "" };
164
- }
165
-
166
- function getDeviceType(text) {
167
- if (/iPad|Tablet|PlayBook|Silk/i.test(text) || (/Android/i.test(text) && !/Mobile/i.test(text))) {
168
- return "tablet";
169
- }
170
-
171
- if (/PlayStation|Xbox|Nintendo|CrKey|Roku|AppleTV|SmartTV|TV/i.test(text)) {
172
- return "console";
173
- }
174
-
175
- if (/bot|crawler|spider|googlebot|bingbot|baiduspider|slurp|yandex|duckduckgo/i.test(text)) {
176
- return "bot";
177
- }
178
-
179
- if (/Mobi|iPhone|iPod|Phone\s*\d|Android.*Mobile|Windows Phone/i.test(text)) {
180
- return "mobile";
181
- }
182
-
183
- if (/HarmonyOS/i.test(text) && !/Pad|Tablet/i.test(text)) {
184
- return "mobile";
185
- }
186
-
187
- if (/HarmonyOS/i.test(text)) {
188
- return "tablet";
189
- }
190
-
191
- return "desktop";
192
- }
193
-
194
- function matchAndroidModel(text) {
195
- const matched = /Android[\d.\s]*;\s*([^;)]+?)(?:\s+Build\/|;|\))/i.exec(text);
196
- return matched ? matched[1].trim() : "";
197
- }
198
-
199
- function matchVendor(text) {
200
- if (/(iPhone|iPad|iPod|Macintosh)\b/i.test(text)) {
201
- return "Apple";
202
- }
203
-
204
- if (/Samsung|SM-\w+/i.test(text)) {
205
- return "Samsung";
206
- }
207
-
208
- if (/Huawei|HUAWEI|Honor|HONOR/i.test(text)) {
209
- return "Huawei";
210
- }
211
-
212
- if (/Xiaomi|Redmi|Mi\s|MI\s|M200|M201|M202|M210|M211|M220|M221|M230|M231|M240/i.test(text)) {
213
- return "Xiaomi";
214
- }
215
-
216
- if (/OPPO|PB[A-Z]|PCHM\d+|PCAM\d+/i.test(text)) {
217
- return "OPPO";
218
- }
219
-
220
- if (/vivo|V\d{4}[A-Z]/i.test(text)) {
221
- return "vivo";
222
- }
223
-
224
- return "";
225
- }
226
-
227
- function matchDevice(text) {
228
- const type = getDeviceType(text);
229
-
230
- if (/iPad/i.test(text)) {
231
- return { vendor: "Apple", model: "iPad", type: type };
232
- }
233
-
234
- if (/iPod/i.test(text)) {
235
- return { vendor: "Apple", model: "iPod", type: type };
236
- }
237
-
238
- if (/iPhone/i.test(text)) {
239
- return { vendor: "Apple", model: "iPhone", type: type };
240
- }
241
-
242
- return { vendor: matchVendor(text), model: matchAndroidModel(text), type: type };
243
- }
244
-
245
- function matchCpuArchitecture(text) {
246
- if (/x86_64|Win64|x64|amd64/i.test(text)) {
247
- return "amd64";
248
- }
249
-
250
- if (/arm64|aarch64/i.test(text)) {
251
- return "arm64";
252
- }
253
-
254
- if (/arm/i.test(text)) {
255
- return "arm";
256
- }
257
-
258
- return "";
259
- }
260
-
261
- export function parseUserAgent(userAgent) {
262
- const text = String(userAgent || "");
263
- const browser = matchBrowser(text);
264
- const engine = matchEngine(text);
265
- const os = matchOs(text);
266
- const device = matchDevice(text);
267
- const cpu = { architecture: matchCpuArchitecture(text) };
268
-
269
- return {
270
- userAgent: text,
271
- browserName: browser.name,
272
- browserVersion: browser.version,
273
- osName: os.name,
274
- osVersion: os.version,
275
- deviceType: device.type,
276
- deviceVendor: device.vendor,
277
- deviceModel: device.model,
278
- engineName: engine.name,
279
- engineVersion: engine.version,
280
- cpuArchitecture: cpu.architecture,
281
- browser: { name: browser.name, version: browser.version, major: majorVersion(browser.version) },
282
- engine: engine,
283
- os: os,
284
- device: device,
285
- cpu: cpu
286
- };
287
- }
288
-
289
- export function getUserAgentFields(userAgent) {
290
- const text = typeof userAgent === "string" ? userAgent.trim() : "";
291
-
292
- if (text.length === 0) {
293
- return null;
294
- }
295
-
296
- return parseUserAgent(text);
297
- }