koishi-plugin-chat-analyse 0.4.0 → 0.4.1
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/lib/Collector.d.ts +6 -0
- package/lib/index.js +32 -6
- package/package.json +1 -1
package/lib/Collector.d.ts
CHANGED
|
@@ -18,6 +18,11 @@ declare module 'koishi' {
|
|
|
18
18
|
analyse_msg: {
|
|
19
19
|
uid: number;
|
|
20
20
|
type: string;
|
|
21
|
+
count: number;
|
|
22
|
+
timestamp: Date;
|
|
23
|
+
};
|
|
24
|
+
analyse_rank: {
|
|
25
|
+
uid: number;
|
|
21
26
|
hour: Date;
|
|
22
27
|
count: number;
|
|
23
28
|
timestamp: Date;
|
|
@@ -48,6 +53,7 @@ export declare class Collector {
|
|
|
48
53
|
/** @const {number} BUFFER_THRESHOLD - 内存缓存区触发自动刷新的消息数量阈值。 */
|
|
49
54
|
private static readonly BUFFER_THRESHOLD;
|
|
50
55
|
private msgStatBuffer;
|
|
56
|
+
private rankStatBuffer;
|
|
51
57
|
private cmdStatBuffer;
|
|
52
58
|
private oriCacheBuffer;
|
|
53
59
|
private whoAtBuffer;
|
package/lib/index.js
CHANGED
|
@@ -55,8 +55,9 @@ var Collector = class _Collector {
|
|
|
55
55
|
static FLUSH_INTERVAL = 60 * 1e3;
|
|
56
56
|
/** @const {number} BUFFER_THRESHOLD - 内存缓存区触发自动刷新的消息数量阈值。 */
|
|
57
57
|
static BUFFER_THRESHOLD = 100;
|
|
58
|
-
//
|
|
58
|
+
// 分离的缓冲区
|
|
59
59
|
msgStatBuffer = /* @__PURE__ */ new Map();
|
|
60
|
+
rankStatBuffer = /* @__PURE__ */ new Map();
|
|
60
61
|
cmdStatBuffer = /* @__PURE__ */ new Map();
|
|
61
62
|
oriCacheBuffer = [];
|
|
62
63
|
whoAtBuffer = [];
|
|
@@ -86,10 +87,15 @@ var Collector = class _Collector {
|
|
|
86
87
|
this.ctx.model.extend("analyse_msg", {
|
|
87
88
|
uid: "unsigned",
|
|
88
89
|
type: "string",
|
|
90
|
+
count: "unsigned",
|
|
91
|
+
timestamp: "timestamp"
|
|
92
|
+
}, { primary: ["uid", "type"] });
|
|
93
|
+
this.ctx.model.extend("analyse_rank", {
|
|
94
|
+
uid: "unsigned",
|
|
89
95
|
hour: "timestamp",
|
|
90
96
|
count: "unsigned",
|
|
91
97
|
timestamp: "timestamp"
|
|
92
|
-
}, { primary: ["uid", "
|
|
98
|
+
}, { primary: ["uid", "hour"] });
|
|
93
99
|
if (this.config.enableOriRecord) {
|
|
94
100
|
this.ctx.model.extend("analyse_cache", {
|
|
95
101
|
id: "unsigned",
|
|
@@ -134,15 +140,23 @@ var Collector = class _Collector {
|
|
|
134
140
|
}
|
|
135
141
|
}
|
|
136
142
|
const hourStart = new Date(messageTime.getFullYear(), messageTime.getMonth(), messageTime.getDate(), messageTime.getHours());
|
|
143
|
+
const rankKey = `${uid}:${hourStart.toISOString()}`;
|
|
144
|
+
const existingRank = this.rankStatBuffer.get(rankKey);
|
|
145
|
+
if (existingRank) {
|
|
146
|
+
existingRank.count++;
|
|
147
|
+
existingRank.timestamp = messageTime;
|
|
148
|
+
} else {
|
|
149
|
+
this.rankStatBuffer.set(rankKey, { uid, hour: hourStart, count: 1, timestamp: messageTime });
|
|
150
|
+
}
|
|
137
151
|
const uniqueElementTypes = new Set(elements.map((e) => e.type));
|
|
138
152
|
for (const type of uniqueElementTypes) {
|
|
139
|
-
const key = `${uid}:${type}
|
|
153
|
+
const key = `${uid}:${type}`;
|
|
140
154
|
const existing = this.msgStatBuffer.get(key);
|
|
141
155
|
if (existing) {
|
|
142
156
|
existing.count++;
|
|
143
157
|
existing.timestamp = messageTime;
|
|
144
158
|
} else {
|
|
145
|
-
this.msgStatBuffer.set(key, { uid, type,
|
|
159
|
+
this.msgStatBuffer.set(key, { uid, type, count: 1, timestamp: messageTime });
|
|
146
160
|
}
|
|
147
161
|
}
|
|
148
162
|
if (this.config.enableWhoAt) {
|
|
@@ -244,10 +258,12 @@ var Collector = class _Collector {
|
|
|
244
258
|
async flushBuffers() {
|
|
245
259
|
const cmdBufferToFlush = Array.from(this.cmdStatBuffer.values());
|
|
246
260
|
const msgBufferToFlush = Array.from(this.msgStatBuffer.values());
|
|
261
|
+
const rankBufferToFlush = Array.from(this.rankStatBuffer.values());
|
|
247
262
|
const oriCacheBufferToFlush = this.oriCacheBuffer;
|
|
248
263
|
const whoAtBufferToFlush = this.whoAtBuffer;
|
|
249
264
|
this.cmdStatBuffer.clear();
|
|
250
265
|
this.msgStatBuffer.clear();
|
|
266
|
+
this.rankStatBuffer.clear();
|
|
251
267
|
this.oriCacheBuffer = [];
|
|
252
268
|
this.whoAtBuffer = [];
|
|
253
269
|
try {
|
|
@@ -268,6 +284,16 @@ var Collector = class _Collector {
|
|
|
268
284
|
(row) => msgBufferToFlush.map((item) => ({
|
|
269
285
|
uid: item.uid,
|
|
270
286
|
type: item.type,
|
|
287
|
+
count: import_koishi.$.add(import_koishi.$.ifNull(row.count, 0), item.count),
|
|
288
|
+
timestamp: item.timestamp
|
|
289
|
+
}))
|
|
290
|
+
);
|
|
291
|
+
}
|
|
292
|
+
if (rankBufferToFlush.length > 0) {
|
|
293
|
+
await this.ctx.database.upsert(
|
|
294
|
+
"analyse_rank",
|
|
295
|
+
(row) => rankBufferToFlush.map((item) => ({
|
|
296
|
+
uid: item.uid,
|
|
271
297
|
hour: item.hour,
|
|
272
298
|
count: import_koishi.$.add(import_koishi.$.ifNull(row.count, 0), item.count),
|
|
273
299
|
timestamp: item.timestamp
|
|
@@ -753,13 +779,13 @@ var Stat = class {
|
|
|
753
779
|
if (usersInGuild.length === 0) return "暂无统计数据";
|
|
754
780
|
const uids = usersInGuild.map((u) => u.uid);
|
|
755
781
|
const userNameMap = new Map(usersInGuild.map((u) => [u.uid, u.userName]));
|
|
756
|
-
const stats = await this.ctx.database.select("
|
|
782
|
+
const stats = await this.ctx.database.select("analyse_rank").where({ uid: { $in: uids }, hour: { $gte: since } }).groupBy("uid", { count: /* @__PURE__ */ __name((row) => import_koishi3.$.sum(row.count), "count") }).orderBy("count", "desc").limit(100).execute();
|
|
757
783
|
if (stats.length === 0) return "暂无统计数据";
|
|
758
784
|
const total = stats.reduce((sum, record) => sum + record.count, 0);
|
|
759
785
|
const list = stats.map((item) => [userNameMap.get(item.uid) || `UID ${item.uid}`, item.count]);
|
|
760
786
|
return { list, total };
|
|
761
787
|
} else {
|
|
762
|
-
const msgStats = await this.ctx.database.select("
|
|
788
|
+
const msgStats = await this.ctx.database.select("analyse_rank").where({ hour: { $gte: since } }).project(["uid", "count"]).execute();
|
|
763
789
|
if (msgStats.length === 0) return "暂无统计数据";
|
|
764
790
|
const allUsers = await this.ctx.database.get("analyse_user", {}, ["uid", "userId", "userName"]);
|
|
765
791
|
const uidToUserMap = new Map(allUsers.map((u) => [u.uid, { userId: u.userId, userName: u.userName }]));
|