import { NextRequest, NextResponse } from 'next/server'; import type { ApiResponse, EventsQueryParams, EventType, Event } from '@/lib/types'; import { getEvents, getEventsSummary, getTimeSeriesData, getGeoAnalytics, getDeviceAnalytics } from '@/lib/analytics'; import clickhouse from '@/lib/clickhouse'; import { v4 as uuidv4 } from 'uuid'; // 获取事件列表 export async function GET(request: NextRequest) { try { const searchParams = request.nextUrl.searchParams; const params: EventsQueryParams = { startTime: searchParams.get('startTime') || undefined, endTime: searchParams.get('endTime') || undefined, eventType: searchParams.get('eventType') as EventType || undefined, linkId: searchParams.get('linkId') || undefined, linkSlug: searchParams.get('linkSlug') || undefined, userId: searchParams.get('userId') || undefined, teamId: searchParams.get('teamId') || undefined, projectId: searchParams.get('projectId') || undefined, page: searchParams.has('page') ? parseInt(searchParams.get('page')!, 10) : 1, pageSize: searchParams.has('pageSize') ? parseInt(searchParams.get('pageSize')!, 10) : 20, sortBy: searchParams.get('sortBy') || undefined, sortOrder: (searchParams.get('sortOrder') as 'asc' | 'desc') || undefined }; const { events, total } = await getEvents(params); const response: ApiResponse = { success: true, data: events, meta: { total, page: params.page, pageSize: params.pageSize } }; return NextResponse.json(response); } catch (error) { const response: ApiResponse = { success: false, error: error instanceof Error ? error.message : 'Unknown error occurred' }; return NextResponse.json(response, { status: 500 }); } } // 写入事件数据 export async function POST(request: NextRequest) { try { // 解析请求体 const eventData = await request.json(); // 验证必填字段 const requiredFields = ['event_type', 'link_id', 'visitor_id']; for (const field of requiredFields) { if (!eventData[field]) { return NextResponse.json({ success: false, error: `Missing required field: ${field}` }, { status: 400 }); } } // 生成事件ID和时间戳(如果未提供) const event: Record = { ...eventData, event_id: eventData.event_id || uuidv4(), event_time: eventData.event_time || new Date().toISOString() }; // 处理JSON字段(ClickHouse要求JSON字段为字符串) const jsonFields = [ 'event_attributes', 'link_attributes', 'user_attributes', 'team_attributes', 'project_attributes', 'qr_code_attributes' ]; // 处理所有JSON对象字段 jsonFields.forEach(field => { if (event[field] && typeof event[field] === 'object') { event[field] = JSON.stringify(event[field]); } }); // 处理数组字段 if (event.link_tags && Array.isArray(event.link_tags)) { event.link_tags = JSON.stringify(event.link_tags); } // 使用ClickHouse客户端插入数据 await clickhouse.insert({ table: 'events', values: [event], format: 'JSONEachRow' }); const response: ApiResponse<{ event_id: string }> = { success: true, data: { event_id: event.event_id as string } }; return NextResponse.json(response, { status: 201 }); } catch (error) { console.error('Error inserting event:', error); const response: ApiResponse = { success: false, error: error instanceof Error ? error.message : 'Unknown error occurred' }; return NextResponse.json(response, { status: 500 }); } }