2026-05-25 17:12:11 +08:00

91 lines
2.5 KiB
TypeScript

import { NextRequest, NextResponse } from 'next/server'
import { getServerSession } from 'next-auth'
import { authOptions } from '@/lib/auth'
import { prisma } from '@/lib/prisma'
export const dynamic = 'force-dynamic'
const DEFAULT_EXPORT_LIMIT = 10000
const MAX_EXPORT_LIMIT = 10000
function parseExportLimit(value: string | null) {
const parsed = Number.parseInt(value || '', 10)
if (!Number.isFinite(parsed) || parsed <= 0) {
return DEFAULT_EXPORT_LIMIT
}
return Math.min(parsed, MAX_EXPORT_LIMIT)
}
export async function GET(req: NextRequest) {
try {
const session = await getServerSession(authOptions)
if (!session?.user) {
return NextResponse.json({ error: '未登录' }, { status: 401 })
}
if ((session.user as any).role !== 'ADMIN') {
return NextResponse.json({ error: '需要管理员权限' }, { status: 403 })
}
const { searchParams } = new URL(req.url)
const limit = parseExportLimit(searchParams.get('limit'))
const where = { deletedAt: null }
const [totalCount, rawMaterials] = await Promise.all([
prisma.material.count({ where }),
prisma.material.findMany({
where,
select: {
id: 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,
zipFileName: true,
zipFileSize: true,
downloadCount: true,
likeCount: true,
isPremium: true,
createdAt: true,
updatedAt: true,
user: {
select: {
username: true,
},
},
},
orderBy: { createdAt: 'desc' },
take: limit,
}),
])
const materials = rawMaterials.map((material) => ({
...material,
zipFileSize: material.zipFileSize.toString(),
createdAt: material.createdAt.toISOString(),
updatedAt: material.updatedAt.toISOString(),
}))
return NextResponse.json({
materials,
totalCount,
exportedCount: materials.length,
limit,
})
} catch (error) {
console.error('[AdminMaterialsExport] GET error:', error)
return NextResponse.json({ error: '导出素材数据失败' }, { status: 500 })
}
}