|
|
@@ -0,0 +1,75 @@
|
|
|
+package org.dromara.main.service.impl;
|
|
|
+
|
|
|
+import cn.hutool.http.HttpUtil;
|
|
|
+import cn.hutool.json.JSONArray;
|
|
|
+import cn.hutool.json.JSONObject;
|
|
|
+import cn.hutool.json.JSONUtil;
|
|
|
+import lombok.RequiredArgsConstructor;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.dromara.common.core.exception.ServiceException;
|
|
|
+import org.dromara.common.core.utils.StringUtils;
|
|
|
+import org.dromara.main.config.AmapGeoProperties;
|
|
|
+import org.dromara.main.domain.dto.GeoPointDto;
|
|
|
+import org.dromara.main.service.CompanyGeoService;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+
|
|
|
+import java.math.BigDecimal;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.Map;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 基于高德 Web 服务地理编码接口,将地址转换为经纬度。
|
|
|
+ */
|
|
|
+@Slf4j
|
|
|
+@Service
|
|
|
+@RequiredArgsConstructor
|
|
|
+public class AmapCompanyGeoServiceImpl implements CompanyGeoService {
|
|
|
+
|
|
|
+ private final AmapGeoProperties amapGeoProperties;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public GeoPointDto geocode(String address) {
|
|
|
+ if (StringUtils.isBlank(address)) {
|
|
|
+ throw new ServiceException("办公地址不能为空");
|
|
|
+ }
|
|
|
+ if (StringUtils.isBlank(amapGeoProperties.getKey())) {
|
|
|
+ throw new ServiceException("未配置高德地图地理编码 Key");
|
|
|
+ }
|
|
|
+
|
|
|
+ Map<String, Object> params = new HashMap<>(4);
|
|
|
+ params.put("key", amapGeoProperties.getKey());
|
|
|
+ params.put("address", address.trim());
|
|
|
+ params.put("output", "JSON");
|
|
|
+
|
|
|
+ try {
|
|
|
+ String response = HttpUtil.get(amapGeoProperties.getGeocodeUrl(), params);
|
|
|
+ JSONObject result = JSONUtil.parseObj(response);
|
|
|
+ if (!"1".equals(result.getStr("status"))) {
|
|
|
+ String info = result.getStr("info");
|
|
|
+ String infocode = result.getStr("infocode");
|
|
|
+ log.error("高德地理编码失败,address={}, info={}, infocode={}", address, info, infocode);
|
|
|
+ throw new ServiceException(StringUtils.format("地址解析失败: {}", StringUtils.blankToDefault(info, "高德接口调用失败")));
|
|
|
+ }
|
|
|
+
|
|
|
+ JSONArray geocodes = result.getJSONArray("geocodes");
|
|
|
+ if (geocodes == null || geocodes.isEmpty()) {
|
|
|
+ throw new ServiceException("地址解析失败: 未匹配到经纬度,请检查办公地址");
|
|
|
+ }
|
|
|
+
|
|
|
+ String location = geocodes.getJSONObject(0).getStr("location");
|
|
|
+ if (StringUtils.isBlank(location) || !location.contains(",")) {
|
|
|
+ throw new ServiceException("地址解析失败: 返回坐标格式异常");
|
|
|
+ }
|
|
|
+
|
|
|
+ String[] parts = location.split(",");
|
|
|
+ BigDecimal longitude = new BigDecimal(parts[0].trim());
|
|
|
+ BigDecimal latitude = new BigDecimal(parts[1].trim());
|
|
|
+ return new GeoPointDto(latitude, longitude);
|
|
|
+ } catch (ServiceException ex) {
|
|
|
+ throw ex;
|
|
|
+ } catch (Exception ex) {
|
|
|
+ log.error("调用高德地理编码接口异常,address={}", address, ex);
|
|
|
+ throw new ServiceException("地址解析失败,请稍后重试");
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|