This commit is contained in:
root
2026-06-08 10:02:16 +08:00
parent 934b9a4a23
commit b65908e328
24 changed files with 1216 additions and 93 deletions

60
app/lib/city-slugs.ts Normal file
View File

@@ -0,0 +1,60 @@
import { cities, type City } from "@/app/data/cities";
const CITY_SLUG_BY_NAME: Record<string, string> = {
大理: "dali",
成都: "chengdu",
深圳: "shenzhen",
上海: "shanghai",
杭州: "hangzhou",
厦门: "xiamen",
北京: "beijing",
广州: "guangzhou",
重庆: "chongqing",
昆明: "kunming",
三亚: "sanya",
丽江: "lijiang",
西安: "xian",
南京: "nanjing",
长沙: "changsha",
青岛: "qingdao",
苏州: "suzhou",
珠海: "zhuhai",
};
function normalizeSlug(value: string): string {
return value
.trim()
.toLowerCase()
.replace(/['’]/g, "")
.replace(/[^a-z0-9]+/g, "-")
.replace(/^-+|-+$/g, "");
}
export function citySlug(city: Pick<City, "slug" | "name" | "nameEn" | "id">): string {
if (city.slug) return normalizeSlug(city.slug);
if (CITY_SLUG_BY_NAME[city.name]) return CITY_SLUG_BY_NAME[city.name];
if (city.nameEn) return normalizeSlug(city.nameEn);
return `city-${city.id}`;
}
export function cityVolunteerHref(city: Pick<City, "slug" | "name" | "nameEn" | "id">): string {
return `/city/${encodeURIComponent(citySlug(city))}/volunteer`;
}
export function findCityBySlug(slug: string): City | undefined {
const decoded = decodeURIComponent(slug).trim();
const normalized = normalizeSlug(decoded);
return cities.find((city) => {
const candidates = [
city.slug,
citySlug(city),
city.name,
city.nameEn,
CITY_SLUG_BY_NAME[city.name],
].filter(Boolean);
return candidates.some((candidate) => {
const text = String(candidate);
return text === decoded || normalizeSlug(text) === normalized;
});
});
}