diff --git a/app/api/activities/route.ts b/app/api/activities/route.ts index e9e4fce..d62a426 100644 --- a/app/api/activities/route.ts +++ b/app/api/activities/route.ts @@ -2,8 +2,8 @@ import { NextRequest, NextResponse } from 'next/server'; import { getEvents } from '@/lib/analytics'; import { ApiResponse } from '@/lib/types'; -// 扩展Event类型以包含所需字段 -interface EventWithFullPath extends Record { +// Extended Event type with required fields +interface EventWithFullPath { event_id?: string; event_time?: string; event_type?: string; @@ -11,7 +11,18 @@ interface EventWithFullPath extends Record { ip_address?: string; req_full_path?: string; referrer?: string; - // 其他可能的字段 + event_attributes?: string | Record; + link_tags?: string | string[]; + link_id?: string; + link_slug?: string; + link_original_url?: string; + link_label?: string; + device_type?: string; + browser?: string; + os?: string; + country?: string; + city?: string; + [key: string]: unknown; } export async function GET(request: NextRequest) { @@ -89,7 +100,7 @@ export async function GET(request: NextRequest) { // If utm_campaign is not found or URL parsing fails, use regex as fallback const campaignMatch = url.match(/[?&]utm_campaign=([^&]+)/i); if (campaignMatch && campaignMatch[1]) return campaignMatch[1]; - } catch (_) { + } catch { // If URL parsing fails, try regex directly const campaignMatch = url.match(/[?&]utm_campaign=([^&]+)/i); if (campaignMatch && campaignMatch[1]) return campaignMatch[1]; @@ -128,16 +139,12 @@ export async function GET(request: NextRequest) { csvContent += `${time},${activity},${campaign},${clientId},${originPath}\n`; }); - // Generate filename based on available parameters - const filename = slug - ? `activities-${slug}.csv` - : `activities-${new Date().toISOString().slice(0,10)}.csv`; + // No need to generate filename since we're not using Content-Disposition header - // Return CSV response + // Return CSV response without forcing download return new NextResponse(csvContent, { headers: { - 'Content-Type': 'text/csv', - 'Content-Disposition': `attachment; filename="${filename}"` + 'Content-Type': 'text/plain' } }); }