From b4aa765c17b9924d416f7de342392cfc2bb93371 Mon Sep 17 00:00:00 2001 From: William Tso Date: Wed, 26 Mar 2025 11:26:53 +0800 Subject: [PATCH] event api --- app/api/events/route.ts | 75 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-) diff --git a/app/api/events/route.ts b/app/api/events/route.ts index 6a43d03..b9086bf 100644 --- a/app/api/events/route.ts +++ b/app/api/events/route.ts @@ -1,5 +1,5 @@ import { NextRequest, NextResponse } from 'next/server'; -import type { ApiResponse, EventsQueryParams, EventType } from '@/lib/types'; +import type { ApiResponse, EventsQueryParams, EventType, Event } from '@/lib/types'; import { getEvents, getEventsSummary, @@ -7,6 +7,8 @@ import { getGeoAnalytics, getDeviceAnalytics } from '@/lib/analytics'; +import clickhouse from '@/lib/clickhouse'; +import { v4 as uuidv4 } from 'uuid'; // 获取事件列表 export async function GET(request: NextRequest) { @@ -46,6 +48,77 @@ export async function GET(request: NextRequest) { 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 }); } } \ No newline at end of file