feat: 新增周末契约盲盒功能,首页重构为双模式入口
- 新增 BlindBoxIdea 数据模型及 migration - 新增盲盒 API (提交想法/查询/抽取) - 新增周末契约盲盒页面 (动效震动+彩带开奖) - 原首页功能拆分至 /panic 路由 - 首页重构为极速救场 + 周末契约双卡片入口
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { prisma } from "@/lib/prisma";
|
||||
|
||||
export async function POST(req: NextRequest) {
|
||||
try {
|
||||
const { roomId } = await req.json();
|
||||
|
||||
if (!roomId || typeof roomId !== "string") {
|
||||
return NextResponse.json({ error: "roomId 不能为空" }, { status: 400 });
|
||||
}
|
||||
|
||||
const pool = await prisma.blindBoxIdea.findMany({
|
||||
where: { roomId: roomId.trim(), status: "in_pool" },
|
||||
select: { id: true },
|
||||
});
|
||||
|
||||
if (pool.length === 0) {
|
||||
return NextResponse.json(
|
||||
{ error: "盒子是空的,先往里面塞点想法吧!" },
|
||||
{ status: 404 },
|
||||
);
|
||||
}
|
||||
|
||||
const picked = pool[Math.floor(Math.random() * pool.length)];
|
||||
|
||||
const idea = await prisma.blindBoxIdea.update({
|
||||
where: { id: picked.id },
|
||||
data: { status: "drawn" },
|
||||
});
|
||||
|
||||
return NextResponse.json({
|
||||
id: idea.id,
|
||||
content: idea.content,
|
||||
createdAt: idea.createdAt,
|
||||
});
|
||||
} catch {
|
||||
return NextResponse.json({ error: "抽取失败" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { prisma } from "@/lib/prisma";
|
||||
|
||||
export async function POST(req: NextRequest) {
|
||||
try {
|
||||
const { roomId, content } = await req.json();
|
||||
|
||||
if (!roomId || typeof roomId !== "string") {
|
||||
return NextResponse.json({ error: "roomId 不能为空" }, { status: 400 });
|
||||
}
|
||||
if (!content || typeof content !== "string" || content.trim().length === 0) {
|
||||
return NextResponse.json({ error: "内容不能为空" }, { status: 400 });
|
||||
}
|
||||
if (content.trim().length > 200) {
|
||||
return NextResponse.json({ error: "内容不能超过 200 字" }, { status: 400 });
|
||||
}
|
||||
|
||||
const idea = await prisma.blindBoxIdea.create({
|
||||
data: {
|
||||
roomId: roomId.trim(),
|
||||
content: content.trim(),
|
||||
},
|
||||
});
|
||||
|
||||
return NextResponse.json({ id: idea.id }, { status: 201 });
|
||||
} catch {
|
||||
return NextResponse.json({ error: "提交失败" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
export async function GET(req: NextRequest) {
|
||||
const roomId = req.nextUrl.searchParams.get("roomId");
|
||||
|
||||
if (!roomId) {
|
||||
return NextResponse.json({ error: "缺少 roomId" }, { status: 400 });
|
||||
}
|
||||
|
||||
const [poolCount, drawn] = await Promise.all([
|
||||
prisma.blindBoxIdea.count({
|
||||
where: { roomId, status: "in_pool" },
|
||||
}),
|
||||
prisma.blindBoxIdea.findMany({
|
||||
where: { roomId, status: "drawn" },
|
||||
orderBy: { createdAt: "desc" },
|
||||
select: { id: true, content: true, createdAt: true },
|
||||
}),
|
||||
]);
|
||||
|
||||
return NextResponse.json({ poolCount, drawn });
|
||||
}
|
||||
Reference in New Issue
Block a user