import { NextRequest, NextResponse } from 'next/server' import { prisma } from '@/lib/prisma' import { storeFile } from '@/lib/fileStorage' import { push } from '@/lib/push' import { withCors } from '@/lib/middleware' interface WindowInfo { title: string path: string memory: number } const timeoutMap = new Map() async function handleScreenshotUpload(req: NextRequest) { try { const pathSegments = req.nextUrl.pathname.split('/') const hostnameIndex = pathSegments.indexOf('hosts') + 1 const hostname = pathSegments[hostnameIndex] if (!hostname) { return NextResponse.json({ error: '缺少主机名' }, { status: 400 }) } const formData = await req.formData() const files: File[] = [] const windowsInfo: WindowInfo[] = JSON.parse(formData.get('windows_info') as string || '[]') // Extract files from formData for (const [key, value] of formData.entries()) { if (key.startsWith('screenshot_') && value instanceof File) { files.push(value) } } if (files.length === 0) { return NextResponse.json({ error: '没有收到文件' }, { status: 400 }) } // Process screenshots const screenshots = await Promise.all(files.map(async (file, index) => { const ext = file.name ? file.name.split('.').pop() : 'webp' const filename = `${hostname}-${Date.now()}-${Math.round(Math.random() * 1E9)}.${ext}` const buffer = Buffer.from(await file.arrayBuffer()) const storedFile = await storeFile(buffer, filename, file.type, 'screenshot', hostname) return { fileId: storedFile.id, objectName: storedFile.objectName, filename: storedFile.filename, contentType: storedFile.contentType, fileSize: storedFile.size, monitorName: formData.get(`monitor_name_${index}`) as string || `Monitor ${index + 1}` } })) // Ensure host exists first await prisma.host.upsert({ where: { hostname }, update: {}, create: { hostname } }) // Create new record const newRecord = await prisma.record.create({ data: { hostname, timestamp: new Date(), windows: { create: windowsInfo }, screenshots: { create: screenshots } } }) // Handle host status and notifications const host = await prisma.host.findUnique({ where: { hostname }, select: { lastUpdate: true } }) const lastUpdate = host?.lastUpdate || new Date(0) if (lastUpdate.getTime() === new Date(0).getTime()) { push(`新设备 ${hostname} 上线`) } else if (lastUpdate.getTime() < new Date().getTime() - 1000 * 60) { push(`设备 ${hostname} 上线`) } // Clear existing timeout and set new one if (timeoutMap.has(hostname)) { clearTimeout(timeoutMap.get(hostname)!) } timeoutMap.set(hostname, setTimeout(() => { push(`设备 ${hostname} 离线`) timeoutMap.delete(hostname) }, 1000 * 60)) // Update host last update time await prisma.host.upsert({ where: { hostname }, update: { lastUpdate: new Date() }, create: { hostname, lastUpdate: new Date() } }) return NextResponse.json({ message: '上传成功', hostname, filesCount: files.length, windowsCount: windowsInfo.length }) } catch (error) { console.error('上传失败:', error) return NextResponse.json({ error: '上传失败' }, { status: 500 }) } } async function handleGetScreenshots(req: NextRequest) { try { const pathSegments = req.nextUrl.pathname.split('/') const hostnameIndex = pathSegments.indexOf('hosts') + 1 const hostname = pathSegments[hostnameIndex] if (!hostname) { return NextResponse.json({ error: '缺少主机名' }, { status: 400 }) } const { searchParams } = req.nextUrl const startTimeParam = searchParams.get('startTime') const endTimeParam = searchParams.get('endTime') let startTime: Date | undefined let endTime: Date | undefined if (startTimeParam) { const timestamp = isNaN(Number(startTimeParam)) ? new Date(startTimeParam) : new Date(Number(startTimeParam) * 1000) startTime = timestamp } if (endTimeParam) { const timestamp = isNaN(Number(endTimeParam)) ? new Date(endTimeParam) : new Date(Number(endTimeParam) * 1000) endTime = timestamp } // Build query conditions const whereClause: any = { hostname } if (startTime || endTime) { whereClause.timestamp = {} if (startTime) whereClause.timestamp.gte = startTime if (endTime) whereClause.timestamp.lte = endTime } // Get records const records = await prisma.record.findMany({ where: whereClause, include: { windows: true, screenshots: true }, orderBy: { timestamp: 'desc' } }) // Get host info const host = await prisma.host.findUnique({ where: { hostname }, select: { hostname: true, lastUpdate: true } }) if (!host) { return NextResponse.json({ error: '未找到主机记录' }, { status: 404 }) } return NextResponse.json({ hostname, lastUpdate: host.lastUpdate, records, total: records.length }) } catch (error) { console.error('获取记录失败:', error) return NextResponse.json({ error: '获取记录失败' }, { status: 500 }) } } export const POST = withCors(handleScreenshotUpload) export const GET = withCors(handleGetScreenshots)