This commit is contained in:
zjf committed 2026-10-21 13:24:04 +08:00
1 parent 0385d9d308
commit 7dee90951c
1 file changed
+15 -15
@@ -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<Long> bookable = dailyMapper.selectDistinctHotelIdsByStayRangeInHotels(from, toEx, scopedHotelIds);
// 全国:按入住日扫日历(通常 1 晚,走 stay_date 索引);有区域则在酒店集合内查
List<Long> 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})