2026-05-25: 等级体系升级(20级)+论坛二级分类+会员空间
This commit is contained in:
@@ -0,0 +1,126 @@
|
||||
import { prisma } from "@/lib/prisma";
|
||||
import { getServerSession } from "next-auth";
|
||||
import { authOptions } from "@/lib/auth";
|
||||
import { NextResponse } from "next/server";
|
||||
import { rewardPoints } from "@/lib/points-reward";
|
||||
|
||||
export async function GET(req: Request, { params }: { params: { id: string } }) {
|
||||
const topicId = parseInt(params.id);
|
||||
const { searchParams } = new URL(req.url);
|
||||
const page = parseInt(searchParams.get("page") || "1", 10);
|
||||
const pageSize = parseInt(searchParams.get("pageSize") || "20", 10);
|
||||
|
||||
const [posts, totalCount] = await Promise.all([
|
||||
prisma.forumPost.findMany({
|
||||
where: { topicId },
|
||||
include: {
|
||||
user: { select: { id: true, name: true, email: true, avatarUrl: true, level: true, points: true } },
|
||||
},
|
||||
orderBy: { createdAt: "asc" },
|
||||
skip: (page - 1) * pageSize,
|
||||
take: pageSize,
|
||||
}),
|
||||
prisma.forumPost.count({ where: { topicId } }),
|
||||
]);
|
||||
|
||||
const formatted = posts.map((p) => ({
|
||||
id: p.id,
|
||||
content: p.content,
|
||||
isAnswer: p.isAnswer,
|
||||
createdAt: p.createdAt,
|
||||
updatedAt: p.updatedAt,
|
||||
user: {
|
||||
id: p.user.id,
|
||||
name: p.user.name || p.user.email.split("@")[0],
|
||||
avatarUrl: p.user.avatarUrl,
|
||||
level: p.user.level,
|
||||
points: p.user.points,
|
||||
},
|
||||
}));
|
||||
|
||||
return NextResponse.json({ posts: formatted, totalCount, page, pageSize });
|
||||
}
|
||||
|
||||
export async function POST(req: Request, { params }: { params: { id: string } }) {
|
||||
const session = await getServerSession(authOptions);
|
||||
if (!session?.user?.id) {
|
||||
return NextResponse.json({ error: "请先登录" }, { status: 401 });
|
||||
}
|
||||
|
||||
const topicId = parseInt(params.id);
|
||||
const userId = parseInt(session.user.id);
|
||||
const body = await req.json();
|
||||
const { content } = body;
|
||||
|
||||
if (!content || !content.trim()) {
|
||||
return NextResponse.json({ error: "回复内容不能为空" }, { status: 400 });
|
||||
}
|
||||
if (content.trim().length > 5000) {
|
||||
return NextResponse.json({ error: "回复不能超过5000个字符" }, { status: 400 });
|
||||
}
|
||||
|
||||
const topic = await prisma.forumTopic.findUnique({ where: { id: topicId } });
|
||||
if (!topic) {
|
||||
return NextResponse.json({ error: "话题不存在" }, { status: 404 });
|
||||
}
|
||||
if (topic.isLocked) {
|
||||
return NextResponse.json({ error: "话题已锁定" }, { status: 400 });
|
||||
}
|
||||
|
||||
const post = await prisma.$transaction(async (tx) => {
|
||||
const newPost = await tx.forumPost.create({
|
||||
data: {
|
||||
topicId,
|
||||
userId,
|
||||
content: content.trim(),
|
||||
},
|
||||
include: {
|
||||
user: { select: { id: true, name: true, email: true, avatarUrl: true, level: true, points: true } },
|
||||
},
|
||||
});
|
||||
|
||||
const now = new Date();
|
||||
await tx.forumTopic.update({
|
||||
where: { id: topicId },
|
||||
data: {
|
||||
replyCount: { increment: 1 },
|
||||
lastReplyAt: now,
|
||||
updatedAt: now,
|
||||
},
|
||||
});
|
||||
|
||||
if (topic.userId !== userId) {
|
||||
await tx.notification.create({
|
||||
data: {
|
||||
userId: topic.userId,
|
||||
type: "TOPIC_REPLY",
|
||||
title: `${session.user.name || "用户"} 回复了你的话题`,
|
||||
content: content.trim().slice(0, 100),
|
||||
link: `/community/topic/${topicId}`,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return newPost;
|
||||
});
|
||||
|
||||
await rewardPoints(userId, "forum_post", `回复话题`, "topic", topicId);
|
||||
|
||||
return NextResponse.json(
|
||||
{
|
||||
id: post.id,
|
||||
content: post.content,
|
||||
isAnswer: post.isAnswer,
|
||||
createdAt: post.createdAt,
|
||||
updatedAt: post.updatedAt,
|
||||
user: {
|
||||
id: post.user.id,
|
||||
name: post.user.name || post.user.email.split("@")[0],
|
||||
avatarUrl: post.user.avatarUrl,
|
||||
level: post.user.level,
|
||||
points: post.user.points,
|
||||
},
|
||||
},
|
||||
{ status: 201 }
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user