import { NextRequest, NextResponse } from 'next/server' import { getServerSession } from 'next-auth' import { authOptions } from '@/lib/auth' import { prisma } from '@/lib/prisma' import { isCurrentSuperAdmin } from '@/lib/admin-permissions' // 获取所有场景类别 export async function GET(req: NextRequest) { try { const { searchParams } = new URL(req.url) const categoryName = searchParams.get('category') const scenes = await prisma.scene.findMany({ orderBy: { name: 'asc', }, }) // 优化:使用SQL聚合查询,避免N+1问题 const whereClause = categoryName ? prisma.$queryRaw>` SELECT "sceneName" as "sceneName", COUNT(*)::bigint as count FROM "materials" WHERE "sceneName" IS NOT NULL AND "sceneName" != '' AND "categoryName" = ${categoryName} GROUP BY "sceneName" ` : prisma.$queryRaw>` SELECT "sceneName" as "sceneName", COUNT(*)::bigint as count FROM "materials" WHERE "sceneName" IS NOT NULL AND "sceneName" != '' GROUP BY "sceneName" ` const counts = await whereClause const countMap = new Map() counts.forEach(item => { countMap.set(item.sceneName, Number(item.count)) }) const scenesWithCount = scenes.map(scene => ({ ...scene, count: countMap.get(scene.name) || 0, })) return NextResponse.json(scenesWithCount) } catch (error) { console.error('Error fetching scenes:', error) return NextResponse.json( { error: '获取场景类别列表失败' }, { status: 500 } ) } } // 添加新场景类别 export async function POST(req: NextRequest) { try { const session = await getServerSession(authOptions) if (!session) { return NextResponse.json( { error: '请先登录' }, { status: 401 } ) } if (!(await isCurrentSuperAdmin(session))) { return NextResponse.json( { error: '仅最高权限账号可新增场景分类' }, { status: 403 } ) } const { name } = await req.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 } ) } } // 更新场景类别名称 export async function PATCH(req: NextRequest) { try { const session = await getServerSession(authOptions) if (!session || !(await isCurrentSuperAdmin(session))) { return NextResponse.json( { error: '仅最高权限账号可修改场景分类' }, { status: 403 } ) } const { id, name, options } = await req.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 } ) } // 处理options:如果是数组,转换为JSON字符串;如果是字符串,直接使用 let optionsValue: string | null = null if (options !== undefined && options !== null) { if (Array.isArray(options)) { optionsValue = JSON.stringify(options) } else if (typeof options === 'string') { // 支持每行一个选项的格式 const trimmed = options.trim() if (trimmed && !trimmed.startsWith('[') && !trimmed.startsWith('{')) { const lines = trimmed.split('\n').map(line => line.trim()).filter(Boolean) optionsValue = lines.length > 0 ? JSON.stringify(lines) : null } else { optionsValue = trimmed || null } } } // 更新场景类别名称和选项 const scene = await prisma.scene.update({ where: { id }, data: { name: name.trim(), options: optionsValue, }, }) // 同步更新所有使用该场景的素材 await prisma.material.updateMany({ where: { sceneName: oldScene.name }, data: { sceneName: name.trim() }, }) return NextResponse.json(scene) } catch (error) { console.error('Error updating scene:', error) return NextResponse.json( { error: '更新失败' }, { status: 500 } ) } } // 删除场景类别 export async function DELETE(req: NextRequest) { try { const session = await getServerSession(authOptions) if (!session || !(await isCurrentSuperAdmin(session))) { return NextResponse.json( { error: '仅最高权限账号可删除场景分类' }, { status: 403 } ) } const { searchParams } = new URL(req.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 } ) } }