diff --git a/pjcloud-supermarket/pjcloud-supermarket-biz/src/main/java/com/bsd/pjcloud/supermarket/service/impl/SmHotelMidServiceImpl.java b/pjcloud-supermarket/pjcloud-supermarket-biz/src/main/java/com/bsd/pjcloud/supermarket/service/impl/SmHotelMidServiceImpl.java index 759ccc061..352394b91 100644 --- a/pjcloud-supermarket/pjcloud-supermarket-biz/src/main/java/com/bsd/pjcloud/supermarket/service/impl/SmHotelMidServiceImpl.java +++ b/pjcloud-supermarket/pjcloud-supermarket-biz/src/main/java/com/bsd/pjcloud/supermarket/service/impl/SmHotelMidServiceImpl.java @@ -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; + } + + /** + * 从位置区域文案取「市级」层名称并去掉「市」。 + *
+ * 规则:先按省/市/州/区县拆层;优先取以「市」结尾的那一层(县级市如恩施市也算); + * 若只有区县(如城阳区),则退回上一层地级市(青岛市)。 + *
*