mirror of
https://github.com/joeseesun/wechat-radar.git
synced 2026-09-10 04:38:30 +09:00
Initial open source release
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import { todayStr } from '@/lib/range';
|
||||
import { db } from '@/lib/db';
|
||||
import { listMessagesForDate, getSyncState, listAllSyncedDates } from '@/lib/messages-store';
|
||||
import { wxSessions } from '@/lib/wx';
|
||||
|
||||
export const dynamic = 'force-dynamic';
|
||||
|
||||
interface DailyHistoryRow {
|
||||
date: string;
|
||||
total: number;
|
||||
}
|
||||
|
||||
export async function GET(
|
||||
req: NextRequest,
|
||||
ctx: { params: Promise<{ id: string }> },
|
||||
) {
|
||||
const { id } = await ctx.params;
|
||||
const chatroomId = decodeURIComponent(id);
|
||||
const url = new URL(req.url);
|
||||
const date = url.searchParams.get('date') ?? todayStr();
|
||||
const limit = Math.min(Number(url.searchParams.get('limit') ?? 1000), 5000);
|
||||
|
||||
// 拉群名(从 wx sessions)
|
||||
let chatName = chatroomId;
|
||||
try {
|
||||
const sessions = await wxSessions(500);
|
||||
const found = sessions.find((s) => s.username === chatroomId);
|
||||
if (found) chatName = found.chat;
|
||||
} catch {}
|
||||
|
||||
// 当日消息
|
||||
const messages = listMessagesForDate(chatroomId, date, limit);
|
||||
|
||||
// 当日聚合统计
|
||||
const total = messages.length;
|
||||
const senderMap = new Map<string, number>();
|
||||
const typeMap = new Map<string, number>();
|
||||
const hours = new Array(24).fill(0) as number[];
|
||||
for (const m of messages) {
|
||||
senderMap.set(m.sender, (senderMap.get(m.sender) ?? 0) + 1);
|
||||
typeMap.set(m.type, (typeMap.get(m.type) ?? 0) + 1);
|
||||
if (m.timestamp) {
|
||||
const h = new Date(m.timestamp * 1000).getHours();
|
||||
if (h >= 0 && h < 24) hours[h]++;
|
||||
}
|
||||
}
|
||||
const stats = {
|
||||
chat: chatName,
|
||||
total,
|
||||
by_hour: hours.map((count, hour) => ({ hour, count })),
|
||||
by_type: Array.from(typeMap.entries())
|
||||
.map(([type, count]) => ({ type, count }))
|
||||
.sort((a, b) => b.count - a.count),
|
||||
top_senders: Array.from(senderMap.entries())
|
||||
.map(([sender, count]) => ({ sender, count }))
|
||||
.sort((a, b) => b.count - a.count)
|
||||
.slice(0, 20),
|
||||
};
|
||||
|
||||
// 历史日柱图
|
||||
const dailyHistory = db()
|
||||
.prepare(
|
||||
'SELECT date, total FROM daily_stats WHERE chatroom_id = ? ORDER BY date ASC',
|
||||
)
|
||||
.all(chatroomId) as DailyHistoryRow[];
|
||||
|
||||
// 同步状态
|
||||
const syncState = getSyncState(chatroomId);
|
||||
const syncedDates = listAllSyncedDates(chatroomId);
|
||||
|
||||
return NextResponse.json({
|
||||
ok: true,
|
||||
chatroom_id: chatroomId,
|
||||
date,
|
||||
stats,
|
||||
recent: messages,
|
||||
daily_history: dailyHistory,
|
||||
sync_state: syncState ?? null,
|
||||
synced_dates: syncedDates,
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user