补充客户信息,检索信息
This commit is contained in:
@@ -10,8 +10,10 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -101,44 +103,90 @@ public class NearbyMerchantSearchServiceImpl implements INearbyMerchantSearchSer
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 地理编码。URL 拼法与 {@link com.rj.gaode#} 一致:
|
||||
* 使用 {@link URLEncoder#encode(String, java.nio.charset.Charset)} 处理中文查询参数。
|
||||
* Spring {@code UriComponentsBuilder} 的编码规则与 {@code URLEncoder} 不一致,易导致高德返回 ENGINE_RESPONSE_DATA_ERROR(如 infocode=30001)。
|
||||
* 首次失败后不传 {@code city},仅用合并后的完整地址再请求一次。
|
||||
*/
|
||||
private String geocodeToLocation(String city, String address) throws Exception {
|
||||
String url = UriComponentsBuilder.fromUriString(GEOCODE_URL)
|
||||
.queryParam("key", amapProperties.getWebServiceKey())
|
||||
.queryParam("city", city)
|
||||
.queryParam("address", address)
|
||||
.queryParam("output", "json")
|
||||
.build()
|
||||
.encode()
|
||||
.toUriString();
|
||||
String json = restTemplate.getForObject(url, String.class);
|
||||
JsonNode root = objectMapper.readTree(json);
|
||||
if (!"1".equals(root.path("status").asText())) {
|
||||
String info = root.path("info").asText("地理编码失败");
|
||||
throw new IllegalArgumentException("地理编码失败:" + info);
|
||||
}
|
||||
JsonNode geocodes = root.path("geocodes");
|
||||
if (!geocodes.isArray() || geocodes.isEmpty()) {
|
||||
throw new IllegalArgumentException("未解析到该地址的经纬度,请检查 CITY、ADDRESS");
|
||||
}
|
||||
String loc = geocodes.get(0).path("location").asText("");
|
||||
if (!StringUtils.hasText(loc)) {
|
||||
throw new IllegalArgumentException("地理编码结果中无 location 字段");
|
||||
}
|
||||
String json = fetchGeocode(city, address);
|
||||
String loc = parseGeocodeLocation(json);
|
||||
if (loc != null) {
|
||||
return loc;
|
||||
}
|
||||
|
||||
String merged = mergeCityAddress(city, address);
|
||||
log.debug("地理编码首次未返回坐标,不传 city、使用合并地址重试");
|
||||
json = fetchGeocode(null, merged);
|
||||
loc = parseGeocodeLocation(json);
|
||||
if (loc != null) {
|
||||
return loc;
|
||||
}
|
||||
|
||||
throw geocodeFailureException(json);
|
||||
}
|
||||
|
||||
/** 与 AllShopCollectorV5 相同:key、c(可选)、address、output;city 与 address 经 UTF-8 URLEncoder。无 city 时不带 city 参数。 */
|
||||
private String fetchGeocode(String city, String address) {
|
||||
String key = amapProperties.getWebServiceKey();
|
||||
StringBuilder sb = new StringBuilder(GEOCODE_URL);
|
||||
sb.append("?key=").append(key);
|
||||
if (StringUtils.hasText(city)) {
|
||||
sb.append("&city=").append(URLEncoder.encode(city, StandardCharsets.UTF_8));
|
||||
}
|
||||
sb.append("&address=").append(URLEncoder.encode(address, StandardCharsets.UTF_8));
|
||||
sb.append("&output=json");
|
||||
String url = sb.toString();
|
||||
String json = restTemplate.getForObject(URI.create(url), String.class);
|
||||
if (json == null) {
|
||||
throw new IllegalStateException("高德地理编码返回空响应");
|
||||
}
|
||||
return json;
|
||||
}
|
||||
|
||||
/** status=1 且存在 location 时返回坐标,否则返回 null。 */
|
||||
private String parseGeocodeLocation(String json) throws Exception {
|
||||
JsonNode root = objectMapper.readTree(json);
|
||||
if (!"1".equals(root.path("status").asText())) {
|
||||
return null;
|
||||
}
|
||||
JsonNode geocodes = root.path("geocodes");
|
||||
if (!geocodes.isArray() || geocodes.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
String loc = geocodes.get(0).path("location").asText("");
|
||||
return StringUtils.hasText(loc) ? loc : null;
|
||||
}
|
||||
|
||||
private static String mergeCityAddress(String city, String address) {
|
||||
String c = city.trim();
|
||||
String a = address.trim();
|
||||
if (a.startsWith(c)) {
|
||||
return a;
|
||||
}
|
||||
return c + a;
|
||||
}
|
||||
|
||||
private IllegalArgumentException geocodeFailureException(String json) throws Exception {
|
||||
JsonNode root = objectMapper.readTree(json);
|
||||
String info = root.path("info").asText("地理编码失败");
|
||||
String infocode = root.path("infocode").asText("");
|
||||
if (StringUtils.hasText(infocode)) {
|
||||
return new IllegalArgumentException("地理编码失败:" + info + "(infocode=" + infocode + ")");
|
||||
}
|
||||
return new IllegalArgumentException("地理编码失败:" + info);
|
||||
}
|
||||
|
||||
/** 与 AllShopCollectorV5#getAllShops 相同的参数顺序与拼接方式(location 为经纬度串,无需 URL 编码)。 */
|
||||
private String fetchAroundPage(String location, int radius, int offset, int page) {
|
||||
String url = UriComponentsBuilder.fromUriString(AROUND_URL)
|
||||
.queryParam("key", amapProperties.getWebServiceKey())
|
||||
.queryParam("location", location)
|
||||
.queryParam("radius", radius)
|
||||
.queryParam("offset", offset)
|
||||
.queryParam("page", page)
|
||||
.queryParam("output", "json")
|
||||
.build()
|
||||
.encode()
|
||||
.toUriString();
|
||||
String body = restTemplate.getForObject(url, String.class);
|
||||
String url = AROUND_URL + "?key=" + amapProperties.getWebServiceKey()
|
||||
+ "&location=" + location
|
||||
+ "&radius=" + radius
|
||||
+ "&offset=" + offset
|
||||
+ "&page=" + page
|
||||
+ "&output=json";
|
||||
String body = restTemplate.getForObject(URI.create(url), String.class);
|
||||
if (body == null) {
|
||||
throw new IllegalStateException("高德周边搜索返回空响应");
|
||||
}
|
||||
|
||||
@@ -271,9 +271,10 @@ dify:
|
||||
top-sales-alldim-token: app-99nVuuKfcRR2vikxgOTiNQm0
|
||||
classification-token: app-Id1eOuv5yBb1pexpEWVDqSS3
|
||||
|
||||
# 高德地图 Web 服务(地理编码、周边 POI);本地可设环境变量 AMAP_WEB_SERVICE_KEY
|
||||
# 高德地图 Web 服务(地理编码、周边 POI)
|
||||
# 未设环境变量时使用与 com.rj.gaode.AllShopCollectorV5 一致的本地默认;生产/正式环境请设置 AMAP_WEB_SERVICE_KEY 覆盖
|
||||
amap:
|
||||
web-service-key: ${AMAP_WEB_SERVICE_KEY:}
|
||||
web-service-key: ${AMAP_WEB_SERVICE_KEY:34eaa47387aa9e8c1a8ca0d4c8abaa1d}
|
||||
|
||||
# MinIO 对象存储配置
|
||||
minio:
|
||||
|
||||
Reference in New Issue
Block a user