diff --git a/fad-app/src/main/java/com/ruoyi/fadapp/controller/FadAppLocationController.java b/fad-app/src/main/java/com/ruoyi/fadapp/controller/FadAppLocationController.java index efde7d5..31b1994 100644 --- a/fad-app/src/main/java/com/ruoyi/fadapp/controller/FadAppLocationController.java +++ b/fad-app/src/main/java/com/ruoyi/fadapp/controller/FadAppLocationController.java @@ -9,6 +9,9 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import java.util.HashMap; +import java.util.Map; + /** * FAD APP 定位控制器 */ @@ -21,14 +24,25 @@ public class FadAppLocationController { private final IFadAppLocationService locationService; /** - * 根据经纬度获取城市 - * - * @param latitude 纬度 - * @param longitude 经度 - * @return 城市名称 + * 兼容老接口:返回单一城市/区县字符串。 + * 用 Map 包一层避开 R.ok(String) 把字符串塞到 msg 的重载冲突。 */ @GetMapping("/city") - public R getCity(@RequestParam Double latitude, @RequestParam Double longitude) { - return R.ok(locationService.getCityByLocation(latitude, longitude)); + public R> getCity(@RequestParam Double latitude, + @RequestParam Double longitude) { + String city = locationService.getCityByLocation(latitude, longitude); + Map data = new HashMap<>(); + data.put("city", city); + return R.ok(data); + } + + /** + * 精确到区县的结构化地址。 + * 返回:province / city / district / township / adcode / address。 + */ + @GetMapping("/detail") + public R> getDetail(@RequestParam Double latitude, + @RequestParam Double longitude) { + return R.ok(locationService.getDetailedLocation(latitude, longitude)); } } diff --git a/fad-app/src/main/java/com/ruoyi/fadapp/service/IFadAppLocationService.java b/fad-app/src/main/java/com/ruoyi/fadapp/service/IFadAppLocationService.java index 93fec4f..dadf7d6 100644 --- a/fad-app/src/main/java/com/ruoyi/fadapp/service/IFadAppLocationService.java +++ b/fad-app/src/main/java/com/ruoyi/fadapp/service/IFadAppLocationService.java @@ -1,16 +1,18 @@ package com.ruoyi.fadapp.service; +import java.util.Map; + /** * FAD APP 定位服务接口 */ public interface IFadAppLocationService { - /** - * 根据经纬度获取城市 - * - * @param latitude 纬度 - * @param longitude 经度 - * @return 城市名称 - */ + /** 老接口:返回单一最精准的可读地址(兼容用),优先 district。 */ String getCityByLocation(Double latitude, Double longitude); + + /** + * 结构化逆地理编码。 + * 返回字段:province / city / district / township / adcode / address。 + */ + Map getDetailedLocation(Double latitude, Double longitude); } diff --git a/fad-app/src/main/java/com/ruoyi/fadapp/service/impl/FadAppLocationServiceImpl.java b/fad-app/src/main/java/com/ruoyi/fadapp/service/impl/FadAppLocationServiceImpl.java index 78a0e3e..0c07493 100644 --- a/fad-app/src/main/java/com/ruoyi/fadapp/service/impl/FadAppLocationServiceImpl.java +++ b/fad-app/src/main/java/com/ruoyi/fadapp/service/impl/FadAppLocationServiceImpl.java @@ -2,37 +2,58 @@ package com.ruoyi.fadapp.service.impl; import com.alibaba.fastjson2.JSONObject; import com.ruoyi.fadapp.service.IFadAppLocationService; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; +import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; /** - * FAD APP 定位服务实现 + * FAD APP 定位服务实现,调高德逆地理编码 API */ @Slf4j +@RequiredArgsConstructor @Service public class FadAppLocationServiceImpl implements IFadAppLocationService { private static final String AMAP_REVERSE_URL = "https://restapi.amap.com/v3/geocode/regeo"; - private final RestTemplate restTemplate = new RestTemplate(); + private final RestTemplate restTemplate; @Value("${fad.amap.key:}") private String amapKey; + /** + * 兼容老接口:只取一个尽量精准的可读地址字符串。 + * 优先级:district → city → province。 + */ @Override public String getCityByLocation(Double latitude, Double longitude) { - if (latitude == null || longitude == null) { - return ""; - } + Map d = getDetailedLocation(latitude, longitude); + if (d == null) return ""; + Object dist = d.get("district"); + if (dist != null && !dist.toString().isEmpty()) return dist.toString(); + Object city = d.get("city"); + if (city != null && !city.toString().isEmpty()) return city.toString(); + Object prov = d.get("province"); + return prov == null ? "" : prov.toString(); + } + /** + * 返回结构化地址:province / city / district / address(完整) / adcode。 + * 失败时返回空 Map。 + */ + @Override + public Map getDetailedLocation(Double latitude, Double longitude) { + Map empty = new HashMap<>(); + if (latitude == null || longitude == null) return empty; if (!org.springframework.util.StringUtils.hasText(amapKey)) { log.warn("高德地图 key 未配置"); - return ""; + return empty; } try { @@ -45,43 +66,39 @@ public class FadAppLocationServiceImpl implements IFadAppLocationService { params.put("output", "JSON"); StringBuilder url = new StringBuilder(AMAP_REVERSE_URL).append("?"); - params.forEach((key, value) -> url.append(key).append("=").append(value).append("&")); + params.forEach((k, v) -> url.append(k).append("=").append(v).append("&")); url.setLength(url.length() - 1); JSONObject response = restTemplate.getForObject(url.toString(), JSONObject.class); - if (response == null) { - return ""; - } - - if (!"1".equals(response.getString("status"))) { + if (response == null || !"1".equals(response.getString("status"))) { log.warn("高德逆地理编码失败: {}", response); - return ""; + return empty; } - JSONObject regeocode = response.getJSONObject("regeocode"); - if (regeocode == null) { - return ""; - } + if (regeocode == null) return empty; + String formatted = regeocode.getString("formatted_address"); + JSONObject ac = regeocode.getJSONObject("addressComponent"); + if (ac == null) return empty; - JSONObject addressComponent = regeocode.getJSONObject("addressComponent"); - if (addressComponent == null) { - return ""; - } - - String city = addressComponent.getString("city"); - if (org.springframework.util.StringUtils.hasText(city)) { - return city; - } - - String province = addressComponent.getString("province"); - if (org.springframework.util.StringUtils.hasText(province)) { - return province; - } - - return ""; + Map out = new LinkedHashMap<>(); + out.put("province", _str(ac, "province")); + out.put("city", _str(ac, "city")); + out.put("district", _str(ac, "district")); + out.put("township", _str(ac, "township")); + out.put("adcode", _str(ac, "adcode")); + out.put("address", formatted == null ? "" : formatted); + return out; } catch (Exception e) { - log.warn("根据经纬度获取城市失败, latitude={}, longitude={}, err={}", latitude, longitude, e.getMessage()); - return ""; + log.warn("根据经纬度获取地址失败, lat={}, lng={}, err={}", latitude, longitude, e.getMessage()); + return empty; } } + + private String _str(JSONObject o, String key) { + Object v = o.get(key); + if (v == null) return ""; + // 高德对部分字段(如 city 是直辖市时)会返回空数组 [] + if (v instanceof java.util.List && ((java.util.List) v).isEmpty()) return ""; + return v.toString(); + } }