181 lines
4.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.

import { NextRequest, NextResponse } from 'next/server'
import { getServerSession } from 'next-auth'
import { authOptions } from '@/lib/auth'
import { prisma } from '@/lib/prisma'
// Get all materials with search and filter support
export async function GET(req: NextRequest) {
try {
const session = await getServerSession(authOptions)
const { searchParams } = new URL(req.url)
const search = searchParams.get('search') || ''
const categoryName = searchParams.get('category') || ''
const sceneName = searchParams.get('scene') || ''
const materialType = searchParams.get('materialType') || ''
const platformName = searchParams.get('platform') || ''
const month = searchParams.get('month') || ''
const sortBy = searchParams.get('sortBy') || 'createdAt' // createdAt | downloadCount
const page = parseInt(searchParams.get('page') || '1')
const pageSize = parseInt(searchParams.get('pageSize') || '20')
// Build where clause
const where: any = {}
// Add search condition (search in SPU, shop, scene category, author)
if (search) {
where.OR = [
{ productModel: { contains: search, mode: 'insensitive' } }, // SPU
{ categoryName: { contains: search, mode: 'insensitive' } }, // 使用店铺
{ sceneName: { contains: search, mode: 'insensitive' } }, // 场景类别
{ authorName: { contains: search, mode: 'insensitive' } }, // 作者
]
}
// Add shop filter (使用店铺)
if (categoryName) {
where.categoryName = categoryName
}
// Add scene category filter (场景类别)
if (sceneName) {
where.sceneName = sceneName
}
// Add material type filter (素材类型)
if (materialType) {
where.materialType = materialType
}
// Add platform filter (平台分类)
if (platformName) {
where.platformName = platformName
}
// Add month filter (上传月份)
if (month) {
const [year, monthNum] = month.split('-')
const startDate = new Date(parseInt(year), parseInt(monthNum) - 1, 1)
const endDate = new Date(parseInt(year), parseInt(monthNum), 1)
where.createdAt = {
gte: startDate,
lt: endDate
}
}
// 计算总数和总页数
const totalCount = await prisma.material.count({ where })
const totalPages = Math.ceil(totalCount / pageSize)
// 构建排序规则
let orderBy: any = { createdAt: 'desc' }
if (sortBy === 'downloadCount') {
orderBy = { downloadCount: 'desc' }
}
// 获取分页数据
const materials = await prisma.material.findMany({
where,
include: {
user: {
select: {
username: true,
},
},
},
orderBy,
skip: (page - 1) * pageSize,
take: pageSize,
})
// 如果用户已登录,查询点赞状态
let userLikes: Set<string> = new Set()
if (session) {
const userId = (session.user as any).id
const likes = await prisma.materialLike.findMany({
where: {
userId,
materialId: {
in: materials.map(m => m.id)
}
},
select: {
materialId: true
}
})
userLikes = new Set(likes.map(l => l.materialId))
}
// 添加点赞状态到每个素材,并转换BigInt为字符串
const materialsWithLikeStatus = materials.map(material => ({
...material,
zipFileSize: material.zipFileSize.toString(),
isLiked: userLikes.has(material.id)
}))
return NextResponse.json({
materials: materialsWithLikeStatus,
totalPages,
totalCount,
currentPage: page,
})
} catch (error) {
console.error('Error fetching materials:', error)
return NextResponse.json(
{ error: '获取素材列表失败' },
{ status: 500 }
)
}
}
// Delete material (admin only)
export async function DELETE(req: NextRequest) {
try {
const session = await getServerSession(authOptions)
if (!session || (session.user as any).role !== 'ADMIN') {
return NextResponse.json(
{ error: '无权限' },
{ status: 403 }
)
}
const { searchParams } = new URL(req.url)
const id = searchParams.get('id')
if (!id) {
return NextResponse.json(
{ error: '缺少素材ID' },
{ status: 400 }
)
}
// Get material to delete files
const material = await prisma.material.findUnique({
where: { id },
})
if (!material) {
return NextResponse.json(
{ error: '素材不存在' },
{ status: 404 }
)
}
// Delete from database
await prisma.material.delete({
where: { id },
})
// TODO: Delete files from S3 and local storage
return NextResponse.json({ message: '删除成功' })
} catch (error) {
console.error('Error deleting material:', error)
return NextResponse.json(
{ error: '删除失败' },
{ status: 500 }
)
}
}