酒店修改
This commit is contained in:
1 parent
7d19ec66b6
commit
aa5a699a52
1 file changed
+93
-22
+93
-22
@@ -59,10 +59,11 @@ public class SmHotelMidServiceImpl implements SmHotelMidService {
|
||||
private static final int LOCAL_DAILY_BATCH_MAX_DAYS = 366;
|
||||
|
||||
/**
|
||||
* 环启 cityName:从「省市区」串中取地级市短名(2~4 字 + 市),再去掉「市」。
|
||||
* 例:山东省青岛市城阳区 → 青岛;恩施市 → 恩施。
|
||||
* 拆「位置区域」拼接文案为级联各层:省 / 市(州) / 区县。
|
||||
* 例:湖北省恩施土家族苗族自治州恩施市 → [湖北省, 恩施土家族苗族自治州, 恩施市]
|
||||
*/
|
||||
private static final Pattern HUANQI_CITY_PATTERN = Pattern.compile("([\\u4e00-\\u9fa5]{2,4})市");
|
||||
private static final Pattern AREA_SEGMENT_PATTERN = Pattern.compile(
|
||||
"[\\u4e00-\\u9fa5]+?(?:省|自治区|特别行政区|自治州|地区|盟|市|区|县|旗)");
|
||||
|
||||
private final ShangyouHotelClient upstreamClient;
|
||||
|
||||
@@ -501,8 +502,10 @@ public class SmHotelMidServiceImpl implements SmHotelMidService {
|
||||
if (StrUtil.isNotBlank(hotel.getPhone())) {
|
||||
hotelBody.put("hotelPhone", hotel.getPhone());
|
||||
}
|
||||
if (StrUtil.isNotBlank(hotel.getAddress())) {
|
||||
hotelBody.put("address", hotel.getAddress());
|
||||
// 环启 address 要完整:位置区域 + 详细地址(表单里 address 往往只有「航空大道188号」)
|
||||
String fullAddress = buildHuanqiFullAddress(hotel.getDistrict(), hotel.getAddress());
|
||||
if (StrUtil.isNotBlank(fullAddress)) {
|
||||
hotelBody.put("address", fullAddress);
|
||||
}
|
||||
if (StrUtil.isNotBlank(hotel.getDistrict())) {
|
||||
hotelBody.put("cityName", hotel.getDistrict());
|
||||
@@ -513,11 +516,15 @@ public class SmHotelMidServiceImpl implements SmHotelMidService {
|
||||
if (StrUtil.isBlank(cityName)) {
|
||||
cityName = StrUtil.trim(hotel.getDistrict());
|
||||
}
|
||||
// 环启要求只传市一级短名,且不要带「市」:恩施市 → 恩施
|
||||
cityName = normalizeHuanqiCityName(cityName);
|
||||
// 环启:只取位置区域里「市级」那一层,再去掉「市」(恩施市→恩施;青岛市城阳区→青岛)
|
||||
cityName = extractHuanqiCityNameFromDistrict(cityName);
|
||||
String address = StrUtil.trim(strObj(hotelBody.get("address")));
|
||||
if (StrUtil.isBlank(address)) {
|
||||
address = StrUtil.trim(hotel.getAddress());
|
||||
address = buildHuanqiFullAddress(hotel.getDistrict(), hotel.getAddress());
|
||||
}
|
||||
else {
|
||||
// remark 里若只写了短地址,同样补全区县前缀
|
||||
address = buildHuanqiFullAddress(hotel.getDistrict(), address);
|
||||
}
|
||||
String phone = StrUtil.trim(strObj(hotelBody.get("hotelPhone")));
|
||||
if (StrUtil.isBlank(phone)) {
|
||||
@@ -1844,31 +1851,95 @@ public class SmHotelMidServiceImpl implements SmHotelMidService {
|
||||
}
|
||||
|
||||
/**
|
||||
* 环启 cityName 规范化:只保留市一级短名,去掉后缀「市」。
|
||||
* 环启 address:位置区域全文 + 详细地址。
|
||||
* 表单「详细地址」常只有路名门牌(如航空大道188号),必须拼上「湖北省…恩施市」。
|
||||
*/
|
||||
static String buildHuanqiFullAddress(String district, String detailAddress) {
|
||||
String area = StrUtil.trim(district);
|
||||
String detail = StrUtil.trim(detailAddress);
|
||||
if (StrUtil.isBlank(area) && StrUtil.isBlank(detail)) {
|
||||
return "";
|
||||
}
|
||||
if (StrUtil.isBlank(area)) {
|
||||
return detail;
|
||||
}
|
||||
if (StrUtil.isBlank(detail)) {
|
||||
return area;
|
||||
}
|
||||
// 已是完整地址(含区县或已带区域前缀)则不再重复拼接
|
||||
if (detail.contains(area) || detail.startsWith(area)) {
|
||||
return detail;
|
||||
}
|
||||
// 详细地址已含省/市/区字样,视为已写全
|
||||
if (detail.contains("省") || detail.contains("自治区") || (detail.contains("市") && detail.contains("区"))) {
|
||||
return detail;
|
||||
}
|
||||
return area + detail;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从位置区域文案取「市级」层名称并去掉「市」。
|
||||
* <p>
|
||||
* 规则:先按省/市/州/区县拆层;优先取以「市」结尾的那一层(县级市如恩施市也算);
|
||||
* 若只有区县(如城阳区),则退回上一层地级市(青岛市)。
|
||||
* </p>
|
||||
* <ul>
|
||||
* <li>湖北省恩施土家族苗族自治州恩施市 → 恩施</li>
|
||||
* <li>山东省青岛市城阳区 → 青岛</li>
|
||||
* <li>恩施市 → 恩施</li>
|
||||
* <li>北京市朝阳区 → 北京</li>
|
||||
* </ul>
|
||||
*/
|
||||
static String normalizeHuanqiCityName(String raw) {
|
||||
if (StrUtil.isBlank(raw)) {
|
||||
static String extractHuanqiCityNameFromDistrict(String district) {
|
||||
if (StrUtil.isBlank(district)) {
|
||||
return "";
|
||||
}
|
||||
String s = raw.trim().replace(" ", "");
|
||||
Matcher m = HUANQI_CITY_PATTERN.matcher(s);
|
||||
String last = null;
|
||||
String s = district.trim().replace(" ", "");
|
||||
List<String> segments = splitAreaSegments(s);
|
||||
if (segments.isEmpty()) {
|
||||
return stripCitySuffix(s);
|
||||
}
|
||||
// 1) 优先:名称以「市」结尾的层(青岛市 / 恩施市 / 北京市)
|
||||
for (int i = segments.size() - 1; i >= 0; i--) {
|
||||
String seg = segments.get(i);
|
||||
if (seg.endsWith("市") && !seg.endsWith("市辖区")) {
|
||||
return stripCitySuffix(seg);
|
||||
}
|
||||
}
|
||||
// 2) 次选:地级「地区/盟」(极少);自治州不作为环启 cityName(对方要的是市短名)
|
||||
for (int i = segments.size() - 1; i >= 0; i--) {
|
||||
String seg = segments.get(i);
|
||||
if (seg.endsWith("地区") || seg.endsWith("盟")) {
|
||||
return seg.replaceAll("(地区|盟)$", "");
|
||||
}
|
||||
}
|
||||
// 3) 兜底:最后一层去掉区县后缀
|
||||
return stripCitySuffix(segments.get(segments.size() - 1));
|
||||
}
|
||||
|
||||
/** 湖北省恩施土家族苗族自治州恩施市 → [湖北省, 恩施土家族苗族自治州, 恩施市] */
|
||||
static List<String> splitAreaSegments(String concatenated) {
|
||||
List<String> list = new ArrayList<>();
|
||||
if (StrUtil.isBlank(concatenated)) {
|
||||
return list;
|
||||
}
|
||||
Matcher m = AREA_SEGMENT_PATTERN.matcher(concatenated.trim());
|
||||
while (m.find()) {
|
||||
last = m.group(1);
|
||||
list.add(m.group());
|
||||
}
|
||||
if (StrUtil.isNotBlank(last)) {
|
||||
return last;
|
||||
return list;
|
||||
}
|
||||
|
||||
/** 去掉末尾「市」(仅去一层后缀,不碰自治州等) */
|
||||
static String stripCitySuffix(String name) {
|
||||
if (StrUtil.isBlank(name)) {
|
||||
return "";
|
||||
}
|
||||
// 已是「xx市」整串、或误写成带市后缀
|
||||
if (s.endsWith("市") && s.length() > 1) {
|
||||
return s.substring(0, s.length() - 1);
|
||||
String n = name.trim();
|
||||
if (n.endsWith("市") && !n.endsWith("市辖区") && n.length() > 1) {
|
||||
return n.substring(0, n.length() - 1);
|
||||
}
|
||||
return s;
|
||||
n = n.replaceAll("(区|县|旗)$", "");
|
||||
return n.trim();
|
||||
}
|
||||
|
||||
private static class DailyDraft {
|
||||
|
||||
Reference in new issue
Block a user