|
|
@@ -103,10 +103,10 @@ export default {
|
|
|
const [startH, startM] = this.startHour.split(':').map(Number);
|
|
|
const [endH, endM] = this.endHour.split(':').map(Number);
|
|
|
|
|
|
- // 构造当天的开始和结束时间对象
|
|
|
+ // 构造当天的开始时间
|
|
|
let current = new Date(targetDateStr.replace(/-/g, '/'));
|
|
|
current.setHours(startH, startM, 0, 0);
|
|
|
-
|
|
|
+ // 结束时间
|
|
|
const endLimit = new Date(targetDateStr.replace(/-/g, '/'));
|
|
|
endLimit.setHours(endH, endM, 0, 0);
|
|
|
|
|
|
@@ -116,30 +116,45 @@ export default {
|
|
|
// 计算这个Slot如果被选中,服务结束的时间戳
|
|
|
const slotEndTimestamp = slotStartTimestamp + this.duration * 60 * 1000;
|
|
|
|
|
|
- let isDisabled = false;
|
|
|
- let reason = '';
|
|
|
+ let isDisabled = false, reason = '';
|
|
|
|
|
|
- // 1. 校验是否过期 (如果是今天)
|
|
|
+ // 1. 校验是否过期(如果是今天)
|
|
|
if (slotStartTimestamp < bufferTimestamp) {
|
|
|
isDisabled = true;
|
|
|
- // 只有在显示“今天”的时候才不需要显示reason,直接置灰即可,或者显示“已过”
|
|
|
- // 这里为了美观,过期时间通常不显示文字,只置灰
|
|
|
+ // 已过的时间通常不需要文字提示,或者显示“已过”
|
|
|
+ // reason = '已过';
|
|
|
}
|
|
|
-
|
|
|
- // 2. 校验是否被占用 (核心算法: 区间重叠)
|
|
|
- // 规则:如果不重叠,必须 (Slot结束 <= 预订开始) 或者 (Slot开始 >= 预订结束)
|
|
|
- // 反之,如果有交集则 disable
|
|
|
- if (!isDisabled && this.bookedTimes.length > 0) {
|
|
|
- const isOverlap = this.bookedTimes.some(book => {
|
|
|
+ // 2. 判断是否“超出营业时间”
|
|
|
+ // 如果服务结束时间 > 营业结束时间
|
|
|
+ // else if (slotEndTimestamp > endLimit) {
|
|
|
+ // isDisabled = true;
|
|
|
+ // reason = '时长不足'; // 或者 "超营业期"
|
|
|
+ // }
|
|
|
+ // 3. 判断与“已预约订单”的冲突
|
|
|
+ else if (this.bookedTimes.length > 0) {
|
|
|
+ for (let book of this.bookedTimes) {
|
|
|
const bookStart = new Date(book.start.replace(/-/g, '/')).getTime();
|
|
|
const bookEnd = new Date(book.end.replace(/-/g, '/')).getTime();
|
|
|
- // 判断交集: (A_start < B_end) && (A_end > B_start)
|
|
|
- return slotStartTimestamp < bookEnd && slotEndTimestamp > bookStart;
|
|
|
- });
|
|
|
-
|
|
|
- if (isOverlap) {
|
|
|
- isDisabled = true;
|
|
|
- reason = '约满';
|
|
|
+
|
|
|
+ // 判断是否有交集
|
|
|
+ // 公式:(SlotStart < BookEnd) && (SlotEnd > BookStart)
|
|
|
+ if (slotStartTimestamp < bookEnd && slotEndTimestamp > bookStart) {
|
|
|
+ isDisabled = true;
|
|
|
+
|
|
|
+ // 情况A:当前格子的“起点”本身就在别人订单里
|
|
|
+ // 例如:别人约了14:00-16:00,我看15:00的格子
|
|
|
+ if (slotStartTimestamp >= bookStart && slotStartTimestamp < bookEnd) {
|
|
|
+ reason = '已约';
|
|
|
+ }
|
|
|
+ // 情况B:当前格子起点是空的,但服务时长太长,撞到了后面的订单
|
|
|
+ // 例如:别人约了17:00开始。我看15:30的格子(服务2小时),15:30是空的,但17:30才结束,撞了。
|
|
|
+ else {
|
|
|
+ reason = '时长不足';
|
|
|
+ }
|
|
|
+
|
|
|
+ // 只要找到一个冲突就跳出循环
|
|
|
+ break;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|