latestPdfPath()); } #[Computed(cache: false)] public function latestPdfMtime(): ?string { $p = $this->latestPdfPath(); return is_file($p) ? date('Y-m-d H:i:s', filemtime($p)) : null; } #[Computed(cache: false)] public function pdfOpenUrl(): string { return route('filament.admin.reports.teacher-weekly-stats.open'); } protected function latestPdfPath(): string { return storage_path('app/reports/teacher-weekly-stats-latest.pdf'); } protected function getHeaderActions(): array { return [ Action::make('regenerate') ->label('生成 / 刷新周报 PDF') ->icon('heroicon-o-arrow-path') ->action(function (): void { $code = Artisan::call('report:teacher-weekly-pdf'); if ($code !== 0) { Notification::make() ->title('生成失败') ->danger() ->body('请查看日志或终端输出') ->send(); return; } $this->dispatch('$refresh'); Notification::make() ->title('周报已生成') ->success() ->send(); }), ]; } }