From d83e5ec6c4c2b895dcfa298b166fb88b5d35b234 Mon Sep 17 00:00:00 2001 From: kurihada Date: Tue, 24 Feb 2026 18:29:38 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=88=9B=E5=BB=BA=E6=88=BF=E9=97=B4?= =?UTF-8?q?=E6=97=B6=E6=94=AF=E6=8C=81=E8=87=AA=E5=AE=9A=E4=B9=89=E7=AD=9B?= =?UTF-8?q?=E9=80=89=E6=9D=A1=E4=BB=B6=EF=BC=88=E8=B7=9D=E7=A6=BB/?= =?UTF-8?q?=E4=BA=BA=E5=9D=87/=E8=8F=9C=E7=B3=BB=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 替换硬编码搜索参数,用户可选择距离范围(1/3/5km)、 人均价格区间(50以下/50-100/100+)和菜系偏好(火锅、 日料、烧烤等),直接提升推荐质量。 --- src/app/api/room/create/route.ts | 46 +++++++++++++++-- src/app/page.tsx | 85 +++++++++++++++++++++++++++++++- 2 files changed, 126 insertions(+), 5 deletions(-) diff --git a/src/app/api/room/create/route.ts b/src/app/api/room/create/route.ts index 5bc5925..f3afa94 100644 --- a/src/app/api/room/create/route.ts +++ b/src/app/api/room/create/route.ts @@ -70,12 +70,42 @@ function mapPoiToRestaurant(poi: AmapPoiV5): Restaurant { }; } +function filterByPrice( + restaurants: Restaurant[], + priceRange: string, +): Restaurant[] { + if (priceRange === "any") return restaurants; + + return restaurants.filter((r) => { + if (r.price === "未知") return true; + const cost = parseInt(r.price.replace(/[¥¥]/g, ""), 10); + if (isNaN(cost)) return true; + + switch (priceRange) { + case "under50": + return cost < 50; + case "50to100": + return cost >= 50 && cost <= 100; + case "over100": + return cost > 100; + default: + return true; + } + }); +} + export async function POST(req: Request) { let restaurants: Restaurant[] = fallbackRestaurants; try { const body = await req.json(); - const { lat, lng } = body; + const { + lat, + lng, + radius = 3000, + priceRange = "any", + cuisine = "不限", + } = body; if (lat && lng) { const apiKey = process.env.AMAP_API_KEY; @@ -85,17 +115,25 @@ export async function POST(req: Request) { const url = new URL("https://restapi.amap.com/v5/place/around"); url.searchParams.set("key", apiKey); url.searchParams.set("location", `${lng},${lat}`); - url.searchParams.set("radius", "3000"); + url.searchParams.set("radius", String(radius)); url.searchParams.set("types", "050000"); url.searchParams.set("show_fields", "business,photos"); - url.searchParams.set("page_size", "15"); url.searchParams.set("sortrule", "weight"); + const needsPriceFilter = priceRange !== "any"; + url.searchParams.set("page_size", needsPriceFilter ? "25" : "15"); + + if (cuisine && cuisine !== "不限") { + url.searchParams.set("keywords", cuisine); + } + const amapRes = await fetch(url.toString()); const amapData = await amapRes.json(); if (amapData.status === "1" && amapData.pois?.length > 0) { - restaurants = amapData.pois.map(mapPoiToRestaurant); + let results: Restaurant[] = amapData.pois.map(mapPoiToRestaurant); + results = filterByPrice(results, priceRange); + restaurants = results.slice(0, 15); } } } diff --git a/src/app/page.tsx b/src/app/page.tsx index b05ad89..c0b57cb 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -17,6 +17,21 @@ interface LocationSuggestion { const SHANGHAI_COORDS = { lat: 31.2222, lng: 121.4764 }; +const DISTANCE_OPTIONS = [ + { label: "1km", value: 1000 }, + { label: "3km", value: 3000 }, + { label: "5km", value: 5000 }, +] as const; + +const PRICE_OPTIONS = [ + { label: "不限", value: "any" }, + { label: "¥50以下", value: "under50" }, + { label: "¥50-100", value: "50to100" }, + { label: "¥100+", value: "over100" }, +] as const; + +const CUISINE_OPTIONS = ["不限", "火锅", "日料", "烧烤", "西餐", "川菜", "粤菜", "东南亚"] as const; + function getLocation(): Promise<{ lat: number; lng: number }> { if (process.env.NODE_ENV === "development") { return Promise.resolve(SHANGHAI_COORDS); @@ -49,6 +64,9 @@ export default function LandingPage() { const [showSuggestions, setShowSuggestions] = useState(false); const [selectedLocation, setSelectedLocation] = useState(null); const [fetchingSuggestions, setFetchingSuggestions] = useState(false); + const [radius, setRadius] = useState(3000); + const [priceRange, setPriceRange] = useState("any"); + const [cuisine, setCuisine] = useState("不限"); const suggestRef = useRef(null); const debounceRef = useRef>(null); @@ -132,7 +150,7 @@ export default function LandingPage() { const res = await fetch("/api/room/create", { method: "POST", headers: { "Content-Type": "application/json" }, - body: JSON.stringify(coords), + body: JSON.stringify({ ...coords, radius, priceRange, cuisine }), }); if (!res.ok) { @@ -304,6 +322,71 @@ export default function LandingPage() { +
+
+ 距离 +
+ {DISTANCE_OPTIONS.map((opt) => ( + + ))} +
+
+ +
+ 人均 +
+ {PRICE_OPTIONS.map((opt) => ( + + ))} +
+
+ +
+ 菜系 +
+ {CUISINE_OPTIONS.map((opt) => ( + + ))} +
+
+
+