Refactor patient follow-up system to focus on monthly reminders. Updated logic to filter and display only patients needing follow-up this month. Enhanced patient model methods for calculating follow-up dates and counts. Improved UI in reminders view with new layout and call button functionality.
This commit is contained in:
parent
ca4d1fa1a5
commit
0dd6529dcf
@ -11,11 +11,10 @@
|
||||
- 🗑️ 删除患者记录
|
||||
|
||||
### 随访提醒
|
||||
- ⏰ 智能计算随访日期(出院后1周、1月、3月、6月)
|
||||
- 🔴 过期提醒 - 显示已过期未随访的患者
|
||||
- 🟡 今日到期 - 当天需要随访的患者
|
||||
- 🔵 即将到期 - 7天内需要随访的患者
|
||||
- ✅ 标记随访完成,自动计算下次随访时间
|
||||
- ⏰ 智能计算随访日期(出院后1、3、6、12个月)
|
||||
- 📅 本月提醒 - 只显示本月需要随访的患者列表
|
||||
- 📊 进度自动更新 - 过期月份自动算作已完成
|
||||
- 📞 一键拨打电话进行回访
|
||||
|
||||
### 用户系统
|
||||
- 👤 用户注册/登录
|
||||
|
||||
@ -46,54 +46,33 @@ class PatientController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示需要随访提醒的患者
|
||||
* 显示需要随访提醒的患者(只显示当月需要随访的)
|
||||
*/
|
||||
public function reminders(Request $request)
|
||||
{
|
||||
$patients = $this->userPatients()->get();
|
||||
|
||||
// 筛选需要随访的患者
|
||||
// 只筛选当月需要随访的患者
|
||||
$reminders = $patients->filter(function ($patient) {
|
||||
return !$patient->isCompleted();
|
||||
return $patient->needsFollowUpThisMonth();
|
||||
})->map(function ($patient) {
|
||||
$nextDate = $patient->getNextFollowUpDate();
|
||||
return [
|
||||
'patient' => $patient,
|
||||
'next_follow_up_date' => $nextDate,
|
||||
'next_follow_up_number' => $patient->getNextFollowUpNumber(),
|
||||
'status' => $patient->getFollowUpStatus(),
|
||||
'needs_attention' => $patient->needsFollowUp(),
|
||||
'days_until' => $nextDate ? Carbon::today()->diffInDays($nextDate, false) : null,
|
||||
'follow_up_date' => $patient->getCurrentMonthFollowUpDate(),
|
||||
'follow_up_number' => $patient->getCurrentMonthFollowUpNumber(),
|
||||
];
|
||||
})->sortBy('days_until');
|
||||
|
||||
// 筛选类型
|
||||
$filter = $request->input('filter', 'all');
|
||||
|
||||
if ($filter === 'overdue') {
|
||||
$reminders = $reminders->filter(fn($r) => $r['days_until'] !== null && $r['days_until'] < 0);
|
||||
} elseif ($filter === 'today') {
|
||||
$reminders = $reminders->filter(fn($r) => $r['days_until'] === 0);
|
||||
} elseif ($filter === 'upcoming') {
|
||||
$reminders = $reminders->filter(fn($r) => $r['days_until'] !== null && $r['days_until'] > 0 && $r['days_until'] <= 7);
|
||||
}
|
||||
})->sortBy(function ($r) {
|
||||
return $r['follow_up_date'];
|
||||
});
|
||||
|
||||
// 统计数据
|
||||
$stats = [
|
||||
'total' => $this->userPatients()->count(),
|
||||
'overdue' => $patients->filter(fn($p) => !$p->isCompleted() && $p->getNextFollowUpDate()?->lt(Carbon::today()))->count(),
|
||||
'today' => $patients->filter(fn($p) => !$p->isCompleted() && $p->getNextFollowUpDate()?->isToday())->count(),
|
||||
'upcoming' => $patients->filter(function ($p) {
|
||||
if ($p->isCompleted()) return false;
|
||||
$next = $p->getNextFollowUpDate();
|
||||
if (!$next) return false;
|
||||
$diff = Carbon::today()->diffInDays($next, false);
|
||||
return $diff > 0 && $diff <= 7;
|
||||
})->count(),
|
||||
'count' => $reminders->count(),
|
||||
'completed' => $patients->filter(fn($p) => $p->isCompleted())->count(),
|
||||
'total' => $patients->count(),
|
||||
];
|
||||
|
||||
return view('patients.reminders', compact('reminders', 'stats', 'filter'));
|
||||
return view('patients.reminders', compact('reminders', 'stats'));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -359,46 +338,34 @@ class PatientController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出提醒列表 (使用 xlswriter 生成 Excel)
|
||||
* 导出本月随访列表 (使用 xlswriter 生成 Excel)
|
||||
*/
|
||||
public function export(Request $request)
|
||||
{
|
||||
$filter = $request->input('filter', 'all');
|
||||
|
||||
$patients = $this->userPatients()->get();
|
||||
|
||||
// 筛选需要随访的患者
|
||||
// 只筛选本月需要随访的患者
|
||||
$reminders = $patients->filter(function ($patient) {
|
||||
return !$patient->isCompleted();
|
||||
return $patient->needsFollowUpThisMonth();
|
||||
})->map(function ($patient) {
|
||||
$nextDate = $patient->getNextFollowUpDate();
|
||||
return [
|
||||
'patient' => $patient,
|
||||
'next_follow_up_date' => $nextDate,
|
||||
'next_follow_up_number' => $patient->getNextFollowUpNumber(),
|
||||
'status' => $patient->getFollowUpStatus(),
|
||||
'days_until' => $nextDate ? Carbon::today()->diffInDays($nextDate, false) : null,
|
||||
'follow_up_date' => $patient->getCurrentMonthFollowUpDate(),
|
||||
'follow_up_number' => $patient->getCurrentMonthFollowUpNumber(),
|
||||
];
|
||||
})->sortBy('days_until');
|
||||
|
||||
// 根据筛选条件过滤
|
||||
if ($filter === 'overdue') {
|
||||
$reminders = $reminders->filter(fn($r) => $r['days_until'] !== null && $r['days_until'] < 0);
|
||||
} elseif ($filter === 'today') {
|
||||
$reminders = $reminders->filter(fn($r) => $r['days_until'] === 0);
|
||||
} elseif ($filter === 'upcoming') {
|
||||
$reminders = $reminders->filter(fn($r) => $r['days_until'] !== null && $r['days_until'] > 0 && $r['days_until'] <= 7);
|
||||
}
|
||||
})->sortBy(function ($r) {
|
||||
return $r['follow_up_date'];
|
||||
});
|
||||
|
||||
// 使用 xlswriter 生成 Excel 文件
|
||||
$config = ['path' => sys_get_temp_dir()];
|
||||
$filename = '随访提醒_' . date('Y-m-d_His') . '.xlsx';
|
||||
$filename = '本月随访_' . date('Y-m') . '.xlsx';
|
||||
|
||||
$excel = new \Vtiful\Kernel\Excel($config);
|
||||
|
||||
// 创建文件并设置表头
|
||||
$fileHandle = $excel->fileName($filename)
|
||||
->header(['姓名', '性别', '年龄', '出院诊断', '转诊时间', '下次随访日期', '第几次随访', '状态', '户籍地址', '联系方式', '备注']);
|
||||
->header(['姓名', '性别', '年龄', '出院诊断', '转诊时间', '随访日期', '第几次随访', '户籍地址', '联系方式', '备注']);
|
||||
|
||||
// 设置表头样式
|
||||
$headerStyle = $fileHandle->getHandle();
|
||||
@ -415,9 +382,8 @@ class PatientController extends Controller
|
||||
$p->age,
|
||||
$p->diagnosis,
|
||||
$p->discharge_date->format('Y-m-d'),
|
||||
$reminder['next_follow_up_date']?->format('Y-m-d') ?? '',
|
||||
'第' . $reminder['next_follow_up_number'] . '次',
|
||||
$reminder['status'],
|
||||
$reminder['follow_up_date']?->format('Y-m-d') ?? '',
|
||||
'第' . $reminder['follow_up_number'] . '次',
|
||||
$p->address ?? '',
|
||||
$p->phone ?? '',
|
||||
$p->remark ?? '',
|
||||
|
||||
@ -53,74 +53,82 @@ class Patient extends Model
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取下次随访日期
|
||||
* 自动计算已完成的随访次数(过期的月份自动算已完成)
|
||||
*/
|
||||
public function getNextFollowUpDate(): ?Carbon
|
||||
public function getAutoFollowUpCount(): int
|
||||
{
|
||||
$schedule = $this->getFollowUpSchedule();
|
||||
$nextIndex = $this->follow_up_count;
|
||||
$currentMonth = Carbon::now()->startOfMonth();
|
||||
$completed = 0;
|
||||
|
||||
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 . '天后)';
|
||||
foreach ($schedule as $months) {
|
||||
$followUpDate = $this->discharge_date->copy()->addMonths($months);
|
||||
// 如果随访日期的月份早于当前月份,则算作已完成
|
||||
if ($followUpDate->startOfMonth()->lt($currentMonth)) {
|
||||
$completed++;
|
||||
} else {
|
||||
return '未到期';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $completed;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当月需要随访的日期(如果有的话)
|
||||
*/
|
||||
public function getCurrentMonthFollowUpDate(): ?Carbon
|
||||
{
|
||||
$schedule = $this->getFollowUpSchedule();
|
||||
$currentMonth = Carbon::now();
|
||||
$monthStart = $currentMonth->copy()->startOfMonth();
|
||||
$monthEnd = $currentMonth->copy()->endOfMonth();
|
||||
|
||||
foreach ($schedule as $index => $months) {
|
||||
$followUpDate = $this->discharge_date->copy()->addMonths($months);
|
||||
// 如果随访日期在当月内
|
||||
if ($followUpDate->gte($monthStart) && $followUpDate->lte($monthEnd)) {
|
||||
return $followUpDate;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当月随访是第几次
|
||||
*/
|
||||
public function getCurrentMonthFollowUpNumber(): ?int
|
||||
{
|
||||
$schedule = $this->getFollowUpSchedule();
|
||||
$currentMonth = Carbon::now();
|
||||
$monthStart = $currentMonth->copy()->startOfMonth();
|
||||
$monthEnd = $currentMonth->copy()->endOfMonth();
|
||||
|
||||
foreach ($schedule as $index => $months) {
|
||||
$followUpDate = $this->discharge_date->copy()->addMonths($months);
|
||||
if ($followUpDate->gte($monthStart) && $followUpDate->lte($monthEnd)) {
|
||||
return $index + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查当月是否需要随访
|
||||
*/
|
||||
public function needsFollowUpThisMonth(): bool
|
||||
{
|
||||
return $this->getCurrentMonthFollowUpDate() !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否已完成所有随访
|
||||
*/
|
||||
public function isCompleted(): bool
|
||||
{
|
||||
return $this->follow_up_count >= count($this->getFollowUpSchedule());
|
||||
return $this->getAutoFollowUpCount() >= count($this->getFollowUpSchedule());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -1113,7 +1113,31 @@
|
||||
.reminder-actions {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
justify-content: flex-end;
|
||||
margin-top: 16px;
|
||||
padding-top: 16px;
|
||||
border-top: 1px solid var(--color-border-light);
|
||||
}
|
||||
|
||||
.call-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
width: 100%;
|
||||
padding: 12px 16px;
|
||||
background: linear-gradient(135deg, var(--color-success), #34d399);
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 10px;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
text-decoration: none;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.call-btn:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 12px rgba(16, 185, 129, 0.4);
|
||||
}
|
||||
|
||||
.action-form {
|
||||
@ -1778,12 +1802,12 @@
|
||||
</svg>
|
||||
<span>随访提醒</span>
|
||||
@php
|
||||
$overdueCount = \App\Models\Patient::where('user_id', Auth::id())->get()->filter(function($p) {
|
||||
return !$p->isCompleted() && $p->getNextFollowUpDate()?->lt(\Carbon\Carbon::today());
|
||||
$monthCount = \App\Models\Patient::where('user_id', Auth::id())->get()->filter(function($p) {
|
||||
return $p->needsFollowUpThisMonth();
|
||||
})->count();
|
||||
@endphp
|
||||
@if($overdueCount > 0)
|
||||
<span class="nav-badge">{{ $overdueCount }}</span>
|
||||
@if($monthCount > 0)
|
||||
<span class="nav-badge">{{ $monthCount }}</span>
|
||||
@endif
|
||||
</a>
|
||||
|
||||
|
||||
@ -600,7 +600,6 @@
|
||||
<th>诊断</th>
|
||||
<th>转诊日期</th>
|
||||
<th>随访进度</th>
|
||||
<th>状态</th>
|
||||
<th>联系方式</th>
|
||||
<th>备注</th>
|
||||
<th style="text-align: right;">操作</th>
|
||||
@ -610,8 +609,7 @@
|
||||
@foreach($patients as $patient)
|
||||
@php
|
||||
$total = count($patient->getFollowUpSchedule());
|
||||
$completed = $patient->follow_up_count;
|
||||
$status = $patient->getFollowUpStatus();
|
||||
$completed = $patient->getAutoFollowUpCount();
|
||||
@endphp
|
||||
<tr>
|
||||
<td>
|
||||
@ -637,17 +635,6 @@
|
||||
<span class="progress-text">{{ $completed }}/{{ $total }}</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
@if($patient->isCompleted())
|
||||
<span class="badge badge-success">已完成</span>
|
||||
@elseif(str_contains($status, '过期'))
|
||||
<span class="badge badge-danger">{{ $status }}</span>
|
||||
@elseif(str_contains($status, '今日'))
|
||||
<span class="badge badge-warning">{{ $status }}</span>
|
||||
@else
|
||||
<span class="badge badge-info">{{ $status }}</span>
|
||||
@endif
|
||||
</td>
|
||||
<td>
|
||||
@if($patient->phone)
|
||||
<a href="tel:{{ $patient->phone }}" class="phone-link">{{ $patient->phone }}</a>
|
||||
@ -671,16 +658,6 @@
|
||||
</svg>
|
||||
</a>
|
||||
@endif
|
||||
@if(!$patient->isCompleted())
|
||||
<form action="{{ route('patients.follow-up', $patient) }}" method="POST" style="display: inline;">
|
||||
@csrf
|
||||
<button type="submit" class="btn-icon success" title="标记已随访" onclick="return confirm('确认标记 {{ $patient->name }} 完成第{{ $patient->getNextFollowUpNumber() }}次随访?')">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<polyline points="20 6 9 17 4 12"/>
|
||||
</svg>
|
||||
</button>
|
||||
</form>
|
||||
@endif
|
||||
<form action="{{ route('patients.destroy', $patient) }}" method="POST" style="display: inline;">
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
@ -705,8 +682,7 @@
|
||||
@foreach($patients as $patient)
|
||||
@php
|
||||
$total = count($patient->getFollowUpSchedule());
|
||||
$completed = $patient->follow_up_count;
|
||||
$status = $patient->getFollowUpStatus();
|
||||
$completed = $patient->getAutoFollowUpCount();
|
||||
@endphp
|
||||
<div class="mobile-patient-card">
|
||||
<div class="mobile-patient-header">
|
||||
@ -719,15 +695,7 @@
|
||||
<div class="mobile-patient-meta">{{ $patient->gender }} · {{ $patient->age }}岁 · {{ $patient->getDiagnosisType() }}</div>
|
||||
</div>
|
||||
</div>
|
||||
@if($patient->isCompleted())
|
||||
<span class="badge badge-success">已完成</span>
|
||||
@elseif(str_contains($status, '过期'))
|
||||
<span class="badge badge-danger">{{ $status }}</span>
|
||||
@elseif(str_contains($status, '今日'))
|
||||
<span class="badge badge-warning">{{ $status }}</span>
|
||||
@else
|
||||
<span class="badge badge-info">{{ $status }}</span>
|
||||
@endif
|
||||
<span class="badge {{ $completed >= $total ? 'badge-success' : 'badge-info' }}">{{ $completed }}/{{ $total }}</span>
|
||||
</div>
|
||||
|
||||
<div class="mobile-patient-body">
|
||||
@ -780,19 +748,6 @@
|
||||
<div></div>
|
||||
@endif
|
||||
|
||||
@if(!$patient->isCompleted())
|
||||
<form action="{{ route('patients.follow-up', $patient) }}" method="POST">
|
||||
@csrf
|
||||
<button type="submit" class="btn btn-primary" onclick="return confirm('确认标记 {{ $patient->name }} 完成第{{ $patient->getNextFollowUpNumber() }}次随访?')">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="18" height="18">
|
||||
<polyline points="20 6 9 17 4 12"/>
|
||||
</svg>
|
||||
已随访
|
||||
</button>
|
||||
</form>
|
||||
@else
|
||||
<div></div>
|
||||
@endif
|
||||
|
||||
<form action="{{ route('patients.destroy', $patient) }}" method="POST">
|
||||
@csrf
|
||||
|
||||
@ -4,35 +4,27 @@
|
||||
|
||||
@section('content')
|
||||
<div class="page-header">
|
||||
<h1 class="page-title">随访提醒</h1>
|
||||
<p class="page-subtitle">查看需要随访的患者,及时完成回访工作</p>
|
||||
<h1 class="page-title">本月随访</h1>
|
||||
<p class="page-subtitle">{{ now()->format('Y年n月') }} 需要随访的患者</p>
|
||||
</div>
|
||||
|
||||
<!-- 统计筛选栏 -->
|
||||
<!-- 统计栏 -->
|
||||
<div class="stats-filter-bar">
|
||||
<div class="stats-filter-grid">
|
||||
<a href="{{ route('patients.reminders', ['filter' => 'all']) }}" class="stats-filter-item {{ $filter === 'all' ? 'active' : '' }}">
|
||||
<span class="sf-value">{{ $stats['total'] }}</span>
|
||||
<span class="sf-label">全部</span>
|
||||
</a>
|
||||
<a href="{{ route('patients.reminders', ['filter' => 'overdue']) }}" class="stats-filter-item danger {{ $filter === 'overdue' ? 'active' : '' }}">
|
||||
<span class="sf-value">{{ $stats['overdue'] }}</span>
|
||||
<span class="sf-label">过期</span>
|
||||
</a>
|
||||
<a href="{{ route('patients.reminders', ['filter' => 'today']) }}" class="stats-filter-item warning {{ $filter === 'today' ? 'active' : '' }}">
|
||||
<span class="sf-value">{{ $stats['today'] }}</span>
|
||||
<span class="sf-label">今日</span>
|
||||
</a>
|
||||
<a href="{{ route('patients.reminders', ['filter' => 'upcoming']) }}" class="stats-filter-item info {{ $filter === 'upcoming' ? 'active' : '' }}">
|
||||
<span class="sf-value">{{ $stats['upcoming'] }}</span>
|
||||
<span class="sf-label">7天内</span>
|
||||
</a>
|
||||
<a href="{{ route('patients.reminders', ['filter' => 'completed']) }}" class="stats-filter-item success {{ $filter === 'completed' ? 'active' : '' }}">
|
||||
<span class="sf-value">{{ $stats['completed'] }}</span>
|
||||
<span class="sf-label">完成</span>
|
||||
</a>
|
||||
<div class="stats-filter-item active">
|
||||
<span class="sf-value">{{ $stats['count'] }}</span>
|
||||
<span class="sf-label">本月待随访</span>
|
||||
</div>
|
||||
<a href="{{ route('patients.export', ['filter' => $filter]) }}" class="export-icon-btn" title="导出">
|
||||
<div class="stats-filter-item success">
|
||||
<span class="sf-value">{{ $stats['completed'] }}</span>
|
||||
<span class="sf-label">已完成</span>
|
||||
</div>
|
||||
<div class="stats-filter-item">
|
||||
<span class="sf-value">{{ $stats['total'] }}</span>
|
||||
<span class="sf-label">总患者</span>
|
||||
</div>
|
||||
</div>
|
||||
<a href="{{ route('patients.export') }}" class="export-icon-btn" title="导出">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="18" height="18">
|
||||
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
|
||||
<polyline points="7 10 12 15 17 10"/>
|
||||
@ -50,60 +42,59 @@
|
||||
<line x1="9" y1="9" x2="9.01" y2="9"/>
|
||||
<line x1="15" y1="9" x2="15.01" y2="9"/>
|
||||
</svg>
|
||||
<div class="empty-state-title">暂无需要随访的患者</div>
|
||||
<p>当前筛选条件下没有需要随访的患者,您可以切换筛选条件或导入新的患者数据。</p>
|
||||
<div style="margin-top: 20px;">
|
||||
<a href="{{ route('patients.import') }}" class="btn btn-primary">导入患者数据</a>
|
||||
</div>
|
||||
<div class="empty-state-title">本月暂无需要随访的患者</div>
|
||||
<p>太棒了!本月没有需要随访的患者</p>
|
||||
</div>
|
||||
</div>
|
||||
@else
|
||||
<!-- 提醒卡片列表 - 两列布局 -->
|
||||
<!-- 提醒卡片列表 -->
|
||||
<div class="reminder-grid">
|
||||
@foreach($reminders as $reminder)
|
||||
@php
|
||||
$patient = $reminder['patient'];
|
||||
$nextDate = $reminder['next_follow_up_date'];
|
||||
$daysUntil = $reminder['days_until'];
|
||||
$followUpDate = $reminder['follow_up_date'];
|
||||
$followUpNumber = $reminder['follow_up_number'];
|
||||
@endphp
|
||||
<div class="reminder-card fade-in">
|
||||
{{-- 卡片头部 --}}
|
||||
<div class="reminder-card-header">
|
||||
<div class="reminder-patient-info">
|
||||
<div class="reminder-avatar">{{ mb_substr($patient->name, 0, 1) }}</div>
|
||||
<div class="reminder-avatar {{ $patient->gender == '女' ? 'female' : 'male' }}">{{ mb_substr($patient->name, 0, 1) }}</div>
|
||||
<div>
|
||||
<div class="reminder-name">{{ $patient->name }}</div>
|
||||
<div class="reminder-meta">{{ $patient->gender }} · {{ $patient->age }}岁</div>
|
||||
</div>
|
||||
</div>
|
||||
@if($daysUntil !== null && $daysUntil < 0)
|
||||
<span class="badge badge-danger">过期 {{ abs($daysUntil) }} 天</span>
|
||||
@elseif($daysUntil === 0)
|
||||
<span class="badge badge-warning">今日到期</span>
|
||||
@elseif($daysUntil !== null && $daysUntil <= 7)
|
||||
<span class="badge badge-info">{{ $daysUntil }} 天后</span>
|
||||
@else
|
||||
<span class="badge badge-success">未到期</span>
|
||||
@endif
|
||||
<span class="badge badge-info">第{{ $followUpNumber }}次</span>
|
||||
</div>
|
||||
|
||||
{{-- 诊断标签 --}}
|
||||
<div class="reminder-diagnosis">
|
||||
<span class="diagnosis-tag">{{ $patient->getDiagnosisType() }}</span>
|
||||
<span class="follow-up-tag">第{{ $reminder['next_follow_up_number'] }}次随访</span>
|
||||
</div>
|
||||
|
||||
{{-- 关键信息 --}}
|
||||
<div class="reminder-details">
|
||||
<div class="detail-row">
|
||||
<span class="detail-icon">🏥</span>
|
||||
<span class="detail-label">转诊日期</span>
|
||||
<span class="detail-value">{{ $patient->discharge_date->format('Y-m-d') }}</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-icon">📅</span>
|
||||
<span class="detail-label">随访日期</span>
|
||||
<span class="detail-value">{{ $nextDate ? $nextDate->format('Y-m-d') : '-' }}</span>
|
||||
<span class="detail-value">{{ $followUpDate->format('Y-m-d') }}</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-icon">📞</span>
|
||||
<span class="detail-label">联系方式</span>
|
||||
<span class="detail-value">{{ $patient->phone ?: '-' }}</span>
|
||||
<span class="detail-value">
|
||||
@if($patient->phone)
|
||||
<a href="tel:{{ $patient->phone }}" class="phone-link">{{ $patient->phone }}</a>
|
||||
@else
|
||||
-
|
||||
@endif
|
||||
</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-icon">📍</span>
|
||||
@ -111,7 +102,7 @@
|
||||
<span class="detail-value text-truncate">{{ $patient->address ?: '-' }}</span>
|
||||
</div>
|
||||
@if($patient->remark)
|
||||
<div class="detail-row">
|
||||
<div class="detail-row remark-row">
|
||||
<span class="detail-icon">📝</span>
|
||||
<span class="detail-label">备注</span>
|
||||
<span class="detail-value remark-text">{{ $patient->remark }}</span>
|
||||
@ -119,41 +110,17 @@
|
||||
@endif
|
||||
</div>
|
||||
|
||||
{{-- 进度条 --}}
|
||||
<div class="reminder-progress">
|
||||
@php
|
||||
$total = count($patient->getFollowUpSchedule());
|
||||
$completed = $patient->follow_up_count;
|
||||
$percent = ($completed / $total) * 100;
|
||||
@endphp
|
||||
<div class="progress-header">
|
||||
<span>随访进度</span>
|
||||
<span>{{ $completed }}/{{ $total }}</span>
|
||||
</div>
|
||||
<div class="progress-track">
|
||||
<div class="progress-fill" style="width: {{ $percent }}%"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- 操作按钮 --}}
|
||||
<div class="reminder-actions">
|
||||
{{-- 拨打电话按钮 --}}
|
||||
@if($patient->phone)
|
||||
<a href="tel:{{ $patient->phone }}" class="action-btn action-call" title="拨打电话">
|
||||
<div class="reminder-actions">
|
||||
<a href="tel:{{ $patient->phone }}" class="call-btn">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="18" height="18">
|
||||
<path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"/>
|
||||
</svg>
|
||||
拨打电话
|
||||
</a>
|
||||
@endif
|
||||
<form action="{{ route('patients.follow-up', $patient) }}" method="POST" class="action-form">
|
||||
@csrf
|
||||
<button type="submit" class="action-btn action-complete" title="标记已随访" onclick="return confirm('确认标记 {{ $patient->name }} 完成第{{ $reminder['next_follow_up_number'] }}次随访?')">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="18" height="18">
|
||||
<polyline points="20 6 9 17 4 12"/>
|
||||
</svg>
|
||||
<span>已随访</span>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user