酒店修改

This commit is contained in:
zjf committed 2026-10-16 12:19:17 +08:00
1 parent 7d19ec66b6
commit aa5a699a52
1 file changed
+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 {