import { NextRequest, NextResponse } from 'next/server' import { getServerSession } from 'next-auth' import { Prisma } from '@prisma/client' import { authOptions } from '@/lib/auth' import { prisma } from '@/lib/prisma' import { buildMaterialManagementScopeWhere, getMaterialPermissionActor } from '@/lib/material-permissions' 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 }) } const actor = await getMaterialPermissionActor(session) if (!actor || (actor.role !== 'ADMIN' && !actor.isSuperAdmin)) { return NextResponse.json({ error: '需要管理员权限' }, { status: 403 }) } const { searchParams } = new URL(req.url) const limit = parseExportLimit(searchParams.get('limit')) const scopeWhere = await buildMaterialManagementScopeWhere(actor) const filters: Prisma.MaterialWhereInput[] = [{ deletedAt: null }] if (Object.keys(scopeWhere).length > 0) { filters.push(scopeWhere) } const where: Prisma.MaterialWhereInput = filters.length === 1 ? filters[0] : { AND: filters } 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 }) } }