'date', 'opens_at' => 'datetime', 'closes_at' => 'datetime', 'day_quota' => 'integer', 'booked_count' => 'integer', ]; public function activity(): BelongsTo { return $this->belongsTo(Activity::class); } /** * 当前时刻是否处于预约开放窗口且仍有余量(与 H5 预约接口判定一致)。 */ public function isCurrentlyBookable(): bool { $available = max(0, (int) $this->day_quota - (int) $this->booked_count); $closesAt = $this->closes_at ?: $this->opens_at->copy()->endOfDay(); $now = now(); $isOpenWindow = $this->opens_at->lte($now) && $closesAt->gte($now); return $isOpenWindow && $available > 0; } }