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 const DEFAULT_REGION: RegionSelection = { province: '河南省', city: '郑州市', district: '金水区', }; export const FALLBACK_CITY_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, }); } /** 校验已选地区是否仍存在于数据源中 */ 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 }; }