import { NextRequest, NextResponse } from 'next/server' import { getServerSession } from 'next-auth' import { authOptions } from '@/lib/auth' import { prisma } from '@/lib/prisma' import { uploadToS3, deleteFromS3 } from '@/lib/s3' import { processImage, getProcessedFileName } from '@/lib/image-processor' export async function PUT(req: NextRequest) { try { const session = await getServerSession(authOptions) if (!session || (session.user as any).role !== 'ADMIN') { return NextResponse.json( { error: '无权限' }, { status: 403 } ) } const formData = await req.formData() const id = formData.get('id') as string const productModel = formData.get('productModel') as string const categoryName = formData.get('categoryName') as string const sceneName = formData.get('sceneName') as string const renderer = (formData.get('renderer') as string) || 'CR' const authorName = formData.get('authorName') as string const previewImage = formData.get('previewImage') as File | null // Validation if (!id || !productModel || !categoryName || !sceneName || !renderer || !authorName) { return NextResponse.json( { error: '所有字段都是必填的' }, { status: 400 } ) } // Get existing material const existingMaterial = await prisma.material.findUnique({ where: { id }, }) if (!existingMaterial) { return NextResponse.json( { error: '素材不存在' }, { status: 404 } ) } let previewUrl = existingMaterial.previewUrl // If new preview image is uploaded if (previewImage && previewImage.size > 0) { // Delete old preview image from S3 try { await deleteFromS3(existingMaterial.previewUrl) } catch (error) { console.error('Error deleting old preview:', error) } // 处理预览图:压缩到300KB以内,转换为webP,缩放到600px const originalBuffer = Buffer.from(await previewImage.arrayBuffer()) const processedBuffer = await processImage(originalBuffer, { maxSizeKB: 300, maxWidth: 600, format: 'webp', }) // Upload processed preview image to S3 const processedFileName = getProcessedFileName(previewImage.name) const previewFileName = `preview-${Date.now()}-${processedFileName}` previewUrl = await uploadToS3( processedBuffer, previewFileName, 'image/webp' ) } // Update material record const material = await prisma.material.update({ where: { id }, data: { previewUrl, productModel, categoryName, sceneName, renderer, authorName, }, include: { user: { select: { username: true, }, }, }, }) // 转换BigInt为字符串 const materialData = { ...material, zipFileSize: material.zipFileSize.toString() } return NextResponse.json( { message: '更新成功', material: materialData }, { status: 200 } ) } catch (error) { console.error('Update error:', error) return NextResponse.json( { error: '更新失败,请稍后再试' }, { status: 500 } ) } }