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.

193 lines
5.3 KiB

11 months ago
<?php
namespace App\Models;
11 months ago
use Illuminate\Database\Eloquent\Factories\HasFactory;
11 months ago
class VisitTime extends SoftDeletesModel
{
11 months ago
use HasFactory;
11 months ago
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;
}
}