Skip to content

kk-418/cn-division

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

cn-division

🇨🇳 中国行政区划数据 2026版 - 基于民政部地名服务(dmfw)最新年版数据

特性

  • 最新数据: 基于民政部地名服务(dmfw.mca.gov.cn)REST 接口最新年版行政区划数据
  • 🎯 精简优化: 数据体积小,支持tree-shaking,仅导入所需部分
  • 📦 多种格式: 提供带编码和不带编码两种版本,满足不同场景需求
  • 🛠 框架无关: 通用 Cascader 数据结构,兼容 antd、TDesign、Element Plus 等主流组件,无需 fieldNames 配置
  • 🔍 地址解析: 内置地址解析功能,可从地址字符串提取省市区信息
  • 💪 TypeScript: 完整的TypeScript类型定义
  • 🚀 ESM: 纯ESM模块,支持现代构建工具

安装

npm install cn-division
#
pnpm add cn-division
#
yarn add cn-division

版本说明

本项目采用特殊的版本号格式:年份.月份数据.修订版本号

  • 年份:数据对应的年份(如 2025)
  • 月份数据:数据更新的月份(0 表示年度整体数据,1-12 表示具体月份)
  • 修订版本号:bug 修复和功能改进的递增版本号

示例

  • 2026.0.0 - 2026年度数据,首次发布
  • 2026.1.0 - 2026年1月数据更新
  • 2026.0.1 - 2026年度数据的第一次修订

数据格式

带编码版本(/dist/code/)

  • 省份代码:2位(如:11)
  • 城市代码:4位(如:1101)
  • 区县/街镇级代码:6位或12位(如:110101、441900401000)

不带编码版本(/dist/no-code/)

  • 纯名称数组和对象结构
  • 适用于只需要显示名称的场景

文件体积

本包提供带编码和不带编码两种版本,可根据需要按需引入,有效控制包体积。

数据文件体积对照表

文件路径 大小 说明
带编码版本 (dist/code/)
dist/code/pca.json 105K 省市区三级结构(含代码)
dist/code/counties.json 126K 区县数据(含代码)
dist/code/cities.json 13K 城市数据(含代码)
dist/code/pc.json 11K 省市二级结构(含代码)
dist/code/provinces.json 833B 省份数据(含代码)
不带编码版本 (dist/no-code/)
dist/no-code/pca.json 43K 省市区三级结构(纯名称)⭐
dist/no-code/counties.json 36K 区县数据(纯名称)
dist/no-code/cities.json 4.6K 城市数据(纯名称)
dist/no-code/pc.json 5.9K 省市二级结构(纯名称)
dist/no-code/provinces.json 430B 省份数据(纯名称)
index.js 3.2K 入口文件
index.d.ts 2.1K TypeScript 类型定义

体积优化建议

  1. 完整功能场景 (推荐使用不带编码版本)

    import { getCascaderData } from 'cn-division';
    // 导入: ~43K (pca.json)
  2. 只需要代码 (使用带编码版本)

    import { getCascaderDataWithCode } from 'cn-division';
    // 导入: ~105K (pca-code.json)
  3. 按需引入 (最小化体积)

    import { provinces, cities } from 'cn-division';
    // 仅导入省份和城市: ~5K
  4. 直接引入 JSON (tree-shaking 友好)

    import pca from 'cn-division/dist/no-code/pca.json';
    // 仅导入需要的 JSON: ~43K

快速开始

基础数据导入

import {
  provinces,      // 省份数据(带编码)
  cities,         // 城市数据(带编码)
  counties,       // 区县数据(带编码)
  provincesNoCode,// 省份数据(纯名称)
  citiesNoCode,   // 城市数据(纯名称)
  countiesNoCode, // 区县数据(纯名称)
  pca,            // 省市区三级结构(不带编码)
  pc,             // 省市二级结构(不带编码)
  pcaCode,        // 省市区三级结构(带编码)
  pcCode          // 省市二级结构(带编码)
} from 'cn-division';

console.log(provinces);
// [{ c: '11', n: '北京市' }, { c: '12', n: '天津市' }, ...]

console.log(provincesNoCode);
// ['北京市', '天津市', '河北省', ...]

Cascader 组件(通用 API)

value 统一为字符串,使用标准 { label, value, children } 结构,兼容 antd、TDesign、Element Plus 等主流组件库,无需配置 fieldNames。内置 lazy init 缓存,多次调用零开销。

import {
  getCascaderDataWithCode,  // 省市区三级,value = 编码
  getCascaderData,          // 省市区三级,value = 名称
  getCascaderPCWithCode,    // 省市二级,value = 编码(适合查价格等场景)
  getAddressValueFromCodes, // 根据编码构建统一 AddressValue 对象
} from 'cn-division';

// 省市区三级(带编码)
const options = getCascaderDataWithCode();
// [{ label: '北京市', value: '11', children: [{ label: '北京市', value: '1101', children: [...] }] }]

// 省市二级(带编码)
const pcOptions = getCascaderPCWithCode();
// [{ label: '北京市', value: '11', children: [{ label: '北京市', value: '1101' }] }]

// 根据编码查询完整地址信息
const addr = getAddressValueFromCodes('11', '1101', '110101');
// { province: { code: '11', name: '北京市' }, city: { code: '1101', name: '北京市' }, county: { code: '110101', name: '东城区' } }

在 antd 中使用:

import { Cascader } from 'antd';
import { getCascaderDataWithCode } from 'cn-division';

const options = getCascaderDataWithCode(); // 一次性初始化,内部有缓存

function AddressSelector() {
  return <Cascader options={options} placeholder="请选择地址" />;
}

在 TDesign 中使用:

import { Cascader } from 'tdesign-react';
import { getCascaderDataWithCode } from 'cn-division';

// TDesign 和 antd 结构相同,直接复用
const options = getCascaderDataWithCode();

function AddressSelector() {
  return <Cascader options={options} placeholder="请选择地址" />;
}

在微信小程序(TDesign miniprogram)中使用:

import { getCascaderPCWithCode } from 'cn-division';

Component({
  data: { areaOptions: [] },
  lifetimes: {
    attached() {
      this.setData({ areaOptions: getCascaderPCWithCode() });
    }
  }
});
<t-cascader options="{{areaOptions}}" bind:change="onAreaChange" />

💡 小程序按需引入(推荐)

微信小程序不支持 tree-shaking,全量引入 cn-division 会增加主包约 800KB。本包提供 miniprogram_dist/ 目录,将每个功能拆分为独立的自包含模块,只有被引用到的模块文件才计入包体积

// 只引入省市二级选择器(带编码) — 仅 ~106 KB
import { getCascaderPCWithCode } from 'cn-division/cascader-pc-code';

// 只引入地址解析 — 仅 ~42 KB
import { parseAddress } from 'cn-division/parse';

// 只引入编码查询 — 仅 ~143 KB
import { getNameByCode, formatFullPath } from 'cn-division/lookup';

可用模块:

模块路径 导出函数 体积
cn-division/cascader-pca-code getCascaderDataWithCode() ~106 KB
cn-division/cascader-pca getCascaderData() ~43 KB
cn-division/cascader-pc-code getCascaderPCWithCode() ~106 KB
cn-division/cascader-pc getCascaderPC() ~6 KB
cn-division/lookup getNameByCode(), getProvinceByCode(), getCityByCode(), getCountyByCode() ~143 KB
cn-division/parse parseAddress() ~42 KB

每个模块附带 .d.ts 类型声明,TypeScript 开发完整类型支持。

工具函数

import {
  getProvinceByCode,
  getCityByCode,
  getCountyByCode,
  getNameByCode,
  parseAddress,
  formatFullPath,
  isMunicipalityCode,
  getCitiesByProvince,
  getCountiesByCity,
  validateCode
} from 'cn-division';

// 根据代码获取信息
getProvinceByCode('110000');  // { c: '11', n: '北京市' }
getCityByCode('110100');      // { c: '1101', n: '北京市', p: '11' }
getCountyByCode('110101');      // { c: '110101', n: '东城区', cc: '1101' }

// 根据代码获取名称
getNameByCode('110000');      // '北京市'
getNameByCode('110101');      // '东城区'

// 格式化完整路径
formatFullPath('110101');     // '北京市 / 东城区'
formatFullPath('320505');     // '江苏省 / 苏州市 / 虎丘区'

// 地址解析
parseAddress('北京市朝阳区建国路88号');
// {
//   province: '北京市',
//   city: undefined,
//   county: '朝阳区',
//   rest: '建国路88号'
// }

parseAddress('广东省深圳市南山区科技园');
// {
//   province: '广东省',
//   city: '深圳市',
//   county: '南山区',
//   rest: '科技园'
// }

// 检查是否为直辖市
isMunicipalityCode('110000');  // true
isMunicipalityCode('320000');  // false

// 获取省份下的城市
getCitiesByProvince('32');     // 江苏省下的所有城市

// 获取城市下的区县
getCountiesByCity('3201');        // 南京市下的所有区县

// 验证代码格式
validateCode('110101');        // true
validateCode('441900401000');  // true
validateCode('123');           // false

API 参考

数据导出

导出名 类型 描述
provinces Province[] 省份数据(带编码)
cities City[] 城市数据(带编码)
counties County[] 区县数据(带编码)
provincesNoCode string[] 省份名称数组
citiesNoCode string[] 城市名称数组
countiesNoCode string[] 区县名称数组
pca PCAData 省市区三级结构(不带编码)
pc PCData 省市二级结构(不带编码)
pcaCode PCACodeData[] 省市区三级结构(带编码)
pcCode PCCodeData[] 省市二级结构(带编码)

函数导出

Cascader 数据生成(通用 API)

// 省市区三级,value = 行政区划编码(string)
// 兼容 antd、TDesign、Element Plus 等主流组件,无需 fieldNames 配置
function getCascaderDataWithCode(): CascaderOption[]

// 省市区三级,value = 名称(string)
function getCascaderData(): CascaderOption[]

// 省市二级,value = 行政区划编码(string)
// 适合查价格等只需省市的场景
function getCascaderPCWithCode(): CascaderOptionPC[]

// 根据三级行政区划编码构建统一 AddressValue 对象
function getAddressValueFromCodes(
  provinceCode: string | number,
  cityCode: string | number,
  countyCode: string | number
): AddressValue | null

查询函数

// 根据代码获取省份信息
function getProvinceByCode(code: string): Province | undefined

// 根据代码获取城市信息
function getCityByCode(code: string): City | undefined

// 根据代码获取区县信息
function getCountyByCode(code: string): County | undefined

// 根据代码获取名称
function getNameByCode(code: string): string | undefined

// 检查是否为直辖市代码
function isMunicipalityCode(code: string): boolean

// 获取省份下的所有城市
function getCitiesByProvince(provinceCode: string): City[]

// 获取城市下的所有区县
function getCountiesByCity(cityCode: string): County[]

// 验证代码格式
function validateCode(code: string): boolean

工具函数

// 地址解析
function parseAddress(address: string): ParseResult | null

// 格式化完整路径
function formatFullPath(code: string): string

TypeScript 类型

interface ProvinceCode {
  c: string;  // 省份代码(2位)
  n: string;  // 省份名称
}

interface CityCode {
  c: string;  // 城市代码(4位)
  n: string;  // 城市名称
  p: string;  // 所属省份代码(2位)
}

interface CountyCode {
  c: string;  // 区县/街镇级代码(6位或12位)
  n: string;  // 区县名称
  cc: string; // 所属城市代码(4位)
}

interface CascaderOption {
  label: string;
  value: string;
  children?: CascaderOption[];
}

interface CascaderOptionWithCode {
  label: string;
  value: string;
  code: string;
  children?: CascaderOptionWithCode[];
}

// 省市二级,用于 getCascaderPCWithCode()
interface CascaderOptionPC {
  label: string;
  value: string;  // 省/市编码
  children?: Array<{ label: string; value: string }>;
}

// 统一地址值,用于 getAddressValueFromCodes() 的返回值
interface AddressValue {
  province: { name: string; code: string };
  city:     { name: string; code: string };
  county:   { name: string; code: string };
}

interface ParseResult {
  province?: string;
  city?: string;
  county?: string;
  rest: string;
}

常量

import { MUNICIPALITY_CODES, VERSION } from 'cn-division';

console.log(MUNICIPALITY_CODES); // ['11', '12', '31', '50']
console.log(VERSION);             // '2026.0.0'

数据更新

本项目通过民政部地名服务(dmfw)REST 接口自动获取最新行政区划数据,无需解析 HTML 页面。

更新命令

# 完整更新(抓取 + 构建)
npm run update

# 仅抓取数据(不构建)
npm run fetch

# 仅构建数据(使用已抓取的数据)
npm run build

更新流程说明

1. 抓取数据 (npm run fetch)

调用民政部地名服务 REST 接口获取最新数据:

  • 数据源: https://dmfw.mca.gov.cn/9095/xzqh/getList
  • 接口文档: https://dmfw.mca.gov.cn/interface.html
  • 请求参数: code(行政区划编码,根节点留空)、maxLevel(层级深度,默认 3)、year(年份,默认最新年版)
  • 响应格式: 返回 JSON,根节点为 response.data.children,每个节点含 codenamelevelchildren 字段
  • 下钻查询: 对没有县级子节点的地级市(东莞、中山、儋州等)使用该市 code 再次请求(maxLevel=2)获取街道/镇级数据
  • 特殊处理:
    • 自动处理直辖市(北京、天津、上海、重庆)
    • 自动过滤台湾、香港、澳门数据
  • 输出文件: temp/raw-data.json(原始抓取数据)
npm run fetch

执行后会看到类似输出:

开始从民政部获取最新行政区划数据...
数据源: https://dmfw.mca.gov.cn/9095/xzqh/getList?code=&maxLevel=3
正在获取接口数据...
接口数据获取成功
开始解析接口数据...
下钻查询: 东莞市 (441900000000)
下钻查询: 中山市 (442000000000)
下钻查询: 儋州市 (460400000000)
解析完成: 省份 33 个, 城市 342 个, 区县 2923 个
数据验证完成
原始数据已保存到: temp/raw-data.json

=== 数据统计 ===
省份数量: 31
城市数量: 342
区县数量: 2923
总计: 3296

2. 构建数据 (npm run build)

将抓取的原始数据转换为多种格式:

  • 输入文件: temp/raw-data.json
  • 输出目录:
    • dist/code/ - 带编码版本(含行政区划代码)
    • dist/no-code/ - 不带编码版本(纯名称)
  • 生成文件:
    • provinces.json - 省份列表
    • cities.json - 城市列表
    • counties.json - 区县列表
    • pca.json - 省市区三级结构
    • pc.json - 省市二级结构
npm run build

3. 完整更新 (npm run update)

相当于依次执行 npm run fetchnpm run build,完成从抓取到构建的完整流程。

npm run update

自定义数据源

接口默认不指定年份(year: undefined),服务端返回最新年版数据。如需固定到特定年份,可修改 lib/fetch.js 中的 year

const CONFIG = {
  year: 2025, // 固定为 2025 年数据;undefined 表示始终使用最新年版
};

注意事项

  1. 网络连接: 数据抓取需要访问民政部地名服务接口,确保网络连接正常
  2. 接口可用性: 接口偶发 5xx 时脚本会自动重试(最多 3 次),连续失败需要稍后重试
  3. 数据验证: 抓取后会自动验证省份数量及引用完整性,如有异常会输出警告
  4. 备份数据: 更新前建议备份现有数据文件

数据说明

数据来源

  • 官方来源: 中华人民共和国民政部 · 地名服务(dmfw)
  • 接口地址: https://dmfw.mca.gov.cn/9095/xzqh/getList
  • 接口文档: https://dmfw.mca.gov.cn/interface.html
  • 数据类型: REST JSON 接口,非 HTML 页面抓取
  • 更新时间: 接口默认返回最新年版;可通过 year 参数指定历史年份
  • 数据范围: 不包含台湾省、香港特别行政区、澳门特别行政区

与微信小程序的兼容性

本数据与微信小程序的 picker-region 组件数据基本一致,可直接用于替代或补充微信小程序的地区选择功能。

已知差异

  • 省直辖县级市显示名称
    • 本项目:显示为 "省直辖县级行政单位"
    • 微信小程序:显示为 "省直辖县级行政区划"
    • 说明:这是唯一已知的显示差异,不影响数据结构和功能使用。其余数据和微信小程序基本一致。如需与微信小程序完全一致,可以通过简单的字符串替换实现。

直辖市处理

对于北京市、天津市、上海市、重庆市四个直辖市:

  • 省级和市级名称相同
  • 避免了传统的"市辖区"显示问题
  • 保持了数据结构的一致性

特殊结构处理

为确保数据完整性和用户体验,项目包含以下特殊结构处理:

1. 无县级子节点城市下钻

对于东莞市、中山市、儋州市、嘉峪关市等接口首层结果中没有县级子节点的地级市,抓取脚本会继续使用该城市 code 调用 getList 下钻查询,使用接口返回的街道/镇级节点作为三级 Cascader 的下级数据。

2. 重庆市虚拟城市映射

为解决重庆市部分县级单位(cityCode=500200)缺少上级城市的问题,创建虚拟城市映射:

虚拟城市"县"(500200)

  • 归属:重庆市下级
  • 包含12个县:城口县、丰都县、垫江县、忠县、云阳县、奉节县、巫山县、巫溪县、石柱土家族自治县、秀山土家族苗族自治县、酉阳土家族苗族自治县、彭水苗族土家族自治县
  • 原因:这些县在原始数据中使用cityCode=500200,但缺少对应的城市记录,通过虚拟映射确保数据结构完整

3. 接口缺失数据补充

为补齐民政部地名服务接口当前未返回的区划,构建阶段(lib/supplemental-counties.js)会自动合并以下数据:

  • 东莞市:松山湖(441900401000)、东莞港(441900402000)、东莞生态园(441900403000)、东莞滨海湾新区(441900404000)
  • 儋州市:洋浦经济开发区(460400499000)、华南热作学院(460400500000)
  • 大兴安岭地区:加格达奇区(232761)、松岭区(232762)、新林区(232763)、呼中区(232764)

若后续官方接口恢复同名/同编码数据,构建脚本会自动跳过重复项。

通过这些特殊结构处理,确保了:

  • 数据结构的完整性和一致性
  • 用户界面显示的正确性
  • 地址解析功能的准确性

数据统计

  • 省份:31个
  • 城市:342个
  • 区县:2933个
  • 总计:3306条记录

性能

经过性能测试,主要操作的执行时间:

  • 生成Cascader数据1000次:~18ms
  • 地址解析1000次:~12ms
  • 数据体积经过优化,最小化存储空间

更新日志

详见 CHANGELOG.md

许可证

MIT License


作者: kk 维护: 如有问题欢迎提交Issue

About

🇨🇳 中国行政区划数据 2026版 - 基于民政部最新数据,与微信小程序 picker-region 数据高度一致,支持省市区三级联动、地址解析、antd Cascader,提供带编码和纯名称两种格式,TypeScript 完整类型支持

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors