15 changed files with 342 additions and 2042 deletions
File diff suppressed because it is too large
@ -1,138 +0,0 @@ |
|||
[ |
|||
{ |
|||
"name": "北京市", |
|||
"id": "110000" |
|||
}, |
|||
{ |
|||
"name": "天津市", |
|||
"id": "120000" |
|||
}, |
|||
{ |
|||
"name": "河北省", |
|||
"id": "130000" |
|||
}, |
|||
{ |
|||
"name": "山西省", |
|||
"id": "140000" |
|||
}, |
|||
{ |
|||
"name": "内蒙古自治区", |
|||
"id": "150000" |
|||
}, |
|||
{ |
|||
"name": "辽宁省", |
|||
"id": "210000" |
|||
}, |
|||
{ |
|||
"name": "吉林省", |
|||
"id": "220000" |
|||
}, |
|||
{ |
|||
"name": "黑龙江省", |
|||
"id": "230000" |
|||
}, |
|||
{ |
|||
"name": "上海市", |
|||
"id": "310000" |
|||
}, |
|||
{ |
|||
"name": "江苏省", |
|||
"id": "320000" |
|||
}, |
|||
{ |
|||
"name": "浙江省", |
|||
"id": "330000" |
|||
}, |
|||
{ |
|||
"name": "安徽省", |
|||
"id": "340000" |
|||
}, |
|||
{ |
|||
"name": "福建省", |
|||
"id": "350000" |
|||
}, |
|||
{ |
|||
"name": "江西省", |
|||
"id": "360000" |
|||
}, |
|||
{ |
|||
"name": "山东省", |
|||
"id": "370000" |
|||
}, |
|||
{ |
|||
"name": "河南省", |
|||
"id": "410000" |
|||
}, |
|||
{ |
|||
"name": "湖北省", |
|||
"id": "420000" |
|||
}, |
|||
{ |
|||
"name": "湖南省", |
|||
"id": "430000" |
|||
}, |
|||
{ |
|||
"name": "广东省", |
|||
"id": "440000" |
|||
}, |
|||
{ |
|||
"name": "广西壮族自治区", |
|||
"id": "450000" |
|||
}, |
|||
{ |
|||
"name": "海南省", |
|||
"id": "460000" |
|||
}, |
|||
{ |
|||
"name": "重庆市", |
|||
"id": "500000" |
|||
}, |
|||
{ |
|||
"name": "四川省", |
|||
"id": "510000" |
|||
}, |
|||
{ |
|||
"name": "贵州省", |
|||
"id": "520000" |
|||
}, |
|||
{ |
|||
"name": "云南省", |
|||
"id": "530000" |
|||
}, |
|||
{ |
|||
"name": "西藏自治区", |
|||
"id": "540000" |
|||
}, |
|||
{ |
|||
"name": "陕西省", |
|||
"id": "610000" |
|||
}, |
|||
{ |
|||
"name": "甘肃省", |
|||
"id": "620000" |
|||
}, |
|||
{ |
|||
"name": "青海省", |
|||
"id": "630000" |
|||
}, |
|||
{ |
|||
"name": "宁夏回族自治区", |
|||
"id": "640000" |
|||
}, |
|||
{ |
|||
"name": "新疆维吾尔自治区", |
|||
"id": "650000" |
|||
}, |
|||
{ |
|||
"name": "台湾省", |
|||
"id": "710000" |
|||
}, |
|||
{ |
|||
"name": "香港特别行政区", |
|||
"id": "810000" |
|||
}, |
|||
{ |
|||
"name": "澳门特别行政区", |
|||
"id": "820000" |
|||
} |
|||
] |
|||
@ -0,0 +1,22 @@ |
|||
import { request } from '@umijs/max'; |
|||
import { beforeEach, describe, expect, it, vi } from 'vitest'; |
|||
import { queryCity } from './service'; |
|||
|
|||
vi.mock('@umijs/max', () => ({ |
|||
request: vi.fn(), |
|||
})); |
|||
|
|||
describe('account settings service', () => { |
|||
beforeEach(() => { |
|||
vi.clearAllMocks(); |
|||
vi.mocked(request).mockResolvedValue({ data: [] }); |
|||
}); |
|||
|
|||
it('encodes province when requesting city options', async () => { |
|||
await queryCity('33/000?x=1'); |
|||
|
|||
expect(request).toHaveBeenCalledWith( |
|||
'/api/geographic/city/33%2F000%3Fx%3D1', |
|||
); |
|||
}); |
|||
}); |
|||
@ -0,0 +1,52 @@ |
|||
import { describe, expect, it } from 'vitest'; |
|||
import { getCityOptions, provinceOptions } from './chinaDivision'; |
|||
|
|||
describe('chinaDivision geographic options', () => { |
|||
it('keeps province values compatible with existing six-digit province ids', () => { |
|||
expect(provinceOptions).toContainEqual({ |
|||
label: '浙江省', |
|||
key: '330000', |
|||
}); |
|||
expect(provinceOptions).toContainEqual({ |
|||
label: '台湾省', |
|||
key: '710000', |
|||
}); |
|||
}); |
|||
|
|||
it('returns city options for ordinary provinces', () => { |
|||
expect(getCityOptions('130000')).toContainEqual({ |
|||
label: '石家庄市', |
|||
key: '130100', |
|||
}); |
|||
expect(getCityOptions('320000')).toContainEqual({ |
|||
label: '南京市', |
|||
key: '320100', |
|||
}); |
|||
expect(getCityOptions('32')).toContainEqual({ |
|||
label: '南京市', |
|||
key: '320100', |
|||
}); |
|||
}); |
|||
|
|||
it('returns district options for municipalities', () => { |
|||
expect(getCityOptions('110000')).toContainEqual({ |
|||
label: '东城区', |
|||
key: '110101', |
|||
}); |
|||
}); |
|||
|
|||
it('returns city options for Hong Kong, Macao and Taiwan', () => { |
|||
expect(getCityOptions('710000')).toContainEqual({ |
|||
label: '台北市', |
|||
key: '710100', |
|||
}); |
|||
expect(getCityOptions('810000')).toContainEqual({ |
|||
label: '香港岛', |
|||
key: '810100', |
|||
}); |
|||
expect(getCityOptions('820000')).toContainEqual({ |
|||
label: '澳门半岛', |
|||
key: '820100', |
|||
}); |
|||
}); |
|||
}); |
|||
@ -0,0 +1,69 @@ |
|||
import hkMoTwSource from 'china-division/dist/HK-MO-TW.json'; |
|||
import pcaSource from 'china-division/dist/pca-code.json'; |
|||
|
|||
export type GeographicOption = { |
|||
label: string; |
|||
key: string; |
|||
}; |
|||
|
|||
type DivisionNode = { |
|||
code: string; |
|||
name: string; |
|||
children?: DivisionNode[]; |
|||
}; |
|||
|
|||
const directAdminCodes = new Set(['11', '12', '31', '50']); |
|||
|
|||
const specialRegions: GeographicOption[] = [ |
|||
{ label: '台湾省', key: '710000' }, |
|||
{ label: '香港特别行政区', key: '810000' }, |
|||
{ label: '澳门特别行政区', key: '820000' }, |
|||
]; |
|||
|
|||
const toProvinceKey = (code: string) => `${code}0000`; |
|||
|
|||
const toCityKey = (code: string) => (code.length === 4 ? `${code}00` : code); |
|||
|
|||
const toOption = (item: DivisionNode): GeographicOption => ({ |
|||
label: item.name, |
|||
key: toCityKey(item.code), |
|||
}); |
|||
|
|||
export const provinceOptions: GeographicOption[] = [ |
|||
...(pcaSource as DivisionNode[]).map((item) => ({ |
|||
label: item.name, |
|||
key: toProvinceKey(item.code), |
|||
})), |
|||
...specialRegions, |
|||
]; |
|||
|
|||
export const getCityOptions = (provinceKey: string): GeographicOption[] => { |
|||
const provinceCode = |
|||
provinceKey.length === 2 ? provinceKey : provinceKey.slice(0, 2); |
|||
const province = (pcaSource as DivisionNode[]).find( |
|||
(item) => item.code === provinceCode, |
|||
); |
|||
|
|||
if (province) { |
|||
const children = province.children ?? []; |
|||
const cityNodes = directAdminCodes.has(provinceCode) |
|||
? children.flatMap((item) => item.children ?? [item]) |
|||
: children; |
|||
|
|||
return cityNodes.map(toOption); |
|||
} |
|||
|
|||
const specialRegion = specialRegions.find((item) => item.key === provinceKey); |
|||
if (!specialRegion) { |
|||
return []; |
|||
} |
|||
|
|||
return Object.keys( |
|||
(hkMoTwSource as Record<string, Record<string, string[]>>)[ |
|||
specialRegion.label |
|||
] ?? {}, |
|||
).map((name, index) => ({ |
|||
label: name, |
|||
key: `${provinceCode}${String(index + 1).padStart(2, '0')}00`, |
|||
})); |
|||
}; |
|||
Loading…
Reference in new issue