61 lines
1.7 KiB
TypeScript
61 lines
1.7 KiB
TypeScript
import { NextResponse } from "next/server";
|
|
import { atomicUpdateRoom } from "@/lib/roomRepository";
|
|
import { notify } from "@/lib/roomEvents";
|
|
import { apiHandler, ApiError, requireUserId } from "@/lib/api";
|
|
|
|
export const POST = apiHandler(async (req, { params }) => {
|
|
const { id } = await params;
|
|
const { userId, restaurantId, action } = await req.json();
|
|
|
|
requireUserId(userId);
|
|
if (restaurantId == null || !action) {
|
|
throw new ApiError("restaurantId and action are required");
|
|
}
|
|
if (action !== "like" && action !== "pass") {
|
|
throw new ApiError("action must be 'like' or 'pass'");
|
|
}
|
|
|
|
const rid = String(restaurantId);
|
|
|
|
const updated = await atomicUpdateRoom(id, (data) => {
|
|
if (!data.users.includes(userId)) {
|
|
throw new ApiError("你不是该房间的成员", 403);
|
|
}
|
|
|
|
const restaurantIndex = data.restaurants.findIndex((r) => r.id === rid);
|
|
if (restaurantIndex < 0) {
|
|
throw new ApiError("restaurantId 不存在于该房间候选列表", 400);
|
|
}
|
|
const alreadySwiped =
|
|
restaurantIndex < (data.swipeCounts[userId] ?? 0);
|
|
|
|
if (alreadySwiped) return data;
|
|
|
|
if (action === "like") {
|
|
if (!data.likes[rid]) {
|
|
data.likes[rid] = [];
|
|
}
|
|
if (!data.likes[rid].includes(userId)) {
|
|
data.likes[rid].push(userId);
|
|
}
|
|
|
|
if (data.likes[rid].length === data.users.length) {
|
|
data.match = rid;
|
|
}
|
|
}
|
|
|
|
data.swipeCounts[userId] = (data.swipeCounts[userId] ?? 0) + 1;
|
|
|
|
return data;
|
|
});
|
|
|
|
if (!updated) throw new ApiError("房间不存在或已过期", 404);
|
|
|
|
notify(id);
|
|
|
|
return NextResponse.json({
|
|
match: updated.match,
|
|
likeCount: updated.likes[rid]?.length ?? 0,
|
|
});
|
|
});
|