/** * 用户素材列表API * * GET: 获取当前登录用户上传的所有素材 * * @created 2025-11-25 * @api */ import { NextRequest, NextResponse } from 'next/server' import { getServerSession } from 'next-auth' import { authOptions } from '@/lib/auth' import { prisma } from '@/lib/prisma' import { rewriteMaterialStorageUrlsForClient } from '@/lib/url-rewrite' function parseDisplayImages(value: string | null): string[] { if (!value) return [] try { const parsed = JSON.parse(value) if (Array.isArray(parsed)) { return parsed.filter((item): item is string => typeof item === 'string' && item.trim().length > 0) } } catch (error) { console.warn('[UserMaterials] Failed to parse displayImages JSON:', error) } return value ? [value] : [] } export async function GET(req: NextRequest) { try { const session = await getServerSession(authOptions) if (!session?.user?.id) { return NextResponse.json( { error: '未登录' }, { status: 401 } ) } const currentUserId = session.user.id const materials = await (prisma as any).material.findMany({ where: { // 个人中心「我的素材」: // 1)我上传的:createdByUserId = 当前用户(新字段); // 2)当前由我负责的:ownerType = 'USER' 且 ownerId = 当前用户; // 3)兜底兼容:userId = 当前用户(历史/遗留字段,且新上传目前也会写入)。 OR: [ { createdByUserId: currentUserId }, { ownerType: 'USER', ownerId: currentUserId }, { userId: currentUserId }, ], deletedAt: null, } as any, select: { id: true, userId: true, productModel: true, previewUrl: true, displayImages: true, materialType: true, materialKind: true, categoryName: true, sceneName: true, renderer: true, downloadCount: true, likeCount: true, createdAt: true, isPremium: true, videoCoverUrl: true, videoPreview540Url: true, videoPreviewClipUrl: true, videoProcessingStatus: true, videoDuration: true, zipFileName: true, zipFileSize: true, }, orderBy: { createdAt: 'desc' }, }) const formatted = materials.map((material: any) => { // 统一处理 BigInt 等前端无法直接消费的类型 const safeZipFileSize = typeof material.zipFileSize === 'bigint' ? material.zipFileSize.toString() : material.zipFileSize ?? null const base = { ...material, zipFileSize: safeZipFileSize, displayImages: parseDisplayImages(material.displayImages as unknown as string | null), } // 统一修正存储相关 URL,避免 localhost/127.0.0.1 导致客户端 404 return rewriteMaterialStorageUrlsForClient(base) }) return NextResponse.json(formatted) } catch (error) { console.error('[UserMaterials] GET error:', error) return NextResponse.json( { error: '获取素材列表失败' }, { status: 500 } ) } }