应由gin提供结构化接口而非前端直接渲染element-china-area-data,因其需服务端校验、动态过滤、权限控制及业务关联;三级联动接口路径为:/api/areas/provinces、/api/areas/cities?province=xxx、/api/areas/districts?city=xxx;数据应从gb/t 2260标准库加载,优先用mysql或内存map;返回扁平数组,含value(6位字符串)、label、level字段,并设置长效缓存头。

为什么不用 element-china-area-data 直接前端渲染?
因为 Gin 是后端框架,element-china-area-data 是纯前端静态数据包,直接在 Vue 或 React 里用没问题,但如果你的场景需要:服务端校验、动态过滤(如只返回某省下开通配送的城市)、权限控制(如隐藏港澳台数据)、或与业务表关联(如查出某市下所有已入驻区县),就必须由 Gin 提供结构化接口,而不是让前端加载几 MB 的 JSON。
如何设计三级联动的 REST 接口路径与参数?
别用 /areas 这种模糊路径。三级联动本质是「逐级依赖」,接口必须支持按上级编码查询下级,且默认不返回全量数据:
-
GET /api/areas/provinces→ 返回省级列表,字段至少含code(如"110000")和name(如"北京市") -
GET /api/areas/cities?province=110000→ 用province查询市级,返回该省所有地级市 -
GET /api/areas/districts?city=110100→ 用city查询区县级,支持传city或province(兼容直辖市直查区)
注意:province 和 city 参数必须做长度和格式校验(如必须是 6 位数字字符串),否则容易被恶意遍历或触发空指针。
从哪来数据?别手写 JSON,优先用 GB/T 2260 标准库
硬编码省市区 JSON 易过期、难维护。2025 年民政部已更新至第 23 版行政区划代码,推荐两种可靠方式:
- 用 Go 包
github.com/go-sql-driver/mysql+ 官方 SQL 文件(如从pan.baidu.com/s/1P-zPgra6YJ1LgqQ_v7RvSw下载的带六位码的 MySQL 表),建三张表provinces、cities、districts,用外键关联 - 轻量场景可用内存加载:找已适配 Go 的标准数据包,例如
github.com/chenhg5/go-admin/area(非官方但持续维护),它把CodeToText结构转为 map[string]string,启动时json.Unmarshal一次即可
千万别在 handler 里每次请求都读文件或解析 JSON —— 会成为性能瓶颈。初始化时加载进全局变量,用 sync.RWMutex 保护读写即可。
返回数据结构怎么定才不踩坑?
前端 el-cascader 要求每个节点有 value 和 label,但后端不该暴露原始编码逻辑给前端拼接。正确做法是:接口返回扁平数组,每个元素明确标注层级:
[
{ "value": "110000", "label": "北京市", "level": "province" },
{ "value": "310000", "label": "上海市", "level": "province" }
]
关键点:
- 不要返回嵌套树形结构(如
{children:[{children:[]}]}),前端处理麻烦且易错 - 确保
value字段始终是 6 位字符串,避免整数自动去零(如310000变成31) - 如果要兼容旧版前端,可在 query 中加
compat=element参数,返回value/label字段名,否则统一用code/name
最常被忽略的是缓存头 —— 对不变的省市区数据,务必加 Cache-Control: public, max-age=31536000,CDN 或浏览器能长期缓存,省掉大量重复请求。











