// 直接调用 bot stats 逻辑,不走 HTTP import { PrismaClient } from "@prisma/client"; import { PrismaMariaDb } from "@prisma/adapter-mariadb"; import "dotenv/config"; const base = process.env.DATABASE_URL.replace("mysql://", "mariadb://"); const sep = base.includes("?") ? "&" : "?"; const connectionString = `${base}${sep}connection_limit=5&pool_timeout=10`; const adapter = new PrismaMariaDb(connectionString); const prisma = new PrismaClient({ adapter }); async function main() { const days = 14; const since = new Date(Date.now() - days * 24 * 60 * 60 * 1000); const sinceDate = new Date(since.getFullYear(), since.getMonth(), since.getDate()); const botUsers = await prisma.user.findMany({ where: { isBot: true }, select: { id: true, name: true, email: true, points: true }, }); const botConfigs = await prisma.botConfig.findMany({ select: { id: true, userId: true, primaryForums: true }, }); const configByUserId = new Map(botConfigs.map((c) => [c.userId, c])); const dailyStats = await prisma.botDailyStat.groupBy({ by: ["botId"], where: { date: { gte: sinceDate } }, _sum: { topicCreated: true, replySent: true, repliesReceived: true, likesReceived: true, humanInteractions: true, }, }); const statMap = new Map( dailyStats.map((s) => [ s.botId, { topicCreated: s._sum.topicCreated || 0, replySent: s._sum.replySent || 0, likesReceived: s._sum.likesReceived || 0, humanInteractions: s._sum.humanInteractions || 0, }, ]) ); const memCount = await prisma.botMemory.count(); console.log("--- Bot Stats Preview ---"); console.log("Total bots:", botUsers.length); console.log("Total configs:", botConfigs.length); console.log("BotDailyStat records:", dailyStats.length); console.log("BotMemory records:", memCount); console.log("Bots with stats:", statMap.size); // Top 5 by health score const top = botUsers .map((u) => { const cfg = configByUserId.get(u.id); const d = statMap.get(cfg?.id) || { topicCreated: 0, replySent: 0, likesReceived: 0, humanInteractions: 0 }; return { name: u.name, health: d.topicCreated * 3 + d.replySent + d.likesReceived * 2 + d.humanInteractions * 5, ...d, }; }) .sort((a, b) => b.health - a.health) .slice(0, 5); console.log("\n--- Top 5 ---"); for (const t of top) { console.log(`${t.name.padEnd(20)} health=${String(t.health).padStart(4)} 话题=${t.topicCreated} 回复=${t.replySent} 赞=${t.likesReceived} 真人=${t.humanInteractions}`); } // Trends const trendRaw = await prisma.botDailyStat.groupBy({ by: ["date"], where: { date: { gte: sinceDate } }, _sum: { topicCreated: true, replySent: true, likesReceived: true, humanInteractions: true }, orderBy: { date: "asc" }, }); console.log("\n--- Trend (近14天) ---"); for (const t of trendRaw) { console.log(`${t.date.toISOString().split("T")[0]} 话题=${t._sum.topicCreated} 回复=${t._sum.replySent} 赞=${t._sum.likesReceived}`); } await prisma.$disconnect(); } main().catch((e) => { console.error(e); process.exit(1); });