diff --git a/pjcloud-supermarket/pjcloud-supermarket-biz/src/main/java/com/bsd/pjcloud/supermarket/controller/SmHotelAppController.java b/pjcloud-supermarket/pjcloud-supermarket-biz/src/main/java/com/bsd/pjcloud/supermarket/controller/SmHotelAppController.java index 793c30da8..df2f362ac 100644 --- a/pjcloud-supermarket/pjcloud-supermarket-biz/src/main/java/com/bsd/pjcloud/supermarket/controller/SmHotelAppController.java +++ b/pjcloud-supermarket/pjcloud-supermarket-biz/src/main/java/com/bsd/pjcloud/supermarket/controller/SmHotelAppController.java @@ -77,8 +77,8 @@ public class SmHotelAppController { private static final long FILTER_META_CACHE_MINUTES = 10L; - /** 可售候选酒店 id 短缓存 */ - private static final String CANDIDATE_CACHE_PREFIX = "sm:hotel:app:cand:"; + /** 可售候选酒店 id 短缓存(v3:全国按入住日 DISTINCT,避免错误 EXISTS) */ + private static final String CANDIDATE_CACHE_PREFIX = "sm:hotel:app:cand:v3:"; private static final long CANDIDATE_CACHE_MINUTES = 3L; @@ -87,7 +87,7 @@ public class SmHotelAppController { private static final String CANDIDATE_CACHE_OVERFLOW = "OVERFLOW"; /** 列表页结果短缓存(同条件重复进入/下拉) */ - private static final String PAGE_CACHE_PREFIX = "sm:hotel:app:page:"; + private static final String PAGE_CACHE_PREFIX = "sm:hotel:app:page:v3:"; private static final long PAGE_CACHE_SECONDS = 45L; @@ -712,19 +712,16 @@ public class SmHotelAppController { LocalDate from = stayFrom != null ? stayFrom : LocalDate.now(); LocalDate toEx = stayToExclusive; if (toEx == null || !toEx.isAfter(from)) { - // 未传离店:只扫入住日起 2 天(列表展示够用),避免默认扫 30 天全库 - toEx = from.plusDays(2); + toEx = from.plusDays(1); } - // 全国无缩小范围:不要 SELECT DISTINCT 全库日历(百万级会拖死),交给 EXISTS - if (scopedHotelIds == null) { - return null; - } - if (scopedHotelIds.isEmpty()) { + if (scopedHotelIds != null && scopedHotelIds.isEmpty()) { return List.of(); } - String scopeDigest = Integer.toHexString(scopedHotelIds.hashCode()); + boolean nationwide = scopedHotelIds == null; + String scopeDigest = nationwide ? "all" : Integer.toHexString(scopedHotelIds.hashCode()); + int scopeSize = nationwide ? -1 : scopedHotelIds.size(); String cacheKey = CANDIDATE_CACHE_PREFIX + from + ":" + toEx + ":" + needCapPerRoom + ":" + scopeDigest + ":" - + scopedHotelIds.size(); + + scopeSize; try { String cached = stringRedisTemplate.opsForValue().get(cacheKey); if (CANDIDATE_CACHE_EMPTY.equals(cached)) { @@ -744,7 +741,10 @@ public class SmHotelAppController { catch (Exception e) { log.warn("|酒店App|候选缓存读取失败|{}", e.getMessage()); } - List bookable = dailyMapper.selectDistinctHotelIdsByStayRangeInHotels(from, toEx, scopedHotelIds); + // 全国:按入住日扫日历(通常 1 晚,走 stay_date 索引);有区域则在酒店集合内查 + List bookable = nationwide + ? dailyMapper.selectDistinctHotelIdsByStayRange(from, toEx) + : dailyMapper.selectDistinctHotelIdsByStayRangeInHotels(from, toEx, scopedHotelIds); if (bookable == null || bookable.isEmpty()) { cacheCandidateIds(cacheKey, CANDIDATE_CACHE_EMPTY); return List.of(); @@ -859,7 +859,7 @@ public class SmHotelAppController { wrapper.apply(""" EXISTS ( SELECT 1 FROM canteen_hotel_daily d - WHERE d.hotel_id = id + WHERE d.hotel_id = canteen_hotel.id AND d.del_flag = '0' AND d.stay_date >= {0} AND d.stay_date < {1} @@ -876,7 +876,7 @@ public class SmHotelAppController { return; } wrapper.apply(""" - id IN ( + canteen_hotel.id IN ( SELECT DISTINCT r.hotel_id FROM canteen_hotel_room r WHERE r.del_flag = '0' AND (r.capacity IS NULL OR r.capacity >= {0})