import { NextResponse } from "next/server"; import { prisma } from "@/lib/prisma"; import { requireAdmin } from "@/lib/admin-auth"; import { toolImportSchema } from "@/lib/validation"; export async function POST(request: Request) { const authError = await requireAdmin(); if (authError) return authError; try { const body = await request.json(); const parsed = toolImportSchema.safeParse(body); if (!parsed.success) { return NextResponse.json({ error: parsed.error.issues[0].message }, { status: 400 }); } const { tools, categoryId } = parsed.data; const [existingPending, existingPublished] = await Promise.all([ prisma.pendingTool.findMany({ select: { name: true, websiteUrl: true } }), prisma.tool.findMany({ select: { name: true, websiteUrl: true } }), ]); const allExisting = [...existingPending, ...existingPublished]; const nameSet = new Set(allExisting.map((t) => t.name)); const urlSet = new Set(allExisting.map((t) => t.websiteUrl).filter(Boolean) as string[]); const existingSlugs = await prisma.pendingTool.findMany({ select: { slug: true } }); const slugSet = new Set(existingSlugs.map((s) => s.slug)); const toCreate: { name: string; slug: string; description: string | null; websiteUrl: string | null; logoUrl: string | null; categoryId: number | null; pricingModel: "free" | "freemium" | "paid" | "subscription"; pricingDetail: string | null; features: any; tags: any; sourceUrl: string }[] = []; const results: { name: string; status: string }[] = []; for (const tool of tools) { const name = tool.name || ""; if (!name || nameSet.has(name)) { results.push({ name: name || "未知", status: nameSet.has(name) ? "跳过-名称重复" : "跳过-名称为空" }); continue; } const websiteUrl = tool.websiteUrl || ""; if (websiteUrl && urlSet.has(websiteUrl)) { results.push({ name, status: "跳过-网址重复" }); continue; } let slug = name .toLowerCase() .replace(/[^a-z0-9\u4e00-\u9fff]+/g, "-") .replace(/^-|-$/g, ""); if (!slug || /^[\u4e00-\u9fff-]+$/.test(slug)) { slug = "tool-" + Date.now().toString(36) + Math.random().toString(36).slice(2, 6); } if (slugSet.has(slug)) { slug = slug + "-" + Math.floor(Math.random() * 10000); } slugSet.add(slug); toCreate.push({ name, slug, description: tool.description || null, websiteUrl: websiteUrl || null, logoUrl: tool.logoUrl || null, categoryId, pricingModel: (tool.pricingModel as "free" | "freemium" | "paid" | "subscription") || "freemium", pricingDetail: tool.pricingDetail || null, features: tool.features || null, tags: tool.tags || null, sourceUrl: "AI发现", }); nameSet.add(name); if (websiteUrl) urlSet.add(websiteUrl); results.push({ name, status: "已导入" }); } if (toCreate.length > 0) { await prisma.$transaction( toCreate.map((data) => prisma.pendingTool.create({ data }) ) ); } return NextResponse.json({ success: true, total: tools.length, imported: results.filter((r) => r.status === "已导入").length, skipped: results.filter((r) => r.status !== "已导入").length, details: results, }); } catch (error: unknown) { const err = error as { message?: string }; return NextResponse.json({ error: err.message }, { status: 500 }); } }