import { regionData } from 'element-china-area-data'; export type RegionTree = Record>; function buildRegionTree(): RegionTree { const tree: RegionTree = {}; for (const province of regionData) { const cities: Record = {}; for (const city of province.children ?? []) { cities[city.label] = (city.children ?? []).map((district) => district.label); } tree[province.label] = cities; } return tree; } export const REGION_TREE: RegionTree = buildRegionTree(); export const PROVINCES = Object.keys(REGION_TREE); export const REGION_ALL = '全市'; export function getCities(province: string): string[] { if (province === REGION_ALL) return []; return Object.keys(REGION_TREE[province] ?? {}); } export function getDistricts(province: string, city: string): string[] { if (province === REGION_ALL || city === REGION_ALL) return []; return REGION_TREE[province]?.[city] ?? []; } export function getProvincesForPicker(): string[] { return [...PROVINCES]; } export function getCitiesForPicker(province: string): string[] { if (province === REGION_ALL) return [REGION_ALL]; return [...getCities(province)]; } export function getDistrictsForPicker(province: string, city: string): string[] { if (province === REGION_ALL || city === REGION_ALL) return [REGION_ALL]; return [REGION_ALL, ...getDistricts(province, city)]; } export function formatRegion(province: string, city: string, district: string): string { if (!province) return ''; if (province === REGION_ALL) return REGION_ALL; if (city === REGION_ALL) return `${province} ${REGION_ALL}`; if (district === REGION_ALL) return `${province} ${city} ${REGION_ALL}`; if (!city || !district) return ''; return `${province} ${city} ${district}`; } export function formatRegionCity(province: string, city: string): string { if (!province) return ''; if (province === REGION_ALL) return REGION_ALL; if (city === REGION_ALL) return `${province} ${REGION_ALL}`; if (!city) return province; return `${province} ${city}`; } export function toCityLevelRegion(selection: RegionSelection): RegionSelection { const normalized = normalizeRegionSelection(selection); return { province: normalized.province, city: normalized.city, district: REGION_ALL, }; } export type RegionSelection = { province: string; city: string; district: string; }; export function normalizeRegionSelection(selection: RegionSelection): RegionSelection { if (selection.province === REGION_ALL) { return { province: REGION_ALL, city: REGION_ALL, district: REGION_ALL }; } const province = PROVINCES.includes(selection.province) ? selection.province : DEFAULT_REGION.province; if (selection.city === REGION_ALL) { return { province, city: REGION_ALL, district: REGION_ALL }; } const cities = getCities(province); const city = cities.includes(selection.city) ? selection.city : (cities[0] ?? DEFAULT_REGION.city); if (selection.district === REGION_ALL) { return { province, city, district: REGION_ALL }; } const districts = getDistricts(province, city); const district = districts.includes(selection.district) ? selection.district : (districts[0] ?? DEFAULT_REGION.district); return { province, city, district }; } export const DEFAULT_REGION: RegionSelection = { province: '河南省', city: '郑州市', district: REGION_ALL, }; export function regionFromGeo(province: string, city: string, district?: string): RegionSelection { const cityName = city.endsWith('市') ? city : `${city}市`; const provinceInTree = PROVINCES.includes(province) ? province : DEFAULT_REGION.province; const cities = getCities(provinceInTree); const matchedCity = cities.includes(cityName) ? cityName : cities.find((c) => c.replace(/市$/, '') === city.replace(/市$/, '')) ?? cityName; const districts = getDistricts(provinceInTree, matchedCity); const districtName = district && districts.includes(district) ? district : REGION_ALL; return normalizeRegionSelection({ province: provinceInTree, city: cities.includes(matchedCity) ? matchedCity : matchedCity, district: districtName, }); } function normalizeCityName(name: string) { return name.replace(/市$/, '').trim(); } type RegionFilterStore = { province?: string; cityName?: string; district?: string; }; /** 门店列表按省市区筛选(支持 REGION_ALL) */ export function matchesRegionFilter(store: RegionFilterStore, region: RegionSelection): boolean { const normalized = normalizeRegionSelection(region); if (normalized.province !== REGION_ALL) { if ((store.province ?? '') !== normalized.province) return false; } if (normalized.city !== REGION_ALL) { const storeCity = store.cityName ?? ''; const cityNorm = normalizeCityName(normalized.city); if ( storeCity !== normalized.city && normalizeCityName(storeCity) !== cityNorm ) { return false; } } if (normalized.district !== REGION_ALL) { if ((store.district ?? '') !== normalized.district) return false; } return true; } export function formatRegionLabel(region: RegionSelection): string { const normalized = normalizeRegionSelection(region); if (normalized.province === REGION_ALL) return REGION_ALL; if (normalized.city === REGION_ALL) return normalized.province; if (normalized.district === REGION_ALL) return `${normalized.city}`; return normalized.district; }