import { NextRequest, NextResponse } from 'next/server'; import { auth } from '@/app/(auth)/auth'; import { db } from '@/lib/db'; import { canvasProject } from '@/lib/db/schema'; import { syncCanvasNodesForProject } from '@/lib/db/queries'; import { and, desc, eq } from 'drizzle-orm'; function resolveWorkspaceType(input: unknown) { return input === "agent" || input === "video" ? input : "canvas"; } function getDefaultWorkspaceTitle(workspaceType: ReturnType) { return workspaceType === "video" ? "未命名视频画布" : "未命名画布"; } function parsePositiveInteger(input: string | null, fallback: number) { const value = Number(input); if (!Number.isFinite(value) || value <= 0) { return fallback; } return Math.floor(value); } // 获取画布列表 export async function GET(request: NextRequest) { try { const session = await auth(); if (!session?.user?.id) { return NextResponse.json({ success: false, error: '未登录' }, { status: 401 }); } const workspaceType = resolveWorkspaceType( request.nextUrl.searchParams.get("workspaceType") ); const limit = Math.min( Math.max( parsePositiveInteger(request.nextUrl.searchParams.get("limit"), 24), 1 ), 50 ); const page = Math.max( parsePositiveInteger(request.nextUrl.searchParams.get("page"), 1), 1 ); const offset = (page - 1) * limit; const projects = await db .select({ id: canvasProject.id, userId: canvasProject.userId, title: canvasProject.title, description: canvasProject.description, thumbnail: canvasProject.thumbnail, workspaceType: canvasProject.workspaceType, createdAt: canvasProject.createdAt, updatedAt: canvasProject.updatedAt, }) .from(canvasProject) .where( and( eq(canvasProject.userId, session.user.id), eq(canvasProject.workspaceType, workspaceType) ) ) .orderBy(desc(canvasProject.updatedAt)) .limit(limit + 1) .offset(offset); const hasMore = projects.length > limit; return NextResponse.json({ success: true, data: hasMore ? projects.slice(0, limit) : projects, pagination: { page, limit, hasMore, }, }); } catch (error) { console.error('获取画布列表失败:', error); return NextResponse.json({ success: false, error: '获取画布列表失败' }, { status: 500 }); } } // 创建画布 export async function POST(request: NextRequest) { try { const session = await auth(); if (!session?.user?.id) { return NextResponse.json({ success: false, error: '未登录' }, { status: 401 }); } const body = await request.json(); const { title, description, canvasData } = body; const workspaceType = resolveWorkspaceType(body?.workspaceType); const [insertedProject] = await db .insert(canvasProject) .values({ userId: session.user.id, title: title || getDefaultWorkspaceTitle(workspaceType), description, workspaceType, canvasData: canvasData || { nodes: [], edges: [], viewport: { x: 0, y: 0, zoom: 1 }, }, }) .returning(); let newProject = insertedProject; if (canvasData) { const syncedCanvasData = await syncCanvasNodesForProject({ projectId: insertedProject.id, userId: session.user.id, canvasData, }); const [updatedProject] = await db .update(canvasProject) .set({ canvasData: syncedCanvasData, updatedAt: new Date(), }) .where(eq(canvasProject.id, insertedProject.id)) .returning(); if (updatedProject) { newProject = updatedProject; } } return NextResponse.json({ success: true, data: newProject }); } catch (error) { console.error('创建画布失败:', error); return NextResponse.json({ success: false, error: '创建画布失败' }, { status: 500 }); } }