WuYongJie d1c6efc79d
Some checks failed
CI Check / check (push) Has been cancelled
feat: NAS 部署与 Harbor 推送流程
2025-12-03 14:39:06 +08:00

103 lines
2.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 用户素材列表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'
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
return {
...material,
zipFileSize: safeZipFileSize,
displayImages: parseDisplayImages(material.displayImages as unknown as string | null),
}
})
return NextResponse.json(formatted)
} catch (error) {
console.error('[UserMaterials] GET error:', error)
return NextResponse.json(
{ error: '获取素材列表失败' },
{ status: 500 }
)
}
}