import dbConnect from "../../lib/dbConnect"; import Match from "../../models/Match"; import { NextResponse } from "next/server"; import { setCORSHeaders, handleError } from "../../lib/apiUtils"; import moment from "moment-timezone/moment-timezone-utils"; import { withAuth } from "../../middleware/authMiddleware"; // 假设你的服务器时区是 'Asia/Shanghai' const timezone = "Asia/Shanghai"; export async function GET(request) { await dbConnect(); try { const { searchParams } = new URL(request.url); const action = searchParams.get("action"); const type = searchParams.get("type"); console.log("type", type); const current = parseInt(searchParams.get("current")) || 1; const pageSize = parseInt(searchParams.get("pageSize")) || 10; let response; const now = moment.tz(timezone); const currentDate = now.toDate(); const currentTimeString = now.format("HH:mm"); // 创建2小时前的时间点 const twoHoursAgo = moment(now).subtract(2, "hours"); const twoHoursAgoDate = twoHoursAgo.format("YYYY-MM-DD"); // 使用日期字符串 const twoHoursAgoTime = twoHoursAgo.format("HH:mm"); switch (action) { case "getMatches": const searchQuery = {}; // 添加类型过滤 if (type) { searchQuery.type = type; } for (const [key, value] of searchParams.entries()) { if (["action", "current", "pageSize", "type"].includes(key)) continue; switch (key) { case "homeTeamScore": case "awayTeamScore": searchQuery[key] = parseInt(value); break; case "date": searchQuery[key] = new Date(value); break; case "homeTeam": case "awayTeam": try { const teamQuery = JSON.parse(value); Object.entries(teamQuery).forEach( ([nestedKey, nestedValue]) => { searchQuery[`${key}.${nestedKey}`] = { $regex: nestedValue, $options: "i", }; } ); } catch (e) { searchQuery[`${key}.name`] = { $regex: value, $options: "i" }; } break; // 根据比赛类型处理特定字段 case "spread": case "totalPoints": if (type === "basketball") { searchQuery[`basketball.${key}`] = value; } break; case "firstTeamToScore": if (type === "football") { searchQuery[`football.result.${key}`] = value; } break; default: searchQuery[key] = { $regex: value, $options: "i" }; } } console.log("Search Query:", searchQuery); // await Promise.all([ // // 更新所有开始超过2小时的比赛为已结束 // Match.updateMany( // { // $or: [ // // 早于今天的比赛 // { date: { $lt: twoHoursAgoDate } }, // // 今天的比赛且开始时间在2小时前 // { // date: twoHoursAgoDate, // time: { $lte: twoHoursAgoTime }, // }, // ], // status: { $in: ["未开始", "进行中"] }, // ...(type ? { type } : {}), // }, // { $set: { status: "已结束" } } // ), // // 更新其他应该进行中的比赛 // Match.updateMany( // { // date: { $lte: currentDate }, // time: { $lte: currentTimeString }, // status: "未开始", // // 排除已经过去2小时的比赛(因为上面的查询会处理) // $or: [ // { date: { $gt: twoHoursAgoDate } }, // { // date: twoHoursAgoDate, // time: { $gt: twoHoursAgoTime }, // }, // ], // ...(type ? { type } : {}), // }, // { $set: { status: "进行中" } } // ), // ]); const skip = (current - 1) * pageSize; const totalMatches = await Match.countDocuments(searchQuery); const matchesData = await Match.find(searchQuery) .sort({ date: 1, time: 1 }) .skip(skip) .limit(pageSize); response = NextResponse.json({ success: true, total: totalMatches, data: matchesData, }); break; case "getMatchDays": const typeFilter = type ? { type } : {}; const currentDay = moment().tz(timezone).startOf("day"); const futureMatches = await Match.find({ date: { $gte: currentDay.toDate() }, status: { $in: ["未开始", "进行中"] }, ...typeFilter, }).sort("date"); const formattedDays = formatMatches(futureMatches); response = NextResponse.json({ success: true, data: formattedDays }); break; case "getMatchesByDate": const dateParam = searchParams.get("date"); if (!dateParam) { return NextResponse.json( { success: false, error: "Date parameter is required" }, { status: 400 } ); } const startDate = moment .tz(dateParam, timezone) .startOf("day") .toDate(); const endDate = moment.tz(dateParam, timezone).endOf("day").toDate(); const dateTypeFilter = type ? { type } : {}; const matches = await Match.find({ date: { $gte: startDate, $lte: endDate }, status: { $in: ["未开始", "进行中"] }, ...dateTypeFilter, }).sort({ time: 1 }); response = NextResponse.json({ success: true, data: matches }); break; default: return NextResponse.json( { success: false, error: "Invalid action" }, { status: 400 } ); } return setCORSHeaders(response); } catch (error) { return handleError(error); } } export const POST = withAuth(async (request) => { await dbConnect(); try { const matchData = await request.json(); // console.log(11, matchData); // 验证比赛类型 if ( !matchData.type || !["football", "basketball"].includes(matchData.type) ) { return NextResponse.json( { success: false, error: "Invalid match type" }, { status: 400 } ); } // 根据类型验证必要字段 if (matchData.type === "basketball") { if (!matchData.basketball?.spread || !matchData.basketball?.totalPoints) { return NextResponse.json( { success: false, error: "Missing required basketball fields" }, { status: 400 } ); } } const match = new Match(matchData); await match.save(); const response = NextResponse.json( { success: true, data: match }, { status: 201 } ); return setCORSHeaders(response); } catch (error) { console.error("插入比赛数据时出错:", error); return NextResponse.json( { success: false, error: "创建比赛失败" }, { status: 500 } ); } }); export const PUT = withAuth(async (request) => { await dbConnect(); try { const { id, type, ...updateData } = await request.json(); if (!id) { return NextResponse.json( { success: false, error: "缺少比赛ID" }, { status: 400 } ); } // 根据类型验证更新数据 if (type === "basketball") { const basketballFields = updateData.basketball; if ( basketballFields && (!basketballFields.spread || !basketballFields.totalPoints) ) { return NextResponse.json( { success: false, error: "Missing required basketball fields" }, { status: 400 } ); } } const updatedMatch = await Match.findByIdAndUpdate(id, updateData, { new: true, runValidators: true, }); if (!updatedMatch) { return NextResponse.json( { success: false, error: "未找到指定比赛" }, { status: 404 } ); } const response = NextResponse.json( { success: true, data: updatedMatch }, { status: 200 } ); return setCORSHeaders(response); } catch (error) { console.error("更新比赛数据时出错:", error); return NextResponse.json( { success: false, error: "更新比赛失败" }, { status: 500 } ); } }); export const DELETE = withAuth(async (request) => { console.log("DELETE request received"); await dbConnect(); try { const url = new URL(request.url); const id = url.searchParams.get("id"); const ids = url.searchParams.get("ids"); console.log("Received delete request for id:", id, "or ids:", ids); if (!id && !ids) { return NextResponse.json( { success: false, error: "缺少比赛ID" }, { status: 400 } ); } let deletedMatches; let message; if (id) { // 单个删除 deletedMatches = await Match.findByIdAndDelete(id); message = deletedMatches ? "比赛已成功删除" : "未找到指定比赛"; } else { // 批量删除 const idArray = ids.split(","); deletedMatches = await Match.deleteMany({ _id: { $in: idArray } }); message = `成功删除 ${deletedMatches.deletedCount} 场比赛`; } if ( !deletedMatches || (Array.isArray(deletedMatches) && deletedMatches.length === 0) ) { return NextResponse.json( { success: false, error: "未找到指定比赛" }, { status: 404 } ); } const response = NextResponse.json( { success: true, message: message }, { status: 200 } ); // Set CORS headers return setCORSHeaders(response); } catch (error) { console.error("删除比赛数据时出错:", error); return NextResponse.json( { success: false, error: "删除比赛失败" }, { status: 500 } ); } }); export async function OPTIONS() { const response = new NextResponse(null, { status: 204 }); return setCORSHeaders(response); } function formatMatches(matches) { // 使用 Set 去除重复的日期 const uniqueDates = Array.from( new Set( matches.map((match) => new Date(match.date).toISOString().split("T")[0]) ) ); // 格式化唯一日期 return uniqueDates.map((dateString, index) => { const date = new Date(dateString); const year = date.getFullYear(); const month = String(date.getMonth() + 1).padStart(2, "0"); const day = String(date.getDate()).padStart(2, "0"); const weekdays = [ "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六", ]; // 获取星期几 const weekday = weekdays[date.getDay()]; return { id: index + 1, title: weekday, date: `${year}-${month}-${day}`, }; }); }