



























@@ -13,7 +13,7 @@ import { debugLog, debugError } from "../utils/log.js";
1313import { getQQBotDataDir, getQQBotDataPath } from "../utils/platform.js";
14141515/** Persisted record for a user who has interacted with the bot. */
16-export interface KnownUser {
16+interface KnownUser {
1717openid: string;
1818type: ChatScope;
1919nickname?: string;
@@ -135,120 +135,3 @@ export function recordKnownUser(user: {
135135isDirty = true;
136136saveUsersToFile();
137137}
138-139-/** Look up one known user. */
140-export function getKnownUser(
141-accountId: string,
142-openid: string,
143-type: ChatScope = "c2c",
144-groupOpenid?: string,
145-): KnownUser | undefined {
146-return loadUsersFromFile().get(makeUserKey({ accountId, openid, type, groupOpenid }));
147-}
148-149-/** List known users with optional filtering and sorting. */
150-export function listKnownUsers(options?: {
151-accountId?: string;
152-type?: ChatScope;
153-activeWithin?: number;
154-limit?: number;
155-sortBy?: "lastSeenAt" | "firstSeenAt" | "interactionCount";
156-sortOrder?: "asc" | "desc";
157-}): KnownUser[] {
158-let users = Array.from(loadUsersFromFile().values());
159-if (options?.accountId) {
160-users = users.filter((u) => u.accountId === options.accountId);
161-}
162-if (options?.type) {
163-users = users.filter((u) => u.type === options.type);
164-}
165-if (options?.activeWithin) {
166-const cutoff = Date.now() - options.activeWithin;
167-users = users.filter((u) => u.lastSeenAt >= cutoff);
168-}
169-const sortBy = options?.sortBy ?? "lastSeenAt";
170-const sortOrder = options?.sortOrder ?? "desc";
171-users.sort((a, b) => {
172-const aV = a[sortBy] ?? 0;
173-const bV = b[sortBy] ?? 0;
174-return sortOrder === "asc" ? aV - bV : bV - aV;
175-});
176-if (options?.limit && options.limit > 0) {
177-users = users.slice(0, options.limit);
178-}
179-return users;
180-}
181-182-/** Return summary stats for known users. */
183-export function getKnownUsersStats(accountId?: string): {
184-totalUsers: number;
185-c2cUsers: number;
186-groupUsers: number;
187-activeIn24h: number;
188-activeIn7d: number;
189-} {
190-const users = listKnownUsers({ accountId });
191-const now = Date.now();
192-const day = 86400000;
193-return {
194-totalUsers: users.length,
195-c2cUsers: users.filter((u) => u.type === "c2c").length,
196-groupUsers: users.filter((u) => u.type === "group").length,
197-activeIn24h: users.filter((u) => now - u.lastSeenAt < day).length,
198-activeIn7d: users.filter((u) => now - u.lastSeenAt < 7 * day).length,
199-};
200-}
201-202-/** Remove one user record. */
203-export function removeKnownUser(
204-accountId: string,
205-openid: string,
206-type: ChatScope = "c2c",
207-groupOpenid?: string,
208-): boolean {
209-const cache = loadUsersFromFile();
210-const key = makeUserKey({ accountId, openid, type, groupOpenid });
211-if (cache.has(key)) {
212-cache.delete(key);
213-isDirty = true;
214-saveUsersToFile();
215-debugLog(`[known-users] Removed user ${openid}`);
216-return true;
217-}
218-return false;
219-}
220-221-/** Clear all user records, optionally scoped to one account. */
222-export function clearKnownUsers(accountId?: string): number {
223-const cache = loadUsersFromFile();
224-let count = 0;
225-if (accountId) {
226-for (const [key, user] of cache.entries()) {
227-if (user.accountId === accountId) {
228-cache.delete(key);
229-count++;
230-}
231-}
232-} else {
233-count = cache.size;
234-cache.clear();
235-}
236-if (count > 0) {
237-isDirty = true;
238-doSaveUsersToFile();
239-debugLog(`[known-users] Cleared ${count} users`);
240-}
241-return count;
242-}
243-244-/** Return all groups in which a user has interacted. */
245-export function getUserGroups(accountId: string, openid: string): string[] {
246-return listKnownUsers({ accountId, type: "group" })
247-.filter((u) => u.openid === openid && u.groupOpenid)
248-.map((u) => u.groupOpenid!);
249-}
250-251-/** Return all recorded members for one group. */
252-export function getGroupMembers(accountId: string, groupOpenid: string): KnownUser[] {
253-return listKnownUsers({ accountId, type: "group" }).filter((u) => u.groupOpenid === groupOpenid);
254-}
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。