import { NextRequest, NextResponse } from 'next/server'; import { getServerSession } from 'next-auth'; import { authOptions } from '@/lib/auth'; import { prisma } from '@/lib/prisma'; // GET - 获取所有场景类别 export async function GET(request: NextRequest) { try { const session = await getServerSession(authOptions); if (!session?.user) { return NextResponse.json({ error: '未登录' }, { status: 401 }); } const { searchParams } = new URL(request.url); const category = searchParams.get('category'); const scenes = await prisma.scene.findMany({ orderBy: { name: 'asc' }, }); // 统计每个场景的素材数量(只统计未删除的素材) const scenesWithCount = await Promise.all( scenes.map(async (scene) => { const where: any = { sceneName: scene.name }; if (category) { where.categoryName = category; } let count: number; try { where.deletedAt = null; count = await prisma.material.count({ where } as any); } catch (e: any) { // 兼容旧版本数据库(没有deletedAt字段) if (e?.meta?.column?.includes('deletedAt')) { delete where.deletedAt; count = await prisma.material.count({ where }); } else { throw e; } } return { ...scene, count, }; }) ); return NextResponse.json(scenesWithCount); } catch (error) { console.error('Error fetching scenes:', error); return NextResponse.json( { error: '获取场景类别列表失败' }, { status: 500 } ); } } // POST - 创建新的场景类别 export async function POST(request: NextRequest) { try { const session = await getServerSession(authOptions); if (!session) { return NextResponse.json({ error: '请先登录' }, { status: 401 }); } const { name } = await request.json(); if (!name || !name.trim()) { return NextResponse.json( { error: '场景类别名称不能为空' }, { status: 400 } ); } // 检查是否已存在 const existing = await prisma.scene.findUnique({ where: { name: name.trim() }, }); if (existing) { return NextResponse.json( { error: '该场景类别已存在' }, { status: 400 } ); } const scene = await prisma.scene.create({ data: { name: name.trim() }, }); return NextResponse.json(scene, { status: 201 }); } catch (error) { console.error('Error creating scene:', error); return NextResponse.json( { error: '创建场景类别失败' }, { status: 500 } ); } } // PATCH - 更新场景类别 export async function PATCH(request: NextRequest) { try { const session = await getServerSession(authOptions); if (!session?.user || !(session.user as any).id) { return NextResponse.json( { error: '未登录' }, { status: 401 } ); } const userRole = (session.user as any).role; if (userRole !== 'ADMIN') { return NextResponse.json({ error: '权限不足' }, { status: 403 }); } const { id, name } = await request.json(); if (!id || !name || !name.trim()) { return NextResponse.json({ error: '参数错误' }, { status: 400 }); } // 检查新名称是否已被其他分类使用 const existing = await prisma.scene.findFirst({ where: { name: name.trim(), NOT: { id }, }, }); if (existing) { return NextResponse.json( { error: '该场景类别已存在' }, { status: 400 } ); } // 获取旧名称 const oldScene = await prisma.scene.findUnique({ where: { id }, }); if (!oldScene) { return NextResponse.json({ error: '分类不存在' }, { status: 404 }); } // 更新分类 const updated = await prisma.scene.update({ where: { id }, data: { name: name.trim() }, }); // 更新所有使用该分类的素材 await prisma.material.updateMany({ where: { sceneName: oldScene.name }, data: { sceneName: name.trim() }, }); return NextResponse.json(updated); } catch (error) { console.error('Error updating scene:', error); return NextResponse.json({ error: '更新失败' }, { status: 500 }); } } // DELETE - 删除场景类别 export async function DELETE(request: NextRequest) { try { const session = await getServerSession(authOptions); if (!session?.user || !(session.user as any).id) { return NextResponse.json( { error: '未登录' }, { status: 401 } ); } const userRole = (session.user as any).role; if (userRole !== 'ADMIN') { return NextResponse.json({ error: '权限不足' }, { status: 403 }); } const { searchParams } = new URL(request.url); const id = searchParams.get('id'); if (!id) { return NextResponse.json({ error: '缺少ID参数' }, { status: 400 }); } await prisma.scene.delete({ where: { id }, }); return NextResponse.json({ success: true }); } catch (error) { console.error('Error deleting scene:', error); return NextResponse.json({ error: '删除失败' }, { status: 500 }); } }