reminder/app/Models/Patient.php
2026-01-12 12:42:48 +08:00

141 lines
3.4 KiB
PHP

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Carbon\Carbon;
class Patient extends Model
{
protected $fillable = [
'user_id',
'name',
'gender',
'age',
'diagnosis',
'discharge_date',
'address',
'phone',
'remark',
'follow_up_count',
'last_follow_up_date',
];
/**
* 获取患者所属用户
*/
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
protected $casts = [
'discharge_date' => 'date',
'last_follow_up_date' => 'date',
];
/**
* 获取随访时间规则(月数)
* 脑卒中/心肌梗塞: 1, 3, 6, 12 个月
* 慢性肾脏病: 1, 2, 3, 6 个月
*/
public function getFollowUpSchedule(): array
{
$diagnosis = $this->diagnosis;
if (str_contains($diagnosis, '慢性肾') || str_contains($diagnosis, '肾脏病')) {
return [1, 2, 3, 6]; // 慢性肾脏病
}
// 脑卒中、心肌梗塞及其他
return [1, 3, 6, 12];
}
/**
* 获取下次随访日期
*/
public function getNextFollowUpDate(): ?Carbon
{
$schedule = $this->getFollowUpSchedule();
$nextIndex = $this->follow_up_count;
if ($nextIndex >= count($schedule)) {
return null; // 已完成所有随访
}
$months = $schedule[$nextIndex];
return $this->discharge_date->copy()->addMonths($months);
}
/**
* 获取下次随访是第几次
*/
public function getNextFollowUpNumber(): int
{
return $this->follow_up_count + 1;
}
/**
* 检查是否需要随访(到期或已过期)
*/
public function needsFollowUp(): bool
{
$nextDate = $this->getNextFollowUpDate();
if (!$nextDate) {
return false;
}
return $nextDate->lte(Carbon::today());
}
/**
* 获取随访状态
*/
public function getFollowUpStatus(): string
{
$nextDate = $this->getNextFollowUpDate();
if (!$nextDate) {
return '已完成';
}
$today = Carbon::today();
$diff = $today->diffInDays($nextDate, false);
if ($diff < 0) {
return '已过期 ' . abs($diff) . ' 天';
} elseif ($diff == 0) {
return '今日到期';
} elseif ($diff <= 7) {
return '即将到期(' . $diff . '天后)';
} else {
return '未到期';
}
}
/**
* 检查是否已完成所有随访
*/
public function isCompleted(): bool
{
return $this->follow_up_count >= count($this->getFollowUpSchedule());
}
/**
* 获取诊断类型名称
*/
public function getDiagnosisType(): string
{
if (str_contains($this->diagnosis, '脑卒中')) {
return '脑卒中';
} elseif (str_contains($this->diagnosis, '心肌梗') || str_contains($this->diagnosis, '心梗')) {
return '心肌梗塞';
} elseif (str_contains($this->diagnosis, '慢性肾') || str_contains($this->diagnosis, '肾脏病')) {
return '慢性肾脏病';
}
return $this->diagnosis;
}
}