You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

189 lines
5.2 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?php
namespace App\Models;
class VisitTime extends SoftDeletesModel
{
protected $table = 'visit_times';
/**
* 关联访问申请
*/
public function visits()
{
return $this->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;
}
}