小程序修改

This commit is contained in:
2026-07-12 19:44:36 +08:00
parent 3b4833b51a
commit e2dfb08de3
45 changed files with 2028 additions and 347 deletions
+166
View File
@@ -0,0 +1,166 @@
import { regionData } from 'element-china-area-data';
export type RegionTree = Record<string, Record<string, string[]>>;
function buildRegionTree(): RegionTree {
const tree: RegionTree = {};
for (const province of regionData) {
const cities: Record<string, string[]> = {};
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: '金水区',
};
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;
}