177 lines
4.8 KiB
TypeScript
177 lines
4.8 KiB
TypeScript
/**
|
||
* 用户浏览历史API
|
||
*
|
||
* GET: 获取用户浏览历史列表
|
||
* POST: 记录浏览行为
|
||
* DELETE: 清除历史记录(支持单条或全部)
|
||
*
|
||
* @created 2025-12-13
|
||
*/
|
||
|
||
import { NextRequest, NextResponse } from 'next/server'
|
||
import { getServerSession } from 'next-auth'
|
||
import { authOptions } from '@/lib/auth'
|
||
import { prisma } from '@/lib/prisma'
|
||
import { toMaterialAssetProxyUrl } from '@/lib/url-rewrite'
|
||
|
||
/**
|
||
* GET /api/user/history
|
||
* 获取用户浏览历史列表
|
||
*/
|
||
export async function GET(request: NextRequest) {
|
||
try {
|
||
const session = await getServerSession(authOptions)
|
||
if (!session?.user?.id) {
|
||
return NextResponse.json({ error: '未登录' }, { status: 401 })
|
||
}
|
||
|
||
const { searchParams } = new URL(request.url)
|
||
const page = parseInt(searchParams.get('page') || '1', 10)
|
||
const pageSize = parseInt(searchParams.get('pageSize') || '20', 10)
|
||
const skip = (page - 1) * pageSize
|
||
|
||
const [history, total] = await Promise.all([
|
||
prisma.browseHistory.findMany({
|
||
where: { userId: session.user.id },
|
||
orderBy: { viewedAt: 'desc' },
|
||
skip,
|
||
take: pageSize,
|
||
include: {
|
||
material: {
|
||
select: {
|
||
id: true,
|
||
productModel: true,
|
||
previewUrl: true,
|
||
materialType: true,
|
||
materialKind: true,
|
||
downloadCount: true,
|
||
likeCount: true,
|
||
deletedAt: true,
|
||
},
|
||
},
|
||
},
|
||
}),
|
||
prisma.browseHistory.count({
|
||
where: { userId: session.user.id },
|
||
}),
|
||
])
|
||
|
||
// 过滤掉已删除的素材
|
||
const validHistory = history.filter((item) => !item.material.deletedAt)
|
||
|
||
return NextResponse.json({
|
||
history: validHistory.map((item) => ({
|
||
id: item.id,
|
||
viewedAt: item.viewedAt.toISOString(),
|
||
material: {
|
||
id: item.material.id,
|
||
title: item.material.productModel,
|
||
thumbnailUrl: toMaterialAssetProxyUrl(item.material.previewUrl),
|
||
materialType: item.material.materialType,
|
||
materialKind: item.material.materialKind,
|
||
viewCount: item.material.downloadCount,
|
||
},
|
||
})),
|
||
pagination: {
|
||
page,
|
||
pageSize,
|
||
total,
|
||
totalPages: Math.ceil(total / pageSize),
|
||
},
|
||
})
|
||
} catch (error) {
|
||
console.error('获取浏览历史失败:', error)
|
||
return NextResponse.json({ error: '获取浏览历史失败' }, { status: 500 })
|
||
}
|
||
}
|
||
|
||
/**
|
||
* POST /api/user/history
|
||
* 记录浏览行为
|
||
*/
|
||
export async function POST(request: NextRequest) {
|
||
try {
|
||
const session = await getServerSession(authOptions)
|
||
if (!session?.user?.id) {
|
||
return NextResponse.json({ error: '未登录' }, { status: 401 })
|
||
}
|
||
|
||
const body = await request.json()
|
||
const { materialId } = body
|
||
|
||
if (!materialId) {
|
||
return NextResponse.json({ error: '缺少素材ID' }, { status: 400 })
|
||
}
|
||
|
||
// 检查素材是否存在
|
||
const material = await prisma.material.findUnique({
|
||
where: { id: materialId },
|
||
select: { id: true, deletedAt: true },
|
||
})
|
||
|
||
if (!material || material.deletedAt) {
|
||
return NextResponse.json({ error: '素材不存在' }, { status: 404 })
|
||
}
|
||
|
||
// 使用upsert更新或创建浏览记录
|
||
const history = await prisma.browseHistory.upsert({
|
||
where: {
|
||
materialId_userId: {
|
||
materialId,
|
||
userId: session.user.id,
|
||
},
|
||
},
|
||
update: {
|
||
viewedAt: new Date(),
|
||
},
|
||
create: {
|
||
materialId,
|
||
userId: session.user.id,
|
||
},
|
||
})
|
||
|
||
return NextResponse.json({ success: true, id: history.id })
|
||
} catch (error) {
|
||
console.error('记录浏览历史失败:', error)
|
||
return NextResponse.json({ error: '记录浏览历史失败' }, { status: 500 })
|
||
}
|
||
}
|
||
|
||
/**
|
||
* DELETE /api/user/history
|
||
* 清除历史记录
|
||
* - 不带参数:清除所有历史
|
||
* - 带materialId参数:清除单条记录
|
||
*/
|
||
export async function DELETE(request: NextRequest) {
|
||
try {
|
||
const session = await getServerSession(authOptions)
|
||
if (!session?.user?.id) {
|
||
return NextResponse.json({ error: '未登录' }, { status: 401 })
|
||
}
|
||
|
||
const { searchParams } = new URL(request.url)
|
||
const materialId = searchParams.get('materialId')
|
||
|
||
if (materialId) {
|
||
// 删除单条记录
|
||
await prisma.browseHistory.deleteMany({
|
||
where: {
|
||
userId: session.user.id,
|
||
materialId,
|
||
},
|
||
})
|
||
} else {
|
||
// 清除所有历史
|
||
await prisma.browseHistory.deleteMany({
|
||
where: { userId: session.user.id },
|
||
})
|
||
}
|
||
|
||
return NextResponse.json({ success: true })
|
||
} catch (error) {
|
||
console.error('清除浏览历史失败:', error)
|
||
return NextResponse.json({ error: '清除浏览历史失败' }, { status: 500 })
|
||
}
|
||
}
|