85 lines
2.4 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';
import { canAccessMaterialPrivacy, TASK_DETAIL_PRIVACY_SELECT } from '@/lib/task-detail-privacy';
// POST - 点赞/取消点赞
export async function POST(request: NextRequest) {
try {
const session = await getServerSession(authOptions);
if (!session?.user) {
return NextResponse.json({ error: '请先登录' }, { status: 401 });
}
const { materialId } = await request.json();
if (!materialId) {
return NextResponse.json({ error: '缺少素材ID' }, { status: 400 });
}
const userId = (session.user as any).id;
const material = await prisma.material.findFirst({
where: { id: materialId, deletedAt: null }, select: TASK_DETAIL_PRIVACY_SELECT,
});
if (!material || !(await canAccessMaterialPrivacy(material, userId))) {
return NextResponse.json({ error: '素材不存在或无权访问' }, { status: 403 });
}
// 检查是否已点赞
const existingLike = await prisma.materialLike.findFirst({
where: {
materialId,
userId,
},
});
if (existingLike) {
// R46修复:使用事务保护取消点赞操作,确保原子性
await prisma.$transaction(async (tx) => {
// 删除点赞记录
await tx.materialLike.delete({
where: { id: existingLike.id },
});
// 减少点赞计数
await tx.material.update({
where: { id: materialId },
data: { likeCount: { decrement: 1 } },
});
});
return NextResponse.json({
liked: false,
message: '已取消点赞',
});
} else {
// R46修复:使用事务保护点赞操作,确保原子性
await prisma.$transaction(async (tx) => {
// 创建点赞记录
await tx.materialLike.create({
data: {
materialId,
userId,
},
});
// 增加点赞计数
await tx.material.update({
where: { id: materialId },
data: { likeCount: { increment: 1 } },
});
});
return NextResponse.json({
liked: true,
message: '点赞成功',
});
}
} catch (error) {
console.error('Like error:', error);
return NextResponse.json({ error: '操作失败' }, { status: 500 });
}
}