commit 19d0df4fa9ac21f4a1ca6e4c791948509f77f3e3 Author: Weiming Date: Thu Jun 11 15:27:52 2026 +0800 初始化 diff --git a/README.md b/README.md new file mode 100644 index 0000000..fc98430 --- /dev/null +++ b/README.md @@ -0,0 +1,173 @@ +# 飞书审批配置服务 + +内网 Web 服务:用户在浏览器中设计审批表单与流程,保存时**下载包含全部配置的独立 HTML 文件**,可离线打开或分发给他人。 + +## 功能 + +- 在线编辑:基础信息、表单设计、流程设计 +- **保存并下载 HTML**:配置写入 HTML 文件,无需本地 bat / data 文件夹 +- **导入 HTML**:继续编辑之前导出的配置文件 + +## 环境要求 + +- **Node.js 16.x**(CentOS 7 推荐 16.20 LTS) +- 无需 `npm install`(零第三方依赖,仅使用 Node 内置模块) + +## 快速启动 + +```bash +cd Approval_of_design +node server.js +``` + +浏览器访问:`http://服务器IP:8080` + +端口与监听地址可在 `project.config.json` 中修改: + +```json +{ + "projectId": "approval_of_design", + "port": 8080, + "host": "0.0.0.0", + "label": "飞书审批配置服务" +} +``` + +## CentOS 7 部署 + +### 1. 安装 Node.js 16.x + +CentOS 7 自带 glibc 较旧,建议使用 NodeSource 16.x 或 nvm: + +**方式 A:NodeSource(推荐)** + +```bash +curl -fsSL https://rpm.nodesource.com/setup_16.x | sudo bash - +sudo yum install -y nodejs +node -v # 应显示 v16.x.x +``` + +**方式 B:nvm** + +```bash +curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash +source ~/.bashrc +nvm install 16 +nvm use 16 +``` + +### 2. 上传并启动 + +```bash +sudo mkdir -p /opt/feishu-approval +# 将项目文件上传到 /opt/feishu-approval +cd /opt/feishu-approval +node server.js +``` + +或使用项目自带脚本: + +```bash +chmod +x deploy/start.sh +./deploy/start.sh +``` + +### 3. systemd 开机自启(推荐) + +```bash +# 修改 deploy/feishu-approval.service 中 WorkingDirectory、User 后: +sudo cp deploy/feishu-approval.service /etc/systemd/system/ +sudo systemctl daemon-reload +sudo systemctl enable feishu-approval +sudo systemctl start feishu-approval +sudo systemctl status feishu-approval +``` + +### 4. 防火墙 + +```bash +sudo firewall-cmd --permanent --add-port=8080/tcp +sudo firewall-cmd --reload +``` + +### 5. 验证 + +```bash +curl http://127.0.0.1:8080/api/health +``` + +## 部署到其他环境 + +### 1. 上传项目 + +将整个 `Approval_of_design` 目录复制到内网服务器。 + +### 2. 启动服务 + +**方式 A:直接运行** + +```bash +node server.js +``` + +**方式 B:使用 pm2 守护进程(推荐)** + +```bash +npm install -g pm2 +pm2 start server.js --name feishu-approval +pm2 save +pm2 startup +``` + +**方式 C:Windows 服务** + +使用 [nssm](https://nssm.cc/) 将 `node server.js` 注册为 Windows 服务,开机自启。 + +### 3. 反向代理(可选) + +若需通过 80 端口或 HTTPS 访问,可在 Nginx 中配置: + +```nginx +location / { + proxy_pass http://127.0.0.1:8080; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; +} +``` + +### 4. 防火墙 + +在内网服务器开放 `project.config.json` 中配置的端口(默认 8080)。 + +## API + +| 方法 | 路径 | 说明 | +|------|------|------| +| GET | `/` | 在线编辑器 | +| GET | `/api/health` | 健康检查 | +| POST | `/api/export` | 提交 JSON 配置,返回 HTML 文件下载 | +| POST | `/api/import` | 提交 HTML 文本,解析其中的配置 JSON | + +## 文件说明 + +| 文件 | 说明 | +|------|------| +| `server.js` | Web 服务主程序 | +| `飞书审批配置文件_V1.0.html` | 编辑器模板(服务与导出共用) | +| `project.config.json` | 端口、服务名称等配置 | +| `deploy/start.sh` | CentOS 7 启动脚本 | +| `deploy/feishu-approval.service` | systemd 服务单元示例 | + +## 使用流程 + +1. 访问服务地址,开始新建或导入已有 HTML +2. 完成表单与流程设计 +3. 点击 **「保存并下载 HTML」**,获得独立配置文件 +4. 下载的 HTML 可双击离线打开;再次编辑可导入回在线服务 + +## 健康检查 + +```bash +curl http://localhost:8080/api/health +``` diff --git a/address-regions.js b/address-regions.js new file mode 100644 index 0000000..c03b954 --- /dev/null +++ b/address-regions.js @@ -0,0 +1,292 @@ +/* Auto-generated address region data for Feishu-style address conditions */ +(function (g) { + var ADDRESS_COUNTRIES = ["中国","中国香港","中国澳门","中国台湾","美国","日本","韩国","新加坡","马来西亚","泰国","越南","印度","印度尼西亚","菲律宾","英国","法国","德国","意大利","西班牙","荷兰","瑞士","瑞典","挪威","丹麦","芬兰","俄罗斯","波兰","捷克","奥地利","比利时","加拿大","墨西哥","巴西","阿根廷","智利","哥伦比亚","澳大利亚","新西兰","南非","埃及","阿联酋","沙特阿拉伯","以色列","土耳其","其他"]; + var COUNTRY_META = { + "中国": { + "lang": "zh", + "hasRegion": true, + "hasDistrict": true + }, + "中国香港": { + "lang": "zh", + "fixedRegion": "香港特别行政区", + "hasRegion": true, + "hasDistrict": true + }, + "中国澳门": { + "lang": "zh", + "fixedRegion": "澳门特别行政区", + "hasRegion": true, + "hasDistrict": false + }, + "中国台湾": { + "lang": "zh", + "fixedRegion": "台湾省", + "hasRegion": true, + "hasDistrict": true + }, + "美国": { + "lang": "en", + "hasRegion": true, + "hasDistrict": false + }, + "日本": { + "lang": "en", + "hasRegion": true, + "hasDistrict": false + }, + "韩国": { + "lang": "en", + "hasRegion": true, + "hasDistrict": false + }, + "新加坡": { + "lang": "en", + "hasRegion": false, + "hasDistrict": false + }, + "马来西亚": { + "lang": "en", + "hasRegion": true, + "hasDistrict": false + }, + "泰国": { + "lang": "en", + "hasRegion": true, + "hasDistrict": false + }, + "越南": { + "lang": "en", + "hasRegion": true, + "hasDistrict": false + }, + "印度": { + "lang": "en", + "hasRegion": true, + "hasDistrict": false + }, + "印度尼西亚": { + "lang": "en", + "hasRegion": true, + "hasDistrict": false + }, + "菲律宾": { + "lang": "en", + "hasRegion": true, + "hasDistrict": false + }, + "英国": { + "lang": "en", + "hasRegion": true, + "hasDistrict": false + }, + "法国": { + "lang": "en", + "hasRegion": true, + "hasDistrict": false + }, + "德国": { + "lang": "en", + "hasRegion": true, + "hasDistrict": false + }, + "意大利": { + "lang": "en", + "hasRegion": true, + "hasDistrict": false + }, + "西班牙": { + "lang": "en", + "hasRegion": true, + "hasDistrict": false + }, + "荷兰": { + "lang": "en", + "hasRegion": true, + "hasDistrict": false + }, + "瑞士": { + "lang": "en", + "hasRegion": true, + "hasDistrict": false + }, + "瑞典": { + "lang": "en", + "hasRegion": true, + "hasDistrict": false + }, + "挪威": { + "lang": "en", + "hasRegion": true, + "hasDistrict": false + }, + "丹麦": { + "lang": "en", + "hasRegion": true, + "hasDistrict": false + }, + "芬兰": { + "lang": "en", + "hasRegion": true, + "hasDistrict": false + }, + "俄罗斯": { + "lang": "en", + "hasRegion": true, + "hasDistrict": false + }, + "波兰": { + "lang": "en", + "hasRegion": true, + "hasDistrict": false + }, + "捷克": { + "lang": "en", + "hasRegion": true, + "hasDistrict": false + }, + "奥地利": { + "lang": "en", + "hasRegion": true, + "hasDistrict": false + }, + "比利时": { + "lang": "en", + "hasRegion": true, + "hasDistrict": false + }, + "加拿大": { + "lang": "en", + "hasRegion": true, + "hasDistrict": false + }, + "墨西哥": { + "lang": "en", + "hasRegion": true, + "hasDistrict": false + }, + "巴西": { + "lang": "en", + "hasRegion": true, + "hasDistrict": false + }, + "阿根廷": { + "lang": "en", + "hasRegion": true, + "hasDistrict": false + }, + "智利": { + "lang": "en", + "hasRegion": true, + "hasDistrict": false + }, + "哥伦比亚": { + "lang": "en", + "hasRegion": true, + "hasDistrict": false + }, + "澳大利亚": { + "lang": "en", + "hasRegion": true, + "hasDistrict": false + }, + "新西兰": { + "lang": "en", + "hasRegion": true, + "hasDistrict": false + }, + "南非": { + "lang": "en", + "hasRegion": true, + "hasDistrict": false + }, + "埃及": { + "lang": "en", + "hasRegion": true, + "hasDistrict": false + }, + "阿联酋": { + "lang": "en", + "hasRegion": true, + "hasDistrict": false + }, + "沙特阿拉伯": { + "lang": "en", + "hasRegion": true, + "hasDistrict": false + }, + "以色列": { + "lang": "en", + "hasRegion": true, + "hasDistrict": false + }, + "土耳其": { + "lang": "en", + "hasRegion": true, + "hasDistrict": false + }, + "其他": { + "lang": "en", + "hasRegion": true, + "hasDistrict": false + } +}; + var WORLD_REGIONS = {"中国":{"北京市":{"市辖区":["东城区","西城区","朝阳区","丰台区","石景山区","海淀区","门头沟区","房山区","通州区","顺义区","昌平区","大兴区","怀柔区","平谷区","密云区","延庆区"]},"天津市":{"市辖区":["和平区","河东区","河西区","南开区","河北区","红桥区","东丽区","西青区","津南区","北辰区","武清区","宝坻区","滨海新区","宁河区","静海区","蓟州区"]},"河北省":{"石家庄市":["长安区","桥西区","新华区","井陉矿区","裕华区","藁城区","鹿泉区","栾城区","井陉县","正定县","行唐县","灵寿县","高邑县","深泽县","赞皇县","无极县","平山县","元氏县","赵县","石家庄高新技术产业开发区","石家庄循环化工园区","辛集市","晋州市","新乐市"],"唐山市":["路南区","路北区","古冶区","开平区","丰南区","丰润区","曹妃甸区","滦南县","乐亭县","迁西县","玉田县","河北唐山芦台经济开发区","唐山市汉沽管理区","唐山高新技术产业开发区","河北唐山海港经济开发区","遵化市","迁安市","滦州市"],"秦皇岛市":["海港区","山海关区","北戴河区","抚宁区","青龙满族自治县","昌黎县","卢龙县","秦皇岛市经济技术开发区","北戴河新区"],"邯郸市":["邯山区","丛台区","复兴区","峰峰矿区","肥乡区","永年区","临漳县","成安县","大名县","涉县","磁县","邱县","鸡泽县","广平县","馆陶县","魏县","曲周县","邯郸经济技术开发区","邯郸冀南新区","武安市"],"邢台市":["襄都区","信都区","任泽区","南和区","临城县","内丘县","柏乡县","隆尧县","宁晋县","巨鹿县","新河县","广宗县","平乡县","威县","清河县","临西县","河北邢台经济开发区","南宫市","沙河市"],"保定市":["竞秀区","莲池区","满城区","清苑区","徐水区","涞水县","���平县","定兴县","唐县","高阳县","容城县","涞源县","望都县","安新县","易县","曲阳县","蠡县","顺平县","博野县","雄县","保定高新技术产业开发区","保定白沟新城","涿州市","定州市","安国市","高碑店市"],"张家口市":["桥东区","桥西区","宣化区","下花园区","万全区","崇礼区","张北县","康保县","沽源县","尚义县","蔚县","阳原县","怀安县","怀来县","涿鹿县","赤城县","张家口经济开发区","张家口市察北管理区","张家口市塞北管理区"],"承德市":["双桥区","双滦区","鹰手营子矿区","承德县","兴隆县","滦平县","隆化县","丰宁满族自治县","宽城满族自治县","围场满族蒙古族自治县","承德高新技术产业开发区","平泉市"],"沧州市":["新华区","运河区","沧县","青县","东光县","海兴县","盐山县","肃宁县","南皮县","吴桥县","献县","孟村回族自治县","河北沧州经济开发区","沧州高新技术产业开发区","沧州���海新区","泊头市","任丘市","黄骅市","河间市"],"廊坊市":["安次区","广阳区","固安县","永清县","香河县","大城县","文安县","大厂回族自治县","廊坊经济技术开发区","霸州市","三河市"],"衡水市":["桃城区","冀州区","枣强县","武邑县","武强县","饶阳县","安平县","故城县","景县","阜城县","河北衡水高新技术产业开发区","衡水滨湖新区","深州市"]},"山西省":{"太原市":["小店区","迎泽区","杏花岭区","尖草坪区","万柏林区","晋源区","清徐县","阳曲县","娄烦县","山西转型综合改革示范区","古交市"],"大同市":["新荣区","平城区","云冈区","云州区","阳高县","天镇县","广灵县","灵丘县","浑源县","左云县","山西大同经济开发区"],"阳泉市":["城区","矿区","郊区","平定县","盂县"],"长治市":["潞州区","上党区","屯留区","潞城区","襄垣县","平顺县","黎城县","壶关县","长子县","武乡县","沁县","沁源县"],"晋城市":["城区","沁水县","阳城县","陵川县","泽州县","高平市"],"朔州市":["朔城区","平鲁区","山阴县","应县","右玉县","山西朔州经济开发区","怀仁市"],"晋中市":["榆次区","太谷区","榆社县","左权县","和顺县","昔阳县","寿阳县","祁县","平遥县","灵石县","介休市"],"运城市":["盐湖区","临猗县","万荣县","闻喜县","稷山县","新绛县","绛县","垣曲县","夏县","平陆县","芮城县","永济市","河津市"],"忻州市":["忻府区","定襄县","五台县","代县","繁峙县","宁武县","静乐县","神池县","五寨县","岢岚县","河曲县","保德县","偏关县","五台山风景名胜区","原平市"],"临汾市":["尧都区","曲沃县","翼城县","襄汾县","洪洞县","古县","安泽县","浮山县","吉县","乡���县","大宁县","隰县","永和县","蒲县","汾西县","侯马市","霍州市"],"吕梁市":["离石区","文水县","交城县","兴县","临县","柳林县","石楼县","岚县","方山县","中阳县","交口县","孝义市","汾阳市"]},"内蒙古自治区":{"呼和浩特市":["新城区","回民区","玉泉区","赛罕区","土默特左旗","托克托县","和林格尔县","清水河县","武川县","呼和浩特经济技术开发区"],"包头市":["东河区","昆都仑区","青山区","石拐区","白云鄂博矿区","九原区","土默特右旗","固阳县","达尔罕茂明安联合旗","包头稀土高新技术产业开发区"],"乌海市":["海勃湾区","海南区","乌达区"],"赤峰市":["红山区","元宝山区","松山区","阿鲁科尔沁旗","巴林左旗","巴林右旗","林西县","克什克腾旗","翁牛特旗","喀喇沁旗","宁城县","敖汉旗"],"通辽市":["科尔沁区","科尔沁左翼中旗","科尔沁左翼后旗","开鲁县","库伦旗","���曼旗","扎鲁特旗","通辽经济技术开发区","霍林郭勒市"],"鄂尔多斯市":["东胜区","康巴什区","达拉特旗","准格尔旗","鄂托克前旗","鄂托克旗","杭锦旗","乌审旗","伊金霍洛旗"],"呼伦贝尔市":["海拉尔区","扎赉诺尔区","阿荣旗","莫力达瓦达斡尔族自治旗","鄂伦春自治旗","鄂温克族自治旗","陈巴尔虎旗","新巴尔虎左旗","新巴尔虎右旗","满洲里市","牙克石市","扎兰屯市","额尔古纳市","根河市"],"巴彦淖尔市":["临河区","五原县","磴口县","乌拉特前旗","乌拉特中旗","乌拉特后旗","杭锦后旗"],"乌兰察布市":["集宁区","卓资县","化德县","商都县","兴和县","凉城县","察哈尔右翼前旗","察哈尔右翼中旗","察哈尔右翼后旗","四子王旗","丰镇市"],"兴安盟":["乌兰浩特市","阿尔山市","科尔沁右翼前旗","科尔沁右翼中旗","扎赉特旗","突泉县"],"锡林郭勒盟":["二连浩特市","锡林浩特市","阿巴嘎旗","苏尼特左旗","苏尼特右旗","东乌珠穆沁旗","西乌珠穆沁旗","太仆��旗","镶黄旗","正镶白旗","正蓝旗","多伦县","乌拉盖管理区管委会"],"阿拉善盟":["阿拉善左旗","阿拉善右旗","额济纳旗","内蒙古阿拉善高新技术产业开发区"]},"辽宁省":{"沈阳市":["和平区","沈河区","大东区","皇姑区","铁西区","苏家屯区","浑南区","沈北新区","于洪区","辽中区","康平县","法库县","新民市"],"大连市":["中山区","西岗区","沙河口区","甘井子区","旅顺口区","金州区","普兰店区","长海县","瓦房店市","庄河市"],"鞍山市":["铁东区","铁西区","立山区","千山区","台安县","岫岩满族自治县","海城市"],"抚顺市":["新抚区","东洲区","望花区","顺城区","抚顺县","新宾满族自治县","清原满族自治县"],"本溪市":["平山区","溪湖区","明山区","南芬区","本溪满族自治县","桓仁满族自治县"],"丹东市":["元宝区","振兴区","振安区","宽甸满族自治县","东港市","凤城市"],"锦州市":["古塔区","凌河区","太和区","黑山县","义县","凌海市","北镇市"],"营口市":["站前区","西市区","鲅鱼圈区","老边区","盖州市","大石桥市"],"阜新市":["海州区","新邱区","太平区","清河门区","细河区","阜新蒙古族自治县","彰武县"],"辽阳市":["白塔区","文圣区","宏伟区","弓长岭区","太子河区","辽阳县","灯塔市"],"盘锦市":["双台子区","兴隆台区","大洼区","盘山县"],"铁岭市":["银州区","清河区","铁岭县","西丰县","昌图县","调兵山市","开原市"],"朝阳市":["双塔区","龙城区","朝阳县","建平县","喀喇沁左翼蒙古族自治县","北票市","凌源市"],"葫芦岛市":["连山区","龙港区","南票区","绥中县","建昌县","兴城市"]},"吉林省":{"长春市":["南关区","宽城区","朝阳区","二道区","绿园区","双阳区","九台区","农安县","长春经济技术开发区","长��净月高新技术产业开发区","长春高新技术产业开发区","长春汽车经济技术开发区","榆树市","德惠市","公主岭市"],"吉林市":["昌邑区","龙潭区","船营区","丰满区","永吉县","吉林经济开发区","吉林高新技术产业开发区","吉林中国新加坡食品区","蛟河市","桦甸市","舒兰市","磐石市"],"四平市":["铁西区","铁东区","梨树县","伊通满族自治县","双辽市"],"辽源市":["龙山区","西安区","东丰县","东辽县"],"通化市":["东昌区","二��江区","通化县","辉南县","柳河县","梅河口市","集安市"],"白山市":["浑江区","江源区","抚松县","靖宇县","长白朝鲜族自治县","临江市"],"松原市":["宁江区","前郭尔罗斯蒙古族自治县","长岭县","乾安县","吉林松原经济开发区","扶余市"],"白城市":["洮北区","镇赉县","通榆县","吉林白城经济开发区","洮南市","大安市"],"延边朝鲜族自治州":["延吉市","图们市","敦化市","珲春市","龙井市","和龙市","汪清县","安图县"]},"黑龙江省":{"哈尔滨市":["道里区","南岗区","道外区","平房区","松北区","香坊区","呼兰区","阿城区","双城区","依兰县","方正县","宾县","巴彦县","木兰县","通河县","延寿县","尚志市","五常市"],"齐齐哈尔市":["龙沙区","建华区","铁锋区","昂昂溪区","富拉尔基区","碾子山区","梅里斯达斡尔族区","龙江县","依安县","泰来县","甘南县","富裕县","���山县","克东县","拜泉县","讷河市"],"鸡西市":["鸡冠区","恒山区","滴道区","梨树区","城子河区","麻山区","鸡东县","虎林市","密山市"],"鹤岗市":["向阳区","工农区","南山区","兴安区","东山区","兴山区","萝北县","绥滨县"],"双鸭山市":["尖山区","岭东区","四方台区","宝山区","集贤县","友谊县","宝清县","饶河县"],"大庆市":["萨尔图区","龙凤区","让胡路区","红岗区","大同区","肇州县","肇源县","林甸县","杜尔伯特蒙古族自治县","大庆高新技术产业开发区"],"伊春市":["伊美区","乌翠区","友好区","嘉荫县","汤旺县","丰林县","大箐山县","南岔县","金林区","铁力市"],"佳木斯市":["向阳区","前进区","东风区","郊区","桦南县","桦川县","汤原县","同江市","富锦市","抚远市"],"七台河市":["新兴区","桃山区","茄子河区","勃利县"],"牡丹江市":["东安区","阳明区","爱民区","西安区","林口县","绥芬河市","海林市","宁安市","穆棱市","东宁市"],"黑河市":["爱辉区","逊克县","孙吴县","北安市","五大连池市","嫩江市"],"绥化市":["北林区","望奎县","兰西县","青冈县","庆安县","明水县","绥棱县","安达市","肇东市","海伦市"],"大兴安岭地区":["漠河市","呼玛县","塔河县","加格达奇区","松岭区","新林区","呼中区"]},"上海市":{"市辖区":["黄浦区","徐汇区","长宁区","静安区","普陀区","虹口区","杨浦区","闵行区","宝山区","嘉定区","浦东新区","金山区","松江区","青浦区","奉贤区","崇明区"]},"江苏省":{"南京市":["玄武区","秦淮区","建邺区","鼓楼区","浦口区","栖霞区","雨花台区","江宁区","六合区","溧水区","高淳区"],"无锡市":["锡山区","惠山区","滨湖区","梁溪区","新吴区","江阴市","宜兴市"],"徐州市":["鼓楼区","云龙区","贾汪区","泉山区","铜山区","丰县","沛县","睢宁县","徐州经济技术开发区","新沂市","邳州市"],"常州市":["天宁区","钟楼区","新北区","武进区","金坛区","溧阳市"],"苏州市":["虎丘区","吴中区","相城区","姑苏区","吴江区","苏州工业园区","常熟市","张家港市","昆山市","太仓市"],"南通市":["通州区","崇川区","海门区","如东县","南通经济技术开发区","启东市","如皋市","海安市"],"连云港市":["连云区","海州区","赣榆区","东海县","灌云县","灌南县","连云港经济技术开发区"],"淮安市":["淮安区","淮阴区","清江浦区","洪泽区","涟水县","盱眙县","金湖县","淮安经济技术开发区"],"盐城市":["亭湖区","盐都区","大丰区","响水县","滨海县","阜宁县","射阳县","建湖县","盐城经济技术开发区","东台市"],"扬州市":["广陵区","邗江区","江都区","宝应县","扬州经济技术开发区","仪征市","高邮市"],"镇江市":["京口区","润州区","丹徒区","镇江新区","丹阳市","扬中市","句容市"],"泰州市":["海陵区","高港区","姜堰区","兴化市","靖江市","泰兴市"],"宿迁市":["宿城区","宿豫区","沭阳县","泗阳县","泗洪县","宿迁经济技术开发区"]},"浙江省":{"杭州市":["上城区","拱墅区","西湖区","滨江区","萧山区","余杭区","富阳区","临安区","临平区","钱塘区","桐庐县","淳安县","建德市"],"宁波市":["海曙区","江北区","北仑区","镇海区","鄞州区","奉化区","象山县","宁海县","余姚市","慈溪市"],"温州市":["鹿城区","龙湾区","瓯海区","洞头区","��嘉县","平阳县","苍南县","文成县","泰顺县","瑞安市","乐清市","龙港市"],"嘉兴市":["南湖区","秀洲区","嘉善县","海盐县","海宁市","平湖市","桐乡市"],"湖州市":["吴兴区","南浔区","德清县","长兴县","安吉县"],"绍兴市":["越城区","柯桥区","上虞区","新昌县","诸暨市","嵊州市"],"金华市":["婺城区","金东区","武义县","浦江县","磐安县","兰溪市","义���市","东阳市","永康市"],"衢州市":["柯城区","衢江区","常山县","开化县","龙游县","江山市"],"舟山市":["定海区","普陀区","岱山县","嵊泗县"],"台州市":["椒江区","黄岩区","路桥区","三门县","天台县","仙居县","温岭市","临海市","玉环市"],"丽水市":["莲都区","青田县","缙云县","遂昌县","松阳县","云和县","庆元县","景宁畲族自治县","龙泉市"]},"安徽省":{"合肥市":["瑶海区","庐阳区","蜀山区","包河区","长丰县","肥东县","肥西县","庐江县","合肥高新技术产业开发区","合肥经济技术开发区","合肥新站高新技术产业开发区","巢湖市"],"芜湖市":["镜湖区","鸠江区","弋江区","湾沚区","繁昌区","南陵县","芜湖经济技术开发区","安徽芜湖三山经济开发区","无为市"],"蚌埠市":["龙子湖区","蚌山区","禹会区","淮上区","怀远县","五河县","固镇县","蚌埠市高新技术开发区","蚌埠��经济开发区"],"淮南市":["大通区","田家庵区","谢家集区","八公山区","潘集区","凤台县","寿县"],"马鞍山市":["花山区","雨山区","博望区","当涂县","含山县","和县"],"淮北市":["杜集区","相山区","烈山区","濉溪县"],"铜陵市":["铜官区","义安区","郊区","枞阳县"],"安庆市":["迎江区","大观区","宜秀区","怀宁县","太湖县","宿松县","望江县","岳西县","安徽安庆经济开发区","桐城市","潜山市"],"黄山市":["屯溪区","黄山区","徽州区","歙县","休宁县","黟县","祁门县"],"滁州市":["琅琊区","南谯区","来安县","全椒县","定远县","凤阳县","中新苏滁高新技术产业开发区","滁州经济技术开发区","天长市","明光市"],"阜阳市":["颍州区","颍东区","颍泉区","临泉县","太和县","阜南县","颍上县","阜阳合肥现代产业园区","阜阳经济技术开发区","界首市"],"宿州市":["埇桥区","砀山县","萧县","灵璧县","泗县","宿州马鞍山现代产业园区","宿州经济技术开发区"],"六安市":["金安区","裕安区","叶集区","霍邱县","舒城县","金寨县","霍山县"],"亳州市":["谯城区","涡阳县","蒙城县","利辛县"],"池州市":["贵池区","东至县","石台县","青阳县"],"宣城市":["宣州区","郎溪县","泾县","绩溪县","旌德县","宣城市经济开发区","宁国市","广德市"]},"福建省":{"福州市":["鼓楼区","台江区","仓山区","马尾区","晋安区","长乐区","闽侯县","连江县","罗源县","闽清县","永泰县","平潭县","福清市"],"厦门市":["思明区","海沧区","湖里区","集美区","同安区","翔安区"],"莆田市":["城厢区","涵江区","荔城区","秀屿区","仙游县"],"三明市":["三元区","沙县区","明溪县","清流县","宁化县","大田县","尤溪县","将乐县","泰宁县","建宁县","永安市"],"泉州市":["鲤城区","丰泽区","洛江区","泉港区","惠安县","安溪县","永春县","德化县","金门县","石狮市","晋江市","南安市"],"漳州市":["芗城区","龙文区","龙海区","长泰区","云霄县","漳浦县","诏安县","东山县","南靖县","平和县","华安县"],"南平市":["延平区","建阳区","顺昌县","浦城县","光泽县","松溪县","政和县","邵武市","武夷山市","建瓯市"],"龙岩市":["新罗区","永定区","长汀县","上杭县","武平县","连城县","漳平市"],"宁德市":["蕉城区","霞浦县","古田县","屏南县","寿宁县","周宁县","柘荣县","福安市","福鼎市"]},"江西省":{"南昌市":["东湖区","西湖区","青云谱区","青山湖区","新建区","红谷滩区","南昌县","安义县","进贤县"],"景德镇市":["昌江区","珠山区","浮梁县","乐平市"],"萍乡市":["安源区","湘东区","莲花县","上栗县","芦溪县"],"九江市":["濂溪区","浔阳区","柴桑区","武宁县","修水县","永修县","德安县","都昌县","湖口县","彭泽县","瑞昌市","共青城市","庐山市"],"新余市":["渝水区","分宜县"],"鹰潭市":["月湖区","余江区","贵溪市"],"赣州市":["章贡区","南康区","赣县区","信丰县","大余县","上犹县","崇义县","安远县","定南县","全南县","宁都县","于都县","兴国县","会昌县","寻乌县","石城县","瑞金市","龙南市"],"吉安市":["吉州区","青原区","吉安县","吉水县","峡江县","新干县","永丰县","泰和县","遂川县","万安县","安福县","永新县","井冈山市"],"宜春市":["袁州区","奉新县","万载县","上高县","宜丰县","靖安县","铜鼓县","丰城市","樟树市","高安市"],"抚州市":["临川区","东乡区","南城县","黎川县","南丰县","崇仁县","乐安县","宜黄县","金溪县","资溪县","广昌县"],"上饶市":["信州区","广丰区","广信区","玉山县","铅山县","横峰县","弋阳县","余干县","鄱阳县","万年县","婺源县","德兴市"]},"山东省":{"济南市":["历下区","市中区","槐荫区","天桥区","历城区","长清区","章丘区","济阳区","莱芜区","钢城区","平阴县","商河县","济南高新技术产业开发区"],"青岛市":["市南区","市北区","黄岛区","崂山区","李沧区","城阳区","即墨区","胶州市","平度市","莱西市"],"淄博市":["淄川区","张店区","博山区","临淄区","周村区","桓台县","高青县","沂源县"],"枣庄市":["市中区","薛城区","峄城区","台儿庄区","山亭区","滕州市"],"东营市":["东营区","河口区","垦利区","利津县","广饶县","东营经济技术开发区","东营港经济开发区"],"烟台市":["芝罘区","福山区","牟平区","莱山区","蓬莱区","烟台高新技术产业开发区","烟台经济技术开发区","龙口市","莱阳市","莱州市","招远市","栖霞市","海阳市"],"潍坊市":["潍城区","寒亭区","坊子区","奎文区","临朐县","昌乐县","潍坊滨海经济技术开发区","青州市","诸城市","寿光市","安丘市","高密市","昌邑市"],"济宁市":["任城区","兖州区","微山县","鱼台县","金乡县","嘉祥县","汶上县","泗水县","梁山县","济宁高新技术产业开发区","曲阜市","邹城市"],"泰安市":["泰山区","岱岳区","宁阳县","东平县","新泰市","肥城市"],"威海市":["环翠区","文登区","威海火炬高技术产业开发区","威海经济技术开发区","威海临港经济技术开发区","荣成市","乳山市"],"日照市":["东港区","岚山区","五莲县","莒县","日照经济技术开发区"],"临沂市":["兰山区","罗庄区","河东区","沂南县","郯城县","沂水县","兰陵县","费县","平邑县","莒南县","蒙阴县","临沭县","临沂高新技术产业开发区"],"德州市":["德城区","陵城区","宁津县","庆云县","临邑县","齐河县","平原县","夏津县","武城县","德州天衢新区","乐陵市","禹城市"],"聊城市":["东昌府区","茌平区","阳谷县","莘县","东阿县","冠县","高唐县","临清市"],"滨州市":["滨城区","沾化区","惠民县","阳信县","无棣县","博兴县","邹平市"],"菏泽市":["牡丹区","定陶区","曹县","单县","成武县","巨野县","郓城县","鄄城县","东明县","菏泽经济技术开发区","菏泽高新技术开发区"]},"河南省":{"郑州市":["中原区","二七区","管城回族区","金水区","上街区","惠济区","中牟县","郑州经济技术开发区","郑州高新技术产业开发区","郑州航空港经济综合实验区","巩义市","荥阳市","新密市","新郑市","登封市"],"开封市":["龙亭区","顺河回族区","鼓楼区","禹王台区","祥符区","杞县","通许县","尉氏县","兰考县"],"洛阳市":["老城区","西工区","瀍河回族区","涧西区","偃师区","孟津区","洛龙区","新安县","栾川县","嵩县","汝阳县","宜阳县","洛宁县","伊川县","洛阳高新技术产业开发区"],"平顶山市":["新华区","卫东区","石龙区","湛河区","宝丰县","叶县","鲁山县","郏县","平顶山高新技术产业开发区","平顶山市城乡一体化示范区","舞钢市","汝州市"],"安阳市":["文峰区","北关区","殷都区","龙安区","安阳县","汤阴县","滑县","内黄县","安阳高新技术产业开发区","林州市"],"鹤壁市":["鹤山区","山城区","淇滨区","浚县","淇县","鹤壁经济技术开发区"],"新乡市":["红旗���","卫滨区","凤泉区","牧野区","新乡县","获嘉县","原阳县","延津县","封丘县","新乡高新技术产业开发区","新乡经济技术开发区","新乡市平原城乡一体化示范区","卫辉市","辉县市","长垣市"],"焦作市":["解放区","中站区","马村区","山阳区","修武县","博爱县","武陟县","温县","焦作城乡一体化示范区","沁阳市","孟州市"],"濮阳市":["华龙区","清丰县","南乐县","范县","台前县","濮阳县","河南濮阳工业园区","濮阳经济技术开发区"],"许昌市":["魏都区","建安区","鄢陵县","襄城县","许昌经济技术开发区","禹州市","长葛市"],"漯河市":["源汇区","郾城区","召陵区","舞阳县","临颍县","漯河经济技术开发区"],"三门峡市":["湖滨区","陕州区","渑池县","卢氏县","河南三门峡经济开发区","义马市","灵宝市"],"南阳市":["宛城区","卧龙区","南召县","方城县","西峡县","镇平县","内乡县","淅川县","社旗县","唐河县","新野县","桐柏县","南阳高新技术产业开发区","南阳市城乡一体化示范区","邓州市"],"商丘市":["梁园区","睢阳区","民权县","睢县","宁陵县","柘城县","虞城县","夏邑县","豫东综合物流产业聚集区","河南商丘经济开发区","永城市"],"信阳市":["浉河区","平桥区","罗山县","光山县","新县","商城县","固始县","潢川县","淮滨县","息县","信阳高新技术产业开发区"],"周口市":["川汇区","淮阳区","扶沟县","西华县","商水县","沈丘县","郸城县","太康县","鹿邑县","周口临港开发区","项城市"],"驻马店市":["驿城区","西平县","上蔡县","平舆县","正阳县","确山县","泌阳县","汝南县","遂平县","新蔡县","河南驻马店经济开发区"],"省直辖县级行政区划":["济源市"]},"湖北省":{"武汉市":["江岸区","江汉区","硚口区","汉阳区","武昌区","青山区","洪山区","东西湖区","汉南区","蔡甸区","江夏区","黄陂区","新洲区"],"黄石市":["黄石港区","西塞山区","下陆区","铁山区","阳新县","大冶市"],"十堰市":["茅箭区","张湾区","郧阳区","郧西县","竹山县","竹溪县","房县","丹江口市"],"宜昌市":["西陵区","伍家岗区","点军区","猇亭区","夷陵区","远安县","兴山县","秭归县","长阳土家族自治县","五峰土家族自治县","宜都市","当阳市","枝江市"],"襄阳市":["襄城区","樊城区","襄州区","南漳县","谷城县","保康县","老河口市","枣阳市","宜城市"],"鄂州市":["梁子湖区","华容区","鄂城区"],"荆门市":["东宝区","掇刀区","沙洋县","钟祥市","京山市"],"孝感市":["孝南区","孝昌县","大悟县","云梦县","应城市","安陆市","汉川市"],"荆州市":["沙市区","荆州区","公安县","江陵县","荆州经济技术开发区","石首市","洪湖市","松滋市","监利市"],"黄冈市":["黄州区","团风县","红安县","罗田县","英山县","浠水县","蕲春县","黄梅县","龙感湖管理区","麻城市","武穴市"],"咸宁市":["咸安区","嘉鱼县","通城县","崇阳县","通山县","赤壁市"],"随州市":["曾都区","随县","广水市"],"恩施土家族苗族自治州":["恩施市","利川市","建始县","巴东县","宣恩县","咸丰县","来凤县","鹤峰县"],"省直辖县级行政区划":["仙桃市","潜江市","天门市","神农架林区"]},"湖南省":{"长沙市":["芙蓉区","天心区","岳麓区","开福区","雨花区","望城区","长沙县","浏阳市","宁乡市"],"株洲市":["荷塘区","芦淞区","石峰区","天元区","渌口区","攸县","茶陵县","炎陵县","醴陵市"],"湘潭市":["雨湖区","岳塘区","湘潭县","湖南湘潭高新技术产业园区","湘潭昭山示范区","湘潭九华示范区","湘乡市","韶山市"],"衡阳市":["珠晖区","雁峰区","石鼓区","蒸湘区","南岳区","衡阳县","衡南县","衡山县","衡东县","祁东县","湖南衡阳松木经济开发区","湖南衡阳高新技术产业园区","耒阳市","常宁市"],"邵阳市":["双清区","大祥区","北塔区","新邵县","邵阳县","隆回县","洞口县","绥宁县","新宁县","城步苗族自治县","武冈市","邵东市"],"岳阳市":["岳阳楼区","云溪区","君山区","岳阳县","华容县","湘阴县","平江县","岳阳市屈原管理区","汨罗市","临湘市"],"常德市":["武陵区","鼎城区","安乡县","汉寿县","澧县","临澧县","桃源县","石门县","常德市西洞庭管理区","津市市"],"张家界市":["永定区","武陵源区","慈利县","桑植县"],"益阳市":["资阳区","赫山区","南县","桃江县","安化县","益阳市大通湖管理区","湖南益阳高新技术产业园区","沅江市"],"郴州市":["北湖区","苏仙区","桂阳县","宜章县","永兴县","嘉禾县","临武县","汝城县","桂东县","安仁县","资兴市"],"永州市":["零陵区","冷水滩区","东安县","双牌县","道县","江永县","宁远县","蓝山县","新田县","江华瑶族自治县","永州经济技术开发区","永州市回龙圩管理区","祁阳市"],"怀化市":["鹤城区","中方县","沅陵县","辰溪县","溆浦县","会同县","麻阳苗族自治县","新晃侗族自治县","芷江侗族自治县","靖州苗族侗族自治县","通道侗族自治县","怀化市洪江管理区","洪江市"],"娄底市":["娄星区","双峰县","新化县","冷水江市","涟源市"],"湘西土家族苗族自治州":["吉首市","泸溪县","凤凰县","花垣县","保靖县","古丈县","永顺县","龙山县"]},"广东省":{"广州市":["荔湾区","越秀区","海珠区","天河区","白云区","黄埔区","番禺区","花都区","南沙区","从化区","增城区"],"韶关市":["武江区","浈江区","曲江区","始兴县","仁化县","翁源县","乳源瑶族自治县","新丰县","乐昌市","南雄市"],"深圳市":["罗湖区","福田区","南山区","宝安区","龙岗区","盐田区","龙华区","坪山区","光明区"],"珠海市":["香洲区","斗门区","金湾区"],"汕头市":["龙湖区","金平区","濠江区","潮阳区","潮南区","澄海区","南澳县"],"佛山市":["禅城区","南海区","顺德区","三水区","高明区"],"江门市":["蓬江区","江海区","新会区","台山市","开平市","鹤山市","恩平市"],"湛江市":["赤坎区","霞山区","坡头区","麻章区","遂溪县","徐闻县","廉江市","雷州市","吴川市"],"茂名市":["茂南区","电白区","高州市","化州市","信宜市"],"肇庆市":["端州区","鼎湖区","高要区","广宁县","怀集县","封开县","德庆县","四会市"],"惠州市":["惠城区","惠阳区","博罗县","惠东县","龙门县"],"梅州市":["梅江区","梅县区","大埔县","丰顺县","五华县","平远县","蕉岭县","兴宁市"],"汕尾市":["城区","海丰县","陆河县","陆丰市"],"河源市":["源城区","紫金县","龙川县","连平县","和平县","东源县"],"阳江市":["江城区","阳东区","阳西县","阳春市"],"清远市":["清城区","清新区","佛冈县","阳山县","连山壮族瑶族自治县","连南瑶族自治县","英德市","连州市"],"东莞市":["东城街道","南城街道","万江街道","莞城街道","石碣镇","石龙镇","茶山镇","石排镇","企石镇","横沥镇","桥头镇","谢岗镇","东坑镇","常平镇","寮步镇","樟木头镇","大朗镇","黄江镇","清溪镇","塘厦镇","凤岗镇","大岭山镇","长安镇","虎门镇","厚街镇","沙田镇","道滘镇","洪梅镇","麻涌镇","望牛墩镇","中堂镇","高埗镇","松山湖","东莞港","东莞生态园","东莞滨海湾新区"],"中山市":["石岐街道","东区街道","中山港街道","西区街道","南区街道","五桂山街道","民众街道","南朗街道","黄圃镇","东凤镇","古镇镇","沙溪镇","坦洲镇","港口镇","三角镇","横栏镇","南头镇","阜沙镇","三乡镇","板芙镇","大涌镇","神湾镇","小榄镇"],"潮州市":["湘桥区","潮安区","饶平县"],"揭阳市":["榕城区","揭东区","揭西县","惠来县","普宁市"],"云浮市":["云城区","云安区","新兴县","郁南县","罗定市"]},"广西壮族自治区":{"南宁市":["兴宁区","青秀区","江南区","西乡塘区","良庆区","邕宁区","武鸣区","隆安县","马山县","上林县","宾阳县","横州市"],"柳州市":["城中区","鱼峰区","柳南区","柳北区","柳江区","柳城县","鹿寨县","融安县","融水苗族自治县","三江侗族自治县"],"桂林市":["秀峰区","叠彩区","象山区","七星区","雁山区","临桂区","阳朔县","灵川县","全州县","兴安县","永福县","灌阳县","龙胜各族自治县","资源县","平乐县","恭城瑶族自治县","荔浦市"],"梧州市":["万秀区","长洲区","龙圩区","苍梧县","藤县","蒙山县","岑溪市"],"北海市":["海城区","银海区","铁山港区","合浦县"],"防城港市":["港口区","防城区","上思县","东兴市"],"钦州市":["钦南区","钦北区","灵山县","浦北县"],"贵港市":["港北区","港南区","覃塘区","平南县","桂平市"],"玉林市":["玉州区","福绵区","容县","陆川县","博白县","兴业县","北流市"],"百色市":["右江区","田阳区","田东县","德保县","那坡县","凌云县","乐业县","田林县","西林县","隆林各族自治县","靖西市","平果市"],"贺州市":["八步区","平桂区","昭平县","钟山县","富川瑶族自治县"],"河池市":["金城江区","宜州区","南丹县","天峨县","凤山县","东兰县","罗城仫佬族自治县","环江毛南族自治县","巴马瑶族自治县","都安瑶族自治县","大化瑶族自治县"],"来宾市":["兴宾区","忻城县","象州县","武宣县","金秀瑶族自治县","合山市"],"崇左市":["江州区","扶绥县","宁明县","龙州县","大新县","天等县","凭祥市"]},"海南省":{"海口市":["秀英区","龙华区","琼山区","美兰区"],"三亚市":["海棠区","吉阳区","天涯区","崖州区"],"三沙市":["西沙群岛","南沙群岛","中沙群岛的岛礁及其海域"],"儋州市":["那大镇","和庆镇","南丰镇","大成镇","雅星镇","兰洋镇","光村镇","木棠镇","海头镇","峨蔓镇","王五镇","白马井镇","中和镇","排浦镇","东成镇","新州镇","洋浦经济开发区","华南热作学院"],"省直辖县级行政区划":["五指山市","琼海市","文昌市","万宁市","东方市","定安县","屯昌县","澄迈县","临高县","白沙黎族自治县","昌江黎族自治县","乐东黎族自治县","陵水黎族自治县","保亭黎族苗族自治县","琼中黎族苗族自治县"]},"重庆市":{"市辖区":["万州区","涪陵区","渝中区","大渡口区","江北区","沙坪坝区","九龙坡区","南岸区","北碚区","綦江区","大足区","渝北区","巴南区","黔江区","长寿区","江津区","合川区","永川区","南川区","璧山区","铜梁区","潼南区","荣昌区","开州区","梁平区","武隆区"],"县":["城口县","丰都县","垫江县","忠县","云阳县","奉节县","巫山县","巫溪县","石柱土家族自治县","秀山土家族苗族自治县","酉阳土家族苗族自治县","彭水苗族土家族自治县"]},"四川省":{"成都市":["锦江区","青羊区","金牛区","武侯区","成华区","龙泉驿区","青白江区","新都区","温江区","双流区","郫都区","新津区","金堂县","大邑县","蒲江县","都江堰市","彭州市","邛崃市","崇州市","简阳市"],"自贡市":["自流井区","贡井区","大安区","沿滩区","荣县","富顺县"],"攀枝花市":["东区","西区","仁和区","米易县","盐边县"],"泸州市":["江阳区","纳溪区","龙马潭区","泸县","合江县","叙永县","古蔺县"],"德阳市":["旌阳区","罗江区","中江县","广汉市","什邡市","绵竹市"],"绵阳市":["涪城区","游仙区","安州区","三台县","盐亭县","梓潼县","北川羌族自治县","平武县","江油市"],"广元市":["利州区","昭化区","朝天区","旺苍县","青川县","剑阁县","苍溪县"],"遂宁市":["船山区","安居区","蓬溪县","大英县","射洪市"],"内江市":["市中区","东兴区","威远县","资中县","隆昌市"],"乐山市":["市中区","沙湾区","五通桥区","金口河区","犍为县","井研县","夹江县","沐川县","峨边彝族自治县","马边彝族自治县","峨眉山市"],"南充市":["顺庆区","高坪区","嘉陵区","南部县","营山县","蓬安县","仪陇县","西充县","阆中市"],"眉山市":["东坡区","彭山区","仁寿县","洪雅县","丹棱县","青神县"],"宜宾市":["翠屏区","南溪区","叙州区","江安县","长宁县","高县","珙县","筠连县","兴文县","屏山县"],"广安市":["广安区","前锋区","岳池县","武胜县","邻水县","华蓥市"],"达州市":["通川区","达川区","宣汉县","开江县","大竹县","渠县","万源市"],"雅安市":["雨城区","名山区","荥经县","汉源县","石棉县","天全县","芦山县","宝兴县"],"巴中市":["巴州区","恩阳区","通江县","南江县","平昌县"],"资阳市":["雁江区","安岳县","乐至县"],"阿坝藏族羌族自治州":["马尔康市","汶川县","理县","茂县","松潘县","九寨沟县","金川县","小金县","黑水县","壤塘县","阿坝县","若尔盖县","红原县"],"甘孜藏族自治州":["康定市","泸定县","丹巴县","九龙县","雅江县","道孚县","炉霍县","甘孜县","新龙县","德格县","白玉县","石渠县","色达县","理塘县","巴塘县","乡城县","稻城县","得荣县"],"凉山彝族自治州":["西昌市","会理市","木里藏族自治县","盐源县","德昌县","会东县","宁南县","普格县","布拖县","金阳县","昭觉县","喜德县","冕宁县","越西县","甘洛县","美姑县","雷波县"]},"贵州省":{"贵阳市":["南明区","云岩区","花溪区","乌当区","白云区","观山湖区","开阳县","息烽县","修文县","清镇市"],"六盘水市":["钟山区","六枝特区","水城区","盘州市"],"遵义市":["红花岗区","汇川区","播州区","桐梓县","绥阳县","正安县","道真仡佬族苗族自治县","务川仡佬族苗族自治县","凤冈县","湄潭县","余庆县","习水县","赤水市","仁怀市"],"安顺市":["西秀区","平坝区","普定县","镇宁布依族苗族自治县","关岭布依族苗族自治县","紫云苗族布依族自治县"],"毕节市":["七星关区","大方县","金沙县","织金县","纳雍县","威宁彝族回族苗族自治县","赫章县","黔西市"],"铜仁市":["碧江区","万山区","江口县","玉屏侗族自治县","石阡县","思南县","印江土家族苗族自治县","德江县","沿河土家族自治县","松桃苗族自治县"],"黔西南布依族苗族自治州":["兴义市","兴仁市","普安县","晴隆县","贞丰县","望谟县","册亨县","安龙县"],"黔东南苗族侗族自治州":["凯里市","黄平县","施秉县","三穗县","镇远县","岑巩县","天柱县","锦屏县","剑河县","台江县","黎平县","榕江县","从江县","雷山县","麻江县","丹寨县"],"黔南布依族苗族自治州":["都匀市","福泉市","荔波县","贵定县","瓮安县","独山县","平塘县","罗甸县","长顺县","龙里县","惠水县","三都水族自治县"]},"云南省":{"昆明市":["五华区","盘龙区","官渡区","西山区","东川区","呈贡区","晋宁区","富民县","宜良县","石林彝族自治县","嵩明县","禄劝彝族苗族自治县","寻甸回族彝族自治县","安宁市"],"曲靖市":["麒麟区","沾益区","马龙区","陆良县","师宗县","罗平县","富源县","会泽县","宣威市"],"玉溪市":["红塔区","江川区","通海县","华宁县","易门县","峨山彝族自治县","新平彝族傣族自治县","元江哈尼族彝族傣族自治县","澄江市"],"保山市":["隆阳区","施甸县","龙陵县","昌宁县","腾冲市"],"昭通市":["昭阳区","鲁甸县","巧家县","盐津县","大关县","永善县","绥江县","镇雄县","彝良县","威信县","水富市"],"丽江市":["古城区","玉龙纳西族自治县","永胜县","华坪县","宁蒗彝族自治县"],"普洱市":["思茅区","宁洱哈尼族彝族自治县","墨江哈尼族自治县","景东彝族自治县","景谷傣族彝族自治县","镇沅彝族哈尼族拉祜族自治县","江城哈尼族彝族自治县","孟连傣族拉祜族佤族自治县","澜沧拉祜族自治县","西盟佤族自治县"],"临沧市":["临翔区","凤庆县","云县","永德县","镇康县","双江拉祜族佤族布朗族傣族自治县","耿马傣族佤族自治县","沧源佤族自治县"],"楚雄彝族自治州":["楚雄市","禄丰市","双柏县","牟定县","南华县","姚安县","大姚县","永仁县","元谋县","武定县"],"红河哈尼族彝族自治州":["个旧市","开远市","蒙自市","弥勒市","屏边苗族自治县","建水县","石屏县","泸西县","元阳县","红河县","金平苗族瑶族傣族自治县","绿春县","河口瑶族自治县"],"文山壮族苗族自治州":["文山市","砚山县","西畴县","麻栗坡县","马关县","丘北县","广南县","富宁县"],"西双版纳傣族自治州":["景洪市","勐海县","勐腊县"],"大理白族自治州":["大理市","漾濞彝族自治县","祥云县","宾川县","弥渡县","南涧彝族自治县","巍山彝族回族自治县","永平县","云龙县","洱源县","剑川县","鹤庆县"],"德宏傣族景颇族自治州":["瑞丽市","芒市","梁河县","盈江县","陇川县"],"怒江傈僳族自治州":["泸水市","福贡县","贡山独龙族怒族自治县","兰坪白族普米族自治县"],"迪庆藏族自治州":["香格里拉市","德钦县","维西傈僳族自治县"]},"西藏自治区":{"拉萨市":["城关区","堆龙德庆区","达孜区","林周县","当雄县","尼木县","曲水县","墨竹工卡县","格尔木藏青工业园区","拉萨经济技术开发区","西藏文化旅游创意园区","达孜工业园区"],"日喀则市":["桑珠孜区","南木林县","江孜县","定日县","萨迦县","拉孜县","昂仁县","谢通门县","白朗县","仁布县","康马县","定结县","仲巴县","亚东县","吉隆县","聂拉木县","萨嘎县","岗巴县"],"昌都市":["卡若区","江达县","贡觉县","类乌齐县","丁青县","察雅县","八宿县","左贡县","芒康县","洛隆县","边坝县"],"林芝市":["巴宜区","工布江达县","墨脱县","波密县","察隅县","朗县","米林市"],"山南市":["乃东区","扎囊县","贡嘎县","桑日县","琼结县","曲松县","措美县","洛扎县","加查县","隆子县","浪卡子县","错那市"],"那曲市":["色尼区","嘉黎县","比如县","聂荣县","安多县","申扎县","索县","班戈县","巴青县","尼玛县","双湖县"],"阿里地区":["普兰县","札达县","噶尔县","日土县","革吉县","改则县","措勤县"]},"陕西省":{"西安市":["新城区","碑林区","莲湖区","灞桥区","未央区","雁塔区","阎良区","临潼区","长安区","高陵区","鄠邑区","蓝田县","周至县"],"铜川市":["王益区","印台区","耀州区","宜君县"],"宝鸡市":["渭滨区","金台区","陈仓区","凤翔区","岐山县","扶风县","眉县","陇县","千阳县","麟游县","凤县","太白县"],"咸阳市":["秦都区","杨陵区","渭城区","三原县","泾阳县","乾县","礼泉县","永寿县","长武县","旬邑县","淳化县","武功县","兴平市","彬州市"],"渭南市":["临渭区","华州区","潼关县","大荔县","合阳县","澄城县","蒲城县","白水县","富平县","韩城市","华阴市"],"延安市":["宝塔区","安塞区","延长县","延川县","志丹县","吴起县","甘泉县","富县","洛川县","宜川县","黄龙县","黄陵县","子长市"],"汉中市":["汉台区","南郑区","城固县","洋县","西乡县","勉县","宁强县","略阳县","镇巴县","留坝县","佛坪县"],"榆林市":["榆阳区","横山区","府谷县","靖边县","定边县","绥德县","米脂县","佳县","吴堡县","清涧县","子洲县","神木市"],"安康市":["汉滨区","汉阴县","石泉县","宁陕县","紫阳县","岚皋县","平利县","镇坪县","白河县","旬阳市"],"商洛市":["商州区","洛南县","丹凤县","商南县","山阳县","镇安县","柞水县"]},"甘肃省":{"兰州市":["城关区","七里河区","西固区","安宁区","红古区","永登县","皋兰县","榆中县","兰州新区"],"嘉峪关市":["雄关街道","钢城街道","新城镇","峪泉镇","文殊镇"],"金昌市":["金川区","永昌县"],"白银市":["白银区","平川区","靖远县","会宁县","景泰县"],"天水市":["秦州区","麦积区","清水县","秦安县","甘谷县","武山县","张家川回族自治县"],"武威市":["凉州区","民勤县","古浪县","天祝藏族自治县"],"张掖市":["甘州区","肃南裕固族自治县","民乐县","临泽县","高台县","山丹县"],"平凉市":["崆峒区","泾川县","灵台县","崇信县","庄浪县","静宁县","华亭市"],"酒泉市":["肃州区","金塔县","瓜州县","肃北蒙古族自治县","阿克塞哈萨克族自治县","玉门市","敦煌市"],"庆阳市":["西峰区","庆城县","环县","华池县","合水县","正宁县","宁县","镇原县"],"定西市":["安定区","通渭县","陇西县","渭源县","临洮县","漳县","岷县"],"陇南市":["武都区","成县","文县","宕昌县","康县","西和县","礼县","徽县","两当县"],"临夏回族自治州":["临夏市","临夏县","康乐县","永靖县","广河县","和政县","东乡族自治县","积石山保安族东乡族撒拉族自治县"],"甘南藏族自治州":["合作市","临潭县","卓尼县","舟曲县","迭部县","玛曲县","碌曲县","夏河县"]},"青海省":{"西宁市":["城东区","城中区","城西区","城北区","湟中区","大通回族土族自治县","湟源县"],"海东市":["乐都区","平安区","民和回族土族自治县","互助土族自治县","化隆回族自治县","循化撒拉族自治县"],"海北藏族自治州":["门源回族自治县","祁连县","海晏县","刚察县"],"黄南藏族自治州":["同仁市","尖扎县","泽库县","河南蒙古族自治县"],"海南藏族自治州":["共和县","同德县","贵德县","兴海县","贵南县"],"果洛藏族自治州":["玛沁县","班玛县","甘德县","达日县","久治县","玛多县"],"玉树藏族自治州":["玉树市","杂多县","称多县","治多县","囊谦县","曲麻莱县"],"海西蒙古族藏族自治州":["格尔木市","德令哈市","茫崖市","乌兰县","都兰县","天峻县","大柴旦行政委员会"]},"宁夏回族自治区":{"银川市":["兴庆区","西夏区","金凤区","永宁县","贺兰县","灵武市"],"石嘴山市":["大武口区","惠农区","平罗县"],"吴忠市":["利通区","红寺堡区","盐池县","同心县","青铜峡市"],"固原市":["原州区","西吉县","隆德县","泾源县","彭阳县"],"中卫市":["沙坡头区","中宁县","海原县"]},"新疆维吾尔自治区":{"乌鲁木齐市":["天山区","沙依巴克区","新市区","水磨沟区","头屯河区","达坂城区","米东区","乌鲁木齐县"],"克拉玛依市":["独山子区","克拉玛依区","白碱滩区","乌尔禾区"],"吐鲁番市":["高昌区","鄯善县","托克逊县"],"哈密市":["伊州区","巴里坤哈萨克自治县","伊吾县"],"昌吉回族自治州":["昌吉市","阜康市","呼图壁县","玛纳斯县","奇台县","吉木萨尔县","木垒哈萨克自治县"],"博尔塔拉蒙古自治州":["博乐市","阿拉山口市","精河县","温泉县"],"巴音郭楞蒙古自治州":["库尔勒市","轮台县","尉犁县","若羌县","且末县","焉耆回族自治县","和静县","和硕县","博湖县"],"阿克苏地区":["阿克苏市","库车市","温宿县","沙雅县","新和县","拜城县","乌什县","阿瓦提县","柯坪县"],"克孜勒苏柯尔克孜自治州":["阿图什市","阿克陶县","阿合奇县","乌恰县"],"喀什地区":["喀什市","疏附县","疏勒县","英吉沙县","泽普县","莎车县","叶城县","麦盖提县","岳普湖县","伽师县","巴楚县","塔什库尔干塔吉克自治县"],"和田地区":["和田市","和田县","墨玉县","皮山县","洛浦县","策勒县","于田县","民丰县"],"伊犁哈萨克自治州":["伊宁市","奎屯市","霍尔果斯市","伊宁县","察布查尔锡伯自治县","霍城县","巩留县","新源县","昭苏县","特克斯县","尼勒克县"],"塔城地区":["塔城市","乌苏市","沙湾市","额敏县","托里县","裕民县","和布克赛尔蒙古自治县"],"阿勒泰地区":["阿勒泰市","布尔津县","富蕴县","福海县","哈巴河县","青河县","吉木乃县"],"自治区直辖县级行政区划":["石河子市","阿拉尔市","图木舒克市","五家渠市","北屯市","铁门关市","双河市","可克达拉市","昆玉市","胡杨河市","新星市","白杨市"]}},"中国香港":{"香港特别行政区":{"香港岛":["中西区","湾仔区","东区","南区"],"九龙":["油尖旺区","深水埗区","九龙城区","黄大仙区","观塘区"],"新界":["荃湾区","屯门区","元朗区","北区","大埔区","沙田区","西贡区","葵青区","离岛区"]}},"中国澳门":{"澳门特别行政区":{"花地玛堂区":["—"],"花王堂区":["—"],"望德堂区":["—"],"大堂区":["—"],"风顺堂区":["—"],"嘉模堂区":["—"],"圣方济各堂区":["—"],"路氹填海区":["—"]}},"中国台湾":{"台湾省":{"台北市":["中正区","大同区","中山区","松山区","大安区","万华区","信义区","士林区","北投区","内湖区","南港区","文山区"],"新北市":["板桥区","三重区","中和区","永和区","新庄区","新店区","树林区","莺歌区","三峡区","淡水区","汐止区","瑞芳区","土城区","芦洲区","五股区","泰山区","林口区"],"桃园市":["桃园区","中坜区","平镇区","八德区","杨梅区","芦竹区","大溪区","龙潭区","龟山区","大园区","观音区","新屋区","复兴区"],"台中市":["中区","东区","南区","西区","北区","北屯区","西屯区","南屯区","太平区","大里区","雾峰区","乌日区","丰原区","后里区","石冈区","东势区","和平区","新社区","潭子区","大雅区","神冈区","大肚区","沙鹿区","龙井区","梧栖区","清水区","大甲区","外埔区","大安区"],"台南市":["中西区","东区","南区","北区","安平区","安南区","永康区","归仁区","新化区","左镇区","玉井区","楠西区","南化区","仁德区","关庙区","龙崎区","官田区","麻豆区","佳里区","西港区","七股区","将军区","学甲区","北门区","新营区","后壁区","白河区","东山区","六甲区","下营区","柳营区","盐水区","大内区","山上区","新市区","安定区"],"高雄市":["新兴区","前金区","苓雅区","盐埕区","鼓山区","旗津区","前镇区","三民区","楠梓区","小港区","左营区","仁武区","大社区","冈山区","路竹区","阿莲区","田寮区","燕巢区","桥头区","梓官区","弥陀区","永安区","湖内区","凤山区","大寮区","林园区","鸟松区","大树区","旗山区","美浓区","六龟区","内门区","杉林区","甲仙区","桃源区","那玛夏区","茂林区","茄萣区"],"基隆市":["仁爱区","信义区","中正区","中山区","安乐区","暖暖区","七堵区"],"新竹市":["东区","北区","香山区"],"嘉义市":["东区","西区"],"新竹县":["竹北市","湖口乡","新丰乡","新埔镇","关西镇","芎林乡","宝山乡","竹东镇","五峰乡","横山乡","尖石乡","北埔乡","峨眉乡"],"苗栗县":["苗栗市","苑里镇","通霄镇","竹南镇","头份市","后龙镇","卓兰镇","大湖乡","公馆乡","铜锣乡","南庄乡","头屋乡","三义乡","西湖乡","造桥乡","三湾乡","狮潭乡","泰安乡"],"彰化县":["彰化市","鹿港镇","和美镇","线西乡","伸港乡","福兴乡","秀水乡","花坛乡","芬园乡","员林镇","溪湖镇","田中镇","大村乡","埔盐乡","埔心乡","永靖乡","社头乡","二水乡","北斗镇","埤头乡","溪州乡","竹塘乡","大城乡","芳苑乡","二林镇"],"南投县":["南投市","埔里镇","草屯镇","竹山镇","集集镇","名间乡","鹿谷乡","中寮乡","鱼池乡","国姓乡","水里乡","信义乡","仁爱乡"],"云林县":["斗六市","斗南镇","虎尾镇","西螺镇","土库镇","北港镇","古坑乡","大埤乡","莿桐乡","林内乡","二仑乡","仑背乡","麦寮乡","东势乡","褒忠乡","台西乡","元长乡","四湖乡","口湖乡","水林乡"],"嘉义县":["太保市","朴子市","布袋镇","大林镇","民雄乡","溪口乡","新港乡","六脚乡","东石乡","义竹乡","鹿草乡","水上乡","中埔乡","竹崎乡","梅山乡","番路乡","大埔乡","阿里山乡"],"屏东县":["屏东市","潮州镇","东港镇","恒春镇","万丹乡","长治乡","麟洛乡","九如乡","里港乡","盐埔乡","高树乡","万峦乡","内埔乡","竹田乡","新埤乡","枋寮乡","新园乡","崁顶乡","林边乡","南州乡","佳冬乡","琉球乡","车城乡","满州乡","枋山乡","三地门乡","雾台乡","玛家乡","泰武乡","来义乡","春日乡","狮子乡","牡丹乡"],"宜兰县":["宜兰市","罗东镇","苏澳镇","头城镇","礁溪乡","壮围乡","员山乡","冬山乡","五结乡","三星乡","大同乡","南澳乡"],"花莲县":["花莲市","凤林镇","玉里镇","新城乡","吉安乡","寿丰乡","光复乡","丰滨乡","瑞穗乡","富里乡","秀林乡","万荣乡","卓溪乡"],"台东县":["台东市","成功镇","关山镇","卑南乡","鹿野乡","池上乡","东河乡","长滨乡","太麻里乡","大武乡","绿岛乡","海端乡","延平乡","金峰乡","达仁乡","兰屿乡"],"澎湖县":["马公市","湖西乡","白沙乡","西屿乡","望安乡","七美乡"],"金门县":["金城镇","金湖镇","金沙镇","金宁乡","烈屿乡","乌坵乡"],"连江县":["南竿乡","北竿乡","莒光乡","东引乡"]}},"美国":{"Alabama":{"Birmingham":["—"],"Montgomery":["—"],"Mobile":["—"],"Huntsville":["—"],"Tuscaloosa":["—"]},"Alaska":{"Anchorage":["—"],"Fairbanks":["—"],"Juneau":["—"],"Sitka":["—"],"Ketchikan":["—"]},"Arizona":{"Phoenix":["—"],"Tucson":["—"],"Mesa":["—"],"Chandler":["—"],"Scottsdale":["—"]},"Arkansas":{"Little Rock":["—"],"Fort Smith":["—"],"Fayetteville":["—"],"Springdale":["—"],"Jonesboro":["—"]},"California":{"Los Angeles":["—"],"San Francisco":["—"],"San Diego":["—"],"San Jose":["—"],"Sacramento":["—"],"Oakland":["—"],"Fresno":["—"],"Long Beach":["—"]},"Colorado":{"Denver":["—"],"Colorado Springs":["—"],"Aurora":["—"],"Fort Collins":["—"],"Lakewood":["—"]},"Connecticut":{"Bridgeport":["—"],"New Haven":["—"],"Hartford":["—"],"Stamford":["—"],"Waterbury":["—"]},"Delaware":{"Wilmington":["—"],"Dover":["—"],"Newark":["—"],"Middletown":["—"],"Smyrna":["—"]},"District of Columbia":{"Washington":["—"]},"Florida":{"Jacksonville":["—"],"Miami":["—"],"Tampa":["—"],"Orlando":["—"],"St. Petersburg":["—"],"Fort Lauderdale":["—"]},"Georgia":{"Atlanta":["—"],"Augusta":["—"],"Columbus":["—"],"Savannah":["—"],"Athens":["—"]},"Hawaii":{"Honolulu":["—"],"Pearl City":["—"],"Hilo":["—"],"Kailua":["—"],"Waipahu":["—"]},"Idaho":{"Boise":["—"],"Meridian":["—"],"Nampa":["—"],"Idaho Falls":["—"],"Pocatello":["—"]},"Illinois":{"Chicago":["—"],"Aurora":["—"],"Naperville":["—"],"Joliet":["—"],"Rockford":["—"],"Springfield":["—"]},"Indiana":{"Indianapolis":["—"],"Fort Wayne":["—"],"Evansville":["—"],"South Bend":["—"],"Carmel":["—"]},"Iowa":{"Des Moines":["—"],"Cedar Rapids":["—"],"Davenport":["—"],"Sioux City":["—"],"Iowa City":["—"]},"Kansas":{"Wichita":["—"],"Overland Park":["—"],"Kansas City":["—"],"Topeka":["—"],"Olathe":["—"]},"Kentucky":{"Louisville":["—"],"Lexington":["—"],"Bowling Green":["—"],"Owensboro":["—"],"Covington":["—"]},"Louisiana":{"New Orleans":["—"],"Baton Rouge":["—"],"Shreveport":["—"],"Lafayette":["—"],"Lake Charles":["—"]},"Maine":{"Portland":["—"],"Lewiston":["—"],"Bangor":["—"],"South Portland":["—"],"Auburn":["—"]},"Maryland":{"Baltimore":["—"],"Frederick":["—"],"Rockville":["—"],"Gaithersburg":["—"],"Bowie":["—"]},"Massachusetts":{"Boston":["—"],"Worcester":["—"],"Springfield":["—"],"Cambridge":["—"],"Lowell":["—"]},"Michigan":{"Detroit":["—"],"Grand Rapids":["—"],"Warren":["—"],"Sterling Heights":["—"],"Ann Arbor":["—"],"Lansing":["—"]},"Minnesota":{"Minneapolis":["—"],"Saint Paul":["—"],"Rochester":["—"],"Duluth":["—"],"Bloomington":["—"]},"Mississippi":{"Jackson":["—"],"Gulfport":["—"],"Southaven":["—"],"Hattiesburg":["—"],"Biloxi":["—"]},"Missouri":{"Kansas City":["—"],"Saint Louis":["—"],"Springfield":["—"],"Columbia":["—"],"Independence":["—"]},"Montana":{"Billings":["—"],"Missoula":["—"],"Great Falls":["—"],"Bozeman":["—"],"Butte":["—"]},"Nebraska":{"Omaha":["—"],"Lincoln":["—"],"Bellevue":["—"],"Grand Island":["—"],"Kearney":["—"]},"Nevada":{"Las Vegas":["—"],"Henderson":["—"],"Reno":["—"],"North Las Vegas":["—"],"Sparks":["—"]},"New Hampshire":{"Manchester":["—"],"Nashua":["—"],"Concord":["—"],"Dover":["—"],"Rochester":["—"]},"New Jersey":{"Newark":["—"],"Jersey City":["—"],"Paterson":["—"],"Elizabeth":["—"],"Edison":["—"],"Trenton":["—"]},"New Mexico":{"Albuquerque":["—"],"Las Cruces":["—"],"Rio Rancho":["—"],"Santa Fe":["—"],"Roswell":["—"]},"New York":{"New York City":["—"],"Buffalo":["—"],"Rochester":["—"],"Yonkers":["—"],"Syracuse":["—"],"Albany":["—"]},"North Carolina":{"Charlotte":["—"],"Raleigh":["—"],"Greensboro":["—"],"Durham":["—"],"Winston-Salem":["—"]},"North Dakota":{"Fargo":["—"],"Bismarck":["—"],"Grand Forks":["—"],"Minot":["—"],"West Fargo":["—"]},"Ohio":{"Columbus":["—"],"Cleveland":["—"],"Cincinnati":["—"],"Toledo":["—"],"Akron":["—"],"Dayton":["—"]},"Oklahoma":{"Oklahoma City":["—"],"Tulsa":["—"],"Norman":["—"],"Broken Arrow":["—"],"Lawton":["—"]},"Oregon":{"Portland":["—"],"Eugene":["—"],"Salem":["—"],"Gresham":["—"],"Hillsboro":["—"]},"Pennsylvania":{"Philadelphia":["—"],"Pittsburgh":["—"],"Allentown":["—"],"Erie":["—"],"Reading":["—"],"Harrisburg":["—"]},"Rhode Island":{"Providence":["—"],"Warwick":["—"],"Cranston":["—"],"Pawtucket":["—"],"East Providence":["—"]},"South Carolina":{"Charleston":["—"],"Columbia":["—"],"North Charleston":["—"],"Mount Pleasant":["—"],"Greenville":["—"]},"South Dakota":{"Sioux Falls":["—"],"Rapid City":["—"],"Aberdeen":["—"],"Brookings":["—"],"Watertown":["—"]},"Tennessee":{"Nashville":["—"],"Memphis":["—"],"Knoxville":["—"],"Chattanooga":["—"],"Clarksville":["—"]},"Texas":{"Houston":["—"],"San Antonio":["—"],"Dallas":["—"],"Austin":["—"],"Fort Worth":["—"],"El Paso":["—"],"Arlington":["—"],"Corpus Christi":["—"]},"Utah":{"Salt Lake City":["—"],"West Valley City":["—"],"Provo":["—"],"West Jordan":["—"],"Orem":["—"]},"Vermont":{"Burlington":["—"],"South Burlington":["—"],"Rutland":["—"],"Barre":["—"],"Montpelier":["—"]},"Virginia":{"Virginia Beach":["—"],"Norfolk":["—"],"Chesapeake":["—"],"Richmond":["—"],"Newport News":["—"],"Alexandria":["—"]},"Washington":{"Seattle":["—"],"Spokane":["—"],"Tacoma":["—"],"Vancouver":["—"],"Bellevue":["—"],"Olympia":["—"]},"West Virginia":{"Charleston":["—"],"Huntington":["—"],"Morgantown":["—"],"Parkersburg":["—"],"Wheeling":["—"]},"Wisconsin":{"Milwaukee":["—"],"Madison":["—"],"Green Bay":["—"],"Kenosha":["—"],"Racine":["—"]},"Wyoming":{"Cheyenne":["—"],"Casper":["—"],"Laramie":["—"],"Gillette":["—"],"Rock Springs":["—"]}},"日本":{"Hokkaido":{"Sapporo":["—"],"Asahikawa":["—"],"Hakodate":["—"],"Kushiro":["—"],"Obihiro":["—"]},"Aomori":{"Aomori":["—"],"Hachinohe":["—"],"Hirosaki":["—"]},"Iwate":{"Morioka":["—"],"Ofunato":["—"],"Hanamaki":["—"]},"Miyagi":{"Sendai":["—"],"Ishinomaki":["—"],"Osaki":["—"]},"Akita":{"Akita":["—"],"Yokote":["—"],"Oga":["—"]},"Yamagata":{"Yamagata":["—"],"Tsuruoka":["—"],"Sakata":["—"]},"Fukushima":{"Fukushima":["—"],"Koriyama":["—"],"Iwaki":["—"]},"Ibaraki":{"Mito":["—"],"Tsukuba":["—"],"Hitachi":["—"]},"Tochigi":{"Utsunomiya":["—"],"Ashikaga":["—"],"Oyama":["—"]},"Gunma":{"Maebashi":["—"],"Takasaki":["—"],"Ota":["—"]},"Saitama":{"Saitama":["—"],"Kawagoe":["—"],"Kawaguchi":["—"]},"Chiba":{"Chiba":["—"],"Funabashi":["—"],"Ichikawa":["—"]},"Tokyo":{"Shinjuku":["—"],"Shibuya":["—"],"Minato":["—"],"Chiyoda":["—"],"Setagaya":["—"]},"Kanagawa":{"Yokohama":["—"],"Kawasaki":["—"],"Sagamihara":["—"]},"Niigata":{"Niigata":["—"],"Nagaoka":["—"],"Joetsu":["—"]},"Toyama":{"Toyama":["—"],"Takaoka":["—"],"Uozu":["—"]},"Ishikawa":{"Kanazawa":["—"],"Komatsu":["—"],"Hakusan":["—"]},"Fukui":{"Fukui":["—"],"Sakai":["—"],"Obama":["—"]},"Yamanashi":{"Kofu":["—"],"Fujiyoshida":["—"],"Kai":["—"]},"Nagano":{"Nagano":["—"],"Matsumoto":["—"],"Ueda":["—"]},"Gifu":{"Gifu":["—"],"Ogaki":["—"],"Takayama":["—"]},"Shizuoka":{"Shizuoka":["—"],"Hamamatsu":["—"],"Numazu":["—"]},"Aichi":{"Nagoya":["—"],"Toyohashi":["—"],"Okazaki":["—"]},"Mie":{"Tsu":["—"],"Yokkaichi":["—"],"Suzuka":["—"]},"Shiga":{"Otsu":["—"],"Hikone":["—"],"Kusatsu":["—"]},"Kyoto":{"Kyoto":["—"],"Uji":["—"],"Maizuru":["—"]},"Osaka":{"Osaka":["—"],"Sakai":["—"],"Higashiosaka":["—"]},"Hyogo":{"Kobe":["—"],"Himeji":["—"],"Nishinomiya":["—"]},"Nara":{"Nara":["—"],"Kashihara":["—"],"Ikoma":["—"]},"Wakayama":{"Wakayama":["—"],"Tanabe":["—"],"Kinokawa":["—"]},"Tottori":{"Tottori":["—"],"Yonago":["—"],"Kurayoshi":["—"]},"Shimane":{"Matsue":["—"],"Izumo":["—"],"Hamada":["—"]},"Okayama":{"Okayama":["—"],"Kurashiki":["—"],"Tsuyama":["—"]},"Hiroshima":{"Hiroshima":["—"],"Fukuyama":["—"],"Kure":["—"]},"Yamaguchi":{"Yamaguchi":["—"],"Shimonoseki":["—"],"Ube":["—"]},"Tokushima":{"Tokushima":["—"],"Naruto":["—"],"Anan":["—"]},"Kagawa":{"Takamatsu":["—"],"Marugame":["—"],"Sakaide":["—"]},"Ehime":{"Matsuyama":["—"],"Imabari":["—"],"Uwajima":["—"]},"Kochi":{"Kochi":["—"],"Nankoku":["—"],"Shimanto":["—"]},"Fukuoka":{"Fukuoka":["—"],"Kitakyushu":["—"],"Kurume":["—"]},"Saga":{"Saga":["—"],"Karatsu":["—"],"Tosu":["—"]},"Nagasaki":{"Nagasaki":["—"],"Sasebo":["—"],"Isahaya":["—"]},"Kumamoto":{"Kumamoto":["—"],"Yatsushiro":["—"],"Amakusa":["—"]},"Oita":{"Oita":["—"],"Beppu":["—"],"Nakatsu":["—"]},"Miyazaki":{"Miyazaki":["—"],"Miyakonojo":["—"],"Nobeoka":["—"]},"Kagoshima":{"Kagoshima":["—"],"Kanoya":["—"],"Satsumasendai":["—"]},"Okinawa":{"Naha":["—"],"Okinawa":["—"],"Uruma":["—"]}},"韩国":{"Seoul":{"Jongno-gu":["—"],"Jung-gu":["—"],"Gangnam-gu":["—"],"Mapo-gu":["—"],"Seocho-gu":["—"]},"Busan":{"Jung-gu":["—"],"Seo-gu":["—"],"Haeundae-gu":["—"],"Saha-gu":["—"]},"Daegu":{"Jung-gu":["—"],"Dong-gu":["—"],"Seo-gu":["—"]},"Incheon":{"Jung-gu":["—"],"Nam-gu":["—"],"Yeonsu-gu":["—"]},"Gwangju":{"Dong-gu":["—"],"Seo-gu":["—"],"Nam-gu":["—"]},"Daejeon":{"Jung-gu":["—"],"Dong-gu":["—"],"Seo-gu":["—"]},"Ulsan":{"Jung-gu":["—"],"Nam-gu":["—"],"Dong-gu":["—"]},"Sejong":{"Sejong":["—"]},"Gyeonggi":{"Suwon":["—"],"Seongnam":["—"],"Goyang":["—"],"Yongin":["—"],"Bucheon":["—"]},"Gangwon":{"Chuncheon":["—"],"Wonju":["—"],"Gangneung":["—"]},"North Chungcheong":{"Cheongju":["—"],"Chungju":["—"],"Jecheon":["—"]},"South Chungcheong":{"Daejeon":["—"],"Cheonan":["—"],"Asan":["—"]},"North Jeolla":{"Jeonju":["—"],"Iksan":["—"],"Gunsan":["—"]},"South Jeolla":{"Gwangju":["—"],"Mokpo":["—"],"Suncheon":["—"]},"North Gyeongsang":{"Pohang":["—"],"Gyeongju":["—"],"Gimhae":["—"]},"South Gyeongsang":{"Changwon":["—"],"Jinju":["—"],"Geoje":["—"]},"Jeju":{"Jeju":["—"],"Seogwipo":["—"]}},"新加坡":{"Central Region":["—"],"East Region":["—"],"North Region":["—"],"North-East Region":["—"],"West Region":["—"]},"马来西亚":{"Kuala Lumpur":{"Kuala Lumpur":["—"]},"Selangor":{"Shah Alam":["—"],"Petaling Jaya":["—"]},"Penang":{"George Town":["—"]},"Johor":{"Johor Bahru":["—"]}},"泰国":{"Bangkok":{"Bangkok":["—"]},"ChiangMai":{"Chiang Mai":["—"]},"Phuket":{"Phuket":["—"]}},"越南":{"Hanoi":{"Hanoi":["—"]},"Ho Chi Minh City":{"Ho Chi Minh City":["—"]},"DaNang":{"Da Nang":["—"]}},"印度":{"Delhi":{"New Delhi":["—"]},"Maharashtra":{"Mumbai":["—"],"Pune":["—"]},"Karnataka":{"Bengaluru":["—"]}},"印度尼西亚":{"Jakarta":{"Central Jakarta":["—"],"South Jakarta":["—"]},"West Java":{"Bandung":["—"]},"Bali":{"Denpasar":["—"]}},"菲律宾":{"Metro Manila":{"Manila":["—"],"Quezon City":["—"]},"Cebu":{"Cebu City":["—"]},"Davao":{"Davao City":["—"]}},"英国":{"England":{"London":["—"],"Manchester":["—"],"Birmingham":["—"],"Leeds":["—"],"Liverpool":["—"],"Bristol":["—"],"Sheffield":["—"]},"Scotland":{"Edinburgh":["—"],"Glasgow":["—"],"Aberdeen":["—"],"Dundee":["—"]},"Wales":{"Cardiff":["—"],"Swansea":["—"],"Newport":["—"],"Wrexham":["—"]},"Northern Ireland":{"Belfast":["—"],"Derry":["—"],"Lisburn":["—"],"Newry":["—"]}},"法国":{"Auvergne-Rhone-Alpes":{"Lyon":["—"],"Grenoble":["—"],"Saint-Etienne":["—"],"Clermont-Ferrand":["—"]},"Bourgogne-Franche-Comte":{"Dijon":["—"],"Besancon":["—"]},"Brittany":{"Rennes":["—"],"Brest":["—"],"Nantes":["—"]},"Centre-Val de Loire":{"Orleans":["—"],"Tours":["—"],"Bourges":["—"]},"Corsica":{"Ajaccio":["—"],"Bastia":["—"]},"Grand Est":{"Strasbourg":["—"],"Reims":["—"],"Metz":["—"],"Nancy":["—"]},"Hauts-de-France":{"Lille":["—"],"Amiens":["—"],"Roubaix":["—"]},"Ile-de-France":{"Paris":["—"],"Versailles":["—"],"Boulogne-Billancourt":["—"],"Saint-Denis":["—"]},"Normandy":{"Rouen":["—"],"Le Havre":["—"],"Caen":["—"]},"Nouvelle-Aquitaine":{"Bordeaux":["—"],"Limoges":["—"],"Poitiers":["—"]},"Occitanie":{"Toulouse":["—"],"Montpellier":["—"],"Nimes":["—"]},"Pays de la Loire":{"Nantes":["—"],"Angers":["—"],"Le Mans":["—"]},"Provence-Alpes-Cote dAzur":{"Marseille":["—"],"Nice":["—"],"Toulon":["—"],"Aix-en-Provence":["—"]}},"德国":{"Baden-Wurttemberg":{"Stuttgart":["—"],"Mannheim":["—"],"Karlsruhe":["—"],"Freiburg":["—"]},"Bavaria":{"Munich":["—"],"Nuremberg":["—"],"Augsburg":["—"],"Regensburg":["—"]},"Berlin":{"Berlin":["—"]},"Brandenburg":{"Potsdam":["—"],"Cottbus":["—"],"Frankfurt (Oder)":["—"]},"Bremen":{"Bremen":["—"],"Bremerhaven":["—"]},"Hamburg":{"Hamburg":["—"]},"Hesse":{"Frankfurt am Main":["—"],"Wiesbaden":["—"],"Darmstadt":["—"],"Kassel":["—"]},"Lower Saxony":{"Hanover":["—"],"Braunschweig":["—"],"Osnabruck":["—"],"Oldenburg":["—"]},"Mecklenburg-Vorpommern":{"Rostock":["—"],"Schwerin":["—"],"Stralsund":["—"]},"North Rhine-Westphalia":{"Cologne":["—"],"Dusseldorf":["—"],"Dortmund":["—"],"Essen":["—"],"Bonn":["—"]},"Rhineland-Palatinate":{"Mainz":["—"],"Ludwigshafen":["—"],"Koblenz":["—"],"Trier":["—"]},"Saarland":{"Saarbrucken":["—"],"Neunkirchen":["—"],"Homburg":["—"]},"Saxony":{"Dresden":["—"],"Leipzig":["—"],"Chemnitz":["—"]},"Saxony-Anhalt":{"Magdeburg":["—"],"Halle (Saale)":["—"],"Dessau-Rosslau":["—"]},"Schleswig-Holstein":{"Kiel":["—"],"Lubeck":["—"],"Flensburg":["—"]},"Thuringia":{"Erfurt":["—"],"Jena":["—"],"Gera":["—"],"Weimar":["—"]}},"意大利":{"Lazio":{"Rome":["—"]},"Lombardy":{"Milan":["—"]},"Veneto":{"Venice":["—"]},"Tuscany":{"Florence":["—"]}},"西班牙":{"Madrid":{"Madrid":["—"]},"Catalonia":{"Barcelona":["—"]},"Andalusia":{"Seville":["—"]}},"荷兰":{"North Holland":{"Amsterdam":["—"],"Haarlem":["—"]},"South Holland":{"Rotterdam":["—"],"The Hague":["—"]}},"瑞士":{"Zurich":{"Zurich":["—"]},"Bern":{"Bern":["—"]},"Geneva":{"Geneva":["—"]}},"瑞典":{"Stockholm":{"Stockholm":["—"]},"VastraGotaland":{"Gothenburg":["—"]},"Skane":{"Malmo":["—"]}},"挪威":{"Oslo":{"Oslo":["—"]},"Viken":{"Drammen":["—"]},"Vestland":{"Bergen":["—"]}},"丹麦":{"Capital Region":{"Copenhagen":["—"]},"Central Denmark":{"Aarhus":["—"]},"Southern Denmark":{"Odense":["—"]}},"芬兰":{"Uusimaa":{"Helsinki":["—"]},"Pirkanmaa":{"Tampere":["—"]},"Southwest Finland":{"Turku":["—"]}},"俄罗斯":{"Moscow":{"Moscow":["—"]},"Saint Petersburg":{"Saint Petersburg":["—"]},"Novosibirsk Oblast":{"Novosibirsk":["—"]}},"波兰":{"Masovian":{"Warsaw":["—"]},"Lesser Poland":{"Krakow":["—"]},"Silesian":{"Katowice":["—"]}},"捷克":{"Prague":{"Prague":["—"]},"South Moravian":{"Brno":["—"]}},"奥地利":{"Vienna":{"Vienna":["—"]},"Tyrol":{"Innsbruck":["—"]},"Styria":{"Graz":["—"]}},"比利时":{"Brussels":{"Brussels":["—"]},"Flanders":{"Antwerp":["—"],"Ghent":["—"]},"Wallonia":{"Liege":["—"],"Charleroi":["—"]}},"加拿大":{"Alberta":{"Calgary":["—"],"Edmonton":["—"],"Red Deer":["—"],"Lethbridge":["—"]},"British Columbia":{"Vancouver":["—"],"Victoria":["—"],"Surrey":["—"],"Burnaby":["—"],"Kelowna":["—"]},"Manitoba":{"Winnipeg":["—"],"Brandon":["—"],"Steinbach":["—"]},"New Brunswick":{"Moncton":["—"],"Saint John":["—"],"Fredericton":["—"]},"Newfoundland and Labrador":{"St. John's":["—"],"Corner Brook":["—"],"Mount Pearl":["—"]},"Nova Scotia":{"Halifax":["—"],"Dartmouth":["—"],"Sydney":["—"]},"Ontario":{"Toronto":["—"],"Ottawa":["—"],"Mississauga":["—"],"Hamilton":["—"],"London":["—"],"Kitchener":["—"]},"Prince Edward Island":{"Charlottetown":["—"],"Summerside":["—"]},"Quebec":{"Montreal":["—"],"Quebec City":["—"],"Laval":["—"],"Gatineau":["—"],"Sherbrooke":["—"]},"Saskatchewan":{"Saskatoon":["—"],"Regina":["—"],"Prince Albert":["—"]},"Yukon":{"Whitehorse":["—"],"Dawson City":["—"]},"Northwest Territories":{"Yellowknife":["—"],"Hay River":["—"]},"Nunavut":{"Iqaluit":["—"],"Rankin Inlet":["—"]}},"墨西哥":{"Mexico City":{"Mexico City":["—"]},"Jalisco":{"Guadalajara":["—"]},"Nuevo Leon":{"Monterrey":["—"]}},"巴西":{"Sao Paulo":{"Sao Paulo":["—"]},"Rio de Janeiro":{"Rio de Janeiro":["—"]},"Minas Gerais":{"Belo Horizonte":["—"]}},"阿根廷":{"Buenos Aires":{"Buenos Aires":["—"]},"Cordoba":{"Cordoba":["—"]},"Mendoza":{"Mendoza":["—"]}},"智利":{"Santiago Metropolitan":{"Santiago":["—"]},"Valparaiso":{"Valparaiso":["—"]},"Biobio":{"Concepcion":["—"]}},"哥伦比亚":{"Bogota":{"Bogota":["—"]},"Antioquia":{"Medellin":["—"]},"Valle":{"Cali":["—"]}},"澳大利亚":{"New South Wales":{"Sydney":["—"],"Newcastle":["—"],"Wollongong":["—"],"Central Coast":["—"]},"Victoria":{"Melbourne":["—"],"Geelong":["—"],"Ballarat":["—"],"Bendigo":["—"]},"Queensland":{"Brisbane":["—"],"Gold Coast":["—"],"Sunshine Coast":["—"],"Townsville":["—"],"Cairns":["—"]},"Western Australia":{"Perth":["—"],"Fremantle":["—"],"Mandurah":["—"],"Bunbury":["—"]},"South Australia":{"Adelaide":["—"],"Mount Gambier":["—"],"Whyalla":["—"]},"Tasmania":{"Hobart":["—"],"Launceston":["—"],"Devonport":["—"]},"Australian Capital Territory":{"Canberra":["—"]},"Northern Territory":{"Darwin":["—"],"Alice Springs":["—"],"Palmerston":["—"]}},"新西兰":{"Auckland":{"Auckland":["—"]},"Wellington":{"Wellington":["—"]},"Canterbury":{"Christchurch":["—"]}},"南非":{"Gauteng":{"Johannesburg":["—"],"Pretoria":["—"]},"Western Cape":{"Cape Town":["—"]},"KwaZulu-Natal":{"Durban":["—"]}},"埃及":{"Cairo":{"Cairo":["—"]},"Alexandria":{"Alexandria":["—"]},"Giza":{"Giza":["—"]}},"阿联酋":{"Dubai":{"Dubai":["—"]},"Abu Dhabi":{"Abu Dhabi":["—"]},"Sharjah":{"Sharjah":["—"]}},"沙特阿拉伯":{"Riyadh":{"Riyadh":["—"]},"Makkah":{"Jeddah":["—"]},"Eastern Province":{"Dammam":["—"]}},"以色列":{"TelAviv":{"Tel Aviv":["—"]},"Jerusalem":{"Jerusalem":["—"]},"Haifa":{"Haifa":["—"]}},"土耳其":{"Istanbul":{"Istanbul":["—"]},"Ankara":{"Ankara":["—"]},"Izmir":{"Izmir":["—"]}},"其他":{"Province/State":{"City":["—"]}}}; + + function getCountryMeta(country) { + return COUNTRY_META[country] || COUNTRY_META['其他']; + } + + function getCountryRegionTree(country) { + return WORLD_REGIONS[country] || WORLD_REGIONS['其他']; + } + + function getProvincesForCountry(country) { + var meta = getCountryMeta(country); + if (meta.fixedRegion) return [meta.fixedRegion]; + if (!meta.hasRegion) return []; + var tree = getCountryRegionTree(country); + return Object.keys(tree); + } + + function getCitiesForCountry(country, province) { + var meta = getCountryMeta(country); + var tree = getCountryRegionTree(country); + if (!meta.hasRegion) return Object.keys(tree); + if (!province) return []; + if (meta.fixedRegion && tree[meta.fixedRegion]) return Object.keys(tree[meta.fixedRegion]); + return tree[province] ? Object.keys(tree[province]) : []; + } + + function getDistrictsForCountry(country, province, city) { + var meta = getCountryMeta(country); + if (!meta.hasDistrict) return []; + var tree = getCountryRegionTree(country); + var regionKey = meta.fixedRegion || province; + if (!regionKey || !city) return []; + if (meta.fixedRegion && tree[meta.fixedRegion] && tree[meta.fixedRegion][city]) return tree[meta.fixedRegion][city]; + if (tree[regionKey] && tree[regionKey][city]) return tree[regionKey][city]; + return []; + } + + function applyCountryAddressDefaults(country, addr) { + var meta = getCountryMeta(country); + addr.country = country; + if (meta.fixedRegion) addr.province = meta.fixedRegion; + else if (!meta.hasRegion) addr.province = ''; + else if (addr.province && !getProvincesForCountry(country).includes(addr.province)) addr.province = ''; + if (addr.city && !getCitiesForCountry(country, addr.province || meta.fixedRegion).includes(addr.city)) addr.city = ''; + if (addr.district && !getDistrictsForCountry(country, addr.province, addr.city).includes(addr.district)) addr.district = ''; + return addr; + } + + g.ADDRESS_COUNTRIES = ADDRESS_COUNTRIES; + g.COUNTRY_META = COUNTRY_META; + g.WORLD_REGIONS = WORLD_REGIONS; + g.getCountryMeta = getCountryMeta; + g.getCountryRegionTree = getCountryRegionTree; + g.getProvincesForCountry = getProvincesForCountry; + g.getCitiesForCountry = getCitiesForCountry; + g.getDistrictsForCountry = getDistrictsForCountry; + g.applyCountryAddressDefaults = applyCountryAddressDefaults; +})(typeof window !== 'undefined' ? window : global); diff --git a/deploy/feishu-approval.service b/deploy/feishu-approval.service new file mode 100644 index 0000000..9886a16 --- /dev/null +++ b/deploy/feishu-approval.service @@ -0,0 +1,17 @@ +[Unit] +Description=Feishu Approval Designer Service +After=network.target + +[Service] +Type=simple +User=root +WorkingDirectory=/opt/feishu-approval +Environment=NODE_ENV=production +Environment=PORT=8080 +Environment=HOST=0.0.0.0 +ExecStart=/usr/bin/node server.js +Restart=on-failure +RestartSec=5 + +[Install] +WantedBy=multi-user.target diff --git a/deploy/start.sh b/deploy/start.sh new file mode 100644 index 0000000..0a04000 --- /dev/null +++ b/deploy/start.sh @@ -0,0 +1,18 @@ +#!/bin/bash +# CentOS 7 启动脚本(Node.js 16.x) +set -e +cd "$(dirname "$0")/.." + +if ! command -v node >/dev/null 2>&1; then + echo "[ERROR] node not found. Install Node.js 16.x first." + exit 1 +fi + +NODE_MAJOR=$(node -p "process.versions.node.split('.')[0]") +if [ "$NODE_MAJOR" -lt 16 ]; then + echo "[ERROR] Node.js 16+ required. Current: $(node -v)" + exit 1 +fi + +echo "Starting with Node $(node -v) ..." +exec node server.js diff --git a/package.json b/package.json new file mode 100644 index 0000000..f47e8cc --- /dev/null +++ b/package.json @@ -0,0 +1,14 @@ +{ + "name": "feishu-approval-designer", + "private": true, + "version": "2.0.0", + "description": "飞书审批配置在线设计服务", + "scripts": { + "start": "node server.js", + "dev": "node server.js", + "build:regions": "node scripts/build-address-regions.js" + }, + "engines": { + "node": ">=16.0.0" + } +} diff --git a/project.config.json b/project.config.json new file mode 100644 index 0000000..cf24eab --- /dev/null +++ b/project.config.json @@ -0,0 +1,6 @@ +{ + "projectId": "approval_of_design", + "port": 8080, + "host": "0.0.0.0", + "label": "飞书审批配置服务" +} diff --git a/scripts/build-address-regions.js b/scripts/build-address-regions.js new file mode 100644 index 0000000..996da99 --- /dev/null +++ b/scripts/build-address-regions.js @@ -0,0 +1,424 @@ +/* eslint-disable */ +const fs = require('fs'); +const path = require('path'); + +function mkTree(stateMap) { + const t = {}; + Object.keys(stateMap).forEach(function (st) { + t[st] = {}; + stateMap[st].forEach(function (c) { t[st][c] = ['—']; }); + }); + return t; +} + +function mkFixed(fixedRegion, cities) { + const t = {}; + t[fixedRegion] = {}; + Object.keys(cities).forEach(function (city) { + t[fixedRegion][city] = cities[city]; + }); + return t; +} + +function mkFlat(cities) { + const t = {}; + cities.forEach(function (c) { t[c] = ['—']; }); + return t; +} + +const US_STATES = { + Alabama: ['Birmingham', 'Montgomery', 'Mobile', 'Huntsville', 'Tuscaloosa'], + Alaska: ['Anchorage', 'Fairbanks', 'Juneau', 'Sitka', 'Ketchikan'], + Arizona: ['Phoenix', 'Tucson', 'Mesa', 'Chandler', 'Scottsdale'], + Arkansas: ['Little Rock', 'Fort Smith', 'Fayetteville', 'Springdale', 'Jonesboro'], + California: ['Los Angeles', 'San Francisco', 'San Diego', 'San Jose', 'Sacramento', 'Oakland', 'Fresno', 'Long Beach'], + Colorado: ['Denver', 'Colorado Springs', 'Aurora', 'Fort Collins', 'Lakewood'], + Connecticut: ['Bridgeport', 'New Haven', 'Hartford', 'Stamford', 'Waterbury'], + Delaware: ['Wilmington', 'Dover', 'Newark', 'Middletown', 'Smyrna'], + 'District of Columbia': ['Washington'], + Florida: ['Jacksonville', 'Miami', 'Tampa', 'Orlando', 'St. Petersburg', 'Fort Lauderdale'], + Georgia: ['Atlanta', 'Augusta', 'Columbus', 'Savannah', 'Athens'], + Hawaii: ['Honolulu', 'Pearl City', 'Hilo', 'Kailua', 'Waipahu'], + Idaho: ['Boise', 'Meridian', 'Nampa', 'Idaho Falls', 'Pocatello'], + Illinois: ['Chicago', 'Aurora', 'Naperville', 'Joliet', 'Rockford', 'Springfield'], + Indiana: ['Indianapolis', 'Fort Wayne', 'Evansville', 'South Bend', 'Carmel'], + Iowa: ['Des Moines', 'Cedar Rapids', 'Davenport', 'Sioux City', 'Iowa City'], + Kansas: ['Wichita', 'Overland Park', 'Kansas City', 'Topeka', 'Olathe'], + Kentucky: ['Louisville', 'Lexington', 'Bowling Green', 'Owensboro', 'Covington'], + Louisiana: ['New Orleans', 'Baton Rouge', 'Shreveport', 'Lafayette', 'Lake Charles'], + Maine: ['Portland', 'Lewiston', 'Bangor', 'South Portland', 'Auburn'], + Maryland: ['Baltimore', 'Frederick', 'Rockville', 'Gaithersburg', 'Bowie'], + Massachusetts: ['Boston', 'Worcester', 'Springfield', 'Cambridge', 'Lowell'], + Michigan: ['Detroit', 'Grand Rapids', 'Warren', 'Sterling Heights', 'Ann Arbor', 'Lansing'], + Minnesota: ['Minneapolis', 'Saint Paul', 'Rochester', 'Duluth', 'Bloomington'], + Mississippi: ['Jackson', 'Gulfport', 'Southaven', 'Hattiesburg', 'Biloxi'], + Missouri: ['Kansas City', 'Saint Louis', 'Springfield', 'Columbia', 'Independence'], + Montana: ['Billings', 'Missoula', 'Great Falls', 'Bozeman', 'Butte'], + Nebraska: ['Omaha', 'Lincoln', 'Bellevue', 'Grand Island', 'Kearney'], + Nevada: ['Las Vegas', 'Henderson', 'Reno', 'North Las Vegas', 'Sparks'], + 'New Hampshire': ['Manchester', 'Nashua', 'Concord', 'Dover', 'Rochester'], + 'New Jersey': ['Newark', 'Jersey City', 'Paterson', 'Elizabeth', 'Edison', 'Trenton'], + 'New Mexico': ['Albuquerque', 'Las Cruces', 'Rio Rancho', 'Santa Fe', 'Roswell'], + 'New York': ['New York City', 'Buffalo', 'Rochester', 'Yonkers', 'Syracuse', 'Albany'], + 'North Carolina': ['Charlotte', 'Raleigh', 'Greensboro', 'Durham', 'Winston-Salem'], + 'North Dakota': ['Fargo', 'Bismarck', 'Grand Forks', 'Minot', 'West Fargo'], + Ohio: ['Columbus', 'Cleveland', 'Cincinnati', 'Toledo', 'Akron', 'Dayton'], + Oklahoma: ['Oklahoma City', 'Tulsa', 'Norman', 'Broken Arrow', 'Lawton'], + Oregon: ['Portland', 'Eugene', 'Salem', 'Gresham', 'Hillsboro'], + Pennsylvania: ['Philadelphia', 'Pittsburgh', 'Allentown', 'Erie', 'Reading', 'Harrisburg'], + 'Rhode Island': ['Providence', 'Warwick', 'Cranston', 'Pawtucket', 'East Providence'], + 'South Carolina': ['Charleston', 'Columbia', 'North Charleston', 'Mount Pleasant', 'Greenville'], + 'South Dakota': ['Sioux Falls', 'Rapid City', 'Aberdeen', 'Brookings', 'Watertown'], + Tennessee: ['Nashville', 'Memphis', 'Knoxville', 'Chattanooga', 'Clarksville'], + Texas: ['Houston', 'San Antonio', 'Dallas', 'Austin', 'Fort Worth', 'El Paso', 'Arlington', 'Corpus Christi'], + Utah: ['Salt Lake City', 'West Valley City', 'Provo', 'West Jordan', 'Orem'], + Vermont: ['Burlington', 'South Burlington', 'Rutland', 'Barre', 'Montpelier'], + Virginia: ['Virginia Beach', 'Norfolk', 'Chesapeake', 'Richmond', 'Newport News', 'Alexandria'], + Washington: ['Seattle', 'Spokane', 'Tacoma', 'Vancouver', 'Bellevue', 'Olympia'], + 'West Virginia': ['Charleston', 'Huntington', 'Morgantown', 'Parkersburg', 'Wheeling'], + Wisconsin: ['Milwaukee', 'Madison', 'Green Bay', 'Kenosha', 'Racine'], + Wyoming: ['Cheyenne', 'Casper', 'Laramie', 'Gillette', 'Rock Springs'] +}; + +const CHINA = require('./china-regions-data.json'); + +const HK = mkFixed('香港特别行政区', { + '香港岛': ['中西区', '湾仔区', '东区', '南区'], + '九龙': ['油尖旺区', '深水埗区', '九龙城区', '黄大仙区', '观塘区'], + '新界': ['荃湾区', '屯门区', '元朗区', '北区', '大埔区', '沙田区', '西贡区', '葵青区', '离岛区'] +}); + +const MO = mkFixed('澳门特别行政区', { + '花地玛堂区': ['—'], '花王堂区': ['—'], '望德堂区': ['—'], '大堂区': ['—'], + '风顺堂区': ['—'], '嘉模堂区': ['—'], '圣方济各堂区': ['—'], '路氹填海区': ['—'] +}); + +const TW = mkFixed('台湾省', { + '台北市': ['中正区', '大同区', '中山区', '松山区', '大安区', '万华区', '信义区', '士林区', '北投区', '内湖区', '南港区', '文山区'], + '新北市': ['板桥区', '三重区', '中和区', '永和区', '新庄区', '新店区', '树林区', '莺歌区', '三峡区', '淡水区', '汐止区', '瑞芳区', '土城区', '芦洲区', '五股区', '泰山区', '林口区'], + '桃园市': ['桃园区', '中坜区', '平镇区', '八德区', '杨梅区', '芦竹区', '大溪区', '龙潭区', '龟山区', '大园区', '观音区', '新屋区', '复兴区'], + '台中市': ['中区', '东区', '南区', '西区', '北区', '北屯区', '西屯区', '南屯区', '太平区', '大里区', '雾峰区', '乌日区', '丰原区', '后里区', '石冈区', '东势区', '和平区', '新社区', '潭子区', '大雅区', '神冈区', '大肚区', '沙鹿区', '龙井区', '梧栖区', '清水区', '大甲区', '外埔区', '大安区'], + '台南市': ['中西区', '东区', '南区', '北区', '安平区', '安南区', '永康区', '归仁区', '新化区', '左镇区', '玉井区', '楠西区', '南化区', '仁德区', '关庙区', '龙崎区', '官田区', '麻豆区', '佳里区', '西港区', '七股区', '将军区', '学甲区', '北门区', '新营区', '后壁区', '白河区', '东山区', '六甲区', '下营区', '柳营区', '盐水区', '大内区', '山上区', '新市区', '安定区'], + '高雄市': ['新兴区', '前金区', '苓雅区', '盐埕区', '鼓山区', '旗津区', '前镇区', '三民区', '楠梓区', '小港区', '左营区', '仁武区', '大社区', '冈山区', '路竹区', '阿莲区', '田寮区', '燕巢区', '桥头区', '梓官区', '弥陀区', '永安区', '湖内区', '凤山区', '大寮区', '林园区', '鸟松区', '大树区', '旗山区', '美浓区', '六龟区', '内门区', '杉林区', '甲仙区', '桃源区', '那玛夏区', '茂林区', '茄萣区'], + '基隆市': ['仁爱区', '信义区', '中正区', '中山区', '安乐区', '暖暖区', '七堵区'], + '新竹市': ['东区', '北区', '香山区'], + '嘉义市': ['东区', '西区'], + '新竹县': ['竹北市', '湖口乡', '新丰乡', '新埔镇', '关西镇', '芎林乡', '宝山乡', '竹东镇', '五峰乡', '横山乡', '尖石乡', '北埔乡', '峨眉乡'], + '苗栗县': ['苗栗市', '苑里镇', '通霄镇', '竹南镇', '头份市', '后龙镇', '卓兰镇', '大湖乡', '公馆乡', '铜锣乡', '南庄乡', '头屋乡', '三义乡', '西湖乡', '造桥乡', '三湾乡', '狮潭乡', '泰安乡'], + '彰化县': ['彰化市', '鹿港镇', '和美镇', '线西乡', '伸港乡', '福兴乡', '秀水乡', '花坛乡', '芬园乡', '员林镇', '溪湖镇', '田中镇', '大村乡', '埔盐乡', '埔心乡', '永靖乡', '社头乡', '二水乡', '北斗镇', '埤头乡', '溪州乡', '竹塘乡', '大城乡', '芳苑乡', '二林镇'], + '南投县': ['南投市', '埔里镇', '草屯镇', '竹山镇', '集集镇', '名间乡', '鹿谷乡', '中寮乡', '鱼池乡', '国姓乡', '水里乡', '信义乡', '仁爱乡'], + '云林县': ['斗六市', '斗南镇', '虎尾镇', '西螺镇', '土库镇', '北港镇', '古坑乡', '大埤乡', '莿桐乡', '林内乡', '二仑乡', '仑背乡', '麦寮乡', '东势乡', '褒忠乡', '台西乡', '元长乡', '四湖乡', '口湖乡', '水林乡'], + '嘉义县': ['太保市', '朴子市', '布袋镇', '大林镇', '民雄乡', '溪口乡', '新港乡', '六脚乡', '东石乡', '义竹乡', '鹿草乡', '水上乡', '中埔乡', '竹崎乡', '梅山乡', '番路乡', '大埔乡', '阿里山乡'], + '屏东县': ['屏东市', '潮州镇', '东港镇', '恒春镇', '万丹乡', '长治乡', '麟洛乡', '九如乡', '里港乡', '盐埔乡', '高树乡', '万峦乡', '内埔乡', '竹田乡', '新埤乡', '枋寮乡', '新园乡', '崁顶乡', '林边乡', '南州乡', '佳冬乡', '琉球乡', '车城乡', '满州乡', '枋山乡', '三地门乡', '雾台乡', '玛家乡', '泰武乡', '来义乡', '春日乡', '狮子乡', '牡丹乡'], + '宜兰县': ['宜兰市', '罗东镇', '苏澳镇', '头城镇', '礁溪乡', '壮围乡', '员山乡', '冬山乡', '五结乡', '三星乡', '大同乡', '南澳乡'], + '花莲县': ['花莲市', '凤林镇', '玉里镇', '新城乡', '吉安乡', '寿丰乡', '光复乡', '丰滨乡', '瑞穗乡', '富里乡', '秀林乡', '万荣乡', '卓溪乡'], + '台东县': ['台东市', '成功镇', '关山镇', '卑南乡', '鹿野乡', '池上乡', '东河乡', '长滨乡', '太麻里乡', '大武乡', '绿岛乡', '海端乡', '延平乡', '金峰乡', '达仁乡', '兰屿乡'], + '澎湖县': ['马公市', '湖西乡', '白沙乡', '西屿乡', '望安乡', '七美乡'], + '金门县': ['金城镇', '金湖镇', '金沙镇', '金宁乡', '烈屿乡', '乌坵乡'], + '连江县': ['南竿乡', '北竿乡', '莒光乡', '东引乡'] +}); + +const JP = mkTree({ + Hokkaido: ['Sapporo', 'Asahikawa', 'Hakodate', 'Kushiro', 'Obihiro'], + Aomori: ['Aomori', 'Hachinohe', 'Hirosaki'], + Iwate: ['Morioka', 'Ofunato', 'Hanamaki'], + Miyagi: ['Sendai', 'Ishinomaki', 'Osaki'], + Akita: ['Akita', 'Yokote', 'Oga'], + Yamagata: ['Yamagata', 'Tsuruoka', 'Sakata'], + Fukushima: ['Fukushima', 'Koriyama', 'Iwaki'], + Ibaraki: ['Mito', 'Tsukuba', 'Hitachi'], + Tochigi: ['Utsunomiya', 'Ashikaga', 'Oyama'], + Gunma: ['Maebashi', 'Takasaki', 'Ota'], + Saitama: ['Saitama', 'Kawagoe', 'Kawaguchi'], + Chiba: ['Chiba', 'Funabashi', 'Ichikawa'], + Tokyo: ['Shinjuku', 'Shibuya', 'Minato', 'Chiyoda', 'Setagaya'], + Kanagawa: ['Yokohama', 'Kawasaki', 'Sagamihara'], + Niigata: ['Niigata', 'Nagaoka', 'Joetsu'], + Toyama: ['Toyama', 'Takaoka', 'Uozu'], + Ishikawa: ['Kanazawa', 'Komatsu', 'Hakusan'], + Fukui: ['Fukui', 'Sakai', 'Obama'], + Yamanashi: ['Kofu', 'Fujiyoshida', 'Kai'], + Nagano: ['Nagano', 'Matsumoto', 'Ueda'], + Gifu: ['Gifu', 'Ogaki', 'Takayama'], + Shizuoka: ['Shizuoka', 'Hamamatsu', 'Numazu'], + Aichi: ['Nagoya', 'Toyohashi', 'Okazaki'], + Mie: ['Tsu', 'Yokkaichi', 'Suzuka'], + Shiga: ['Otsu', 'Hikone', 'Kusatsu'], + Kyoto: ['Kyoto', 'Uji', 'Maizuru'], + Osaka: ['Osaka', 'Sakai', 'Higashiosaka'], + Hyogo: ['Kobe', 'Himeji', 'Nishinomiya'], + Nara: ['Nara', 'Kashihara', 'Ikoma'], + Wakayama: ['Wakayama', 'Tanabe', 'Kinokawa'], + Tottori: ['Tottori', 'Yonago', 'Kurayoshi'], + Shimane: ['Matsue', 'Izumo', 'Hamada'], + Okayama: ['Okayama', 'Kurashiki', 'Tsuyama'], + Hiroshima: ['Hiroshima', 'Fukuyama', 'Kure'], + Yamaguchi: ['Yamaguchi', 'Shimonoseki', 'Ube'], + Tokushima: ['Tokushima', 'Naruto', 'Anan'], + Kagawa: ['Takamatsu', 'Marugame', 'Sakaide'], + Ehime: ['Matsuyama', 'Imabari', 'Uwajima'], + Kochi: ['Kochi', 'Nankoku', 'Shimanto'], + Fukuoka: ['Fukuoka', 'Kitakyushu', 'Kurume'], + Saga: ['Saga', 'Karatsu', 'Tosu'], + Nagasaki: ['Nagasaki', 'Sasebo', 'Isahaya'], + Kumamoto: ['Kumamoto', 'Yatsushiro', 'Amakusa'], + Oita: ['Oita', 'Beppu', 'Nakatsu'], + Miyazaki: ['Miyazaki', 'Miyakonojo', 'Nobeoka'], + Kagoshima: ['Kagoshima', 'Kanoya', 'Satsumasendai'], + Okinawa: ['Naha', 'Okinawa', 'Uruma'] +}); + +const KR = mkTree({ + Seoul: ['Jongno-gu', 'Jung-gu', 'Gangnam-gu', 'Mapo-gu', 'Seocho-gu'], + Busan: ['Jung-gu', 'Seo-gu', 'Haeundae-gu', 'Saha-gu'], + Daegu: ['Jung-gu', 'Dong-gu', 'Seo-gu'], + Incheon: ['Jung-gu', 'Nam-gu', 'Yeonsu-gu'], + Gwangju: ['Dong-gu', 'Seo-gu', 'Nam-gu'], + Daejeon: ['Jung-gu', 'Dong-gu', 'Seo-gu'], + Ulsan: ['Jung-gu', 'Nam-gu', 'Dong-gu'], + Sejong: ['Sejong'], + Gyeonggi: ['Suwon', 'Seongnam', 'Goyang', 'Yongin', 'Bucheon'], + Gangwon: ['Chuncheon', 'Wonju', 'Gangneung'], + 'North Chungcheong': ['Cheongju', 'Chungju', 'Jecheon'], + 'South Chungcheong': ['Daejeon', 'Cheonan', 'Asan'], + 'North Jeolla': ['Jeonju', 'Iksan', 'Gunsan'], + 'South Jeolla': ['Gwangju', 'Mokpo', 'Suncheon'], + 'North Gyeongsang': ['Pohang', 'Gyeongju', 'Gimhae'], + 'South Gyeongsang': ['Changwon', 'Jinju', 'Geoje'], + Jeju: ['Jeju', 'Seogwipo'] +}); + +const CA = mkTree({ + Alberta: ['Calgary', 'Edmonton', 'Red Deer', 'Lethbridge'], + 'British Columbia': ['Vancouver', 'Victoria', 'Surrey', 'Burnaby', 'Kelowna'], + Manitoba: ['Winnipeg', 'Brandon', 'Steinbach'], + 'New Brunswick': ['Moncton', 'Saint John', 'Fredericton'], + 'Newfoundland and Labrador': ["St. John's", 'Corner Brook', 'Mount Pearl'], + 'Nova Scotia': ['Halifax', 'Dartmouth', 'Sydney'], + Ontario: ['Toronto', 'Ottawa', 'Mississauga', 'Hamilton', 'London', 'Kitchener'], + 'Prince Edward Island': ['Charlottetown', 'Summerside'], + Quebec: ['Montreal', 'Quebec City', 'Laval', 'Gatineau', 'Sherbrooke'], + Saskatchewan: ['Saskatoon', 'Regina', 'Prince Albert'], + Yukon: ['Whitehorse', 'Dawson City'], + 'Northwest Territories': ['Yellowknife', 'Hay River'], + Nunavut: ['Iqaluit', 'Rankin Inlet'] +}); + +const AU = mkTree({ + 'New South Wales': ['Sydney', 'Newcastle', 'Wollongong', 'Central Coast'], + Victoria: ['Melbourne', 'Geelong', 'Ballarat', 'Bendigo'], + Queensland: ['Brisbane', 'Gold Coast', 'Sunshine Coast', 'Townsville', 'Cairns'], + 'Western Australia': ['Perth', 'Fremantle', 'Mandurah', 'Bunbury'], + 'South Australia': ['Adelaide', 'Mount Gambier', 'Whyalla'], + Tasmania: ['Hobart', 'Launceston', 'Devonport'], + 'Australian Capital Territory': ['Canberra'], + 'Northern Territory': ['Darwin', 'Alice Springs', 'Palmerston'] +}); + +const GB = mkTree({ + England: ['London', 'Manchester', 'Birmingham', 'Leeds', 'Liverpool', 'Bristol', 'Sheffield'], + Scotland: ['Edinburgh', 'Glasgow', 'Aberdeen', 'Dundee'], + Wales: ['Cardiff', 'Swansea', 'Newport', 'Wrexham'], + 'Northern Ireland': ['Belfast', 'Derry', 'Lisburn', 'Newry'] +}); + +const DE = mkTree({ + 'Baden-Wurttemberg': ['Stuttgart', 'Mannheim', 'Karlsruhe', 'Freiburg'], + Bavaria: ['Munich', 'Nuremberg', 'Augsburg', 'Regensburg'], + Berlin: ['Berlin'], + Brandenburg: ['Potsdam', 'Cottbus', 'Frankfurt (Oder)'], + Bremen: ['Bremen', 'Bremerhaven'], + Hamburg: ['Hamburg'], + Hesse: ['Frankfurt am Main', 'Wiesbaden', 'Darmstadt', 'Kassel'], + 'Lower Saxony': ['Hanover', 'Braunschweig', 'Osnabruck', 'Oldenburg'], + 'Mecklenburg-Vorpommern': ['Rostock', 'Schwerin', 'Stralsund'], + 'North Rhine-Westphalia': ['Cologne', 'Dusseldorf', 'Dortmund', 'Essen', 'Bonn'], + 'Rhineland-Palatinate': ['Mainz', 'Ludwigshafen', 'Koblenz', 'Trier'], + Saarland: ['Saarbrucken', 'Neunkirchen', 'Homburg'], + Saxony: ['Dresden', 'Leipzig', 'Chemnitz'], + 'Saxony-Anhalt': ['Magdeburg', 'Halle (Saale)', 'Dessau-Rosslau'], + 'Schleswig-Holstein': ['Kiel', 'Lubeck', 'Flensburg'], + Thuringia: ['Erfurt', 'Jena', 'Gera', 'Weimar'] +}); + +const FR = mkTree({ + 'Auvergne-Rhone-Alpes': ['Lyon', 'Grenoble', 'Saint-Etienne', 'Clermont-Ferrand'], + 'Bourgogne-Franche-Comte': ['Dijon', 'Besancon'], + Brittany: ['Rennes', 'Brest', 'Nantes'], + 'Centre-Val de Loire': ['Orleans', 'Tours', 'Bourges'], + Corsica: ['Ajaccio', 'Bastia'], + 'Grand Est': ['Strasbourg', 'Reims', 'Metz', 'Nancy'], + 'Hauts-de-France': ['Lille', 'Amiens', 'Roubaix'], + 'Ile-de-France': ['Paris', 'Versailles', 'Boulogne-Billancourt', 'Saint-Denis'], + Normandy: ['Rouen', 'Le Havre', 'Caen'], + 'Nouvelle-Aquitaine': ['Bordeaux', 'Limoges', 'Poitiers'], + Occitanie: ['Toulouse', 'Montpellier', 'Nimes'], + 'Pays de la Loire': ['Nantes', 'Angers', 'Le Mans'], + 'Provence-Alpes-Cote dAzur': ['Marseille', 'Nice', 'Toulon', 'Aix-en-Provence'] +}); + +const COUNTRY_META = { + '中国': { lang: 'zh', hasRegion: true, hasDistrict: true }, + '中国香港': { lang: 'zh', fixedRegion: '香港特别行政区', hasRegion: true, hasDistrict: true }, + '中国澳门': { lang: 'zh', fixedRegion: '澳门特别行政区', hasRegion: true, hasDistrict: false }, + '中国台湾': { lang: 'zh', fixedRegion: '台湾省', hasRegion: true, hasDistrict: true }, + '美国': { lang: 'en', hasRegion: true, hasDistrict: false }, + '日本': { lang: 'en', hasRegion: true, hasDistrict: false }, + '韩国': { lang: 'en', hasRegion: true, hasDistrict: false }, + '新加坡': { lang: 'en', hasRegion: false, hasDistrict: false }, + '马来西亚': { lang: 'en', hasRegion: true, hasDistrict: false }, + '泰国': { lang: 'en', hasRegion: true, hasDistrict: false }, + '越南': { lang: 'en', hasRegion: true, hasDistrict: false }, + '印度': { lang: 'en', hasRegion: true, hasDistrict: false }, + '印度尼西亚': { lang: 'en', hasRegion: true, hasDistrict: false }, + '菲律宾': { lang: 'en', hasRegion: true, hasDistrict: false }, + '英国': { lang: 'en', hasRegion: true, hasDistrict: false }, + '法国': { lang: 'en', hasRegion: true, hasDistrict: false }, + '德国': { lang: 'en', hasRegion: true, hasDistrict: false }, + '意大利': { lang: 'en', hasRegion: true, hasDistrict: false }, + '西班牙': { lang: 'en', hasRegion: true, hasDistrict: false }, + '荷兰': { lang: 'en', hasRegion: true, hasDistrict: false }, + '瑞士': { lang: 'en', hasRegion: true, hasDistrict: false }, + '瑞典': { lang: 'en', hasRegion: true, hasDistrict: false }, + '挪威': { lang: 'en', hasRegion: true, hasDistrict: false }, + '丹麦': { lang: 'en', hasRegion: true, hasDistrict: false }, + '芬兰': { lang: 'en', hasRegion: true, hasDistrict: false }, + '俄罗斯': { lang: 'en', hasRegion: true, hasDistrict: false }, + '波兰': { lang: 'en', hasRegion: true, hasDistrict: false }, + '捷克': { lang: 'en', hasRegion: true, hasDistrict: false }, + '奥地利': { lang: 'en', hasRegion: true, hasDistrict: false }, + '比利时': { lang: 'en', hasRegion: true, hasDistrict: false }, + '加拿大': { lang: 'en', hasRegion: true, hasDistrict: false }, + '墨西哥': { lang: 'en', hasRegion: true, hasDistrict: false }, + '巴西': { lang: 'en', hasRegion: true, hasDistrict: false }, + '阿根廷': { lang: 'en', hasRegion: true, hasDistrict: false }, + '智利': { lang: 'en', hasRegion: true, hasDistrict: false }, + '哥伦比亚': { lang: 'en', hasRegion: true, hasDistrict: false }, + '澳大利亚': { lang: 'en', hasRegion: true, hasDistrict: false }, + '新西兰': { lang: 'en', hasRegion: true, hasDistrict: false }, + '南非': { lang: 'en', hasRegion: true, hasDistrict: false }, + '埃及': { lang: 'en', hasRegion: true, hasDistrict: false }, + '阿联酋': { lang: 'en', hasRegion: true, hasDistrict: false }, + '沙特阿拉伯': { lang: 'en', hasRegion: true, hasDistrict: false }, + '以色列': { lang: 'en', hasRegion: true, hasDistrict: false }, + '土耳其': { lang: 'en', hasRegion: true, hasDistrict: false }, + '其他': { lang: 'en', hasRegion: true, hasDistrict: false } +}; + +const WORLD_REGIONS = { + '中国': CHINA, + '中国香港': HK, + '中国澳门': MO, + '中国台湾': TW, + '美国': mkTree(US_STATES), + '日本': JP, + '韩国': KR, + '新加坡': mkFlat(['Central Region', 'East Region', 'North Region', 'North-East Region', 'West Region']), + '马来西亚': mkTree({ 'Kuala Lumpur': ['Kuala Lumpur'], Selangor: ['Shah Alam', 'Petaling Jaya'], Penang: ['George Town'], Johor: ['Johor Bahru'] }), + '泰国': mkTree({ Bangkok: ['Bangkok'], ChiangMai: ['Chiang Mai'], Phuket: ['Phuket'] }), + '越南': mkTree({ Hanoi: ['Hanoi'], 'Ho Chi Minh City': ['Ho Chi Minh City'], DaNang: ['Da Nang'] }), + '印度': mkTree({ Delhi: ['New Delhi'], Maharashtra: ['Mumbai', 'Pune'], Karnataka: ['Bengaluru'] }), + '印度尼西亚': mkTree({ Jakarta: ['Central Jakarta', 'South Jakarta'], 'West Java': ['Bandung'], Bali: ['Denpasar'] }), + '菲律宾': mkTree({ 'Metro Manila': ['Manila', 'Quezon City'], Cebu: ['Cebu City'], Davao: ['Davao City'] }), + '英国': GB, + '法国': FR, + '德国': DE, + '意大利': mkTree({ Lazio: ['Rome'], Lombardy: ['Milan'], Veneto: ['Venice'], Tuscany: ['Florence'] }), + '西班牙': mkTree({ Madrid: ['Madrid'], Catalonia: ['Barcelona'], Andalusia: ['Seville'] }), + '荷兰': mkTree({ 'North Holland': ['Amsterdam', 'Haarlem'], 'South Holland': ['Rotterdam', 'The Hague'] }), + '瑞士': mkTree({ Zurich: ['Zurich'], Bern: ['Bern'], Geneva: ['Geneva'] }), + '瑞典': mkTree({ Stockholm: ['Stockholm'], VastraGotaland: ['Gothenburg'], Skane: ['Malmo'] }), + '挪威': mkTree({ Oslo: ['Oslo'], Viken: ['Drammen'], Vestland: ['Bergen'] }), + '丹麦': mkTree({ 'Capital Region': ['Copenhagen'], 'Central Denmark': ['Aarhus'], 'Southern Denmark': ['Odense'] }), + '芬兰': mkTree({ Uusimaa: ['Helsinki'], Pirkanmaa: ['Tampere'], 'Southwest Finland': ['Turku'] }), + '俄罗斯': mkTree({ Moscow: ['Moscow'], 'Saint Petersburg': ['Saint Petersburg'], 'Novosibirsk Oblast': ['Novosibirsk'] }), + '波兰': mkTree({ Masovian: ['Warsaw'], 'Lesser Poland': ['Krakow'], Silesian: ['Katowice'] }), + '捷克': mkTree({ Prague: ['Prague'], 'South Moravian': ['Brno'] }), + '奥地利': mkTree({ Vienna: ['Vienna'], Tyrol: ['Innsbruck'], Styria: ['Graz'] }), + '比利时': mkTree({ Brussels: ['Brussels'], Flanders: ['Antwerp', 'Ghent'], Wallonia: ['Liege', 'Charleroi'] }), + '加拿大': CA, + '墨西哥': mkTree({ 'Mexico City': ['Mexico City'], Jalisco: ['Guadalajara'], 'Nuevo Leon': ['Monterrey'] }), + '巴西': mkTree({ 'Sao Paulo': ['Sao Paulo'], 'Rio de Janeiro': ['Rio de Janeiro'], 'Minas Gerais': ['Belo Horizonte'] }), + '阿根廷': mkTree({ 'Buenos Aires': ['Buenos Aires'], Cordoba: ['Cordoba'], Mendoza: ['Mendoza'] }), + '智利': mkTree({ 'Santiago Metropolitan': ['Santiago'], Valparaiso: ['Valparaiso'], Biobio: ['Concepcion'] }), + '哥伦比亚': mkTree({ Bogota: ['Bogota'], Antioquia: ['Medellin'], Valle: ['Cali'] }), + '澳大利亚': AU, + '新西兰': mkTree({ Auckland: ['Auckland'], Wellington: ['Wellington'], Canterbury: ['Christchurch'] }), + '南非': mkTree({ Gauteng: ['Johannesburg', 'Pretoria'], 'Western Cape': ['Cape Town'], 'KwaZulu-Natal': ['Durban'] }), + '埃及': mkTree({ Cairo: ['Cairo'], Alexandria: ['Alexandria'], Giza: ['Giza'] }), + '阿联酋': mkTree({ Dubai: ['Dubai'], 'Abu Dhabi': ['Abu Dhabi'], Sharjah: ['Sharjah'] }), + '沙特阿拉伯': mkTree({ Riyadh: ['Riyadh'], Makkah: ['Jeddah'], 'Eastern Province': ['Dammam'] }), + '以色列': mkTree({ TelAviv: ['Tel Aviv'], Jerusalem: ['Jerusalem'], Haifa: ['Haifa'] }), + '土耳其': mkTree({ Istanbul: ['Istanbul'], Ankara: ['Ankara'], Izmir: ['Izmir'] }), + '其他': mkTree({ 'Province/State': ['City'] }) +}; + +const ADDRESS_COUNTRIES = Object.keys(COUNTRY_META); + +const out = `/* Auto-generated address region data for Feishu-style address conditions */ +(function (g) { + var ADDRESS_COUNTRIES = ${JSON.stringify(ADDRESS_COUNTRIES)}; + var COUNTRY_META = ${JSON.stringify(COUNTRY_META, null, 2)}; + var WORLD_REGIONS = ${JSON.stringify(WORLD_REGIONS)}; + + function getCountryMeta(country) { + return COUNTRY_META[country] || COUNTRY_META['其他']; + } + + function getCountryRegionTree(country) { + return WORLD_REGIONS[country] || WORLD_REGIONS['其他']; + } + + function getProvincesForCountry(country) { + var meta = getCountryMeta(country); + if (meta.fixedRegion) return [meta.fixedRegion]; + if (!meta.hasRegion) return []; + var tree = getCountryRegionTree(country); + return Object.keys(tree); + } + + function getCitiesForCountry(country, province) { + var meta = getCountryMeta(country); + var tree = getCountryRegionTree(country); + if (!meta.hasRegion) return Object.keys(tree); + if (!province) return []; + if (meta.fixedRegion && tree[meta.fixedRegion]) return Object.keys(tree[meta.fixedRegion]); + return tree[province] ? Object.keys(tree[province]) : []; + } + + function getDistrictsForCountry(country, province, city) { + var meta = getCountryMeta(country); + if (!meta.hasDistrict) return []; + var tree = getCountryRegionTree(country); + var regionKey = meta.fixedRegion || province; + if (!regionKey || !city) return []; + if (meta.fixedRegion && tree[meta.fixedRegion] && tree[meta.fixedRegion][city]) return tree[meta.fixedRegion][city]; + if (tree[regionKey] && tree[regionKey][city]) return tree[regionKey][city]; + return []; + } + + function applyCountryAddressDefaults(country, addr) { + var meta = getCountryMeta(country); + addr.country = country; + if (meta.fixedRegion) addr.province = meta.fixedRegion; + else if (!meta.hasRegion) addr.province = ''; + else if (addr.province && !getProvincesForCountry(country).includes(addr.province)) addr.province = ''; + if (addr.city && !getCitiesForCountry(country, addr.province || meta.fixedRegion).includes(addr.city)) addr.city = ''; + if (addr.district && !getDistrictsForCountry(country, addr.province, addr.city).includes(addr.district)) addr.district = ''; + return addr; + } + + g.ADDRESS_COUNTRIES = ADDRESS_COUNTRIES; + g.COUNTRY_META = COUNTRY_META; + g.WORLD_REGIONS = WORLD_REGIONS; + g.getCountryMeta = getCountryMeta; + g.getCountryRegionTree = getCountryRegionTree; + g.getProvincesForCountry = getProvincesForCountry; + g.getCitiesForCountry = getCitiesForCountry; + g.getDistrictsForCountry = getDistrictsForCountry; + g.applyCountryAddressDefaults = applyCountryAddressDefaults; +})(typeof window !== 'undefined' ? window : global); +`; + +fs.writeFileSync(path.join(__dirname, '..', 'address-regions.js'), out, 'utf8'); +console.log('Wrote address-regions.js', (out.length / 1024).toFixed(1), 'KB'); diff --git a/scripts/china-regions-data.json b/scripts/china-regions-data.json new file mode 100644 index 0000000..fd52459 --- /dev/null +++ b/scripts/china-regions-data.json @@ -0,0 +1 @@ +{"北京市":{"市辖区":["东城区","西城区","朝阳区","丰台区","石景山区","海淀区","门头沟区","房山区","通州区","顺义区","昌平区","大兴区","怀柔区","平谷区","密云区","延庆区"]},"天津市":{"市辖区":["和平区","河东区","河西区","南开区","河北区","红桥区","东丽区","西青区","津南区","北辰区","武清区","宝坻区","滨海新区","宁河区","静海区","蓟州区"]},"河北省":{"石家庄市":["长安区","桥西区","新华区","井陉矿区","裕华区","藁城区","鹿泉区","栾城区","井陉县","正定县","行唐县","灵寿县","高邑县","深泽县","赞皇县","无极县","平山县","元氏县","赵县","石家庄高新技术产业开发区","石家庄循环化工园区","辛集市","晋州市","新乐市"],"唐山市":["路南区","路北区","古冶区","开平区","丰南区","丰润区","曹妃甸区","滦南县","乐亭县","迁西县","玉田县","河北唐山芦台经济开发区","唐山市汉沽管理区","唐山高新技术产业开发区","河北唐山海港经济开发区","遵化市","迁安市","滦州市"],"秦皇岛市":["海港区","山海关区","北戴河区","抚宁区","青龙满族自治县","昌黎县","卢龙县","秦皇岛市经济技术开发区","北戴河新区"],"邯郸市":["邯山区","丛台区","复兴区","峰峰矿区","肥乡区","永年区","临漳县","成安县","大名县","涉县","磁县","邱县","鸡泽县","广平县","馆陶县","魏县","曲周县","邯郸经济技术开发区","邯郸冀南新区","武安市"],"邢台市":["襄都区","信都区","任泽区","南和区","临城县","内丘县","柏乡县","隆尧县","宁晋县","巨鹿县","新河县","广宗县","平乡县","威县","清河县","临西县","河北邢台经济开发区","南宫市","沙河市"],"保定市":["竞秀区","莲池区","满城区","清苑区","徐水区","涞水县","���平县","定兴县","唐县","高阳县","容城县","涞源县","望都县","安新县","易县","曲阳县","蠡县","顺平县","博野县","雄县","保定高新技术产业开发区","保定白沟新城","涿州市","定州市","安国市","高碑店市"],"张家口市":["桥东区","桥西区","宣化区","下花园区","万全区","崇礼区","张北县","康保县","沽源县","尚义县","蔚县","阳原县","怀安县","怀来县","涿鹿县","赤城县","张家口经济开发区","张家口市察北管理区","张家口市塞北管理区"],"承德市":["双桥区","双滦区","鹰手营子矿区","承德县","兴隆县","滦平县","隆化县","丰宁满族自治县","宽城满族自治县","围场满族蒙古族自治县","承德高新技术产业开发区","平泉市"],"沧州市":["新华区","运河区","沧县","青县","东光县","海兴县","盐山县","肃宁县","南皮县","吴桥县","献县","孟村回族自治县","河北沧州经济开发区","沧州高新技术产业开发区","沧州���海新区","泊头市","任丘市","黄骅市","河间市"],"廊坊市":["安次区","广阳区","固安县","永清县","香河县","大城县","文安县","大厂回族自治县","廊坊经济技术开发区","霸州市","三河市"],"衡水市":["桃城区","冀州区","枣强县","武邑县","武强县","饶阳县","安平县","故城县","景县","阜城县","河北衡水高新技术产业开发区","衡水滨湖新区","深州市"]},"山西省":{"太原市":["小店区","迎泽区","杏花岭区","尖草坪区","万柏林区","晋源区","清徐县","阳曲县","娄烦县","山西转型综合改革示范区","古交市"],"大同市":["新荣区","平城区","云冈区","云州区","阳高县","天镇县","广灵县","灵丘县","浑源县","左云县","山西大同经济开发区"],"阳泉市":["城区","矿区","郊区","平定县","盂县"],"长治市":["潞州区","上党区","屯留区","潞城区","襄垣县","平顺县","黎城县","壶关县","长子县","武乡县","沁县","沁源县"],"晋城市":["城区","沁水县","阳城县","陵川县","泽州县","高平市"],"朔州市":["朔城区","平鲁区","山阴县","应县","右玉县","山西朔州经济开发区","怀仁市"],"晋中市":["榆次区","太谷区","榆社县","左权县","和顺县","昔阳县","寿阳县","祁县","平遥县","灵石县","介休市"],"运城市":["盐湖区","临猗县","万荣县","闻喜县","稷山县","新绛县","绛县","垣曲县","夏县","平陆县","芮城县","永济市","河津市"],"忻州市":["忻府区","定襄县","五台县","代县","繁峙县","宁武县","静乐县","神池县","五寨县","岢岚县","河曲县","保德县","偏关县","五台山风景名胜区","原平市"],"临汾市":["尧都区","曲沃县","翼城县","襄汾县","洪洞县","古县","安泽县","浮山县","吉县","乡���县","大宁县","隰县","永和县","蒲县","汾西县","侯马市","霍州市"],"吕梁市":["离石区","文水县","交城县","兴县","临县","柳林县","石楼县","岚县","方山县","中阳县","交口县","孝义市","汾阳市"]},"内蒙古自治区":{"呼和浩特市":["新城区","回民区","玉泉区","赛罕区","土默特左旗","托克托县","和林格尔县","清水河县","武川县","呼和浩特经济技术开发区"],"包头市":["东河区","昆都仑区","青山区","石拐区","白云鄂博矿区","九原区","土默特右旗","固阳县","达尔罕茂明安联合旗","包头稀土高新技术产业开发区"],"乌海市":["海勃湾区","海南区","乌达区"],"赤峰市":["红山区","元宝山区","松山区","阿鲁科尔沁旗","巴林左旗","巴林右旗","林西县","克什克腾旗","翁牛特旗","喀喇沁旗","宁城县","敖汉旗"],"通辽市":["科尔沁区","科尔沁左翼中旗","科尔沁左翼后旗","开鲁县","库伦旗","���曼旗","扎鲁特旗","通辽经济技术开发区","霍林郭勒市"],"鄂尔多斯市":["东胜区","康巴什区","达拉特旗","准格尔旗","鄂托克前旗","鄂托克旗","杭锦旗","乌审旗","伊金霍洛旗"],"呼伦贝尔市":["海拉尔区","扎赉诺尔区","阿荣旗","莫力达瓦达斡尔族自治旗","鄂伦春自治旗","鄂温克族自治旗","陈巴尔虎旗","新巴尔虎左旗","新巴尔虎右旗","满洲里市","牙克石市","扎兰屯市","额尔古纳市","根河市"],"巴彦淖尔市":["临河区","五原县","磴口县","乌拉特前旗","乌拉特中旗","乌拉特后旗","杭锦后旗"],"乌兰察布市":["集宁区","卓资县","化德县","商都县","兴和县","凉城县","察哈尔右翼前旗","察哈尔右翼中旗","察哈尔右翼后旗","四子王旗","丰镇市"],"兴安盟":["乌兰浩特市","阿尔山市","科尔沁右翼前旗","科尔沁右翼中旗","扎赉特旗","突泉县"],"锡林郭勒盟":["二连浩特市","锡林浩特市","阿巴嘎旗","苏尼特左旗","苏尼特右旗","东乌珠穆沁旗","西乌珠穆沁旗","太仆��旗","镶黄旗","正镶白旗","正蓝旗","多伦县","乌拉盖管理区管委会"],"阿拉善盟":["阿拉善左旗","阿拉善右旗","额济纳旗","内蒙古阿拉善高新技术产业开发区"]},"辽宁省":{"沈阳市":["和平区","沈河区","大东区","皇姑区","铁西区","苏家屯区","浑南区","沈北新区","于洪区","辽中区","康平县","法库县","新民市"],"大连市":["中山区","西岗区","沙河口区","甘井子区","旅顺口区","金州区","普兰店区","长海县","瓦房店市","庄河市"],"鞍山市":["铁东区","铁西区","立山区","千山区","台安县","岫岩满族自治县","海城市"],"抚顺市":["新抚区","东洲区","望花区","顺城区","抚顺县","新宾满族自治县","清原满族自治县"],"本溪市":["平山区","溪湖区","明山区","南芬区","本溪满族自治县","桓仁满族自治县"],"丹东市":["元宝区","振兴区","振安区","宽甸满族自治县","东港市","凤城市"],"锦州市":["古塔区","凌河区","太和区","黑山县","义县","凌海市","北镇市"],"营口市":["站前区","西市区","鲅鱼圈区","老边区","盖州市","大石桥市"],"阜新市":["海州区","新邱区","太平区","清河门区","细河区","阜新蒙古族自治县","彰武县"],"辽阳市":["白塔区","文圣区","宏伟区","弓长岭区","太子河区","辽阳县","灯塔市"],"盘锦市":["双台子区","兴隆台区","大洼区","盘山县"],"铁岭市":["银州区","清河区","铁岭县","西丰县","昌图县","调兵山市","开原市"],"朝阳市":["双塔区","龙城区","朝阳县","建平县","喀喇沁左翼蒙古族自治县","北票市","凌源市"],"葫芦岛市":["连山区","龙港区","南票区","绥中县","建昌县","兴城市"]},"吉林省":{"长春市":["南关区","宽城区","朝阳区","二道区","绿园区","双阳区","九台区","农安县","长春经济技术开发区","长��净月高新技术产业开发区","长春高新技术产业开发区","长春汽车经济技术开发区","榆树市","德惠市","公主岭市"],"吉林市":["昌邑区","龙潭区","船营区","丰满区","永吉县","吉林经济开发区","吉林高新技术产业开发区","吉林中国新加坡食品区","蛟河市","桦甸市","舒兰市","磐石市"],"四平市":["铁西区","铁东区","梨树县","伊通满族自治县","双辽市"],"辽源市":["龙山区","西安区","东丰县","东辽县"],"通化市":["东昌区","二��江区","通化县","辉南县","柳河县","梅河口市","集安市"],"白山市":["浑江区","江源区","抚松县","靖宇县","长白朝鲜族自治县","临江市"],"松原市":["宁江区","前郭尔罗斯蒙古族自治县","长岭县","乾安县","吉林松原经济开发区","扶余市"],"白城市":["洮北区","镇赉县","通榆县","吉林白城经济开发区","洮南市","大安市"],"延边朝鲜族自治州":["延吉市","图们市","敦化市","珲春市","龙井市","和龙市","汪清县","安图县"]},"黑龙江省":{"哈尔滨市":["道里区","南岗区","道外区","平房区","松北区","香坊区","呼兰区","阿城区","双城区","依兰县","方正县","宾县","巴彦县","木兰县","通河县","延寿县","尚志市","五常市"],"齐齐哈尔市":["龙沙区","建华区","铁锋区","昂昂溪区","富拉尔基区","碾子山区","梅里斯达斡尔族区","龙江县","依安县","泰来县","甘南县","富裕县","���山县","克东县","拜泉县","讷河市"],"鸡西市":["鸡冠区","恒山区","滴道区","梨树区","城子河区","麻山区","鸡东县","虎林市","密山市"],"鹤岗市":["向阳区","工农区","南山区","兴安区","东山区","兴山区","萝北县","绥滨县"],"双鸭山市":["尖山区","岭东区","四方台区","宝山区","集贤县","友谊县","宝清县","饶河县"],"大庆市":["萨尔图区","龙凤区","让胡路区","红岗区","大同区","肇州县","肇源县","林甸县","杜尔伯特蒙古族自治县","大庆高新技术产业开发区"],"伊春市":["伊美区","乌翠区","友好区","嘉荫县","汤旺县","丰林县","大箐山县","南岔县","金林区","铁力市"],"佳木斯市":["向阳区","前进区","东风区","郊区","桦南县","桦川县","汤原县","同江市","富锦市","抚远市"],"七台河市":["新兴区","桃山区","茄子河区","勃利县"],"牡丹江市":["东安区","阳明区","爱民区","西安区","林口县","绥芬河市","海林市","宁安市","穆棱市","东宁市"],"黑河市":["爱辉区","逊克县","孙吴县","北安市","五大连池市","嫩江市"],"绥化市":["北林区","望奎县","兰西县","青冈县","庆安县","明水县","绥棱县","安达市","肇东市","海伦市"],"大兴安岭地区":["漠河市","呼玛县","塔河县","加格达奇区","松岭区","新林区","呼中区"]},"上海市":{"市辖区":["黄浦区","徐汇区","长宁区","静安区","普陀区","虹口区","杨浦区","闵行区","宝山区","嘉定区","浦东新区","金山区","松江区","青浦区","奉贤区","崇明区"]},"江苏省":{"南京市":["玄武区","秦淮区","建邺区","鼓楼区","浦口区","栖霞区","雨花台区","江宁区","六合区","溧水区","高淳区"],"无锡市":["锡山区","惠山区","滨湖区","梁溪区","新吴区","江阴市","宜兴市"],"徐州市":["鼓楼区","云龙区","贾汪区","泉山区","铜山区","丰县","沛县","睢宁县","徐州经济技术开发区","新沂市","邳州市"],"常州市":["天宁区","钟楼区","新北区","武进区","金坛区","溧阳市"],"苏州市":["虎丘区","吴中区","相城区","姑苏区","吴江区","苏州工业园区","常熟市","张家港市","昆山市","太仓市"],"南通市":["通州区","崇川区","海门区","如东县","南通经济技术开发区","启东市","如皋市","海安市"],"连云港市":["连云区","海州区","赣榆区","东海县","灌云县","灌南县","连云港经济技术开发区"],"淮安市":["淮安区","淮阴区","清江浦区","洪泽区","涟水县","盱眙县","金湖县","淮安经济技术开发区"],"盐城市":["亭湖区","盐都区","大丰区","响水县","滨海县","阜宁县","射阳县","建湖县","盐城经济技术开发区","东台市"],"扬州市":["广陵区","邗江区","江都区","宝应县","扬州经济技术开发区","仪征市","高邮市"],"镇江市":["京口区","润州区","丹徒区","镇江新区","丹阳市","扬中市","句容市"],"泰州市":["海陵区","高港区","姜堰区","兴化市","靖江市","泰兴市"],"宿迁市":["宿城区","宿豫区","沭阳县","泗阳县","泗洪县","宿迁经济技术开发区"]},"浙江省":{"杭州市":["上城区","拱墅区","西湖区","滨江区","萧山区","余杭区","富阳区","临安区","临平区","钱塘区","桐庐县","淳安县","建德市"],"宁波市":["海曙区","江北区","北仑区","镇海区","鄞州区","奉化区","象山县","宁海县","余姚市","慈溪市"],"温州市":["鹿城区","龙湾区","瓯海区","洞头区","��嘉县","平阳县","苍南县","文成县","泰顺县","瑞安市","乐清市","龙港市"],"嘉兴市":["南湖区","秀洲区","嘉善县","海盐县","海宁市","平湖市","桐乡市"],"湖州市":["吴兴区","南浔区","德清县","长兴县","安吉县"],"绍兴市":["越城区","柯桥区","上虞区","新昌县","诸暨市","嵊州市"],"金华市":["婺城区","金东区","武义县","浦江县","磐安县","兰溪市","义���市","东阳市","永康市"],"衢州市":["柯城区","衢江区","常山县","开化县","龙游县","江山市"],"舟山市":["定海区","普陀区","岱山县","嵊泗县"],"台州市":["椒江区","黄岩区","路桥区","三门县","天台县","仙居县","温岭市","临海市","玉环市"],"丽水市":["莲都区","青田县","缙云县","遂昌县","松阳县","云和县","庆元县","景宁畲族自治县","龙泉市"]},"安徽省":{"合肥市":["瑶海区","庐阳区","蜀山区","包河区","长丰县","肥东县","肥西县","庐江县","合肥高新技术产业开发区","合肥经济技术开发区","合肥新站高新技术产业开发区","巢湖市"],"芜湖市":["镜湖区","鸠江区","弋江区","湾沚区","繁昌区","南陵县","芜湖经济技术开发区","安徽芜湖三山经济开发区","无为市"],"蚌埠市":["龙子湖区","蚌山区","禹会区","淮上区","怀远县","五河县","固镇县","蚌埠市高新技术开发区","蚌埠��经济开发区"],"淮南市":["大通区","田家庵区","谢家集区","八公山区","潘集区","凤台县","寿县"],"马鞍山市":["花山区","雨山区","博望区","当涂县","含山县","和县"],"淮北市":["杜集区","相山区","烈山区","濉溪县"],"铜陵市":["铜官区","义安区","郊区","枞阳县"],"安庆市":["迎江区","大观区","宜秀区","怀宁县","太湖县","宿松县","望江县","岳西县","安徽安庆经济开发区","桐城市","潜山市"],"黄山市":["屯溪区","黄山区","徽州区","歙县","休宁县","黟县","祁门县"],"滁州市":["琅琊区","南谯区","来安县","全椒县","定远县","凤阳县","中新苏滁高新技术产业开发区","滁州经济技术开发区","天长市","明光市"],"阜阳市":["颍州区","颍东区","颍泉区","临泉县","太和县","阜南县","颍上县","阜阳合肥现代产业园区","阜阳经济技术开发区","界首市"],"宿州市":["埇桥区","砀山县","萧县","灵璧县","泗县","宿州马鞍山现代产业园区","宿州经济技术开发区"],"六安市":["金安区","裕安区","叶集区","霍邱县","舒城县","金寨县","霍山县"],"亳州市":["谯城区","涡阳县","蒙城县","利辛县"],"池州市":["贵池区","东至县","石台县","青阳县"],"宣城市":["宣州区","郎溪县","泾县","绩溪县","旌德县","宣城市经济开发区","宁国市","广德市"]},"福建省":{"福州市":["鼓楼区","台江区","仓山区","马尾区","晋安区","长乐区","闽侯县","连江县","罗源县","闽清县","永泰县","平潭县","福清市"],"厦门市":["思明区","海沧区","湖里区","集美区","同安区","翔安区"],"莆田市":["城厢区","涵江区","荔城区","秀屿区","仙游县"],"三明市":["三元区","沙县区","明溪县","清流县","宁化县","大田县","尤溪县","将乐县","泰宁县","建宁县","永安市"],"泉州市":["鲤城区","丰泽区","洛江区","泉港区","惠安县","安溪县","永春县","德化县","金门县","石狮市","晋江市","南安市"],"漳州市":["芗城区","龙文区","龙海区","长泰区","云霄县","漳浦县","诏安县","东山县","南靖县","平和县","华安县"],"南平市":["延平区","建阳区","顺昌县","浦城县","光泽县","松溪县","政和县","邵武市","武夷山市","建瓯市"],"龙岩市":["新罗区","永定区","长汀县","上杭县","武平县","连城县","漳平市"],"宁德市":["蕉城区","霞浦县","古田县","屏南县","寿宁县","周宁县","柘荣县","福安市","福鼎市"]},"江西省":{"南昌市":["东湖区","西湖区","青云谱区","青山湖区","新建区","红谷滩区","南昌县","安义县","进贤县"],"景德镇市":["昌江区","珠山区","浮梁县","乐平市"],"萍乡市":["安源区","湘东区","莲花县","上栗县","芦溪县"],"九江市":["濂溪区","浔阳区","柴桑区","武宁县","修水县","永修县","德安县","都昌县","湖口县","彭泽县","瑞昌市","共青城市","庐山市"],"新余市":["渝水区","分宜县"],"鹰潭市":["月湖区","余江区","贵溪市"],"赣州市":["章贡区","南康区","赣县区","信丰县","大余县","上犹县","崇义县","安远县","定南县","全南县","宁都县","于都县","兴国县","会昌县","寻乌县","石城县","瑞金市","龙南市"],"吉安市":["吉州区","青原区","吉安县","吉水县","峡江县","新干县","永丰县","泰和县","遂川县","万安县","安福县","永新县","井冈山市"],"宜春市":["袁州区","奉新县","万载县","上高县","宜丰县","靖安县","铜鼓县","丰城市","樟树市","高安市"],"抚州市":["临川区","东乡区","南城县","黎川县","南丰县","崇仁县","乐安县","宜黄县","金溪县","资溪县","广昌县"],"上饶市":["信州区","广丰区","广信区","玉山县","铅山县","横峰县","弋阳县","余干县","鄱阳县","万年县","婺源县","德兴市"]},"山东省":{"济南市":["历下区","市中区","槐荫区","天桥区","历城区","长清区","章丘区","济阳区","莱芜区","钢城区","平阴县","商河县","济南高新技术产业开发区"],"青岛市":["市南区","市北区","黄岛区","崂山区","李沧区","城阳区","即墨区","胶州市","平度市","莱西市"],"淄博市":["淄川区","张店区","博山区","临淄区","周村区","桓台县","高青县","沂源县"],"枣庄市":["市中区","薛城区","峄城区","台儿庄区","山亭区","滕州市"],"东营市":["东营区","河口区","垦利区","利津县","广饶县","东营经济技术开发区","东营港经济开发区"],"烟台市":["芝罘区","福山区","牟平区","莱山区","蓬莱区","烟台高新技术产业开发区","烟台经济技术开发区","龙口市","莱阳市","莱州市","招远市","栖霞市","海阳市"],"潍坊市":["潍城区","寒亭区","坊子区","奎文区","临朐县","昌乐县","潍坊滨海经济技术开发区","青州市","诸城市","寿光市","安丘市","高密市","昌邑市"],"济宁市":["任城区","兖州区","微山县","鱼台县","金乡县","嘉祥县","汶上县","泗水县","梁山县","济宁高新技术产业开发区","曲阜市","邹城市"],"泰安市":["泰山区","岱岳区","宁阳县","东平县","新泰市","肥城市"],"威海市":["环翠区","文登区","威海火炬高技术产业开发区","威海经济技术开发区","威海临港经济技术开发区","荣成市","乳山市"],"日照市":["东港区","岚山区","五莲县","莒县","日照经济技术开发区"],"临沂市":["兰山区","罗庄区","河东区","沂南县","郯城县","沂水县","兰陵县","费县","平邑县","莒南县","蒙阴县","临沭县","临沂高新技术产业开发区"],"德州市":["德城区","陵城区","宁津县","庆云县","临邑县","齐河县","平原县","夏津县","武城县","德州天衢新区","乐陵市","禹城市"],"聊城市":["东昌府区","茌平区","阳谷县","莘县","东阿县","冠县","高唐县","临清市"],"滨州市":["滨城区","沾化区","惠民县","阳信县","无棣县","博兴县","邹平市"],"菏泽市":["牡丹区","定陶区","曹县","单县","成武县","巨野县","郓城县","鄄城县","东明县","菏泽经济技术开发区","菏泽高新技术开发区"]},"河南省":{"郑州市":["中原区","二七区","管城回族区","金水区","上街区","惠济区","中牟县","郑州经济技术开发区","郑州高新技术产业开发区","郑州航空港经济综合实验区","巩义市","荥阳市","新密市","新郑市","登封市"],"开封市":["龙亭区","顺河回族区","鼓楼区","禹王台区","祥符区","杞县","通许县","尉氏县","兰考县"],"洛阳市":["老城区","西工区","瀍河回族区","涧西区","偃师区","孟津区","洛龙区","新安县","栾川县","嵩县","汝阳县","宜阳县","洛宁县","伊川县","洛阳高新技术产业开发区"],"平顶山市":["新华区","卫东区","石龙区","湛河区","宝丰县","叶县","鲁山县","郏县","平顶山高新技术产业开发区","平顶山市城乡一体化示范区","舞钢市","汝州市"],"安阳市":["文峰区","北关区","殷都区","龙安区","安阳县","汤阴县","滑县","内黄县","安阳高新技术产业开发区","林州市"],"鹤壁市":["鹤山区","山城区","淇滨区","浚县","淇县","鹤壁经济技术开发区"],"新乡市":["红旗���","卫滨区","凤泉区","牧野区","新乡县","获嘉县","原阳县","延津县","封丘县","新乡高新技术产业开发区","新乡经济技术开发区","新乡市平原城乡一体化示范区","卫辉市","辉县市","长垣市"],"焦作市":["解放区","中站区","马村区","山阳区","修武县","博爱县","武陟县","温县","焦作城乡一体化示范区","沁阳市","孟州市"],"濮阳市":["华龙区","清丰县","南乐县","范县","台前县","濮阳县","河南濮阳工业园区","濮阳经济技术开发区"],"许昌市":["魏都区","建安区","鄢陵县","襄城县","许昌经济技术开发区","禹州市","长葛市"],"漯河市":["源汇区","郾城区","召陵区","舞阳县","临颍县","漯河经济技术开发区"],"三门峡市":["湖滨区","陕州区","渑池县","卢氏县","河南三门峡经济开发区","义马市","灵宝市"],"南阳市":["宛城区","卧龙区","南召县","方城县","西峡县","镇平县","内乡县","淅川县","社旗县","唐河县","新野县","桐柏县","南阳高新技术产业开发区","南阳市城乡一体化示范区","邓州市"],"商丘市":["梁园区","睢阳区","民权县","睢县","宁陵县","柘城县","虞城县","夏邑县","豫东综合物流产业聚集区","河南商丘经济开发区","永城市"],"信阳市":["浉河区","平桥区","罗山县","光山县","新县","商城县","固始县","潢川县","淮滨县","息县","信阳高新技术产业开发区"],"周口市":["川汇区","淮阳区","扶沟县","西华县","商水县","沈丘县","郸城县","太康县","鹿邑县","周口临港开发区","项城市"],"驻马店市":["驿城区","西平县","上蔡县","平舆县","正阳县","确山县","泌阳县","汝南县","遂平县","新蔡县","河南驻马店经济开发区"],"省直辖县级行政区划":["济源市"]},"湖北省":{"武汉市":["江岸区","江汉区","硚口区","汉阳区","武昌区","青山区","洪山区","东西湖区","汉南区","蔡甸区","江夏区","黄陂区","新洲区"],"黄石市":["黄石港区","西塞山区","下陆区","铁山区","阳新县","大冶市"],"十堰市":["茅箭区","张湾区","郧阳区","郧西县","竹山县","竹溪县","房县","丹江口市"],"宜昌市":["西陵区","伍家岗区","点军区","猇亭区","夷陵区","远安县","兴山县","秭归县","长阳土家族自治县","五峰土家族自治县","宜都市","当阳市","枝江市"],"襄阳市":["襄城区","樊城区","襄州区","南漳县","谷城县","保康县","老河口市","枣阳市","宜城市"],"鄂州市":["梁子湖区","华容区","鄂城区"],"荆门市":["东宝区","掇刀区","沙洋县","钟祥市","京山市"],"孝感市":["孝南区","孝昌县","大悟县","云梦县","应城市","安陆市","汉川市"],"荆州市":["沙市区","荆州区","公安县","江陵县","荆州经济技术开发区","石首市","洪湖市","松滋市","监利市"],"黄冈市":["黄州区","团风县","红安县","罗田县","英山县","浠水县","蕲春县","黄梅县","龙感湖管理区","麻城市","武穴市"],"咸宁市":["咸安区","嘉鱼县","通城县","崇阳县","通山县","赤壁市"],"随州市":["曾都区","随县","广水市"],"恩施土家族苗族自治州":["恩施市","利川市","建始县","巴东县","宣恩县","咸丰县","来凤县","鹤峰县"],"省直辖县级行政区划":["仙桃市","潜江市","天门市","神农架林区"]},"湖南省":{"长沙市":["芙蓉区","天心区","岳麓区","开福区","雨花区","望城区","长沙县","浏阳市","宁乡市"],"株洲市":["荷塘区","芦淞区","石峰区","天元区","渌口区","攸县","茶陵县","炎陵县","醴陵市"],"湘潭市":["雨湖区","岳塘区","湘潭县","湖南湘潭高新技术产业园区","湘潭昭山示范区","湘潭九华示范区","湘乡市","韶山市"],"衡阳市":["珠晖区","雁峰区","石鼓区","蒸湘区","南岳区","衡阳县","衡南县","衡山县","衡东县","祁东县","湖南衡阳松木经济开发区","湖南衡阳高新技术产业园区","耒阳市","常宁市"],"邵阳市":["双清区","大祥区","北塔区","新邵县","邵阳县","隆回县","洞口县","绥宁县","新宁县","城步苗族自治县","武冈市","邵东市"],"岳阳市":["岳阳楼区","云溪区","君山区","岳阳县","华容县","湘阴县","平江县","岳阳市屈原管理区","汨罗市","临湘市"],"常德市":["武陵区","鼎城区","安乡县","汉寿县","澧县","临澧县","桃源县","石门县","常德市西洞庭管理区","津市市"],"张家界市":["永定区","武陵源区","慈利县","桑植县"],"益阳市":["资阳区","赫山区","南县","桃江县","安化县","益阳市大通湖管理区","湖南益阳高新技术产业园区","沅江市"],"郴州市":["北湖区","苏仙区","桂阳县","宜章县","永兴县","嘉禾县","临武县","汝城县","桂东县","安仁县","资兴市"],"永州市":["零陵区","冷水滩区","东安县","双牌县","道县","江永县","宁远县","蓝山县","新田县","江华瑶族自治县","永州经济技术开发区","永州市回龙圩管理区","祁阳市"],"怀化市":["鹤城区","中方县","沅陵县","辰溪县","溆浦县","会同县","麻阳苗族自治县","新晃侗族自治县","芷江侗族自治县","靖州苗族侗族自治县","通道侗族自治县","怀化市洪江管理区","洪江市"],"娄底市":["娄星区","双峰县","新化县","冷水江市","涟源市"],"湘西土家族苗族自治州":["吉首市","泸溪县","凤凰县","花垣县","保靖县","古丈县","永顺县","龙山县"]},"广东省":{"广州市":["荔湾区","越秀区","海珠区","天河区","白云区","黄埔区","番禺区","花都区","南沙区","从化区","增城区"],"韶关市":["武江区","浈江区","曲江区","始兴县","仁化县","翁源县","乳源瑶族自治县","新丰县","乐昌市","南雄市"],"深圳市":["罗湖区","福田区","南山区","宝安区","龙岗区","盐田区","龙华区","坪山区","光明区"],"珠海市":["香洲区","斗门区","金湾区"],"汕头市":["龙湖区","金平区","濠江区","潮阳区","潮南区","澄海区","南澳县"],"佛山市":["禅城区","南海区","顺德区","三水区","高明区"],"江门市":["蓬江区","江海区","新会区","台山市","开平市","鹤山市","恩平市"],"湛江市":["赤坎区","霞山区","坡头区","麻章区","遂溪县","徐闻县","廉江市","雷州市","吴川市"],"茂名市":["茂南区","电白区","高州市","化州市","信宜市"],"肇庆市":["端州区","鼎湖区","高要区","广宁县","怀集县","封开县","德庆县","四会市"],"惠州市":["惠城区","惠阳区","博罗县","惠东县","龙门县"],"梅州市":["梅江区","梅县区","大埔县","丰顺县","五华县","平远县","蕉岭县","兴宁市"],"汕尾市":["城区","海丰县","陆河县","陆丰市"],"河源市":["源城区","紫金县","龙川县","连平县","和平县","东源县"],"阳江市":["江城区","阳东区","阳西县","阳春市"],"清远市":["清城区","清新区","佛冈县","阳山县","连山壮族瑶族自治县","连南瑶族自治县","英德市","连州市"],"东莞市":["东城街道","南城街道","万江街道","莞城街道","石碣镇","石龙镇","茶山镇","石排镇","企石镇","横沥镇","桥头镇","谢岗镇","东坑镇","常平镇","寮步镇","樟木头镇","大朗镇","黄江镇","清溪镇","塘厦镇","凤岗镇","大岭山镇","长安镇","虎门镇","厚街镇","沙田镇","道滘镇","洪梅镇","麻涌镇","望牛墩镇","中堂镇","高埗镇","松山湖","东莞港","东莞生态园","东莞滨海湾新区"],"中山市":["石岐街道","东区街道","中山港街道","西区街道","南区街道","五桂山街道","民众街道","南朗街道","黄圃镇","东凤镇","古镇镇","沙溪镇","坦洲镇","港口镇","三角镇","横栏镇","南头镇","阜沙镇","三乡镇","板芙镇","大涌镇","神湾镇","小榄镇"],"潮州市":["湘桥区","潮安区","饶平县"],"揭阳市":["榕城区","揭东区","揭西县","惠来县","普宁市"],"云浮市":["云城区","云安区","新兴县","郁南县","罗定市"]},"广西壮族自治区":{"南宁市":["兴宁区","青秀区","江南区","西乡塘区","良庆区","邕宁区","武鸣区","隆安县","马山县","上林县","宾阳县","横州市"],"柳州市":["城中区","鱼峰区","柳南区","柳北区","柳江区","柳城县","鹿寨县","融安县","融水苗族自治县","三江侗族自治县"],"桂林市":["秀峰区","叠彩区","象山区","七星区","雁山区","临桂区","阳朔县","灵川县","全州县","兴安县","永福县","灌阳县","龙胜各族自治县","资源县","平乐县","恭城瑶族自治县","荔浦市"],"梧州市":["万秀区","长洲区","龙圩区","苍梧县","藤县","蒙山县","岑溪市"],"北海市":["海城区","银海区","铁山港区","合浦县"],"防城港市":["港口区","防城区","上思县","东兴市"],"钦州市":["钦南区","钦北区","灵山县","浦北县"],"贵港市":["港北区","港南区","覃塘区","平南县","桂平市"],"玉林市":["玉州区","福绵区","容县","陆川县","博白县","兴业县","北流市"],"百色市":["右江区","田阳区","田东县","德保县","那坡县","凌云县","乐业县","田林县","西林县","隆林各族自治县","靖西市","平果市"],"贺州市":["八步区","平桂区","昭平县","钟山县","富川瑶族自治县"],"河池市":["金城江区","宜州区","南丹县","天峨县","凤山县","东兰县","罗城仫佬族自治县","环江毛南族自治县","巴马瑶族自治县","都安瑶族自治县","大化瑶族自治县"],"来宾市":["兴宾区","忻城县","象州县","武宣县","金秀瑶族自治县","合山市"],"崇左市":["江州区","扶绥县","宁明县","龙州县","大新县","天等县","凭祥市"]},"海南省":{"海口市":["秀英区","龙华区","琼山区","美兰区"],"三亚市":["海棠区","吉阳区","天涯区","崖州区"],"三沙市":["西沙群岛","南沙群岛","中沙群岛的岛礁及其海域"],"儋州市":["那大镇","和庆镇","南丰镇","大成镇","雅星镇","兰洋镇","光村镇","木棠镇","海头镇","峨蔓镇","王五镇","白马井镇","中和镇","排浦镇","东成镇","新州镇","洋浦经济开发区","华南热作学院"],"省直辖县级行政区划":["五指山市","琼海市","文昌市","万宁市","东方市","定安县","屯昌县","澄迈县","临高县","白沙黎族自治县","昌江黎族自治县","乐东黎族自治县","陵水黎族自治县","保亭黎族苗族自治县","琼中黎族苗族自治县"]},"重庆市":{"市辖区":["万州区","涪陵区","渝中区","大渡口区","江北区","沙坪坝区","九龙坡区","南岸区","北碚区","綦江区","大足区","渝北区","巴南区","黔江区","长寿区","江津区","合川区","永川区","南川区","璧山区","铜梁区","潼南区","荣昌区","开州区","梁平区","武隆区"],"县":["城口县","丰都县","垫江县","忠县","云阳县","奉节县","巫山县","巫溪县","石柱土家族自治县","秀山土家族苗族自治县","酉阳土家族苗族自治县","彭水苗族土家族自治县"]},"四川省":{"成都市":["锦江区","青羊区","金牛区","武侯区","成华区","龙泉驿区","青白江区","新都区","温江区","双流区","郫都区","新津区","金堂县","大邑县","蒲江县","都江堰市","彭州市","邛崃市","崇州市","简阳市"],"自贡市":["自流井区","贡井区","大安区","沿滩区","荣县","富顺县"],"攀枝花市":["东区","西区","仁和区","米易县","盐边县"],"泸州市":["江阳区","纳溪区","龙马潭区","泸县","合江县","叙永县","古蔺县"],"德阳市":["旌阳区","罗江区","中江县","广汉市","什邡市","绵竹市"],"绵阳市":["涪城区","游仙区","安州区","三台县","盐亭县","梓潼县","北川羌族自治县","平武县","江油市"],"广元市":["利州区","昭化区","朝天区","旺苍县","青川县","剑阁县","苍溪县"],"遂宁市":["船山区","安居区","蓬溪县","大英县","射洪市"],"内江市":["市中区","东兴区","威远县","资中县","隆昌市"],"乐山市":["市中区","沙湾区","五通桥区","金口河区","犍为县","井研县","夹江县","沐川县","峨边彝族自治县","马边彝族自治县","峨眉山市"],"南充市":["顺庆区","高坪区","嘉陵区","南部县","营山县","蓬安县","仪陇县","西充县","阆中市"],"眉山市":["东坡区","彭山区","仁寿县","洪雅县","丹棱县","青神县"],"宜宾市":["翠屏区","南溪区","叙州区","江安县","长宁县","高县","珙县","筠连县","兴文县","屏山县"],"广安市":["广安区","前锋区","岳池县","武胜县","邻水县","华蓥市"],"达州市":["通川区","达川区","宣汉县","开江县","大竹县","渠县","万源市"],"雅安市":["雨城区","名山区","荥经县","汉源县","石棉县","天全县","芦山县","宝兴县"],"巴中市":["巴州区","恩阳区","通江县","南江县","平昌县"],"资阳市":["雁江区","安岳县","乐至县"],"阿坝藏族羌族自治州":["马尔康市","汶川县","理县","茂县","松潘县","九寨沟县","金川县","小金县","黑水县","壤塘县","阿坝县","若尔盖县","红原县"],"甘孜藏族自治州":["康定市","泸定县","丹巴县","九龙县","雅江县","道孚县","炉霍县","甘孜县","新龙县","德格县","白玉县","石渠县","色达县","理塘县","巴塘县","乡城县","稻城县","得荣县"],"凉山彝族自治州":["西昌市","会理市","木里藏族自治县","盐源县","德昌县","会东县","宁南县","普格县","布拖县","金阳县","昭觉县","喜德县","冕宁县","越西县","甘洛县","美姑县","雷波县"]},"贵州省":{"贵阳市":["南明区","云岩区","花溪区","乌当区","白云区","观山湖区","开阳县","息烽县","修文县","清镇市"],"六盘水市":["钟山区","六枝特区","水城区","盘州市"],"遵义市":["红花岗区","汇川区","播州区","桐梓县","绥阳县","正安县","道真仡佬族苗族自治县","务川仡佬族苗族自治县","凤冈县","湄潭县","余庆县","习水县","赤水市","仁怀市"],"安顺市":["西秀区","平坝区","普定县","镇宁布依族苗族自治县","关岭布依族苗族自治县","紫云苗族布依族自治县"],"毕节市":["七星关区","大方县","金沙县","织金县","纳雍县","威宁彝族回族苗族自治县","赫章县","黔西市"],"铜仁市":["碧江区","万山区","江口县","玉屏侗族自治县","石阡县","思南县","印江土家族苗族自治县","德江县","沿河土家族自治县","松桃苗族自治县"],"黔西南布依族苗族自治州":["兴义市","兴仁市","普安县","晴隆县","贞丰县","望谟县","册亨县","安龙县"],"黔东南苗族侗族自治州":["凯里市","黄平县","施秉县","三穗县","镇远县","岑巩县","天柱县","锦屏县","剑河县","台江县","黎平县","榕江县","从江县","雷山县","麻江县","丹寨县"],"黔南布依族苗族自治州":["都匀市","福泉市","荔波县","贵定县","瓮安县","独山县","平塘县","罗甸县","长顺县","龙里县","惠水县","三都水族自治县"]},"云南省":{"昆明市":["五华区","盘龙区","官渡区","西山区","东川区","呈贡区","晋宁区","富民县","宜良县","石林彝族自治县","嵩明县","禄劝彝族苗族自治县","寻甸回族彝族自治县","安宁市"],"曲靖市":["麒麟区","沾益区","马龙区","陆良县","师宗县","罗平县","富源县","会泽县","宣威市"],"玉溪市":["红塔区","江川区","通海县","华宁县","易门县","峨山彝族自治县","新平彝族傣族自治县","元江哈尼族彝族傣族自治县","澄江市"],"保山市":["隆阳区","施甸县","龙陵县","昌宁县","腾冲市"],"昭通市":["昭阳区","鲁甸县","巧家县","盐津县","大关县","永善县","绥江县","镇雄县","彝良县","威信县","水富市"],"丽江市":["古城区","玉龙纳西族自治县","永胜县","华坪县","宁蒗彝族自治县"],"普洱市":["思茅区","宁洱哈尼族彝族自治县","墨江哈尼族自治县","景东彝族自治县","景谷傣族彝族自治县","镇沅彝族哈尼族拉祜族自治县","江城哈尼族彝族自治县","孟连傣族拉祜族佤族自治县","澜沧拉祜族自治县","西盟佤族自治县"],"临沧市":["临翔区","凤庆县","云县","永德县","镇康县","双江拉祜族佤族布朗族傣族自治县","耿马傣族佤族自治县","沧源佤族自治县"],"楚雄彝族自治州":["楚雄市","禄丰市","双柏县","牟定县","南华县","姚安县","大姚县","永仁县","元谋县","武定县"],"红河哈尼族彝族自治州":["个旧市","开远市","蒙自市","弥勒市","屏边苗族自治县","建水县","石屏县","泸西县","元阳县","红河县","金平苗族瑶族傣族自治县","绿春县","河口瑶族自治县"],"文山壮族苗族自治州":["文山市","砚山县","西畴县","麻栗坡县","马关县","丘北县","广南县","富宁县"],"西双版纳傣族自治州":["景洪市","勐海县","勐腊县"],"大理白族自治州":["大理市","漾濞彝族自治县","祥云县","宾川县","弥渡县","南涧彝族自治县","巍山彝族回族自治县","永平县","云龙县","洱源县","剑川县","鹤庆县"],"德宏傣族景颇族自治州":["瑞丽市","芒市","梁河县","盈江县","陇川县"],"怒江傈僳族自治州":["泸水市","福贡县","贡山独龙族怒族自治县","兰坪白族普米族自治县"],"迪庆藏族自治州":["香格里拉市","德钦县","维西傈僳族自治县"]},"西藏自治区":{"拉萨市":["城关区","堆龙德庆区","达孜区","林周县","当雄县","尼木县","曲水县","墨竹工卡县","格尔木藏青工业园区","拉萨经济技术开发区","西藏文化旅游创意园区","达孜工业园区"],"日喀则市":["桑珠孜区","南木林县","江孜县","定日县","萨迦县","拉孜县","昂仁县","谢通门县","白朗县","仁布县","康马县","定结县","仲巴县","亚东县","吉隆县","聂拉木县","萨嘎县","岗巴县"],"昌都市":["卡若区","江达县","贡觉县","类乌齐县","丁青县","察雅县","八宿县","左贡县","芒康县","洛隆县","边坝县"],"林芝市":["巴宜区","工布江达县","墨脱县","波密县","察隅县","朗县","米林市"],"山南市":["乃东区","扎囊县","贡嘎县","桑日县","琼结县","曲松县","措美县","洛扎县","加查县","隆子县","浪卡子县","错那市"],"那曲市":["色尼区","嘉黎县","比如县","聂荣县","安多县","申扎县","索县","班戈县","巴青县","尼玛县","双湖县"],"阿里地区":["普兰县","札达县","噶尔县","日土县","革吉县","改则县","措勤县"]},"陕西省":{"西安市":["新城区","碑林区","莲湖区","灞桥区","未央区","雁塔区","阎良区","临潼区","长安区","高陵区","鄠邑区","蓝田县","周至县"],"铜川市":["王益区","印台区","耀州区","宜君县"],"宝鸡市":["渭滨区","金台区","陈仓区","凤翔区","岐山县","扶风县","眉县","陇县","千阳县","麟游县","凤县","太白县"],"咸阳市":["秦都区","杨陵区","渭城区","三原县","泾阳县","乾县","礼泉县","永寿县","长武县","旬邑县","淳化县","武功县","兴平市","彬州市"],"渭南市":["临渭区","华州区","潼关县","大荔县","合阳县","澄城县","蒲城县","白水县","富平县","韩城市","华阴市"],"延安市":["宝塔区","安塞区","延长县","延川县","志丹县","吴起县","甘泉县","富县","洛川县","宜川县","黄龙县","黄陵县","子长市"],"汉中市":["汉台区","南郑区","城固县","洋县","西乡县","勉县","宁强县","略阳县","镇巴县","留坝县","佛坪县"],"榆林市":["榆阳区","横山区","府谷县","靖边县","定边县","绥德县","米脂县","佳县","吴堡县","清涧县","子洲县","神木市"],"安康市":["汉滨区","汉阴县","石泉县","宁陕县","紫阳县","岚皋县","平利县","镇坪县","白河县","旬阳市"],"商洛市":["商州区","洛南县","丹凤县","商南县","山阳县","镇安县","柞水县"]},"甘肃省":{"兰州市":["城关区","七里河区","西固区","安宁区","红古区","永登县","皋兰县","榆中县","兰州新区"],"嘉峪关市":["雄关街道","钢城街道","新城镇","峪泉镇","文殊镇"],"金昌市":["金川区","永昌县"],"白银市":["白银区","平川区","靖远县","会宁县","景泰县"],"天水市":["秦州区","麦积区","清水县","秦安县","甘谷县","武山县","张家川回族自治县"],"武威市":["凉州区","民勤县","古浪县","天祝藏族自治县"],"张掖市":["甘州区","肃南裕固族自治县","民乐县","临泽县","高台县","山丹县"],"平凉市":["崆峒区","泾川县","灵台县","崇信县","庄浪县","静宁县","华亭市"],"酒泉市":["肃州区","金塔县","瓜州县","肃北蒙古族自治县","阿克塞哈萨克族自治县","玉门市","敦煌市"],"庆阳市":["西峰区","庆城县","环县","华池县","合水县","正宁县","宁县","镇原县"],"定西市":["安定区","通渭县","陇西县","渭源县","临洮县","漳县","岷县"],"陇南市":["武都区","成县","文县","宕昌县","康县","西和县","礼县","徽县","两当县"],"临夏回族自治州":["临夏市","临夏县","康乐县","永靖县","广河县","和政县","东乡族自治县","积石山保安族东乡族撒拉族自治县"],"甘南藏族自治州":["合作市","临潭县","卓尼县","舟曲县","迭部县","玛曲县","碌曲县","夏河县"]},"青海省":{"西宁市":["城东区","城中区","城西区","城北区","湟中区","大通回族土族自治县","湟源县"],"海东市":["乐都区","平安区","民和回族土族自治县","互助土族自治县","化隆回族自治县","循化撒拉族自治县"],"海北藏族自治州":["门源回族自治县","祁连县","海晏县","刚察县"],"黄南藏族自治州":["同仁市","尖扎县","泽库县","河南蒙古族自治县"],"海南藏族自治州":["共和县","同德县","贵德县","兴海县","贵南县"],"果洛藏族自治州":["玛沁县","班玛县","甘德县","达日县","久治县","玛多县"],"玉树藏族自治州":["玉树市","杂多县","称多县","治多县","囊谦县","曲麻莱县"],"海西蒙古族藏族自治州":["格尔木市","德令哈市","茫崖市","乌兰县","都兰县","天峻县","大柴旦行政委员会"]},"宁夏回族自治区":{"银川市":["兴庆区","西夏区","金凤区","永宁县","贺兰县","灵武市"],"石嘴山市":["大武口区","惠农区","平罗县"],"吴忠市":["利通区","红寺堡区","盐池县","同心县","青铜峡市"],"固原市":["原州区","西吉县","隆德县","泾源县","彭阳县"],"中卫市":["沙坡头区","中宁县","海原县"]},"新疆维吾尔自治区":{"乌鲁木齐市":["天山区","沙依巴克区","新市区","水磨沟区","头屯河区","达坂城区","米东区","乌鲁木齐县"],"克拉玛依市":["独山子区","克拉玛依区","白碱滩区","乌尔禾区"],"吐鲁番市":["高昌区","鄯善县","托克逊县"],"哈密市":["伊州区","巴里坤哈萨克自治县","伊吾县"],"昌吉回族自治州":["昌吉市","阜康市","呼图壁县","玛纳斯县","奇台县","吉木萨尔县","木垒哈萨克自治县"],"博尔塔拉蒙古自治州":["博乐市","阿拉山口市","精河县","温泉县"],"巴音郭楞蒙古自治州":["库尔勒市","轮台县","尉犁县","若羌县","且末县","焉耆回族自治县","和静县","和硕县","博湖县"],"阿克苏地区":["阿克苏市","库车市","温宿县","沙雅县","新和县","拜城县","乌什县","阿瓦提县","柯坪县"],"克孜勒苏柯尔克孜自治州":["阿图什市","阿克陶县","阿合奇县","乌恰县"],"喀什地区":["喀什市","疏附县","疏勒县","英吉沙县","泽普县","莎车县","叶城县","麦盖提县","岳普湖县","伽师县","巴楚县","塔什库尔干塔吉克自治县"],"和田地区":["和田市","和田县","墨玉县","皮山县","洛浦县","策勒县","于田县","民丰县"],"伊犁哈萨克自治州":["伊宁市","奎屯市","霍尔果斯市","伊宁县","察布查尔锡伯自治县","霍城县","巩留县","新源县","昭苏县","特克斯县","尼勒克县"],"塔城地区":["塔城市","乌苏市","沙湾市","额敏县","托里县","裕民县","和布克赛尔蒙古自治县"],"阿勒泰地区":["阿勒泰市","布尔津县","富蕴县","福海县","哈巴河县","青河县","吉木乃县"],"自治区直辖县级行政区划":["石河子市","阿拉尔市","图木舒克市","五家渠市","北屯市","铁门关市","双河市","可克达拉市","昆玉市","胡杨河市","新星市","白杨市"]}} \ No newline at end of file diff --git a/server.js b/server.js new file mode 100644 index 0000000..93a4b0e --- /dev/null +++ b/server.js @@ -0,0 +1,205 @@ +const http = require('http'); +const fs = require('fs'); +const path = require('path'); +const url = require('url'); + +const ROOT = __dirname; +const CONFIG_PATH = path.join(ROOT, 'project.config.json'); +const TEMPLATE_HTML = path.join(ROOT, '飞书审批配置文件_V1.0.html'); +const ADDRESS_REGIONS_JS = path.join(ROOT, 'address-regions.js'); + +function loadProjectConfig() { + try { + if (fs.existsSync(CONFIG_PATH)) return JSON.parse(fs.readFileSync(CONFIG_PATH, 'utf8')); + } catch (e) {} + return { projectId: 'approval_of_design', port: 8080, host: '0.0.0.0', label: '飞书审批配置服务' }; +} + +const PROJECT = loadProjectConfig(); +const PORT = Number(process.env.PORT) || PROJECT.port || 8080; +const HOST = process.env.HOST || PROJECT.host || '0.0.0.0'; + +const NODE_MAJOR = parseInt(String(process.versions.node).split('.')[0], 10); +if (NODE_MAJOR < 16) { + console.error('[ERROR] Node.js 16.x or later is required. Current: ' + process.version); + process.exit(1); +} + +let templateCache = null; + +function readTemplate() { + if (!templateCache) { + templateCache = fs.readFileSync(TEMPLATE_HTML, 'utf8'); + } + return templateCache; +} + +function reloadTemplate() { + templateCache = null; + return readTemplate(); +} + +function safeJsonForScript(value) { + return JSON.stringify(value).replace(/<\//g, '\\u003c/'); +} + +function renderBootScript(config, mode) { + const project = { + id: PROJECT.projectId || 'approval_of_design', + label: PROJECT.label || '飞书审批配置服务' + }; + return [ + '' + ].join('\n'); +} + +function injectBoot(html, config, mode) { + return html.replace(/' + ); +} + +function prepareHtml(config, mode) { + return inlineAddressRegions(injectBoot(readTemplate(), config, mode)); +} + +function sanitizeFilename(name) { + return String(name || '审批配置') + .replace(/[<>:"/\\|?*\x00-\x1f]/g, '_') + .replace(/\s+/g, '_') + .slice(0, 80) || '审批配置'; +} + +function sendJson(res, status, data) { + res.writeHead(status, { 'Content-Type': 'application/json; charset=utf-8' }); + res.end(JSON.stringify(data)); +} + +function readBody(req, limit) { + const maxBytes = limit || 20 * 1024 * 1024; + return new Promise(function (resolve, reject) { + var body = ''; + var size = 0; + req.on('data', function (chunk) { + size += chunk.length; + if (size > maxBytes) { + reject(new Error('request body too large')); + req.destroy(); + return; + } + body += chunk; + }); + req.on('end', function () { resolve(body); }); + req.on('error', reject); + }); +} + +function parseInitialConfigFromHtml(html) { + const match = html.match(/window\.__INITIAL_CONFIG__\s*=\s*([\s\S]*?);\s*(?:\n|<\/script>)/); + if (!match) return null; + try { + return JSON.parse(match[1]); + } catch (e) { + return null; + } +} + +const server = http.createServer(async (req, res) => { + res.setHeader('Access-Control-Allow-Origin', '*'); + res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS'); + res.setHeader('Access-Control-Allow-Headers', 'Content-Type'); + + if (req.method === 'OPTIONS') { + res.writeHead(204); + res.end(); + return; + } + + const parsed = url.parse(req.url, true); + const pathname = parsed.pathname; + + try { + if (req.method === 'GET' && (pathname === '/' || pathname === '/editor')) { + const initial = parsed.query.config ? JSON.parse(parsed.query.config) : null; + const html = prepareHtml(initial, 'server'); + res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8', 'Cache-Control': 'no-store' }); + res.end(html); + return; + } + + if (req.method === 'GET' && pathname === '/address-regions.js') { + if (!fs.existsSync(ADDRESS_REGIONS_JS)) { + res.writeHead(404, { 'Content-Type': 'text/plain; charset=utf-8' }); + res.end('address-regions.js not found'); + return; + } + res.writeHead(200, { 'Content-Type': 'application/javascript; charset=utf-8', 'Cache-Control': 'no-store' }); + res.end(fs.readFileSync(ADDRESS_REGIONS_JS, 'utf8')); + return; + } + + if (req.method === 'GET' && pathname === '/api/health') { + sendJson(res, 200, { ok: true, service: PROJECT.label, projectId: PROJECT.projectId }); + return; + } + + if (req.method === 'POST' && pathname === '/api/export') { + const body = await readBody(req); + const config = JSON.parse(body); + config.exportedAt = new Date().toISOString(); + config.projectId = PROJECT.projectId; + const html = prepareHtml(config, 'standalone'); + const filename = sanitizeFilename(config.approvalName) + '.html'; + res.writeHead(200, { + 'Content-Type': 'text/html; charset=utf-8', + 'Content-Disposition': 'attachment; filename="' + encodeURIComponent(filename) + '"', + 'Cache-Control': 'no-store' + }); + res.end(html); + return; + } + + if (req.method === 'POST' && pathname === '/api/import') { + const body = await readBody(req); + const payload = JSON.parse(body); + let config = null; + if (payload.config) { + config = payload.config; + } else if (payload.html) { + config = parseInitialConfigFromHtml(payload.html); + } + if (!config) { + sendJson(res, 400, { ok: false, error: 'invalid import payload' }); + return; + } + sendJson(res, 200, { ok: true, config }); + return; + } + + if (req.method === 'POST' && pathname === '/api/reload-template') { + reloadTemplate(); + sendJson(res, 200, { ok: true }); + return; + } + + res.writeHead(404, { 'Content-Type': 'text/plain; charset=utf-8' }); + res.end('Not Found'); + } catch (err) { + sendJson(res, 500, { ok: false, error: err.message || 'server error' }); + } +}); + +server.listen(PORT, HOST, () => { + console.log('[' + (PROJECT.label || 'approval') + '] http://' + HOST + ':' + PORT); +}); diff --git a/飞书审批配置文件_V1.0.html b/飞书审批配置文件_V1.0.html new file mode 100644 index 0000000..bea328a --- /dev/null +++ b/飞书审批配置文件_V1.0.html @@ -0,0 +1,4182 @@ + + + + + +飞书审批配置参考工具 + + + + + +
+ +
+ +
新建审批
+ +
+
+ 1基础信息 +
+
+ 2表单设计 +
+
+ 3流程设计 +
+
+
+ + + +
如您有疑问可联系TH818部门人员
+
+
+ + +
+ + + + + +
+ +
+
组件库
+
+
+ 飞书云文档 +
1
+
+
+
+ 📄云文档 +
+
+
+
+
+ 文本 +
3
+
+
+
📝单行文本
+
📜多行文本
+
💬说明
+
+
+
+
+ 数值 +
3
+
+
+
🔢数字
+
💰金额
+
🖩计算公式
+
+
+
+
+ 选项 +
2
+
+
+
单选
+
多选
+
+
+
+
+ 日期 +
2
+
+
+
📅日期
+
📆日期区间
+
+
+
+
+ 其他 +
12
+
+
+
🗏明细/表格
+
📊引用多维表格
+
📷图片/视频
+
📦附件
+
🏢部门
+
👤联系人
+
🔗关联审批
+
📍地址
+
🚩定位
+
💳收款账户
+
📞电话
+
📑流水号
+
+
+
+ + +
+
+
+
+ 新建审批 + +
+
+
+
+ + 点击或拖拽左侧控件至此处 +
+
+
+
+
+
+ + +
+
+
+ 字段设置 +
+
+
基础设置
+
显隐设置
+
+
+
+
+ +
+
+
+ + + + + + + +
+
+ + + + +