Laravel日期冲突查询问题:排除重叠预订房源失败排查
代码问题分析及修正
你的代码存在以下几个关键问题:
1. 查询逻辑完全反转
需求是排除所有存在日期重叠预订的房源,但你用了whereHas方法——这个方法会筛选出有符合条件预订记录的房源,刚好和需求相反。应该使用whereDoesntHave,它会返回没有匹配到指定预订条件的房源。
2. 日期重叠的判断逻辑错误
你当前的日期条件无法正确识别区间重叠的情况。两个日期区间[用户开始, 用户结束]和[已有预订开始, 已有预订结束]重叠的核心判断逻辑是:
已有预订的开始日期 < 用户的结束日期 且 已有预订的结束日期 > 用户的开始日期
只有满足这个条件,两个区间才存在重叠。
3. Carbon对象处理无效
你调用$startDate->addDay()->format('Y-m-d')后,没有把格式化后的字符串赋值回变量,所以后续使用的$startDate还是原始的Carbon对象,addDay()的修改和format()的结果都没被实际使用。
4. 运算符拼写错误
代码里的'=>'是HTML转义字符,应该直接写PHP的比较运算符'>='。
修正后的代码
// 正确处理日期,保存格式化后的字符串 $userStart = Carbon::parse($request->start)->addDay()->format('Y-m-d'); $userEnd = Carbon::parse($request->end)->addDay()->format('Y-m-d'); $suits = Homes::where('type', 0) ->where('status', 1) ->where('info_capacity', '<=', $countPeople) ->with('Reservations') // 使用whereDoesntHave排除有重叠预订的房源 ->whereDoesntHave('Reservations', function ($query) use ($userEnd, $userStart) { $query->where('start_date', '<', $userEnd) ->where('end_date', '>', $userStart); }) ->get(); return response()->json(HomesListResource::collection($suits));
如果你数据库里的日期是闭区间(比如end_date是退房当天,包含当天),可以把判断条件调整为:
$query->where('start_date', '<=', $userEnd) ->where('end_date', '>=', $userStart);
具体根据你实际的日期存储规则调整。
内容的提问来源于stack exchange,提问作者Beggy
相关产品推荐
相关产品推荐

