From 199772a95d0e32f40a1034422fb872c8a3247962 Mon Sep 17 00:00:00 2001 From: gaoziman <2942894660@qq.com> Date: Fri, 19 Dec 2025 15:57:12 +0800 Subject: [PATCH] =?UTF-8?q?feat(api):=20=E6=B7=BB=E5=8A=A0=E5=AF=B9?= =?UTF-8?q?=E8=AF=9D=E6=95=B0=E6=8D=AE=E5=AF=BC=E5=87=BA=E5=92=8C=E6=B8=85?= =?UTF-8?q?=E9=99=A4=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 GET /api/conversations/export 导出所有对话数据 - 新增 GET /api/conversations/all 获取对话统计信息 - 新增 DELETE /api/conversations/all 清除所有对话和消息 --- src/app/api/conversations/all/route.ts | 52 ++++++++++++++++ src/app/api/conversations/export/route.ts | 73 +++++++++++++++++++++++ 2 files changed, 125 insertions(+) create mode 100644 src/app/api/conversations/all/route.ts create mode 100644 src/app/api/conversations/export/route.ts diff --git a/src/app/api/conversations/all/route.ts b/src/app/api/conversations/all/route.ts new file mode 100644 index 0000000..95542a1 --- /dev/null +++ b/src/app/api/conversations/all/route.ts @@ -0,0 +1,52 @@ +import { NextResponse } from 'next/server'; +import { db } from '@/drizzle/db'; +import { conversations, messages } from '@/drizzle/schema'; +import { sql } from 'drizzle-orm'; + +// GET /api/conversations/all - 获取统计信息 +export async function GET() { + try { + // 获取对话数量 + const conversationCount = await db + .select({ count: sql`count(*)` }) + .from(conversations); + + // 获取消息数量 + const messageCount = await db + .select({ count: sql`count(*)` }) + .from(messages); + + return NextResponse.json({ + conversationCount: Number(conversationCount[0]?.count || 0), + messageCount: Number(messageCount[0]?.count || 0), + }); + } catch (error) { + console.error('Failed to get stats:', error); + return NextResponse.json( + { error: 'Failed to get stats' }, + { status: 500 } + ); + } +} + +// DELETE /api/conversations/all - 清除所有对话和消息 +export async function DELETE() { + try { + // 先删除所有消息 + await db.delete(messages); + + // 再删除所有对话 + await db.delete(conversations); + + return NextResponse.json({ + success: true, + message: 'All conversations and messages have been deleted', + }); + } catch (error) { + console.error('Failed to delete all conversations:', error); + return NextResponse.json( + { error: 'Failed to delete all conversations' }, + { status: 500 } + ); + } +} diff --git a/src/app/api/conversations/export/route.ts b/src/app/api/conversations/export/route.ts new file mode 100644 index 0000000..baceddd --- /dev/null +++ b/src/app/api/conversations/export/route.ts @@ -0,0 +1,73 @@ +import { NextResponse } from 'next/server'; +import { db } from '@/drizzle/db'; +import { conversations, messages } from '@/drizzle/schema'; +import { desc, eq } from 'drizzle-orm'; + +// GET /api/conversations/export - 导出所有对话数据 +export async function GET() { + try { + // 获取所有对话 + const allConversations = await db.query.conversations.findMany({ + orderBy: [desc(conversations.createdAt)], + }); + + // 获取所有消息 + const allMessages = await db.query.messages.findMany({ + orderBy: [desc(messages.createdAt)], + }); + + // 按对话组织数据 + const exportData = { + exportedAt: new Date().toISOString(), + version: '1.0', + totalConversations: allConversations.length, + totalMessages: allMessages.length, + conversations: allConversations.map((conv) => { + // 获取该对话的所有消息 + const convMessages = allMessages + .filter((msg) => msg.conversationId === conv.conversationId) + .sort((a, b) => new Date(a.createdAt!).getTime() - new Date(b.createdAt!).getTime()) + .map((msg) => ({ + messageId: msg.messageId, + role: msg.role, + content: msg.content, + thinkingContent: msg.thinkingContent, + toolCalls: msg.toolCalls, + toolResults: msg.toolResults, + inputTokens: msg.inputTokens, + outputTokens: msg.outputTokens, + status: msg.status, + feedback: msg.feedback, + createdAt: msg.createdAt, + })); + + return { + conversationId: conv.conversationId, + title: conv.title, + summary: conv.summary, + model: conv.model, + tools: conv.tools, + enableThinking: conv.enableThinking, + systemPrompt: conv.systemPrompt, + temperature: conv.temperature, + messageCount: conv.messageCount, + totalTokens: conv.totalTokens, + isArchived: conv.isArchived, + isPinned: conv.isPinned, + createdAt: conv.createdAt, + updatedAt: conv.updatedAt, + lastMessageAt: conv.lastMessageAt, + messages: convMessages, + }; + }), + }; + + return NextResponse.json(exportData); + } catch (error) { + console.error('Failed to export conversations:', error); + return NextResponse.json( + { error: 'Failed to export conversations' }, + { status: 500 } + ); + } +}