diff --git a/src/app/api/blindbox/draw/route.ts b/src/app/api/blindbox/draw/route.ts index 062de1e..7adc1d7 100644 --- a/src/app/api/blindbox/draw/route.ts +++ b/src/app/api/blindbox/draw/route.ts @@ -11,25 +11,39 @@ export const POST = apiHandler(async (req) => { await requireMembership(roomId, userId); - const pool = await prisma.blindBoxIdea.findMany({ - where: { roomId, status: "in_pool" }, - select: { id: true }, + const userSelect = { id: true, username: true, avatar: true } as const; + + const idea = await prisma.$transaction(async (tx) => { + const pool = await tx.blindBoxIdea.findMany({ + where: { roomId, status: "in_pool" }, + select: { id: true }, + }); + + if (pool.length === 0) { + throw new ApiError("盒子是空的,先往里面塞点想法吧!", 404); + } + + const picked = pool[Math.floor(Math.random() * pool.length)]; + + const { count } = await tx.blindBoxIdea.updateMany({ + where: { id: picked.id, status: "in_pool" }, + data: { status: "drawn", drawnById: userId }, + }); + + if (count === 0) { + throw new ApiError("手慢了,再试一次", 409); + } + + return tx.blindBoxIdea.findUnique({ + where: { id: picked.id }, + include: { + user: { select: userSelect }, + drawnBy: { select: userSelect }, + }, + }); }); - if (pool.length === 0) { - throw new ApiError("盒子是空的,先往里面塞点想法吧!", 404); - } - - const picked = pool[Math.floor(Math.random() * pool.length)]; - - const idea = await prisma.blindBoxIdea.update({ - where: { id: picked.id }, - data: { status: "drawn", drawnById: userId }, - include: { - user: { select: { id: true, username: true, avatar: true } }, - drawnBy: { select: { id: true, username: true, avatar: true } }, - }, - }); + if (!idea) throw new ApiError("抽取失败", 500); return NextResponse.json({ id: idea.id,