hasMany(Visit::class, 'visit_time_id'); } /** * 获取时段文本 */ public function getTimeTextAttribute() { return $this->start_time . ' - ' . $this->end_time; } /** * 获取时段时长(分钟) */ public function getDuration() { $start = \Carbon\Carbon::createFromFormat('H:i', $this->start_time); $end = \Carbon\Carbon::createFromFormat('H:i', $this->end_time); return $end->diffInMinutes($start); } /** * 检查时间是否冲突 */ public function hasTimeConflict($startTime, $endTime, $excludeId = null) { $query = self::where(function ($q) use ($startTime, $endTime) { $q->where(function ($q1) use ($startTime, $endTime) { // 新时段开始时间在现有时段内 $q1->where('start_time', '<=', $startTime) ->where('end_time', '>', $startTime); })->orWhere(function ($q2) use ($startTime, $endTime) { // 新时段结束时间在现有时段内 $q2->where('start_time', '<', $endTime) ->where('end_time', '>=', $endTime); })->orWhere(function ($q3) use ($startTime, $endTime) { // 新时段完全包含现有时段 $q3->where('start_time', '>=', $startTime) ->where('end_time', '<=', $endTime); }); }); if ($excludeId) { $query->where('id', '!=', $excludeId); } return $query->exists(); } /** * 检查指定时间是否在时段内 */ public function isTimeInRange($time) { $checkTime = \Carbon\Carbon::createFromFormat('H:i', $time); $startTime = \Carbon\Carbon::createFromFormat('H:i', $this->start_time); $endTime = \Carbon\Carbon::createFromFormat('H:i', $this->end_time); return $checkTime->between($startTime, $endTime); } /** * 获取可用的时段列表 */ public static function getAvailableTimes($date = null) { $query = self::orderBy('start_time'); if ($date) { // 可以根据日期过滤,比如某些时段在特定日期不可用 // 这里可以根据实际需求扩展 } return $query->get(); } /** * 检查时段是否可用 */ public function isAvailable($date = null) { // 基本检查 if (empty($this->start_time) || empty($this->end_time)) { return false; } // 检查时间格式 try { $start = \Carbon\Carbon::createFromFormat('H:i', $this->start_time); $end = \Carbon\Carbon::createFromFormat('H:i', $this->end_time); } catch (\Exception $e) { return false; } // 检查开始时间不能晚于结束时间 if ($start->gte($end)) { return false; } // 可以根据日期进行更复杂的检查 if ($date) { // 例如:检查是否是工作日、节假日等 // 这里可以根据实际需求扩展 } return true; } /** * 获取时段统计信息 */ public function getStatistics() { $visits = $this->visits(); return [ 'time_text' => $this->getTimeTextAttribute(), 'duration' => $this->getDuration(), 'total_visits' => $visits->count(), 'today_visits' => $visits->whereDate('date', today())->count(), 'this_week_visits' => $visits->whereBetween('date', [ now()->startOfWeek(), now()->endOfWeek() ])->count(), 'this_month_visits' => $visits->whereMonth('date', now()->month)->count(), ]; } /** * 获取时段使用率 */ public function getUsageRate($date = null) { if (!$date) { $date = today(); } $visits = $this->visits()->whereDate('date', $date)->count(); $maxCapacity = 10; // 假设每个时段最大容量为10人,可以根据实际需求调整 return min(100, ($visits / $maxCapacity) * 100); } /** * 验证时段数据 */ public function validate() { $errors = []; if (empty($this->start_time)) { $errors[] = '开始时间不能为空'; } if (empty($this->end_time)) { $errors[] = '结束时间不能为空'; } if (!empty($this->start_time) && !empty($this->end_time)) { try { $start = \Carbon\Carbon::createFromFormat('H:i', $this->start_time); $end = \Carbon\Carbon::createFromFormat('H:i', $this->end_time); if ($start->gte($end)) { $errors[] = '开始时间不能晚于或等于结束时间'; } } catch (\Exception $e) { $errors[] = '时间格式不正确'; } } return $errors; } }