docs(changelog): 行程精准定位 schema 追加镇级字段 (#1574/#1575)
PlaceItem 加 provinceName/township/towncode 三段镇级行政区字段。 @mmg 选 POI 后多调一次高德 regeo 拿 addressComponent.township/towncode + 拼 4 段 fullPath。 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
这个提交包含在:
父节点
cf5f6df4c8
当前提交
51ddc2f58e
@ -1,11 +1,13 @@
|
|||||||
# 行程编排集合地/解散地:行政区 → 高德 POI 精准定位
|
# 行程编排集合地/解散地:行政区 → 高德 POI 精准定位
|
||||||
|
|
||||||
**类型**: 后端 FEAT(字段扩展+读路径增强) + 前端 picker 切换
|
**类型**: 后端 FEAT(字段扩展+读路径增强) + 前端 picker 切换 + regeo 调用
|
||||||
**关联**: 工单 #1563 / PR #1570
|
**关联**: 工单 #1563 / PR #1570 + follow-up 工单 #1574 / PR #1575(镇级行政区字段)
|
||||||
**日期**: 2026-04-30
|
**日期**: 2026-04-30
|
||||||
**前端处理者**: mmg
|
**前端处理者**: mmg
|
||||||
**影响范围**: 管理后台产品编辑页 Step 2「行程编排」→ DAY X 的「开始 / 结束」字段(即 `gatherPlace` / `dismissalPlace`)
|
**影响范围**: 管理后台产品编辑页 Step 2「行程编排」→ DAY X 的「开始 / 结束」字段(即 `gatherPlace` / `dismissalPlace`)
|
||||||
|
|
||||||
|
> ⚠️ **2026-04-30 16:25 update(PR #1575)**:行政区精度要求**到镇/街道级**。POI 自身只到区县,前端选 POI 后**必须额外调高德 regeo (逆地理编码)** 拿镇级数据。详见下方 schema 和 mmg 前端 mapping。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 业务目的
|
## 业务目的
|
||||||
@ -18,20 +20,26 @@
|
|||||||
|
|
||||||
## JSON Schema 升级
|
## JSON Schema 升级
|
||||||
|
|
||||||
### 新格式(POI 精准定位,2026-04-30 起新数据按这个落库)
|
### 新格式(POI 精准定位 + 镇级行政区,2026-04-30 起新数据按这个落库)
|
||||||
|
|
||||||
```jsonc
|
```jsonc
|
||||||
{
|
{
|
||||||
"name": "海拉尔东山国际机场", // POI 名称
|
"name": "海拉尔东山国际机场", // POI 名称
|
||||||
"address": "内蒙古呼伦贝尔市海拉尔区机场路", // 详细地址
|
"address": "内蒙古呼伦贝尔市海拉尔区机场路", // 详细地址
|
||||||
"location": { "lng": 119.825, "lat": 49.205 },// 嵌套对象,POI 精确坐标
|
"location": { "lng": 119.825, "lat": 49.205 }, // POI 精确坐标
|
||||||
"poiId": "B0FFGTEST1", // 高德 POI ID
|
"poiId": "B0FFGTEST1", // 高德 POI ID
|
||||||
"adcode": "150702", // POI 解析所属行政区编码
|
"adcode": "150702", // 区县编码(POI 自带)
|
||||||
"cityName": "呼伦贝尔市", // POI 解析所属城市
|
"provinceName": "内蒙古自治区", // 省(regeo addressComponent.province)
|
||||||
"districtName": "海拉尔区" // POI 解析所属行政区
|
"cityName": "呼伦贝尔市", // 市(regeo addressComponent.city)
|
||||||
|
"districtName": "海拉尔区", // 区(regeo addressComponent.district)
|
||||||
|
"township": "东山街道", // 镇/街道(regeo addressComponent.township)
|
||||||
|
"towncode": "150702002000", // 镇编码(regeo addressComponent.towncode)
|
||||||
|
"fullPath": "内蒙古自治区/呼伦贝尔市/海拉尔区/东山街道" // 4 段(前端拼)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**关键点**:POI 本身(高德 PlaceSearch 返回)只到区县级 `adname`,**到镇级必须前端额外调高德 regeo (`AMap.Geocoder.getAddress`)** 拿 `addressComponent.{township, towncode}` 后 merge 到 gatherPlace JSON。
|
||||||
|
|
||||||
### 老格式(行政区,2026-04-30 之前已落库的存量数据,零迁移继续工作)
|
### 老格式(行政区,2026-04-30 之前已落库的存量数据,零迁移继续工作)
|
||||||
|
|
||||||
```jsonc
|
```jsonc
|
||||||
@ -62,20 +70,39 @@
|
|||||||
### 2. 落库 JSON 字段映射(高德 POI → 后端字段)
|
### 2. 落库 JSON 字段映射(高德 POI → 后端字段)
|
||||||
|
|
||||||
```js
|
```js
|
||||||
// 高德 PlaceSearch 单个 POI 结果 → 后端 gatherPlace/dismissalPlace
|
// 选 POI 后,先用 location 调 regeo 拿镇级行政区,再 merge
|
||||||
function poiToPlace(poi) {
|
function poiToPlace(poi, callback) {
|
||||||
return {
|
const geocoder = new AMap.Geocoder();
|
||||||
name: poi.name, // POI 名称
|
geocoder.getAddress([poi.location.lng, poi.location.lat], (status, result) => {
|
||||||
address: poi.address || '', // 详细地址
|
if (status !== 'complete') {
|
||||||
location: {
|
// 降级:regeo 失败时退回到 POI 自带数据(无 township/towncode)
|
||||||
lng: Number(poi.location.lng), // 高德 LngLat 对象
|
callback({
|
||||||
lat: Number(poi.location.lat)
|
name: poi.name,
|
||||||
},
|
address: poi.address || '',
|
||||||
poiId: poi.id || '',
|
location: { lng: Number(poi.location.lng), lat: Number(poi.location.lat) },
|
||||||
adcode: poi.adcode || '', // POI 自带 adcode
|
poiId: poi.id || '',
|
||||||
cityName: poi.cityname || '', // 高德 cityname 全小写
|
adcode: poi.adcode || '',
|
||||||
districtName: poi.adname || '' // 高德 adname
|
cityName: poi.cityname || '',
|
||||||
};
|
districtName: poi.adname || ''
|
||||||
|
// 此时 provinceName/township/towncode/fullPath 留空,后端兼容
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const ac = result.regeocode.addressComponent;
|
||||||
|
callback({
|
||||||
|
name: poi.name,
|
||||||
|
address: poi.address || result.regeocode.formattedAddress,
|
||||||
|
location: { lng: Number(poi.location.lng), lat: Number(poi.location.lat) },
|
||||||
|
poiId: poi.id || '',
|
||||||
|
adcode: poi.adcode || ac.adcode,
|
||||||
|
provinceName: ac.province || '',
|
||||||
|
cityName: (ac.city && ac.city.length) ? ac.city : '', // 直辖市 city 是空数组
|
||||||
|
districtName: ac.district || '',
|
||||||
|
township: ac.township || '',
|
||||||
|
towncode: ac.towncode || '',
|
||||||
|
fullPath: [ac.province, ac.city, ac.district, ac.township].filter(s => s && s.length).join('/')
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
正在加载...
x
在新工单中引用
屏蔽一个用户