@zhin.js/plugin-group-suite 0.1.0 → 0.1.2

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/teach.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { MessageCommand } from "zhin.js";
2
- import { getMessageContextKey, ts } from "./shared.js";
2
+ import { extractInboundText, getMessageContextKey, ts } from "./shared.js";
3
3
  const cooldownMap = new Map();
4
4
  function isSafeRegex(pattern) {
5
5
  if (pattern.length > 200)
@@ -15,6 +15,34 @@ function isSafeRegex(pattern) {
15
15
  }
16
16
  return true;
17
17
  }
18
+ /** 从 teach / teach-regex 命令的剩余文本解析「问题|答案」或「问题 答案」 */
19
+ function extractRestParam(payload) {
20
+ if (Array.isArray(payload)) {
21
+ return payload.map((v) => String(v)).join(" ").trim();
22
+ }
23
+ return String(payload ?? "").trim();
24
+ }
25
+ function parseTeachPair(raw) {
26
+ if (!raw)
27
+ return null;
28
+ const pipe = raw.indexOf("|");
29
+ if (pipe >= 0) {
30
+ const question = raw.slice(0, pipe).trim();
31
+ const answer = raw.slice(pipe + 1).trim();
32
+ if (question && answer)
33
+ return { question, answer };
34
+ return null;
35
+ }
36
+ const lastSpace = raw.lastIndexOf(" ");
37
+ if (lastSpace < 0)
38
+ return null;
39
+ const question = raw.slice(0, lastSpace).trim();
40
+ const answer = raw.slice(lastSpace + 1).trim();
41
+ if (!question || !answer)
42
+ return null;
43
+ return { question, answer };
44
+ }
45
+ const TEACH_USAGE_HINT = "格式:teach 关键词 回答(回答可含空格),或 teach 问题|答案";
18
46
  function processAnswer(answer, message, match) {
19
47
  let result = answer;
20
48
  result = result.replace(/\{sender\}/g, message.$sender?.name || "你");
@@ -32,8 +60,18 @@ let _db = null;
32
60
  function getQA() {
33
61
  return _db?.models?.get("teach_qa") ?? null;
34
62
  }
63
+ /** teach_qa 无自增 id 列,更新/删除用业务主键 */
64
+ function qaWhereKey(row) {
65
+ return {
66
+ question: row.question,
67
+ context_type: row.context_type,
68
+ context_id: row.context_id,
69
+ is_regex: row.is_regex ? 1 : 0,
70
+ };
71
+ }
35
72
  export function registerTeach(plugin, cfg) {
36
- const { addCommand, addMiddleware, useContext, onDispose } = plugin;
73
+ const { addCommand, useContext, onDispose } = plugin;
74
+ const root = plugin.root;
37
75
  useContext("database", (db) => {
38
76
  _db = db;
39
77
  db.define("teach_qa", {
@@ -83,15 +121,16 @@ export function registerTeach(plugin, cfg) {
83
121
  }
84
122
  return null;
85
123
  }
86
- addMiddleware(async (message, next) => {
87
- const content = (message.$raw || "").trim();
124
+ // 入站链只执行 root.middleware(见 packages/im/core inbound-runner)
125
+ root.addMiddleware(async (message, next) => {
126
+ const content = extractInboundText(message);
88
127
  if (!content)
89
128
  return next();
90
129
  const { type: ctxType, id: ctxId } = getMessageContextKey(message);
91
130
  const matched = await findMatch(content, ctxType, ctxId);
92
131
  if (!matched)
93
132
  return next();
94
- const cooldownKey = `${matched.id}:${ctxType}:${ctxId}`;
133
+ const cooldownKey = `${matched.question}:${ctxType}:${ctxId}:${matched.is_regex ?? 0}`;
95
134
  const last = cooldownMap.get(cooldownKey);
96
135
  if (last && Date.now() - last < cfg.teachCooldownMs)
97
136
  return next();
@@ -102,7 +141,7 @@ export function registerTeach(plugin, cfg) {
102
141
  await QA.update({
103
142
  hit_count: (matched.hit_count || 0) + 1,
104
143
  updated_at: ts(),
105
- }).where({ id: matched.id });
144
+ }).where(qaWhereKey(matched));
106
145
  }
107
146
  catch {
108
147
  /* ignore */
@@ -122,64 +161,48 @@ export function registerTeach(plugin, cfg) {
122
161
  answer = processAnswer(answer, message);
123
162
  }
124
163
  await message.$reply(answer);
164
+ return;
125
165
  });
126
- addCommand(new MessageCommand("teach <question:text> <answer:text>")
127
- .desc("教我问答", "教会 Bot 一个新的问答对")
166
+ // 先注册较长前缀,避免 `teach [...]` 误匹配 teach-list / teach-regex
167
+ addCommand(new MessageCommand("teach-list [page:number]")
168
+ .desc("问答列表", "查看问答对")
128
169
  .action(async (message, result) => {
129
170
  const QA = getQA();
130
171
  if (!QA)
131
- return "问答数据库尚未就绪,请稍后重试";
132
- const question = result.params.question?.trim();
133
- const answer = result.params.answer?.trim();
134
- if (!question || !answer)
135
- return "请提供问题和回答";
172
+ return "问答数据库尚未就绪";
173
+ const page = Math.max(1, result.params.page || 1);
136
174
  const { type: ctxType, id: ctxId } = getMessageContextKey(message);
137
- if (ctxType === "group") {
138
- const existing = await QA.select().where({
139
- context_type: ctxType,
140
- context_id: ctxId,
141
- });
142
- if (existing.length >= cfg.teachMaxPerGroup) {
143
- return `该群问答数已达上限 (${cfg.teachMaxPerGroup})`;
144
- }
145
- }
146
- const duplicate = await QA.select().where({
147
- question,
148
- context_type: ctxType,
149
- context_id: ctxId,
150
- });
151
- if (duplicate.length > 0) {
152
- await QA.update({ answer, updated_at: ts() }).where({
153
- id: duplicate[0].id,
154
- });
155
- return `已更新问答:「${question}」→「${answer}」`;
156
- }
157
- await QA.insert({
158
- question,
159
- answer,
160
- is_regex: 0,
161
- context_type: ctxType,
162
- context_id: ctxId,
163
- creator_id: message.$sender?.id || "",
164
- creator_name: message.$sender?.name || "",
165
- hit_count: 0,
166
- created_at: ts(),
167
- updated_at: ts(),
175
+ const allItems = await QA.select().where(ctxType === "global"
176
+ ? { context_type: "global" }
177
+ : { context_type: ctxType, context_id: ctxId });
178
+ if (allItems.length === 0)
179
+ return "还没有教过任何问答哦~";
180
+ const totalPages = Math.ceil(allItems.length / cfg.teachPageSize);
181
+ const safePage = Math.min(page, totalPages);
182
+ const start = (safePage - 1) * cfg.teachPageSize;
183
+ const pageItems = allItems.slice(start, start + cfg.teachPageSize);
184
+ const lines = pageItems.map((item, i) => {
185
+ const prefix = item.is_regex ? "[正则]" : "[精确]";
186
+ const q = item.is_regex ? `/${item.question}/` : item.question;
187
+ return `${start + i + 1}. ${prefix} ${q} → ${item.answer}`;
168
188
  });
169
- return `学会了!发送「${question}」我会回复「${answer}」`;
189
+ const header = ctxType === "global" ? "全局问答列表" : "本群问答列表";
190
+ return `${header}\n${lines.join("\n")}\n第 ${safePage}/${totalPages} 页 · 共 ${allItems.length} 条`;
170
191
  }));
171
- addCommand(new MessageCommand("teach-regex <pattern:text> <answer:text>")
192
+ addCommand(new MessageCommand("teach-regex [...payload:text]")
172
193
  .desc("教我正则问答", "用正则匹配")
194
+ .usage("teach-regex 正则 回答", "teach-regex 正则|回答")
173
195
  .action(async (message, result) => {
174
196
  const QA = getQA();
175
197
  if (!QA)
176
198
  return "问答数据库尚未就绪";
177
199
  if (!cfg.teachAllowRegex)
178
200
  return "管理员已禁用正则问答";
179
- const pattern = result.params.pattern?.trim();
180
- const answer = result.params.answer?.trim();
181
- if (!pattern || !answer)
182
- return "请提供正则和回答";
201
+ const parsed = parseTeachPair(extractRestParam(result.params.payload));
202
+ if (!parsed)
203
+ return "格式:teach-regex 正则 回答,或 teach-regex 正则|回答";
204
+ const pattern = parsed.question;
205
+ const answer = parsed.answer;
183
206
  try {
184
207
  new RegExp(pattern, "i");
185
208
  }
@@ -220,33 +243,52 @@ export function registerTeach(plugin, cfg) {
220
243
  });
221
244
  if (items.length === 0)
222
245
  return `没有找到问题「${question}」`;
223
- await QA.delete().where({ id: items[0].id });
246
+ await QA.delete().where(qaWhereKey(items[0]));
224
247
  return `已忘记「${question}」的回答`;
225
248
  }));
226
- addCommand(new MessageCommand("teach-list [page:number]")
227
- .desc("问答列表", "查看问答对")
249
+ addCommand(new MessageCommand("teach [...payload:text]")
250
+ .desc("教我问答", "教会 Bot 一个新的问答对")
251
+ .usage("teach 关键词 回答", "teach 问题|答案")
228
252
  .action(async (message, result) => {
229
253
  const QA = getQA();
230
254
  if (!QA)
231
- return "问答数据库尚未就绪";
232
- const page = Math.max(1, result.params.page || 1);
255
+ return "问答数据库尚未就绪,请稍后重试";
256
+ const parsed = parseTeachPair(extractRestParam(result.params.payload));
257
+ if (!parsed)
258
+ return TEACH_USAGE_HINT;
259
+ const { question, answer } = parsed;
233
260
  const { type: ctxType, id: ctxId } = getMessageContextKey(message);
234
- const allItems = await QA.select().where(ctxType === "global"
235
- ? { context_type: "global" }
236
- : { context_type: ctxType, context_id: ctxId });
237
- if (allItems.length === 0)
238
- return "还没有教过任何问答哦~";
239
- const totalPages = Math.ceil(allItems.length / cfg.teachPageSize);
240
- const safePage = Math.min(page, totalPages);
241
- const start = (safePage - 1) * cfg.teachPageSize;
242
- const pageItems = allItems.slice(start, start + cfg.teachPageSize);
243
- const lines = pageItems.map((item, i) => {
244
- const prefix = item.is_regex ? "[正则]" : "[精确]";
245
- const q = item.is_regex ? `/${item.question}/` : item.question;
246
- return `${start + i + 1}. ${prefix} ${q} → ${item.answer}`;
261
+ if (ctxType === "group") {
262
+ const existing = await QA.select().where({
263
+ context_type: ctxType,
264
+ context_id: ctxId,
265
+ });
266
+ if (existing.length >= cfg.teachMaxPerGroup) {
267
+ return `该群问答数已达上限 (${cfg.teachMaxPerGroup})`;
268
+ }
269
+ }
270
+ const duplicate = await QA.select().where({
271
+ question,
272
+ context_type: ctxType,
273
+ context_id: ctxId,
247
274
  });
248
- const header = ctxType === "global" ? "全局问答列表" : "本群问答列表";
249
- return `${header}\n${lines.join("\n")}\n第 ${safePage}/${totalPages} 页 · 共 ${allItems.length} 条`;
275
+ if (duplicate.length > 0) {
276
+ await QA.update({ answer, updated_at: ts() }).where(qaWhereKey(duplicate[0]));
277
+ return `已更新问答:「${question}」→「${answer}」`;
278
+ }
279
+ await QA.insert({
280
+ question,
281
+ answer,
282
+ is_regex: 0,
283
+ context_type: ctxType,
284
+ context_id: ctxId,
285
+ creator_id: message.$sender?.id || "",
286
+ creator_name: message.$sender?.name || "",
287
+ hit_count: 0,
288
+ created_at: ts(),
289
+ updated_at: ts(),
290
+ });
291
+ return `学会了!发送「${question}」我会回复「${answer}」`;
250
292
  }));
251
293
  }
252
294
  //# sourceMappingURL=teach.js.map
package/lib/teach.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"teach.js","sourceRoot":"","sources":["../src/teach.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"teach.js","sourceRoot":"","sources":["../src/teach.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhin.js/plugin-group-suite",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Zhin.js 群运营套件 — 群管、签到、统计、日常分析、问答(合并原 5 个插件)",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",
@@ -41,12 +41,12 @@
41
41
  "dependencies": {},
42
42
  "devDependencies": {
43
43
  "typescript": "^6.0.3",
44
- "@zhin.js/plugin-html-renderer": "0.0.63",
45
- "zhin.js": "1.0.85"
44
+ "zhin.js": "1.0.87",
45
+ "@zhin.js/plugin-html-renderer": "0.0.65"
46
46
  },
47
47
  "peerDependencies": {
48
- "@zhin.js/plugin-html-renderer": "0.0.63",
49
- "zhin.js": "1.0.85"
48
+ "zhin.js": "1.0.87",
49
+ "@zhin.js/plugin-html-renderer": "0.0.65"
50
50
  },
51
51
  "peerDependenciesMeta": {
52
52
  "@zhin.js/plugin-html-renderer": {
package/src/admin.ts CHANGED
@@ -8,7 +8,7 @@ import { adapterAllowed } from "./shared.js";
8
8
  import type { GroupSuiteConfig } from "./config.js";
9
9
 
10
10
  export function registerAdmin(plugin: Plugin, cfg: GroupSuiteConfig): void {
11
- const { addCommand, addMiddleware, addTool, logger } = plugin;
11
+ const { addCommand, addTool, logger } = plugin;
12
12
  const welcomeTemplate = cfg.welcome;
13
13
  const noticeAdapters = cfg.noticeAdapters;
14
14
 
@@ -73,7 +73,7 @@ export function registerAdmin(plugin: Plugin, cfg: GroupSuiteConfig): void {
73
73
 
74
74
  const keywords = new Map<string, string>();
75
75
 
76
- addMiddleware(async (message, next) => {
76
+ plugin.root.addMiddleware(async (message, next) => {
77
77
  if (message.$channel.type !== "group") {
78
78
  await next();
79
79
  return;
package/src/checkin.ts CHANGED
@@ -14,7 +14,7 @@ function randomInt(min: number, max: number): number {
14
14
 
15
15
  let _db: any = null;
16
16
 
17
- function getModel(): any {
17
+ export function getCheckinModel(): any {
18
18
  return _db?.models?.get("checkin_records") ?? null;
19
19
  }
20
20
 
@@ -36,7 +36,7 @@ export function registerCheckin(plugin: Plugin, cfg: GroupSuiteConfig): void {
36
36
  created_at: { type: "text", default: "" },
37
37
  updated_at: { type: "text", default: "" },
38
38
  });
39
- logger.info(formatCompact({ op: "checkin_model" }));
39
+ logger.info(formatCompact({ 模块: "签到", 数据模型: "已就绪" }));
40
40
  });
41
41
 
42
42
  async function getOrCreateUser(
@@ -79,7 +79,7 @@ export function registerCheckin(plugin: Plugin, cfg: GroupSuiteConfig): void {
79
79
  new MessageCommand("checkin")
80
80
  .desc("签到", "每日签到获得积分")
81
81
  .action(async (message) => {
82
- const M = getModel();
82
+ const M = getCheckinModel();
83
83
  if (!M) return "签到数据库尚未就绪,请稍后重试";
84
84
 
85
85
  const userId = String(message.$sender?.id || "");
@@ -110,7 +110,11 @@ export function registerCheckin(plugin: Plugin, cfg: GroupSuiteConfig): void {
110
110
  last_checkin: today,
111
111
  user_name: userName,
112
112
  updated_at: ts(),
113
- }).where({ id: user.id });
113
+ }).where({
114
+ user_id: userId,
115
+ context_type: ctxType,
116
+ context_id: ctxId,
117
+ });
114
118
 
115
119
  const lines = [`签到成功!`, `基础积分: +${base}`];
116
120
  if (bonus > 0) lines.push(`连续奖励: +${bonus} (连续${newStreak}天)`);
@@ -123,7 +127,7 @@ export function registerCheckin(plugin: Plugin, cfg: GroupSuiteConfig): void {
123
127
  new MessageCommand("mypoints")
124
128
  .desc("我的积分", "查看个人积分与签到信息")
125
129
  .action(async (message) => {
126
- const M = getModel();
130
+ const M = getCheckinModel();
127
131
  if (!M) return "签到数据库尚未就绪";
128
132
  const userId = String(message.$sender?.id || "");
129
133
  const { type: ctxType, id: ctxId } = getMessageContextKey(message);
@@ -150,7 +154,7 @@ export function registerCheckin(plugin: Plugin, cfg: GroupSuiteConfig): void {
150
154
  new MessageCommand("rank")
151
155
  .desc("积分排行", "查看积分排行榜")
152
156
  .action(async (message) => {
153
- const M = getModel();
157
+ const M = getCheckinModel();
154
158
  if (!M) return "签到数据库尚未就绪";
155
159
  const { type: ctxType, id: ctxId } = getMessageContextKey(message);
156
160
  const all = (await M.select().where(
@@ -183,9 +187,10 @@ export function registerCheckin(plugin: Plugin, cfg: GroupSuiteConfig): void {
183
187
 
184
188
  logger.info(
185
189
  formatCompact({
186
- op: "checkin_load",
187
- base_min: cfg.basePointsMin,
188
- base_max: cfg.basePointsMax,
190
+ 模块: "签到",
191
+ 状态: "已加载",
192
+ 基础积分最小值: cfg.basePointsMin,
193
+ 基础积分最大值: cfg.basePointsMax,
189
194
  }),
190
195
  );
191
196
  }
package/src/index.ts CHANGED
@@ -30,4 +30,4 @@ registerStats(plugin, cfg);
30
30
  registerDailyAnalysis(plugin, cfg);
31
31
  registerTeach(plugin, cfg);
32
32
 
33
- logger.info(formatCompact({ op: "group_suite_load" }));
33
+ logger.info(formatCompact({ 模块: "群组套件", 状态: "已加载" }));
package/src/shared.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { Plugin } from "zhin.js";
1
+ import { segment, type Message, type Plugin } from "zhin.js";
2
2
 
3
3
  export function todayStr(): string {
4
4
  const d = new Date();
@@ -9,6 +9,15 @@ export function ts(): string {
9
9
  return new Date().toISOString();
10
10
  }
11
11
 
12
+ /** 入站纯文本(与 AI trigger 一致:segment.toString($content),否则 $raw) */
13
+ export function extractInboundText(message: Pick<Message, "$raw" | "$content">): string {
14
+ if (message.$content?.length) {
15
+ const fromContent = segment.toString(message.$content).trim();
16
+ if (fromContent) return fromContent;
17
+ }
18
+ return (message.$raw ?? "").trim();
19
+ }
20
+
12
21
  /** 消息所属群/全局上下文 */
13
22
  export function getMessageContextKey(message: {
14
23
  $channel?: { type?: string; id?: string | number };
package/src/stats.ts CHANGED
@@ -16,7 +16,7 @@ export function monthStartStr(): string {
16
16
 
17
17
  let _db: any = null;
18
18
 
19
- function getModel(): any {
19
+ export function getStatsModel(): any {
20
20
  return _db?.models?.get("message_stats") ?? null;
21
21
  }
22
22
 
@@ -41,8 +41,8 @@ function getGroupId(message: { $channel?: { type?: string; id?: string } }): str
41
41
  return "";
42
42
  }
43
43
 
44
- async function flushBuffer(): Promise<void> {
45
- const M = getModel();
44
+ export async function flushStatsBuffer(): Promise<void> {
45
+ const M = getStatsModel();
46
46
  if (!M || buffer.size === 0) return;
47
47
  const entries = [...buffer.values()];
48
48
  buffer.clear();
@@ -58,7 +58,11 @@ async function flushBuffer(): Promise<void> {
58
58
  count: (existing[0].count || 0) + entry.count,
59
59
  user_name: entry.user_name,
60
60
  updated_at: ts(),
61
- }).where({ id: existing[0].id });
61
+ }).where({
62
+ user_id: entry.user_id,
63
+ group_id: entry.group_id,
64
+ date: entry.date,
65
+ });
62
66
  } else {
63
67
  await M.insert({
64
68
  user_id: entry.user_id,
@@ -75,11 +79,11 @@ async function flushBuffer(): Promise<void> {
75
79
  }
76
80
  }
77
81
 
78
- async function queryStats(
82
+ export async function queryStats(
79
83
  groupId: string,
80
84
  fromDate: string,
81
85
  ): Promise<Map<string, { name: string; count: number }>> {
82
- const M = getModel();
86
+ const M = getStatsModel();
83
87
  if (!M) return new Map();
84
88
  const all: any[] = groupId
85
89
  ? await M.select().where({ group_id: groupId })
@@ -127,7 +131,7 @@ function formatRank(
127
131
  }
128
132
 
129
133
  export function registerStats(plugin: Plugin, cfg: GroupSuiteConfig): void {
130
- const { logger, addCommand, addMiddleware, useContext, onDispose } = plugin;
134
+ const { logger, addCommand, useContext, onDispose } = plugin;
131
135
 
132
136
  useContext("database", (db: any) => {
133
137
  _db = db;
@@ -139,17 +143,17 @@ export function registerStats(plugin: Plugin, cfg: GroupSuiteConfig): void {
139
143
  count: { type: "integer", default: 0 },
140
144
  updated_at: { type: "text", default: "" },
141
145
  });
142
- logger.info(formatCompact({ op: "stats_model" }));
146
+ logger.info(formatCompact({ 模块: "消息统计", 数据模型: "已就绪" }));
143
147
  });
144
148
 
145
- const flushTimer = setInterval(flushBuffer, 10_000);
149
+ const flushTimer = setInterval(flushStatsBuffer, 10_000);
146
150
  onDispose(async () => {
147
151
  clearInterval(flushTimer);
148
- await flushBuffer();
152
+ await flushStatsBuffer();
149
153
  buffer.clear();
150
154
  });
151
155
 
152
- addMiddleware(async (message, next) => {
156
+ plugin.root.addMiddleware(async (message, next) => {
153
157
  const userId = String(message.$sender?.id || "");
154
158
  if (!userId) return next();
155
159
  const key = bufferKey(userId, getGroupId(message), todayStr());
@@ -173,7 +177,7 @@ export function registerStats(plugin: Plugin, cfg: GroupSuiteConfig): void {
173
177
  new MessageCommand("stats")
174
178
  .desc("消息统计", "查看今日消息统计")
175
179
  .action(async (message) => {
176
- await flushBuffer();
180
+ await flushStatsBuffer();
177
181
  const groupId = getGroupId(message);
178
182
  const stats = await queryStats(groupId, todayStr());
179
183
  const title = groupId ? "今日本群消息统计" : "今日全局消息统计";
@@ -190,7 +194,7 @@ export function registerStats(plugin: Plugin, cfg: GroupSuiteConfig): void {
190
194
  new MessageCommand("stats-week")
191
195
  .desc("周消息统计", "查看本周消息统计")
192
196
  .action(async (message) => {
193
- await flushBuffer();
197
+ await flushStatsBuffer();
194
198
  const groupId = getGroupId(message);
195
199
  const stats = await queryStats(groupId, weekStartStr());
196
200
  const title = groupId ? "本周本群消息统计" : "本周全局消息统计";
@@ -207,7 +211,7 @@ export function registerStats(plugin: Plugin, cfg: GroupSuiteConfig): void {
207
211
  new MessageCommand("stats-rank")
208
212
  .desc("话唠排行", "查看活跃度排行榜")
209
213
  .action(async (message) => {
210
- await flushBuffer();
214
+ await flushStatsBuffer();
211
215
  const groupId = getGroupId(message);
212
216
  const stats = await queryStats(groupId, monthStartStr());
213
217
  const title = groupId ? "本月话唠排行" : "全局话唠排行";
@@ -224,8 +228,8 @@ export function registerStats(plugin: Plugin, cfg: GroupSuiteConfig): void {
224
228
  new MessageCommand("mystats")
225
229
  .desc("我的统计", "查看个人消息统计")
226
230
  .action(async (message) => {
227
- await flushBuffer();
228
- const M = getModel();
231
+ await flushStatsBuffer();
232
+ const M = getStatsModel();
229
233
  if (!M) return "统计数据库尚未就绪";
230
234
  const userId = String(message.$sender?.id || "");
231
235
  if (!userId) return "无法获取用户信息";
@@ -261,7 +265,7 @@ export function registerStats(plugin: Plugin, cfg: GroupSuiteConfig): void {
261
265
  );
262
266
 
263
267
  const cleanupTimer = setInterval(async () => {
264
- const M = getModel();
268
+ const M = getStatsModel();
265
269
  if (!M) return;
266
270
  try {
267
271
  const cutoff = new Date();
@@ -269,7 +273,11 @@ export function registerStats(plugin: Plugin, cfg: GroupSuiteConfig): void {
269
273
  const cutoffStr = `${cutoff.getFullYear()}-${String(cutoff.getMonth() + 1).padStart(2, "0")}-${String(cutoff.getDate()).padStart(2, "0")}`;
270
274
  const all: any[] = await M.select();
271
275
  for (const row of all.filter((r) => r.date < cutoffStr)) {
272
- await M.delete().where({ id: row.id });
276
+ await M.delete().where({
277
+ user_id: row.user_id,
278
+ group_id: row.group_id,
279
+ date: row.date,
280
+ });
273
281
  }
274
282
  } catch {
275
283
  /* ignore */
@@ -280,9 +288,10 @@ export function registerStats(plugin: Plugin, cfg: GroupSuiteConfig): void {
280
288
 
281
289
  logger.info(
282
290
  formatCompact({
283
- op: "stats_load",
284
- rank_size: cfg.rankSize,
285
- retention_days: cfg.statsRetentionDays,
291
+ 模块: "消息统计",
292
+ 状态: "已加载",
293
+ 排行榜大小: cfg.rankSize,
294
+ 数据保留天数: cfg.statsRetentionDays,
286
295
  }),
287
296
  );
288
297
  }