我正在开发一个 Laravel/Filament 应用程序,我需要从排队作业中广播事件来更新 Filament RelationManager 的状态。
设置
我有一个排队作业,可以为患者生成分析。分析完成后,它会广播一个事件,该事件应在我的 Filament RelationManager 组件中触发刷新。
广播工作正常(工作完成后我收到“分析完成”通知),但 RelationManager 中的 Livewire 侦听器未触发。
什么在起作用
什么不起作用
日志
[2024-12-04 15:07:27] local.INFO: Dispatching job with: {"livewire_record_type":"App\\Models\\Patient","livewire_record_data":{"id":1...}}
[2024-12-04 15:07:27] local.INFO: Job constructor called with: {"patient_type":"App\\Models\\Patient","patient_data":{"id":1...}}
[2024-12-04 15:07:28] local.INFO: Broadcasting analysis event {"channel":"analyses","event":"analysis-completed"}
[2024-12-04 15:07:29] local.INFO: Broadcasting analysis completed event
代码结构
作业(应用程序/作业/GeneratePatientAnalysis.php):
class GeneratePatientAnalysis implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected int $userId;
public function __construct(protected Patient $patient)
{
\Log::info('Job constructor called with:', [
'patient_type' => get_class($patient),
'patient_data' => $patient->toArray()
]);
$this->userId = auth()->id();
}
public function handle(AiAnalysisService $aiService): void
{
$latestVersion = $this->patient->analyses()
->latest()
->first()?->version ?? '0.0';
$newVersion = number_format((float) $latestVersion + 0.1, 1);
$analysis = Analysis::create([
'patient_id' => $this->patient->id,
'generated_by' => $this->userId,
'status' => 'pending',
'version' => $newVersion,
'model_used' => 'gpt-4o',
]);
try {
$patientData = $this->gatherPatientData();
$analysis->update([
'analysis_content' => 'Generated Analysis Here',
'status' => 'completed',
'completed_at' => now(),
]);
$user = User::find($this->userId);
Notification::make()
->title('Analysis Complete')
->success()
->broadcast([$user])
->send();
\Log::info('Broadcasting analysis event', [
'channel' => 'analyses',
'event' => 'analysis-completed'
]);
broadcast(new AnalysisCompleted($analysis))->toOthers();
} catch (\Exception $e) {
$analysis->update(['status' => 'failed']);
Notification::make()
->title('Analysis Failed')
->danger()
->send();
}
}
}
事件(应用程序/事件/AnalysisCompleted.php):
class AnalysisCompleted implements ShouldBroadcast
{
public Analysis $analysis;
public function broadcastOn(): array
{
return ['analyses'];
}
public function broadcastAs(): string
{
return 'analysis-completed';
}
}
RelationManager(应用程序/灯丝/资源/PatientResource/RelationManagers/AnalysesRelationManager.php):
protected $listeners = [
'echo:analyses,analysis-completed' => 'refreshAnalyses'
];
public function refreshAnalyses(): void
{
$this->isGenerating = false;
$this->render();
}
public function table(Table $table): Table
{
return $table
->columns([]),
->headerActions([
\Filament\Tables\Actions\Action::make('generate')
->label('Generate New Analysis')
->action(function ($livewire) {
\Log::info('Dispatching job with:', [
'livewire_record_type' => get_class($livewire->ownerRecord),
'livewire_record_data' => $livewire->ownerRecord->toArray()
]);
$this->isGenerating = true;
GeneratePatientAnalysis::dispatch($livewire->ownerRecord)
->onQueue('default');
$this->render();
Notification::make()
->title('Analysis Generation Started')
->body('You will be notified when the analysis is ready.')
->success()
->send();
})
->icon('heroicon-o-plus')
->disabled(fn() => $this->isGenerating)
])
}
我解决了这个问题,它就像你想象的那样愚蠢。 我缺少事件名称上的前缀点。
protected $listeners = [
'echo:analyses,.analysis-completed' => 'refreshAnalyses'
];
现在一切都按预期进行。