import { NextRequest, NextResponse } from "next/server"; import { getDb } from "@/lib/mongo"; import { ObjectId } from "mongodb"; import { z } from "zod"; import { OPC_SIGNAL_VALUES } from "@/lib/opc"; export async function GET(_: NextRequest, { params }: { params: { slug: string } }) { const db = await getDb(); const post = await db.collection("posts").findOneAndUpdate( { slug: params.slug }, { $inc: { views: 1 } }, { returnDocument: "after" } ); if (!post || !post.value) { return NextResponse.json({ error: "Not found" }, { status: 404 }); } return NextResponse.json({ ...post.value, author: post.value.author ?? "佚名", _id: (post.value._id as ObjectId)?.toString() }); } export async function PATCH(req: NextRequest, { params }: { params: { slug: string } }) { const body = await req.json().catch(() => ({})); const schema = z.object({ title: z.string().min(2).max(80).optional(), markdown: z.string().min(5).optional(), cover: z.string().url().nullable().optional(), tags: z.array(z.string().trim()).optional(), signal: z.enum(OPC_SIGNAL_VALUES).optional() }); const parsed = schema.safeParse(body); if (!parsed.success) { return NextResponse.json({ error: parsed.error.flatten() }, { status: 400 }); } const data = parsed.data; const set: Record = { updatedAt: new Date().toISOString() }; const unset: Record = {}; if (typeof data.title === "string") set.title = data.title; if (typeof data.markdown === "string") set.markdown = data.markdown; if (data.cover === null) { unset.cover = ""; } else if (typeof data.cover === "string") { set.cover = data.cover; } if (Array.isArray(data.tags)) set.tags = data.tags; if (typeof data.signal === "string") set.signal = data.signal; const update: Record = { $set: set }; if (Object.keys(unset).length > 0) update.$unset = unset; const db = await getDb(); const result = await db.collection("posts").updateOne({ slug: params.slug }, update); if (result.matchedCount === 0) { return NextResponse.json({ error: "Not found" }, { status: 404 }); } return NextResponse.json({ ok: true }); } export async function DELETE(_: NextRequest, { params }: { params: { slug: string } }) { const db = await getDb(); const result = await db.collection("posts").deleteOne({ slug: params.slug }); if (result.deletedCount === 0) { return NextResponse.json({ error: "Not found" }, { status: 404 }); } return NextResponse.json({ ok: true }); }