import areaData from 'china-area-data'; export interface CascadeOption { value: string; label: string; children?: CascadeOption[]; } /** * 将 china-area-data 原始数据转换为 antd Cascader 所需的 options 格式 * * 原始数据格式: { '86': { '110000': '北京' }, '110000': { '110100': '市辖区' }, ... } * 目标格式: [{ value: '110000', label: '北京', children: [...] }] */ function buildTree(parentCode: string): CascadeOption[] { const nodes = areaData[parentCode]; if (!nodes) return []; return Object.entries(nodes).map(([code, name]) => { const node: CascadeOption = { value: code, label: name as string, }; const children = buildTree(code); if (children.length > 0) { node.children = children; } return node; }); } /** 省市区三级联动数据 */ export const regionOptions: CascadeOption[] = buildTree('86'); // ============================================================ // 省市选项(精确到市,直辖市仅市名) // ============================================================ /** 直辖市代码 */ const MUNICIPALITY_CODES = ['110000', '120000', '310000', '500000']; /** 省市选项 */ export interface ProvinceCityOption { value: string; label: string; } /** * 获取"省-市"格式的选项列表 * - 普通省份:格式为 "省名-市名",如 "广东省-深圳市" * - 直辖市:直接使用市名,如 "北京市" */ export function getProvinceCityOptions(): ProvinceCityOption[] { const options: ProvinceCityOption[] = []; const provinces = areaData['86']; if (!provinces) return options; for (const [provinceCode, provinceName] of Object.entries(provinces)) { const pname = provinceName as string; if (MUNICIPALITY_CODES.includes(provinceCode)) { options.push({ value: pname, label: pname }); } else { const cities = areaData[provinceCode]; if (cities) { for (const [, cityName] of Object.entries(cities)) { const fullName = `${pname}-${cityName}`; options.push({ value: fullName, label: fullName }); } } } } return options; } /** Cascader 节点 */ export interface CascaderNode { value: string; label: string; children?: CascaderNode[]; } /** * 获取省市两级 Cascader 选项 * - 普通省份:省 → 市,选中值 ["省名", "市名"] * - 直辖市:直接叶子节点,选中值 ["市名"] */ export function getProvinceCityCascaderOptions(): CascaderNode[] { const nodes: CascaderNode[] = []; const provinces = areaData['86']; if (!provinces) return nodes; for (const [provinceCode, provinceName] of Object.entries(provinces)) { const pname = provinceName as string; if (MUNICIPALITY_CODES.includes(provinceCode)) { // 直辖市:直接作为叶子节点 nodes.push({ value: pname, label: pname }); } else { const cities = areaData[provinceCode]; if (cities) { const cityNodes: CascaderNode[] = Object.entries(cities).map(([, cname]) => ({ value: cname as string, label: cname as string, })); nodes.push({ value: pname, label: pname, children: cityNodes }); } } } return nodes; } /** * 将 Cascader 选中的路径数组转为存储用的区域字符串 * ["广东省", "深圳市"] → "广东省-深圳市" * ["北京市"] → "北京市" */ export function formatCascaderArea(path: string[]): string { if (!path || path.length === 0) return ''; return path.join('-'); } /** * 将存储的区域字符串反向解析为 Cascader 路径数组 * "广东省-深圳市" → ["广东省", "深圳市"] * "北京市" → ["北京市"] */ export function parseAreaToCascaderPath(area: string): string[] { if (!area) return []; return area.split('-'); } // ============================================================ // 城市级别选项(仅市名,加"全国") // ============================================================ /** 城市 Select 选项 */ export interface CityOption { value: string; label: string; } /** * 获取仅城市名的选项列表,第一项为"全国" * 用于 Banner 弹窗中"所属区域"下拉选择 * - 直辖市:直接取市名(如"北京市") * - 普通省份:取市名(如"深圳市") */ export function getCityOnlyOptions(): CityOption[] { const options: CityOption[] = [{ value: '全国', label: '全国' }]; const provinces = areaData['86']; if (!provinces) return options; for (const [provinceCode, provinceName] of Object.entries(provinces)) { if (MUNICIPALITY_CODES.includes(provinceCode)) { options.push({ value: provinceName as string, label: provinceName as string }); } else { const cities = areaData[provinceCode]; if (cities) { for (const [, cityName] of Object.entries(cities)) { options.push({ value: cityName as string, label: cityName as string }); } } } } return options; } /** * 根据城市名反查 Cascader 路径数组 * "深圳市" → ["广东省", "深圳市"] * "北京市" → ["北京市"] * "全国" → ["全国"] */ export function cityNameToCascaderPath(cityName: string): string[] { if (!cityName || cityName === '全国') return ['全国']; const provinces = areaData['86']; if (!provinces) return [cityName]; for (const [provinceCode, provinceName] of Object.entries(provinces)) { const pname = provinceName as string; if (MUNICIPALITY_CODES.includes(provinceCode)) { if (pname === cityName) return [pname]; } else { const cities = areaData[provinceCode]; if (cities) { for (const [, cname] of Object.entries(cities)) { if ((cname as string) === cityName) { return [pname, cname as string]; } } } } } // 兜底:找不到省份隶属,直接用市名 return [cityName]; }