chenpei 4e89b57798 feat(upload): optimize upload UI and performance
- Expand batch upload list area and optimize preview image layout
- Improve upload speed tracking and display (server-side & client-side)
- Reduce network detection log noise
- Optimize Docker build process (caching, env validation)
- Add shadow environment deployment support
2026-01-28 15:07:50 +08:00

78 lines
2.0 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';
// 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 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 });
}
}