import { NextResponse } from "next/server"; import { createSupabaseRouteClient } from "@/lib/supabase/server"; import type { MediaAsset } from "@/types/media"; import { extname } from "path"; export const dynamic = "force-dynamic"; const MEDIA_BUCKET = process.env.NEXT_PUBLIC_SUPABASE_MEDIA_BUCKET ?? "media"; const resolveAssetType = (mime: string): "image" | "video" | "audio" | "file" => { if (mime.startsWith("image/")) return "image"; if (mime.startsWith("video/")) return "video"; if (mime.startsWith("audio/")) return "audio"; return "file"; }; export async function POST(request: Request) { const supabase = await createSupabaseRouteClient(); const { data: { session }, } = await supabase.auth.getSession(); if (!session) { return NextResponse.json({ error: "未登录" }, { status: 401 }); } const formData = await request.formData(); const file = formData.get("file"); const workspaceId = String(formData.get("workspaceId") ?? ""); const documentId = String(formData.get("documentId") ?? ""); if (!(file instanceof File) || !workspaceId || !documentId) { return NextResponse.json({ error: "缺少必要参数" }, { status: 400 }); } try { const arrayBuffer = await file.arrayBuffer(); const buffer = Buffer.from(arrayBuffer); const extension = extname(file.name || "").replace(/\s+/g, ""); const uniqueId = typeof crypto.randomUUID === "function" ? crypto.randomUUID() : Math.random().toString(36).slice(2); const path = `${workspaceId}/${Date.now()}-${uniqueId}${extension}`; const assetType = resolveAssetType(file.type || ""); const { error: uploadError } = await supabase.storage.from(MEDIA_BUCKET).upload(path, buffer, { contentType: file.type, upsert: false, }); if (uploadError) { return NextResponse.json({ error: uploadError.message }, { status: 500 }); } const { data: { publicUrl }, } = supabase.storage.from(MEDIA_BUCKET).getPublicUrl(path); const { data: asset, error } = await supabase .from("media_assets") .insert({ workspace_id: workspaceId, document_id: documentId, file_url: publicUrl, thumbnail_url: publicUrl, asset_type: assetType, file_name: file.name, file_size: file.size, mime_type: file.type, created_by: session.user.id, }) .select("*") .single(); if (error) { return NextResponse.json({ error: error.message }, { status: 500 }); } return NextResponse.json({ asset: asset as MediaAsset }); } catch (error) { console.error(error); return NextResponse.json({ error: "上传失败" }, { status: 500 }); } }