# App 地图与计价对接契约(2026-10-23) 本轮后端保留 Google 与自部署两套能力,共用 `sys_map_distance_source`。旧 Google 页面与 Key 接口继续可用;App 选址 UI 替换由前端单独实施,本仓库不修改 App 源码。自部署服务地址与读令牌仅在服务端使用。 ## 地址接口 以下均为 GET,必须携带登录 `token` 请求头,返回既有 `AjaxResult`,结果放在 `data`。不要把自部署服务地址、令牌或 Google Key 传给这些接口。 | 接口 | 查询参数 | data | | --- | --- | --- | | `/system/map/search` | `q`:1~200 字关键词 | 候选数组,最多 20 项 | | `/system/map/nearby` | `latitude`、`longitude`;`radius` 默认 300 米,范围 10~2000;`limit` 默认 10,范围 1~50 | 候选数组(Google 最多返回其第一页 20 项) | | `/system/map/reverse` | `latitude`、`longitude` | 地图点选位置 | | `/system/map/place` | `id`:前述候选的完整 ID | 地点详情 | 经纬度采用 WGS84 十进制度,纬度 -90~90、经度 -180~180。参数校验错误与上游不可用使用国际化业务错误;空搜索结果返回空数组。选择自部署后上游故障不会暗中调用 Google。 每个地点统一包含: ```json { "id": "self_hosted:osm:123", "name": "台北車站", "address": "臺北市中正區", "latitude": 25.0478, "longitude": 121.517, "source": "SELF_HOSTED", "precision": "poi", "requiresConfirmation": true } ``` `source` 为 `GOOGLE` 或 `SELF_HOSTED`。`id` 含 `google:` / `self_hosted:` 前缀,前端必须原样传回;详情按 ID 来源解析,因此配置切换后已有候选仍可查到原来源详情。不能把旧页面原始 Google ID 或地图原始 ID 直接传入;需要先使用新搜索接口获得完整 ID。 `distanceMeters`(附近候选距离)、`country`、`province`、`city`、`district` 在来源提供时返回;不存在时不要拼成“null”地址。`precision` 保留自部署精度;Google 的门牌点为 `address`,地点为 `poi`,其它结果标明其精度。`requiresConfirmation=true` 时让用户核对地址、入口、楼层或门牌,不可把近似结果显示为精确门牌。 逆查永远返回请求的原始点选经纬度,即使附近候选在其它坐标。前端保存和画点均使用返回的 `latitude` / `longitude`,不要再次用候选详情覆盖;无候选时仍返回坐标并要求确认。逆查结果的 `pin` ID 只是本次点选标识,不用于地点详情;地点详情只用于搜索和附近候选。新地址接口不保存地址簿,选定后继续使用现有地址簿接口。 ## 运费与路线 现有运费响应字段沿用当前接口;前端不要因地图来源切换改名、删除金额字段,或把地图路线距离直接当作费用。普通外卖、多店外卖、自配送运费与闪送仍按平台既有规则由服务端计价。 完整普通外卖报价`POST /app/userPromotionCalc/deliveryQuote`额外返回`routeDistanceMeters`(道路米数)和`distanceSource=ROUTE`;金额字段不改。订单`jvli`仍为公里,由后端保存,不以客户端提供的距离作为收费依据。闪送继续使用原有`distanceMeters / estimatedDurationSeconds / distanceSource`;时长缺失时按车型估算,`distanceSource`只标明距离来源。 旧结算链路兼容:`GET /utils/getluxianjvli?latlng1=收货点纬度,经度&latlng2=门店纬度,经度`仍读取`data[0].legs[0].distance.value`(米),内部按门店→收货点计价;可继续把该米数/1000传给旧`getZuiyyfei`。Google和自部署均保留这个参数约定。旧`getyunfei`则传门店坐标为lat1/lng1、收货点为lat2/lng2,返回jvli(公里)、freight/yunf(最终运费),已改为道路矩阵。新接入优先完整报价,减少旧兼容接口的额外请求。 旧路线响应保留绘图所需的overview_polyline,自部署时额外提供GeoJSON geometry,坐标为[经度,纬度]。这不等同于提供逐转向导航指令;App地图画面与导航应用调用由前端另行接入。 报价与下单使用同一经纬度和服务端金额。金额不一致时按现有错误提示重新报价;不能在 App 静默覆盖后直接提交。自取、堂食不请求配送路线。地图行驶时长是参考值,前端不要将其直接显示为承诺送达时间。 Google 回滚保留现有字典、Key 和旧有效接口。切换配置不会改写历史订单金额或支付快照。真实设备选址、四语言错误展示、报价→下单金额一致性及 Google/自部署切换联调仍需人工验收。 ## 2026-10-28 旧地址接口兼容(本轮不改前端代码) `GET /utils/getAddr?latlng=纬度,经度&id=旧语言缓存ID` 保留 `data.name/data.address`;自部署额外返回原点选 `latitude/longitude`、`source`、`precision`、`requiresConfirmation`。缺门牌时不伪造地址,`address` 可为空字符串。 `GET /utils/getLocationAddr?latlng=纬度,经度&type=1&id=...` 保留 `data.address:{name,address}` 和 `data.results[]:{place_id,name,vicinity,geometry:{location:{lat,lng}}}`,附近仍为10km/最多20项;候选可以是0项或1项,不能直接读取第二项。自部署 `place_id` 带 `self_hosted:` 前缀,不能传给 Google SDK 地点详情。新页面建议使用前述统一接口。 两入口遵循同一来源字典:SELF_HOSTED下只请求自部署服务,不读旧Redis语言缓存、不请求Google/Baidu,不因失败自动回Google;GOOGLE下保留旧响应及语言行为。已停用的type=0百度页面存在坐标再次转换逻辑,自部署拒绝该类型,不把WGS84冒充百度坐标。 只读核查发现旧App `pages/UserCenter/map/map.vue` 在结果非空时直接读取 `pois[1]`,单候选也可能越界。按用户要求本轮未改该文件,交由前端人员处理;后端不会为此伪造第二条候选。页面底图、SDK、导航调用和旧页面自身直连Google仍由前端负责,后端字典不能控制这些请求。