From 29c209116eb0f2f23f60d0c67855bd0fa45948c5 Mon Sep 17 00:00:00 2001 From: lizhuoran <625237490@qq.com> Date: Thu, 12 Mar 2026 15:58:24 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=BC=BA=E6=96=87=E6=A1=A3?= =?UTF-8?q?=E8=BD=AC=E6=8D=A2=E5=A4=B1=E8=B4=A5=E5=A4=84=E7=90=86=E6=9C=BA?= =?UTF-8?q?=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 FixStuckDocuments 命令用于修复卡住的文档 - 支持批量检测和修复超时的转换任务 - 改进重试按钮,支持 failed/processing/pending 状态 - 在确认对话框中显示当前状态和错误信息 - 提供 dry-run 模式预览修复操作 --- app/Console/Commands/FixStuckDocuments.php | 103 ++++++++++++++++++++ app/Filament/Resources/DocumentResource.php | 12 ++- 2 files changed, 113 insertions(+), 2 deletions(-) create mode 100644 app/Console/Commands/FixStuckDocuments.php diff --git a/app/Console/Commands/FixStuckDocuments.php b/app/Console/Commands/FixStuckDocuments.php new file mode 100644 index 0000000..4c980c0 --- /dev/null +++ b/app/Console/Commands/FixStuckDocuments.php @@ -0,0 +1,103 @@ +option('timeout'); + $status = $this->option('status'); + $dryRun = $this->option('dry-run'); + + $this->info("正在查找卡住的文档..."); + $this->info("状态: {$status}"); + $this->info("超时时间: {$timeout} 分钟"); + + // 查找卡住的文档 + $stuckDocuments = Document::where('conversion_status', $status) + ->where('updated_at', '<', now()->subMinutes($timeout)) + ->get(); + + if ($stuckDocuments->isEmpty()) { + $this->info('✓ 没有发现卡住的文档'); + return self::SUCCESS; + } + + $this->warn("发现 {$stuckDocuments->count()} 个卡住的文档:"); + + // 显示文档列表 + $tableData = $stuckDocuments->map(function ($doc) { + return [ + 'ID' => $doc->id, + '标题' => \Illuminate\Support\Str::limit($doc->title, 40), + '状态' => $doc->conversion_status, + '更新时间' => $doc->updated_at->format('Y-m-d H:i:s'), + '卡住时长' => $doc->updated_at->diffForHumans(), + ]; + })->toArray(); + + $this->table( + ['ID', '标题', '状态', '更新时间', '卡住时长'], + $tableData + ); + + if ($dryRun) { + $this->info(''); + $this->info('这是预览模式,没有实际修改任何数据'); + $this->info('移除 --dry-run 选项以执行修复'); + return self::SUCCESS; + } + + // 确认操作 + if (!$this->confirm('是否要将这些文档标记为失败状态?', true)) { + $this->info('操作已取消'); + return self::SUCCESS; + } + + // 修复文档 + $fixed = 0; + foreach ($stuckDocuments as $document) { + try { + $document->update([ + 'conversion_status' => 'failed', + 'conversion_error' => "转换任务超时(卡在 {$status} 状态超过 {$timeout} 分钟)", + ]); + $fixed++; + $this->line("✓ 已修复: [{$document->id}] {$document->title}"); + } catch (\Exception $e) { + $this->error("✗ 修复失败: [{$document->id}] {$document->title} - {$e->getMessage()}"); + } + } + + $this->info(''); + $this->info("修复完成!共修复 {$fixed} 个文档"); + $this->info('现在可以在管理界面使用"重试转换"功能重新处理这些文档'); + + return self::SUCCESS; + } +} diff --git a/app/Filament/Resources/DocumentResource.php b/app/Filament/Resources/DocumentResource.php index 56e633c..f0f93e2 100644 --- a/app/Filament/Resources/DocumentResource.php +++ b/app/Filament/Resources/DocumentResource.php @@ -226,12 +226,20 @@ class DocumentResource extends Resource ->label('重试转换') ->icon('heroicon-o-arrow-path') ->color('warning') - ->visible(fn (Document $record): bool => $record->conversion_status === 'failed') + ->visible(fn (Document $record): bool => + in_array($record->conversion_status, ['failed', 'processing', 'pending']) + ) ->requiresConfirmation() ->modalHeading('重试文档转换') ->modalDescription(fn (Document $record): string => '确定要重新转换文档 "' . $record->title . '" 吗?' . - ($record->conversion_error ? "\n\n上次失败原因:" . $record->conversion_error : '') + "\n\n当前状态:" . match($record->conversion_status) { + 'failed' => '转换失败', + 'processing' => '转换中(可能卡住)', + 'pending' => '等待转换', + default => $record->conversion_status, + } . + ($record->conversion_error ? "\n\n错误信息:" . $record->conversion_error : '') ) ->modalSubmitActionLabel('确认重试') ->action(function (Document $record) {