211 lines
5.7 KiB
TypeScript
211 lines
5.7 KiB
TypeScript
import { NextRequest, NextResponse } from 'next/server'
|
||
import { getServerSession } from 'next-auth'
|
||
import { authOptions } from '@/lib/auth'
|
||
import { prisma } from '@/lib/prisma'
|
||
|
||
// GET /api/materials/[id] - 获取单个素材详情
|
||
export async function GET(
|
||
request: NextRequest,
|
||
{ params }: { params: { id: string } }
|
||
) {
|
||
try {
|
||
const material = await prisma.material.findUnique({
|
||
where: { id: params.id },
|
||
select: {
|
||
id: true,
|
||
userId: true,
|
||
productModel: true,
|
||
brandName: true,
|
||
seriesName: true,
|
||
skuCode: true,
|
||
materialTexture: true,
|
||
categoryName: true,
|
||
sceneName: true,
|
||
platformName: true,
|
||
materialType: true,
|
||
renderer: true,
|
||
renderTime: true,
|
||
imageResolution: true,
|
||
colorMode: true,
|
||
authorName: true,
|
||
previewUrl: true,
|
||
zipFileName: true,
|
||
zipFileSize: true,
|
||
downloadCount: true,
|
||
likeCount: true,
|
||
displayImages: true,
|
||
createdAt: true,
|
||
user: {
|
||
select: {
|
||
id: true,
|
||
username: true,
|
||
}
|
||
}
|
||
}
|
||
})
|
||
|
||
if (!material) {
|
||
return NextResponse.json(
|
||
{ error: '素材不存在' },
|
||
{ status: 404 }
|
||
)
|
||
}
|
||
|
||
// 返回素材信息(转换BigInt为字符串)
|
||
return NextResponse.json({
|
||
id: material.id,
|
||
userId: material.userId,
|
||
productModel: material.productModel,
|
||
brandName: material.brandName,
|
||
seriesName: material.seriesName,
|
||
skuCode: material.skuCode,
|
||
materialTexture: material.materialTexture,
|
||
categoryName: material.categoryName,
|
||
sceneName: material.sceneName,
|
||
materialType: material.materialType,
|
||
renderer: material.renderer,
|
||
renderTime: material.renderTime,
|
||
imageResolution: material.imageResolution,
|
||
colorMode: material.colorMode,
|
||
authorName: material.authorName,
|
||
previewUrl: material.previewUrl,
|
||
zipFileName: material.zipFileName,
|
||
zipFileSize: material.zipFileSize.toString(),
|
||
downloadCount: material.downloadCount,
|
||
likeCount: material.likeCount,
|
||
displayImages: material.displayImages,
|
||
createdAt: material.createdAt,
|
||
user: {
|
||
username: material.user.username
|
||
}
|
||
})
|
||
} catch (error: any) {
|
||
console.error('[Materials] GET [id] error:', error)
|
||
return NextResponse.json(
|
||
{ error: '获取素材失败' },
|
||
{ status: 500 }
|
||
)
|
||
}
|
||
}
|
||
|
||
// PUT /api/materials/[id] - 更新素材信息
|
||
export async function PUT(
|
||
request: NextRequest,
|
||
{ params }: { params: { id: string } }
|
||
) {
|
||
try {
|
||
const session = await getServerSession(authOptions)
|
||
|
||
if (!session?.user) {
|
||
return NextResponse.json(
|
||
{ error: '请先登录' },
|
||
{ status: 401 }
|
||
)
|
||
}
|
||
|
||
const body = await request.json()
|
||
const {
|
||
productModel,
|
||
categoryName,
|
||
sceneName,
|
||
materialType,
|
||
renderer,
|
||
authorName,
|
||
brandName,
|
||
seriesName,
|
||
skuCode,
|
||
materialTexture,
|
||
renderTime,
|
||
imageResolution,
|
||
colorMode
|
||
} = body
|
||
|
||
// 验证必填字段
|
||
if (!productModel || !categoryName || !sceneName || !materialType || !renderer || !authorName) {
|
||
return NextResponse.json(
|
||
{ error: '缺少必填字段' },
|
||
{ status: 400 }
|
||
)
|
||
}
|
||
|
||
// 获取素材信息
|
||
const material = await prisma.material.findUnique({
|
||
where: { id: params.id }
|
||
})
|
||
|
||
if (!material) {
|
||
return NextResponse.json(
|
||
{ error: '素材不存在' },
|
||
{ status: 404 }
|
||
)
|
||
}
|
||
|
||
// 权限检查:只有素材上传者或管理员可以编辑
|
||
const userFromSession = session.user as any
|
||
if (material.userId !== userFromSession.id && userFromSession.role !== 'ADMIN') {
|
||
return NextResponse.json(
|
||
{ error: '您没有权限编辑此素材' },
|
||
{ status: 403 }
|
||
)
|
||
}
|
||
|
||
// 更新素材信息
|
||
const updateData: any = {
|
||
productModel,
|
||
categoryName,
|
||
sceneName,
|
||
materialType,
|
||
renderer,
|
||
authorName,
|
||
updatedAt: new Date()
|
||
}
|
||
|
||
const assignOptional = (key: string, value: any) => {
|
||
if (value !== undefined) {
|
||
updateData[key] = value === null || value === '' ? null : value
|
||
}
|
||
}
|
||
|
||
assignOptional('brandName', brandName)
|
||
assignOptional('seriesName', seriesName)
|
||
assignOptional('skuCode', skuCode)
|
||
assignOptional('materialTexture', materialTexture)
|
||
assignOptional('renderTime', renderTime)
|
||
assignOptional('imageResolution', imageResolution)
|
||
assignOptional('colorMode', colorMode)
|
||
|
||
const updatedMaterial = await prisma.material.update({
|
||
where: { id: params.id },
|
||
data: updateData
|
||
})
|
||
|
||
return NextResponse.json({
|
||
success: true,
|
||
message: '素材信息更新成功',
|
||
material: {
|
||
id: updatedMaterial.id,
|
||
productModel: updatedMaterial.productModel,
|
||
brandName: updatedMaterial.brandName,
|
||
seriesName: updatedMaterial.seriesName,
|
||
skuCode: updatedMaterial.skuCode,
|
||
materialTexture: updatedMaterial.materialTexture,
|
||
categoryName: updatedMaterial.categoryName,
|
||
sceneName: updatedMaterial.sceneName,
|
||
materialType: updatedMaterial.materialType,
|
||
renderer: updatedMaterial.renderer,
|
||
renderTime: updatedMaterial.renderTime,
|
||
imageResolution: updatedMaterial.imageResolution,
|
||
colorMode: updatedMaterial.colorMode,
|
||
authorName: updatedMaterial.authorName
|
||
}
|
||
})
|
||
} catch (error: any) {
|
||
console.error('[Materials] PUT [id] error:', error)
|
||
return NextResponse.json(
|
||
{ error: '更新素材失败' },
|
||
{ status: 500 }
|
||
)
|
||
}
|
||
}
|
||
|